@akin-travel/sdk-core
v0.2.0
Published
Framework-agnostic TypeScript core for the Akin partner SDK — auth, token lifecycle, GraphQL operations, and loyalty domain. No UI framework, no DOM assumptions. Every binding (web/React, React Native, embed) wraps this.
Maintainers
Readme
@akin-travel/sdk-core
Framework-agnostic TypeScript core for the Akin partner SDK.
This is Phase 1, the foundation of the multi-platform Partner SDK (epic akin-travel/issues#2042). It contains the auth, token-lifecycle, GraphQL-operation, and loyalty-domain logic that every binding wraps — once, tested, in one place — so the web/React, React Native, and embeddable-widget bindings don't each re-implement it.
No React. No DOM. The package compiles with a
lib: ["ES2022"]tsconfig — any accidental use ofwindow,document,localStorage, a WebAuthn browser global, or a React import fails the build. Network globals Apollo needs (fetch,Response,AbortController) come from@types/node, which exist in every runtime core targets.
What's in it
| Area | Exports |
|---|---|
| Config | resolveConfig, ENVIRONMENT_URLS, AkinSDKConfig, ResolvedAkinSDKConfig, FirebaseConfig |
| Adapters | StorageAdapter, MemoryStorageAdapter, Authenticator, FirebaseAuthClient (interfaces — implementations live in bindings) |
| Auth | TokenManager (token cache/refresh/clear lifecycle), UserSwitchTracker (a sign-in as a different user), mapAuthError → stable AkinAuthErrorCode |
| GraphQL | createAkinClient (React-free Apollo client), typed partner-facing operations (LOGIN_MEMBER_GIP, REQUEST_MAGIC_LINK, VERIFY_AUTH_TOKEN, PASSKEY_*, UPDATE_MEMBER, …) |
| Loyalty domain | TierConfig, LoyaltyTransaction, MemberTierHistory, … + TIER_LABELS, getLabel, extractRequirementKeys, parseLocalDate |
The adapter model
Three concerns vary per platform (per the spike RFC, #2043 §3); core defines them as interfaces and a binding injects an implementation:
StorageAdapter— where tokens persist. WeblocalStorage, React NativeAsyncStorage, native keychain. Core shipsMemoryStorageAdapter(non-persistent) as the default and for tests.Authenticator— the passkey ceremony.@simplewebauthn/browseron web,ASAuthorizationon iOS, Credential Manager on Android.FirebaseAuthClient— the identity provider.firebase/auth(web) and@react-native-firebase/auth(RN) are different packages with differentsignInWithCustomToken/getIdTokensurfaces, so core abstracts the Firebase auth client itself rather than assuming the web SDK (the subtle point the RFC flags for this issue).
Core orchestrates the flows (token caching, the passkey server round-trips, error normalisation) against these interfaces — it never imports Firebase or WebAuthn directly.
Usage sketch
import {
createAkinClient,
TokenManager,
UserSwitchTracker,
resolveConfig,
type AkinSDKConfig,
} from '@akin-travel/sdk-core';
const config: AkinSDKConfig = {
partnerId: 'b8a131b2-…',
apiKey: 'pk_…',
environment: 'production',
};
// A binding installs a token provider once its authenticator is ready.
const tokens = new TokenManager();
tokens.setProvider(async () => myAuthenticator.getIdToken());
// On every auth-state change: a new user id drops the cached token, so a
// direct switch from user A to user B never sends A's token.
const client = createAkinClient(config, { tokenManager: tokens });
// The Apollo store is not keyed on the user either: clear it on a switch to a
// different user, before that user's member sync starts.
const userSwitch = new UserSwitchTracker();
firebaseAuthClient.onAuthStateChanged(async (user) => {
tokens.setIdentity(user?.id ?? null);
if (userSwitch.observe(user?.id ?? null)) await client.clearStore();
});Conformance
@akin-travel/sdk-core/conformance is a framework-agnostic kit of behavioural
contracts (storage adapter, auth error mapping, token lifecycle) that every
binding — web/React, React Native, embed — runs against its own implementations.
It is the cross-platform parity guardrail: a core change that breaks parity fails
the bindings' conformance tests. See
docs/SDK_CONFORMANCE.md for the supported-platforms
- parity-status matrix and the per-binding wiring.
Status
Foundation only. The web/React binding is re-based onto this core in akin-travel/issues#2046; the npm publish pipeline is akin-travel/issues#2045.
