Skip to content

quckapp/api-client

Repository files navigation

@quckapp/api-client

Type-safe TypeScript client for the QuckApp API, auto-generated from our OpenAPI specification.

Installation

npm install @quckapp/api-client
# or
yarn add @quckapp/api-client
# or
pnpm add @quckapp/api-client

Quick Start

import { createClient } from '@quckapp/api-client';

const client = createClient({
  baseUrl: 'https://api.quckapp.io/v1',
  token: 'your-jwt-token',
});

// Login
const { data, error } = await client.auth.login({
  email: '[email protected]',
  password: 'password',
});

if (error) {
  console.error('Login failed:', error.message);
} else {
  console.log('Logged in:', data.user);
}

Configuration

import { createClient } from '@quckapp/api-client';

const client = createClient({
  // Required: API base URL
  baseUrl: 'https://api.quckapp.io/v1',

  // Optional: JWT token for authenticated requests
  token: 'your-jwt-token',

  // Optional: Custom fetch implementation
  fetch: customFetch,

  // Optional: Callback when token refresh is needed
  onTokenRefresh: async (refreshToken) => {
    // Return new tokens or null if refresh failed
    return { accessToken: 'new-token', refreshToken: 'new-refresh' };
  },

  // Optional: Callback when authentication fails
  onAuthError: (error) => {
    // Handle auth errors (e.g., redirect to login)
    console.error('Auth error:', error);
  },
});

API Namespaces

The client is organized into logical namespaces:

Authentication (client.auth)

// Login with email/password
const { data } = await client.auth.login({
  email: '[email protected]',
  password: 'password',
});

// Register new user
await client.auth.register({
  email: '[email protected]',
  password: 'password',
  displayName: 'John Doe',
});

// Refresh tokens
await client.auth.refreshToken({ refreshToken: 'token' });

// Logout
await client.auth.logout();

// Request password reset
await client.auth.requestPasswordReset({ email: '[email protected]' });

// OAuth login
await client.auth.oauthLogin({ provider: 'google', code: 'oauth-code' });

// MFA
await client.auth.setupMfa();
await client.auth.verifyMfa({ code: '123456' });
await client.auth.disableMfa({ code: '123456' });

Users (client.users)

// Get current user
const { data: me } = await client.users.me();

// Update current user
await client.users.updateMe({ displayName: 'New Name' });

// Get user by ID
const { data: user } = await client.users.get('user-id');

// Update user preferences
await client.users.updatePreferences({ theme: 'dark' });

// List users (admin)
const { data: users } = await client.users.list({ limit: 20 });

Workspaces (client.workspaces)

// List workspaces
const { data: workspaces } = await client.workspaces.list();

// Create workspace
const { data: workspace } = await client.workspaces.create({
  name: 'My Workspace',
  description: 'A new workspace',
});

// Get workspace
const { data } = await client.workspaces.get('workspace-id');

// Update workspace
await client.workspaces.update('workspace-id', { name: 'Updated Name' });

// Delete workspace
await client.workspaces.delete('workspace-id');

// Members
await client.workspaces.getMembers('workspace-id');
await client.workspaces.inviteMembers('workspace-id', {
  emails: ['[email protected]'],
  role: 'member',
});
await client.workspaces.removeMember('workspace-id', 'user-id');
await client.workspaces.updateMemberRole('workspace-id', 'user-id', 'admin');

Channels (client.channels)

// List channels
const { data: channels } = await client.channels.list('workspace-id');

// Create channel
const { data: channel } = await client.channels.create('workspace-id', {
  name: 'general',
  description: 'General discussion',
  isPrivate: false,
});

// Get channel
const { data } = await client.channels.get('channel-id');

// Update channel
await client.channels.update('channel-id', { description: 'Updated' });

// Delete channel
await client.channels.delete('channel-id');

// Members
await client.channels.getMembers('channel-id');
await client.channels.addMembers('channel-id', { userIds: ['user-id'] });
await client.channels.removeMember('channel-id', 'user-id');

// Join/Leave
await client.channels.join('channel-id');
await client.channels.leave('channel-id');

Messages (client.messages)

// List messages
const { data: messages } = await client.messages.list('channel-id', {
  limit: 50,
  before: 'message-id',
});

// Send message
const { data: message } = await client.messages.send('channel-id', {
  content: 'Hello, world!',
});

// Update message
await client.messages.update('message-id', { content: 'Updated content' });

// Delete message
await client.messages.delete('message-id');

// Reactions
await client.messages.addReaction('message-id', { emoji: 'πŸ‘' });
await client.messages.removeReaction('message-id', 'πŸ‘');

// Pin/Unpin
await client.messages.pin('message-id');
await client.messages.unpin('message-id');

Search (client.search)

// Full search
const { data: results } = await client.search.search({
  query: 'search term',
  filters: {
    type: ['message', 'file'],
    channelIds: ['channel-id'],
    from: '2024-01-01',
    to: '2024-12-31',
  },
  limit: 20,
});

// Quick search
const { data: quick } = await client.search.quick('search term');

// Saved searches
await client.search.getSavedSearches();
await client.search.createSavedSearch({ name: 'My Search', query: 'term' });
await client.search.deleteSavedSearch('search-id');

// Search history
await client.search.getHistory();
await client.search.clearHistory();

Notifications (client.notifications)

// List notifications
const { data: notifications } = await client.notifications.list({
  unreadOnly: true,
});

// Get notification
const { data } = await client.notifications.get('notification-id');

// Mark as read
await client.notifications.markAsRead(['notification-id']);

// Mark all as read
await client.notifications.markAllAsRead();

// Delete notification
await client.notifications.delete('notification-id');

// Settings
await client.notifications.getSettings();
await client.notifications.updateSettings({ desktop: { enabled: true } });

// Push subscriptions
await client.notifications.subscribePush({ endpoint: '...', keys: {} });
await client.notifications.unsubscribePush('subscription-id');

Presence (client.presence)

// Get user presence
const { data: presence } = await client.presence.get('user-id');

// Get bulk presence
const { data } = await client.presence.getBulk(['user-id-1', 'user-id-2']);

// Update presence
await client.presence.update({ status: 'online', statusText: 'Working' });

// Set typing indicator
await client.presence.setTyping('channel-id', true);

// Get channel presence
const { data: channelPresence } = await client.presence.getChannelPresence('channel-id');

Error Handling

import { createClient, QuckAppError, isQuckAppError } from '@quckapp/api-client';

const client = createClient({ baseUrl: '...' });

try {
  const { data, error } = await client.users.get('invalid-id');

  if (error) {
    // error is a QuckAppError instance
    console.log(error.code);      // 'NOT_FOUND'
    console.log(error.status);    // 404
    console.log(error.message);   // 'User not found'
    console.log(error.requestId); // For support tickets

    // Check error types
    if (error.isNotFound()) {
      // Handle not found
    } else if (error.isUnauthorized()) {
      // Handle unauthorized
    } else if (error.isValidationError()) {
      // Get field-specific errors
      const emailErrors = error.getFieldErrors('email');
      const allErrors = error.getFieldErrorsMap();
    }
  }
} catch (e) {
  if (isQuckAppError(e)) {
    // Handle API error
  } else {
    // Handle network or other error
  }
}

Types

All API types are exported and can be used for type annotations:

import type {
  User,
  Workspace,
  Channel,
  Message,
  Notification,
  LoginRequest,
  LoginResponse,
} from '@quckapp/api-client';

function handleUser(user: User) {
  console.log(user.displayName);
}

const loginData: LoginRequest = {
  email: '[email protected]',
  password: 'password',
};

Development

Generate Types from OpenAPI

# Generate TypeScript types from OpenAPI spec
npm run generate

# Build the package
npm run build

# Run type checking
npm run typecheck

# Lint
npm run lint

Project Structure

packages/api-client/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ generated/
β”‚   β”‚   └── schema.ts      # Auto-generated from OpenAPI
β”‚   β”œβ”€β”€ client.ts          # Main client implementation
β”‚   β”œβ”€β”€ error.ts           # Error handling
β”‚   β”œβ”€β”€ types.ts           # Type re-exports
β”‚   └── index.ts           # Public API
β”œβ”€β”€ package.json
β”œβ”€β”€ tsconfig.json
└── tsup.config.ts

License

MIT

About

QuickApp API Client - Shared TypeScript/JavaScript SDK for API interactions

Topics

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •