npm package: @kulkan/contracts
Description: Shared types, enums, and interfaces for kulflow projects
Latest version: 1.1.7

# @kulkan/contracts

Shared TypeScript types, enums, and error classes for Truffa projects. Published as a scoped npm package (`@kulkan/contracts`).

## Requirements

- Node.js **18.18+** (see `engines` in `package.json`)
- [pnpm](https://pnpm.io/) is used in this repo (npm/yarn work for consumers)

## Installation

```bash
pnpm add @kulkan/contracts
# or
npm install @kulkan/contracts
```

For a **scoped public** package, publishing typically uses:

```bash
pnpm publish --access public
```

Configure your registry in `.npmrc` if you use GitHub Packages or another host.

### From Git (alternative)

```bash
pnpm add git+https://github.com/your-org/contracts.git
pnpm add git+https://github.com/your-org/contracts.git#v1.0.0
```

## Usage

```typescript
import {
  AuthMethod,
  Errors,
  HealthCheck,
  HealthStatus,
  IConfig,
  IApiResponse,
  IPaginatedResponse,
  IServerInit,
  OAuthProvider,
  type AuthSessionResponse,
  type LoginRequest,
  type RegisterRequest,
  type TokenPair,
  type User,
  BaseError,
  BusinessError,
  ForbiddenError,
  NotFoundError,
  ServerError,
  UnauthorizedError,
} from '@kulkan/contracts';

// Example: typed health-check response body
const health: IApiResponse<HealthCheck> = {
  success: true,
  message: 'API is running',
  data: { message: 'API is running', status: HealthStatus.HEALTHY },
};
```

### Authentication and users

The package defines **shared contracts** for email/password and OAuth (Google via Auth0 on the server), **API-issued JWTs** (access) and **opaque refresh tokens** (server-side storage only—hashes are not part of the public types):

- **Enums:** `AuthMethod` (`password` | `oauth`), `OAuthProvider` (e.g. `GOOGLE`, extensible later).
- **Entities / DTOs:** `User`, `TokenPair`, `AuthUserResponse`, `AuthSessionResponse`, `RegisterRequest`, `LoginRequest`, `RefreshRequest`, `LogoutRequest`, OAuth Google start/callback types, `CreateUserInput`.
- **Repository ports (implementations live in services):** `IUserRepository`, `IRefreshTokenRepository`, `IOAuthStateRepository` — keep domain types free of MongoDB/Passport imports so SQL or other adapters can implement the same interfaces later.
- **Service ports** (`interfaces/services/`): `IAuthService`, `IJwtTokensService`, `IAuth0GoogleOAuthService` — implemented by the API’s concrete classes for DI, testing, and clear boundaries.
- **Auth0/OIDC helpers:** `Auth0UserProfile`, `Auth0AuthorizationParams`, `OAuthAccessTokenResult`.

`IConfig` includes optional fields for **RS256** JWT (`jwtIssuer`, `jwtAudience`, PEM keys, TTLs), **MongoDB**, **Auth0**, and **`oauthAllowedRedirectUris`** (comma-separated allowlist for OAuth redirect URIs).

Path aliases (`@/…`) apply only inside this package’s source; consumers import from `@kulkan/contracts` as above.

The published package is **dual CJS + ESM** (`exports.require` → `dist/index.js`, `exports.import` → `dist/index.mjs`).
That way **`import { BaseError, BusinessError } from '@kulkan/contracts'`** works in ESM projects (`"type": "module"`,
Vite, etc.), and **`require('@kulkan/contracts')`** still works in CommonJS. Use TypeScript
**`moduleResolution`: `"node16"`** or **`"nodenext"`** (or **`"bundler"`**) in consuming apps so types resolve through
`package.json` `exports`.

## Development

Install dependencies and (on first clone) install Git hooks:

```bash
pnpm install
```

| Script                  | Description                                                                                |
| ----------------------- | ------------------------------------------------------------------------------------------ |
| `pnpm run build`        | **tsup**: bundle `src/index.ts` → `dist/index.js` (CJS) + `dist/index.mjs` (ESM) + `.d.ts` |
| `pnpm run clean`        | Remove `dist/`                                                                             |
| `pnpm run typecheck`    | `tsc --noEmit` (no emit, full typecheck)                                                   |
| `pnpm run lint`         | ESLint with cache (`.eslintcache`)                                                         |
| `pnpm run lint:fix`     | ESLint with `--fix`                                                                        |
| `pnpm run format`       | Prettier write (respects `.prettierignore`)                                                |
| `pnpm run format:check` | Prettier check only                                                                        |
| `pnpm run validate`     | `typecheck` → `lint` → `format:check` (use in CI)                                          |

**Pre-commit:** [Husky](https://typicode.github.io/husky/) runs [lint-staged](https://github.com/lint-staged/lint-staged): ESLint + Prettier on staged `*.ts` / `*.tsx`, Prettier on staged `*.json` / `*.md`.

**Before publish:** `prepublishOnly` runs `validate` then `build`, so broken code should not ship.

### Tooling in this repo

- **tsup** — `tsup.config.ts`; dual CJS/ESM build for the npm entry
- **ESLint** — `eslint.config.mjs` (flat config), TypeScript type-aware rules via `typescript-eslint`, conflicts with Prettier disabled via `eslint-config-prettier`
- **Prettier** — `.prettierrc.json`, `.prettierignore`
- **Editor defaults** — `.editorconfig`

## Publishing

1. Bump the version in `package.json`.
2. Run `pnpm run validate` and fix any issues.
3. Publish: `pnpm publish` (or your registry-specific command).

`pnpm run build` runs automatically in `prepublishOnly` after `validate`.

## Package layout

Source lives under `src/`:

- `enums/` — shared enums (e.g. `Errors`, `HealthStatus`, `AuthMethod`, `OAuthProvider`)
- `errors/` — error classes (`BaseError`, domain errors, …)
- `interfaces/general/` — cross-cutting interfaces (`IConfig`, pagination, API responses, server bootstrap types, …)
- `interfaces/auth/` — repository ports (`IUserRepository`, `IRefreshTokenRepository`, `IOAuthStateRepository`)
- `interfaces/services/` — service ports (`IAuthService`, `IJwtTokensService`, `IAuth0GoogleOAuthService`)
- `types/` — shared type aliases (`HealthCheck`, auth DTOs under `types/auth/`, …)

The public API is whatever `src/index.ts` re-exports. Additional error classes may exist under `src/errors/` but only appear in consumers if listed in `index.ts`.

## Serverless / private registry notes

- **Private npm:** set `@kulkan:registry=…` and auth in `.npmrc` (or `NPM_TOKEN` in CI).
- **Git installs:** ensure deploy environments can reach the repo and run `pnpm install` / `npm install` as usual.

### AWS Lambda / Serverless Framework (example)

```yaml
package:
  patterns:
    - '!node_modules/**'
    - 'node_modules/@kulkan/contracts/**'
```

### Vercel

Dependencies resolve at build time; ensure registry or Git access is configured for private packages.

## License

See [LICENSE](./LICENSE) (MIT).