@umituz/react-native-ai-fal-provider 1.0.45 → 1.0.47

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-ai-fal-provider",
3
- "version": "1.0.45",
3
+ "version": "1.0.47",
4
4
  "description": "FAL AI provider for React Native - implements IAIProvider interface for unified AI generation",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
package/src/index.ts CHANGED
@@ -25,7 +25,7 @@ export type { FeatureModelConfig } from "./domain/constants/feature-models.const
25
25
 
26
26
  export {
27
27
  FalProvider, falProvider, falModelsService,
28
- getImageFeatureModel, getVideoFeatureModel,
28
+ getImageFeatureModel, getVideoFeatureModel, NSFWContentError,
29
29
  } from "./infrastructure/services";
30
30
  export type { ModelFetcher } from "./infrastructure/services";
31
31
 
@@ -20,6 +20,7 @@ import type {
20
20
  import type { FalQueueStatus } from "../../domain/entities/fal.types";
21
21
  import { DEFAULT_FAL_CONFIG, FAL_CAPABILITIES } from "./fal-provider.constants";
22
22
  import { mapFalStatusToJobStatus } from "./fal-status-mapper";
23
+ import { NSFWContentError } from "./nsfw-content-error";
23
24
  import { FAL_IMAGE_FEATURE_MODELS, FAL_VIDEO_FEATURE_MODELS } from "../../domain/constants/feature-models.constants";
24
25
  import {
25
26
  buildSingleImageInput,
@@ -142,6 +143,8 @@ export class FalProvider implements IAIProvider {
142
143
  console.log("[FalProvider] Subscribe completed:", { model });
143
144
  }
144
145
 
146
+ this.checkForNSFWContent(result as Record<string, unknown>);
147
+
145
148
  options?.onResult?.(result as T);
146
149
  return result as T;
147
150
  } finally {
@@ -163,19 +166,29 @@ export class FalProvider implements IAIProvider {
163
166
  console.log("[FalProvider] run() raw result:", JSON.stringify(result, null, 2));
164
167
  console.log("[FalProvider] run() result type:", typeof result);
165
168
  console.log("[FalProvider] run() result keys:", result ? Object.keys(result as object) : "null");
166
- const r = result as Record<string, unknown>;
167
- if (r?.data) {
168
- console.log("[FalProvider] run() has data property, data keys:", Object.keys(r.data as object));
169
- }
170
- if (r?.images) {
171
- console.log("[FalProvider] run() has images property, images:", JSON.stringify(r.images));
172
- }
173
169
  }
174
170
 
171
+ this.checkForNSFWContent(result as Record<string, unknown>);
172
+
175
173
  options?.onProgress?.({ progress: 100, status: "COMPLETED" });
176
174
  return result as T;
177
175
  }
178
176
 
177
+ private checkForNSFWContent(result: Record<string, unknown>): void {
178
+ const nsfwConcepts = result?.has_nsfw_concepts as boolean[] | undefined;
179
+
180
+ if (nsfwConcepts && Array.isArray(nsfwConcepts)) {
181
+ const hasNSFW = nsfwConcepts.some((value) => value === true);
182
+
183
+ if (hasNSFW) {
184
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
185
+ console.log("[FalProvider] NSFW content detected, rejecting result");
186
+ }
187
+ throw new NSFWContentError();
188
+ }
189
+ }
190
+ }
191
+
179
192
  reset(): void {
180
193
  this.apiKey = null;
181
194
  this.config = null;
@@ -7,6 +7,7 @@ import type { ImageFeatureType, VideoFeatureType } from "@umituz/react-native-ai
7
7
 
8
8
  export { FalProvider, falProvider } from "./fal-provider";
9
9
  export { falModelsService, type FalModelConfig, type ModelFetcher } from "./fal-models.service";
10
+ export { NSFWContentError } from "./nsfw-content-error";
10
11
 
11
12
  export function getImageFeatureModel(feature: ImageFeatureType): string {
12
13
  return FAL_IMAGE_FEATURE_MODELS[feature];
@@ -0,0 +1,24 @@
1
+ /**
2
+ * NSFW Content Error
3
+ * Thrown when AI provider detects NSFW content in generated output
4
+ */
5
+
6
+ import { FalErrorType } from "../../domain/entities/error.types";
7
+
8
+ export class NSFWContentError extends Error {
9
+ public readonly type = FalErrorType.CONTENT_POLICY;
10
+ public readonly retryable = false;
11
+ public readonly messageKey = "error.nsfw_content_detected";
12
+
13
+ constructor(message?: string) {
14
+ super(
15
+ message ||
16
+ "The generated content was flagged as inappropriate. Please try a different prompt."
17
+ );
18
+ this.name = "NSFWContentError";
19
+ }
20
+
21
+ getUserMessage(): string {
22
+ return this.message;
23
+ }
24
+ }
@@ -104,13 +104,20 @@ export function buildVideoFromImageInput(
104
104
 
105
105
  /**
106
106
  * Build face swap input for FAL face-swap
107
+ * FAL API requires: base_image_url (target face) and swap_image_url (face to swap in)
107
108
  */
108
109
  export function buildFaceSwapInput(
109
110
  sourceBase64: string,
110
111
  targetBase64: string,
111
112
  _options?: FaceSwapOptions,
112
113
  ): Record<string, unknown> {
113
- return buildDualImageInput(sourceBase64, targetBase64);
114
+ const formatImage = (b64: string) =>
115
+ b64.startsWith("data:") ? b64 : `data:image/jpeg;base64,${b64}`;
116
+
117
+ return {
118
+ base_image_url: formatImage(sourceBase64),
119
+ swap_image_url: formatImage(targetBase64),
120
+ };
114
121
  }
115
122
 
116
123
  /**