Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 52 additions & 11 deletions src/hooks/useProofSubmit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@
ipfsPending?: boolean;
}

/**
* Type guard to check if an error is a ProofUploadError with attached CIDs
*/
function isProofUploadError(err: unknown): err is ProofUploadError {

Check failure on line 29 in src/hooks/useProofSubmit.ts

View workflow job for this annotation

GitHub Actions / lint

'isProofUploadError' is defined but never used
return err instanceof Error && 'photoCid' in err && 'metadataCid' in err;
}

export type ProofSubmitResult =
| {
status: 'success';
Expand Down Expand Up @@ -136,6 +143,29 @@
return { photoCid, metadataCid, ipfsPending };
}

/**
* React Native FormData file type
* Matches the structure React Native expects for FormData.append with a file
*/
interface ReactNativeFile {
uri: string;
type: string;
name: string;
}

/**
* Type guard to check if an object is a React Native file
*/
function isReactNativeFile(value: unknown): value is ReactNativeFile {

Check failure on line 159 in src/hooks/useProofSubmit.ts

View workflow job for this annotation

GitHub Actions / lint

'isReactNativeFile' is defined but never used
return (
typeof value === 'object' &&
value !== null &&
'uri' in value &&
'type' in value &&
'name' in value
);
}

export function useProofSubmit() {
const { isInitialised } = useNetworkStatus();
const [isSubmitting, setIsSubmitting] = useState(false);
Expand Down Expand Up @@ -176,16 +206,17 @@
formData.append('lng', String(opts.lng));
}

interface ReactNativeFilePart {
uri: string;
type: string;
name: string;
}
formData.append('photos', {
// Properly typed React Native file for FormData
const photoFile: ReactNativeFile = {
uri: photoUri,
type: 'image/jpeg',
name: 'proof.jpg',
} as ReactNativeFilePart as unknown as Blob);
};

Check failure on line 215 in src/hooks/useProofSubmit.ts

View workflow job for this annotation

GitHub Actions / lint

Delete `······`
// FormData.append expects a Blob/File in browser, but in React Native it accepts { uri, type, name }
// We pass it as any because React Native's FormData type is not fully typed for this use case
// The runtime behavior is correct - this is a known limitation of React Native's FormData types
formData.append('photos', photoFile as unknown as Blob);

if (photoCid) {
formData.append('ipfsPhotoCid', photoCid);
Expand All @@ -198,11 +229,17 @@
const result = await submitProof(formData);
return { result, ipfsPending };
} catch (err) {
// attach the generated cids so callers can persist them
const uploadError = err as ProofUploadError;
// Attach the generated CIDs to the error for persistence
// Use a type-safe approach: create a new error with the additional properties
const error = err instanceof Error ? err : new Error(String(err));
const uploadError = new Error(error.message) as ProofUploadError;
uploadError.photoCid = photoCid;
uploadError.metadataCid = metadataCid;
uploadError.ipfsPending = ipfsPending;
// Preserve the original stack if available
if (error.stack) {
uploadError.stack = error.stack;
}
throw uploadError;
}
},
Expand Down Expand Up @@ -253,7 +290,9 @@
...(attemptIpfsPending ? { ipfsPending: true } : {}),
};
} catch (err) {
const uploadError = err as ProofUploadError;
const uploadError = err instanceof Error

Check failure on line 293 in src/hooks/useProofSubmit.ts

View workflow job for this annotation

GitHub Actions / lint

Replace `·err·instanceof·Error·⏎··········?·err·as·ProofUploadError·` with `⏎··········err·instanceof·Error⏎············?·(err·as·ProofUploadError)`
? err as ProofUploadError
: new Error(String(err)) as ProofUploadError;

Check failure on line 295 in src/hooks/useProofSubmit.ts

View workflow job for this annotation

GitHub Actions / lint

Replace `··········:·new·Error(String(err))·as·ProofUploadError` with `············:·(new·Error(String(err))·as·ProofUploadError)`
const message = uploadError.message || 'Upload failed';
const ipfsPending = uploadError.ipfsPending || false;
try {
Expand Down Expand Up @@ -336,7 +375,9 @@
},
);
} catch (err) {
const uploadError = err as ProofUploadError;
const uploadError = err instanceof Error

Check failure on line 378 in src/hooks/useProofSubmit.ts

View workflow job for this annotation

GitHub Actions / lint

Replace `·err·instanceof·Error·` with `⏎············err·instanceof·Error`
? err as ProofUploadError

Check failure on line 379 in src/hooks/useProofSubmit.ts

View workflow job for this annotation

GitHub Actions / lint

Replace `············?·err·as·ProofUploadError·⏎············:·new·Error(String(err))·as·ProofUploadError` with `··············?·(err·as·ProofUploadError)⏎··············:·(new·Error(String(err))·as·ProofUploadError)`
: new Error(String(err)) as ProofUploadError;
remaining.push({
...proof,
photoCid: uploadError.photoCid || proof.photoCid,
Expand Down
Loading