@medialane/ui 0.250.0 → 0.252.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 (53) hide show
  1. package/dist/components/asset-overview-content.cjs +1 -3
  2. package/dist/components/asset-overview-content.cjs.map +1 -1
  3. package/dist/components/asset-overview-content.js +2 -4
  4. package/dist/components/asset-overview-content.js.map +1 -1
  5. package/dist/components/asset-page.cjs +11 -4
  6. package/dist/components/asset-page.cjs.map +1 -1
  7. package/dist/components/asset-page.js +11 -4
  8. package/dist/components/asset-page.js.map +1 -1
  9. package/dist/components/asset-publication.cjs +5 -13
  10. package/dist/components/asset-publication.cjs.map +1 -1
  11. package/dist/components/asset-publication.d.cts +2 -2
  12. package/dist/components/asset-publication.d.ts +2 -2
  13. package/dist/components/asset-publication.js +5 -13
  14. package/dist/components/asset-publication.js.map +1 -1
  15. package/dist/components/asset-top-sections.cjs +9 -1
  16. package/dist/components/asset-top-sections.cjs.map +1 -1
  17. package/dist/components/asset-top-sections.d.cts +2 -1
  18. package/dist/components/asset-top-sections.d.ts +2 -1
  19. package/dist/components/asset-top-sections.js +9 -1
  20. package/dist/components/asset-top-sections.js.map +1 -1
  21. package/dist/components/button.d.cts +1 -1
  22. package/dist/components/button.d.ts +1 -1
  23. package/dist/components/drop/create/launch-dialog.cjs +0 -1
  24. package/dist/components/drop/create/launch-dialog.cjs.map +1 -1
  25. package/dist/components/drop/create/launch-dialog.js +0 -1
  26. package/dist/components/drop/create/launch-dialog.js.map +1 -1
  27. package/dist/components/fast-mint/fast-mint.d.cts +2 -2
  28. package/dist/components/fast-mint/fast-mint.d.ts +2 -2
  29. package/dist/components/sheet.d.cts +1 -1
  30. package/dist/components/sheet.d.ts +1 -1
  31. package/dist/utils/drop/metadata.cjs +1 -2
  32. package/dist/utils/drop/metadata.cjs.map +1 -1
  33. package/dist/utils/drop/metadata.d.cts +0 -1
  34. package/dist/utils/drop/metadata.d.ts +0 -1
  35. package/dist/utils/drop/metadata.js +1 -2
  36. package/dist/utils/drop/metadata.js.map +1 -1
  37. package/dist/utils/external-link.cjs +44 -0
  38. package/dist/utils/external-link.cjs.map +1 -0
  39. package/dist/utils/external-link.d.cts +4 -0
  40. package/dist/utils/external-link.d.ts +4 -0
  41. package/dist/utils/external-link.js +19 -0
  42. package/dist/utils/external-link.js.map +1 -0
  43. package/dist/utils/ipfs-upload.cjs.map +1 -1
  44. package/dist/utils/ipfs-upload.d.cts +1 -1
  45. package/dist/utils/ipfs-upload.d.ts +1 -1
  46. package/dist/utils/ipfs-upload.js.map +1 -1
  47. package/dist/utils/use-collections.d.cts +3 -0
  48. package/dist/utils/use-collections.d.ts +3 -0
  49. package/dist/utils/use-tokens-by-ip-type.d.cts +2 -0
  50. package/dist/utils/use-tokens-by-ip-type.d.ts +2 -0
  51. package/dist/utils/use-tokens.d.cts +4 -0
  52. package/dist/utils/use-tokens.d.ts +4 -0
  53. package/package.json +3 -3
@@ -12,7 +12,6 @@ interface DropMetadataInput {
12
12
  creator: string;
13
13
  coverUri: string | null;
14
14
  license: DropLicense;
15
- registrationDate: string;
16
15
  /** Edition: the one artwork. Collection: one per token. */
17
16
  items: {
18
17
  name: string;
@@ -15,8 +15,7 @@ function buildDropMetadataFiles(input) {
15
15
  description: item.description || input.description,
16
16
  imageUri: item.imageUri,
17
17
  creator: input.creator,
18
- edition: edition ? `${id}/${count}` : null,
19
- registrationDate: input.registrationDate
18
+ edition: edition ? `${id}/${count}` : null
20
19
  })
21
20
  });
22
21
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/drop/metadata.ts"],"sourcesContent":["import { buildAssetMetadata, type BuildAssetMetadataInput } from \"@medialane/sdk\";\n\n/** The metadata folder upload holds 2,001 files (tokens + collection.json). */\nexport const MAX_DROP_SUPPLY = 2000;\nexport const MAX_DROP_METADATA_BYTES = 5 * 1024 * 1024;\n\nexport type DropKind = \"edition\" | \"collection\";\n\nexport type DropLicense = Record<\n keyof Pick<BuildAssetMetadataInput, \"ipType\" | \"licenseType\" | \"commercialUse\" | \"derivatives\" | \"attribution\" | \"geographicScope\" | \"aiPolicy\" | \"royalty\">,\n string\n>;\n\nexport interface DropMetadataInput {\n kind: DropKind;\n name: string;\n description: string;\n creator: string;\n coverUri: string | null;\n license: DropLicense;\n registrationDate: string;\n /** Edition: the one artwork. Collection: one per token. */\n items: { name: string; description: string; imageUri: string }[];\n /** Edition copies; ignored for a collection. */\n supply: number;\n}\n\nexport interface DropMetadataFile {\n name: string;\n content: unknown;\n}\n\n/** Token files 1…N (token URI = base URI + id) and collection.json. */\nexport function buildDropMetadataFiles(input: DropMetadataInput): DropMetadataFile[] {\n const edition = input.kind === \"edition\";\n const count = edition ? input.supply : input.items.length;\n const files: DropMetadataFile[] = [];\n for (let id = 1; id <= count; id++) {\n const item = edition ? input.items[0]! : input.items[id - 1]!;\n files.push({\n name: String(id),\n content: buildAssetMetadata({\n ...input.license,\n name: edition || !item.name ? `${input.name} #${id}` : item.name,\n description: item.description || input.description,\n imageUri: item.imageUri,\n creator: input.creator,\n edition: edition ? `${id}/${count}` : null,\n registrationDate: input.registrationDate,\n }),\n });\n }\n files.push({\n name: \"collection.json\",\n content: {\n name: input.name,\n description: input.description,\n image: input.coverUri ?? input.items[0]?.imageUri ?? null,\n drop_kind: input.kind,\n },\n });\n return files;\n}\n\n/** Size as the upload route counts it. */\nexport function metadataBytes(files: DropMetadataFile[]): number {\n return files.reduce((n, f) => n + JSON.stringify(f.content).length, 0);\n}\n"],"mappings":"AAAA,SAAS,0BAAwD;AAG1D,MAAM,kBAAkB;AACxB,MAAM,0BAA0B,IAAI,OAAO;AA6B3C,SAAS,uBAAuB,OAA8C;AACnF,QAAM,UAAU,MAAM,SAAS;AAC/B,QAAM,QAAQ,UAAU,MAAM,SAAS,MAAM,MAAM;AACnD,QAAM,QAA4B,CAAC;AACnC,WAAS,KAAK,GAAG,MAAM,OAAO,MAAM;AAClC,UAAM,OAAO,UAAU,MAAM,MAAM,CAAC,IAAK,MAAM,MAAM,KAAK,CAAC;AAC3D,UAAM,KAAK;AAAA,MACT,MAAM,OAAO,EAAE;AAAA,MACf,SAAS,mBAAmB;AAAA,QAC1B,GAAG,MAAM;AAAA,QACT,MAAM,WAAW,CAAC,KAAK,OAAO,GAAG,MAAM,IAAI,KAAK,EAAE,KAAK,KAAK;AAAA,QAC5D,aAAa,KAAK,eAAe,MAAM;AAAA,QACvC,UAAU,KAAK;AAAA,QACf,SAAS,MAAM;AAAA,QACf,SAAS,UAAU,GAAG,EAAE,IAAI,KAAK,KAAK;AAAA,QACtC,kBAAkB,MAAM;AAAA,MAC1B,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AACA,QAAM,KAAK;AAAA,IACT,MAAM;AAAA,IACN,SAAS;AAAA,MACP,MAAM,MAAM;AAAA,MACZ,aAAa,MAAM;AAAA,MACnB,OAAO,MAAM,YAAY,MAAM,MAAM,CAAC,GAAG,YAAY;AAAA,MACrD,WAAW,MAAM;AAAA,IACnB;AAAA,EACF,CAAC;AACD,SAAO;AACT;AAGO,SAAS,cAAc,OAAmC;AAC/D,SAAO,MAAM,OAAO,CAAC,GAAG,MAAM,IAAI,KAAK,UAAU,EAAE,OAAO,EAAE,QAAQ,CAAC;AACvE;","names":[]}
1
+ {"version":3,"sources":["../../../src/utils/drop/metadata.ts"],"sourcesContent":["import { buildAssetMetadata, type BuildAssetMetadataInput } from \"@medialane/sdk\";\n\n/** The metadata folder upload holds 2,001 files (tokens + collection.json). */\nexport const MAX_DROP_SUPPLY = 2000;\nexport const MAX_DROP_METADATA_BYTES = 5 * 1024 * 1024;\n\nexport type DropKind = \"edition\" | \"collection\";\n\nexport type DropLicense = Record<\n keyof Pick<BuildAssetMetadataInput, \"ipType\" | \"licenseType\" | \"commercialUse\" | \"derivatives\" | \"attribution\" | \"geographicScope\" | \"aiPolicy\" | \"royalty\">,\n string\n>;\n\nexport interface DropMetadataInput {\n kind: DropKind;\n name: string;\n description: string;\n creator: string;\n coverUri: string | null;\n license: DropLicense;\n /** Edition: the one artwork. Collection: one per token. */\n items: { name: string; description: string; imageUri: string }[];\n /** Edition copies; ignored for a collection. */\n supply: number;\n}\n\nexport interface DropMetadataFile {\n name: string;\n content: unknown;\n}\n\n/** Token files 1…N (token URI = base URI + id) and collection.json. */\nexport function buildDropMetadataFiles(input: DropMetadataInput): DropMetadataFile[] {\n const edition = input.kind === \"edition\";\n const count = edition ? input.supply : input.items.length;\n const files: DropMetadataFile[] = [];\n for (let id = 1; id <= count; id++) {\n const item = edition ? input.items[0]! : input.items[id - 1]!;\n files.push({\n name: String(id),\n content: buildAssetMetadata({\n ...input.license,\n name: edition || !item.name ? `${input.name} #${id}` : item.name,\n description: item.description || input.description,\n imageUri: item.imageUri,\n creator: input.creator,\n edition: edition ? `${id}/${count}` : null,\n }),\n });\n }\n files.push({\n name: \"collection.json\",\n content: {\n name: input.name,\n description: input.description,\n image: input.coverUri ?? input.items[0]?.imageUri ?? null,\n drop_kind: input.kind,\n },\n });\n return files;\n}\n\n/** Size as the upload route counts it. */\nexport function metadataBytes(files: DropMetadataFile[]): number {\n return files.reduce((n, f) => n + JSON.stringify(f.content).length, 0);\n}\n"],"mappings":"AAAA,SAAS,0BAAwD;AAG1D,MAAM,kBAAkB;AACxB,MAAM,0BAA0B,IAAI,OAAO;AA4B3C,SAAS,uBAAuB,OAA8C;AACnF,QAAM,UAAU,MAAM,SAAS;AAC/B,QAAM,QAAQ,UAAU,MAAM,SAAS,MAAM,MAAM;AACnD,QAAM,QAA4B,CAAC;AACnC,WAAS,KAAK,GAAG,MAAM,OAAO,MAAM;AAClC,UAAM,OAAO,UAAU,MAAM,MAAM,CAAC,IAAK,MAAM,MAAM,KAAK,CAAC;AAC3D,UAAM,KAAK;AAAA,MACT,MAAM,OAAO,EAAE;AAAA,MACf,SAAS,mBAAmB;AAAA,QAC1B,GAAG,MAAM;AAAA,QACT,MAAM,WAAW,CAAC,KAAK,OAAO,GAAG,MAAM,IAAI,KAAK,EAAE,KAAK,KAAK;AAAA,QAC5D,aAAa,KAAK,eAAe,MAAM;AAAA,QACvC,UAAU,KAAK;AAAA,QACf,SAAS,MAAM;AAAA,QACf,SAAS,UAAU,GAAG,EAAE,IAAI,KAAK,KAAK;AAAA,MACxC,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AACA,QAAM,KAAK;AAAA,IACT,MAAM;AAAA,IACN,SAAS;AAAA,MACP,MAAM,MAAM;AAAA,MACZ,aAAa,MAAM;AAAA,MACnB,OAAO,MAAM,YAAY,MAAM,MAAM,CAAC,GAAG,YAAY;AAAA,MACrD,WAAW,MAAM;AAAA,IACnB;AAAA,EACF,CAAC;AACD,SAAO;AACT;AAGO,SAAS,cAAc,OAAmC;AAC/D,SAAO,MAAM,OAAO,CAAC,GAAG,MAAM,IAAI,KAAK,UAAU,EAAE,OAAO,EAAE,QAAQ,CAAC;AACvE;","names":[]}
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var external_link_exports = {};
20
+ __export(external_link_exports, {
21
+ externalLink: () => externalLink,
22
+ webAddress: () => webAddress
23
+ });
24
+ module.exports = __toCommonJS(external_link_exports);
25
+ const PLATFORM_DEFAULT = "https://medialane.io";
26
+ function webAddress(url) {
27
+ if (!url) return null;
28
+ try {
29
+ const parsed = new URL(url);
30
+ return parsed.protocol === "https:" || parsed.protocol === "http:" ? parsed.href : null;
31
+ } catch {
32
+ return null;
33
+ }
34
+ }
35
+ function externalLink(url) {
36
+ const address = webAddress(url);
37
+ return address && address !== `${PLATFORM_DEFAULT}/` ? address : null;
38
+ }
39
+ // Annotate the CommonJS export names for ESM import in node:
40
+ 0 && (module.exports = {
41
+ externalLink,
42
+ webAddress
43
+ });
44
+ //# sourceMappingURL=external-link.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/external-link.ts"],"sourcesContent":["const PLATFORM_DEFAULT = \"https://medialane.io\";\n\nexport function webAddress(url?: string | null): string | null {\n if (!url) return null;\n try {\n const parsed = new URL(url);\n return parsed.protocol === \"https:\" || parsed.protocol === \"http:\" ? parsed.href : null;\n } catch {\n return null;\n }\n}\n\nexport function externalLink(url?: string | null): string | null {\n const address = webAddress(url);\n return address && address !== `${PLATFORM_DEFAULT}/` ? address : null;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAAM,mBAAmB;AAElB,SAAS,WAAW,KAAoC;AAC7D,MAAI,CAAC,IAAK,QAAO;AACjB,MAAI;AACF,UAAM,SAAS,IAAI,IAAI,GAAG;AAC1B,WAAO,OAAO,aAAa,YAAY,OAAO,aAAa,UAAU,OAAO,OAAO;AAAA,EACrF,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,aAAa,KAAoC;AAC/D,QAAM,UAAU,WAAW,GAAG;AAC9B,SAAO,WAAW,YAAY,GAAG,gBAAgB,MAAM,UAAU;AACnE;","names":[]}
@@ -0,0 +1,4 @@
1
+ declare function webAddress(url?: string | null): string | null;
2
+ declare function externalLink(url?: string | null): string | null;
3
+
4
+ export { externalLink, webAddress };
@@ -0,0 +1,4 @@
1
+ declare function webAddress(url?: string | null): string | null;
2
+ declare function externalLink(url?: string | null): string | null;
3
+
4
+ export { externalLink, webAddress };
@@ -0,0 +1,19 @@
1
+ const PLATFORM_DEFAULT = "https://medialane.io";
2
+ function webAddress(url) {
3
+ if (!url) return null;
4
+ try {
5
+ const parsed = new URL(url);
6
+ return parsed.protocol === "https:" || parsed.protocol === "http:" ? parsed.href : null;
7
+ } catch {
8
+ return null;
9
+ }
10
+ }
11
+ function externalLink(url) {
12
+ const address = webAddress(url);
13
+ return address && address !== `${PLATFORM_DEFAULT}/` ? address : null;
14
+ }
15
+ export {
16
+ externalLink,
17
+ webAddress
18
+ };
19
+ //# sourceMappingURL=external-link.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/external-link.ts"],"sourcesContent":["const PLATFORM_DEFAULT = \"https://medialane.io\";\n\nexport function webAddress(url?: string | null): string | null {\n if (!url) return null;\n try {\n const parsed = new URL(url);\n return parsed.protocol === \"https:\" || parsed.protocol === \"http:\" ? parsed.href : null;\n } catch {\n return null;\n }\n}\n\nexport function externalLink(url?: string | null): string | null {\n const address = webAddress(url);\n return address && address !== `${PLATFORM_DEFAULT}/` ? address : null;\n}\n"],"mappings":"AAAA,MAAM,mBAAmB;AAElB,SAAS,WAAW,KAAoC;AAC7D,MAAI,CAAC,IAAK,QAAO;AACjB,MAAI;AACF,UAAM,SAAS,IAAI,IAAI,GAAG;AAC1B,WAAO,OAAO,aAAa,YAAY,OAAO,aAAa,UAAU,OAAO,OAAO;AAAA,EACrF,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,aAAa,KAAoC;AAC/D,QAAM,UAAU,WAAW,GAAG;AAC9B,SAAO,WAAW,YAAY,GAAG,gBAAgB,MAAM,UAAU;AACnE;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/ipfs-upload.ts"],"sourcesContent":["import { buildAssetMetadata, UserFacingError, type ApiClient, type BuildAssetMetadataInput } from \"@medialane/sdk\";\n\nexport const FILE_UPLOAD_FAILED =\n \"We couldn't upload your file. Check your connection and try again, or choose a different file.\";\n\nfunction uploadFailed(cause: unknown): UserFacingError {\n return Object.assign(new UserFacingError(FILE_UPLOAD_FAILED), { cause });\n}\n\nexport interface UploadedIpfsFile {\n cid: string;\n uri: string;\n}\n\nexport type SignedUploadKind = \"image\" | \"document\" | \"media\";\n\nexport interface UploadDiagnostics {\n kind: SignedUploadKind;\n fileSize: number;\n fileType: string;\n failedAfterMs: number;\n error: string;\n fileReadable: string;\n uploadHostReachable: string;\n retry: string;\n online: boolean | null;\n connection: string | null;\n}\n\nlet reportDiagnostics: ((diagnostics: UploadDiagnostics) => void) | null = null;\n\nexport function setUploadDiagnosticsReporter(reporter: ((diagnostics: UploadDiagnostics) => void) | null): void {\n reportDiagnostics = reporter;\n}\n\nfunction describe(err: unknown): string {\n const text = err instanceof Error ? `${err.name}: ${err.message}` : String(err);\n return text.slice(0, 300);\n}\n\nfunction connectionType(): string | null {\n if (typeof navigator === \"undefined\") return null;\n const connection = (navigator as Navigator & { connection?: { effectiveType?: string } }).connection;\n return connection?.effectiveType ?? null;\n}\n\nasync function signedUploadUrl(api: ApiClient, kind: SignedUploadKind): Promise<string> {\n const signedUrl = (await api.metadata.signedUrl(kind)).data?.url;\n if (!signedUrl) throw new Error(\"Failed to prepare the upload\");\n return signedUrl;\n}\n\nfunction postFile(signedUrl: string, file: File): Promise<Response> {\n const formData = new FormData();\n formData.append(\"file\", file, file.name);\n formData.append(\"network\", \"public\");\n formData.append(\"name\", file.name);\n return fetch(signedUrl, { method: \"POST\", body: formData });\n}\n\nasync function uploadedFile(res: Response): Promise<UploadedIpfsFile> {\n const uploadJson = (await res.json().catch(() => ({}))) as { data?: { cid?: string } };\n const cid = uploadJson.data?.cid;\n if (!res.ok || !cid) {\n throw uploadFailed(new Error(`File upload returned HTTP ${res.status}${cid ? \"\" : \" without a cid\"}`));\n }\n return { cid, uri: `ipfs://${cid}` };\n}\n\nasync function recoverUpload(\n api: ApiClient,\n file: File,\n kind: SignedUploadKind,\n signedUrl: string,\n err: unknown,\n failedAfterMs: number,\n): Promise<UploadedIpfsFile> {\n const diagnostics: UploadDiagnostics = {\n kind,\n fileSize: file.size,\n fileType: file.type,\n failedAfterMs,\n error: describe(err),\n fileReadable: \"not checked\",\n uploadHostReachable: \"not checked\",\n retry: \"not attempted\",\n online: typeof navigator === \"undefined\" ? null : navigator.onLine,\n connection: connectionType(),\n };\n\n let copy: File | null = null;\n try {\n copy = new File([await file.arrayBuffer()], file.name, { type: file.type });\n diagnostics.fileReadable = \"ok\";\n } catch (readErr) {\n diagnostics.fileReadable = describe(readErr);\n }\n\n try {\n await fetch(new URL(signedUrl).origin, { mode: \"no-cors\", cache: \"no-store\" });\n diagnostics.uploadHostReachable = \"ok\";\n } catch (probeErr) {\n diagnostics.uploadHostReachable = describe(probeErr);\n }\n\n let result: UploadedIpfsFile | null = null;\n if (copy) {\n try {\n result = await uploadedFile(await postFile(await signedUploadUrl(api, kind), copy));\n diagnostics.retry = \"ok\";\n } catch (retryErr) {\n diagnostics.retry = describe(retryErr instanceof UserFacingError && retryErr.cause ? retryErr.cause : retryErr);\n }\n }\n\n try {\n reportDiagnostics?.(diagnostics);\n } catch {}\n\n if (result) return result;\n throw Object.assign(uploadFailed(err), { diagnostics });\n}\n\nexport async function uploadFileToIpfs(\n api: ApiClient,\n file: File,\n kind: SignedUploadKind = \"image\",\n): Promise<UploadedIpfsFile> {\n const signedUrl = await signedUploadUrl(api, kind);\n const startedAt = Date.now();\n let uploadRes: Response;\n try {\n uploadRes = await postFile(signedUrl, file);\n } catch (err) {\n return recoverUpload(api, file, kind, signedUrl, err, Date.now() - startedAt);\n }\n return uploadedFile(uploadRes);\n}\n\nexport async function uploadJsonToIpfs(api: ApiClient, payload: unknown): Promise<string> {\n const uri = (await api.metadata.upload(payload as Record<string, unknown>)).data?.url;\n if (!uri) throw new Error(\"Metadata upload failed\");\n return uri;\n}\n\nexport function uploadDirectoryToIpfs(\n api: ApiClient,\n files: { name: string; content: unknown }[],\n): Promise<{ cid: string; baseUri: string }> {\n return api.metadata.uploadDirectory(files);\n}\n\nexport function isUserRejection(err: unknown): boolean {\n const msg = err instanceof Error ? err.message : String(err ?? \"\");\n return /reject|denied|declin|abort|cancel|refus/i.test(msg);\n}\n\nexport function uploadFailureToast(err: unknown): { title: string; description?: string } {\n if (isUserRejection(err)) {\n return {\n title: \"Signature declined\",\n description: \"Try again and approve the request in your wallet.\",\n };\n }\n return {\n title: \"Upload failed\",\n description: err instanceof Error ? err.message : undefined,\n };\n}\n\nexport interface PinAssetMetadataInput extends Omit<BuildAssetMetadataInput, \"registrationDate\"> {\n imageFile?: File | null;\n}\n\nexport interface PinnedAsset {\n uri: string;\n imageUri: string | null;\n}\n\nexport async function pinAssetMetadata(api: ApiClient, input: PinAssetMetadataInput): Promise<PinnedAsset> {\n const { imageFile, ...fields } = input;\n\n let imageUri = fields.imageUri ?? null;\n if (!imageUri && imageFile && imageFile.size > 0) {\n imageUri = (await uploadFileToIpfs(api, imageFile)).uri;\n }\n\n const uri = await uploadJsonToIpfs(\n api,\n buildAssetMetadata({\n ...fields,\n imageUri,\n externalUrl: fields.externalUrl || \"https://medialane.io\",\n }),\n );\n\n return { uri, imageUri };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/utils/ipfs-upload.ts"],"sourcesContent":["import { buildAssetMetadata, UserFacingError, type ApiClient, type BuildAssetMetadataInput } from \"@medialane/sdk\";\n\nexport const FILE_UPLOAD_FAILED =\n \"We couldn't upload your file. Check your connection and try again, or choose a different file.\";\n\nfunction uploadFailed(cause: unknown): UserFacingError {\n return Object.assign(new UserFacingError(FILE_UPLOAD_FAILED), { cause });\n}\n\nexport interface UploadedIpfsFile {\n cid: string;\n uri: string;\n}\n\nexport type SignedUploadKind = \"image\" | \"document\" | \"media\";\n\nexport interface UploadDiagnostics {\n kind: SignedUploadKind;\n fileSize: number;\n fileType: string;\n failedAfterMs: number;\n error: string;\n fileReadable: string;\n uploadHostReachable: string;\n retry: string;\n online: boolean | null;\n connection: string | null;\n}\n\nlet reportDiagnostics: ((diagnostics: UploadDiagnostics) => void) | null = null;\n\nexport function setUploadDiagnosticsReporter(reporter: ((diagnostics: UploadDiagnostics) => void) | null): void {\n reportDiagnostics = reporter;\n}\n\nfunction describe(err: unknown): string {\n const text = err instanceof Error ? `${err.name}: ${err.message}` : String(err);\n return text.slice(0, 300);\n}\n\nfunction connectionType(): string | null {\n if (typeof navigator === \"undefined\") return null;\n const connection = (navigator as Navigator & { connection?: { effectiveType?: string } }).connection;\n return connection?.effectiveType ?? null;\n}\n\nasync function signedUploadUrl(api: ApiClient, kind: SignedUploadKind): Promise<string> {\n const signedUrl = (await api.metadata.signedUrl(kind)).data?.url;\n if (!signedUrl) throw new Error(\"Failed to prepare the upload\");\n return signedUrl;\n}\n\nfunction postFile(signedUrl: string, file: File): Promise<Response> {\n const formData = new FormData();\n formData.append(\"file\", file, file.name);\n formData.append(\"network\", \"public\");\n formData.append(\"name\", file.name);\n return fetch(signedUrl, { method: \"POST\", body: formData });\n}\n\nasync function uploadedFile(res: Response): Promise<UploadedIpfsFile> {\n const uploadJson = (await res.json().catch(() => ({}))) as { data?: { cid?: string } };\n const cid = uploadJson.data?.cid;\n if (!res.ok || !cid) {\n throw uploadFailed(new Error(`File upload returned HTTP ${res.status}${cid ? \"\" : \" without a cid\"}`));\n }\n return { cid, uri: `ipfs://${cid}` };\n}\n\nasync function recoverUpload(\n api: ApiClient,\n file: File,\n kind: SignedUploadKind,\n signedUrl: string,\n err: unknown,\n failedAfterMs: number,\n): Promise<UploadedIpfsFile> {\n const diagnostics: UploadDiagnostics = {\n kind,\n fileSize: file.size,\n fileType: file.type,\n failedAfterMs,\n error: describe(err),\n fileReadable: \"not checked\",\n uploadHostReachable: \"not checked\",\n retry: \"not attempted\",\n online: typeof navigator === \"undefined\" ? null : navigator.onLine,\n connection: connectionType(),\n };\n\n let copy: File | null = null;\n try {\n copy = new File([await file.arrayBuffer()], file.name, { type: file.type });\n diagnostics.fileReadable = \"ok\";\n } catch (readErr) {\n diagnostics.fileReadable = describe(readErr);\n }\n\n try {\n await fetch(new URL(signedUrl).origin, { mode: \"no-cors\", cache: \"no-store\" });\n diagnostics.uploadHostReachable = \"ok\";\n } catch (probeErr) {\n diagnostics.uploadHostReachable = describe(probeErr);\n }\n\n let result: UploadedIpfsFile | null = null;\n if (copy) {\n try {\n result = await uploadedFile(await postFile(await signedUploadUrl(api, kind), copy));\n diagnostics.retry = \"ok\";\n } catch (retryErr) {\n diagnostics.retry = describe(retryErr instanceof UserFacingError && retryErr.cause ? retryErr.cause : retryErr);\n }\n }\n\n try {\n reportDiagnostics?.(diagnostics);\n } catch {}\n\n if (result) return result;\n throw Object.assign(uploadFailed(err), { diagnostics });\n}\n\nexport async function uploadFileToIpfs(\n api: ApiClient,\n file: File,\n kind: SignedUploadKind = \"image\",\n): Promise<UploadedIpfsFile> {\n const signedUrl = await signedUploadUrl(api, kind);\n const startedAt = Date.now();\n let uploadRes: Response;\n try {\n uploadRes = await postFile(signedUrl, file);\n } catch (err) {\n return recoverUpload(api, file, kind, signedUrl, err, Date.now() - startedAt);\n }\n return uploadedFile(uploadRes);\n}\n\nexport async function uploadJsonToIpfs(api: ApiClient, payload: unknown): Promise<string> {\n const uri = (await api.metadata.upload(payload as Record<string, unknown>)).data?.url;\n if (!uri) throw new Error(\"Metadata upload failed\");\n return uri;\n}\n\nexport function uploadDirectoryToIpfs(\n api: ApiClient,\n files: { name: string; content: unknown }[],\n): Promise<{ cid: string; baseUri: string }> {\n return api.metadata.uploadDirectory(files);\n}\n\nexport function isUserRejection(err: unknown): boolean {\n const msg = err instanceof Error ? err.message : String(err ?? \"\");\n return /reject|denied|declin|abort|cancel|refus/i.test(msg);\n}\n\nexport function uploadFailureToast(err: unknown): { title: string; description?: string } {\n if (isUserRejection(err)) {\n return {\n title: \"Signature declined\",\n description: \"Try again and approve the request in your wallet.\",\n };\n }\n return {\n title: \"Upload failed\",\n description: err instanceof Error ? err.message : undefined,\n };\n}\n\nexport interface PinAssetMetadataInput extends BuildAssetMetadataInput {\n imageFile?: File | null;\n}\n\nexport interface PinnedAsset {\n uri: string;\n imageUri: string | null;\n}\n\nexport async function pinAssetMetadata(api: ApiClient, input: PinAssetMetadataInput): Promise<PinnedAsset> {\n const { imageFile, ...fields } = input;\n\n let imageUri = fields.imageUri ?? null;\n if (!imageUri && imageFile && imageFile.size > 0) {\n imageUri = (await uploadFileToIpfs(api, imageFile)).uri;\n }\n\n const uri = await uploadJsonToIpfs(\n api,\n buildAssetMetadata({\n ...fields,\n imageUri,\n externalUrl: fields.externalUrl || \"https://medialane.io\",\n }),\n );\n\n return { uri, imageUri };\n}\n"],"mappings":"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","names":[]}
@@ -33,7 +33,7 @@ declare function uploadFailureToast(err: unknown): {
33
33
  title: string;
34
34
  description?: string;
35
35
  };
36
- interface PinAssetMetadataInput extends Omit<BuildAssetMetadataInput, "registrationDate"> {
36
+ interface PinAssetMetadataInput extends BuildAssetMetadataInput {
37
37
  imageFile?: File | null;
38
38
  }
39
39
  interface PinnedAsset {
@@ -33,7 +33,7 @@ declare function uploadFailureToast(err: unknown): {
33
33
  title: string;
34
34
  description?: string;
35
35
  };
36
- interface PinAssetMetadataInput extends Omit<BuildAssetMetadataInput, "registrationDate"> {
36
+ interface PinAssetMetadataInput extends BuildAssetMetadataInput {
37
37
  imageFile?: File | null;
38
38
  }
39
39
  interface PinnedAsset {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/ipfs-upload.ts"],"sourcesContent":["import { buildAssetMetadata, UserFacingError, type ApiClient, type BuildAssetMetadataInput } from \"@medialane/sdk\";\n\nexport const FILE_UPLOAD_FAILED =\n \"We couldn't upload your file. Check your connection and try again, or choose a different file.\";\n\nfunction uploadFailed(cause: unknown): UserFacingError {\n return Object.assign(new UserFacingError(FILE_UPLOAD_FAILED), { cause });\n}\n\nexport interface UploadedIpfsFile {\n cid: string;\n uri: string;\n}\n\nexport type SignedUploadKind = \"image\" | \"document\" | \"media\";\n\nexport interface UploadDiagnostics {\n kind: SignedUploadKind;\n fileSize: number;\n fileType: string;\n failedAfterMs: number;\n error: string;\n fileReadable: string;\n uploadHostReachable: string;\n retry: string;\n online: boolean | null;\n connection: string | null;\n}\n\nlet reportDiagnostics: ((diagnostics: UploadDiagnostics) => void) | null = null;\n\nexport function setUploadDiagnosticsReporter(reporter: ((diagnostics: UploadDiagnostics) => void) | null): void {\n reportDiagnostics = reporter;\n}\n\nfunction describe(err: unknown): string {\n const text = err instanceof Error ? `${err.name}: ${err.message}` : String(err);\n return text.slice(0, 300);\n}\n\nfunction connectionType(): string | null {\n if (typeof navigator === \"undefined\") return null;\n const connection = (navigator as Navigator & { connection?: { effectiveType?: string } }).connection;\n return connection?.effectiveType ?? null;\n}\n\nasync function signedUploadUrl(api: ApiClient, kind: SignedUploadKind): Promise<string> {\n const signedUrl = (await api.metadata.signedUrl(kind)).data?.url;\n if (!signedUrl) throw new Error(\"Failed to prepare the upload\");\n return signedUrl;\n}\n\nfunction postFile(signedUrl: string, file: File): Promise<Response> {\n const formData = new FormData();\n formData.append(\"file\", file, file.name);\n formData.append(\"network\", \"public\");\n formData.append(\"name\", file.name);\n return fetch(signedUrl, { method: \"POST\", body: formData });\n}\n\nasync function uploadedFile(res: Response): Promise<UploadedIpfsFile> {\n const uploadJson = (await res.json().catch(() => ({}))) as { data?: { cid?: string } };\n const cid = uploadJson.data?.cid;\n if (!res.ok || !cid) {\n throw uploadFailed(new Error(`File upload returned HTTP ${res.status}${cid ? \"\" : \" without a cid\"}`));\n }\n return { cid, uri: `ipfs://${cid}` };\n}\n\nasync function recoverUpload(\n api: ApiClient,\n file: File,\n kind: SignedUploadKind,\n signedUrl: string,\n err: unknown,\n failedAfterMs: number,\n): Promise<UploadedIpfsFile> {\n const diagnostics: UploadDiagnostics = {\n kind,\n fileSize: file.size,\n fileType: file.type,\n failedAfterMs,\n error: describe(err),\n fileReadable: \"not checked\",\n uploadHostReachable: \"not checked\",\n retry: \"not attempted\",\n online: typeof navigator === \"undefined\" ? null : navigator.onLine,\n connection: connectionType(),\n };\n\n let copy: File | null = null;\n try {\n copy = new File([await file.arrayBuffer()], file.name, { type: file.type });\n diagnostics.fileReadable = \"ok\";\n } catch (readErr) {\n diagnostics.fileReadable = describe(readErr);\n }\n\n try {\n await fetch(new URL(signedUrl).origin, { mode: \"no-cors\", cache: \"no-store\" });\n diagnostics.uploadHostReachable = \"ok\";\n } catch (probeErr) {\n diagnostics.uploadHostReachable = describe(probeErr);\n }\n\n let result: UploadedIpfsFile | null = null;\n if (copy) {\n try {\n result = await uploadedFile(await postFile(await signedUploadUrl(api, kind), copy));\n diagnostics.retry = \"ok\";\n } catch (retryErr) {\n diagnostics.retry = describe(retryErr instanceof UserFacingError && retryErr.cause ? retryErr.cause : retryErr);\n }\n }\n\n try {\n reportDiagnostics?.(diagnostics);\n } catch {}\n\n if (result) return result;\n throw Object.assign(uploadFailed(err), { diagnostics });\n}\n\nexport async function uploadFileToIpfs(\n api: ApiClient,\n file: File,\n kind: SignedUploadKind = \"image\",\n): Promise<UploadedIpfsFile> {\n const signedUrl = await signedUploadUrl(api, kind);\n const startedAt = Date.now();\n let uploadRes: Response;\n try {\n uploadRes = await postFile(signedUrl, file);\n } catch (err) {\n return recoverUpload(api, file, kind, signedUrl, err, Date.now() - startedAt);\n }\n return uploadedFile(uploadRes);\n}\n\nexport async function uploadJsonToIpfs(api: ApiClient, payload: unknown): Promise<string> {\n const uri = (await api.metadata.upload(payload as Record<string, unknown>)).data?.url;\n if (!uri) throw new Error(\"Metadata upload failed\");\n return uri;\n}\n\nexport function uploadDirectoryToIpfs(\n api: ApiClient,\n files: { name: string; content: unknown }[],\n): Promise<{ cid: string; baseUri: string }> {\n return api.metadata.uploadDirectory(files);\n}\n\nexport function isUserRejection(err: unknown): boolean {\n const msg = err instanceof Error ? err.message : String(err ?? \"\");\n return /reject|denied|declin|abort|cancel|refus/i.test(msg);\n}\n\nexport function uploadFailureToast(err: unknown): { title: string; description?: string } {\n if (isUserRejection(err)) {\n return {\n title: \"Signature declined\",\n description: \"Try again and approve the request in your wallet.\",\n };\n }\n return {\n title: \"Upload failed\",\n description: err instanceof Error ? err.message : undefined,\n };\n}\n\nexport interface PinAssetMetadataInput extends Omit<BuildAssetMetadataInput, \"registrationDate\"> {\n imageFile?: File | null;\n}\n\nexport interface PinnedAsset {\n uri: string;\n imageUri: string | null;\n}\n\nexport async function pinAssetMetadata(api: ApiClient, input: PinAssetMetadataInput): Promise<PinnedAsset> {\n const { imageFile, ...fields } = input;\n\n let imageUri = fields.imageUri ?? null;\n if (!imageUri && imageFile && imageFile.size > 0) {\n imageUri = (await uploadFileToIpfs(api, imageFile)).uri;\n }\n\n const uri = await uploadJsonToIpfs(\n api,\n buildAssetMetadata({\n ...fields,\n imageUri,\n externalUrl: fields.externalUrl || \"https://medialane.io\",\n }),\n );\n\n return { uri, imageUri };\n}\n"],"mappings":"AAAA,SAAS,oBAAoB,uBAAqE;AAE3F,MAAM,qBACX;AAEF,SAAS,aAAa,OAAiC;AACrD,SAAO,OAAO,OAAO,IAAI,gBAAgB,kBAAkB,GAAG,EAAE,MAAM,CAAC;AACzE;AAsBA,IAAI,oBAAuE;AAEpE,SAAS,6BAA6B,UAAmE;AAC9G,sBAAoB;AACtB;AAEA,SAAS,SAAS,KAAsB;AACtC,QAAM,OAAO,eAAe,QAAQ,GAAG,IAAI,IAAI,KAAK,IAAI,OAAO,KAAK,OAAO,GAAG;AAC9E,SAAO,KAAK,MAAM,GAAG,GAAG;AAC1B;AAEA,SAAS,iBAAgC;AACvC,MAAI,OAAO,cAAc,YAAa,QAAO;AAC7C,QAAM,aAAc,UAAsE;AAC1F,SAAO,YAAY,iBAAiB;AACtC;AAEA,eAAe,gBAAgB,KAAgB,MAAyC;AACtF,QAAM,aAAa,MAAM,IAAI,SAAS,UAAU,IAAI,GAAG,MAAM;AAC7D,MAAI,CAAC,UAAW,OAAM,IAAI,MAAM,8BAA8B;AAC9D,SAAO;AACT;AAEA,SAAS,SAAS,WAAmB,MAA+B;AAClE,QAAM,WAAW,IAAI,SAAS;AAC9B,WAAS,OAAO,QAAQ,MAAM,KAAK,IAAI;AACvC,WAAS,OAAO,WAAW,QAAQ;AACnC,WAAS,OAAO,QAAQ,KAAK,IAAI;AACjC,SAAO,MAAM,WAAW,EAAE,QAAQ,QAAQ,MAAM,SAAS,CAAC;AAC5D;AAEA,eAAe,aAAa,KAA0C;AACpE,QAAM,aAAc,MAAM,IAAI,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AACrD,QAAM,MAAM,WAAW,MAAM;AAC7B,MAAI,CAAC,IAAI,MAAM,CAAC,KAAK;AACnB,UAAM,aAAa,IAAI,MAAM,6BAA6B,IAAI,MAAM,GAAG,MAAM,KAAK,gBAAgB,EAAE,CAAC;AAAA,EACvG;AACA,SAAO,EAAE,KAAK,KAAK,UAAU,GAAG,GAAG;AACrC;AAEA,eAAe,cACb,KACA,MACA,MACA,WACA,KACA,eAC2B;AAC3B,QAAM,cAAiC;AAAA,IACrC;AAAA,IACA,UAAU,KAAK;AAAA,IACf,UAAU,KAAK;AAAA,IACf;AAAA,IACA,OAAO,SAAS,GAAG;AAAA,IACnB,cAAc;AAAA,IACd,qBAAqB;AAAA,IACrB,OAAO;AAAA,IACP,QAAQ,OAAO,cAAc,cAAc,OAAO,UAAU;AAAA,IAC5D,YAAY,eAAe;AAAA,EAC7B;AAEA,MAAI,OAAoB;AACxB,MAAI;AACF,WAAO,IAAI,KAAK,CAAC,MAAM,KAAK,YAAY,CAAC,GAAG,KAAK,MAAM,EAAE,MAAM,KAAK,KAAK,CAAC;AAC1E,gBAAY,eAAe;AAAA,EAC7B,SAAS,SAAS;AAChB,gBAAY,eAAe,SAAS,OAAO;AAAA,EAC7C;AAEA,MAAI;AACF,UAAM,MAAM,IAAI,IAAI,SAAS,EAAE,QAAQ,EAAE,MAAM,WAAW,OAAO,WAAW,CAAC;AAC7E,gBAAY,sBAAsB;AAAA,EACpC,SAAS,UAAU;AACjB,gBAAY,sBAAsB,SAAS,QAAQ;AAAA,EACrD;AAEA,MAAI,SAAkC;AACtC,MAAI,MAAM;AACR,QAAI;AACF,eAAS,MAAM,aAAa,MAAM,SAAS,MAAM,gBAAgB,KAAK,IAAI,GAAG,IAAI,CAAC;AAClF,kBAAY,QAAQ;AAAA,IACtB,SAAS,UAAU;AACjB,kBAAY,QAAQ,SAAS,oBAAoB,mBAAmB,SAAS,QAAQ,SAAS,QAAQ,QAAQ;AAAA,IAChH;AAAA,EACF;AAEA,MAAI;AACF,wBAAoB,WAAW;AAAA,EACjC,QAAQ;AAAA,EAAC;AAET,MAAI,OAAQ,QAAO;AACnB,QAAM,OAAO,OAAO,aAAa,GAAG,GAAG,EAAE,YAAY,CAAC;AACxD;AAEA,eAAsB,iBACpB,KACA,MACA,OAAyB,SACE;AAC3B,QAAM,YAAY,MAAM,gBAAgB,KAAK,IAAI;AACjD,QAAM,YAAY,KAAK,IAAI;AAC3B,MAAI;AACJ,MAAI;AACF,gBAAY,MAAM,SAAS,WAAW,IAAI;AAAA,EAC5C,SAAS,KAAK;AACZ,WAAO,cAAc,KAAK,MAAM,MAAM,WAAW,KAAK,KAAK,IAAI,IAAI,SAAS;AAAA,EAC9E;AACA,SAAO,aAAa,SAAS;AAC/B;AAEA,eAAsB,iBAAiB,KAAgB,SAAmC;AACxF,QAAM,OAAO,MAAM,IAAI,SAAS,OAAO,OAAkC,GAAG,MAAM;AAClF,MAAI,CAAC,IAAK,OAAM,IAAI,MAAM,wBAAwB;AAClD,SAAO;AACT;AAEO,SAAS,sBACd,KACA,OAC2C;AAC3C,SAAO,IAAI,SAAS,gBAAgB,KAAK;AAC3C;AAEO,SAAS,gBAAgB,KAAuB;AACrD,QAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,OAAO,EAAE;AACjE,SAAO,2CAA2C,KAAK,GAAG;AAC5D;AAEO,SAAS,mBAAmB,KAAuD;AACxF,MAAI,gBAAgB,GAAG,GAAG;AACxB,WAAO;AAAA,MACL,OAAO;AAAA,MACP,aAAa;AAAA,IACf;AAAA,EACF;AACA,SAAO;AAAA,IACL,OAAO;AAAA,IACP,aAAa,eAAe,QAAQ,IAAI,UAAU;AAAA,EACpD;AACF;AAWA,eAAsB,iBAAiB,KAAgB,OAAoD;AACzG,QAAM,EAAE,WAAW,GAAG,OAAO,IAAI;AAEjC,MAAI,WAAW,OAAO,YAAY;AAClC,MAAI,CAAC,YAAY,aAAa,UAAU,OAAO,GAAG;AAChD,gBAAY,MAAM,iBAAiB,KAAK,SAAS,GAAG;AAAA,EACtD;AAEA,QAAM,MAAM,MAAM;AAAA,IAChB;AAAA,IACA,mBAAmB;AAAA,MACjB,GAAG;AAAA,MACH;AAAA,MACA,aAAa,OAAO,eAAe;AAAA,IACrC,CAAC;AAAA,EACH;AAEA,SAAO,EAAE,KAAK,SAAS;AACzB;","names":[]}
1
+ {"version":3,"sources":["../../src/utils/ipfs-upload.ts"],"sourcesContent":["import { buildAssetMetadata, UserFacingError, type ApiClient, type BuildAssetMetadataInput } from \"@medialane/sdk\";\n\nexport const FILE_UPLOAD_FAILED =\n \"We couldn't upload your file. Check your connection and try again, or choose a different file.\";\n\nfunction uploadFailed(cause: unknown): UserFacingError {\n return Object.assign(new UserFacingError(FILE_UPLOAD_FAILED), { cause });\n}\n\nexport interface UploadedIpfsFile {\n cid: string;\n uri: string;\n}\n\nexport type SignedUploadKind = \"image\" | \"document\" | \"media\";\n\nexport interface UploadDiagnostics {\n kind: SignedUploadKind;\n fileSize: number;\n fileType: string;\n failedAfterMs: number;\n error: string;\n fileReadable: string;\n uploadHostReachable: string;\n retry: string;\n online: boolean | null;\n connection: string | null;\n}\n\nlet reportDiagnostics: ((diagnostics: UploadDiagnostics) => void) | null = null;\n\nexport function setUploadDiagnosticsReporter(reporter: ((diagnostics: UploadDiagnostics) => void) | null): void {\n reportDiagnostics = reporter;\n}\n\nfunction describe(err: unknown): string {\n const text = err instanceof Error ? `${err.name}: ${err.message}` : String(err);\n return text.slice(0, 300);\n}\n\nfunction connectionType(): string | null {\n if (typeof navigator === \"undefined\") return null;\n const connection = (navigator as Navigator & { connection?: { effectiveType?: string } }).connection;\n return connection?.effectiveType ?? null;\n}\n\nasync function signedUploadUrl(api: ApiClient, kind: SignedUploadKind): Promise<string> {\n const signedUrl = (await api.metadata.signedUrl(kind)).data?.url;\n if (!signedUrl) throw new Error(\"Failed to prepare the upload\");\n return signedUrl;\n}\n\nfunction postFile(signedUrl: string, file: File): Promise<Response> {\n const formData = new FormData();\n formData.append(\"file\", file, file.name);\n formData.append(\"network\", \"public\");\n formData.append(\"name\", file.name);\n return fetch(signedUrl, { method: \"POST\", body: formData });\n}\n\nasync function uploadedFile(res: Response): Promise<UploadedIpfsFile> {\n const uploadJson = (await res.json().catch(() => ({}))) as { data?: { cid?: string } };\n const cid = uploadJson.data?.cid;\n if (!res.ok || !cid) {\n throw uploadFailed(new Error(`File upload returned HTTP ${res.status}${cid ? \"\" : \" without a cid\"}`));\n }\n return { cid, uri: `ipfs://${cid}` };\n}\n\nasync function recoverUpload(\n api: ApiClient,\n file: File,\n kind: SignedUploadKind,\n signedUrl: string,\n err: unknown,\n failedAfterMs: number,\n): Promise<UploadedIpfsFile> {\n const diagnostics: UploadDiagnostics = {\n kind,\n fileSize: file.size,\n fileType: file.type,\n failedAfterMs,\n error: describe(err),\n fileReadable: \"not checked\",\n uploadHostReachable: \"not checked\",\n retry: \"not attempted\",\n online: typeof navigator === \"undefined\" ? null : navigator.onLine,\n connection: connectionType(),\n };\n\n let copy: File | null = null;\n try {\n copy = new File([await file.arrayBuffer()], file.name, { type: file.type });\n diagnostics.fileReadable = \"ok\";\n } catch (readErr) {\n diagnostics.fileReadable = describe(readErr);\n }\n\n try {\n await fetch(new URL(signedUrl).origin, { mode: \"no-cors\", cache: \"no-store\" });\n diagnostics.uploadHostReachable = \"ok\";\n } catch (probeErr) {\n diagnostics.uploadHostReachable = describe(probeErr);\n }\n\n let result: UploadedIpfsFile | null = null;\n if (copy) {\n try {\n result = await uploadedFile(await postFile(await signedUploadUrl(api, kind), copy));\n diagnostics.retry = \"ok\";\n } catch (retryErr) {\n diagnostics.retry = describe(retryErr instanceof UserFacingError && retryErr.cause ? retryErr.cause : retryErr);\n }\n }\n\n try {\n reportDiagnostics?.(diagnostics);\n } catch {}\n\n if (result) return result;\n throw Object.assign(uploadFailed(err), { diagnostics });\n}\n\nexport async function uploadFileToIpfs(\n api: ApiClient,\n file: File,\n kind: SignedUploadKind = \"image\",\n): Promise<UploadedIpfsFile> {\n const signedUrl = await signedUploadUrl(api, kind);\n const startedAt = Date.now();\n let uploadRes: Response;\n try {\n uploadRes = await postFile(signedUrl, file);\n } catch (err) {\n return recoverUpload(api, file, kind, signedUrl, err, Date.now() - startedAt);\n }\n return uploadedFile(uploadRes);\n}\n\nexport async function uploadJsonToIpfs(api: ApiClient, payload: unknown): Promise<string> {\n const uri = (await api.metadata.upload(payload as Record<string, unknown>)).data?.url;\n if (!uri) throw new Error(\"Metadata upload failed\");\n return uri;\n}\n\nexport function uploadDirectoryToIpfs(\n api: ApiClient,\n files: { name: string; content: unknown }[],\n): Promise<{ cid: string; baseUri: string }> {\n return api.metadata.uploadDirectory(files);\n}\n\nexport function isUserRejection(err: unknown): boolean {\n const msg = err instanceof Error ? err.message : String(err ?? \"\");\n return /reject|denied|declin|abort|cancel|refus/i.test(msg);\n}\n\nexport function uploadFailureToast(err: unknown): { title: string; description?: string } {\n if (isUserRejection(err)) {\n return {\n title: \"Signature declined\",\n description: \"Try again and approve the request in your wallet.\",\n };\n }\n return {\n title: \"Upload failed\",\n description: err instanceof Error ? err.message : undefined,\n };\n}\n\nexport interface PinAssetMetadataInput extends BuildAssetMetadataInput {\n imageFile?: File | null;\n}\n\nexport interface PinnedAsset {\n uri: string;\n imageUri: string | null;\n}\n\nexport async function pinAssetMetadata(api: ApiClient, input: PinAssetMetadataInput): Promise<PinnedAsset> {\n const { imageFile, ...fields } = input;\n\n let imageUri = fields.imageUri ?? null;\n if (!imageUri && imageFile && imageFile.size > 0) {\n imageUri = (await uploadFileToIpfs(api, imageFile)).uri;\n }\n\n const uri = await uploadJsonToIpfs(\n api,\n buildAssetMetadata({\n ...fields,\n imageUri,\n externalUrl: fields.externalUrl || \"https://medialane.io\",\n }),\n );\n\n return { uri, imageUri };\n}\n"],"mappings":"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","names":[]}
@@ -228,6 +228,7 @@ declare function useCollectionTokens(contract: string | null, page?: number, lim
228
228
  ipType: string | null;
229
229
  licenseType: string | null;
230
230
  commercialUse: boolean | null;
231
+ externalUrl: string | null;
231
232
  };
232
233
  balances: {
233
234
  amount: string;
@@ -315,6 +316,7 @@ declare function useCollectionTokens(contract: string | null, page?: number, lim
315
316
  ipType: string | null;
316
317
  licenseType: string | null;
317
318
  commercialUse: boolean | null;
319
+ externalUrl: string | null;
318
320
  };
319
321
  balances: {
320
322
  amount: string;
@@ -401,6 +403,7 @@ declare function useNearbyCollectionTokens(contract: string | null, currentToken
401
403
  ipType: string | null;
402
404
  licenseType: string | null;
403
405
  commercialUse: boolean | null;
406
+ externalUrl: string | null;
404
407
  };
405
408
  balances: {
406
409
  amount: string;
@@ -228,6 +228,7 @@ declare function useCollectionTokens(contract: string | null, page?: number, lim
228
228
  ipType: string | null;
229
229
  licenseType: string | null;
230
230
  commercialUse: boolean | null;
231
+ externalUrl: string | null;
231
232
  };
232
233
  balances: {
233
234
  amount: string;
@@ -315,6 +316,7 @@ declare function useCollectionTokens(contract: string | null, page?: number, lim
315
316
  ipType: string | null;
316
317
  licenseType: string | null;
317
318
  commercialUse: boolean | null;
319
+ externalUrl: string | null;
318
320
  };
319
321
  balances: {
320
322
  amount: string;
@@ -401,6 +403,7 @@ declare function useNearbyCollectionTokens(contract: string | null, currentToken
401
403
  ipType: string | null;
402
404
  licenseType: string | null;
403
405
  commercialUse: boolean | null;
406
+ externalUrl: string | null;
404
407
  };
405
408
  balances: {
406
409
  amount: string;
@@ -29,6 +29,7 @@ declare function useTokensByIpType(ipTypeSlug: string | null, page?: number, lim
29
29
  ipType: string | null;
30
30
  licenseType: string | null;
31
31
  commercialUse: boolean | null;
32
+ externalUrl: string | null;
32
33
  };
33
34
  balances: {
34
35
  amount: string;
@@ -116,6 +117,7 @@ declare function useTokensByIpType(ipTypeSlug: string | null, page?: number, lim
116
117
  ipType: string | null;
117
118
  licenseType: string | null;
118
119
  commercialUse: boolean | null;
120
+ externalUrl: string | null;
119
121
  };
120
122
  balances: {
121
123
  amount: string;
@@ -29,6 +29,7 @@ declare function useTokensByIpType(ipTypeSlug: string | null, page?: number, lim
29
29
  ipType: string | null;
30
30
  licenseType: string | null;
31
31
  commercialUse: boolean | null;
32
+ externalUrl: string | null;
32
33
  };
33
34
  balances: {
34
35
  amount: string;
@@ -116,6 +117,7 @@ declare function useTokensByIpType(ipTypeSlug: string | null, page?: number, lim
116
117
  ipType: string | null;
117
118
  licenseType: string | null;
118
119
  commercialUse: boolean | null;
120
+ externalUrl: string | null;
119
121
  };
120
122
  balances: {
121
123
  amount: string;
@@ -28,6 +28,7 @@ declare function useToken(contract: string | null, tokenId: string | null): {
28
28
  ipType: string | null;
29
29
  licenseType: string | null;
30
30
  commercialUse: boolean | null;
31
+ externalUrl: string | null;
31
32
  };
32
33
  balances: {
33
34
  amount: string;
@@ -115,6 +116,7 @@ declare function useToken(contract: string | null, tokenId: string | null): {
115
116
  ipType: string | null;
116
117
  licenseType: string | null;
117
118
  commercialUse: boolean | null;
119
+ externalUrl: string | null;
118
120
  };
119
121
  balances: {
120
122
  amount: string;
@@ -205,6 +207,7 @@ declare function useTokensByOwner(address: string | null, page?: number, limit?:
205
207
  ipType: string | null;
206
208
  licenseType: string | null;
207
209
  commercialUse: boolean | null;
210
+ externalUrl: string | null;
208
211
  };
209
212
  balances: {
210
213
  amount: string;
@@ -292,6 +295,7 @@ declare function useTokensByOwner(address: string | null, page?: number, limit?:
292
295
  ipType: string | null;
293
296
  licenseType: string | null;
294
297
  commercialUse: boolean | null;
298
+ externalUrl: string | null;
295
299
  };
296
300
  balances: {
297
301
  amount: string;
@@ -28,6 +28,7 @@ declare function useToken(contract: string | null, tokenId: string | null): {
28
28
  ipType: string | null;
29
29
  licenseType: string | null;
30
30
  commercialUse: boolean | null;
31
+ externalUrl: string | null;
31
32
  };
32
33
  balances: {
33
34
  amount: string;
@@ -115,6 +116,7 @@ declare function useToken(contract: string | null, tokenId: string | null): {
115
116
  ipType: string | null;
116
117
  licenseType: string | null;
117
118
  commercialUse: boolean | null;
119
+ externalUrl: string | null;
118
120
  };
119
121
  balances: {
120
122
  amount: string;
@@ -205,6 +207,7 @@ declare function useTokensByOwner(address: string | null, page?: number, limit?:
205
207
  ipType: string | null;
206
208
  licenseType: string | null;
207
209
  commercialUse: boolean | null;
210
+ externalUrl: string | null;
208
211
  };
209
212
  balances: {
210
213
  amount: string;
@@ -292,6 +295,7 @@ declare function useTokensByOwner(address: string | null, page?: number, limit?:
292
295
  ipType: string | null;
293
296
  licenseType: string | null;
294
297
  commercialUse: boolean | null;
298
+ externalUrl: string | null;
295
299
  };
296
300
  balances: {
297
301
  amount: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@medialane/ui",
3
- "version": "0.250.0",
3
+ "version": "0.252.0",
4
4
  "description": "Shared UI components for Medialane apps",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -51,7 +51,7 @@
51
51
  "preview": "vite --config preview/vite.config.ts"
52
52
  },
53
53
  "peerDependencies": {
54
- "@medialane/sdk": ">=0.203.0 <0.204.0",
54
+ "@medialane/sdk": ">=0.205.0 <0.206.0",
55
55
  "@radix-ui/react-checkbox": ">=1.1.0",
56
56
  "@radix-ui/react-collapsible": ">=1.1.0",
57
57
  "@radix-ui/react-dialog": ">=1.1.0",
@@ -85,7 +85,7 @@
85
85
  "devDependencies": {
86
86
  "@happy-dom/global-registrator": "^20.14.5",
87
87
  "@hookform/resolvers": "^3.10.0",
88
- "@medialane/sdk": "0.203.0",
88
+ "@medialane/sdk": "0.205.0",
89
89
  "@radix-ui/react-checkbox": "^1.3.8",
90
90
  "@radix-ui/react-collapsible": "^1.1.17",
91
91
  "@radix-ui/react-dialog": "^1.1.20",