← Back to Library

@wip/client

lib ·  app devs
typescriptclient-librarysdk

@wip/client

What it is. @wip/client is the TypeScript client library for WIP (World In a Pie) services. It is framework-agnostic, has zero runtime dependencies, and talks to WIP over native fetch — it runs in Node.js 18+ and any modern browser. An app dev calls createWipClient() once to get a WipClient, then reaches every store through one property each: client.defStore, client.templates, client.documents, client.files, client.registry, client.reporting. Each property is a thin typed wrapper — one method per REST endpoint — over that store's HTTP API, sharing a single FetchTransport (one baseUrl, one auth provider, one retry/timeout policy) underneath. The library encodes WIP's cross-cutting conventions once so callers don't have to: bulk-first writes, identity-hash-driven natural-upsert, per-item vs. bulk error handling, and namespace scoping under multi-namespace keys.

Install & import. The package is @wip/client, currently at version 0.32.0 (package.json). It is "private": true — not published to a registry — so a consumer depends on it as a local package, either a file: path reference or a packed tarball:

{
  "dependencies": {
    "@wip/client": "file:../../libs/wip-client"
  }
}

It ships a dual ESM/CJS build (tsup, target es2020) with bundled .d.ts: main/require resolves dist/index.cjs + dist/index.d.cts, module/import resolves dist/index.js + dist/index.d.ts. The primary import:

import { createWipClient } from '@wip/client'

Core API

createWipClient(config: WipClientConfig): WipClient

Auth providers — AuthProvider, ApiKeyAuthProvider, OidcAuthProvider

Error hierarchy — WipError and its subclasses

FetchTransport (advanced usage)

client.defStoreDefStoreService

client.templatesTemplateStoreService

client.documentsDocumentStoreService

client.filesFileStoreService

client.registryRegistryService

client.reportingReportingSyncService

templateToFormSchema(template: Template): FormField[]

bulkImport<T>(items: T[], writeFn: (batch: T[]) => Promise<BulkResponse>, options?: BulkImportOptions): Promise<BulkImportProgress>

resolveReference(client: WipClient, templateId: string, searchTerm: string, limit?: number): Promise<ResolvedReference[]>

buildQueryString(params: Record<string, unknown>): string


Usage patterns

1. Bootstrap a client and read.

import { createWipClient } from '@wip/client'

const client = createWipClient({
  baseUrl: '/wip', // browser behind a Vite proxy; use '' for direct Caddy, or an absolute URL in Node.js
  auth: { type: 'api-key', key: 'dev_master_key_for_testing' },
})

const terminologies = await client.defStore.listTerminologies({ status: 'active' })

2. Identity-preserving document upsert. Creating a document twice with the same identity_fields values versions the same document instead of duplicating it — this is the platform's identity-hash-driven natural-upsert, surfaced through the single-item convenience method:

// First call: creates version 1
await client.documents.createDocument({
  template_id: 'PATIENT_RECORD', namespace: 'wip',
  data: { email: 'jane@example.com', name: 'Jane' },
})

// Second call, same identity field (email): creates version 2 of the SAME document
await client.documents.createDocument({
  template_id: 'PATIENT_RECORD', namespace: 'wip',
  data: { email: 'jane@example.com', name: 'Jane Doe' },
})

3. Batch-import with progress, via bulkImport. bulkImport chunks a large array and calls a bulk write method per chunk — the pattern the library's own tests exercise:

import { bulkImport } from '@wip/client'

const result = await bulkImport(
  tenThousandTerms,
  (batch) => client.defStore.createTerms('ICD10', batch, { namespace: 'wip' }),
  { batchSize: 500, concurrency: 1, continueOnError: true,
    onProgress: ({ processed, total, failed }) => console.log(`${processed}/${total} (${failed} errors)`) },
)
// result: { processed, total, succeeded, failed }

4. Dry-run then apply a template-version migration. A validated, identity-preserving bulk re-pin of every active document from one template version to another (the two versions must declare the same identity_fields):

const preview = await client.documents.migrateDocuments({
  template_id: 'PATIENT_RECORD', from_version: 1, to_version: 2, // dry_run defaults true
})

if (preview.failed === 0) {
  await client.documents.migrateDocuments({
    template_id: 'PATIENT_RECORD', from_version: 1, to_version: 2, dry_run: false,
  })
}

Gotchas


See also

Generated from real source code, not hand-written — see the WIP Technical Library.