@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.
Files changed (186) hide show
  1. package/LICENSE +9 -0
  2. package/README.md +690 -28
  3. package/dist/cjs/_virtual/rolldown_runtime.cjs +29 -0
  4. package/dist/cjs/adapters/pinata/adapter.cjs +88 -0
  5. package/dist/cjs/adapters/pinata/adapter.cjs.map +1 -0
  6. package/dist/cjs/adapters/pinata/adapter.d.cts +35 -0
  7. package/dist/cjs/adapters/pinata/builder.cjs +194 -0
  8. package/dist/cjs/adapters/pinata/builder.cjs.map +1 -0
  9. package/dist/cjs/adapters/pinata/index.cjs +3 -0
  10. package/dist/cjs/adapters/pinata/list-builder.cjs +52 -0
  11. package/dist/cjs/adapters/pinata/list-builder.cjs.map +1 -0
  12. package/dist/cjs/blockstore/index.cjs +2 -0
  13. package/dist/cjs/blockstore/unstorage-base.cjs +240 -0
  14. package/dist/cjs/blockstore/unstorage-base.cjs.map +1 -0
  15. package/dist/cjs/blockstore/unstorage-base.d.cts +23 -0
  16. package/dist/cjs/blockstore/unstorage.cjs +39 -0
  17. package/dist/cjs/blockstore/unstorage.cjs.map +1 -0
  18. package/dist/cjs/blockstore/unstorage.d.cts +36 -0
  19. package/dist/cjs/config.d.cts +51 -0
  20. package/dist/cjs/encoder/base64.cjs +38 -0
  21. package/dist/cjs/encoder/base64.cjs.map +1 -0
  22. package/dist/cjs/encoder/csv/csv-formatter.cjs +81 -0
  23. package/dist/cjs/encoder/csv/csv-formatter.cjs.map +1 -0
  24. package/dist/cjs/encoder/csv/field-formatter.cjs +76 -0
  25. package/dist/cjs/encoder/csv/field-formatter.cjs.map +1 -0
  26. package/dist/cjs/encoder/csv/row-formatter.cjs +159 -0
  27. package/dist/cjs/encoder/csv/row-formatter.cjs.map +1 -0
  28. package/dist/cjs/encoder/csv.cjs +44 -0
  29. package/dist/cjs/encoder/csv.cjs.map +1 -0
  30. package/dist/cjs/encoder/error.cjs +19 -0
  31. package/dist/cjs/encoder/error.cjs.map +1 -0
  32. package/dist/cjs/encoder/index.cjs +6 -0
  33. package/dist/cjs/encoder/json.cjs +36 -0
  34. package/dist/cjs/encoder/json.cjs.map +1 -0
  35. package/dist/cjs/encoder/text.cjs +35 -0
  36. package/dist/cjs/encoder/text.cjs.map +1 -0
  37. package/dist/cjs/encoder/url.cjs +39 -0
  38. package/dist/cjs/encoder/url.cjs.map +1 -0
  39. package/dist/cjs/errors/index.cjs +104 -0
  40. package/dist/cjs/errors/index.cjs.map +1 -0
  41. package/dist/cjs/errors/index.d.cts +47 -0
  42. package/dist/cjs/index.cjs +42 -0
  43. package/dist/cjs/index.d.cts +14 -0
  44. package/dist/cjs/pin/client.cjs +96 -0
  45. package/dist/cjs/pin/client.cjs.map +1 -0
  46. package/dist/cjs/pin/index.cjs +1 -0
  47. package/dist/cjs/pinner.cjs +126 -0
  48. package/dist/cjs/pinner.cjs.map +1 -0
  49. package/dist/cjs/pinner.d.cts +77 -0
  50. package/dist/cjs/types/constants.cjs +34 -0
  51. package/dist/cjs/types/constants.cjs.map +1 -0
  52. package/dist/cjs/types/mime-types.cjs +11 -0
  53. package/dist/cjs/types/mime-types.cjs.map +1 -0
  54. package/dist/cjs/types/mime-types.d.cts +7 -0
  55. package/dist/cjs/types/pin.d.cts +74 -0
  56. package/dist/cjs/types/pinata.d.cts +99 -0
  57. package/dist/cjs/types/type-guards.cjs +20 -0
  58. package/dist/cjs/types/type-guards.cjs.map +1 -0
  59. package/dist/cjs/types/type-guards.d.cts +15 -0
  60. package/dist/cjs/types/upload.cjs +18 -0
  61. package/dist/cjs/types/upload.cjs.map +1 -0
  62. package/dist/cjs/types/upload.d.cts +189 -0
  63. package/dist/cjs/upload/base-upload.cjs +135 -0
  64. package/dist/cjs/upload/base-upload.cjs.map +1 -0
  65. package/dist/cjs/upload/builder.cjs +174 -0
  66. package/dist/cjs/upload/builder.cjs.map +1 -0
  67. package/dist/cjs/upload/builder.d.cts +60 -0
  68. package/dist/cjs/upload/car.cjs +129 -0
  69. package/dist/cjs/upload/car.cjs.map +1 -0
  70. package/dist/cjs/upload/car.d.cts +19 -0
  71. package/dist/cjs/upload/constants.cjs +9 -0
  72. package/dist/cjs/upload/constants.cjs.map +1 -0
  73. package/dist/cjs/upload/index.cjs +8 -0
  74. package/dist/cjs/upload/manager.cjs +249 -0
  75. package/dist/cjs/upload/manager.cjs.map +1 -0
  76. package/dist/cjs/upload/manager.d.cts +35 -0
  77. package/dist/cjs/upload/normalize.cjs +28 -0
  78. package/dist/cjs/upload/normalize.cjs.map +1 -0
  79. package/dist/cjs/upload/tus-upload.cjs +74 -0
  80. package/dist/cjs/upload/tus-upload.cjs.map +1 -0
  81. package/dist/cjs/upload/xhr-upload.cjs +41 -0
  82. package/dist/cjs/upload/xhr-upload.cjs.map +1 -0
  83. package/dist/cjs/utils/env.cjs +12 -0
  84. package/dist/cjs/utils/env.cjs.map +1 -0
  85. package/dist/cjs/utils/stream.cjs +141 -0
  86. package/dist/cjs/utils/stream.cjs.map +1 -0
  87. package/dist/cjs/utils/stream.d.cts +23 -0
  88. package/dist/cjs/utils/tus-patch.cjs +50 -0
  89. package/dist/cjs/utils/tus-patch.cjs.map +1 -0
  90. package/dist/cjs/utils/validation.cjs +62 -0
  91. package/dist/cjs/utils/validation.cjs.map +1 -0
  92. package/dist/esm/_virtual/rolldown_runtime.js +8 -0
  93. package/dist/esm/adapters/pinata/adapter.d.ts +35 -0
  94. package/dist/esm/adapters/pinata/adapter.js +87 -0
  95. package/dist/esm/adapters/pinata/adapter.js.map +1 -0
  96. package/dist/esm/adapters/pinata/builder.d.ts +1 -0
  97. package/dist/esm/adapters/pinata/builder.js +187 -0
  98. package/dist/esm/adapters/pinata/builder.js.map +1 -0
  99. package/dist/esm/adapters/pinata/index.d.ts +4 -0
  100. package/dist/esm/adapters/pinata/index.js +3 -0
  101. package/dist/esm/adapters/pinata/list-builder.d.ts +1 -0
  102. package/dist/esm/adapters/pinata/list-builder.js +51 -0
  103. package/dist/esm/adapters/pinata/list-builder.js.map +1 -0
  104. package/dist/esm/blockstore/index.d.ts +2 -0
  105. package/dist/esm/blockstore/index.js +2 -0
  106. package/dist/esm/blockstore/unstorage-base.d.ts +23 -0
  107. package/dist/esm/blockstore/unstorage-base.js +231 -0
  108. package/dist/esm/blockstore/unstorage-base.js.map +1 -0
  109. package/dist/esm/blockstore/unstorage.d.ts +36 -0
  110. package/dist/esm/blockstore/unstorage.js +38 -0
  111. package/dist/esm/blockstore/unstorage.js.map +1 -0
  112. package/dist/esm/config.d.ts +51 -0
  113. package/dist/esm/encoder/base64.js +37 -0
  114. package/dist/esm/encoder/base64.js.map +1 -0
  115. package/dist/esm/encoder/csv/csv-formatter.js +81 -0
  116. package/dist/esm/encoder/csv/csv-formatter.js.map +1 -0
  117. package/dist/esm/encoder/csv/field-formatter.js +75 -0
  118. package/dist/esm/encoder/csv/field-formatter.js.map +1 -0
  119. package/dist/esm/encoder/csv/row-formatter.js +159 -0
  120. package/dist/esm/encoder/csv/row-formatter.js.map +1 -0
  121. package/dist/esm/encoder/csv.js +43 -0
  122. package/dist/esm/encoder/csv.js.map +1 -0
  123. package/dist/esm/encoder/error.js +18 -0
  124. package/dist/esm/encoder/error.js.map +1 -0
  125. package/dist/esm/encoder/index.js +6 -0
  126. package/dist/esm/encoder/json.js +35 -0
  127. package/dist/esm/encoder/json.js.map +1 -0
  128. package/dist/esm/encoder/text.js +34 -0
  129. package/dist/esm/encoder/text.js.map +1 -0
  130. package/dist/esm/encoder/url.js +36 -0
  131. package/dist/esm/encoder/url.js.map +1 -0
  132. package/dist/esm/errors/index.d.ts +47 -0
  133. package/dist/esm/errors/index.js +93 -0
  134. package/dist/esm/errors/index.js.map +1 -0
  135. package/dist/esm/index.d.ts +16 -0
  136. package/dist/esm/index.js +14 -0
  137. package/dist/esm/pin/client.js +95 -0
  138. package/dist/esm/pin/client.js.map +1 -0
  139. package/dist/esm/pin/index.js +1 -0
  140. package/dist/esm/pinner.d.ts +77 -0
  141. package/dist/esm/pinner.js +125 -0
  142. package/dist/esm/pinner.js.map +1 -0
  143. package/dist/esm/types/constants.js +29 -0
  144. package/dist/esm/types/constants.js.map +1 -0
  145. package/dist/esm/types/mime-types.d.ts +7 -0
  146. package/dist/esm/types/mime-types.js +8 -0
  147. package/dist/esm/types/mime-types.js.map +1 -0
  148. package/dist/esm/types/pin.d.ts +74 -0
  149. package/dist/esm/types/pinata.d.ts +99 -0
  150. package/dist/esm/types/type-guards.d.ts +15 -0
  151. package/dist/esm/types/type-guards.js +19 -0
  152. package/dist/esm/types/type-guards.js.map +1 -0
  153. package/dist/esm/types/upload.d.ts +189 -0
  154. package/dist/esm/types/upload.js +16 -0
  155. package/dist/esm/types/upload.js.map +1 -0
  156. package/dist/esm/upload/base-upload.js +132 -0
  157. package/dist/esm/upload/base-upload.js.map +1 -0
  158. package/dist/esm/upload/builder.d.ts +60 -0
  159. package/dist/esm/upload/builder.js +173 -0
  160. package/dist/esm/upload/builder.js.map +1 -0
  161. package/dist/esm/upload/car.d.ts +19 -0
  162. package/dist/esm/upload/car.js +125 -0
  163. package/dist/esm/upload/car.js.map +1 -0
  164. package/dist/esm/upload/constants.js +7 -0
  165. package/dist/esm/upload/constants.js.map +1 -0
  166. package/dist/esm/upload/index.js +8 -0
  167. package/dist/esm/upload/manager.d.ts +35 -0
  168. package/dist/esm/upload/manager.js +248 -0
  169. package/dist/esm/upload/manager.js.map +1 -0
  170. package/dist/esm/upload/normalize.js +28 -0
  171. package/dist/esm/upload/normalize.js.map +1 -0
  172. package/dist/esm/upload/tus-upload.js +72 -0
  173. package/dist/esm/upload/tus-upload.js.map +1 -0
  174. package/dist/esm/upload/xhr-upload.js +39 -0
  175. package/dist/esm/upload/xhr-upload.js.map +1 -0
  176. package/dist/esm/utils/env.js +11 -0
  177. package/dist/esm/utils/env.js.map +1 -0
  178. package/dist/esm/utils/stream.d.ts +23 -0
  179. package/dist/esm/utils/stream.js +134 -0
  180. package/dist/esm/utils/stream.js.map +1 -0
  181. package/dist/esm/utils/tus-patch.js +51 -0
  182. package/dist/esm/utils/tus-patch.js.map +1 -0
  183. package/dist/esm/utils/validation.js +60 -0
  184. package/dist/esm/utils/validation.js.map +1 -0
  185. package/package.json +95 -8
  186. package/public/mockServiceWorker.js +349 -0
@@ -0,0 +1,240 @@
1
+ const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
2
+ const require_stream = require('../utils/stream.cjs');
3
+ const require_constants = require('../types/constants.cjs');
4
+ let _home_runner_work_web_web_node_modules__pnpm_blockstore_core_6_1_2_node_modules_blockstore_core_dist_src_index_js = require("/home/runner/work/web/web/node_modules/.pnpm/blockstore-core@6.1.2/node_modules/blockstore-core/dist/src/index.js");
5
+ let multiformats_cid = require("multiformats/cid");
6
+ let unstorage = require("unstorage");
7
+ let interface_datastore = require("interface-datastore");
8
+
9
+ //#region src/blockstore/unstorage-base.ts
10
+ let driverFactory = null;
11
+ function setDriverFactory(factory) {
12
+ driverFactory = factory;
13
+ }
14
+ function createStorageWithOptions(options) {
15
+ return options.storage ? options.storage : (0, unstorage.createStorage)({ driver: options.driver });
16
+ }
17
+ async function initializeStorage(storage, options, getDefaultDriver) {
18
+ if (options.storage || options.driver) return;
19
+ const driver = await getDefaultDriver(options.base);
20
+ Object.assign(storage, (0, unstorage.createStorage)({ driver }));
21
+ }
22
+ function createUnstorageBase(options, getDefaultDriver) {
23
+ const storage = createStorageWithOptions(options);
24
+ const initialized = initializeStorage(storage, options, getDefaultDriver);
25
+ async function ensureInitialized() {
26
+ await initialized;
27
+ }
28
+ async function hasItem(key) {
29
+ await ensureInitialized();
30
+ return await storage.hasItem(key);
31
+ }
32
+ async function getItem(key) {
33
+ await ensureInitialized();
34
+ const value = await storage.getItemRaw(key);
35
+ if (value === null) throw new Error(`Item not found: ${key}`);
36
+ return value;
37
+ }
38
+ async function putItem(key, value) {
39
+ await ensureInitialized();
40
+ await storage.setItemRaw(key, value);
41
+ }
42
+ async function deleteItem(key) {
43
+ await ensureInitialized();
44
+ await storage.removeItem(key);
45
+ }
46
+ async function getAllKeys() {
47
+ await ensureInitialized();
48
+ return await storage.getKeys();
49
+ }
50
+ return {
51
+ storage,
52
+ hasItem,
53
+ getItem,
54
+ putItem,
55
+ deleteItem,
56
+ getAllKeys
57
+ };
58
+ }
59
+ function createUnstorageBlockstore(getDefaultDriver) {
60
+ return class UnstorageBlockstore extends _home_runner_work_web_web_node_modules__pnpm_blockstore_core_6_1_2_node_modules_blockstore_core_dist_src_index_js.BaseBlockstore {
61
+ prefix;
62
+ base;
63
+ constructor(options = {}) {
64
+ super();
65
+ this.prefix = options.prefix ?? require_constants.DEFAULT_BLOCKSTORE_PREFIX;
66
+ this.base = createUnstorageBase(options, getDefaultDriver);
67
+ }
68
+ keyToStorageKey(key) {
69
+ return `${this.prefix}:${key.toString()}`;
70
+ }
71
+ async has(key, _) {
72
+ return await this.base.hasItem(this.keyToStorageKey(key));
73
+ }
74
+ async put(key, val, _) {
75
+ const storageKey = this.keyToStorageKey(key);
76
+ const bytes = val instanceof Uint8Array ? val : await require_stream.collectAsyncIterable(val);
77
+ await this.base.putItem(storageKey, bytes);
78
+ return key;
79
+ }
80
+ async *putMany(source, options) {
81
+ for await (const { cid, bytes } of source) yield await this.put(cid, bytes, options);
82
+ }
83
+ async *get(key, _) {
84
+ const storageKey = this.keyToStorageKey(key);
85
+ yield await this.base.getItem(storageKey);
86
+ }
87
+ async *getMany(source, options) {
88
+ for await (const cid of source) yield {
89
+ cid,
90
+ bytes: async function* () {
91
+ yield* await this.get(cid, options);
92
+ }.call(this)
93
+ };
94
+ }
95
+ async delete(key, _) {
96
+ await this.base.deleteItem(this.keyToStorageKey(key));
97
+ }
98
+ async *deleteMany(source, options) {
99
+ for await (const cid of source) {
100
+ await this.delete(cid, options);
101
+ yield cid;
102
+ }
103
+ }
104
+ async *getAll(_) {
105
+ const keys = await this.base.getAllKeys();
106
+ for (const key of keys) if (key.startsWith(this.prefix + ":")) {
107
+ const cidString = key.slice(this.prefix.length + 1);
108
+ try {
109
+ const cid = multiformats_cid.CID.parse(cidString);
110
+ const value = await this.base.getItem(key);
111
+ yield {
112
+ cid,
113
+ bytes: (async function* () {
114
+ yield value;
115
+ })()
116
+ };
117
+ } catch {}
118
+ }
119
+ }
120
+ };
121
+ }
122
+ function createUnstorageDatastore(getDefaultDriver) {
123
+ return class UnstorageDatastore {
124
+ prefix;
125
+ base;
126
+ constructor(options = {}) {
127
+ this.prefix = options.datastorePrefix ?? options.prefix ?? require_constants.DEFAULT_BLOCKSTORE_PREFIX;
128
+ this.base = createUnstorageBase(options, getDefaultDriver);
129
+ }
130
+ keyToStorageKey(key) {
131
+ return `${this.prefix}:${key.toString()}`;
132
+ }
133
+ storageKeyToKey(storageKey) {
134
+ return new interface_datastore.Key(storageKey.slice(this.prefix.length + 1));
135
+ }
136
+ async has(key, _) {
137
+ return await this.base.hasItem(this.keyToStorageKey(key));
138
+ }
139
+ async put(key, val, _) {
140
+ await this.base.putItem(this.keyToStorageKey(key), val);
141
+ return key;
142
+ }
143
+ async *putMany(source, options) {
144
+ for await (const { key, value } of source) yield await this.put(key, value, options);
145
+ }
146
+ async get(key, _) {
147
+ const storageKey = this.keyToStorageKey(key);
148
+ try {
149
+ return await this.base.getItem(storageKey);
150
+ } catch (error) {
151
+ throw new Error(`Datastore item not found: ${key.toString()}`);
152
+ }
153
+ }
154
+ async *getMany(source, options) {
155
+ for await (const key of source) yield {
156
+ key,
157
+ value: await this.get(key, options)
158
+ };
159
+ }
160
+ async delete(key, _) {
161
+ await this.base.deleteItem(this.keyToStorageKey(key));
162
+ }
163
+ async *deleteMany(source, options) {
164
+ for await (const key of source) {
165
+ await this.delete(key, options);
166
+ yield key;
167
+ }
168
+ }
169
+ batch() {
170
+ const operations = [];
171
+ const base = this.base;
172
+ const keyToStorageKey = this.keyToStorageKey.bind(this);
173
+ return {
174
+ put(key, value) {
175
+ operations.push({
176
+ type: "put",
177
+ key,
178
+ value
179
+ });
180
+ },
181
+ delete(key) {
182
+ operations.push({
183
+ type: "delete",
184
+ key
185
+ });
186
+ },
187
+ async commit() {
188
+ for (const op of operations) if (op.type === "put" && op.value !== void 0) await base.putItem(keyToStorageKey(op.key), op.value);
189
+ else if (op.type === "delete") await base.deleteItem(keyToStorageKey(op.key));
190
+ operations.length = 0;
191
+ }
192
+ };
193
+ }
194
+ async *query(query, _) {
195
+ const keys = await this.base.getAllKeys();
196
+ for (const key of keys) {
197
+ if (!key.startsWith(this.prefix + ":")) continue;
198
+ const datastoreKey = this.storageKeyToKey(key);
199
+ if (query.prefix && !datastoreKey.toString().startsWith(query.prefix.toString())) continue;
200
+ const value = await this.base.getItem(key);
201
+ if (query.filters) {
202
+ let match = true;
203
+ for (const filter of query.filters) if (!filter({
204
+ key: datastoreKey,
205
+ value
206
+ })) {
207
+ match = false;
208
+ break;
209
+ }
210
+ if (!match) continue;
211
+ }
212
+ yield {
213
+ key: datastoreKey,
214
+ value
215
+ };
216
+ }
217
+ }
218
+ async *queryKeys(query, _) {
219
+ const keys = await this.base.getAllKeys();
220
+ for (const key of keys) {
221
+ if (!key.startsWith(this.prefix + ":")) continue;
222
+ const datastoreKey = this.storageKeyToKey(key);
223
+ if (query.prefix && !datastoreKey.toString().startsWith(query.prefix.toString())) continue;
224
+ yield datastoreKey;
225
+ }
226
+ }
227
+ };
228
+ }
229
+
230
+ //#endregion
231
+ exports.createUnstorageBlockstore = createUnstorageBlockstore;
232
+ exports.createUnstorageDatastore = createUnstorageDatastore;
233
+ Object.defineProperty(exports, 'driverFactory', {
234
+ enumerable: true,
235
+ get: function () {
236
+ return driverFactory;
237
+ }
238
+ });
239
+ exports.setDriverFactory = setDriverFactory;
240
+ //# sourceMappingURL=unstorage-base.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unstorage-base.cjs","names":["BaseBlockstore","DEFAULT_BLOCKSTORE_PREFIX","collectAsyncIterable","CID","Key"],"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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"}
@@ -0,0 +1,23 @@
1
+ import { Driver, Storage } from "unstorage";
2
+ import { Datastore } from "interface-datastore";
3
+
4
+ //#region src/blockstore/unstorage-base.d.ts
5
+ interface UnstorageBlockstoreOptions {
6
+ storage?: Storage;
7
+ prefix?: string;
8
+ driver?: Driver;
9
+ base?: string;
10
+ datastorePrefix?: string;
11
+ }
12
+ /**
13
+ * prefix: Key prefix for blockstore keys (e.g., "blockstore" or "pinner-helia-blocks").
14
+ * This is prepended to CID strings in storage keys.
15
+ *
16
+ * base: Base path for the storage driver (e.g., "pinner:" for IndexedDB, "./.pinner-blocks" for filesystem).
17
+ * This determines where the storage driver stores data.
18
+ */
19
+ type DriverFactory = () => Driver | Promise<Driver>;
20
+ declare function setDriverFactory(factory: DriverFactory | null): void;
21
+ //#endregion
22
+ export { UnstorageBlockstoreOptions, setDriverFactory };
23
+ //# sourceMappingURL=unstorage-base.d.cts.map
@@ -0,0 +1,39 @@
1
+ const require_constants = require('../types/constants.cjs');
2
+ const require_unstorage_base = require('./unstorage-base.cjs');
3
+
4
+ //#region src/blockstore/unstorage.ts
5
+ function isBrowser() {
6
+ return typeof window !== "undefined" && typeof window.localStorage !== "undefined";
7
+ }
8
+ async function getDefaultDriver(base) {
9
+ if (require_unstorage_base.driverFactory) return await require_unstorage_base.driverFactory();
10
+ if (isBrowser()) return (await import("unstorage/drivers/indexedb")).default({ base: base ?? require_constants.DEFAULT_BLOCKSTORE_BASE });
11
+ else return (await import("unstorage/drivers/fs-lite")).default({ base: base ?? require_constants.DEFAULT_BLOCKSTORE_FS_BASE });
12
+ }
13
+ function createBlockstore(options) {
14
+ const BlockstoreClass = require_unstorage_base.createUnstorageBlockstore(getDefaultDriver);
15
+ return class extends BlockstoreClass {
16
+ constructor(instanceOptions) {
17
+ super({
18
+ ...options,
19
+ ...instanceOptions
20
+ });
21
+ }
22
+ };
23
+ }
24
+ function createDatastore(options) {
25
+ const DatastoreClass = require_unstorage_base.createUnstorageDatastore(getDefaultDriver);
26
+ return class extends DatastoreClass {
27
+ constructor(instanceOptions) {
28
+ super({
29
+ ...options,
30
+ ...instanceOptions
31
+ });
32
+ }
33
+ };
34
+ }
35
+
36
+ //#endregion
37
+ exports.createBlockstore = createBlockstore;
38
+ exports.createDatastore = createDatastore;
39
+ //# sourceMappingURL=unstorage.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unstorage.cjs","names":["driverFactory","DEFAULT_BLOCKSTORE_BASE","DEFAULT_BLOCKSTORE_FS_BASE","createUnstorageBlockstore","createUnstorageDatastore"],"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":";;;;AAYA,SAAS,YAAqB;AAC5B,QACE,OAAO,WAAW,eAAe,OAAO,OAAO,iBAAiB;;AAIpE,eAAe,iBAAiB,MAAe;AAE7C,KAAIA,qCACF,QAAO,MAAMA,sCAAe;AAG9B,KAAI,WAAW,CACb,SAAQ,MAAM,OAAO,+BAA+B,QAAQ,EAC1D,MAAM,QAAQC,2CACf,CAAC;KAEF,SAAQ,MAAM,OAAO,8BAA8B,QAAQ,EACzD,MAAM,QAAQC,8CACf,CAAC;;AAIN,SAAgB,iBAAiB,SAAsC;CACrE,MAAM,kBAAkBC,iDAA0B,iBAAiB;AACnE,QAAO,cAAc,gBAAgB;EACnC,YAAY,iBAA8C;AACxD,SAAM;IAAE,GAAG;IAAS,GAAG;IAAiB,CAAC;;;;AAK/C,SAAgB,gBAAgB,SAAsC;CACpE,MAAM,iBAAiBC,gDAAyB,iBAAiB;AACjE,QAAO,cAAc,eAAe;EAClC,YAAY,iBAA8C;AACxD,SAAM;IAAE,GAAG;IAAS,GAAG;IAAiB,CAAC"}
@@ -0,0 +1,36 @@
1
+ import { UnstorageBlockstoreOptions, setDriverFactory } from "./unstorage-base.cjs";
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";
6
+
7
+ //#region src/blockstore/unstorage.d.ts
8
+ declare function createBlockstore(options?: UnstorageBlockstoreOptions): {
9
+ new (instanceOptions?: UnstorageBlockstoreOptions): {
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
+ };
34
+ //#endregion
35
+ export { createBlockstore, createDatastore };
36
+ //# sourceMappingURL=unstorage.d.cts.map
@@ -0,0 +1,51 @@
1
+ import { Storage } from "unstorage";
2
+ import { Datastore } from "interface-datastore";
3
+
4
+ //#region src/config.d.ts
5
+ interface PinnerConfig {
6
+ /**
7
+ * JWT authentication token. Required for all API operations.
8
+ */
9
+ jwt: string;
10
+ /**
11
+ * API endpoint URL. Defaults to the official pinning service.
12
+ * @default "https://ipfs.pinner.xyz"
13
+ */
14
+ endpoint?: string;
15
+ /**
16
+ * IPFS gateway URL for content retrieval.
17
+ * @default "https://dweb.link"
18
+ */
19
+ gateway?: string;
20
+ /**
21
+ * Allowed MIME types for upload. If undefined, all types allowed.
22
+ */
23
+ allowedFileTypes?: string[];
24
+ /**
25
+ * Custom fetch implementation.
26
+ */
27
+ fetch?: typeof fetch;
28
+ /**
29
+ * Custom datastore instance for Helia.
30
+ * If provided, this datastore will be used directly without creating one from storage.
31
+ * Highest priority - takes precedence over storage and datastoreName.
32
+ */
33
+ datastore?: Datastore;
34
+ /**
35
+ * Custom storage instance for both Helia blockstore and datastore.
36
+ * If provided, this storage will be used instead of creating default storage.
37
+ * The storage instance must implement the unstorage Storage interface.
38
+ * Used when datastore is not provided.
39
+ */
40
+ storage?: Storage;
41
+ /**
42
+ * Custom base name for Helia storage.
43
+ * Passed as the `base` option to both blockstore and datastore storage instances.
44
+ * Only used when neither datastore nor storage are provided.
45
+ * @default "pinner-helia-data"
46
+ */
47
+ datastoreName?: string;
48
+ }
49
+ //#endregion
50
+ export { PinnerConfig };
51
+ //# sourceMappingURL=config.d.cts.map
@@ -0,0 +1,38 @@
1
+ const require_error = require('./error.cjs');
2
+
3
+ //#region src/encoder/base64.ts
4
+ /**
5
+ * Base64 encoder - converts base64 strings to File objects.
6
+ */
7
+ var Base64Encoder = class {
8
+ async encode(base64String, options) {
9
+ try {
10
+ const binaryString = atob(base64String);
11
+ const bytes = new Uint8Array(binaryString.length);
12
+ for (let i = 0; i < binaryString.length; i++) bytes[i] = binaryString.charCodeAt(i);
13
+ const blob = new Blob([bytes], { type: "application/octet-stream" });
14
+ const filename = options?.name || "file.bin";
15
+ return {
16
+ file: new File([blob], filename, { type: "application/octet-stream" }),
17
+ options: {
18
+ name: options?.name,
19
+ keyvalues: options?.keyvalues
20
+ }
21
+ };
22
+ } catch (error) {
23
+ if (error instanceof Error) throw new require_error.EncoderError(`Base64 encoding failed: ${error.message}`, "INVALID_BASE64", error);
24
+ throw new require_error.EncoderError("Base64 encoding failed: unknown error", "INVALID_BASE64");
25
+ }
26
+ }
27
+ };
28
+ /**
29
+ * Encode a base64 string to a File object.
30
+ */
31
+ async function base64ToFile(base64String, options) {
32
+ return new Base64Encoder().encode(base64String, options);
33
+ }
34
+
35
+ //#endregion
36
+ exports.Base64Encoder = Base64Encoder;
37
+ exports.base64ToFile = base64ToFile;
38
+ //# sourceMappingURL=base64.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base64.cjs","names":["EncoderError"],"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,MALW,IAAI,KAAK,CAAC,KAAK,EAAE,UAAU,EACtC,MAAM,4BACP,CAAC;IAIA,SAAS;KACP,MAAM,SAAS;KACf,WAAW,SAAS;KACrB;IACF;WACM,OAAO;AACd,OAAI,iBAAiB,MACnB,OAAM,IAAIA,2BACR,2BAA2B,MAAM,WACjC,kBACA,MACD;AAEH,SAAM,IAAIA,2BACR,yCACA,iBACD;;;;;;;AAQP,eAAsB,aACpB,cACA,SACwB;AAExB,QADgB,IAAI,eAAe,CACpB,OAAO,cAAc,QAAQ"}
@@ -0,0 +1,81 @@
1
+ const require_row_formatter = require('./row-formatter.cjs');
2
+
3
+ //#region src/encoder/csv/csv-formatter.ts
4
+ /**
5
+ * Simple CSV formatter without streaming support.
6
+ * Converts arrays of objects or arrays to CSV strings.
7
+ *
8
+ * This implementation is derived from @fast-csv/format (https://github.com/C2FO/fast-csv)
9
+ * Copyright (c) 2011 C2FO Labs, LLC
10
+ * Licensed under the MIT License
11
+ */
12
+ var CsvFormatter = class {
13
+ options;
14
+ rowFormatter;
15
+ hasWrittenBOM = false;
16
+ constructor(options = {}) {
17
+ this.options = {
18
+ objectMode: true,
19
+ delimiter: ",",
20
+ rowDelimiter: "\n",
21
+ quote: "\"",
22
+ escape: void 0,
23
+ quoteColumns: false,
24
+ quoteHeaders: void 0,
25
+ headers: null,
26
+ writeHeaders: void 0,
27
+ includeEndRowDelimiter: false,
28
+ transform: void 0,
29
+ writeBOM: false,
30
+ BOM: "",
31
+ alwaysWriteHeaders: false,
32
+ ...options
33
+ };
34
+ if (typeof this.options.escape !== "string") this.options.escape = this.options.quote === true ? "\"" : this.options.quote;
35
+ if (typeof this.options.quoteHeaders === "undefined") this.options.quoteHeaders = this.options.quoteColumns;
36
+ if (this.options.quote === true) this.options.quote = "\"";
37
+ else if (this.options.quote === false) this.options.quote = "";
38
+ this.rowFormatter = new require_row_formatter.RowFormatter(this.options);
39
+ this.hasWrittenBOM = !this.options.writeBOM;
40
+ }
41
+ /**
42
+ * Format an array of rows to CSV string.
43
+ */
44
+ format(rows) {
45
+ const chunks = [];
46
+ if (!this.hasWrittenBOM) {
47
+ chunks.push(this.options.BOM || "");
48
+ this.hasWrittenBOM = true;
49
+ }
50
+ for (const row of rows) {
51
+ const formattedRows = this.rowFormatter.format(row);
52
+ chunks.push(...formattedRows);
53
+ }
54
+ const finishRows = this.rowFormatter.finish();
55
+ chunks.push(...finishRows);
56
+ return chunks.join("");
57
+ }
58
+ /**
59
+ * Format a single row to CSV string.
60
+ */
61
+ formatRow(row) {
62
+ const chunks = [];
63
+ if (!this.hasWrittenBOM) {
64
+ chunks.push(this.options.BOM || "");
65
+ this.hasWrittenBOM = true;
66
+ }
67
+ const formattedRows = this.rowFormatter.format(row);
68
+ chunks.push(...formattedRows);
69
+ return chunks.join("");
70
+ }
71
+ };
72
+ /**
73
+ * Create a CSV formatter with the given options.
74
+ */
75
+ function createCsvFormatter(options) {
76
+ return new CsvFormatter(options);
77
+ }
78
+
79
+ //#endregion
80
+ exports.createCsvFormatter = createCsvFormatter;
81
+ //# sourceMappingURL=csv-formatter.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csv-formatter.cjs","names":["RowFormatter"],"sources":["../../../../src/encoder/csv/csv-formatter.ts"],"sourcesContent":["import type { CsvFormatterOptions } from \"./csv-options\";\nimport { RowFormatter } from \"./row-formatter\";\n\nexport type { CsvFormatterOptions };\n\n/**\n * Simple CSV formatter without streaming support.\n * Converts arrays of objects or arrays to CSV strings.\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 CsvFormatter {\n private options: CsvFormatterOptions;\n private rowFormatter: RowFormatter;\n private hasWrittenBOM = false;\n\n constructor(options: CsvFormatterOptions = {}) {\n this.options = {\n objectMode: true,\n delimiter: \",\",\n rowDelimiter: \"\\n\",\n quote: '\"',\n escape: undefined,\n quoteColumns: false,\n quoteHeaders: undefined,\n headers: null as string[] | null,\n writeHeaders: undefined,\n includeEndRowDelimiter: false,\n transform: undefined,\n writeBOM: false,\n BOM: \"\\ufeff\",\n alwaysWriteHeaders: false,\n ...options,\n };\n\n // Set escape to quote if not provided\n if (typeof this.options.escape !== \"string\") {\n this.options.escape =\n this.options.quote === true ? '\"' : (this.options.quote as string);\n }\n\n // Set quoteHeaders to quoteColumns if not provided\n if (typeof this.options.quoteHeaders === \"undefined\") {\n this.options.quoteHeaders = this.options.quoteColumns;\n }\n\n // Normalize quote option\n if (this.options.quote === true) {\n this.options.quote = '\"';\n } else if (this.options.quote === false) {\n this.options.quote = \"\";\n }\n\n this.rowFormatter = new RowFormatter(this.options);\n this.hasWrittenBOM = !this.options.writeBOM;\n }\n\n /**\n * Format an array of rows to CSV string.\n */\n format(rows: unknown[]): string {\n const chunks: string[] = [];\n\n // Write BOM if configured\n if (!this.hasWrittenBOM) {\n chunks.push(this.options.BOM || \"\\ufeff\");\n this.hasWrittenBOM = true;\n }\n\n // Format each row\n for (const row of rows) {\n const formattedRows = this.rowFormatter.format(row);\n chunks.push(...formattedRows);\n }\n\n // Add finish content (end row delimiter, etc.)\n const finishRows = this.rowFormatter.finish();\n chunks.push(...finishRows);\n\n return chunks.join(\"\");\n }\n\n /**\n * Format a single row to CSV string.\n */\n formatRow(row: unknown): string {\n const chunks: string[] = [];\n\n // Write BOM if configured\n if (!this.hasWrittenBOM) {\n chunks.push(this.options.BOM || \"\\ufeff\");\n this.hasWrittenBOM = true;\n }\n\n const formattedRows = this.rowFormatter.format(row);\n chunks.push(...formattedRows);\n\n return chunks.join(\"\");\n }\n}\n\n/**\n * Create a CSV formatter with the given options.\n */\nexport function createCsvFormatter(\n options?: CsvFormatterOptions,\n): CsvFormatter {\n return new CsvFormatter(options);\n}\n"],"mappings":";;;;;;;;;;;AAaA,IAAa,eAAb,MAA0B;CACxB,AAAQ;CACR,AAAQ;CACR,AAAQ,gBAAgB;CAExB,YAAY,UAA+B,EAAE,EAAE;AAC7C,OAAK,UAAU;GACb,YAAY;GACZ,WAAW;GACX,cAAc;GACd,OAAO;GACP,QAAQ;GACR,cAAc;GACd,cAAc;GACd,SAAS;GACT,cAAc;GACd,wBAAwB;GACxB,WAAW;GACX,UAAU;GACV,KAAK;GACL,oBAAoB;GACpB,GAAG;GACJ;AAGD,MAAI,OAAO,KAAK,QAAQ,WAAW,SACjC,MAAK,QAAQ,SACX,KAAK,QAAQ,UAAU,OAAO,OAAO,KAAK,QAAQ;AAItD,MAAI,OAAO,KAAK,QAAQ,iBAAiB,YACvC,MAAK,QAAQ,eAAe,KAAK,QAAQ;AAI3C,MAAI,KAAK,QAAQ,UAAU,KACzB,MAAK,QAAQ,QAAQ;WACZ,KAAK,QAAQ,UAAU,MAChC,MAAK,QAAQ,QAAQ;AAGvB,OAAK,eAAe,IAAIA,mCAAa,KAAK,QAAQ;AAClD,OAAK,gBAAgB,CAAC,KAAK,QAAQ;;;;;CAMrC,OAAO,MAAyB;EAC9B,MAAM,SAAmB,EAAE;AAG3B,MAAI,CAAC,KAAK,eAAe;AACvB,UAAO,KAAK,KAAK,QAAQ,OAAO,IAAS;AACzC,QAAK,gBAAgB;;AAIvB,OAAK,MAAM,OAAO,MAAM;GACtB,MAAM,gBAAgB,KAAK,aAAa,OAAO,IAAI;AACnD,UAAO,KAAK,GAAG,cAAc;;EAI/B,MAAM,aAAa,KAAK,aAAa,QAAQ;AAC7C,SAAO,KAAK,GAAG,WAAW;AAE1B,SAAO,OAAO,KAAK,GAAG;;;;;CAMxB,UAAU,KAAsB;EAC9B,MAAM,SAAmB,EAAE;AAG3B,MAAI,CAAC,KAAK,eAAe;AACvB,UAAO,KAAK,KAAK,QAAQ,OAAO,IAAS;AACzC,QAAK,gBAAgB;;EAGvB,MAAM,gBAAgB,KAAK,aAAa,OAAO,IAAI;AACnD,SAAO,KAAK,GAAG,cAAc;AAE7B,SAAO,OAAO,KAAK,GAAG;;;;;;AAO1B,SAAgB,mBACd,SACc;AACd,QAAO,IAAI,aAAa,QAAQ"}
@@ -0,0 +1,76 @@
1
+
2
+ //#region src/encoder/csv/field-formatter.ts
3
+ /**
4
+ * Escape special regex characters in a string.
5
+ */
6
+ function escapeRegExp(str) {
7
+ return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
8
+ }
9
+ /**
10
+ * Handles formatting of individual CSV fields including quoting and escaping.
11
+ *
12
+ * This implementation is derived from @fast-csv/format (https://github.com/C2FO/fast-csv)
13
+ * Copyright (c) 2011 C2FO Labs, LLC
14
+ * Licensed under the MIT License
15
+ */
16
+ var FieldFormatter = class {
17
+ options;
18
+ _headers = null;
19
+ quoteReplaceRegExp;
20
+ escapePatternRegExp;
21
+ constructor(options) {
22
+ this.options = options;
23
+ if (Array.isArray(options.headers)) this._headers = options.headers;
24
+ else this._headers = null;
25
+ const quote = options.quote === true ? "\"" : options.quote === false ? "" : options.quote ?? "\"";
26
+ this.quoteReplaceRegExp = new RegExp(quote, "g");
27
+ const escapePattern = `[${escapeRegExp(options.delimiter ?? ",")}${escapeRegExp(options.rowDelimiter ?? "\n")}|\r|\n]`;
28
+ this.escapePatternRegExp = new RegExp(escapePattern);
29
+ }
30
+ get headers() {
31
+ return this._headers;
32
+ }
33
+ set headers(headers) {
34
+ this._headers = headers;
35
+ }
36
+ /**
37
+ * Escape special regex characters in a string.
38
+ */
39
+ #escapeRegExpString(str) {
40
+ return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
41
+ }
42
+ /**
43
+ * Determine if a field should be quoted.
44
+ */
45
+ shouldQuote(fieldIndex, isHeader) {
46
+ const quoteConfig = isHeader ? this.options.quoteHeaders : this.options.quoteColumns;
47
+ if (typeof quoteConfig === "boolean") return quoteConfig;
48
+ if (Array.isArray(quoteConfig)) return quoteConfig[fieldIndex] === true;
49
+ if (this._headers !== null && typeof quoteConfig === "object") return quoteConfig[this._headers[fieldIndex]] === true;
50
+ return false;
51
+ }
52
+ /**
53
+ * Format a single field value.
54
+ */
55
+ format(field, fieldIndex, isHeader) {
56
+ const quote = this.options.quote === true ? "\"" : this.options.quote === false ? "" : this.options.quote ?? "\"";
57
+ const escape = this.options.escape ?? quote;
58
+ const preparedField = `${field == null ? "" : field}`.replace(/\0/g, "");
59
+ if (quote !== "") {
60
+ if (preparedField.indexOf(quote) !== -1) return this.quoteField(preparedField.replace(this.quoteReplaceRegExp, `${escape}${quote}`));
61
+ }
62
+ if (preparedField.search(this.escapePatternRegExp) !== -1 || this.shouldQuote(fieldIndex, isHeader)) return this.quoteField(preparedField);
63
+ return preparedField;
64
+ }
65
+ /**
66
+ * Quote a field value.
67
+ */
68
+ quoteField(field) {
69
+ const quote = this.options.quote === true ? "\"" : this.options.quote === false ? "" : this.options.quote ?? "\"";
70
+ return `${quote}${field}${quote}`;
71
+ }
72
+ };
73
+
74
+ //#endregion
75
+ exports.FieldFormatter = FieldFormatter;
76
+ //# sourceMappingURL=field-formatter.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field-formatter.cjs","names":[],"sources":["../../../../src/encoder/csv/field-formatter.ts"],"sourcesContent":["import type { CsvFormatterOptions } from \"./csv-options\";\n\n/**\n * Escape special regex characters in a string.\n */\nfunction escapeRegExp(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * Handles formatting of individual CSV fields including quoting and escaping.\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 FieldFormatter {\n private options: CsvFormatterOptions;\n private _headers: string[] | null = null;\n private quoteReplaceRegExp: RegExp;\n private escapePatternRegExp: RegExp;\n\n constructor(options: CsvFormatterOptions) {\n this.options = options;\n\n if (Array.isArray(options.headers)) {\n this._headers = options.headers;\n } else {\n this._headers = null;\n }\n\n const quote =\n options.quote === true\n ? '\"'\n : options.quote === false\n ? \"\"\n : (options.quote ?? '\"');\n this.quoteReplaceRegExp = new RegExp(quote, \"g\");\n\n // Use lodash.escapeRegExp pattern for delimiter and row delimiter\n const escapePattern = `[${escapeRegExp(options.delimiter ?? \",\")}${escapeRegExp(options.rowDelimiter ?? \"\\n\")}|\\r|\\n]`;\n this.escapePatternRegExp = new RegExp(escapePattern);\n }\n\n get headers(): string[] | null {\n return this._headers;\n }\n\n set headers(headers: string[] | null) {\n this._headers = headers;\n }\n\n /**\n * Escape special regex characters in a string.\n */\n #escapeRegExpString(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n }\n\n /**\n * Determine if a field should be quoted.\n */\n private shouldQuote(fieldIndex: number, isHeader: boolean): boolean {\n const quoteConfig = isHeader\n ? this.options.quoteHeaders\n : this.options.quoteColumns;\n\n if (typeof quoteConfig === \"boolean\") {\n return quoteConfig;\n }\n\n if (Array.isArray(quoteConfig)) {\n return quoteConfig[fieldIndex] === true;\n }\n\n if (this._headers !== null && typeof quoteConfig === \"object\") {\n return quoteConfig[this._headers[fieldIndex]] === true;\n }\n\n return false;\n }\n\n /**\n * Format a single field value.\n */\n format(field: unknown, fieldIndex: number, isHeader: boolean): string {\n const quote =\n this.options.quote === true\n ? '\"'\n : this.options.quote === false\n ? \"\"\n : (this.options.quote ?? '\"');\n const escape = this.options.escape ?? quote;\n\n // Convert to string, handle null/undefined\n const preparedField = `${field == null ? \"\" : field}`.replace(/\\0/g, \"\");\n\n // Handle quote escaping\n if (quote !== \"\") {\n const shouldEscape = preparedField.indexOf(quote) !== -1;\n if (shouldEscape) {\n return this.quoteField(\n preparedField.replace(this.quoteReplaceRegExp, `${escape}${quote}`),\n );\n }\n }\n\n // Check if field needs quoting (contains delimiter, row delimiter, etc.)\n const hasEscapeCharacters =\n preparedField.search(this.escapePatternRegExp) !== -1;\n if (hasEscapeCharacters || this.shouldQuote(fieldIndex, isHeader)) {\n return this.quoteField(preparedField);\n }\n\n return preparedField;\n }\n\n /**\n * Quote a field value.\n */\n private quoteField(field: string): string {\n const quote =\n this.options.quote === true\n ? '\"'\n : this.options.quote === false\n ? \"\"\n : (this.options.quote ?? '\"');\n return `${quote}${field}${quote}`;\n }\n}\n"],"mappings":";;;;;AAKA,SAAS,aAAa,KAAqB;AACzC,QAAO,IAAI,QAAQ,uBAAuB,OAAO;;;;;;;;;AAUnD,IAAa,iBAAb,MAA4B;CAC1B,AAAQ;CACR,AAAQ,WAA4B;CACpC,AAAQ;CACR,AAAQ;CAER,YAAY,SAA8B;AACxC,OAAK,UAAU;AAEf,MAAI,MAAM,QAAQ,QAAQ,QAAQ,CAChC,MAAK,WAAW,QAAQ;MAExB,MAAK,WAAW;EAGlB,MAAM,QACJ,QAAQ,UAAU,OACd,OACA,QAAQ,UAAU,QAChB,KACC,QAAQ,SAAS;AAC1B,OAAK,qBAAqB,IAAI,OAAO,OAAO,IAAI;EAGhD,MAAM,gBAAgB,IAAI,aAAa,QAAQ,aAAa,IAAI,GAAG,aAAa,QAAQ,gBAAgB,KAAK,CAAC;AAC9G,OAAK,sBAAsB,IAAI,OAAO,cAAc;;CAGtD,IAAI,UAA2B;AAC7B,SAAO,KAAK;;CAGd,IAAI,QAAQ,SAA0B;AACpC,OAAK,WAAW;;;;;CAMlB,oBAAoB,KAAqB;AACvC,SAAO,IAAI,QAAQ,uBAAuB,OAAO;;;;;CAMnD,AAAQ,YAAY,YAAoB,UAA4B;EAClE,MAAM,cAAc,WAChB,KAAK,QAAQ,eACb,KAAK,QAAQ;AAEjB,MAAI,OAAO,gBAAgB,UACzB,QAAO;AAGT,MAAI,MAAM,QAAQ,YAAY,CAC5B,QAAO,YAAY,gBAAgB;AAGrC,MAAI,KAAK,aAAa,QAAQ,OAAO,gBAAgB,SACnD,QAAO,YAAY,KAAK,SAAS,iBAAiB;AAGpD,SAAO;;;;;CAMT,OAAO,OAAgB,YAAoB,UAA2B;EACpE,MAAM,QACJ,KAAK,QAAQ,UAAU,OACnB,OACA,KAAK,QAAQ,UAAU,QACrB,KACC,KAAK,QAAQ,SAAS;EAC/B,MAAM,SAAS,KAAK,QAAQ,UAAU;EAGtC,MAAM,gBAAgB,GAAG,SAAS,OAAO,KAAK,QAAQ,QAAQ,OAAO,GAAG;AAGxE,MAAI,UAAU,IAEZ;OADqB,cAAc,QAAQ,MAAM,KAAK,GAEpD,QAAO,KAAK,WACV,cAAc,QAAQ,KAAK,oBAAoB,GAAG,SAAS,QAAQ,CACpE;;AAOL,MADE,cAAc,OAAO,KAAK,oBAAoB,KAAK,MAC1B,KAAK,YAAY,YAAY,SAAS,CAC/D,QAAO,KAAK,WAAW,cAAc;AAGvC,SAAO;;;;;CAMT,AAAQ,WAAW,OAAuB;EACxC,MAAM,QACJ,KAAK,QAAQ,UAAU,OACnB,OACA,KAAK,QAAQ,UAAU,QACrB,KACC,KAAK,QAAQ,SAAS;AAC/B,SAAO,GAAG,QAAQ,QAAQ"}