@zodic/shared 0.0.339 → 0.0.340
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app/api/index.ts +82 -29
- package/package.json +1 -1
package/app/api/index.ts
CHANGED
|
@@ -785,43 +785,96 @@ export const Api = (env: BackendBindings) => ({
|
|
|
785
785
|
Authorization: `Bearer ${env.PIAPI_API_KEY}`,
|
|
786
786
|
'Content-Type': 'application/json',
|
|
787
787
|
};
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
}
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
788
|
+
|
|
789
|
+
// Validate image URLs before making the request
|
|
790
|
+
const validateImageUrl = async (url: string, label: string): Promise<void> => {
|
|
791
|
+
try {
|
|
792
|
+
const response = await fetch(url, { method: 'HEAD' });
|
|
793
|
+
if (!response.ok) {
|
|
794
|
+
throw new Error(`${label} is inaccessible: ${response.status} ${response.statusText}`);
|
|
795
|
+
}
|
|
796
|
+
const contentType = response.headers.get('Content-Type');
|
|
797
|
+
if (!contentType || !contentType.startsWith('image/')) {
|
|
798
|
+
throw new Error(`${label} is not a valid image: Content-Type is ${contentType}`);
|
|
799
|
+
}
|
|
800
|
+
} catch (err: any) {
|
|
801
|
+
console.error(`Error validating ${label}:`, err.message);
|
|
802
|
+
throw new Error(`Invalid ${label}: ${err.message}`);
|
|
803
|
+
}
|
|
804
|
+
};
|
|
805
|
+
|
|
805
806
|
try {
|
|
807
|
+
// Validate image URLs
|
|
808
|
+
await validateImageUrl(sourceImageUrl, 'Source image URL');
|
|
809
|
+
await validateImageUrl(targetImageUrl, 'Target image URL');
|
|
810
|
+
|
|
811
|
+
const body = JSON.stringify({
|
|
812
|
+
model: 'Qubico/image-toolkit',
|
|
813
|
+
type: 'faceswap',
|
|
814
|
+
input: {
|
|
815
|
+
source_image_url: sourceImageUrl,
|
|
816
|
+
target_image_url: targetImageUrl,
|
|
817
|
+
},
|
|
818
|
+
config: {
|
|
819
|
+
webhook_config: {
|
|
820
|
+
endpoint:
|
|
821
|
+
'https://zodic-backend.lucdelbel.workers.dev/api/webhook/faceswap',
|
|
822
|
+
// secret: '',
|
|
823
|
+
},
|
|
824
|
+
},
|
|
825
|
+
});
|
|
826
|
+
|
|
827
|
+
console.log('Sending FaceSwap request:', { sourceImageUrl, targetImageUrl });
|
|
828
|
+
|
|
806
829
|
const response = await fetch(endpoint, {
|
|
807
830
|
method: 'POST',
|
|
808
831
|
headers,
|
|
809
832
|
body,
|
|
810
833
|
});
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
834
|
+
|
|
835
|
+
// Log the HTTP status and headers for debugging
|
|
836
|
+
console.log('PiAPI FaceSwap Response Status:', response.status);
|
|
837
|
+
console.log('PiAPI FaceSwap Response Headers:', [...response.headers.entries()]);
|
|
838
|
+
|
|
839
|
+
// Read the response body as text first to inspect it
|
|
840
|
+
const responseText = await response.text();
|
|
841
|
+
console.log('PiAPI FaceSwap Raw Response Body:', responseText);
|
|
842
|
+
|
|
843
|
+
// Check for the expected 201 Created status
|
|
844
|
+
if (response.status !== 201) {
|
|
845
|
+
let errorData;
|
|
846
|
+
try {
|
|
847
|
+
errorData = JSON.parse(responseText);
|
|
848
|
+
} catch {
|
|
849
|
+
errorData = { message: responseText || 'Unknown error' };
|
|
850
|
+
}
|
|
851
|
+
console.error('Error from PiAPI FaceSwap:', errorData);
|
|
852
|
+
throw new Error(`PiAPI FaceSwap Error: ${response.status} - ${errorData.message || 'Unknown error'}`);
|
|
816
853
|
}
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
854
|
+
|
|
855
|
+
// Check if the response body is empty
|
|
856
|
+
if (!responseText) {
|
|
857
|
+
console.error('PiAPI FaceSwap response body is empty');
|
|
858
|
+
throw new Error('PiAPI FaceSwap Error: Empty response body');
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
// Try to parse the response as JSON
|
|
862
|
+
let data;
|
|
863
|
+
try {
|
|
864
|
+
data = JSON.parse(responseText) as { task_id: string; message: string };
|
|
865
|
+
} catch (err) {
|
|
866
|
+
console.error('Failed to parse PiAPI FaceSwap response as JSON:', responseText);
|
|
867
|
+
throw new Error('PiAPI FaceSwap Error: Invalid JSON response');
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
// Validate the response structure
|
|
871
|
+
if (!data.task_id || !data.message) {
|
|
872
|
+
console.error('PiAPI FaceSwap response missing required fields:', data);
|
|
873
|
+
throw new Error('PiAPI FaceSwap Error: Invalid response structure');
|
|
874
|
+
}
|
|
875
|
+
|
|
823
876
|
console.log('FaceSwap task created successfully:', data);
|
|
824
|
-
|
|
877
|
+
|
|
825
878
|
return {
|
|
826
879
|
taskId: data.task_id,
|
|
827
880
|
message: data.message,
|