npm package: @lstrihic/codekey
Description: TypeScript client for code-key.com API
Author: Lovro Strihic
Latest version: 1.1.0

# @lstrihic/codekey

TypeScript client for the code-key.com door access control API.

## Installation

```bash
npm install @lstrihic/codekey
```

## Requirements

- Node.js 18+
- TypeScript 5+ (for TypeScript projects)

## Quick Start

```typescript
import { CodeKeyClient } from '@lstrihic/codekey'

const client = new CodeKeyClient(
  process.env.CODEKEY_USERNAME!,
  process.env.CODEKEY_PASSWORD!
)

// List all users
const users = await client.listUsersParsed('account-id')
console.log(users)

// Get single user
const user = await client.getUser('account-id', 'user-id')

// Add new guest
await client.addOrUpdateUser({
  id: 'account-id',
  userStatus: '0',
  userType: '1',
  name: 'Guest Name',
  device: '15666322',
  dateStart: '24.10.2025',
  timeStart: '05:50',
  dateEnd: '26.10.2025',
  timeEnd: '20:30',
  code: '123456',
  note: '',
  mailTrigger: 'false',
  otp: 'false',
  openAPILink: 'uuid',
  importID: '0',
})
```

## API Reference

### Constructor

```typescript
new CodeKeyClient(username: string, password: string)
```

Creates a new client instance with automatic authentication and session management.

### User Management Methods

#### listUsers(id: string): Promise\<Buffer\>

Get all users as raw CSV data.

**Parameters:**
- `id` - Account ID

**Returns:** Buffer containing CSV response

```typescript
const rawUsers = await client.listUsers('24E40CAB556911EFA812F2FABB7CF30C')
console.log(rawUsers.toString())
```

#### listUsersParsed(id: string): Promise\<User[]\>

Get all users as parsed objects.

**Parameters:**
- `id` - Account ID

**Returns:** Array of User objects

```typescript
const users = await client.listUsersParsed('24E40CAB556911EFA812F2FABB7CF30C')
for (const user of users) {
  console.log(`${user.name} - Code: ${user.code}`)
}
```

#### getUser(id: string, userID: string): Promise\<UserInfo\>

Get detailed info for a single user as a parsed JSON object.

**Parameters:**
- `id` - Account ID
- `userID` - User ID

**Returns:** UserInfo object

```typescript
const user = await client.getUser('24E40CAB556911EFA812F2FABB7CF30C', '2685015')
console.log(`${user.name}: ${user.dateStart} - ${user.dateEnd}`)
```

#### getUserRaw(id: string, userID: string): Promise\<Buffer\>

Get detailed info for a single user as raw JSON data.

**Parameters:**
- `id` - Account ID
- `userID` - User ID

**Returns:** Buffer containing JSON response

```typescript
const rawUser = await client.getUserRaw('24E40CAB556911EFA812F2FABB7CF30C', '2685015')
```

#### addOrUpdateUser(req: AddOrUpdateUserRequest): Promise\<Buffer\>

Create or update a temporary user with time restrictions.

**Creating a new user:** Set `importID: '0'` and omit `editing`
**Updating existing user:** Set `editing` to user ID and omit `importID`

**Parameters:**
- `req` - AddOrUpdateUserRequest object

**Returns:** Buffer containing response

```typescript
// Create new guest
await client.addOrUpdateUser({
  id: '24E40CAB556911EFA812F2FABB7CF30C',
  userStatus: '0',
  userType: '1',
  name: 'New Guest',
  device: '15666322',
  dateStart: '24.10.2025',
  timeStart: '05:50',
  dateEnd: '26.10.2025',
  timeEnd: '20:30',
  code: '543543',
  note: '',
  mailTrigger: 'false',
  otp: 'false',
  openAPILink: 'uuid',
  importID: '0',
})

// Update existing user
await client.addOrUpdateUser({
  id: '24E40CAB556911EFA812F2FABB7CF30C',
  userStatus: '0',
  userType: '1',
  name: 'Updated Name',
  device: '15666322',
  dateStart: '24.10.2025',
  timeStart: '05:50',
  dateEnd: '30.12.2025',
  timeEnd: '20:30',
  code: '246811',
  note: '',
  mailTrigger: 'false',
  otp: 'false',
  openAPILink: 'uuid',
  editing: '2685015',
})
```

### Private/Permanent User Methods

#### listPrivateUsers(id: string): Promise\<Buffer\>

Get permanent users as raw CSV data.

**Parameters:**
- `id` - Account ID

**Returns:** Buffer containing CSV response

```typescript
const rawPrivateUsers = await client.listPrivateUsers('24E40CAB556911EFA812F2FABB7CF30C')
```

#### listPrivateUsersParsed(id: string): Promise\<PrivateUser[]\>

Get permanent users (staff/cleaners) as parsed objects.

**Parameters:**
- `id` - Account ID

**Returns:** Array of PrivateUser objects

```typescript
const privateUsers = await client.listPrivateUsersParsed('24E40CAB556911EFA812F2FABB7CF30C')
for (const user of privateUsers) {
  console.log(`${user.name} - Code: ${user.code}`)
}
```

#### addPermanentUser(req: AddPermanentUserRequest): Promise\<Buffer\>

Add a permanent user (staff/cleaner) without time restrictions.

**Parameters:**
- `req` - AddPermanentUserRequest object

**Returns:** Buffer containing response

```typescript
await client.addPermanentUser({
  id: '24E40CAB556911EFA812F2FABB7CF30C',
  userStatus: '0',
  name: 'Staff Member',
  device: '15666322',
  code: '765433',
  openAPILink: 'uuid',
  cleanerFlag: '0', // Set to '1' for cleaners
  note: '',
})
```

### Access Control Methods

#### updateAccessPeriod(req: UpdateAccessPeriodRequest): Promise\<Buffer\>

Update access date range for a user.

**Parameters:**
- `req` - UpdateAccessPeriodRequest object

**Returns:** Buffer containing response

```typescript
await client.updateAccessPeriod({
  id: '24E40CAB556911EFA812F2FABB7CF30C',
  groupUserID: 'group-uuid',
  dateStart: '24.10.2025',
  dateEnd: '28.11.2025',
  userID: '2685015',
  actionID: '0',
})
```

#### updateAccessCode(req: UpdateAccessCodeRequest): Promise\<Buffer\>

Update door access code for a user.

**Parameters:**
- `req` - UpdateAccessCodeRequest object

**Returns:** Buffer containing response

```typescript
await client.updateAccessCode({
  id: '24E40CAB556911EFA812F2FABB7CF30C',
  groupUserID: 'group-uuid',
  newCode: '246810',
  userID: '2685015',
  actionID: '0',
  name: 'test1',
  currentCode: '246811',
  userType: '1',
})
```

## TypeScript Support

Full TypeScript support with type definitions included.

```typescript
import type {
  User,
  PrivateUser,
  UserInfo,
  AddOrUpdateUserRequest,
  AddPermanentUserRequest,
  UpdateAccessPeriodRequest,
  UpdateAccessCodeRequest,
} from '@lstrihic/codekey'
```

### Type Definitions

**User** - Temporary user with time restrictions
```typescript
interface User {
  userID: string
  status: string
  userType: string
  name: string
  device: string
  dateStart: string
  timeStart: string
  dateEnd: string
  timeEnd: string
  code: string
  userStatus: string
  deviceName: string
  createdAt: string
  lastAccess: string
  groupUserID: string
  openAPILink: string
}
```

**PrivateUser** - Permanent user (staff/cleaner)
```typescript
interface PrivateUser {
  deviceName: string
  userID: string
  status: string
  name: string
  device: string
  code: string
  lastAccess: string
  groupUserID: string
}
```

**UserInfo** - Detailed user information
```typescript
interface UserInfo {
  id: string
  groupUserID: string
  userID: string
  name: string
  code: string
  dateStart: string
  dateEnd: string
  userType: string
  actionID: string
  active: boolean
  createdAt?: Date
  updatedAt?: Date
}
```

## Error Handling

```typescript
import {
  AuthenticationError,
  RequestError,
  ParseError,
} from '@lstrihic/codekey'

try {
  await client.listUsers('account-id')
} catch (error) {
  if (error instanceof AuthenticationError) {
    console.error('Login failed')
  } else if (error instanceof RequestError) {
    console.error('API request failed:', error.statusCode)
  } else if (error instanceof ParseError) {
    console.error('Response parsing failed')
  }
}
```

**Error Types:**

- `AuthenticationError` - Login or authentication failed
- `RequestError` - API request failed (includes statusCode)
- `ParseError` - CSV/JSON parsing failed

## Features

- Automatic authentication and session management
- Cookie-based session handling with automatic re-authentication
- Promise-based async operations
- Full TypeScript support
- Clean error handling with custom error classes
- CSV parsing for list operations
- JSON parsing for detailed user info

## Usage in Next.js

```typescript
// app/api/users/route.ts
import { CodeKeyClient } from '@lstrihic/codekey'
import { NextResponse } from 'next/server'

export async function GET() {
  const client = new CodeKeyClient(
    process.env.CODEKEY_USERNAME!,
    process.env.CODEKEY_PASSWORD!
  )

  try {
    const users = await client.listUsersParsed(process.env.CODEKEY_ACCOUNT_ID!)
    return NextResponse.json(users)
  } catch (error) {
    return NextResponse.json({ error: 'Failed to fetch users' }, { status: 500 })
  }
}
```

## License

MIT

## Author

Lovro Strihic