npm.io
0.3.2 • Published 3d ago

@timeback/clr

Licence
Version
0.3.2
Deps
2
Size
197 kB
Vulns
0
Weekly
0

@timeback/clr

TypeScript client for the IMS CLR v2.0 API — Comprehensive Learner Record for verifiable credentials.

Installation

bun add @timeback/clr

Quick Start

import { ClrClient } from '@timeback/clr'

const client = new ClrClient({
	env: 'staging', // or 'production'
	auth: {
		clientId: 'your-client-id',
		clientSecret: 'your-client-secret',
	},
})

// Upsert a CLR credential (creates or updates, returns signed credential)
const signed = await client.credentials.upsert(clrCredential)

// Get API discovery information
const discovery = await client.discovery.get()

API Design

Standalone vs Composed
// Composed
import { TimebackClient } from '@timeback/core'

// Standalone
const clr = new ClrClient({ env: 'staging', auth })

const client = new TimebackClient({ env: 'staging', auth })
client.clr.credentials.upsert(clrCredential)
Client Structure
const client = new ClrClient(options)

client.credentials // CLR verifiable credentials (upsert)
client.discovery // API discovery (OpenAPI spec)
Credentials

Upsert verifiable CLR credentials. The platform acts as the publisher, digitally signing credentials to ensure authenticity and integrity:

const signed = await client.credentials.upsert({
	'@context': [
		'https://www.w3.org/ns/credentials/v2',
		'https://purl.imsglobal.org/spec/clr/v2p0/context-2.0.1',
	],
	id: 'urn:uuid:example-clr-id',
	type: ['VerifiableCredential', 'ClrCredential'],
	issuer: {
		id: 'https://example.edu',
		type: ['Profile'],
		name: 'Example University',
	},
	name: 'Student Transcript',
	validFrom: '2024-01-01T00:00:00Z',
	credentialSubject: {
		type: ['ClrSubject'],
		verifiableCredential: [
			{
				'@context': [
					'https://www.w3.org/ns/credentials/v2',
					'https://purl.imsglobal.org/spec/clr/v2p0/context-2.0.1',
				],
				id: 'urn:uuid:nested-credential-id',
				type: ['VerifiableCredential', 'AchievementCredential'],
				issuer: {
					id: 'https://example.edu',
					type: ['Profile'],
					name: 'Example University',
				},
				name: 'Course Completion',
				validFrom: '2024-01-15T00:00:00Z',
				credentialSubject: {
					type: ['AchievementSubject'],
					achievement: {
						id: 'urn:uuid:achievement-id',
						type: ['Achievement'],
						name: 'Algebra 101',
						criteria: { narrative: 'Completed all coursework' },
						achievementType: 'Course',
					},
				},
			},
		],
	},
})

// The returned credential includes a cryptographic proof added by the platform
console.log(signed.proof) // { type: 'DataIntegrityProof', ... }
Discovery

Retrieve the CLR v2.0 OpenAPI specification describing available endpoints, OAuth2 flows, and supported scopes:

const discovery = await client.discovery.get()
console.log(discovery) // OpenAPI 3.0 spec object
Authentication

The client handles OAuth2 token management automatically:

// Environment mode (recommended for Timeback APIs)
const client = new ClrClient({
	env: 'staging', // or 'production'
	auth: {
		clientId: 'xxx',
		clientSecret: 'xxx',
	},
})

// Explicit mode (custom API)
const client = new ClrClient({
	baseUrl: 'https://clr.example.com',
	auth: {
		clientId: 'xxx',
		clientSecret: 'xxx',
		authUrl: 'https://auth.example.com/oauth2/token',
	},
})

Tokens are cached and refreshed automatically before expiry.

Error Handling
import { ClrError, NotFoundError } from '@timeback/clr/errors'

try {
	await client.credentials.upsert(invalidCredential)
} catch (error) {
	if (error instanceof ClrError) {
		console.log(error.status) // HTTP status
		console.log(error.message) // Error message
	}
}

Configuration

new ClrClient({
	// Environment mode (Timeback APIs)
	env: 'staging' | 'production',
	auth: {
		clientId: string,
		clientSecret: string,
	},

	// OR Explicit mode (custom API)
	baseUrl: string,
	auth: {
		clientId: string,
		clientSecret: string,
		authUrl: string,
	},

	// OR Provider mode (shared auth across clients)
	provider: TimebackProvider,

	// Optional
	timeout?: number, // Request timeout in ms (default: 30000)
})

Environment variables fallback:

  • TIMEBACK_API_CLIENT_ID / TIMEBACK_CLIENT_ID / CLR_CLIENT_ID
  • TIMEBACK_API_CLIENT_SECRET / TIMEBACK_CLIENT_SECRET / CLR_CLIENT_SECRET
  • TIMEBACK_API_BASE_URL / TIMEBACK_BASE_URL / CLR_BASE_URL
  • TIMEBACK_API_AUTH_URL / TIMEBACK_AUTH_URL / CLR_TOKEN_URL

Debug Mode

Enable debug logging by setting DEBUG=1 or DEBUG=true:

DEBUG=1 bun run my-script.ts

This outputs detailed logs for HTTP requests and authentication:

[2025-02-13T10:30:00.000Z] DEBUG [clr:auth] Fetching new access token...
[2025-02-13T10:30:00.500Z] DEBUG [clr:auth] Token acquired (500ms, expires in 3600s)
[2025-02-13T10:30:00.501Z] DEBUG [clr:http] → POST https://api.example.com/ims/clr/v2p0/credentials/
[2025-02-13T10:30:00.800Z] DEBUG [clr:http] ← 200 OK (299ms)