@lumeweb/pinner 0.0.1 → 0.1.1

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 (200) hide show
  1. package/LICENSE +9 -0
  2. package/README.md +707 -28
  3. package/dist/cjs/_virtual/rolldown_runtime.cjs +29 -0
  4. package/dist/cjs/adapters/pinata/index.cjs +6 -0
  5. package/dist/cjs/adapters/pinata/legacy/adapter.cjs +83 -0
  6. package/dist/cjs/adapters/pinata/legacy/adapter.cjs.map +1 -0
  7. package/dist/cjs/adapters/pinata/legacy/adapter.d.cts +74 -0
  8. package/dist/cjs/adapters/pinata/legacy/index.cjs +1 -0
  9. package/dist/cjs/adapters/pinata/shared/index.cjs +1 -0
  10. package/dist/cjs/adapters/pinata/shared/types.d.cts +218 -0
  11. package/dist/cjs/adapters/pinata/shared/utils.cjs +83 -0
  12. package/dist/cjs/adapters/pinata/shared/utils.cjs.map +1 -0
  13. package/dist/cjs/adapters/pinata/v2/adapter-interface.d.cts +198 -0
  14. package/dist/cjs/adapters/pinata/v2/adapter.cjs +636 -0
  15. package/dist/cjs/adapters/pinata/v2/adapter.cjs.map +1 -0
  16. package/dist/cjs/adapters/pinata/v2/adapter.d.cts +17 -0
  17. package/dist/cjs/adapters/pinata/v2/index.cjs +1 -0
  18. package/dist/cjs/adapters/pinata/v2/types.d.cts +308 -0
  19. package/dist/cjs/blockstore/index.cjs +2 -0
  20. package/dist/cjs/blockstore/unstorage-base.cjs +240 -0
  21. package/dist/cjs/blockstore/unstorage-base.cjs.map +1 -0
  22. package/dist/cjs/blockstore/unstorage-base.d.cts +23 -0
  23. package/dist/cjs/blockstore/unstorage.cjs +39 -0
  24. package/dist/cjs/blockstore/unstorage.cjs.map +1 -0
  25. package/dist/cjs/blockstore/unstorage.d.cts +36 -0
  26. package/dist/cjs/config.d.cts +51 -0
  27. package/dist/cjs/encoder/base64.cjs +38 -0
  28. package/dist/cjs/encoder/base64.cjs.map +1 -0
  29. package/dist/cjs/encoder/csv/csv-formatter.cjs +81 -0
  30. package/dist/cjs/encoder/csv/csv-formatter.cjs.map +1 -0
  31. package/dist/cjs/encoder/csv/field-formatter.cjs +76 -0
  32. package/dist/cjs/encoder/csv/field-formatter.cjs.map +1 -0
  33. package/dist/cjs/encoder/csv/row-formatter.cjs +159 -0
  34. package/dist/cjs/encoder/csv/row-formatter.cjs.map +1 -0
  35. package/dist/cjs/encoder/csv.cjs +44 -0
  36. package/dist/cjs/encoder/csv.cjs.map +1 -0
  37. package/dist/cjs/encoder/error.cjs +19 -0
  38. package/dist/cjs/encoder/error.cjs.map +1 -0
  39. package/dist/cjs/encoder/index.cjs +6 -0
  40. package/dist/cjs/encoder/json.cjs +36 -0
  41. package/dist/cjs/encoder/json.cjs.map +1 -0
  42. package/dist/cjs/encoder/text.cjs +35 -0
  43. package/dist/cjs/encoder/text.cjs.map +1 -0
  44. package/dist/cjs/encoder/url.cjs +39 -0
  45. package/dist/cjs/encoder/url.cjs.map +1 -0
  46. package/dist/cjs/errors/index.cjs +104 -0
  47. package/dist/cjs/errors/index.cjs.map +1 -0
  48. package/dist/cjs/errors/index.d.cts +47 -0
  49. package/dist/cjs/index.cjs +44 -0
  50. package/dist/cjs/index.d.cts +16 -0
  51. package/dist/cjs/pin/client.cjs +98 -0
  52. package/dist/cjs/pin/client.cjs.map +1 -0
  53. package/dist/cjs/pin/index.cjs +1 -0
  54. package/dist/cjs/pinner.cjs +132 -0
  55. package/dist/cjs/pinner.cjs.map +1 -0
  56. package/dist/cjs/pinner.d.cts +81 -0
  57. package/dist/cjs/types/constants.cjs +39 -0
  58. package/dist/cjs/types/constants.cjs.map +1 -0
  59. package/dist/cjs/types/mime-types.cjs +11 -0
  60. package/dist/cjs/types/mime-types.cjs.map +1 -0
  61. package/dist/cjs/types/mime-types.d.cts +7 -0
  62. package/dist/cjs/types/pin.d.cts +78 -0
  63. package/dist/cjs/types/type-guards.cjs +20 -0
  64. package/dist/cjs/types/type-guards.cjs.map +1 -0
  65. package/dist/cjs/types/type-guards.d.cts +15 -0
  66. package/dist/cjs/types/upload.cjs +18 -0
  67. package/dist/cjs/types/upload.cjs.map +1 -0
  68. package/dist/cjs/types/upload.d.cts +189 -0
  69. package/dist/cjs/upload/base-upload.cjs +135 -0
  70. package/dist/cjs/upload/base-upload.cjs.map +1 -0
  71. package/dist/cjs/upload/builder.cjs +174 -0
  72. package/dist/cjs/upload/builder.cjs.map +1 -0
  73. package/dist/cjs/upload/builder.d.cts +60 -0
  74. package/dist/cjs/upload/car.cjs +129 -0
  75. package/dist/cjs/upload/car.cjs.map +1 -0
  76. package/dist/cjs/upload/car.d.cts +19 -0
  77. package/dist/cjs/upload/constants.cjs +9 -0
  78. package/dist/cjs/upload/constants.cjs.map +1 -0
  79. package/dist/cjs/upload/index.cjs +8 -0
  80. package/dist/cjs/upload/manager.cjs +249 -0
  81. package/dist/cjs/upload/manager.cjs.map +1 -0
  82. package/dist/cjs/upload/manager.d.cts +35 -0
  83. package/dist/cjs/upload/normalize.cjs +28 -0
  84. package/dist/cjs/upload/normalize.cjs.map +1 -0
  85. package/dist/cjs/upload/tus-upload.cjs +74 -0
  86. package/dist/cjs/upload/tus-upload.cjs.map +1 -0
  87. package/dist/cjs/upload/xhr-upload.cjs +41 -0
  88. package/dist/cjs/upload/xhr-upload.cjs.map +1 -0
  89. package/dist/cjs/utils/env.cjs +12 -0
  90. package/dist/cjs/utils/env.cjs.map +1 -0
  91. package/dist/cjs/utils/stream.cjs +141 -0
  92. package/dist/cjs/utils/stream.cjs.map +1 -0
  93. package/dist/cjs/utils/stream.d.cts +23 -0
  94. package/dist/cjs/utils/tus-patch.cjs +50 -0
  95. package/dist/cjs/utils/tus-patch.cjs.map +1 -0
  96. package/dist/cjs/utils/validation.cjs +62 -0
  97. package/dist/cjs/utils/validation.cjs.map +1 -0
  98. package/dist/esm/_virtual/rolldown_runtime.js +8 -0
  99. package/dist/esm/adapters/pinata/index.d.ts +7 -0
  100. package/dist/esm/adapters/pinata/index.js +6 -0
  101. package/dist/esm/adapters/pinata/legacy/adapter.d.ts +74 -0
  102. package/dist/esm/adapters/pinata/legacy/adapter.js +83 -0
  103. package/dist/esm/adapters/pinata/legacy/adapter.js.map +1 -0
  104. package/dist/esm/adapters/pinata/legacy/index.d.ts +1 -0
  105. package/dist/esm/adapters/pinata/legacy/index.js +1 -0
  106. package/dist/esm/adapters/pinata/shared/index.d.ts +2 -0
  107. package/dist/esm/adapters/pinata/shared/index.js +1 -0
  108. package/dist/esm/adapters/pinata/shared/types.d.ts +218 -0
  109. package/dist/esm/adapters/pinata/shared/utils.d.ts +1 -0
  110. package/dist/esm/adapters/pinata/shared/utils.js +78 -0
  111. package/dist/esm/adapters/pinata/shared/utils.js.map +1 -0
  112. package/dist/esm/adapters/pinata/v2/adapter-interface.d.ts +198 -0
  113. package/dist/esm/adapters/pinata/v2/adapter.d.ts +17 -0
  114. package/dist/esm/adapters/pinata/v2/adapter.js +636 -0
  115. package/dist/esm/adapters/pinata/v2/adapter.js.map +1 -0
  116. package/dist/esm/adapters/pinata/v2/index.d.ts +3 -0
  117. package/dist/esm/adapters/pinata/v2/index.js +1 -0
  118. package/dist/esm/adapters/pinata/v2/types.d.ts +308 -0
  119. package/dist/esm/blockstore/index.d.ts +2 -0
  120. package/dist/esm/blockstore/index.js +2 -0
  121. package/dist/esm/blockstore/unstorage-base.d.ts +23 -0
  122. package/dist/esm/blockstore/unstorage-base.js +231 -0
  123. package/dist/esm/blockstore/unstorage-base.js.map +1 -0
  124. package/dist/esm/blockstore/unstorage.d.ts +36 -0
  125. package/dist/esm/blockstore/unstorage.js +38 -0
  126. package/dist/esm/blockstore/unstorage.js.map +1 -0
  127. package/dist/esm/config.d.ts +51 -0
  128. package/dist/esm/encoder/base64.js +37 -0
  129. package/dist/esm/encoder/base64.js.map +1 -0
  130. package/dist/esm/encoder/csv/csv-formatter.js +81 -0
  131. package/dist/esm/encoder/csv/csv-formatter.js.map +1 -0
  132. package/dist/esm/encoder/csv/field-formatter.js +75 -0
  133. package/dist/esm/encoder/csv/field-formatter.js.map +1 -0
  134. package/dist/esm/encoder/csv/row-formatter.js +159 -0
  135. package/dist/esm/encoder/csv/row-formatter.js.map +1 -0
  136. package/dist/esm/encoder/csv.js +43 -0
  137. package/dist/esm/encoder/csv.js.map +1 -0
  138. package/dist/esm/encoder/error.js +18 -0
  139. package/dist/esm/encoder/error.js.map +1 -0
  140. package/dist/esm/encoder/index.js +6 -0
  141. package/dist/esm/encoder/json.js +35 -0
  142. package/dist/esm/encoder/json.js.map +1 -0
  143. package/dist/esm/encoder/text.js +34 -0
  144. package/dist/esm/encoder/text.js.map +1 -0
  145. package/dist/esm/encoder/url.js +36 -0
  146. package/dist/esm/encoder/url.js.map +1 -0
  147. package/dist/esm/errors/index.d.ts +47 -0
  148. package/dist/esm/errors/index.js +93 -0
  149. package/dist/esm/errors/index.js.map +1 -0
  150. package/dist/esm/index.d.ts +18 -0
  151. package/dist/esm/index.js +15 -0
  152. package/dist/esm/pin/client.js +97 -0
  153. package/dist/esm/pin/client.js.map +1 -0
  154. package/dist/esm/pin/index.js +1 -0
  155. package/dist/esm/pinner.d.ts +81 -0
  156. package/dist/esm/pinner.js +131 -0
  157. package/dist/esm/pinner.js.map +1 -0
  158. package/dist/esm/types/constants.js +33 -0
  159. package/dist/esm/types/constants.js.map +1 -0
  160. package/dist/esm/types/mime-types.d.ts +7 -0
  161. package/dist/esm/types/mime-types.js +8 -0
  162. package/dist/esm/types/mime-types.js.map +1 -0
  163. package/dist/esm/types/pin.d.ts +78 -0
  164. package/dist/esm/types/type-guards.d.ts +15 -0
  165. package/dist/esm/types/type-guards.js +19 -0
  166. package/dist/esm/types/type-guards.js.map +1 -0
  167. package/dist/esm/types/upload.d.ts +189 -0
  168. package/dist/esm/types/upload.js +16 -0
  169. package/dist/esm/types/upload.js.map +1 -0
  170. package/dist/esm/upload/base-upload.js +132 -0
  171. package/dist/esm/upload/base-upload.js.map +1 -0
  172. package/dist/esm/upload/builder.d.ts +60 -0
  173. package/dist/esm/upload/builder.js +173 -0
  174. package/dist/esm/upload/builder.js.map +1 -0
  175. package/dist/esm/upload/car.d.ts +19 -0
  176. package/dist/esm/upload/car.js +125 -0
  177. package/dist/esm/upload/car.js.map +1 -0
  178. package/dist/esm/upload/constants.js +7 -0
  179. package/dist/esm/upload/constants.js.map +1 -0
  180. package/dist/esm/upload/index.js +8 -0
  181. package/dist/esm/upload/manager.d.ts +35 -0
  182. package/dist/esm/upload/manager.js +248 -0
  183. package/dist/esm/upload/manager.js.map +1 -0
  184. package/dist/esm/upload/normalize.js +28 -0
  185. package/dist/esm/upload/normalize.js.map +1 -0
  186. package/dist/esm/upload/tus-upload.js +72 -0
  187. package/dist/esm/upload/tus-upload.js.map +1 -0
  188. package/dist/esm/upload/xhr-upload.js +39 -0
  189. package/dist/esm/upload/xhr-upload.js.map +1 -0
  190. package/dist/esm/utils/env.js +11 -0
  191. package/dist/esm/utils/env.js.map +1 -0
  192. package/dist/esm/utils/stream.d.ts +23 -0
  193. package/dist/esm/utils/stream.js +134 -0
  194. package/dist/esm/utils/stream.js.map +1 -0
  195. package/dist/esm/utils/tus-patch.js +51 -0
  196. package/dist/esm/utils/tus-patch.js.map +1 -0
  197. package/dist/esm/utils/validation.js +60 -0
  198. package/dist/esm/utils/validation.js.map +1 -0
  199. package/package.json +95 -8
  200. package/public/mockServiceWorker.js +349 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream.cjs","names":["isNodeEnvironment"],"sources":["../../../src/utils/stream.ts"],"sourcesContent":["import type { AwaitIterable } from \"interface-store\";\nimport { isNodeEnvironment } from \"./env\";\n\n/**\n * Convert a ReadableStream to a Blob.\n */\nexport async function streamToBlob(\n stream: ReadableStream<Uint8Array>,\n mimeType: string,\n): Promise<Blob> {\n const chunks: Uint8Array[] = [];\n const reader = stream.getReader();\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n }\n\n return new Blob(chunks as any, { type: mimeType });\n}\n\n/**\n * Calculate the total size of a ReadableStream by consuming it.\n */\nexport async function calculateStreamSize(\n stream: ReadableStream<Uint8Array>,\n signal?: AbortSignal,\n): Promise<bigint> {\n let size = 0n;\n const reader = stream.getReader();\n\n while (true) {\n if (signal?.aborted) {\n throw new Error(\"Aborted\");\n }\n\n const { done, value } = await reader.read();\n if (done) break;\n size += BigInt(value.length);\n }\n\n return size;\n}\n\n/**\n * Convert an async generator to a ReadableStream.\n */\nexport function asyncGeneratorToReadableStream<T>(\n generator: AsyncGenerator<T>,\n): ReadableStream<T> {\n return new ReadableStream({\n async start(controller) {\n try {\n for await (const item of generator) {\n controller.enqueue(item);\n }\n controller.close();\n } catch (error) {\n controller.error(error);\n }\n },\n });\n}\n\n/**\n * Convert a ReadableStream to an async iterable.\n */\nexport async function* readableStreamToAsyncIterable<T>(\n stream: ReadableStream<T>,\n): AsyncIterable<T> {\n const reader = stream.getReader();\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n yield value;\n }\n } finally {\n reader.releaseLock();\n }\n}\n\n/**\n * Convert a web ReadableStream to a Node.js stream.Readable\n * This is needed for Node.js environments where tus-js-client expects Node streams.\n */\nexport async function readableStreamToNodeStream(\n stream: ReadableStream<Uint8Array>,\n): Promise<import(\"stream\").Readable> {\n if (!isNodeEnvironment()) {\n throw new Error(\n \"readableStreamToNodeStream can only be used in Node.js environment\",\n );\n }\n\n const { Readable } = await import(\"stream\");\n\n // Create a single reader for the entire stream lifecycle\n // The read() method is called multiple times by Node.js, so we cannot\n // call getReader() inside it - that would create multiple readers and\n // cause \"ReadableStream is locked\" errors\n const reader = stream.getReader();\n\n return new Readable({\n async read() {\n try {\n const { done, value } = await reader.read();\n if (done) {\n reader.releaseLock();\n this.push(null);\n } else {\n this.push(Buffer.from(value));\n }\n } catch (error) {\n reader.releaseLock();\n this.destroy(error as Error);\n }\n },\n\n // Ensure reader is released if stream is destroyed\n destroy(error, callback) {\n try {\n reader.releaseLock();\n } catch (e) {\n // Ignore errors during cleanup\n }\n if (callback) callback(error);\n },\n });\n}\n\n/**\n * Convert a ReadableStream to a Blob using the Response API.\n * This is the preferred method in browser environments as it's built-in and efficient.\n */\nexport async function streamToBlobViaResponse(\n stream: ReadableStream<Uint8Array>,\n): Promise<Blob> {\n return new Response(stream).blob();\n}\n\n/**\n * Convert a File to a ReadableStream of Uint8Array without loading entire blob into memory.\n * This streams the file content chunk by chunk.\n */\nexport function fileToReadableStream(file: File): ReadableStream<Uint8Array> {\n return new ReadableStream<Uint8Array>({\n async start(controller) {\n try {\n const reader = (file as any).stream().getReader();\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n controller.close();\n break;\n }\n controller.enqueue(value);\n }\n } catch (error) {\n controller.error(error);\n }\n },\n });\n}\n\n/**\n * Collect all chunks from an async iterable or iterable into a single Uint8Array.\n */\nexport async function collectAsyncIterable(\n iterable: AwaitIterable<Uint8Array>,\n): Promise<Uint8Array> {\n const chunks: Uint8Array[] = [];\n for await (const chunk of iterable) {\n chunks.push(chunk);\n }\n\n const totalLength = chunks.reduce((acc, chunk) => acc + chunk.length, 0);\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const chunk of chunks) {\n result.set(chunk, offset);\n offset += chunk.length;\n }\n\n return result;\n}\n"],"mappings":";;;;;;AAMA,eAAsB,aACpB,QACA,UACe;CACf,MAAM,SAAuB,EAAE;CAC/B,MAAM,SAAS,OAAO,WAAW;AAEjC,QAAO,MAAM;EACX,MAAM,EAAE,MAAM,UAAU,MAAM,OAAO,MAAM;AAC3C,MAAI,KAAM;AACV,SAAO,KAAK,MAAM;;AAGpB,QAAO,IAAI,KAAK,QAAe,EAAE,MAAM,UAAU,CAAC;;;;;AAMpD,eAAsB,oBACpB,QACA,QACiB;CACjB,IAAI,OAAO;CACX,MAAM,SAAS,OAAO,WAAW;AAEjC,QAAO,MAAM;AACX,MAAI,QAAQ,QACV,OAAM,IAAI,MAAM,UAAU;EAG5B,MAAM,EAAE,MAAM,UAAU,MAAM,OAAO,MAAM;AAC3C,MAAI,KAAM;AACV,UAAQ,OAAO,MAAM,OAAO;;AAG9B,QAAO;;;;;AAMT,SAAgB,+BACd,WACmB;AACnB,QAAO,IAAI,eAAe,EACxB,MAAM,MAAM,YAAY;AACtB,MAAI;AACF,cAAW,MAAM,QAAQ,UACvB,YAAW,QAAQ,KAAK;AAE1B,cAAW,OAAO;WACX,OAAO;AACd,cAAW,MAAM,MAAM;;IAG5B,CAAC;;;;;AAMJ,gBAAuB,8BACrB,QACkB;CAClB,MAAM,SAAS,OAAO,WAAW;AAEjC,KAAI;AACF,SAAO,MAAM;GACX,MAAM,EAAE,MAAM,UAAU,MAAM,OAAO,MAAM;AAC3C,OAAI,KAAM;AACV,SAAM;;WAEA;AACR,SAAO,aAAa;;;;;;;AAQxB,eAAsB,2BACpB,QACoC;AACpC,KAAI,CAACA,+BAAmB,CACtB,OAAM,IAAI,MACR,qEACD;CAGH,MAAM,EAAE,aAAa,MAAM,OAAO;CAMlC,MAAM,SAAS,OAAO,WAAW;AAEjC,QAAO,IAAI,SAAS;EAClB,MAAM,OAAO;AACX,OAAI;IACF,MAAM,EAAE,MAAM,UAAU,MAAM,OAAO,MAAM;AAC3C,QAAI,MAAM;AACR,YAAO,aAAa;AACpB,UAAK,KAAK,KAAK;UAEf,MAAK,KAAK,OAAO,KAAK,MAAM,CAAC;YAExB,OAAO;AACd,WAAO,aAAa;AACpB,SAAK,QAAQ,MAAe;;;EAKhC,QAAQ,OAAO,UAAU;AACvB,OAAI;AACF,WAAO,aAAa;YACb,GAAG;AAGZ,OAAI,SAAU,UAAS,MAAM;;EAEhC,CAAC;;;;;;AAOJ,eAAsB,wBACpB,QACe;AACf,QAAO,IAAI,SAAS,OAAO,CAAC,MAAM;;;;;;AAOpC,SAAgB,qBAAqB,MAAwC;AAC3E,QAAO,IAAI,eAA2B,EACpC,MAAM,MAAM,YAAY;AACtB,MAAI;GACF,MAAM,SAAU,KAAa,QAAQ,CAAC,WAAW;AAEjD,UAAO,MAAM;IACX,MAAM,EAAE,MAAM,UAAU,MAAM,OAAO,MAAM;AAC3C,QAAI,MAAM;AACR,gBAAW,OAAO;AAClB;;AAEF,eAAW,QAAQ,MAAM;;WAEpB,OAAO;AACd,cAAW,MAAM,MAAM;;IAG5B,CAAC;;;;;AAMJ,eAAsB,qBACpB,UACqB;CACrB,MAAM,SAAuB,EAAE;AAC/B,YAAW,MAAM,SAAS,SACxB,QAAO,KAAK,MAAM;CAGpB,MAAM,cAAc,OAAO,QAAQ,KAAK,UAAU,MAAM,MAAM,QAAQ,EAAE;CACxE,MAAM,SAAS,IAAI,WAAW,YAAY;CAC1C,IAAI,SAAS;AACb,MAAK,MAAM,SAAS,QAAQ;AAC1B,SAAO,IAAI,OAAO,OAAO;AACzB,YAAU,MAAM;;AAGlB,QAAO"}
@@ -0,0 +1,23 @@
1
+ import "stream";
2
+
3
+ //#region src/utils/stream.d.ts
4
+
5
+ /**
6
+ * Convert a ReadableStream to a Blob.
7
+ */
8
+ declare function streamToBlob(stream: ReadableStream<Uint8Array>, mimeType: string): Promise<Blob>;
9
+ /**
10
+ * Calculate the total size of a ReadableStream by consuming it.
11
+ */
12
+ declare function calculateStreamSize(stream: ReadableStream<Uint8Array>, signal?: AbortSignal): Promise<bigint>;
13
+ /**
14
+ * Convert an async generator to a ReadableStream.
15
+ */
16
+ declare function asyncGeneratorToReadableStream<T>(generator: AsyncGenerator<T>): ReadableStream<T>;
17
+ /**
18
+ * Convert a ReadableStream to an async iterable.
19
+ */
20
+ declare function readableStreamToAsyncIterable<T>(stream: ReadableStream<T>): AsyncIterable<T>;
21
+ //#endregion
22
+ export { asyncGeneratorToReadableStream, calculateStreamSize, readableStreamToAsyncIterable, streamToBlob };
23
+ //# sourceMappingURL=stream.d.cts.map
@@ -0,0 +1,50 @@
1
+ const require_env = require('./env.cjs');
2
+
3
+ //#region src/utils/tus-patch.ts
4
+ /**
5
+ * Runtime patch for tus-js-client's NodeHttpStack Request class.
6
+ *
7
+ * PROBLEM:
8
+ * Code using onBeforeRequest hook may need to call abort() on the request
9
+ * before send() is called. However, the Request class only sets this._request
10
+ * inside the send() method, so getUnderlyingObject() returns null before send().
11
+ *
12
+ * SOLUTION:
13
+ * Patch the Request class to initialize a dummy _request object with an abort()
14
+ * method immediately when the request is created.
15
+ *
16
+ * NOTE:
17
+ * This patch is only needed in Node.js environments. In browser environments,
18
+ * the tus-js-client uses a different HTTP stack that doesn't have this issue.
19
+ */
20
+ function patchTusNodeHttpStack() {
21
+ if (!require_env.isNodeEnvironment()) return;
22
+ try {
23
+ const tusHttpStackModule = require("tus-js-client/lib.es5/node/httpStack");
24
+ if (!tusHttpStackModule || !tusHttpStackModule.default) {
25
+ console.warn("[tus-patch] tus-js-client NodeHttpStack not found, patch skipped");
26
+ return;
27
+ }
28
+ const NodeHttpStack = tusHttpStackModule.default;
29
+ const originalCreateRequest = NodeHttpStack.prototype.createRequest;
30
+ if (typeof originalCreateRequest !== "function") {
31
+ console.warn("[tus-patch] createRequest method not found, patch skipped");
32
+ return;
33
+ }
34
+ NodeHttpStack.prototype.createRequest = function(method, url) {
35
+ const request = originalCreateRequest.call(this, method, url);
36
+ request._request = {
37
+ abort: () => {},
38
+ destroyed: false
39
+ };
40
+ return request;
41
+ };
42
+ console.debug("[tus-patch] Successfully patched tus-js-client NodeHttpStack");
43
+ } catch (error) {
44
+ console.warn("[tus-patch] Failed to patch tus-js-client:", error);
45
+ }
46
+ }
47
+
48
+ //#endregion
49
+ exports.patchTusNodeHttpStack = patchTusNodeHttpStack;
50
+ //# sourceMappingURL=tus-patch.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tus-patch.cjs","names":["isNodeEnvironment"],"sources":["../../../src/utils/tus-patch.ts"],"sourcesContent":["/**\n * Runtime patch for tus-js-client's NodeHttpStack Request class.\n *\n * PROBLEM:\n * Code using onBeforeRequest hook may need to call abort() on the request\n * before send() is called. However, the Request class only sets this._request\n * inside the send() method, so getUnderlyingObject() returns null before send().\n *\n * SOLUTION:\n * Patch the Request class to initialize a dummy _request object with an abort()\n * method immediately when the request is created.\n *\n * NOTE:\n * This patch is only needed in Node.js environments. In browser environments,\n * the tus-js-client uses a different HTTP stack that doesn't have this issue.\n */\n\nimport { isNodeEnvironment } from \"./env\";\n\n// Track whether the patch has been applied to prevent multiple patches\nlet isPatched = false;\n\nexport function patchTusNodeHttpStack(): void {\n // Prevent multiple patches\n if (isPatched) {\n return;\n }\n\n // Only apply patch in Node.js environments\n if (!isNodeEnvironment()) {\n return;\n }\n\n // Find the tus-js-client NodeHttpStack module\n // It exports the default as NodeHttpStack with a nested Request class\n try {\n // Use dynamic require() to avoid bundling issues\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const tusHttpStackModule = require(\"tus-js-client/lib.es5/node/httpStack\");\n\n if (!tusHttpStackModule || !tusHttpStackModule.default) {\n console.warn(\n \"[tus-patch] tus-js-client NodeHttpStack not found, patch skipped\",\n );\n return;\n }\n\n const NodeHttpStack = tusHttpStackModule.default;\n\n // Get the original createRequest method\n const originalCreateRequest = NodeHttpStack.prototype.createRequest;\n\n if (typeof originalCreateRequest !== \"function\") {\n console.warn(\"[tus-patch] createRequest method not found, patch skipped\");\n return;\n }\n\n // Patch createRequest to set up a dummy _request on the Request instance\n NodeHttpStack.prototype.createRequest = function (\n method: string,\n url: string,\n ) {\n // Call the original createRequest to get the Request instance\n const request = originalCreateRequest.call(this, method, url);\n\n // Set a dummy _request object with an abort() method\n // This allows getUnderlyingObject().abort() to work before send() is called\n request._request = {\n abort: () => {\n // No-op abort before actual request is created\n // The real request will be created in send() and this will be replaced\n },\n // Preserve any existing properties that might be checked\n destroyed: false,\n };\n\n return request;\n };\n\n console.debug(\n \"[tus-patch] Successfully patched tus-js-client NodeHttpStack\",\n );\n } catch (error) {\n console.warn(\"[tus-patch] Failed to patch tus-js-client:\", error);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAsBA,SAAgB,wBAA8B;AAO5C,KAAI,CAACA,+BAAmB,CACtB;AAKF,KAAI;EAGF,MAAM,qBAAqB,QAAQ,uCAAuC;AAE1E,MAAI,CAAC,sBAAsB,CAAC,mBAAmB,SAAS;AACtD,WAAQ,KACN,mEACD;AACD;;EAGF,MAAM,gBAAgB,mBAAmB;EAGzC,MAAM,wBAAwB,cAAc,UAAU;AAEtD,MAAI,OAAO,0BAA0B,YAAY;AAC/C,WAAQ,KAAK,4DAA4D;AACzE;;AAIF,gBAAc,UAAU,gBAAgB,SACtC,QACA,KACA;GAEA,MAAM,UAAU,sBAAsB,KAAK,MAAM,QAAQ,IAAI;AAI7D,WAAQ,WAAW;IACjB,aAAa;IAKb,WAAW;IACZ;AAED,UAAO;;AAGT,UAAQ,MACN,+DACD;UACM,OAAO;AACd,UAAQ,KAAK,8CAA8C,MAAM"}
@@ -0,0 +1,62 @@
1
+ const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
2
+ const require_index = require('../errors/index.cjs');
3
+ let ipaddr_js = require("ipaddr.js");
4
+ ipaddr_js = require_rolldown_runtime.__toESM(ipaddr_js);
5
+
6
+ //#region src/utils/validation.ts
7
+ /**
8
+ * URL validation utilities to prevent SSRF and other security issues.
9
+ */
10
+ const BLOCKED_IPV4_RANGES = new Set([
11
+ "private",
12
+ "loopback",
13
+ "linkLocal",
14
+ "reserved",
15
+ "broadcast",
16
+ "carrierGradeNat",
17
+ "unspecified"
18
+ ]);
19
+ const BLOCKED_IPV6_RANGES = new Set([
20
+ "uniqueLocal",
21
+ "loopback",
22
+ "linkLocal",
23
+ "reserved",
24
+ "multicast",
25
+ "ipv4Mapped",
26
+ "unspecified"
27
+ ]);
28
+ /**
29
+ * Validates a URL string to ensure it's safe to fetch.
30
+ * Only allows HTTP/HTTPS protocols and validates the URL format.
31
+ *
32
+ * @param urlString - The URL string to validate
33
+ * @throws ValidationError if the URL is invalid or uses an unsafe protocol
34
+ */
35
+ function validateUrl(urlString) {
36
+ if (/\s/.test(urlString)) throw new require_index.ValidationError(`Invalid URL: contains whitespace characters`, "url");
37
+ try {
38
+ const url = new URL(urlString);
39
+ if (url.protocol !== "http:" && url.protocol !== "https:") throw new require_index.ValidationError(`Invalid URL protocol: ${url.protocol}. Only http: and https: are allowed.`, "url");
40
+ const hostname = url.hostname.toLowerCase();
41
+ if (hostname === "localhost") throw new require_index.ValidationError("Access to localhost addresses is not allowed", "url");
42
+ const cleanHostname = hostname.replace(/^\[|\]$/g, "");
43
+ if (ipaddr_js.default.isValid(cleanHostname)) {
44
+ const addr = ipaddr_js.default.parse(cleanHostname);
45
+ if (addr.kind() === "ipv4") {
46
+ const range = addr.range();
47
+ if (BLOCKED_IPV4_RANGES.has(range)) throw new require_index.ValidationError("Access to private IP addresses is not allowed", "url");
48
+ }
49
+ if (addr.kind() === "ipv6") {
50
+ const range = addr.range();
51
+ if (BLOCKED_IPV6_RANGES.has(range)) throw new require_index.ValidationError("Access to private IP addresses is not allowed", "url");
52
+ }
53
+ }
54
+ } catch (error) {
55
+ if (error instanceof require_index.ValidationError) throw error;
56
+ throw new require_index.ValidationError(`Invalid URL format: ${urlString}`, "url", error);
57
+ }
58
+ }
59
+
60
+ //#endregion
61
+ exports.validateUrl = validateUrl;
62
+ //# sourceMappingURL=validation.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.cjs","names":["ValidationError","ipaddr"],"sources":["../../../src/utils/validation.ts"],"sourcesContent":["/**\n * URL validation utilities to prevent SSRF and other security issues.\n */\n\nimport { ValidationError } from \"@/errors\";\nimport ipaddr from \"ipaddr.js\";\n\nexport { ValidationError };\n\n// IPv4 ranges to block\nconst BLOCKED_IPV4_RANGES = new Set([\n \"private\", // 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16\n \"loopback\", // 127.0.0.0/8\n \"linkLocal\", // 169.254.0.0/16\n \"reserved\",\n \"broadcast\",\n \"carrierGradeNat\", // 100.64.0.0/10\n \"unspecified\", // 0.0.0.0/8\n]);\n\n// IPv6 ranges to block\nconst BLOCKED_IPV6_RANGES = new Set([\n \"uniqueLocal\", // fc00::/7\n \"loopback\", // ::1\n \"linkLocal\", // fe80::/10\n \"reserved\",\n \"multicast\", // ff00::/8\n \"ipv4Mapped\", // ::ffff:0:0/96\n \"unspecified\", // ::\n]);\n\n/**\n * Validates a URL string to ensure it's safe to fetch.\n * Only allows HTTP/HTTPS protocols and validates the URL format.\n *\n * @param urlString - The URL string to validate\n * @throws ValidationError if the URL is invalid or uses an unsafe protocol\n */\nexport function validateUrl(urlString: string): void {\n // Reject URLs with spaces or other invalid characters that shouldn't be in URLs\n if (/\\s/.test(urlString)) {\n throw new ValidationError(\n `Invalid URL: contains whitespace characters`,\n \"url\",\n );\n }\n\n try {\n const url = new URL(urlString);\n\n // Only allow HTTP and HTTPS protocols\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") {\n throw new ValidationError(\n `Invalid URL protocol: ${url.protocol}. Only http: and https: are allowed.`,\n \"url\",\n );\n }\n\n const hostname = url.hostname.toLowerCase();\n\n // Block localhost (case-insensitive)\n if (hostname === \"localhost\") {\n throw new ValidationError(\n \"Access to localhost addresses is not allowed\",\n \"url\",\n );\n }\n\n // Strip brackets from IPv6 addresses for ipaddr.js\n const cleanHostname = hostname.replace(/^\\[|\\]$/g, \"\");\n\n // Block IP addresses using ipaddr.js\n // This library handles alternative notations (decimal, octal, hex)\n // and comprehensive private range detection for both IPv4 and IPv6\n if (ipaddr.isValid(cleanHostname)) {\n const addr = ipaddr.parse(cleanHostname);\n\n // Check for IPv4 private ranges\n if (addr.kind() === \"ipv4\") {\n const ipv4Addr = addr as ipaddr.IPv4;\n const range = ipv4Addr.range();\n\n if (BLOCKED_IPV4_RANGES.has(range)) {\n throw new ValidationError(\n \"Access to private IP addresses is not allowed\",\n \"url\",\n );\n }\n }\n\n // Check for IPv6 private ranges\n if (addr.kind() === \"ipv6\") {\n const ipv6Addr = addr as ipaddr.IPv6;\n const range = ipv6Addr.range();\n\n if (BLOCKED_IPV6_RANGES.has(range)) {\n throw new ValidationError(\n \"Access to private IP addresses is not allowed\",\n \"url\",\n );\n }\n }\n }\n } catch (error) {\n if (error instanceof ValidationError) {\n throw error;\n }\n throw new ValidationError(\n `Invalid URL format: ${urlString}`,\n \"url\",\n error as Error,\n );\n }\n}\n\n/**\n * Validates a URL and returns the parsed URL object if valid.\n *\n * @param urlString - The URL string to validate\n * @returns The parsed URL object\n * @throws ValidationError if the URL is invalid\n */\nexport function parseValidatedUrl(urlString: string): URL {\n validateUrl(urlString);\n return new URL(urlString);\n}\n"],"mappings":";;;;;;;;;AAUA,MAAM,sBAAsB,IAAI,IAAI;CAClC;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;AAGF,MAAM,sBAAsB,IAAI,IAAI;CAClC;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;;;;;;;;AASF,SAAgB,YAAY,WAAyB;AAEnD,KAAI,KAAK,KAAK,UAAU,CACtB,OAAM,IAAIA,8BACR,+CACA,MACD;AAGH,KAAI;EACF,MAAM,MAAM,IAAI,IAAI,UAAU;AAG9B,MAAI,IAAI,aAAa,WAAW,IAAI,aAAa,SAC/C,OAAM,IAAIA,8BACR,yBAAyB,IAAI,SAAS,uCACtC,MACD;EAGH,MAAM,WAAW,IAAI,SAAS,aAAa;AAG3C,MAAI,aAAa,YACf,OAAM,IAAIA,8BACR,gDACA,MACD;EAIH,MAAM,gBAAgB,SAAS,QAAQ,YAAY,GAAG;AAKtD,MAAIC,kBAAO,QAAQ,cAAc,EAAE;GACjC,MAAM,OAAOA,kBAAO,MAAM,cAAc;AAGxC,OAAI,KAAK,MAAM,KAAK,QAAQ;IAE1B,MAAM,QADW,KACM,OAAO;AAE9B,QAAI,oBAAoB,IAAI,MAAM,CAChC,OAAM,IAAID,8BACR,iDACA,MACD;;AAKL,OAAI,KAAK,MAAM,KAAK,QAAQ;IAE1B,MAAM,QADW,KACM,OAAO;AAE9B,QAAI,oBAAoB,IAAI,MAAM,CAChC,OAAM,IAAIA,8BACR,iDACA,MACD;;;UAIA,OAAO;AACd,MAAI,iBAAiBA,8BACnB,OAAM;AAER,QAAM,IAAIA,8BACR,uBAAuB,aACvB,OACA,MACD"}
@@ -0,0 +1,8 @@
1
+ //#region rolldown:runtime
2
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { get: (a, b) => (typeof require !== "undefined" ? require : a)[b] }) : x)(function(x) {
3
+ if (typeof require !== "undefined") return require.apply(this, arguments);
4
+ throw Error("Calling `require` for \"" + x + "\" in an environment that doesn't expose the `require` function.");
5
+ });
6
+
7
+ //#endregion
8
+ export { __require };
@@ -0,0 +1,7 @@
1
+ import { PinataAdapter } from "./v2/adapter-interface.js";
2
+ import { pinataAdapter } from "./v2/adapter.js";
3
+ import "./v2/index.js";
4
+ import { AnalyticsQuery, FileListItem, FileListQuery, FileListResponse, PinJobItem, PinJobQuery, PinJobResponse, PinataConfig, PinataMetadata, SignedUrlOptions, SwapCidOptions, SwapCidResponse, SwapHistoryOptions, TimeIntervalAnalyticsQuery, TimeIntervalAnalyticsResponse, TimePeriodItem, TopAnalyticsItem, TopAnalyticsQuery, TopAnalyticsResponse, UploadOptions, UploadResponse } from "./shared/types.js";
5
+ import { PinataLegacyAdapter, pinataLegacyAdapter } from "./legacy/adapter.js";
6
+ import "./legacy/index.js";
7
+ import "./shared/index.js";
@@ -0,0 +1,6 @@
1
+ import { createFileListItem, createPinJobItem, createUploadResponse, notSupported, parseCID } from "./shared/utils.js";
2
+ import { pinataAdapter } from "./v2/adapter.js";
3
+ import "./v2/index.js";
4
+ import { pinataLegacyAdapter } from "./legacy/adapter.js";
5
+ import "./legacy/index.js";
6
+ import "./shared/index.js";
@@ -0,0 +1,74 @@
1
+ import { Pinner } from "../../../pinner.js";
2
+ import { FileListQuery, FileListResponse, PinJobQuery, PinJobResponse, PinataConfig, SignedUrlOptions, SwapCidOptions, SwapCidResponse, SwapHistoryOptions, TimeIntervalAnalyticsQuery, TimeIntervalAnalyticsResponse, TopAnalyticsQuery, TopAnalyticsResponse, UploadOptions, UploadResponse } from "../shared/types.js";
3
+
4
+ //#region src/adapters/pinata/legacy/adapter.d.ts
5
+
6
+ /**
7
+ * Pinata 1.x Legacy Adapter Interface
8
+ * Matches Pinata SDK 1.x API exactly
9
+ */
10
+ interface PinataLegacyAdapter {
11
+ /**
12
+ * Upload a file to IPFS
13
+ */
14
+ pinFileToIPFS(file: File, options?: UploadOptions): Promise<UploadResponse>;
15
+ /**
16
+ * Upload JSON data to IPFS
17
+ */
18
+ pinJSONToIPFS(data: any, options?: UploadOptions): Promise<UploadResponse>;
19
+ /**
20
+ * Pin content by CID
21
+ */
22
+ pinByHash(cid: string, options?: UploadOptions): Promise<UploadResponse>;
23
+ /**
24
+ * List pinned files
25
+ */
26
+ pinList(query?: FileListQuery): Promise<FileListResponse>;
27
+ /**
28
+ * Unpin content by CID
29
+ */
30
+ unpin(cid: string): Promise<{
31
+ message: string;
32
+ }>;
33
+ /**
34
+ * Update pin metadata
35
+ */
36
+ hashMetadata(cid: string, metadata: Record<string, string>): Promise<{
37
+ message: string;
38
+ }>;
39
+ /**
40
+ * Create signed URL for private IPFS files
41
+ */
42
+ createSignedURL(options: SignedUrlOptions): Promise<string>;
43
+ /**
44
+ * Get pin jobs
45
+ */
46
+ pinJobs(query?: PinJobQuery): Promise<PinJobResponse>;
47
+ /**
48
+ * Get top usage analytics
49
+ */
50
+ topUsageAnalytics(query: TopAnalyticsQuery): Promise<TopAnalyticsResponse>;
51
+ /**
52
+ * Get date interval analytics
53
+ */
54
+ dateIntervalAnalytics(query: TimeIntervalAnalyticsQuery): Promise<TimeIntervalAnalyticsResponse>;
55
+ /**
56
+ * Swap CID
57
+ */
58
+ swapCid(options: SwapCidOptions): Promise<SwapCidResponse>;
59
+ /**
60
+ * Get swap history
61
+ */
62
+ swapHistory(options: SwapHistoryOptions): Promise<SwapCidResponse[]>;
63
+ }
64
+ /**
65
+ * Create Pinata 1.x Legacy Adapter
66
+ *
67
+ * @param pinner - Pinner client instance
68
+ * @param config - Pinata configuration
69
+ * @returns PinataLegacyAdapter
70
+ */
71
+ declare function pinataLegacyAdapter(pinner: Pinner, config?: PinataConfig): PinataLegacyAdapter;
72
+ //#endregion
73
+ export { PinataLegacyAdapter, pinataLegacyAdapter };
74
+ //# sourceMappingURL=adapter.d.ts.map
@@ -0,0 +1,83 @@
1
+ import { DEFAULT_GATEWAY } from "../../../types/constants.js";
2
+ import { createFileListItem, createPinJobItem, createUploadResponse, notSupported, parseCID } from "../shared/utils.js";
3
+
4
+ //#region src/adapters/pinata/legacy/adapter.ts
5
+ /**
6
+ * Create Pinata 1.x Legacy Adapter
7
+ *
8
+ * @param pinner - Pinner client instance
9
+ * @param config - Pinata configuration
10
+ * @returns PinataLegacyAdapter
11
+ */
12
+ function pinataLegacyAdapter(pinner, config) {
13
+ return {
14
+ async pinFileToIPFS(file, options) {
15
+ return createUploadResponse(await pinner.uploadAndWait(file, {
16
+ name: options?.metadata?.name,
17
+ keyvalues: options?.metadata?.keyvalues
18
+ }), file.name);
19
+ },
20
+ async pinJSONToIPFS(data, options) {
21
+ const jsonString = JSON.stringify(data);
22
+ const file = new File([jsonString], options?.metadata?.name || "data.json", { type: "application/json" });
23
+ return createUploadResponse(await pinner.uploadAndWait(file, {
24
+ name: options?.metadata?.name,
25
+ keyvalues: options?.metadata?.keyvalues
26
+ }), file.name);
27
+ },
28
+ async pinByHash(cid, options) {
29
+ const cidObj = parseCID(cid);
30
+ const generator = await pinner.pinByHash(cidObj, {
31
+ name: options?.metadata?.name,
32
+ metadata: options?.metadata?.keyvalues
33
+ });
34
+ for await (const _ of generator);
35
+ const pin = await pinner.getPinStatus(cidObj);
36
+ return createUploadResponse({
37
+ cid: pin.cid.toString(),
38
+ size: pin.size || 0,
39
+ createdAt: pin.created
40
+ }, pin.name || "");
41
+ },
42
+ async pinList(query) {
43
+ return {
44
+ files: (await pinner.listPins({ limit: query?.limit })).map(createFileListItem),
45
+ next_page_token: ""
46
+ };
47
+ },
48
+ async unpin(cid) {
49
+ await pinner.unpin(cid);
50
+ return { message: `Unpinned ${cid}` };
51
+ },
52
+ async hashMetadata(cid, metadata) {
53
+ await pinner.setPinMetadata(cid, metadata);
54
+ return { message: `Updated metadata for ${cid}` };
55
+ },
56
+ async createSignedURL(options) {
57
+ return `${config?.pinataGateway || DEFAULT_GATEWAY}/ipfs/${options.cid}`;
58
+ },
59
+ async pinJobs(query) {
60
+ return { rows: (await pinner.listPins({ limit: query?.limit })).map(createPinJobItem) };
61
+ },
62
+ async topUsageAnalytics(query) {
63
+ return { data: [] };
64
+ },
65
+ async dateIntervalAnalytics(query) {
66
+ return {
67
+ total_requests: 0,
68
+ total_bandwidth: 0,
69
+ time_periods: []
70
+ };
71
+ },
72
+ async swapCid(options) {
73
+ notSupported("Swap CID");
74
+ },
75
+ async swapHistory(options) {
76
+ return [];
77
+ }
78
+ };
79
+ }
80
+
81
+ //#endregion
82
+ export { pinataLegacyAdapter };
83
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.js","names":[],"sources":["../../../../../src/adapters/pinata/legacy/adapter.ts"],"sourcesContent":["/**\n * Pinata SDK 1.x Legacy Adapter\n * Provides compatibility with Pinata SDK 1.x API\n *\n * Source: https://github.com/PinataCloud/pinata/commit/c141177ff3036e46fa7b95fcc68c159b58817836\n * - src/core/pinataSDK.ts\n * - src/core/types.ts\n *\n * Copyright © 2024 Pinata Cloud Technologies\n * Type definitions and API interfaces adapted from Pinata SDK for compatibility.\n * Original Pinata SDK: https://github.com/PinataCloud/pinata\n */\n\nimport type { Pinner } from \"@/pinner\";\nimport type {\n\tPinataConfig,\n\tUploadResponse,\n\tUploadOptions,\n\tFileListResponse,\n\tFileListQuery,\n\tPinJobResponse,\n\tPinJobQuery,\n\tDeleteResponse,\n\tPinataMetadata,\n\tSignedUrlOptions,\n\tTopAnalyticsQuery,\n\tTopAnalyticsResponse,\n\tTimeIntervalAnalyticsQuery,\n\tTimeIntervalAnalyticsResponse,\n\tSwapCidOptions,\n\tSwapCidResponse,\n\tSwapHistoryOptions,\n} from \"../shared/types\";\nimport { parseCID, createUploadResponse, createFileListItem, createPinJobItem, notSupported } from \"../shared/utils\";\nimport { DEFAULT_GATEWAY } from \"@/types/constants\";\n\n/**\n * Pinata 1.x Legacy Adapter Interface\n * Matches Pinata SDK 1.x API exactly\n */\nexport interface PinataLegacyAdapter {\n\t/**\n\t * Upload a file to IPFS\n\t */\n\tpinFileToIPFS(file: File, options?: UploadOptions): Promise<UploadResponse>;\n\n\t/**\n\t * Upload JSON data to IPFS\n\t */\n\tpinJSONToIPFS(data: any, options?: UploadOptions): Promise<UploadResponse>;\n\n\t/**\n\t * Pin content by CID\n\t */\n\tpinByHash(cid: string, options?: UploadOptions): Promise<UploadResponse>;\n\n\t/**\n\t * List pinned files\n\t */\n\tpinList(query?: FileListQuery): Promise<FileListResponse>;\n\n\t/**\n\t * Unpin content by CID\n\t */\n\tunpin(cid: string): Promise<{ message: string }>;\n\n\t/**\n\t * Update pin metadata\n\t */\n\thashMetadata(cid: string, metadata: Record<string, string>): Promise<{ message: string }>;\n\n\t/**\n\t * Create signed URL for private IPFS files\n\t */\n\tcreateSignedURL(options: SignedUrlOptions): Promise<string>;\n\n\t/**\n\t * Get pin jobs\n\t */\n\tpinJobs(query?: PinJobQuery): Promise<PinJobResponse>;\n\n\t/**\n\t * Get top usage analytics\n\t */\n\ttopUsageAnalytics(query: TopAnalyticsQuery): Promise<TopAnalyticsResponse>;\n\n\t/**\n\t * Get date interval analytics\n\t */\n\tdateIntervalAnalytics(\n\t\tquery: TimeIntervalAnalyticsQuery,\n\t): Promise<TimeIntervalAnalyticsResponse>;\n\n\t/**\n\t * Swap CID\n\t */\n\tswapCid(options: SwapCidOptions): Promise<SwapCidResponse>;\n\n\t/**\n\t * Get swap history\n\t */\n\tswapHistory(options: SwapHistoryOptions): Promise<SwapCidResponse[]>;\n}\n\n/**\n * Create Pinata 1.x Legacy Adapter\n *\n * @param pinner - Pinner client instance\n * @param config - Pinata configuration\n * @returns PinataLegacyAdapter\n */\nexport function pinataLegacyAdapter(\n\tpinner: Pinner,\n\tconfig?: PinataConfig,\n): PinataLegacyAdapter {\n\treturn {\n\t\t/**\n\t\t * Pin a file to IPFS\n\t\t */\n\t\tasync pinFileToIPFS(\n\t\t\tfile: File,\n\t\t\toptions?: UploadOptions,\n\t\t): Promise<UploadResponse> {\n\t\t\tconst result = await pinner.uploadAndWait(file, {\n\t\t\t\tname: options?.metadata?.name,\n\t\t\t\tkeyvalues: options?.metadata?.keyvalues,\n\t\t\t});\n\n\t\t\treturn createUploadResponse(result, file.name);\n\t\t},\n\n\t\t/**\n\t\t * Pin JSON data to IPFS\n\t\t */\n\t\tasync pinJSONToIPFS(\n\t\t\tdata: any,\n\t\t\toptions?: UploadOptions,\n\t\t): Promise<UploadResponse> {\n\t\t\t// Convert JSON to File\n\t\t\tconst jsonString = JSON.stringify(data);\n\t\t\tconst file = new File(\n\t\t\t\t[jsonString],\n\t\t\t\toptions?.metadata?.name || \"data.json\",\n\t\t\t\t{ type: \"application/json\" },\n\t\t\t);\n\n\t\t\tconst result = await pinner.uploadAndWait(file, {\n\t\t\t\tname: options?.metadata?.name,\n\t\t\t\tkeyvalues: options?.metadata?.keyvalues,\n\t\t\t});\n\n\t\t\treturn createUploadResponse(result, file.name);\n\t\t},\n\n\t\t/**\n\t\t * Pin content by CID\n\t\t */\n\t\tasync pinByHash(\n\t\t\tcid: string,\n\t\t\toptions?: UploadOptions,\n\t\t): Promise<UploadResponse> {\n\t\t\tconst cidObj = parseCID(cid);\n\t\t\tconst generator = await pinner.pinByHash(cidObj, {\n\t\t\t\tname: options?.metadata?.name,\n\t\t\t\tmetadata: options?.metadata?.keyvalues,\n\t\t\t});\n\n\t\t\tfor await (const _ of generator) {\n\t\t\t\t// Wait for pin to complete\n\t\t\t}\n\n\t\t\tconst pin = await pinner.getPinStatus(cidObj);\n\t\t\treturn createUploadResponse(\n\t\t\t\t{\n\t\t\t\t\tcid: pin.cid.toString(),\n\t\t\t\t\tsize: pin.size || 0,\n\t\t\t\t\tcreatedAt: pin.created,\n\t\t\t\t},\n\t\t\t\tpin.name || \"\",\n\t\t\t);\n\t\t},\n\n\t\t/**\n\t\t * List pinned files\n\t\t */\n\t\tasync pinList(query?: FileListQuery): Promise<FileListResponse> {\n\t\t\tconst pins = await pinner.listPins({\n\t\t\t\tlimit: query?.limit,\n\t\t\t});\n\n\t\t\treturn {\n\t\t\t\tfiles: pins.map(createFileListItem),\n\t\t\t\tnext_page_token: \"\",\n\t\t\t};\n\t\t},\n\n\t\t/**\n\t\t * Unpin content\n\t\t */\n\t\tasync unpin(cid: string): Promise<{ message: string }> {\n\t\t\tawait pinner.unpin(cid);\n\t\t\treturn { message: `Unpinned ${cid}` };\n\t\t},\n\n\t\t/**\n\t\t * Update pin metadata\n\t\t */\n\t\tasync hashMetadata(\n\t\t\tcid: string,\n\t\t\tmetadata: Record<string, string>,\n\t\t): Promise<{ message: string }> {\n\t\t\tawait pinner.setPinMetadata(cid, metadata);\n\t\t\treturn { message: `Updated metadata for ${cid}` };\n\t\t},\n\n\t\t/**\n\t\t * Create signed URL (not fully supported in Pinner)\n\t\t * Returns a gateway URL instead\n\t\t */\n\t\tasync createSignedURL(options: SignedUrlOptions): Promise<string> {\n\t\t\t// Pinner doesn't support signed URLs for private files\n\t\t\t// Return a gateway URL as fallback\n\t\t\tconst gateway = config?.pinataGateway || DEFAULT_GATEWAY;\n\t\t\treturn `${gateway}/ipfs/${options.cid}`;\n\t\t},\n\n\t\t/**\n\t\t * Get pin jobs\n\t\t */\n\t\tasync pinJobs(query?: PinJobQuery): Promise<PinJobResponse> {\n\t\t\tconst pins = await pinner.listPins({\n\t\t\t\tlimit: query?.limit,\n\t\t\t});\n\n\t\t\treturn {\n\t\t\t\trows: pins.map(createPinJobItem),\n\t\t\t};\n\t\t},\n\n\t\t/**\n\t\t * Get top usage analytics (not supported in Pinner)\n\t\t * Returns empty data\n\t\t */\n\t\tasync topUsageAnalytics(\n\t\t\tquery: TopAnalyticsQuery,\n\t\t): Promise<TopAnalyticsResponse> {\n\t\t\t// Pinner doesn't support analytics\n\t\t\treturn {\n\t\t\t\tdata: [],\n\t\t\t};\n\t\t},\n\n\t\t/**\n\t\t * Get date interval analytics (not supported in Pinner)\n\t\t * Returns empty data\n\t\t */\n\t\tasync dateIntervalAnalytics(\n\t\t\tquery: TimeIntervalAnalyticsQuery,\n\t\t): Promise<TimeIntervalAnalyticsResponse> {\n\t\t\t// Pinner doesn't support analytics\n\t\t\treturn {\n\t\t\t\ttotal_requests: 0,\n\t\t\t\ttotal_bandwidth: 0,\n\t\t\t\ttime_periods: [],\n\t\t\t};\n\t\t},\n\n\t\t/**\n\t\t * Swap CID (not supported in Pinner)\n\t\t * Returns error\n\t\t */\n\t\tasync swapCid(options: SwapCidOptions): Promise<SwapCidResponse> {\n\t\t\tnotSupported(\"Swap CID\");\n\t\t},\n\n\t\t/**\n\t\t * Get swap history (not supported in Pinner)\n\t\t * Returns empty array\n\t\t */\n\t\tasync swapHistory(options: SwapHistoryOptions): Promise<SwapCidResponse[]> {\n\t\t\t// Pinner doesn't support swaps\n\t\t\treturn [];\n\t\t},\n\t};\n}\n"],"mappings":";;;;;;;;;;;AA+GA,SAAgB,oBACf,QACA,QACsB;AACtB,QAAO;EAIN,MAAM,cACL,MACA,SAC0B;AAM1B,UAAO,qBALQ,MAAM,OAAO,cAAc,MAAM;IAC/C,MAAM,SAAS,UAAU;IACzB,WAAW,SAAS,UAAU;IAC9B,CAAC,EAEkC,KAAK,KAAK;;EAM/C,MAAM,cACL,MACA,SAC0B;GAE1B,MAAM,aAAa,KAAK,UAAU,KAAK;GACvC,MAAM,OAAO,IAAI,KAChB,CAAC,WAAW,EACZ,SAAS,UAAU,QAAQ,aAC3B,EAAE,MAAM,oBAAoB,CAC5B;AAOD,UAAO,qBALQ,MAAM,OAAO,cAAc,MAAM;IAC/C,MAAM,SAAS,UAAU;IACzB,WAAW,SAAS,UAAU;IAC9B,CAAC,EAEkC,KAAK,KAAK;;EAM/C,MAAM,UACL,KACA,SAC0B;GAC1B,MAAM,SAAS,SAAS,IAAI;GAC5B,MAAM,YAAY,MAAM,OAAO,UAAU,QAAQ;IAChD,MAAM,SAAS,UAAU;IACzB,UAAU,SAAS,UAAU;IAC7B,CAAC;AAEF,cAAW,MAAM,KAAK;GAItB,MAAM,MAAM,MAAM,OAAO,aAAa,OAAO;AAC7C,UAAO,qBACN;IACC,KAAK,IAAI,IAAI,UAAU;IACvB,MAAM,IAAI,QAAQ;IAClB,WAAW,IAAI;IACf,EACD,IAAI,QAAQ,GACZ;;EAMF,MAAM,QAAQ,OAAkD;AAK/D,UAAO;IACN,QALY,MAAM,OAAO,SAAS,EAClC,OAAO,OAAO,OACd,CAAC,EAGW,IAAI,mBAAmB;IACnC,iBAAiB;IACjB;;EAMF,MAAM,MAAM,KAA2C;AACtD,SAAM,OAAO,MAAM,IAAI;AACvB,UAAO,EAAE,SAAS,YAAY,OAAO;;EAMtC,MAAM,aACL,KACA,UAC+B;AAC/B,SAAM,OAAO,eAAe,KAAK,SAAS;AAC1C,UAAO,EAAE,SAAS,wBAAwB,OAAO;;EAOlD,MAAM,gBAAgB,SAA4C;AAIjE,UAAO,GADS,QAAQ,iBAAiB,gBACvB,QAAQ,QAAQ;;EAMnC,MAAM,QAAQ,OAA8C;AAK3D,UAAO,EACN,OALY,MAAM,OAAO,SAAS,EAClC,OAAO,OAAO,OACd,CAAC,EAGU,IAAI,iBAAiB,EAChC;;EAOF,MAAM,kBACL,OACgC;AAEhC,UAAO,EACN,MAAM,EAAE,EACR;;EAOF,MAAM,sBACL,OACyC;AAEzC,UAAO;IACN,gBAAgB;IAChB,iBAAiB;IACjB,cAAc,EAAE;IAChB;;EAOF,MAAM,QAAQ,SAAmD;AAChE,gBAAa,WAAW;;EAOzB,MAAM,YAAY,SAAyD;AAE1E,UAAO,EAAE;;EAEV"}
@@ -0,0 +1 @@
1
+ import { PinataLegacyAdapter, pinataLegacyAdapter } from "./adapter.js";
@@ -0,0 +1 @@
1
+ import { pinataLegacyAdapter } from "./adapter.js";
@@ -0,0 +1,2 @@
1
+ import { AnalyticsQuery, FileListItem, FileListQuery, FileListResponse, PinJobItem, PinJobQuery, PinJobResponse, PinataConfig, PinataMetadata, SignedUrlOptions, SwapCidOptions, SwapCidResponse, SwapHistoryOptions, TimeIntervalAnalyticsQuery, TimeIntervalAnalyticsResponse, TimePeriodItem, TopAnalyticsItem, TopAnalyticsQuery, TopAnalyticsResponse, UploadOptions, UploadResponse } from "./types.js";
2
+ import "./utils.js";
@@ -0,0 +1 @@
1
+ import { createFileListItem, createPinJobItem, createUploadResponse, notSupported, parseCID } from "./utils.js";
@@ -0,0 +1,218 @@
1
+ //#region src/adapters/pinata/shared/types.d.ts
2
+ /**
3
+ * Pinata SDK 1.x Types
4
+ * Source: https://github.com/PinataCloud/pinata/commit/c141177ff3036e46fa7b95fcc68c159b58817836
5
+ * - src/core/types.ts
6
+ *
7
+ * Copyright © 2024 Pinata Cloud Technologies
8
+ * Type definitions adapted from Pinata SDK for compatibility.
9
+ * Original Pinata SDK: https://github.com/PinataCloud/pinata
10
+ */
11
+ /**
12
+ * Pinata configuration options
13
+ */
14
+ type PinataConfig = {
15
+ pinataJwt?: string;
16
+ pinataGateway?: string;
17
+ pinataGatewayKey?: string;
18
+ customHeaders?: Record<string, string>;
19
+ endpointUrl?: string;
20
+ uploadUrl?: string;
21
+ };
22
+ /**
23
+ * Upload response from Pinata
24
+ */
25
+ type UploadResponse = {
26
+ id: string;
27
+ name: string;
28
+ cid: string;
29
+ size: number;
30
+ created_at: string;
31
+ number_of_files: number;
32
+ mime_type: string;
33
+ user_id: string;
34
+ group_id: string | null;
35
+ is_duplicate: true | null;
36
+ vectorized: true | null;
37
+ };
38
+ /**
39
+ * Pinata metadata options
40
+ */
41
+ type PinataMetadata = {
42
+ name?: string;
43
+ keyvalues?: Record<string, string>;
44
+ };
45
+ /**
46
+ * Upload options
47
+ */
48
+ type UploadOptions = {
49
+ metadata?: PinataMetadata;
50
+ keys?: string;
51
+ groupId?: string;
52
+ vectorize?: boolean;
53
+ url?: string;
54
+ };
55
+ /**
56
+ * File list item
57
+ */
58
+ type FileListItem = {
59
+ id: string;
60
+ name: string | null;
61
+ cid: "pending" | string;
62
+ size: number;
63
+ number_of_files: number;
64
+ mime_type: string;
65
+ keyvalues: Record<string, string>;
66
+ group_id: string | null;
67
+ created_at: string;
68
+ };
69
+ /**
70
+ * File list response
71
+ */
72
+ type FileListResponse = {
73
+ files: FileListItem[];
74
+ next_page_token: string;
75
+ };
76
+ /**
77
+ * File list query options
78
+ */
79
+ type FileListQuery = {
80
+ name?: string;
81
+ group?: string;
82
+ noGroup?: boolean;
83
+ mimeType?: string;
84
+ cid?: string;
85
+ cidPending?: boolean;
86
+ metadata?: Record<string, string>;
87
+ order?: "ASC" | "DESC";
88
+ limit?: number;
89
+ pageToken?: number;
90
+ };
91
+ /**
92
+ * Pin job query options
93
+ */
94
+ type PinJobQuery = {
95
+ sort?: "ASC" | "DSC";
96
+ status?: "prechecking" | "retrieving" | "expired" | "over_free_limit" | "over_max_size" | "invalid_object" | "bad_host_node";
97
+ ipfs_pin_hash?: string;
98
+ limit?: number;
99
+ offset?: number;
100
+ };
101
+ /**
102
+ * Pin job item
103
+ */
104
+ type PinJobItem = {
105
+ id: string;
106
+ ipfs_pin_hash: string;
107
+ date_queued: string;
108
+ name: string;
109
+ status: string;
110
+ keyvalues: any;
111
+ host_nodes: string[];
112
+ pin_policy: {
113
+ regions: {
114
+ id: string;
115
+ desiredReplicationCount: number;
116
+ }[];
117
+ version: number;
118
+ };
119
+ };
120
+ /**
121
+ * Pin job response
122
+ */
123
+ type PinJobResponse = {
124
+ rows: PinJobItem[];
125
+ };
126
+ /**
127
+ * Signed URL options
128
+ */
129
+ type SignedUrlOptions = {
130
+ cid: string;
131
+ date?: number;
132
+ expires: number;
133
+ gateway?: string;
134
+ };
135
+ /**
136
+ * Analytics query options
137
+ */
138
+ type AnalyticsQuery = {
139
+ gateway_domain: string;
140
+ start_date: string;
141
+ end_date: string;
142
+ cid?: string;
143
+ file_name?: string;
144
+ user_agent?: string;
145
+ country?: string;
146
+ region?: string;
147
+ referer?: string;
148
+ limit?: number;
149
+ sort_order?: "asc" | "desc";
150
+ };
151
+ /**
152
+ * Top analytics query options
153
+ */
154
+ type TopAnalyticsQuery = AnalyticsQuery & {
155
+ sort_by: "requests" | "bandwidth";
156
+ attribute: "cid" | "country" | "region" | "user_agent" | "referer" | "file_name";
157
+ };
158
+ /**
159
+ * Top analytics response
160
+ */
161
+ type TopAnalyticsResponse = {
162
+ data: TopAnalyticsItem[];
163
+ };
164
+ /**
165
+ * Top analytics item
166
+ */
167
+ type TopAnalyticsItem = {
168
+ value: string;
169
+ requests: number;
170
+ bandwidth: number;
171
+ };
172
+ /**
173
+ * Time interval analytics query options
174
+ */
175
+ type TimeIntervalAnalyticsQuery = AnalyticsQuery & {
176
+ sort_by?: "requests" | "bandwidth";
177
+ date_interval: "day" | "week";
178
+ };
179
+ /**
180
+ * Time period item
181
+ */
182
+ type TimePeriodItem = {
183
+ period_start_time: string;
184
+ requests: number;
185
+ bandwidth: number;
186
+ };
187
+ /**
188
+ * Time interval analytics response
189
+ */
190
+ type TimeIntervalAnalyticsResponse = {
191
+ total_requests: number;
192
+ total_bandwidth: number;
193
+ time_periods: TimePeriodItem[];
194
+ };
195
+ /**
196
+ * Swap CID options
197
+ */
198
+ type SwapCidOptions = {
199
+ cid: string;
200
+ swapCid: string;
201
+ };
202
+ /**
203
+ * Swap history options
204
+ */
205
+ type SwapHistoryOptions = {
206
+ cid: string;
207
+ domain: string;
208
+ };
209
+ /**
210
+ * Swap CID response
211
+ */
212
+ type SwapCidResponse = {
213
+ mapped_cid: string;
214
+ created_at: string;
215
+ };
216
+ //#endregion
217
+ export { AnalyticsQuery, FileListItem, FileListQuery, FileListResponse, PinJobItem, PinJobQuery, PinJobResponse, PinataConfig, PinataMetadata, SignedUrlOptions, SwapCidOptions, SwapCidResponse, SwapHistoryOptions, TimeIntervalAnalyticsQuery, TimeIntervalAnalyticsResponse, TimePeriodItem, TopAnalyticsItem, TopAnalyticsQuery, TopAnalyticsResponse, UploadOptions, UploadResponse };
218
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ import { CID } from "multiformats/cid";