{"_id":"@archlast/sdk-expo","name":"@archlast/sdk-expo","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.1":{"name":"@archlast/sdk-expo","version":"0.1.1","description":"Archlast SDK for Expo (React Native) with SecureStore and deep linking","license":"MIT","repository":{"type":"git","url":"git+https://github.com/algochad/archlast-sync.git"},"type":"module","main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./auth":{"types":"./dist/auth/index.d.ts","import":"./dist/auth/index.js","require":"./dist/auth/index.cjs"},"./react":{"types":"./dist/react.d.ts","import":"./dist/react.js","require":"./dist/react.cjs"}},"scripts":{"build":"tsup","prepublishOnly":"npm run build","test":"bun test","format":"prettier --write \"**/*.{ts,tsx,js,jsx,json,md}\"","format:check":"prettier --check \"**/*.{ts,tsx,js,jsx,json,md}\"","clean":"rm -rf dist"},"dependencies":{"@archlast/sdk-core":"^0.1.1","@better-auth/expo":"^1.4.10","better-auth":"^1.4.10"},"devDependencies":{"expo":"~52.0.0","react":"^18.0.0 || ^19.0.0","react-native":">=0.73.0","typescript":"^5.0.0","tsup":"^8.5.1","prettier":"^3.4.2","@types/react":"^19","@types/react-native":"^0.73.0"},"peerDependencies":{"expo":"*","react":"^18.0.0 || ^19.0.0","react-native":">=0.73.0"},"peerDependenciesMeta":{"expo":{"optional":false},"react-native":{"optional":false}},"_id":"@archlast/sdk-expo@0.1.1","gitHead":"5c702f9d66c02436cf156c2bd7791beb6764360d","bugs":{"url":"https://github.com/algochad/archlast-sync/issues"},"homepage":"https://github.com/algochad/archlast-sync#readme","_nodeVersion":"22.20.0","_npmVersion":"10.9.3","dist":{"integrity":"sha512-oKTCFv7s7etZzkvm4zLKlL90eirPs0dkWmVWYkMWVgFS+c0cXChxZ49UpxUe351dW0M9kn/wajhVJd29d/aLfQ==","shasum":"029e21ca24a99561df479601a2702920bf80eadf","tarball":"https://registry.npmjs.org/@archlast/sdk-expo/-/sdk-expo-0.1.1.tgz","fileCount":20,"unpackedSize":473453,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIH4uC8d9U1BrmSMHJFNAd2afGF5xzwLYRobzovPhp488AiAeh9zBlsd4uN4iLWcwQBnXClq8bZ2nkYNqM4KqqgSiPQ=="}]},"_npmUser":{"name":"algochad","email":"givillamor01@gmail.com"},"directories":{},"maintainers":[{"name":"algochad","email":"givillamor01@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/sdk-expo_0.1.1_1769954263075_0.17791450768186556"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-01T13:57:42.967Z","0.1.1":"2026-02-01T13:57:43.217Z","modified":"2026-02-01T13:57:43.457Z"},"maintainers":[{"name":"algochad","email":"givillamor01@gmail.com"}],"description":"Archlast SDK for Expo (React Native) with SecureStore and deep linking","homepage":"https://github.com/algochad/archlast-sync#readme","repository":{"type":"git","url":"git+https://github.com/algochad/archlast-sync.git"},"bugs":{"url":"https://github.com/algochad/archlast-sync/issues"},"license":"MIT","readme":"# @archlast/sdk-expo\n\nArchlast SDK for Expo (React Native) with SecureStore and deep linking support.\n\n## Installation\n\n```bash\nnpm install @archlast/sdk-expo\nnpx expo install expo-secure-store\n```\n\n## Features\n\n- **Secure Storage**: Uses `expo-secure-store` for session persistence\n- **Deep Linking**: OAuth callback support via deep links\n- **Better-Auth Wrapped**: No need to install `better-auth` directly\n- **React Native Hooks**: `useAuth()`, `useSession()`\n- **Type-Safe**: Full TypeScript support\n\n## Configuration\n\n### 1. Update app.json\n\nAdd your app's scheme to `app.json` for deep linking:\n\n```json\n{\n    \"expo\": {\n        \"scheme\": \"archlast\",\n        \"extra\": {\n            \"eas\": {\n                \"projectId\": \"your-project-id\"\n            }\n        }\n    }\n}\n```\n\n### 2. Update Metro Config\n\nEnable package exports in `metro.config.js`:\n\n```javascript\nconst { getDefaultConfig } = require(\"expo/metro-config\");\n\nconst config = getDefaultConfig(__dirname);\n\nconfig.resolver.unstable_enablePackageExports = true;\n\nmodule.exports = config;\n```\n\nOr use babel plugin resolution:\n\n```javascript\n// babel.config.js\nmodule.exports = function (api) {\n    return {\n        presets: [\"babel-preset-expo\"],\n        plugins: [\n            [\n                \"module-resolver\",\n                {\n                    alias: {\n                        \"better-auth/react\":\n                            \"./node_modules/better-auth/dist/client/react/index.mjs\",\n                        \"better-auth/client/plugins\":\n                            \"./node_modules/better-auth/dist/client/plugins/index.mjs\",\n                        \"@better-auth/expo/client\":\n                            \"./node_modules/@better-auth/expo/dist/client.mjs\",\n                    },\n                },\n            ],\n        ],\n    };\n};\n```\n\n### 3. Environment Variables\n\n```env\n# Optional: Set Better-Auth server URL\nEXPO_PUBLIC_BETTER_AUTH_URL=http://localhost:4000\n\n# Or use Archlast URL\nEXPO_PUBLIC_ARCHLAST_HTTP_URL=http://localhost:4000\n\n# Optional: Set deep link scheme (default: archlast)\nEXPO_PUBLIC_DEEP_LINK_SCHEME=archlast\n```\n\n## Usage\n\n### Basic Client\n\n```tsx\nimport { BaseClient } from \"@archlast/sdk-expo\";\n\nconst client = new BaseClient({\n    baseUrl: \"http://localhost:4000\",\n});\n\n// Query\nconst tasks = await client.query(\"listTasks\", { limit: 10 });\n\n// Mutate\nconst task = await client.mutate(\"createTask\", {\n    text: \"New task\",\n});\n```\n\n### Authentication\n\n```tsx\n\"use client\";\nimport { authClient } from \"@archlast/sdk-expo/auth\";\nimport { useAuth } from \"@archlast/sdk-expo/react\";\n\nexport default function LoginScreen() {\n    const { signIn, session, isLoading } = useAuth();\n\n    const handleLogin = async () => {\n        await authClient.signIn.email({\n            email: \"user@example.com\",\n            password: \"password\",\n        });\n    };\n\n    if (isLoading) return <ActivityIndicator />;\n\n    if (session) {\n        return <Text>Welcome {session.user.name}</Text>;\n    }\n\n    return <Button title=\"Sign In\" onPress={handleLogin} />;\n}\n```\n\n### Deep Link Handling\n\nFor OAuth providers, handle the deep link callback:\n\n```app.json\n{\n  \"expo\": {\n    \"scheme\": \"archlast\"\n  }\n}\n```\n\n```tsx\nimport * as React from \"react\";\nimport { useEffect } from \"react\";\nimport { parseOAuthCallback, getInitialURL, addDeepLinkListener } from \"@archlast/sdk-expo/linking\";\n\nexport default function App() {\n    useEffect(() => {\n        // Handle initial URL (app opened from OAuth redirect)\n        getInitialURL().then((url) => {\n            if (url) {\n                const callback = parseOAuthCallback(url);\n                // Exchange code for session...\n            }\n        });\n\n        // Listen for deep links while app is running\n        const subscription = addDeepLinkListener(({ url }) => {\n            const callback = parseOAuthCallback(url);\n            // Handle callback...\n        });\n\n        return () => subscription.remove();\n    }, []);\n\n    return <YourRootComponent />;\n}\n```\n\n### Social Sign-In\n\n```tsx\nimport { authClient } from \"@archlast/sdk-expo/auth\";\n\nexport default function SocialLogin() {\n    const handleGoogleLogin = async () => {\n        await authClient.signIn.social({\n            provider: \"google\",\n            callbackURL: \"/dashboard\", // Becomes archlast://dashboard\n        });\n    };\n\n    return <Button title=\"Login with Google\" onPress={handleGoogleLogin} />;\n}\n```\n\n### Protected Routes\n\n```tsx\nimport { useAuth } from \"@archlast/sdk-expo/react\";\n\nexport default function ProtectedScreen() {\n    const { session, isLoading } = useAuth();\n\n    if (isLoading) return <ActivityIndicator />;\n\n    if (!session) {\n        return <LoginPage />;\n    }\n\n    return <DashboardScreen />;\n}\n```\n\n## API\n\n### Client Creation\n\n```ts\nimport { BaseClient } from \"@archlast/sdk-expo\";\n\nconst client = new BaseClient({\n  baseUrl: string;        // Archlast server URL\n  appId?: string;         // Optional app ID for isolation\n  apiKey?: string;        // Better-Auth API key\n});\n```\n\n### Auth\n\n- `authClient` - Default Better-Auth client\n- `useSession()` - Hook for session state\n- `createAuthClient(options)` - Create custom client\n\n### Storage\n\n- `secureStoreAdapter` - SecureStore adapter for Better-Auth\n- `initializeSecureStoreAdapter()` - Initialize the SecureStore adapter\n\n### Linking\n\n- `parseOAuthCallback(url)` - Parse OAuth deep link\n- `getInitialURL()` - Get app's opening URL\n- `addDeepLinkListener(callback)` - Listen for deep links\n- `openOAuthURL(url)` - Open OAuth provider in browser\n\n## Session Persistence\n\nSessions are automatically persisted in SecureStore with these settings:\n\n- **Storage**: `expo-secure-store` (encrypted on most devices)\n- **Prefix**: `better-auth.session_token`\n- **Sync**: Automatic with Better-Auth server\n\n## Web Support\n\nThe SDK works on Expo Web (in development) using:\n\n- Cookies instead of SecureStore\n- Standard browser navigation\n- Same API as native\n\n## Troubleshooting\n\n### Metro Bundler Issues\n\nIf you see import errors, add to `babel.config.js`:\n\n```js\nplugins: [\n    [\n        \"module-resolver\",\n        {\n            alias: {\n                \"better-auth/react\": \"./node_modules/better-auth/dist/client/react/index.mjs\",\n                \"@better-auth/expo/client\": \"./node_modules/@better-auth/expo/dist/client.mjs\",\n            },\n        },\n    ],\n];\n```\n\n### Deep Links Not Working\n\n1. Check `app.json` has the correct scheme\n2. Ensure `EXPO_PUBLIC_DEEP_LINK_SCHEME` matches\n3. Test with: `npx expo url --scheme archlast`\n\n### Clear Cache\n\n```bash\nnpx expo start --clear\n```\n\n## License\n\nMIT\n","readmeFilename":"README.md","_rev":"1-dad77aa52dca143dc0ec091593561486"}