Shared public contracts for Ankhorage packages and standalone provider packages.
- Strongly typed app structures
- Serializable schemas for app manifests and UI definitions
- Provider-neutral runtime contracts for auth and database adapters
- Clear contracts between systems without depending on framework internals
- Serializable app, action, theme, infra, and auth config contracts
- UI and navigation definitions
- Auth adapter contracts using signIn, signUp, and signOut naming
- Database adapter contracts for provider-neutral CRUD-style access
- Dedicated subpath exports for focused imports
import type { AppManifest } from '@ankhorage/contracts';
import type { AuthAdapter } from '@ankhorage/contracts/auth';
import type { DbAdapter } from '@ankhorage/contracts/db';
import type { StorageAdapter } from '@ankhorage/contracts/storage';Contracts keeps theme configuration serializable. Color validation, harmony,
swatch generation, contrast helpers, and semantic color references live in
@ankhorage/color-theory.
import type { ThemeConfig } from '@ankhorage/contracts';
const theme: ThemeConfig = {
id: 'theme-default',
name: 'Default',
light: { primaryColor: '#3366ff', harmony: 'analogous' },
dark: { primaryColor: '#3366ff', harmony: 'analogous' },
};Provider packages can implement the shared contracts without importing runtime, CLI, ZORA, Expo Router, color generation, or app-generation logic.
import type { AuthAdapter } from '@ankhorage/contracts/auth';
export function createSupabaseAuthAdapter(): AuthAdapter {
return {
async signIn(input) {
return {
ok: true,
data: {
accessToken: `token:${input.identifier.value}`,
user: { id: 'user-1', email: input.identifier.value },
},
};
},
async signUp(input) {
return { ok: true, data: { id: 'user-1', email: input.identifier.value } };
},
async signOut() {
return { ok: true };
},
async getSession() {
return { ok: true, data: null };
},
};
}Auth providers own identity records. App-facing profile data should be modeled separately, usually in an app table such as profiles.
const auth = {
scope: 'global',
provider: 'supabase',
authorization: { kind: 'RBAC', engine: 'native' },
profile: {
fields: ['email', 'displayName', 'avatarUrl'],
table: 'profiles',
primaryKey: 'authUserId',
createStrategy: 'trigger',
updateStrategy: 'api',
},
};Generated infra can use this metadata to create and maintain app profile rows while leaving identity lifecycle changes to the auth provider.
Contracts separates shared data and runtime contracts from implementation details. Standalone packages such as Supabase, Clerk, database providers, or UI/color packages can depend on these contracts while staying independent from Ankhorage app generation, runtime, CLI, and UI packages.