# @arco/clarizen-lib

TypeScript client for the [Planview Adaptive Work REST API V2.0](https://api.clarizen.com/V2.0/services/).

Human-readable guide: [REST API Guide Version 2](https://success.planview.com/Planview_AdaptiveWork/API/REST_API_Guide_Version_2) — see also [docs/references/planview-rest-api-v2.md](docs/references/planview-rest-api-v2.md).

## Install (library)

```bash
cd clarizen-lib
npm install
npm run build
```

## Use from another package in this repo

From the ARCO root (npm workspaces):

```bash
cd /path/to/ARCO
npm install
```

In your app `package.json`:

```json
{
  "dependencies": {
    "@arco/clarizen-lib": "workspace:*"
  }
}
```

Without workspaces (sibling folder):

```json
{
  "dependencies": {
    "@arco/clarizen-lib": "file:../clarizen-lib"
  }
}
```

Then build the library once (`npm run build` inside `clarizen-lib`) and import:

```typescript
import { Clarizen } from "@arco/clarizen-lib";
```

## Usage

### API key (recommended)

```typescript
import { Clarizen } from "@arco/clarizen-lib";

const clarizen = new Clarizen("https://api.clarizen.com", process.env.CLARIZEN_API_KEY);

const users = await clarizen.data.entityQuery({
  typeName: "User",
  fields: ["Name", "Email"],
  paging: { limit: 10, from: 0 },
});
```

Or with options:

```typescript
const clarizen = new Clarizen({
  baseUrl: "https://api.clarizen.com",
  apiToken: process.env.CLARIZEN_API_KEY,
});
```

### Session (username + password)

```typescript
const clarizen = Clarizen.createForLogin("https://api.clarizen.com");

const { sessionId } = await clarizen.loginWithDiscovery({
  userName: "user@company.com",
  password: "secret",
});
```

### Entity CRUD

```typescript
const { id } = await clarizen.objects.create("Issue", { title: "Issue 1" });
const issue = await clarizen.objects.get("Issue", id, {
  fields: ["CreatedOn", "CreatedBy.Name"],
});
```

Or construct directly with an existing session:

```typescript
const clarizen = new Clarizen({
  baseUrl: "https://api.clarizen.com",
  sessionId: "abc123_28849473",
});
```

## Services

All documented operations are exposed under namespaces:

| Namespace | Example |
|-----------|---------|
| `authentication` | `clarizen.authentication.login({ userName, password })` |
| `data` | `clarizen.data.entityQuery({ typeName, fields })` |
| `objects` | `clarizen.objects.get("Issue", id, { fields: [...] })` |
| `metadata` | `clarizen.metadata.fetchCatalog()` |
| `files` | `clarizen.files.getUploadUrl()` |
| `bulk` | `clarizen.bulk.execute({ ... })` |
| `applications` | `clarizen.applications.getApplicationStatus()` |
| `utils` | `clarizen.utils.sendEMail({ ... })` |

Generic call:

```typescript
await clarizen.call("data", "EntityQuery", { typeName: "Project", fields: ["Name"] });
```

## Environment

Copy `.env.example` to `.env`:

```
CLARIZEN_BASE_URL=https://api.clarizen.com
CLARIZEN_API_KEY=...
CLARIZEN_USERNAME=...
CLARIZEN_PASSWORD=...
```

## Examples

```bash
npm run example:api-key
npm run example:session
```

## Regenerate endpoints from API docs

```bash
npm run scrape
```

## Regenerate API types (60 types, recursive crawl)

Crawls all operations and `/V2.0/services/types/*`, then generates `src/clarizen-api-types.ts`:

```bash
npm run scrape:types    # writes src/generated/clarizen-schema.json
npm run generate:types  # writes src/clarizen-api-types.ts
```

Includes `Condition`, `Expression`, `Query` (11 variants), `EntityQuery`, enums (`Operator`, `ErrorCode`, …), and nested types referenced from each page.

## Org metadata catalog (runtime + codegen)

Fetches your tenant’s entity types, fields, and relations via `listEntities` + `describeMetadata` (`flags: ["fields", "relations"]`). Custom names containing `C_` or `R_` are excluded.

**Runtime:**

```typescript
const catalog = await clarizen.metadata.fetchCatalog();
const project = catalog.entities.find((e) => e.typeName === "Project");
```

**Regenerate** (requires `.env` credentials):

```bash
npm run scrape:metadata   # writes src/generated/metadata-catalog.json + metadata-types.ts
npm run build
```

**Typed entity/field names** (after scrape):

```typescript
import type { EntityTypeName } from "@arco/clarizen-lib";
import { FIELDS_BY_ENTITY, entityFields } from "@arco/clarizen-lib/metadata";
```

Commit `metadata-types.ts` (and optionally `metadata-catalog.json`) when refreshing against your reference tenant.
