diff --git a/fync/examples/unified-usage.ts b/fync/examples/unified-usage.ts index a45d822..b0ce6ce 100644 --- a/fync/examples/unified-usage.ts +++ b/fync/examples/unified-usage.ts @@ -7,6 +7,20 @@ import { GitHub, GitLab, NPM, Spotify, Vercel } from "src"; +/** + * Runs a set of GitLab usage examples against the GitLab API. + * + * Demonstrates common read, search and mutation operations using the unified GitLab client: + * - instantiates the client from `process.env.GITLAB_TOKEN` + * - retrieves users, projects (by slug and URL), commits (including timeframe variants) + * - queries project stars and aggregated user statistics + * - performs project searches with sorting/pagination + * - accesses advanced resources (issues, merge requests, pipelines, jobs, groups) + * - creates a project issue and logs the authenticated user + * + * Side effects: performs network requests and creates a new issue via `projects.createProjectIssue`. + * Requires a valid `GITLAB_TOKEN` in the environment; without it the client will fail to authenticate. + */ async function gitlabExamples() { const gitlab = GitLab({ token: process.env.GITLAB_TOKEN! }); @@ -75,6 +89,14 @@ async function gitlabExamples() { console.log(`Authenticated as: ${currentUser.username}`); } +/** + * Runs a set of example GitHub API calls using the unified GitHub client. + * + * Demonstrates instantiation of the client (requires GITHUB_TOKEN in the environment) and common operations: + * fetching a user, querying repositories (by owner/name and by URL), retrieving commits (all, latest, and within time frames), + * fetching repository stars and user star counts, collecting aggregated user statistics, performing repository searches, + * accessing advanced repo resources (issues) and creating a new issue. Results are logged to the console. + */ async function githubExamples() { const github = GitHub({ token: process.env.GITHUB_TOKEN! }); @@ -320,7 +342,15 @@ async function addingNewApiExample() { // That's it! New API added in ~30 lines of code } -// Run examples +/** + * Orchestrates and runs the example suites for the supported APIs based on environment tokens. + * + * For each supported service, prints a header and runs its example function only if the corresponding + * environment token is present. NPM examples are always executed. The function resolves when all + * invoked example tasks complete. + * + * @returns A promise that resolves when all selected examples have finished running. + */ async function main() { console.log("🚀 Fync Unified API Examples\n"); diff --git a/fync/src/core/api-factory-enhanced.ts b/fync/src/core/api-factory-enhanced.ts index 290992c..b45c837 100644 --- a/fync/src/core/api-factory-enhanced.ts +++ b/fync/src/core/api-factory-enhanced.ts @@ -90,6 +90,23 @@ async function sleep(ms: number): Promise { return new Promise(resolve => setTimeout(resolve, ms)); } +/** + * Creates an enhanced HTTP API client with built-in authentication headers, caching, rate limiting, and retry logic. + * + * The returned client supports typed request methods (request/get/post/put/delete/patch), cache management + * (clearCache, invalidateCache), and rate-limit introspection (getRateLimitInfo). Behavior is governed by + * the provided config: baseUrl and headers are used to build requests; auth selects authentication headers; + * cache controls an internal cache instance; rateLimit accepts either a preset name or a custom rate config; + * retryConfig controls automatic retries. + * + * Defaults applied when not provided: + * - retryConfig.maxRetries: 3 + * - retryConfig.retryDelay: 1000 ms + * - retryConfig.retryOn: [429, 503, 504] + * + * @param config - API client configuration (baseUrl, optional headers, auth, cache, rateLimit, retryConfig). + * @returns A TEnhancedApiClient instance exposing request helpers, cache controls, and rate-limit information. + */ export function createEnhancedApi(config: TApiConfig): TEnhancedApiClient { const authHeaders = buildAuthHeaders(config.auth); const defaultHeaders = { diff --git a/fync/src/core/api-factory.ts b/fync/src/core/api-factory.ts index 15ce23b..82b364d 100644 --- a/fync/src/core/api-factory.ts +++ b/fync/src/core/api-factory.ts @@ -68,6 +68,17 @@ function buildUrl( return url.toString(); } +/** + * Creates an API client configured from the provided config. + * + * The client merges config.headers and authentication headers into default headers, + * constructs URLs from config.baseUrl and per-call paths/params, and performs fetch requests. + * Request bodies for non-GET methods are JSON-stringified; responses are parsed as JSON and returned. + * Non-OK HTTP responses cause an Error that includes the status and response body text. + * + * @param config - API configuration (must include `baseUrl`; optional `headers` and `auth` are applied) + * @returns A TApiClient with `request`, `get`, `post`, `put`, `delete`, and `patch` methods + */ export function createFyncApi(config: TApiConfig): TApiClient { const authHeaders = buildAuthHeaders(config.auth); const defaultHeaders = { diff --git a/fync/src/core/module-factory.ts b/fync/src/core/module-factory.ts index f439554..2cd7e36 100644 --- a/fync/src/core/module-factory.ts +++ b/fync/src/core/module-factory.ts @@ -20,6 +20,16 @@ type TModule = { api: TApiClient; }; +/** + * Build a typed module that bundles an API client with resource handlers and optional helpers. + * + * Constructs and returns a TModule whose `api` property is an API client created from `config.apiConfig`, + * whose resource keys are handlers created from `config.resources`, and which includes any `config.helpers` + * attached at the top level. + * + * @param config - Module configuration containing `name`, `apiConfig`, `resources`, and optional `helpers`. + * @returns A fully assembled module typed as `TModule`. + */ export function createFyncModule( config: TModuleConfig, ): TModule { diff --git a/fync/src/core/resource-factory.ts b/fync/src/core/resource-factory.ts index 2fdb1a3..43a2c9e 100644 --- a/fync/src/core/resource-factory.ts +++ b/fync/src/core/resource-factory.ts @@ -1,4 +1,3 @@ - import type { TApiClient } from "./api-factory"; type TMethodDefinition = { @@ -22,6 +21,15 @@ type TResource = { }; +/** + * Replace `{key}` placeholders in a path template with URL-encoded values and collect remaining params as query parameters. + * + * The function returns an object with `path` — the template with any `{key}` placeholders replaced by `encodeURIComponent(String(value))` for matching keys — and `queryParams` — a map of all input entries whose keys did not correspond to a placeholder in the template. + * + * @param template - Path template containing zero or more placeholders in the form `{key}`. + * @param params - Key/value map used to interpolate placeholders and produce query parameters. + * @returns An object with the interpolated `path` and a `queryParams` record of remaining params. + */ function interpolatePath( template: string, params: Record, @@ -41,6 +49,18 @@ function interpolatePath( return { path, queryParams }; } +/** + * Builds a typed resource object from a resource configuration and an API client. + * + * Creates one function per entry in `config.methods`. Each generated method: + * - Interpolates `config.basePath + method.path` with provided options to produce the final path and query params. + * - For methods with HTTP verb POST/PUT/PATCH: produced function has signature `(data?: any, options?: any) => Promise` and calls the corresponding `post|put|patch` client method with `(path, data, { params })`. + * - For other verbs (GET/DELETE or undefined): produced function has signature `(options?: any) => Promise` and calls the corresponding `get|delete` client method with `(path, { params })`. + * - If a method `transform` function is provided in the method definition, its return value is used; otherwise the raw API response is returned. + * + * @param config - Resource configuration that defines the basePath and per-method definitions used to build the resource. + * @returns A typed resource object whose methods match `TMethods` with the runtime implementations described above. + */ export function createFyncResource( config: TResourceConfig, apiClient: TApiClient, diff --git a/fync/src/github/index.ts b/fync/src/github/index.ts index 20407ab..5fe8411 100644 --- a/fync/src/github/index.ts +++ b/fync/src/github/index.ts @@ -220,6 +220,19 @@ type TGitHubModule = TModule & { getUserActivity: (username: string, options?: any) => Promise; }; +/** + * Create a configured GitHub API client module. + * + * Returns a GitHub API wrapper built from the shared resource definitions and the provided personal access token. The returned module exposes the underlying resource methods plus convenience helpers such as: + * - getUser, getRepository, getRepositoryFromUrl + * - getUserCommits, getUserLatestCommit, getUserCommitsInTimeframe + * - getRepositoryStars, getUserStarredCount, getUserStats + * - searchRepositories, getUserActivity + * + * @param config - Configuration object containing authentication credentials. + * - token: A GitHub personal access token used for bearer authentication. + * @returns A fully configured TGitHubModule instance with the standard resource methods and additional convenience helpers. + */ export function GitHub(config: { token: string }): TGitHubModule { const base = buildGitHub(config, resources); diff --git a/fync/src/gitlab/index.ts b/fync/src/gitlab/index.ts index 68d564a..c7825c5 100644 --- a/fync/src/gitlab/index.ts +++ b/fync/src/gitlab/index.ts @@ -225,6 +225,19 @@ type TGitLabModule = TModule & { getCurrentUser: () => Promise; }; +/** + * Create a configured GitLab API module exposing resource endpoints and higher-level helpers. + * + * Returns a module built against the GitLab API (https://gitlab.com/api/v4) that includes: + * - typed resource namespaces (users, projects, groups, search, snippets, issues, merge_requests, pipelines, activity, me) + * - convenience helpers for common workflows (e.g., getUser, getProject, getProjectFromUrl, getUserCommits, getUserStats, searchProjects, getCurrentUser) + * + * The returned module delegates most calls to the underlying resource clients and adds small utility functions + * for parsing GitLab URLs and computing timeframe dates used by commit-related helpers. + * + * @param config - Configuration object containing a GitLab personal access token: `{ token: string }`. + * @returns A configured TGitLabModule instance with resource methods and helper utilities. + */ export function GitLab(config: { token: string }): TGitLabModule { const base = buildGitLab(config, resources); diff --git a/fync/src/google-calendar/index.ts b/fync/src/google-calendar/index.ts index 43db195..9e4be58 100644 --- a/fync/src/google-calendar/index.ts +++ b/fync/src/google-calendar/index.ts @@ -135,6 +135,20 @@ type TGoogleCalendarModule = TModule & { quickAddEvent: (calendarId: string, text: string) => Promise; }; +/** + * Constructs a Google Calendar API module bound to the provided OAuth bearer token. + * + * Returns a high-level calendar client with convenience methods for listing calendars and events, + * querying free/busy, creating/updating/deleting events, and other common operations. The returned + * object implements TGoogleCalendarModule and delegates to the underlying Google Calendar REST + * resources using the supplied token. + * + * Note: getAllCalendarEvents will ignore errors when fetching events for individual calendars + * (errors for a specific calendar are swallowed and processing continues). + * + * @param config - Configuration object containing the OAuth bearer token to use for requests. + * @returns A TGoogleCalendarModule instance with bound convenience methods. + */ export function GoogleCalendar(config: { token: string; }): TGoogleCalendarModule { diff --git a/fync/src/google-drive/index.ts b/fync/src/google-drive/index.ts index 2d92c1f..2379159 100644 --- a/fync/src/google-drive/index.ts +++ b/fync/src/google-drive/index.ts @@ -157,6 +157,18 @@ type TGoogleDriveModule = TModule & { permanentlyDeleteFile: (fileId: string) => Promise; }; +/** + * Creates a Google Drive client with low-level resource endpoints and high-level convenience methods. + * + * Returns an API module bound to the provided bearer token that exposes the underlying resource methods + * (files, permissions, comments, replies, revisions, drives, changes, channels, about) and a set of + * higher-level helper functions for common operations (listing, creating, updating, moving, downloading, + * exporting files; folder management; searching; sharing; quota retrieval; etc.). + * + * @param config - Configuration object + * @param config.token - OAuth2 bearer token used for authenticating requests + * @returns A TGoogleDriveModule instance providing both resource-level API methods and convenience helpers + */ export function GoogleDrive(config: { token: string }): TGoogleDriveModule { const base = buildGoogleDrive(config, resources); const drive = base as unknown as TGoogleDriveModule; diff --git a/fync/src/npm/index.ts b/fync/src/npm/index.ts index 434b18c..c6d0688 100644 --- a/fync/src/npm/index.ts +++ b/fync/src/npm/index.ts @@ -62,6 +62,19 @@ type TNpmModule = TModule & { getPackageReadme: (packageName: string) => Promise; }; +/** + * Create a configured NPM registry client module with convenience methods for querying package metadata, downloads, search, and stats. + * + * The returned module exposes resource-based API methods plus helpers such as: + * - getPackage, getPackageVersion, getLatestVersion + * - getPackageDownloads, getPackageSize, getPackageStats + * - searchPackages + * - getPackageDependencies, getPackageMaintainers, getPackageKeywords, getPackageReadme + * - isPackageDeprecated + * + * @param config - Optional configuration. If provided, `config.registry` overrides the default registry base URL. + * @returns A TNpmModule instance bound to the configured registry. + */ export function NPM(config?: { registry?: string }): TNpmModule { const base = buildNpm( { diff --git a/fync/src/spotify/index.ts b/fync/src/spotify/index.ts index 0fc7800..67039b9 100644 --- a/fync/src/spotify/index.ts +++ b/fync/src/spotify/index.ts @@ -184,6 +184,17 @@ type TSpotifyModule = TModule & { searchPlaylists: (query: string, options?: any) => Promise; }; +/** + * Create a configured Spotify client module with convenience wrappers for common endpoints. + * + * The function builds a resource-based Spotify API client using the provided bearer token + * and augments it with higher-level helper methods (e.g., getTrack, searchTracks, + * createPlaylist, playTrack, pausePlayback, getMyTopTracks) that return Promises for + * corresponding Spotify API calls. + * + * @param config - Configuration object containing a Spotify OAuth bearer token (`token`) used for requests. + * @returns A configured TSpotifyModule instance exposing both the underlying resources and the convenience methods. + */ export function Spotify(config: { token: string }): TSpotifyModule { const base = buildSpotify(config, resources); const spotify = base as unknown as TSpotifyModule; diff --git a/fync/src/vercel/index.ts b/fync/src/vercel/index.ts index dc10970..fc6257d 100644 --- a/fync/src/vercel/index.ts +++ b/fync/src/vercel/index.ts @@ -96,6 +96,18 @@ type TVercelModule = TModule & { getTeamUsage: (teamId: string) => Promise; }; +/** + * Creates and returns a typed Vercel API module with convenience helpers. + * + * Builds a client configured with the provided token (and optional team ID) + * and exposes resource methods (projects, deployments, domains, teams, user) + * plus higher-level helpers such as getProject, listProjects, getLatestDeployment, + * getDeploymentStatus, redeployProject, getProjectAnalytics, getDomainStatus, and getTeamUsage. + * + * @param config.token - Vercel personal or team API token used for Authorization. + * @param config.teamId - Optional Vercel team ID; when provided it is sent as `x-vercel-team-id` on requests. + * @returns A TVercelModule instance: the generated API client augmented with higher-level helper methods. + */ export function Vercel(config: { token: string; teamId?: string;