|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +## Project Overview |
| 4 | + |
| 5 | +ArcXP SDK for TypeScript — a strongly typed wrapper around ArcXP REST APIs. ESM-only, published as `@code.store/arcxp-sdk-ts`. |
| 6 | + |
| 7 | +## Tech Stack |
| 8 | + |
| 9 | +- **Runtime:** Node.js >= 22 |
| 10 | +- **Package Manager:** pnpm >= 10 |
| 11 | +- **Language:** TypeScript (strict mode, ESM with `.js` extensions in imports) |
| 12 | +- **Build:** Rollup (outputs ESM + CJS) |
| 13 | +- **Linter/Formatter:** Biome (single quotes, trailing commas, semicolons, 120 line width, spaces) |
| 14 | +- **Tests:** Vitest + nock for HTTP mocking |
| 15 | +- **Changesets:** `@changesets/cli` for versioning |
| 16 | + |
| 17 | +## Commands |
| 18 | + |
| 19 | +| Task | Command | |
| 20 | +|------|---------| |
| 21 | +| Type-check | `tsc --noEmit` | |
| 22 | +| Build | `pnpm build` | |
| 23 | +| Test | `pnpm test` | |
| 24 | +| Lint + fix | `pnpm lint` | |
| 25 | +| Format | `pnpm format` | |
| 26 | +| Check (biome) | `pnpm check` | |
| 27 | + |
| 28 | +Always run `tsc --noEmit` after making changes to verify types. |
| 29 | + |
| 30 | +## Project Structure |
| 31 | + |
| 32 | +``` |
| 33 | +src/ |
| 34 | + api/ # API client implementations |
| 35 | + abstract-api.ts # Base class (ArcAbstractAPI) all API clients extend |
| 36 | + index.ts # ArcAPI factory — registers all API clients |
| 37 | + <api-name>/ |
| 38 | + index.ts # API class (extends ArcAbstractAPI) |
| 39 | + types.ts # Request params / response types for this API |
| 40 | + types/ # Global ANS types (AStory, AnImage, etc.) — auto-generated, do not edit manually |
| 41 | + tests/ # Test files (*.test.ts) |
| 42 | + utils/ # Shared utilities |
| 43 | +.changeset/ # Changeset files for versioning |
| 44 | +``` |
| 45 | + |
| 46 | +## Contributing API Endpoints |
| 47 | + |
| 48 | +### Workflow |
| 49 | + |
| 50 | +1. **Fetch the OpenAPI spec** for the target API using the `sdk-creator` skill (it has URLs for all ArcXP APIs). |
| 51 | +2. **Read existing code** in `src/api/<api-name>/` before changing anything. |
| 52 | +3. **Identify missing endpoints** by comparing the spec to the implementation. |
| 53 | +4. **Implement** following the patterns below, then type-check with `tsc --noEmit`. |
| 54 | +5. **Create a changeset** in `.changeset/` (see below). |
| 55 | + |
| 56 | +### API Implementation Pattern |
| 57 | + |
| 58 | +Each API client extends `ArcAbstractAPI` and is registered in `src/api/index.ts`. |
| 59 | + |
| 60 | +```ts |
| 61 | +// src/api/example/index.ts |
| 62 | +import { ArcAbstractAPI, type ArcAPIOptions } from '../abstract-api.js'; |
| 63 | +import type { GetThingParams, CreateThingPayload, Thing } from './types.js'; |
| 64 | + |
| 65 | +export class ArcExample extends ArcAbstractAPI { |
| 66 | + constructor(options: ArcAPIOptions) { |
| 67 | + super({ ...options, apiPath: 'example' }); |
| 68 | + } |
| 69 | + |
| 70 | + async getThing(params: GetThingParams): Promise<Thing> { |
| 71 | + const { data } = await this.client.get<Thing>('/v1/things', { params }); |
| 72 | + return data; |
| 73 | + } |
| 74 | + |
| 75 | + async createThing(payload: CreateThingPayload): Promise<Thing> { |
| 76 | + const { data } = await this.client.post<Thing>('/v1/things', payload); |
| 77 | + return data; |
| 78 | + } |
| 79 | +} |
| 80 | +``` |
| 81 | + |
| 82 | +### Type Conventions |
| 83 | + |
| 84 | +- **Params types** (query params): suffix with `Params` — e.g. `ListAuthorsParams`. Define in the API's local `types.ts`. |
| 85 | +- **Payload types** (POST body): suffix with `Payload` — e.g. `CreateAuthorPayload`. Define in the API's local `types.ts`. |
| 86 | +- **Response types**: check `src/types/` for existing global ANS types first. Only define locally if no global type exists. |
| 87 | +- **Do not duplicate types** that already exist globally. |
| 88 | + |
| 89 | +### Changeset |
| 90 | + |
| 91 | +After making changes, create a file in `.changeset/` named after the feature: |
| 92 | + |
| 93 | +```md |
| 94 | +--- |
| 95 | +"@arcxp/sdk-ts": minor |
| 96 | +--- |
| 97 | + |
| 98 | +Add getAuthor and createAuthor methods to Author API |
| 99 | +``` |
| 100 | + |
| 101 | +Use `patch` for fixes, `minor` for new endpoints/features, `major` for breaking changes. |
| 102 | + |
| 103 | +## Code Style Rules |
| 104 | + |
| 105 | +- ESM imports with `.js` extensions (e.g. `'../abstract-api.js'`) |
| 106 | +- Use `type` keyword for type-only imports |
| 107 | +- Single quotes, semicolons, trailing commas (es5), arrow parens always |
| 108 | +- Indent with spaces (2), max line width 120 |
| 109 | +- No unused variables or imports (enforced by biome) |
| 110 | +- Keep methods concise — destructure `{ data }` from axios response and return directly |
| 111 | +- Name methods clearly: `getX`, `listX`, `createX`, `updateX`, `deleteX` |
| 112 | + |
| 113 | +## Things to Avoid |
| 114 | + |
| 115 | +- Do not edit files in `src/types/` — these are auto-generated from ANS schemas |
| 116 | +- Do not overwrite existing endpoint implementations without being asked |
| 117 | +- Do not add dependencies without explicit approval |
| 118 | +- Do not use `any` unless truly unavoidable (biome allows it but prefer proper types) |
0 commit comments