/** * Base Resource * * Abstract base class for all OneRoster resources. * Provides common CRUD operations. */ import { Paginator } from '../lib'; import type { z } from 'zod/v4'; import type { ListParams, PageResult } from '@timeback/internal-client-infra'; import type { Base, CreateResponse, OneRosterTransportLike, ResourceType } from '../types'; /** * Abstract base class for all OneRoster resources. * * Provides common CRUD operations with automatic response unwrapping. * * @template T - The resource type (must extend Base) - used for responses * @template F - The filter fields type for type-safe where clauses * @template I - The input type for create/update (defaults to Partial) * @template P - The list params type (defaults to ListParams) * @template W - The write return type for `update()`/`upsert()` (defaults to `void`). * Subclasses whose API returns the updated entity (e.g. gradebook/assessment) * set `W` to the entity type and **must** override `update()` and `upsert()` * with concrete implementations — the base class returns `undefined as W` * which is only sound when `W = void`. */ export declare abstract class BaseResource, P extends ListParams = ListParams, W = void> { protected readonly transport: OneRosterTransportLike; /** Full path for this resource (pathPrefix + suffix) */ protected readonly basePath: string; /** * @param transport - Transport instance for making requests * @param resourceType - Type of resource (rostering or gradebook) * @param suffix - Resource suffix (e.g., '/users', '/lineItems') */ constructor(transport: OneRosterTransportLike, resourceType: ResourceType, suffix: string); /** * List the first page of resources (Caliper-style). * * This returns a single page plus metadata (`hasMore`, `total`, `nextOffset`). * Use `stream()` for lazy iteration or `listAll()` to fetch everything. * * @param params - Optional `where` clause, sorting, and pagination parameters * @returns Promise resolving to the first page of matching resources * * @example * ```typescript * const page = await client.users.list() * console.log(page.data.length, page.hasMore) * ``` */ list(params?: P): Promise>; /** * List all resources, fetching all pages automatically. * * @param params - Optional `where` clause, sorting, and pagination parameters * @returns Promise resolving to an array of all matching resources */ listAll(params?: P): Promise; /** * Get the first matching resource, or undefined if none match. * * @param params - Optional `where` clause parameters * @returns The first matching resource, or undefined * * @example * ```typescript * const user = await client.users.first({ where: { email } }) * if (!user) throw new Error('User not found') * ``` */ first(params?: P): Promise; /** * Stream resources with lazy pagination. * * Use this for large datasets where you want to process items * one at a time without loading everything into memory. * * @param params - Optional `where` clause, sorting, and pagination parameters * @returns Async iterable paginator for streaming results * @throws {InputValidationError} If params are invalid (e.g., negative limit) * * @example * ```typescript * for await (const user of client.users.stream()) { * console.log(user.name) * } * ``` */ stream(params?: P): Paginator; /** * Get a single resource by sourcedId. * * @param sourcedId - The unique identifier of the resource * @returns The requested resource * @throws {InputValidationError} If sourcedId is empty * @throws {NotFoundError} If the resource doesn't exist */ get(sourcedId: string): Promise; /** * Check whether a single resource exists by sourcedId. * * @param sourcedId - The unique identifier of the resource * @returns True if found, false for 404 * @throws {InputValidationError} If sourcedId is empty * @throws {ApiError} For non-404 failures */ exists(sourcedId: string): Promise; /** * Create a new resource. * * @param data - The resource data to create * @returns Response containing the created resource's sourcedId * @throws {InputValidationError} If the data fails client-side validation * @throws {ValidationError} If the server rejects the data */ create(data: I): Promise; /** * Update an existing resource (full replacement). * * Always throws NotFoundError if the resource doesn't exist, regardless * of whether the server's PUT handler natively upserts. * * @param sourcedId - The unique identifier of the resource to update * @param data - The fields to update * @returns Void on success * @throws {InputValidationError} If sourcedId is empty or data fails client-side validation * @throws {NotFoundError} If the resource doesn't exist * @throws {ValidationError} If the server rejects the data */ update(sourcedId: string, data: Partial): Promise; /** * Create or update a resource by sourcedId. * * If the resource exists it is updated; otherwise it is created. * Works consistently across all resources regardless of server-side * upsert support. * * @param sourcedId - The unique identifier of the resource * @param data - Resource data (sourcedId is provided separately) * @returns Void on success * @throws {InputValidationError} If sourcedId is empty or data fails validation * @throws {ApiError} For non-404 failures */ upsert(sourcedId: string, data: Omit): Promise; /** * Send a PUT request (no existence pre-check). * Shared by `update()` and `upsert()`. * * @param sourcedId - The unique identifier of the resource to update * @param data - The fields to update * @returns Void on success * @throws {InputValidationError} If data fails client-side validation * @throws {ValidationError} If the server rejects the data */ protected sendUpdate(sourcedId: string, data: Partial): Promise; /** * Send a PUT request and return the updated entity. * * @param sourcedId - The unique identifier of the resource to update * @param data - The fields to update * @returns The updated resource * @throws {InputValidationError} If data fails client-side validation * @throws {ValidationError} If the server rejects the data */ protected sendUpdateAndReturn(sourcedId: string, data: Partial): Promise; /** * Enforce strict update behavior for resources backed by native server upsert. * * @param sourcedId - The unique identifier of the resource to update * @throws {NotFoundError} If the resource doesn't exist */ protected ensureExistsForUpdate(sourcedId: string): Promise; /** * Delete a resource. * * @param sourcedId - The unique identifier of the resource to delete * @throws {InputValidationError} If sourcedId is empty * @throws {NotFoundError} If the resource doesn't exist */ delete(sourcedId: string): Promise; /** * The key used to unwrap list responses (e.g., "users", "classes"). * Override in subclasses. */ protected abstract get unwrapKey(): string; /** * The key used to wrap request bodies (e.g., "user", "class"). * Override in subclasses. */ protected abstract get wrapKey(): string; /** * Transform a response entity before returning it. * * Override in subclasses to normalize API responses (e.g., convert grades from strings to numbers). * Default implementation returns the entity unchanged. * * @param entity - The raw entity from the API * @returns The transformed entity */ protected transform(entity: T): T; /** * Zod schema for validating create input. * * Override in subclasses to enable client-side validation before create requests. * * @returns Zod schema for validation, or undefined to skip validation */ protected get createSchema(): z.ZodTypeAny | undefined; /** * Zod schema for validating update input. * * Override in subclasses to enable client-side validation before update requests. * * @returns Zod schema for validation, or undefined to skip validation */ protected get updateSchema(): z.ZodTypeAny | undefined; /** * Zod schema for validating patch input. * * Override in subclasses to enable client-side validation before patch requests. * * @returns Zod schema for validation, or undefined to skip validation */ protected get patchSchema(): z.ZodTypeAny | undefined; /** * Whether the server's PUT handler creates the resource if it doesn't exist. * * When true, `update()` adds a pre-check via `exists()` so it consistently * throws NotFoundError across all resources. Override in gradebook/assessment * subclasses where the server natively upserts on PUT. * * @returns True if the server natively upserts, false otherwise */ protected get serverNativelyUpserts(): boolean; /** * Human-readable resource name for error messages. * Derived from wrapKey by default (e.g., "user", "class"). * * @returns Resource name for error messages */ protected get resourceName(): string; /** * Unwrap a single-item response. * * @param response - Raw API response object * @returns The unwrapped resource * @throws {Error} If expected key is missing from response */ protected unwrapSingle(response: Record): T; /** * Wrap data for POST/PUT requests. * * @param data - Resource data to wrap * @returns Wrapped request body */ protected wrapBody(data: I): Record; } /** * Base class for read-only resources (no create/update/delete). * * @template T - The resource type (must extend Base) * @template F - The filter fields type for type-safe where clauses */ export declare abstract class ReadOnlyResource = ListParams> { protected readonly transport: OneRosterTransportLike; /** Full path for this resource (pathPrefix + suffix) */ protected readonly basePath: string; /** * @param transport - Transport instance for making requests * @param resourceType - Type of resource (rostering or gradebook) * @param suffix - Resource suffix (e.g., '/demographics') */ constructor(transport: OneRosterTransportLike, resourceType: ResourceType, suffix: string); /** * List the first page of resources. * * @param params - Optional `where` clause, sorting, and pagination parameters * @returns Promise resolving to the first page (data + pagination metadata) */ list(params?: P): Promise>; /** * List all resources, fetching all pages automatically. * * @param params - Optional `where` clause, sorting, and pagination parameters * @returns Promise resolving to an array of all matching resources */ listAll(params?: P): Promise; /** * Get the first matching resource, or undefined if none match. * * @param params - Optional `where` clause parameters * @returns The first matching resource, or undefined */ first(params?: P): Promise; /** * Stream resources with lazy pagination. * * Use this for large datasets where you want to process items * one at a time without loading everything into memory. * * @param params - Optional `where` clause, sorting, and pagination parameters * @returns Async iterable paginator for streaming results * @throws {InputValidationError} If params are invalid (e.g., negative limit) */ stream(params?: P): Paginator; /** * Get a single resource by sourcedId. * * @param sourcedId - The unique identifier of the resource * @returns The requested resource * @throws {InputValidationError} If sourcedId is empty * @throws {NotFoundError} If the resource doesn't exist */ get(sourcedId: string): Promise; /** * Check whether a single resource exists by sourcedId. * * @param sourcedId - The unique identifier of the resource * @returns True if found, false for 404 * @throws {InputValidationError} If sourcedId is empty * @throws {ApiError} For non-404 failures */ exists(sourcedId: string): Promise; /** * Transform a response entity before returning it. * * Override in subclasses to normalize API responses. * Default implementation returns the entity unchanged. * * @param entity - The raw entity from the API * @returns The transformed entity */ protected transform(entity: T): T; protected abstract get unwrapKey(): string; protected abstract get wrapKey(): string; } //# sourceMappingURL=base.d.ts.map