diff --git a/packages/cli/src/commands/registry/implementation/registry.ts b/packages/cli/src/commands/registry/implementation/registry.ts index 2b21b98f..f7666ef6 100644 --- a/packages/cli/src/commands/registry/implementation/registry.ts +++ b/packages/cli/src/commands/registry/implementation/registry.ts @@ -24,6 +24,13 @@ function isAlreadyExistsError(errorObj: any): boolean { ); } +/** + * Adds one or more registry components to a Xano instance, attempting to install each component file and collecting success, skip, and failure outcomes. + * + * @param componentNames - Registry component names to install; if empty, the user will be prompted to select components. + * @param context - CLI context used to resolve instance, workspace, and branch configuration; defaults to an empty object. + * @returns An object with `installed` (entries with `component`, `file` path, and `response`), `failed` (entries with `component`, `file`, `error`, and optional `response`), and `skipped` (entries for items skipped because the resource already exists). + */ async function addToXano({ componentNames, context = {}, @@ -93,12 +100,11 @@ async function addToXano({ } /** - * Installs a component file to Xano. + * Install a single component file into the configured Xano instance. * - * @param {Object} file - The component file metadata. - * @param {Object} resolvedContext - The resolved context configs. - * @param {any} core - Core utilities. - * @returns {Promise<{ success: boolean, error?: string, body?: any }>} + * @param file - Component file metadata (e.g., `type`, `path`, `target`, and for query files `apiGroupName`) that identifies what to install and where. + * @param resolvedContext - Resolved configuration objects: `instanceConfig`, `workspaceConfig`, and `branchConfig`. + * @returns An object with `success: true` and the parsed response `body` on success; on failure `success: false` and `error` contains a human-readable message, `body` may include the raw response when available. */ async function installComponentToXano(file, resolvedContext, core) { const { instanceConfig, workspaceConfig, branchConfig } = resolvedContext; @@ -177,4 +183,4 @@ async function installComponentToXano(file, resolvedContext, core) { } } -export { addToXano, scaffoldRegistry }; +export { addToXano, scaffoldRegistry }; \ No newline at end of file diff --git a/packages/cli/src/commands/test/implementation/test.ts b/packages/cli/src/commands/test/implementation/test.ts index f2263019..4fe7a54d 100644 --- a/packages/cli/src/commands/test/implementation/test.ts +++ b/packages/cli/src/commands/test/implementation/test.ts @@ -10,15 +10,17 @@ import { } from '../../../utils/index'; /** - * Prints a formatted summary table of test outcomes to the log. + * Print a formatted table of test outcomes and an optional detailed warnings section to the log. * - * Logs a header, one row per result showing status, HTTP method, path, and duration, and a final summary line with totals and aggregate duration. + * The table includes columns for status, HTTP method, path, warnings count, and duration (ms), + * followed by an aggregate summary line with total, passed, failed, and total duration. * * @param results - Array of test result objects. Each object should include: - * - `success` (boolean): whether the test passed, - * - `method` (string): HTTP method used, - * - `path` (string): endpoint path, - * - `duration` (number, optional): duration of the test in milliseconds + * - `success`: whether the test passed + * - `method`: HTTP method used for the test + * - `path`: endpoint path exercised by the test + * - `duration` (optional): duration of the test in milliseconds + * - `warnings` (optional): array of warning objects; each warning should include `key` and `message` */ function printTestSummary(results) { // Collect all rows for sizing @@ -128,9 +130,13 @@ async function loadTestConfig(testConfigPath) { } /** - * Runs API tests for selected API groups using a provided test configuration and writes per-group results to disk. + * Run API tests for selected API groups, write per-group JSON results to disk, and print a formatted summary. * - * @param instance - Name or alias of the target instance + * Resolves the target instance/workspace/branch, selects API groups (optionally prompting), loads the test + * configuration, executes tests via the provided runtime `core`, writes each group's results to a timestamped + * JSON file under the configured output path, and prints a summary table and optional output directory path. + * + * @param instance - Target instance name or alias used to resolve configuration * @param workspace - Workspace name within the instance * @param branch - Branch label within the workspace * @param group - Specific API group name to run; when omitted and `isAll` is false the user may be prompted @@ -221,4 +227,4 @@ async function runTest({ } } -export { runTest }; +export { runTest }; \ No newline at end of file diff --git a/packages/cli/src/utils/feature-focused/registry/scaffold.ts b/packages/cli/src/utils/feature-focused/registry/scaffold.ts index f8e0050c..b547888e 100644 --- a/packages/cli/src/utils/feature-focused/registry/scaffold.ts +++ b/packages/cli/src/utils/feature-focused/registry/scaffold.ts @@ -1,11 +1,21 @@ import { dirname, join } from 'node:path'; import { mkdir, writeFile } from 'node:fs/promises'; +/** + * Ensures the parent directory for the provided file path exists, creating it recursively if needed. + * + * @param filePath - Path to the target file whose containing directory should exist + */ async function ensureDirForFile(filePath: string) { const dir = dirname(filePath); await mkdir(dir, { recursive: true }); } +/** + * Creates a sample registry scaffold (components, function implementation, function definition, and index) under the specified registry root. + * + * @param registryRoot - Root directory where registry files will be written. Defaults to `'registry'`. + */ async function scaffoldRegistry( { registryRoot }: { registryRoot?: string } = { registryRoot: 'registry', @@ -69,4 +79,4 @@ async function scaffoldRegistry( await writeFile(indexPath, JSON.stringify(sampleIndex, null, 2), 'utf8'); } -export { scaffoldRegistry }; +export { scaffoldRegistry }; \ No newline at end of file diff --git a/packages/core/src/features/testing/index.ts b/packages/core/src/features/testing/index.ts index 349456e1..5b03ec7e 100644 --- a/packages/core/src/features/testing/index.ts +++ b/packages/core/src/features/testing/index.ts @@ -42,9 +42,24 @@ function getByPath(obj, path) { } /** - * testConfig is actually an array of objects defining in what order and which - * endpoints to run, also optionally define custom asserts (either inline func, or predefined asserts) - * ApiGroupConfig allows for extra keys. In this case it should include an 'oas' key + * Execute the configured API tests across the provided API groups and return per-group results. + * + * For each group, ensures an OpenAPI spec is available (fetching and patching from the remote API if absent), + * runs the endpoints defined by `testConfig` in order, evaluates assertions (built-in or custom), + * optionally extracts runtime values from JSON responses into a shared runtime store, and records timing, + * successes, errors, and warnings for each endpoint. + * + * @param context - Execution context containing instance, workspace, and branch identifiers + * @param groups - Array of API group configurations; each group may include an `oas` property (OpenAPI) and a `canonical` identifier used to build request base URLs + * @param testConfig - Ordered array of endpoint test definitions. Each entry should include: + * - `path` and `method` for the request + * - `headers`, `queryParams`, and `requestBody` for request composition + * - optional `store` mappings [{ key, path }] to extract values from JSON responses into runtime variables + * - optional `customAsserts` to override or provide per-endpoint assertions + * + * @returns An array of objects, one per input group, each containing the original `group` and a `results` array. + * Each result includes `path`, `method`, `success` (true if no assertion errors), `errors` (or null), + * `warnings` (or null), and `duration` (milliseconds) */ async function testRunner({ context, @@ -244,4 +259,4 @@ async function testRunner({ return finalOutput; } -export { testRunner }; +export { testRunner }; \ No newline at end of file