mirror of
https://github.com/LukeHagar/redocly-cli.git
synced 2025-12-07 20:57:49 +00:00
* feat(bh): make 'project' and 'domain' required for push command (CMS) * chore: add OutputFormat type for 'format' parameter for push-status command * feat: add 'format' parameter for 'push-status' command * feat: add 'markdown' to OutputFormat type * feat: make domain not required for push-status * refactor: simplify `handlePushStatus` function * feat: add json format for push-status command * feat: remove `async` from printPushStatus * feat: improve printing json summary and exit with error * feat: add 'format' option to cli push command * feat: add push metadata to json output * feat: add return data for push and pushStatus commands * feat: update push status command * tests: add new unit tests for push status * refactor: remove json format for "push" and "push-status" commands * feat: add "ignore-deployment-failures" option * chore: replace "satisfies" with "as" * chore: add changeset * feat: add onTimeOutExceeded callback * Apply suggestions from code review Co-authored-by: Lorna Jane Mitchell <github@lornajane.net> * Apply suggestions from code review Co-authored-by: Andrew Tatomyr <andrew.tatomyr@redocly.com> Co-authored-by: Roman Sainchuk <albuman32@gmail.com> * chore: update return type for commandHandler * tests: use expect.rejects instead of catching errors * feat: rename 'ignore-deployment-failures' to 'continue-on-deployment-failures' * feat: add onConditionNotMet callback * tests: add unit tests * chore: add comments * refactor: rename "wait" to "pause" and move to utils * refactor: change import type * refactor: add explicit array length check * fix: add correct wrapper type for argv params * feat: update types for push status API * chore: add "unit:watch" script to package.json * test: fix unit tests * tests: add tests for "onRetry" and "max-execution-time" parameters * chore: restore museum.yaml * feat: update API types for PushResponse * refactor: rename "continue-on-deployment-failures" to "continue-on-deploy-failures" * feat: update interface for `onRetry` function * feat: remove "instanceof Promise" check * refactor: reorder imports * feat: increase maxExecutionTime to 20 min --------- Co-authored-by: Lorna Jane Mitchell <github@lornajane.net> Co-authored-by: Andrew Tatomyr <andrew.tatomyr@redocly.com> Co-authored-by: Roman Sainchuk <albuman32@gmail.com>
53 lines
1.8 KiB
TypeScript
53 lines
1.8 KiB
TypeScript
import { pause } from '@redocly/openapi-core';
|
|
|
|
/**
|
|
* This function retries an operation until a condition is met or a timeout is exceeded.
|
|
* If the condition is not met within the timeout, an error is thrown.
|
|
* @operation The operation to retry.
|
|
* @condition The condition to check after each operation result. Return false to continue retrying. Return true to stop retrying.
|
|
* If not provided, the first result will be returned.
|
|
* @param onConditionNotMet Will be called with the last result right after checking condition and before timeout and retrying.
|
|
* @param onRetry Will be called right before retrying operation with the last result before retrying.
|
|
* @param startTime The start time of the operation. Default is the current time.
|
|
* @param retryTimeoutMs The maximum time to retry the operation. Default is 10 minutes.
|
|
* @param retryIntervalMs The interval between retries. Default is 5 seconds.
|
|
*/
|
|
export async function retryUntilConditionMet<T>({
|
|
operation,
|
|
condition,
|
|
onConditionNotMet,
|
|
onRetry,
|
|
startTime = Date.now(),
|
|
retryTimeoutMs = 600000, // 10 min
|
|
retryIntervalMs = 5000, // 5 sec
|
|
}: {
|
|
operation: () => Promise<T>;
|
|
condition?: ((result: T) => boolean) | null;
|
|
onConditionNotMet?: (lastResult: T) => void;
|
|
onRetry?: (lastResult: T) => void | Promise<void>;
|
|
startTime?: number;
|
|
retryTimeoutMs?: number;
|
|
retryIntervalMs?: number;
|
|
}): Promise<T> {
|
|
async function attempt(): Promise<T> {
|
|
const result = await operation();
|
|
|
|
if (!condition) {
|
|
return result;
|
|
}
|
|
|
|
if (condition(result)) {
|
|
return result;
|
|
} else if (Date.now() - startTime > retryTimeoutMs) {
|
|
throw new Error('Timeout exceeded');
|
|
} else {
|
|
onConditionNotMet?.(result);
|
|
await pause(retryIntervalMs);
|
|
await onRetry?.(result);
|
|
return attempt();
|
|
}
|
|
}
|
|
|
|
return attempt();
|
|
}
|