@umituz/react-native-ai-generation-content 1.40.1 → 1.40.3
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-generation-content",
|
|
3
|
-
"version": "1.40.
|
|
3
|
+
"version": "1.40.3",
|
|
4
4
|
"description": "Provider-agnostic AI generation orchestration for React Native with result preview components",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"types": "src/index.ts",
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useAIFeatureGate Hook
|
|
3
|
+
* Centralized access control for AI features
|
|
4
|
+
*
|
|
5
|
+
* Single hook that handles:
|
|
6
|
+
* 1. Authentication check
|
|
7
|
+
* 2. Premium subscription check
|
|
8
|
+
* 3. Credit balance check
|
|
9
|
+
* 4. Paywall display
|
|
10
|
+
*
|
|
11
|
+
* Usage:
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const { requireFeature } = useAIFeatureGate({ creditCost: 1 });
|
|
14
|
+
*
|
|
15
|
+
* <AtomicButton onPress={() => requireFeature(handleGenerate)}>
|
|
16
|
+
* Generate
|
|
17
|
+
* </AtomicButton>
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import { useCallback, useMemo } from "react";
|
|
22
|
+
import { useAuth, useAuthModalStore } from "@umituz/react-native-auth";
|
|
23
|
+
import {
|
|
24
|
+
usePremium,
|
|
25
|
+
useCredits,
|
|
26
|
+
usePaywallVisibility,
|
|
27
|
+
useFeatureGate,
|
|
28
|
+
} from "@umituz/react-native-subscription";
|
|
29
|
+
import type {
|
|
30
|
+
AIFeatureGateOptions,
|
|
31
|
+
AIFeatureGateReturn,
|
|
32
|
+
} from "../types/access-control.types";
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Hook for AI feature access control with 3-tier gating:
|
|
36
|
+
* Auth → Premium/Credits → Paywall → Execute
|
|
37
|
+
*
|
|
38
|
+
* @param options - Configuration for feature gate
|
|
39
|
+
* @returns Access control interface with requireFeature function
|
|
40
|
+
*/
|
|
41
|
+
export function useAIFeatureGate(
|
|
42
|
+
options: AIFeatureGateOptions,
|
|
43
|
+
): AIFeatureGateReturn {
|
|
44
|
+
const { creditCost, featureName, onSuccess, onError } = options;
|
|
45
|
+
|
|
46
|
+
// Auth state
|
|
47
|
+
const { isAuthenticated: rawIsAuthenticated, isAnonymous } = useAuth();
|
|
48
|
+
const { showAuthModal } = useAuthModalStore();
|
|
49
|
+
|
|
50
|
+
// Subscription state
|
|
51
|
+
const { isPremium } = usePremium();
|
|
52
|
+
const { credits, isLoading: isCreditsLoading } = useCredits();
|
|
53
|
+
const { openPaywall } = usePaywallVisibility();
|
|
54
|
+
|
|
55
|
+
// Derived states
|
|
56
|
+
const isCreditsLoaded = !isCreditsLoading;
|
|
57
|
+
const isAuthenticated = rawIsAuthenticated && !isAnonymous;
|
|
58
|
+
const creditBalance = credits?.credits ?? 0;
|
|
59
|
+
const hasCredits = creditBalance >= creditCost;
|
|
60
|
+
|
|
61
|
+
// Configure feature gate from subscription package
|
|
62
|
+
const { requireFeature: requireFeatureFromPackage } = useFeatureGate({
|
|
63
|
+
isAuthenticated,
|
|
64
|
+
onShowAuthModal: (cb) => showAuthModal(cb),
|
|
65
|
+
hasSubscription: isPremium,
|
|
66
|
+
creditBalance,
|
|
67
|
+
requiredCredits: creditCost,
|
|
68
|
+
onShowPaywall: () => openPaywall(),
|
|
69
|
+
isCreditsLoaded,
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// Can access if: authenticated AND (premium OR has credits)
|
|
73
|
+
const canAccess = useMemo(() => {
|
|
74
|
+
if (!isAuthenticated) return false;
|
|
75
|
+
if (isPremium) return true;
|
|
76
|
+
return hasCredits;
|
|
77
|
+
}, [isAuthenticated, isPremium, hasCredits]);
|
|
78
|
+
|
|
79
|
+
// Wrapped requireFeature with error handling
|
|
80
|
+
const requireFeature = useCallback(
|
|
81
|
+
async (action: () => void | Promise<void>): Promise<void> => {
|
|
82
|
+
try {
|
|
83
|
+
requireFeatureFromPackage(async () => {
|
|
84
|
+
try {
|
|
85
|
+
await action();
|
|
86
|
+
onSuccess?.();
|
|
87
|
+
} catch (error) {
|
|
88
|
+
const errorObj =
|
|
89
|
+
error instanceof Error ? error : new Error(String(error));
|
|
90
|
+
onError?.(errorObj);
|
|
91
|
+
throw error;
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
} catch (error) {
|
|
95
|
+
const errorObj =
|
|
96
|
+
error instanceof Error ? error : new Error(String(error));
|
|
97
|
+
onError?.(errorObj);
|
|
98
|
+
throw error;
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
[requireFeatureFromPackage, onSuccess, onError],
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
requireFeature,
|
|
106
|
+
canAccess,
|
|
107
|
+
isCheckingAccess: isCreditsLoading,
|
|
108
|
+
hasCredits,
|
|
109
|
+
isAuthenticated,
|
|
110
|
+
isPremium,
|
|
111
|
+
creditBalance,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Access Control Domain
|
|
3
|
+
* Centralized AI feature access control
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export { useAIFeatureGate } from "./hooks/useAIFeatureGate";
|
|
7
|
+
|
|
8
|
+
export type {
|
|
9
|
+
AIFeatureGateOptions,
|
|
10
|
+
AIFeatureGateReturn,
|
|
11
|
+
AIFeatureGateHook,
|
|
12
|
+
} from "./types/access-control.types";
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Access Control Types
|
|
3
|
+
* Type definitions for AI feature access control
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export interface AIFeatureGateOptions {
|
|
7
|
+
/**
|
|
8
|
+
* Number of credits required for this feature
|
|
9
|
+
*/
|
|
10
|
+
creditCost: number;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Optional feature name for analytics tracking
|
|
14
|
+
*/
|
|
15
|
+
featureName?: string;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Callback fired when feature is successfully accessed and executed
|
|
19
|
+
*/
|
|
20
|
+
onSuccess?: () => void;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Callback fired when feature access fails or execution errors
|
|
24
|
+
*/
|
|
25
|
+
onError?: (error: Error) => void;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface AIFeatureGateReturn {
|
|
29
|
+
/**
|
|
30
|
+
* Function to execute protected feature
|
|
31
|
+
* Handles all access control checks (auth, premium, credits, paywall)
|
|
32
|
+
*/
|
|
33
|
+
requireFeature: (action: () => void | Promise<void>) => Promise<void>;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Whether user can access this feature (all checks passed)
|
|
37
|
+
*/
|
|
38
|
+
canAccess: boolean;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Whether access checks are currently loading
|
|
42
|
+
*/
|
|
43
|
+
isCheckingAccess: boolean;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Whether user has sufficient credits
|
|
47
|
+
*/
|
|
48
|
+
hasCredits: boolean;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Whether user is authenticated (not anonymous)
|
|
52
|
+
*/
|
|
53
|
+
isAuthenticated: boolean;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Whether user has premium subscription
|
|
57
|
+
*/
|
|
58
|
+
isPremium: boolean;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Current credit balance
|
|
62
|
+
*/
|
|
63
|
+
creditBalance: number;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Hook type definition for useAIFeatureGate
|
|
68
|
+
*/
|
|
69
|
+
export type AIFeatureGateHook = (
|
|
70
|
+
options: AIFeatureGateOptions,
|
|
71
|
+
) => AIFeatureGateReturn;
|
package/src/index.ts
CHANGED
|
@@ -135,6 +135,7 @@ export * from "./domains/content-moderation";
|
|
|
135
135
|
export * from "./domains/creations";
|
|
136
136
|
export * from "./domains/face-detection";
|
|
137
137
|
export * from "./domains/scenarios";
|
|
138
|
+
export * from "./domains/access-control";
|
|
138
139
|
export * from "./infrastructure/orchestration";
|
|
139
140
|
|
|
140
141
|
export {
|