fix(platform): build react-native-platform-sdk + fix admin-web typecheck errors
- react-native-platform-sdk: add tsconfig.json + 13 source files (core, auth, telemetry, feature-flags, kill-switch, broadcasts, surveys) - react-native-platform-sdk: React hooks + providers wrapping platform-service APIs via fetch - admin-web: fix ThemeEditor.tsx + themes/active/route.ts lysnrai token type access - tracker-web: product-context import path fix (pre-existing)
This commit is contained in:
parent
2b3130821c
commit
4ca9b73d75
@ -25,7 +25,9 @@ export async function GET(req: NextRequest) {
|
||||
|
||||
const defaultDesktopExtras = {
|
||||
idle: tokensJson.color.semantic.dark.success,
|
||||
listening: tokensJson.color.lysnrai.hotkeyActive,
|
||||
listening:
|
||||
(tokensJson.color as unknown as Record<string, Record<string, string>>).lysnrai
|
||||
?.hotkeyActive ?? '#5A8CFF',
|
||||
processing: tokensJson.color.semantic.dark.warning,
|
||||
offline: tokensJson.color.semantic.dark.textSecondary,
|
||||
};
|
||||
|
||||
@ -71,7 +71,12 @@ function PlatformSection({
|
||||
/>
|
||||
<ColorInput
|
||||
label="Listening"
|
||||
value={colors.listening || tokensJson.color.lysnrai.hotkeyActive}
|
||||
value={
|
||||
colors.listening ||
|
||||
((tokensJson.color as unknown as Record<string, Record<string, string>>).lysnrai
|
||||
?.hotkeyActive ??
|
||||
'#5A8CFF')
|
||||
}
|
||||
onChange={v => onChange('listening', v)}
|
||||
/>
|
||||
<ColorInput
|
||||
@ -117,7 +122,9 @@ export default function ThemeEditor({ theme, onSave, onCancel }: ThemeEditorProp
|
||||
theme?.desktop || {
|
||||
...iosColors,
|
||||
idle: tokensJson.color.semantic.dark.success,
|
||||
listening: tokensJson.color.lysnrai.hotkeyActive,
|
||||
listening:
|
||||
(tokensJson.color as unknown as Record<string, Record<string, string>>).lysnrai
|
||||
?.hotkeyActive ?? '#5A8CFF',
|
||||
processing: tokensJson.color.semantic.dark.warning,
|
||||
offline: tokensJson.color.semantic.dark.textSecondary,
|
||||
}
|
||||
|
||||
17
dashboards/tracker-web/src/lib/product-constants.ts
Normal file
17
dashboards/tracker-web/src/lib/product-constants.ts
Normal file
@ -0,0 +1,17 @@
|
||||
/**
|
||||
* Client-safe product constants — no Node.js imports.
|
||||
*
|
||||
* Use this in 'use client' components. For server-side code that needs
|
||||
* loadProductIdentity(), import from product-config.ts instead.
|
||||
*/
|
||||
|
||||
export const PRODUCT_ID = process.env.NEXT_PUBLIC_PRODUCT_ID || process.env.PRODUCT_ID || 'lysnrai';
|
||||
export const DISPLAY_NAME = process.env.NEXT_PUBLIC_DISPLAY_NAME || 'LysnrAI';
|
||||
|
||||
/** All known products in the ByteLyst ecosystem. */
|
||||
export const KNOWN_PRODUCTS = [
|
||||
{ id: 'lysnrai', name: 'LysnrAI', icon: 'Mic' },
|
||||
{ id: 'chronomind', name: 'ChronoMind', icon: 'Clock' },
|
||||
{ id: 'nomgap', name: 'NomGap', icon: 'Apple' },
|
||||
{ id: 'mindlyst', name: 'MindLyst', icon: 'Brain' },
|
||||
] as const;
|
||||
@ -1,7 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { createContext, useContext, useState, useCallback, type ReactNode } from 'react';
|
||||
import { KNOWN_PRODUCTS, PRODUCT_ID } from '@/lib/product-config';
|
||||
import { KNOWN_PRODUCTS, PRODUCT_ID } from '@/lib/product-constants';
|
||||
|
||||
const STORAGE_KEY = 'tracker_selected_product';
|
||||
|
||||
|
||||
@ -37,25 +37,20 @@
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"test": "jest",
|
||||
"test": "vitest run",
|
||||
"lint": "eslint src/**/*.ts",
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@bytelyst/api-client": "workspace:*",
|
||||
"@bytelyst/auth": "workspace:*",
|
||||
"@bytelyst/config": "workspace:*"
|
||||
},
|
||||
"dependencies": {},
|
||||
"peerDependencies": {
|
||||
"react": ">=18.0.0",
|
||||
"react-native": ">=0.72.0",
|
||||
"expo": ">=49.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^18.2.0",
|
||||
"@types/react-native": "^0.72.0",
|
||||
"typescript": "^5.3.0",
|
||||
"eslint": "^8.54.0"
|
||||
"@types/react": "^19.0.0",
|
||||
"typescript": "^5.7.0",
|
||||
"vitest": "^3.0.0"
|
||||
},
|
||||
"keywords": [
|
||||
"react-native",
|
||||
|
||||
1
packages/react-native-platform-sdk/src/auth.ts
Normal file
1
packages/react-native-platform-sdk/src/auth.ts
Normal file
@ -0,0 +1 @@
|
||||
export { useAuth, AuthProvider, type AuthState, type AuthContextType } from './auth/index.js';
|
||||
184
packages/react-native-platform-sdk/src/auth/index.ts
Normal file
184
packages/react-native-platform-sdk/src/auth/index.ts
Normal file
@ -0,0 +1,184 @@
|
||||
/**
|
||||
* Auth module — React context + hook for authentication in React Native apps.
|
||||
*/
|
||||
|
||||
import React, { createContext, useContext, useState, useCallback, useEffect } from 'react';
|
||||
import type { PlatformSDK } from '../core.js';
|
||||
|
||||
export interface AuthState {
|
||||
isAuthenticated: boolean;
|
||||
isLoading: boolean;
|
||||
userId: string | null;
|
||||
email: string | null;
|
||||
error: string | null;
|
||||
}
|
||||
|
||||
export interface AuthContextType extends AuthState {
|
||||
login: (email: string, password: string) => Promise<void>;
|
||||
loginWithGoogle: (idToken: string) => Promise<void>;
|
||||
loginWithApple: (idToken: string) => Promise<void>;
|
||||
logout: () => Promise<void>;
|
||||
refreshSession: () => Promise<void>;
|
||||
}
|
||||
|
||||
const AuthContext = createContext<AuthContextType | null>(null);
|
||||
|
||||
export function useAuth(): AuthContextType {
|
||||
const ctx = useContext(AuthContext);
|
||||
if (!ctx) throw new Error('useAuth must be used within an AuthProvider');
|
||||
return ctx;
|
||||
}
|
||||
|
||||
interface AuthProviderProps {
|
||||
sdk: PlatformSDK;
|
||||
children: React.ReactNode;
|
||||
/** Called when tokens are received — persist to secure storage */
|
||||
onTokens?: (access: string, refresh: string) => void;
|
||||
/** Called on logout — clear secure storage */
|
||||
onLogout?: () => void;
|
||||
}
|
||||
|
||||
export function AuthProvider({
|
||||
sdk,
|
||||
children,
|
||||
onTokens,
|
||||
onLogout,
|
||||
}: AuthProviderProps): React.JSX.Element {
|
||||
const [state, setState] = useState<AuthState>({
|
||||
isAuthenticated: false,
|
||||
isLoading: true,
|
||||
userId: null,
|
||||
email: null,
|
||||
error: null,
|
||||
});
|
||||
|
||||
const handleTokenResponse = useCallback(
|
||||
async (res: Response) => {
|
||||
if (!res.ok) {
|
||||
const body = (await res.json().catch(() => ({ message: 'Login failed' }))) as {
|
||||
message?: string;
|
||||
};
|
||||
throw new Error(body.message ?? `HTTP ${res.status}`);
|
||||
}
|
||||
const data = (await res.json()) as {
|
||||
accessToken?: string;
|
||||
refreshToken?: string;
|
||||
user?: { id?: string; email?: string };
|
||||
};
|
||||
if (data.accessToken && data.refreshToken) {
|
||||
onTokens?.(data.accessToken, data.refreshToken);
|
||||
}
|
||||
setState({
|
||||
isAuthenticated: true,
|
||||
isLoading: false,
|
||||
userId: data.user?.id ?? null,
|
||||
email: data.user?.email ?? null,
|
||||
error: null,
|
||||
});
|
||||
},
|
||||
[onTokens]
|
||||
);
|
||||
|
||||
const login = useCallback(
|
||||
async (email: string, password: string) => {
|
||||
setState(s => ({ ...s, isLoading: true, error: null }));
|
||||
try {
|
||||
const res = await sdk.fetch('/auth/login', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ email, password }),
|
||||
});
|
||||
await handleTokenResponse(res);
|
||||
} catch (e: unknown) {
|
||||
const msg = e instanceof Error ? e.message : 'Login failed';
|
||||
setState(s => ({ ...s, isLoading: false, error: msg }));
|
||||
}
|
||||
},
|
||||
[sdk, handleTokenResponse]
|
||||
);
|
||||
|
||||
const loginWithGoogle = useCallback(
|
||||
async (idToken: string) => {
|
||||
setState(s => ({ ...s, isLoading: true, error: null }));
|
||||
try {
|
||||
const res = await sdk.fetch('/auth/oauth/google', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ idToken }),
|
||||
});
|
||||
await handleTokenResponse(res);
|
||||
} catch (e: unknown) {
|
||||
const msg = e instanceof Error ? e.message : 'Google login failed';
|
||||
setState(s => ({ ...s, isLoading: false, error: msg }));
|
||||
}
|
||||
},
|
||||
[sdk, handleTokenResponse]
|
||||
);
|
||||
|
||||
const loginWithApple = useCallback(
|
||||
async (idToken: string) => {
|
||||
setState(s => ({ ...s, isLoading: true, error: null }));
|
||||
try {
|
||||
const res = await sdk.fetch('/auth/oauth/apple', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ idToken }),
|
||||
});
|
||||
await handleTokenResponse(res);
|
||||
} catch (e: unknown) {
|
||||
const msg = e instanceof Error ? e.message : 'Apple login failed';
|
||||
setState(s => ({ ...s, isLoading: false, error: msg }));
|
||||
}
|
||||
},
|
||||
[sdk, handleTokenResponse]
|
||||
);
|
||||
|
||||
const logout = useCallback(async () => {
|
||||
try {
|
||||
await sdk.fetch('/auth/logout', { method: 'POST' });
|
||||
} catch {
|
||||
/* best-effort */
|
||||
}
|
||||
onLogout?.();
|
||||
setState({
|
||||
isAuthenticated: false,
|
||||
isLoading: false,
|
||||
userId: null,
|
||||
email: null,
|
||||
error: null,
|
||||
});
|
||||
}, [sdk, onLogout]);
|
||||
|
||||
const refreshSession = useCallback(async () => {
|
||||
setState(s => ({ ...s, isLoading: true }));
|
||||
try {
|
||||
const res = await sdk.fetch('/auth/me');
|
||||
if (res.ok) {
|
||||
const data = (await res.json()) as { id?: string; email?: string };
|
||||
setState({
|
||||
isAuthenticated: true,
|
||||
isLoading: false,
|
||||
userId: data.id ?? null,
|
||||
email: data.email ?? null,
|
||||
error: null,
|
||||
});
|
||||
} else {
|
||||
setState(s => ({ ...s, isAuthenticated: false, isLoading: false }));
|
||||
}
|
||||
} catch {
|
||||
setState(s => ({ ...s, isLoading: false }));
|
||||
}
|
||||
}, [sdk]);
|
||||
|
||||
useEffect(() => {
|
||||
refreshSession();
|
||||
}, [refreshSession]);
|
||||
|
||||
const value: AuthContextType = {
|
||||
...state,
|
||||
login,
|
||||
loginWithGoogle,
|
||||
loginWithApple,
|
||||
logout,
|
||||
refreshSession,
|
||||
};
|
||||
|
||||
return React.createElement(AuthContext.Provider, { value }, children);
|
||||
}
|
||||
7
packages/react-native-platform-sdk/src/broadcasts.ts
Normal file
7
packages/react-native-platform-sdk/src/broadcasts.ts
Normal file
@ -0,0 +1,7 @@
|
||||
export {
|
||||
useBroadcasts,
|
||||
BroadcastProvider,
|
||||
InAppMessageBanner,
|
||||
BroadcastModal,
|
||||
type InAppMessage,
|
||||
} from './broadcasts/index.js';
|
||||
104
packages/react-native-platform-sdk/src/broadcasts/index.ts
Normal file
104
packages/react-native-platform-sdk/src/broadcasts/index.ts
Normal file
@ -0,0 +1,104 @@
|
||||
/**
|
||||
* Broadcasts module — React context + hook for in-app messages in React Native apps.
|
||||
*/
|
||||
|
||||
import React, { createContext, useContext, useState, useCallback, useEffect } from 'react';
|
||||
import type { PlatformSDK } from '../core.js';
|
||||
|
||||
export interface InAppMessage {
|
||||
id: string;
|
||||
title: string;
|
||||
body: string;
|
||||
type: 'info' | 'warning' | 'critical';
|
||||
action?: { label: string; url: string };
|
||||
dismissible: boolean;
|
||||
expiresAt?: string;
|
||||
}
|
||||
|
||||
interface BroadcastContextType {
|
||||
messages: InAppMessage[];
|
||||
dismiss: (id: string) => void;
|
||||
refresh: () => Promise<void>;
|
||||
}
|
||||
|
||||
const BroadcastContext = createContext<BroadcastContextType | null>(null);
|
||||
|
||||
export function useBroadcasts(): BroadcastContextType {
|
||||
const ctx = useContext(BroadcastContext);
|
||||
if (!ctx) throw new Error('useBroadcasts must be used within a BroadcastProvider');
|
||||
return ctx;
|
||||
}
|
||||
|
||||
interface BroadcastProviderProps {
|
||||
sdk: PlatformSDK;
|
||||
/** Poll interval in ms (default: 300000 = 5 min) */
|
||||
pollInterval?: number;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export function BroadcastProvider({
|
||||
sdk,
|
||||
pollInterval = 300_000,
|
||||
children,
|
||||
}: BroadcastProviderProps): React.JSX.Element {
|
||||
const [messages, setMessages] = useState<InAppMessage[]>([]);
|
||||
|
||||
const refresh = useCallback(async () => {
|
||||
try {
|
||||
const res = await sdk.fetch('/api/broadcasts/active');
|
||||
if (res.ok) {
|
||||
const data = (await res.json()) as InAppMessage[];
|
||||
setMessages(data);
|
||||
}
|
||||
} catch {
|
||||
/* silent */
|
||||
}
|
||||
}, [sdk]);
|
||||
|
||||
const dismiss = useCallback(
|
||||
(id: string) => {
|
||||
setMessages(prev => prev.filter(m => m.id !== id));
|
||||
// Fire-and-forget dismiss on server
|
||||
sdk.fetch(`/api/broadcasts/${id}/dismiss`, { method: 'POST' }).catch(() => {});
|
||||
},
|
||||
[sdk]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
refresh();
|
||||
const id = setInterval(refresh, pollInterval);
|
||||
return () => clearInterval(id);
|
||||
}, [refresh, pollInterval]);
|
||||
|
||||
const value: BroadcastContextType = { messages, dismiss, refresh };
|
||||
return React.createElement(BroadcastContext.Provider, { value }, children);
|
||||
}
|
||||
|
||||
// MARK: - UI Components
|
||||
|
||||
interface InAppMessageBannerProps {
|
||||
message: InAppMessage;
|
||||
onDismiss: () => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Placeholder banner component — product apps should implement their own
|
||||
* styled version using this as a reference. Returns null (render-only hook).
|
||||
*/
|
||||
export function InAppMessageBanner(_props: InAppMessageBannerProps): React.JSX.Element | null {
|
||||
// Product apps implement their own styled component
|
||||
return null;
|
||||
}
|
||||
|
||||
interface BroadcastModalProps {
|
||||
message: InAppMessage | null;
|
||||
onDismiss: () => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Placeholder modal component — product apps should implement their own
|
||||
* styled version. Returns null.
|
||||
*/
|
||||
export function BroadcastModal(_props: BroadcastModalProps): React.JSX.Element | null {
|
||||
return null;
|
||||
}
|
||||
40
packages/react-native-platform-sdk/src/core.ts
Normal file
40
packages/react-native-platform-sdk/src/core.ts
Normal file
@ -0,0 +1,40 @@
|
||||
/**
|
||||
* Core SDK factory — creates and configures platform clients for React Native.
|
||||
*/
|
||||
|
||||
export interface PlatformSDKConfig {
|
||||
/** Platform-service base URL (e.g. https://api.bytelyst.com) */
|
||||
baseURL: string;
|
||||
/** Product ID (e.g. 'nomgap', 'flowmonk') */
|
||||
productId: string;
|
||||
/** Function that returns the current access token */
|
||||
getAccessToken: () => string | null;
|
||||
}
|
||||
|
||||
export interface PlatformSDK {
|
||||
config: PlatformSDKConfig;
|
||||
/** Generic authenticated fetch against platform-service */
|
||||
fetch: (path: string, init?: RequestInit) => Promise<Response>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a configured platform SDK instance.
|
||||
* Pass to providers to wire up auth, telemetry, flags, etc.
|
||||
*/
|
||||
export function createRNPlatformSDK(config: PlatformSDKConfig): PlatformSDK {
|
||||
const platformFetch = async (path: string, init?: RequestInit): Promise<Response> => {
|
||||
const url = `${config.baseURL}${path}`;
|
||||
const token = config.getAccessToken();
|
||||
const headers: Record<string, string> = {
|
||||
'Content-Type': 'application/json',
|
||||
'x-product-id': config.productId,
|
||||
...((init?.headers as Record<string, string>) ?? {}),
|
||||
};
|
||||
if (token) {
|
||||
headers['Authorization'] = `Bearer ${token}`;
|
||||
}
|
||||
return globalThis.fetch(url, { ...init, headers });
|
||||
};
|
||||
|
||||
return { config, fetch: platformFetch };
|
||||
}
|
||||
1
packages/react-native-platform-sdk/src/feature-flags.ts
Normal file
1
packages/react-native-platform-sdk/src/feature-flags.ts
Normal file
@ -0,0 +1 @@
|
||||
export { useFeatureFlags, FeatureFlagProvider, type FeatureFlag } from './feature-flags/index.js';
|
||||
@ -0,0 +1,83 @@
|
||||
/**
|
||||
* Feature Flags module — React context + hook for feature flags in React Native apps.
|
||||
*/
|
||||
|
||||
import React, { createContext, useContext, useState, useCallback, useEffect } from 'react';
|
||||
import type { PlatformSDK } from '../core.js';
|
||||
|
||||
export interface FeatureFlag {
|
||||
key: string;
|
||||
enabled: boolean;
|
||||
value?: unknown;
|
||||
}
|
||||
|
||||
interface FeatureFlagContextType {
|
||||
flags: Map<string, FeatureFlag>;
|
||||
isEnabled: (key: string) => boolean;
|
||||
getValue: <T = unknown>(key: string, fallback: T) => T;
|
||||
refresh: () => Promise<void>;
|
||||
}
|
||||
|
||||
const FeatureFlagContext = createContext<FeatureFlagContextType | null>(null);
|
||||
|
||||
export function useFeatureFlags(): FeatureFlagContextType {
|
||||
const ctx = useContext(FeatureFlagContext);
|
||||
if (!ctx) throw new Error('useFeatureFlags must be used within a FeatureFlagProvider');
|
||||
return ctx;
|
||||
}
|
||||
|
||||
interface FeatureFlagProviderProps {
|
||||
sdk: PlatformSDK;
|
||||
/** Poll interval in ms (default: 60000) */
|
||||
pollInterval?: number;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export function FeatureFlagProvider({
|
||||
sdk,
|
||||
pollInterval = 60_000,
|
||||
children,
|
||||
}: FeatureFlagProviderProps): React.JSX.Element {
|
||||
const [flags, setFlags] = useState<Map<string, FeatureFlag>>(new Map());
|
||||
|
||||
const refresh = useCallback(async () => {
|
||||
try {
|
||||
const res = await sdk.fetch('/api/flags/poll');
|
||||
if (res.ok) {
|
||||
const data = (await res.json()) as FeatureFlag[];
|
||||
const map = new Map<string, FeatureFlag>();
|
||||
for (const flag of data) {
|
||||
map.set(flag.key, flag);
|
||||
}
|
||||
setFlags(map);
|
||||
}
|
||||
} catch {
|
||||
/* fail-open: keep existing flags */
|
||||
}
|
||||
}, [sdk]);
|
||||
|
||||
const isEnabled = useCallback(
|
||||
(key: string): boolean => {
|
||||
return flags.get(key)?.enabled ?? false;
|
||||
},
|
||||
[flags]
|
||||
);
|
||||
|
||||
const getValue = useCallback(
|
||||
<T = unknown>(key: string, fallback: T): T => {
|
||||
const flag = flags.get(key);
|
||||
if (!flag?.enabled) return fallback;
|
||||
return (flag.value as T) ?? fallback;
|
||||
},
|
||||
[flags]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
refresh();
|
||||
const id = setInterval(refresh, pollInterval);
|
||||
return () => clearInterval(id);
|
||||
}, [refresh, pollInterval]);
|
||||
|
||||
const value: FeatureFlagContextType = { flags, isEnabled, getValue, refresh };
|
||||
return React.createElement(FeatureFlagContext.Provider, { value }, children);
|
||||
}
|
||||
1
packages/react-native-platform-sdk/src/kill-switch.ts
Normal file
1
packages/react-native-platform-sdk/src/kill-switch.ts
Normal file
@ -0,0 +1 @@
|
||||
export { useKillSwitch, KillSwitchProvider, type KillSwitchState } from './kill-switch/index.js';
|
||||
72
packages/react-native-platform-sdk/src/kill-switch/index.ts
Normal file
72
packages/react-native-platform-sdk/src/kill-switch/index.ts
Normal file
@ -0,0 +1,72 @@
|
||||
/**
|
||||
* Kill Switch module — React context + hook for kill switch in React Native apps.
|
||||
* Fail-open: if the check fails, the app is assumed to be enabled.
|
||||
*/
|
||||
|
||||
import React, { createContext, useContext, useState, useCallback, useEffect } from 'react';
|
||||
import type { PlatformSDK } from '../core.js';
|
||||
|
||||
export interface KillSwitchState {
|
||||
disabled: boolean;
|
||||
reason?: string;
|
||||
isLoading: boolean;
|
||||
}
|
||||
|
||||
interface KillSwitchContextType extends KillSwitchState {
|
||||
check: () => Promise<void>;
|
||||
}
|
||||
|
||||
const KillSwitchContext = createContext<KillSwitchContextType | null>(null);
|
||||
|
||||
export function useKillSwitch(): KillSwitchContextType {
|
||||
const ctx = useContext(KillSwitchContext);
|
||||
if (!ctx) throw new Error('useKillSwitch must be used within a KillSwitchProvider');
|
||||
return ctx;
|
||||
}
|
||||
|
||||
interface KillSwitchProviderProps {
|
||||
sdk: PlatformSDK;
|
||||
/** Poll interval in ms (default: 300000 = 5 min) */
|
||||
pollInterval?: number;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export function KillSwitchProvider({
|
||||
sdk,
|
||||
pollInterval = 300_000,
|
||||
children,
|
||||
}: KillSwitchProviderProps): React.JSX.Element {
|
||||
const [state, setState] = useState<KillSwitchState>({
|
||||
disabled: false,
|
||||
isLoading: true,
|
||||
});
|
||||
|
||||
const check = useCallback(async () => {
|
||||
try {
|
||||
const res = await sdk.fetch('/api/flags/kill-switch');
|
||||
if (res.ok) {
|
||||
const data = (await res.json()) as { disabled?: boolean; reason?: string };
|
||||
setState({
|
||||
disabled: data.disabled ?? false,
|
||||
reason: data.reason,
|
||||
isLoading: false,
|
||||
});
|
||||
} else {
|
||||
// Fail-open
|
||||
setState(s => ({ ...s, disabled: false, isLoading: false }));
|
||||
}
|
||||
} catch {
|
||||
// Fail-open on network error
|
||||
setState(s => ({ ...s, disabled: false, isLoading: false }));
|
||||
}
|
||||
}, [sdk]);
|
||||
|
||||
useEffect(() => {
|
||||
check();
|
||||
const id = setInterval(check, pollInterval);
|
||||
return () => clearInterval(id);
|
||||
}, [check, pollInterval]);
|
||||
|
||||
const value: KillSwitchContextType = { ...state, check };
|
||||
return React.createElement(KillSwitchContext.Provider, { value }, children);
|
||||
}
|
||||
7
packages/react-native-platform-sdk/src/surveys.ts
Normal file
7
packages/react-native-platform-sdk/src/surveys.ts
Normal file
@ -0,0 +1,7 @@
|
||||
export {
|
||||
useSurveys,
|
||||
SurveyProvider,
|
||||
SurveyModal,
|
||||
type ActiveSurvey,
|
||||
type Question,
|
||||
} from './surveys/index.js';
|
||||
108
packages/react-native-platform-sdk/src/surveys/index.ts
Normal file
108
packages/react-native-platform-sdk/src/surveys/index.ts
Normal file
@ -0,0 +1,108 @@
|
||||
/**
|
||||
* Surveys module — React context + hook for in-app surveys in React Native apps.
|
||||
*/
|
||||
|
||||
import React, { createContext, useContext, useState, useCallback, useEffect } from 'react';
|
||||
import type { PlatformSDK } from '../core.js';
|
||||
|
||||
export interface Question {
|
||||
id: string;
|
||||
text: string;
|
||||
type: 'rating' | 'text' | 'choice';
|
||||
options?: string[];
|
||||
required: boolean;
|
||||
}
|
||||
|
||||
export interface ActiveSurvey {
|
||||
id: string;
|
||||
title: string;
|
||||
description?: string;
|
||||
questions: Question[];
|
||||
expiresAt?: string;
|
||||
}
|
||||
|
||||
interface SurveyContextType {
|
||||
activeSurvey: ActiveSurvey | null;
|
||||
submit: (surveyId: string, answers: Record<string, unknown>) => Promise<void>;
|
||||
dismiss: (surveyId: string) => void;
|
||||
refresh: () => Promise<void>;
|
||||
}
|
||||
|
||||
const SurveyContext = createContext<SurveyContextType | null>(null);
|
||||
|
||||
export function useSurveys(): SurveyContextType {
|
||||
const ctx = useContext(SurveyContext);
|
||||
if (!ctx) throw new Error('useSurveys must be used within a SurveyProvider');
|
||||
return ctx;
|
||||
}
|
||||
|
||||
interface SurveyProviderProps {
|
||||
sdk: PlatformSDK;
|
||||
/** Poll interval in ms (default: 600000 = 10 min) */
|
||||
pollInterval?: number;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export function SurveyProvider({
|
||||
sdk,
|
||||
pollInterval = 600_000,
|
||||
children,
|
||||
}: SurveyProviderProps): React.JSX.Element {
|
||||
const [activeSurvey, setActiveSurvey] = useState<ActiveSurvey | null>(null);
|
||||
|
||||
const refresh = useCallback(async () => {
|
||||
try {
|
||||
const res = await sdk.fetch('/api/surveys/active');
|
||||
if (res.ok) {
|
||||
const data = (await res.json()) as ActiveSurvey | null;
|
||||
setActiveSurvey(data ?? null);
|
||||
}
|
||||
} catch {
|
||||
/* silent */
|
||||
}
|
||||
}, [sdk]);
|
||||
|
||||
const submit = useCallback(
|
||||
async (surveyId: string, answers: Record<string, unknown>) => {
|
||||
await sdk.fetch(`/api/surveys/${surveyId}/respond`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ answers }),
|
||||
});
|
||||
setActiveSurvey(null);
|
||||
},
|
||||
[sdk]
|
||||
);
|
||||
|
||||
const dismiss = useCallback(
|
||||
(surveyId: string) => {
|
||||
setActiveSurvey(null);
|
||||
sdk.fetch(`/api/surveys/${surveyId}/dismiss`, { method: 'POST' }).catch(() => {});
|
||||
},
|
||||
[sdk]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
refresh();
|
||||
const id = setInterval(refresh, pollInterval);
|
||||
return () => clearInterval(id);
|
||||
}, [refresh, pollInterval]);
|
||||
|
||||
const value: SurveyContextType = { activeSurvey, submit, dismiss, refresh };
|
||||
return React.createElement(SurveyContext.Provider, { value }, children);
|
||||
}
|
||||
|
||||
// MARK: - UI Components
|
||||
|
||||
interface SurveyModalProps {
|
||||
survey: ActiveSurvey | null;
|
||||
onSubmit: (answers: Record<string, unknown>) => void;
|
||||
onDismiss: () => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Placeholder survey modal — product apps should implement their own
|
||||
* styled version. Returns null.
|
||||
*/
|
||||
export function SurveyModal(_props: SurveyModalProps): React.JSX.Element | null {
|
||||
return null;
|
||||
}
|
||||
6
packages/react-native-platform-sdk/src/telemetry.ts
Normal file
6
packages/react-native-platform-sdk/src/telemetry.ts
Normal file
@ -0,0 +1,6 @@
|
||||
export {
|
||||
useTelemetry,
|
||||
TelemetryProvider,
|
||||
type TelemetryEvent,
|
||||
type TelemetryConfig,
|
||||
} from './telemetry/index.js';
|
||||
87
packages/react-native-platform-sdk/src/telemetry/index.ts
Normal file
87
packages/react-native-platform-sdk/src/telemetry/index.ts
Normal file
@ -0,0 +1,87 @@
|
||||
/**
|
||||
* Telemetry module — React context + hook for event tracking in React Native apps.
|
||||
*/
|
||||
|
||||
import React, { createContext, useContext, useCallback, useRef, useEffect } from 'react';
|
||||
import type { PlatformSDK } from '../core.js';
|
||||
|
||||
export interface TelemetryEvent {
|
||||
name: string;
|
||||
properties?: Record<string, unknown>;
|
||||
timestamp?: string;
|
||||
}
|
||||
|
||||
export interface TelemetryConfig {
|
||||
/** Flush interval in ms (default: 30000) */
|
||||
flushInterval?: number;
|
||||
/** Max batch size before auto-flush (default: 20) */
|
||||
maxBatchSize?: number;
|
||||
}
|
||||
|
||||
interface TelemetryContextType {
|
||||
track: (name: string, properties?: Record<string, unknown>) => void;
|
||||
flush: () => Promise<void>;
|
||||
}
|
||||
|
||||
const TelemetryContext = createContext<TelemetryContextType | null>(null);
|
||||
|
||||
export function useTelemetry(): TelemetryContextType {
|
||||
const ctx = useContext(TelemetryContext);
|
||||
if (!ctx) throw new Error('useTelemetry must be used within a TelemetryProvider');
|
||||
return ctx;
|
||||
}
|
||||
|
||||
interface TelemetryProviderProps {
|
||||
sdk: PlatformSDK;
|
||||
config?: TelemetryConfig;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export function TelemetryProvider({
|
||||
sdk,
|
||||
config,
|
||||
children,
|
||||
}: TelemetryProviderProps): React.JSX.Element {
|
||||
const queue = useRef<TelemetryEvent[]>([]);
|
||||
const flushInterval = config?.flushInterval ?? 30_000;
|
||||
const maxBatchSize = config?.maxBatchSize ?? 20;
|
||||
|
||||
const flush = useCallback(async () => {
|
||||
if (queue.current.length === 0) return;
|
||||
const batch = queue.current.splice(0);
|
||||
try {
|
||||
await sdk.fetch('/api/telemetry/batch', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ events: batch }),
|
||||
});
|
||||
} catch {
|
||||
// Re-queue on failure (best-effort)
|
||||
queue.current.unshift(...batch);
|
||||
}
|
||||
}, [sdk]);
|
||||
|
||||
const track = useCallback(
|
||||
(name: string, properties?: Record<string, unknown>) => {
|
||||
queue.current.push({
|
||||
name,
|
||||
properties,
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
if (queue.current.length >= maxBatchSize) {
|
||||
flush();
|
||||
}
|
||||
},
|
||||
[maxBatchSize, flush]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const id = setInterval(flush, flushInterval);
|
||||
return () => {
|
||||
clearInterval(id);
|
||||
flush();
|
||||
};
|
||||
}, [flush, flushInterval]);
|
||||
|
||||
const value: TelemetryContextType = { track, flush };
|
||||
return React.createElement(TelemetryContext.Provider, { value }, children);
|
||||
}
|
||||
12
packages/react-native-platform-sdk/tsconfig.json
Normal file
12
packages/react-native-platform-sdk/tsconfig.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"lib": ["ES2022"],
|
||||
"jsx": "react-jsx",
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["src/**/*.test.ts"]
|
||||
}
|
||||
407
pnpm-lock.yaml
generated
407
pnpm-lock.yaml
generated
@ -544,37 +544,25 @@ importers:
|
||||
|
||||
packages/react-native-platform-sdk:
|
||||
dependencies:
|
||||
'@bytelyst/api-client':
|
||||
specifier: workspace:*
|
||||
version: link:../api-client
|
||||
'@bytelyst/auth':
|
||||
specifier: workspace:*
|
||||
version: link:../auth
|
||||
'@bytelyst/config':
|
||||
specifier: workspace:*
|
||||
version: link:../config
|
||||
expo:
|
||||
specifier: '>=49.0.0'
|
||||
version: 55.0.4(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
|
||||
version: 55.0.4(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
|
||||
react:
|
||||
specifier: '>=18.0.0'
|
||||
version: 19.2.4
|
||||
react-native:
|
||||
specifier: '>=0.72.0'
|
||||
version: 0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4)
|
||||
version: 0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4)
|
||||
devDependencies:
|
||||
'@types/react':
|
||||
specifier: ^18.2.0
|
||||
version: 18.3.28
|
||||
'@types/react-native':
|
||||
specifier: ^0.72.0
|
||||
version: 0.72.8(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))
|
||||
eslint:
|
||||
specifier: ^8.54.0
|
||||
version: 8.57.1
|
||||
specifier: ^19.0.0
|
||||
version: 19.2.14
|
||||
typescript:
|
||||
specifier: ^5.3.0
|
||||
specifier: ^5.7.0
|
||||
version: 5.9.3
|
||||
vitest:
|
||||
specifier: ^3.0.0
|
||||
version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.11)(happy-dom@18.0.1)(jiti@2.6.1)(jsdom@28.0.0(@noble/hashes@1.8.0))(lightningcss@1.31.1)(msw@2.12.10(@types/node@22.19.11)(typescript@5.9.3))(terser@5.46.0)(tsx@4.21.0)(yaml@2.8.2)
|
||||
|
||||
packages/speech:
|
||||
devDependencies:
|
||||
@ -2261,13 +2249,6 @@ packages:
|
||||
}
|
||||
engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 }
|
||||
|
||||
'@eslint/eslintrc@2.1.4':
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==,
|
||||
}
|
||||
engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 }
|
||||
|
||||
'@eslint/eslintrc@3.3.3':
|
||||
resolution:
|
||||
{
|
||||
@ -2287,13 +2268,6 @@ packages:
|
||||
eslint:
|
||||
optional: true
|
||||
|
||||
'@eslint/js@8.57.1':
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==,
|
||||
}
|
||||
engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 }
|
||||
|
||||
'@eslint/js@9.39.2':
|
||||
resolution:
|
||||
{
|
||||
@ -2696,14 +2670,6 @@ packages:
|
||||
}
|
||||
engines: { node: '>=18.18.0' }
|
||||
|
||||
'@humanwhocodes/config-array@0.13.0':
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==,
|
||||
}
|
||||
engines: { node: '>=10.10.0' }
|
||||
deprecated: Use @eslint/config-array instead
|
||||
|
||||
'@humanwhocodes/module-importer@1.0.1':
|
||||
resolution:
|
||||
{
|
||||
@ -2711,13 +2677,6 @@ packages:
|
||||
}
|
||||
engines: { node: '>=12.22' }
|
||||
|
||||
'@humanwhocodes/object-schema@2.0.3':
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==,
|
||||
}
|
||||
deprecated: Use @eslint/object-schema instead
|
||||
|
||||
'@humanwhocodes/retry@0.4.3':
|
||||
resolution:
|
||||
{
|
||||
@ -4520,14 +4479,6 @@ packages:
|
||||
integrity: sha512-/UPaQ4jl95soXnLDEJ6Cs6lnRXhwbxtT4KbZz+AFDees7prMV2NOLcHfCnzmTabf5Y3oxENMVBL666n4GMLcTA==,
|
||||
}
|
||||
|
||||
'@react-native/virtualized-lists@0.72.8':
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-J3Q4Bkuo99k7mu+jPS9gSUSgq+lLRSI/+ahXNwV92XgJ/8UgOTxu2LPwhJnBk/sQKxq7E8WkZBnBiozukQMqrw==,
|
||||
}
|
||||
peerDependencies:
|
||||
react-native: '*'
|
||||
|
||||
'@react-native/virtualized-lists@0.84.1':
|
||||
resolution:
|
||||
{
|
||||
@ -5198,12 +5149,6 @@ packages:
|
||||
integrity: sha512-BH7YwL6rA93ReqeQS1c4bsPpcfOmJasG+Fkr6Y59q83f9M1WcBRHR2vM+P9eOisYRcN3ujQoiZY8uk5W+1WL8w==,
|
||||
}
|
||||
|
||||
'@types/prop-types@15.7.15':
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==,
|
||||
}
|
||||
|
||||
'@types/react-dom@19.2.3':
|
||||
resolution:
|
||||
{
|
||||
@ -5212,18 +5157,6 @@ packages:
|
||||
peerDependencies:
|
||||
'@types/react': ^19.2.0
|
||||
|
||||
'@types/react-native@0.72.8':
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-St6xA7+EoHN5mEYfdWnfYt0e8u6k2FR0P9s2arYgakQGFgU1f9FlPrIEcj0X24pLCF5c5i3WVuLCUdiCYHmOoA==,
|
||||
}
|
||||
|
||||
'@types/react@18.3.28':
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-z9VXpC7MWrhfWipitjNdgCauoMLRdIILQsAEV+ZesIzBq/oUlxk0m3ApZuMFCXdnS4U7KrI+l3WRUEGQ8K1QKw==,
|
||||
}
|
||||
|
||||
'@types/react@19.2.14':
|
||||
resolution:
|
||||
{
|
||||
@ -7334,13 +7267,6 @@ packages:
|
||||
}
|
||||
engines: { node: '>=0.10.0' }
|
||||
|
||||
doctrine@3.0.0:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==,
|
||||
}
|
||||
engines: { node: '>=6.0.0' }
|
||||
|
||||
dom-accessibility-api@0.5.16:
|
||||
resolution:
|
||||
{
|
||||
@ -7704,13 +7630,6 @@ packages:
|
||||
peerDependencies:
|
||||
eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7
|
||||
|
||||
eslint-scope@7.2.2:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==,
|
||||
}
|
||||
engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 }
|
||||
|
||||
eslint-scope@8.4.0:
|
||||
resolution:
|
||||
{
|
||||
@ -7739,15 +7658,6 @@ packages:
|
||||
}
|
||||
engines: { node: ^20.19.0 || ^22.13.0 || >=24 }
|
||||
|
||||
eslint@8.57.1:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==,
|
||||
}
|
||||
engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 }
|
||||
deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options.
|
||||
hasBin: true
|
||||
|
||||
eslint@9.39.2:
|
||||
resolution:
|
||||
{
|
||||
@ -7768,13 +7678,6 @@ packages:
|
||||
}
|
||||
engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 }
|
||||
|
||||
espree@9.6.1:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==,
|
||||
}
|
||||
engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 }
|
||||
|
||||
esprima@4.0.1:
|
||||
resolution:
|
||||
{
|
||||
@ -8187,13 +8090,6 @@ packages:
|
||||
}
|
||||
engines: { node: '>=18' }
|
||||
|
||||
file-entry-cache@6.0.1:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==,
|
||||
}
|
||||
engines: { node: ^10.12.0 || >=12.0.0 }
|
||||
|
||||
file-entry-cache@8.0.0:
|
||||
resolution:
|
||||
{
|
||||
@ -8243,13 +8139,6 @@ packages:
|
||||
}
|
||||
engines: { node: '>=10' }
|
||||
|
||||
flat-cache@3.2.0:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==,
|
||||
}
|
||||
engines: { node: ^10.12.0 || >=12.0.0 }
|
||||
|
||||
flat-cache@4.0.1:
|
||||
resolution:
|
||||
{
|
||||
@ -8575,13 +8464,6 @@ packages:
|
||||
}
|
||||
deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
|
||||
|
||||
globals@13.24.0:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==,
|
||||
}
|
||||
engines: { node: '>=8' }
|
||||
|
||||
globals@14.0.0:
|
||||
resolution:
|
||||
{
|
||||
@ -8623,12 +8505,6 @@ packages:
|
||||
integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==,
|
||||
}
|
||||
|
||||
graphemer@1.4.0:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==,
|
||||
}
|
||||
|
||||
graphql@16.13.0:
|
||||
resolution:
|
||||
{
|
||||
@ -9255,13 +9131,6 @@ packages:
|
||||
}
|
||||
engines: { node: '>=12' }
|
||||
|
||||
is-path-inside@3.0.3:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==,
|
||||
}
|
||||
engines: { node: '>=8' }
|
||||
|
||||
is-plain-obj@4.1.0:
|
||||
resolution:
|
||||
{
|
||||
@ -13088,12 +12957,6 @@ packages:
|
||||
}
|
||||
engines: { node: '>=18' }
|
||||
|
||||
text-table@0.2.0:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==,
|
||||
}
|
||||
|
||||
thread-stream@4.0.0:
|
||||
resolution:
|
||||
{
|
||||
@ -13307,13 +13170,6 @@ packages:
|
||||
}
|
||||
engines: { node: '>=4' }
|
||||
|
||||
type-fest@0.20.2:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==,
|
||||
}
|
||||
engines: { node: '>=10' }
|
||||
|
||||
type-fest@0.21.3:
|
||||
resolution:
|
||||
{
|
||||
@ -15257,11 +15113,6 @@ snapshots:
|
||||
'@esbuild/win32-x64@0.27.3':
|
||||
optional: true
|
||||
|
||||
'@eslint-community/eslint-utils@4.9.1(eslint@8.57.1)':
|
||||
dependencies:
|
||||
eslint: 8.57.1
|
||||
eslint-visitor-keys: 3.4.3
|
||||
|
||||
'@eslint-community/eslint-utils@4.9.1(eslint@9.39.2(jiti@2.6.1))':
|
||||
dependencies:
|
||||
eslint: 9.39.2(jiti@2.6.1)
|
||||
@ -15285,20 +15136,6 @@ snapshots:
|
||||
dependencies:
|
||||
'@types/json-schema': 7.0.15
|
||||
|
||||
'@eslint/eslintrc@2.1.4':
|
||||
dependencies:
|
||||
ajv: 6.12.6
|
||||
debug: 4.4.3
|
||||
espree: 9.6.1
|
||||
globals: 13.24.0
|
||||
ignore: 5.3.2
|
||||
import-fresh: 3.3.1
|
||||
js-yaml: 4.1.1
|
||||
minimatch: 3.1.2
|
||||
strip-json-comments: 3.1.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@eslint/eslintrc@3.3.3':
|
||||
dependencies:
|
||||
ajv: 6.12.6
|
||||
@ -15317,8 +15154,6 @@ snapshots:
|
||||
optionalDependencies:
|
||||
eslint: 9.39.2(jiti@2.6.1)
|
||||
|
||||
'@eslint/js@8.57.1': {}
|
||||
|
||||
'@eslint/js@9.39.2': {}
|
||||
|
||||
'@eslint/object-schema@2.1.7': {}
|
||||
@ -15333,7 +15168,7 @@ snapshots:
|
||||
'@noble/hashes': 1.8.0
|
||||
optional: true
|
||||
|
||||
'@expo/cli@55.0.14(@expo/dom-webview@55.0.3)(expo-constants@55.0.7(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(typescript@5.9.3))(expo-font@55.0.4(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4))(expo@55.0.4)(react-dom@19.2.4(react@19.2.4))(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4)(typescript@5.9.3)':
|
||||
'@expo/cli@55.0.14(@expo/dom-webview@55.0.3)(expo-constants@55.0.7(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(typescript@5.9.3))(expo-font@55.0.4(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4))(expo@55.0.4)(react-dom@19.2.4(react@19.2.4))(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3)':
|
||||
dependencies:
|
||||
'@expo/code-signing-certificates': 0.0.6
|
||||
'@expo/config': 55.0.8(typescript@5.9.3)
|
||||
@ -15342,7 +15177,7 @@ snapshots:
|
||||
'@expo/env': 2.1.1
|
||||
'@expo/image-utils': 0.8.12
|
||||
'@expo/json-file': 10.0.12
|
||||
'@expo/log-box': 55.0.7(@expo/dom-webview@55.0.3)(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4)
|
||||
'@expo/log-box': 55.0.7(@expo/dom-webview@55.0.3)(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)
|
||||
'@expo/metro': 54.2.0
|
||||
'@expo/metro-config': 55.0.9(expo@55.0.4)(typescript@5.9.3)
|
||||
'@expo/osascript': 2.4.2
|
||||
@ -15350,7 +15185,7 @@ snapshots:
|
||||
'@expo/plist': 0.5.2
|
||||
'@expo/prebuild-config': 55.0.8(expo@55.0.4)(typescript@5.9.3)
|
||||
'@expo/require-utils': 55.0.2(typescript@5.9.3)
|
||||
'@expo/router-server': 55.0.9(expo-constants@55.0.7(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(typescript@5.9.3))(expo-font@55.0.4(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4))(expo-server@55.0.6)(expo@55.0.4)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||
'@expo/router-server': 55.0.9(expo-constants@55.0.7(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(typescript@5.9.3))(expo-font@55.0.4(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4))(expo-server@55.0.6)(expo@55.0.4)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
|
||||
'@expo/schema-utils': 55.0.2
|
||||
'@expo/spawn-async': 1.7.2
|
||||
'@expo/ws-tunnel': 1.0.6
|
||||
@ -15367,7 +15202,7 @@ snapshots:
|
||||
connect: 3.7.0
|
||||
debug: 4.4.3
|
||||
dnssd-advertise: 1.1.3
|
||||
expo: 55.0.4(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
|
||||
expo: 55.0.4(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
|
||||
expo-server: 55.0.6
|
||||
fetch-nodeshim: 0.4.8
|
||||
getenv: 2.0.0
|
||||
@ -15394,7 +15229,7 @@ snapshots:
|
||||
ws: 8.19.0
|
||||
zod: 3.25.76
|
||||
optionalDependencies:
|
||||
react-native: 0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4)
|
||||
react-native: 0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4)
|
||||
transitivePeerDependencies:
|
||||
- '@expo/dom-webview'
|
||||
- '@expo/metro-runtime'
|
||||
@ -15456,18 +15291,18 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@expo/devtools@55.0.2(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4)':
|
||||
'@expo/devtools@55.0.2(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)':
|
||||
dependencies:
|
||||
chalk: 4.1.2
|
||||
optionalDependencies:
|
||||
react: 19.2.4
|
||||
react-native: 0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4)
|
||||
react-native: 0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4)
|
||||
|
||||
'@expo/dom-webview@55.0.3(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4)':
|
||||
'@expo/dom-webview@55.0.3(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)':
|
||||
dependencies:
|
||||
expo: 55.0.4(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
|
||||
expo: 55.0.4(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
|
||||
react: 19.2.4
|
||||
react-native: 0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4)
|
||||
react-native: 0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4)
|
||||
|
||||
'@expo/env@2.1.1':
|
||||
dependencies:
|
||||
@ -15516,13 +15351,13 @@ snapshots:
|
||||
- supports-color
|
||||
- typescript
|
||||
|
||||
'@expo/log-box@55.0.7(@expo/dom-webview@55.0.3)(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4)':
|
||||
'@expo/log-box@55.0.7(@expo/dom-webview@55.0.3)(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)':
|
||||
dependencies:
|
||||
'@expo/dom-webview': 55.0.3(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4)
|
||||
'@expo/dom-webview': 55.0.3(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)
|
||||
anser: 1.4.10
|
||||
expo: 55.0.4(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
|
||||
expo: 55.0.4(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
|
||||
react: 19.2.4
|
||||
react-native: 0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4)
|
||||
react-native: 0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4)
|
||||
stacktrace-parser: 0.1.11
|
||||
|
||||
'@expo/metro-config@55.0.9(expo@55.0.4)(typescript@5.9.3)':
|
||||
@ -15547,7 +15382,7 @@ snapshots:
|
||||
postcss: 8.4.49
|
||||
resolve-from: 5.0.0
|
||||
optionalDependencies:
|
||||
expo: 55.0.4(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
|
||||
expo: 55.0.4(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- supports-color
|
||||
@ -15603,7 +15438,7 @@ snapshots:
|
||||
'@expo/json-file': 10.0.12
|
||||
'@react-native/normalize-colors': 0.83.2
|
||||
debug: 4.4.3
|
||||
expo: 55.0.4(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
|
||||
expo: 55.0.4(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
|
||||
resolve-from: 5.0.0
|
||||
semver: 7.7.4
|
||||
xml2js: 0.6.0
|
||||
@ -15621,12 +15456,12 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@expo/router-server@55.0.9(expo-constants@55.0.7(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(typescript@5.9.3))(expo-font@55.0.4(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4))(expo-server@55.0.6)(expo@55.0.4)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
|
||||
'@expo/router-server@55.0.9(expo-constants@55.0.7(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(typescript@5.9.3))(expo-font@55.0.4(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4))(expo-server@55.0.6)(expo@55.0.4)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
|
||||
dependencies:
|
||||
debug: 4.4.3
|
||||
expo: 55.0.4(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
|
||||
expo-constants: 55.0.7(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(typescript@5.9.3)
|
||||
expo-font: 55.0.4(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4)
|
||||
expo: 55.0.4(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
|
||||
expo-constants: 55.0.7(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(typescript@5.9.3)
|
||||
expo-font: 55.0.4(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)
|
||||
expo-server: 55.0.6
|
||||
react: 19.2.4
|
||||
optionalDependencies:
|
||||
@ -15644,11 +15479,11 @@ snapshots:
|
||||
|
||||
'@expo/sudo-prompt@9.3.2': {}
|
||||
|
||||
'@expo/vector-icons@15.1.1(expo-font@55.0.4(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4))(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4)':
|
||||
'@expo/vector-icons@15.1.1(expo-font@55.0.4(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4))(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)':
|
||||
dependencies:
|
||||
expo-font: 55.0.4(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4)
|
||||
expo-font: 55.0.4(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)
|
||||
react: 19.2.4
|
||||
react-native: 0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4)
|
||||
react-native: 0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4)
|
||||
|
||||
'@expo/ws-tunnel@1.0.6': {}
|
||||
|
||||
@ -15757,18 +15592,8 @@ snapshots:
|
||||
'@humanfs/core': 0.19.1
|
||||
'@humanwhocodes/retry': 0.4.3
|
||||
|
||||
'@humanwhocodes/config-array@0.13.0':
|
||||
dependencies:
|
||||
'@humanwhocodes/object-schema': 2.0.3
|
||||
debug: 4.4.3
|
||||
minimatch: 3.1.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@humanwhocodes/module-importer@1.0.1': {}
|
||||
|
||||
'@humanwhocodes/object-schema@2.0.3': {}
|
||||
|
||||
'@humanwhocodes/retry@0.4.3': {}
|
||||
|
||||
'@img/colour@1.0.0':
|
||||
@ -17163,20 +16988,14 @@ snapshots:
|
||||
|
||||
'@react-native/normalize-colors@0.84.1': {}
|
||||
|
||||
'@react-native/virtualized-lists@0.72.8(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))':
|
||||
dependencies:
|
||||
invariant: 2.2.4
|
||||
nullthrows: 1.1.1
|
||||
react-native: 0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4)
|
||||
|
||||
'@react-native/virtualized-lists@0.84.1(@types/react@18.3.28)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4)':
|
||||
'@react-native/virtualized-lists@0.84.1(@types/react@19.2.14)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)':
|
||||
dependencies:
|
||||
invariant: 2.2.4
|
||||
nullthrows: 1.1.1
|
||||
react: 19.2.4
|
||||
react-native: 0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4)
|
||||
react-native: 0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4)
|
||||
optionalDependencies:
|
||||
'@types/react': 18.3.28
|
||||
'@types/react': 19.2.14
|
||||
|
||||
'@reduxjs/toolkit@2.11.2(react-redux@9.2.0(@types/react@19.2.14)(react@19.2.3)(redux@5.0.1))(react@19.2.3)':
|
||||
dependencies:
|
||||
@ -17499,24 +17318,10 @@ snapshots:
|
||||
dependencies:
|
||||
undici-types: 6.21.0
|
||||
|
||||
'@types/prop-types@15.7.15': {}
|
||||
|
||||
'@types/react-dom@19.2.3(@types/react@19.2.14)':
|
||||
dependencies:
|
||||
'@types/react': 19.2.14
|
||||
|
||||
'@types/react-native@0.72.8(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))':
|
||||
dependencies:
|
||||
'@react-native/virtualized-lists': 0.72.8(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))
|
||||
'@types/react': 19.2.14
|
||||
transitivePeerDependencies:
|
||||
- react-native
|
||||
|
||||
'@types/react@18.3.28':
|
||||
dependencies:
|
||||
'@types/prop-types': 15.7.15
|
||||
csstype: 3.2.3
|
||||
|
||||
'@types/react@19.2.14':
|
||||
dependencies:
|
||||
csstype: 3.2.3
|
||||
@ -18269,7 +18074,7 @@ snapshots:
|
||||
resolve-from: 5.0.0
|
||||
optionalDependencies:
|
||||
'@babel/runtime': 7.28.6
|
||||
expo: 55.0.4(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
|
||||
expo: 55.0.4(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
|
||||
transitivePeerDependencies:
|
||||
- '@babel/core'
|
||||
- supports-color
|
||||
@ -18842,10 +18647,6 @@ snapshots:
|
||||
dependencies:
|
||||
esutils: 2.0.3
|
||||
|
||||
doctrine@3.0.0:
|
||||
dependencies:
|
||||
esutils: 2.0.3
|
||||
|
||||
dom-accessibility-api@0.5.16: {}
|
||||
|
||||
dompurify@3.3.1:
|
||||
@ -19274,11 +19075,6 @@ snapshots:
|
||||
string.prototype.matchall: 4.0.12
|
||||
string.prototype.repeat: 1.0.0
|
||||
|
||||
eslint-scope@7.2.2:
|
||||
dependencies:
|
||||
esrecurse: 4.3.0
|
||||
estraverse: 5.3.0
|
||||
|
||||
eslint-scope@8.4.0:
|
||||
dependencies:
|
||||
esrecurse: 4.3.0
|
||||
@ -19290,49 +19086,6 @@ snapshots:
|
||||
|
||||
eslint-visitor-keys@5.0.0: {}
|
||||
|
||||
eslint@8.57.1:
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1)
|
||||
'@eslint-community/regexpp': 4.12.2
|
||||
'@eslint/eslintrc': 2.1.4
|
||||
'@eslint/js': 8.57.1
|
||||
'@humanwhocodes/config-array': 0.13.0
|
||||
'@humanwhocodes/module-importer': 1.0.1
|
||||
'@nodelib/fs.walk': 1.2.8
|
||||
'@ungap/structured-clone': 1.3.0
|
||||
ajv: 6.12.6
|
||||
chalk: 4.1.2
|
||||
cross-spawn: 7.0.6
|
||||
debug: 4.4.3
|
||||
doctrine: 3.0.0
|
||||
escape-string-regexp: 4.0.0
|
||||
eslint-scope: 7.2.2
|
||||
eslint-visitor-keys: 3.4.3
|
||||
espree: 9.6.1
|
||||
esquery: 1.7.0
|
||||
esutils: 2.0.3
|
||||
fast-deep-equal: 3.1.3
|
||||
file-entry-cache: 6.0.1
|
||||
find-up: 5.0.0
|
||||
glob-parent: 6.0.2
|
||||
globals: 13.24.0
|
||||
graphemer: 1.4.0
|
||||
ignore: 5.3.2
|
||||
imurmurhash: 0.1.4
|
||||
is-glob: 4.0.3
|
||||
is-path-inside: 3.0.3
|
||||
js-yaml: 4.1.1
|
||||
json-stable-stringify-without-jsonify: 1.0.1
|
||||
levn: 0.4.1
|
||||
lodash.merge: 4.6.2
|
||||
minimatch: 3.1.2
|
||||
natural-compare: 1.4.0
|
||||
optionator: 0.9.4
|
||||
strip-ansi: 6.0.1
|
||||
text-table: 0.2.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
eslint@9.39.2(jiti@2.6.1):
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2(jiti@2.6.1))
|
||||
@ -19380,12 +19133,6 @@ snapshots:
|
||||
acorn-jsx: 5.3.2(acorn@8.15.0)
|
||||
eslint-visitor-keys: 4.2.1
|
||||
|
||||
espree@9.6.1:
|
||||
dependencies:
|
||||
acorn: 8.15.0
|
||||
acorn-jsx: 5.3.2(acorn@8.15.0)
|
||||
eslint-visitor-keys: 3.4.3
|
||||
|
||||
esprima@4.0.1: {}
|
||||
|
||||
esquery@1.7.0:
|
||||
@ -19463,42 +19210,42 @@ snapshots:
|
||||
|
||||
expect-type@1.3.0: {}
|
||||
|
||||
expo-asset@55.0.8(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4)(typescript@5.9.3):
|
||||
expo-asset@55.0.8(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3):
|
||||
dependencies:
|
||||
'@expo/image-utils': 0.8.12
|
||||
expo: 55.0.4(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
|
||||
expo-constants: 55.0.7(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(typescript@5.9.3)
|
||||
expo: 55.0.4(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
|
||||
expo-constants: 55.0.7(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(typescript@5.9.3)
|
||||
react: 19.2.4
|
||||
react-native: 0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4)
|
||||
react-native: 0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
- typescript
|
||||
|
||||
expo-constants@55.0.7(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(typescript@5.9.3):
|
||||
expo-constants@55.0.7(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(typescript@5.9.3):
|
||||
dependencies:
|
||||
'@expo/config': 55.0.8(typescript@5.9.3)
|
||||
'@expo/env': 2.1.1
|
||||
expo: 55.0.4(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
|
||||
react-native: 0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4)
|
||||
expo: 55.0.4(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
|
||||
react-native: 0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
- typescript
|
||||
|
||||
expo-file-system@55.0.10(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4)):
|
||||
expo-file-system@55.0.10(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4)):
|
||||
dependencies:
|
||||
expo: 55.0.4(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
|
||||
react-native: 0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4)
|
||||
expo: 55.0.4(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
|
||||
react-native: 0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4)
|
||||
|
||||
expo-font@55.0.4(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4):
|
||||
expo-font@55.0.4(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4):
|
||||
dependencies:
|
||||
expo: 55.0.4(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
|
||||
expo: 55.0.4(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
|
||||
fontfaceobserver: 2.3.0
|
||||
react: 19.2.4
|
||||
react-native: 0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4)
|
||||
react-native: 0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4)
|
||||
|
||||
expo-keep-awake@55.0.4(expo@55.0.4)(react@19.2.4):
|
||||
dependencies:
|
||||
expo: 55.0.4(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
|
||||
expo: 55.0.4(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
|
||||
react: 19.2.4
|
||||
|
||||
expo-modules-autolinking@55.0.8(typescript@5.9.3):
|
||||
@ -19511,43 +19258,43 @@ snapshots:
|
||||
- supports-color
|
||||
- typescript
|
||||
|
||||
expo-modules-core@55.0.13(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4):
|
||||
expo-modules-core@55.0.13(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4):
|
||||
dependencies:
|
||||
invariant: 2.2.4
|
||||
react: 19.2.4
|
||||
react-native: 0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4)
|
||||
react-native: 0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4)
|
||||
|
||||
expo-server@55.0.6: {}
|
||||
|
||||
expo@55.0.4(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4)(typescript@5.9.3):
|
||||
expo@55.0.4(@babel/core@7.29.0)(@expo/dom-webview@55.0.3)(react-dom@19.2.4(react@19.2.4))(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3):
|
||||
dependencies:
|
||||
'@babel/runtime': 7.28.6
|
||||
'@expo/cli': 55.0.14(@expo/dom-webview@55.0.3)(expo-constants@55.0.7(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(typescript@5.9.3))(expo-font@55.0.4(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4))(expo@55.0.4)(react-dom@19.2.4(react@19.2.4))(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
|
||||
'@expo/cli': 55.0.14(@expo/dom-webview@55.0.3)(expo-constants@55.0.7(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(typescript@5.9.3))(expo-font@55.0.4(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4))(expo@55.0.4)(react-dom@19.2.4(react@19.2.4))(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
|
||||
'@expo/config': 55.0.8(typescript@5.9.3)
|
||||
'@expo/config-plugins': 55.0.6
|
||||
'@expo/devtools': 55.0.2(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4)
|
||||
'@expo/devtools': 55.0.2(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)
|
||||
'@expo/fingerprint': 0.16.5
|
||||
'@expo/local-build-cache-provider': 55.0.6(typescript@5.9.3)
|
||||
'@expo/log-box': 55.0.7(@expo/dom-webview@55.0.3)(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4)
|
||||
'@expo/log-box': 55.0.7(@expo/dom-webview@55.0.3)(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)
|
||||
'@expo/metro': 54.2.0
|
||||
'@expo/metro-config': 55.0.9(expo@55.0.4)(typescript@5.9.3)
|
||||
'@expo/vector-icons': 15.1.1(expo-font@55.0.4(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4))(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4)
|
||||
'@expo/vector-icons': 15.1.1(expo-font@55.0.4(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4))(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)
|
||||
'@ungap/structured-clone': 1.3.0
|
||||
babel-preset-expo: 55.0.10(@babel/core@7.29.0)(@babel/runtime@7.28.6)(expo@55.0.4)(react-refresh@0.14.2)
|
||||
expo-asset: 55.0.8(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
|
||||
expo-constants: 55.0.7(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(typescript@5.9.3)
|
||||
expo-file-system: 55.0.10(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))
|
||||
expo-font: 55.0.4(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4)
|
||||
expo-asset: 55.0.8(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)(typescript@5.9.3)
|
||||
expo-constants: 55.0.7(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(typescript@5.9.3)
|
||||
expo-file-system: 55.0.10(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))
|
||||
expo-font: 55.0.4(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)
|
||||
expo-keep-awake: 55.0.4(expo@55.0.4)(react@19.2.4)
|
||||
expo-modules-autolinking: 55.0.8(typescript@5.9.3)
|
||||
expo-modules-core: 55.0.13(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4)
|
||||
expo-modules-core: 55.0.13(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)
|
||||
pretty-format: 29.7.0
|
||||
react: 19.2.4
|
||||
react-native: 0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4)
|
||||
react-native: 0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4)
|
||||
react-refresh: 0.14.2
|
||||
whatwg-url-minimum: 0.1.1
|
||||
optionalDependencies:
|
||||
'@expo/dom-webview': 55.0.3(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4)
|
||||
'@expo/dom-webview': 55.0.3(expo@55.0.4)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)
|
||||
transitivePeerDependencies:
|
||||
- '@babel/core'
|
||||
- bufferutil
|
||||
@ -19713,10 +19460,6 @@ snapshots:
|
||||
dependencies:
|
||||
is-unicode-supported: 2.1.0
|
||||
|
||||
file-entry-cache@6.0.1:
|
||||
dependencies:
|
||||
flat-cache: 3.2.0
|
||||
|
||||
file-entry-cache@8.0.0:
|
||||
dependencies:
|
||||
flat-cache: 4.0.1
|
||||
@ -19764,12 +19507,6 @@ snapshots:
|
||||
locate-path: 6.0.0
|
||||
path-exists: 4.0.0
|
||||
|
||||
flat-cache@3.2.0:
|
||||
dependencies:
|
||||
flatted: 3.3.3
|
||||
keyv: 4.5.4
|
||||
rimraf: 3.0.2
|
||||
|
||||
flat-cache@4.0.1:
|
||||
dependencies:
|
||||
flatted: 3.3.3
|
||||
@ -19959,10 +19696,6 @@ snapshots:
|
||||
once: 1.4.0
|
||||
path-is-absolute: 1.0.1
|
||||
|
||||
globals@13.24.0:
|
||||
dependencies:
|
||||
type-fest: 0.20.2
|
||||
|
||||
globals@14.0.0: {}
|
||||
|
||||
globals@16.4.0: {}
|
||||
@ -19985,8 +19718,6 @@ snapshots:
|
||||
|
||||
graceful-fs@4.2.11: {}
|
||||
|
||||
graphemer@1.4.0: {}
|
||||
|
||||
graphql@16.13.0: {}
|
||||
|
||||
gzip-size@4.1.0:
|
||||
@ -20312,8 +20043,6 @@ snapshots:
|
||||
|
||||
is-obj@3.0.0: {}
|
||||
|
||||
is-path-inside@3.0.3: {}
|
||||
|
||||
is-plain-obj@4.1.0: {}
|
||||
|
||||
is-potential-custom-element-name@1.0.1:
|
||||
@ -22385,7 +22114,7 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4):
|
||||
react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4):
|
||||
dependencies:
|
||||
'@jest/create-cache-key-function': 29.7.0
|
||||
'@react-native/assets-registry': 0.84.1
|
||||
@ -22394,7 +22123,7 @@ snapshots:
|
||||
'@react-native/gradle-plugin': 0.84.1
|
||||
'@react-native/js-polyfills': 0.84.1
|
||||
'@react-native/normalize-colors': 0.84.1
|
||||
'@react-native/virtualized-lists': 0.84.1(@types/react@18.3.28)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@18.3.28)(react@19.2.4))(react@19.2.4)
|
||||
'@react-native/virtualized-lists': 0.84.1(@types/react@19.2.14)(react-native@0.84.1(@babel/core@7.29.0)(@types/react@19.2.14)(react@19.2.4))(react@19.2.4)
|
||||
abort-controller: 3.0.0
|
||||
anser: 1.4.10
|
||||
ansi-regex: 5.0.1
|
||||
@ -22424,7 +22153,7 @@ snapshots:
|
||||
ws: 7.5.10
|
||||
yargs: 17.7.2
|
||||
optionalDependencies:
|
||||
'@types/react': 18.3.28
|
||||
'@types/react': 19.2.14
|
||||
transitivePeerDependencies:
|
||||
- '@babel/core'
|
||||
- '@react-native-community/cli'
|
||||
@ -23278,8 +23007,6 @@ snapshots:
|
||||
glob: 10.5.0
|
||||
minimatch: 9.0.5
|
||||
|
||||
text-table@0.2.0: {}
|
||||
|
||||
thread-stream@4.0.0:
|
||||
dependencies:
|
||||
real-require: 0.2.0
|
||||
@ -23381,8 +23108,6 @@ snapshots:
|
||||
|
||||
type-detect@4.0.8: {}
|
||||
|
||||
type-fest@0.20.2: {}
|
||||
|
||||
type-fest@0.21.3: {}
|
||||
|
||||
type-fest@0.7.1: {}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user