@felixgeelhaar/jira-sdk 0.2.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +214 -374
- package/dist/auth/index.cjs +400 -0
- package/dist/auth/index.cjs.map +1 -0
- package/dist/auth/index.d.cts +192 -0
- package/dist/auth/index.d.ts +192 -0
- package/dist/auth/index.js +386 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/errors/index.cjs +272 -0
- package/dist/errors/index.cjs.map +1 -0
- package/dist/errors/index.d.cts +203 -0
- package/dist/errors/index.d.ts +203 -0
- package/dist/errors/index.js +254 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/http-client-BSzRYQZa.d.cts +317 -0
- package/dist/http-client-erRvYNs-.d.ts +317 -0
- package/dist/index.cjs +9582 -13466
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1242 -76
- package/dist/index.d.ts +1242 -76
- package/dist/index.js +9166 -13318
- package/dist/index.js.map +1 -1
- package/dist/schemas/index.cjs +2481 -13092
- package/dist/schemas/index.cjs.map +1 -1
- package/dist/schemas/index.d.cts +335 -207
- package/dist/schemas/index.d.ts +335 -207
- package/dist/schemas/index.js +2138 -13047
- package/dist/schemas/index.js.map +1 -1
- package/dist/services/index.cjs +6375 -13323
- package/dist/services/index.cjs.map +1 -1
- package/dist/services/index.d.cts +3852 -299
- package/dist/services/index.d.ts +3852 -299
- package/dist/services/index.js +6350 -13321
- package/dist/services/index.js.map +1 -1
- package/dist/transport/index.cjs +1016 -0
- package/dist/transport/index.cjs.map +1 -0
- package/dist/transport/index.d.cts +372 -0
- package/dist/transport/index.d.ts +372 -0
- package/dist/transport/index.js +997 -0
- package/dist/transport/index.js.map +1 -0
- package/dist/types-E6djPHpW.d.cts +95 -0
- package/dist/types-E6djPHpW.d.ts +95 -0
- package/dist/webhook-Bn8gme6Y.d.cts +6959 -0
- package/dist/webhook-Bn8gme6Y.d.ts +6959 -0
- package/package.json +73 -27
- package/dist/project-BtUx-eSv.d.cts +0 -1480
- package/dist/project-BtUx-eSv.d.ts +0 -1480
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/logging/noop-logger.ts","../../src/utils/runtime.ts","../../src/errors/base.error.ts","../../src/errors/network.error.ts","../../src/errors/api.error.ts","../../src/utils/index.ts","../../src/transport/http-client.ts","../../src/transport/middleware.ts","../../src/transport/circuit-breaker.ts","../../src/transport/rate-limit-headers.ts"],"names":["CircuitState"],"mappings":"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","file":"index.js","sourcesContent":["import type { Logger, LogFields } from './types.js';\n\n/**\n * No-op logger that discards all log messages.\n * Used as the default logger when no logger is configured.\n */\nexport class NoopLogger implements Logger {\n debug(_message: string, _fields?: LogFields): void {\n // Intentionally empty\n }\n\n info(_message: string, _fields?: LogFields): void {\n // Intentionally empty\n }\n\n warn(_message: string, _fields?: LogFields): void {\n // Intentionally empty\n }\n\n error(_message: string, _fields?: LogFields): void {\n // Intentionally empty\n }\n\n child(_fields: LogFields): Logger {\n return this;\n }\n}\n\n/** Singleton instance of the no-op logger */\nexport const noopLogger = new NoopLogger();\n","/**\n * Feature detection for host globals that TypeScript's DOM/Node lib types\n * declare as always present, but which are genuinely absent in some runtimes\n * this SDK supports (browsers, Workers, Deno, edge functions).\n *\n * Reading them through a widened view of `globalThis` keeps the runtime guard —\n * removing it would crash outside Node — while letting the type system see that\n * the check is meaningful, so it no longer reports the guard as an unnecessary\n * condition.\n */\ninterface RuntimeGlobals {\n process?: { env?: Record<string, string | undefined> };\n console?: { warn?: (...args: unknown[]) => void };\n crypto?: { randomUUID?: () => string };\n}\n\nfunction runtime(): RuntimeGlobals {\n return globalThis;\n}\n\n/**\n * Read `process.env`, or an empty object where `process` is unavailable.\n */\nexport function processEnv(): Record<string, string | undefined> {\n return runtime().process?.env ?? {};\n}\n\n/**\n * Read a single environment variable, or `undefined` where unavailable.\n */\nexport function readEnvVar(name: string): string | undefined {\n return processEnv()[name];\n}\n\n/**\n * Emit a warning through `console.warn` where one exists, otherwise do nothing.\n */\nexport function warn(message: string): void {\n runtime().console?.warn?.(message);\n}\n\n/**\n * Generate a UUID using `crypto.randomUUID` where available, falling back to a\n * timestamp-and-random identifier. The fallback is not cryptographically\n * random and is only used for request correlation IDs.\n */\nexport function randomId(): string {\n const uuid = runtime().crypto?.randomUUID?.();\n if (uuid !== undefined) {\n return uuid;\n }\n return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 11)}`;\n}\n\n/**\n * V8-only API used to trim the constructor frame from error stacks. Absent on\n * SpiderMonkey and JavaScriptCore.\n */\ntype CaptureStackTrace = (target: object, constructor?: unknown) => void;\n\n/**\n * Trim the constructor frame from an error's stack where the engine supports\n * it; a no-op elsewhere.\n *\n * `constructor` is typed `unknown` rather than `Function` so the signature does\n * not widen to \"any callable\" for callers. V8 expects a constructor function\n * there, and every call site passes `this.constructor`.\n */\nexport function captureStackTrace(target: object, constructor?: unknown): void {\n const capture = (Error as unknown as { captureStackTrace?: CaptureStackTrace }).captureStackTrace;\n capture?.(target, constructor);\n}\n","import { captureStackTrace } from '../utils/runtime.js';\n/**\n * Base error class for all SDK errors.\n * Provides consistent error structure with error codes and cause chaining.\n */\nexport abstract class JiraSdkError extends Error {\n /** Unique error code for programmatic handling */\n abstract readonly code: string;\n\n /** HTTP status code if applicable */\n readonly statusCode?: number;\n\n /** Original cause of the error */\n readonly cause?: Error;\n\n /** Additional context/metadata */\n readonly context?: Record<string, unknown>;\n\n constructor(\n message: string,\n options?: {\n cause?: Error | undefined;\n statusCode?: number | undefined;\n context?: Record<string, unknown> | undefined;\n }\n ) {\n super(message, options?.cause !== undefined ? { cause: options.cause } : undefined);\n this.name = this.constructor.name;\n\n // Only assign properties when values are defined (for exactOptionalPropertyTypes)\n if (options?.cause !== undefined) {\n this.cause = options.cause;\n }\n if (options?.statusCode !== undefined) {\n this.statusCode = options.statusCode;\n }\n if (options?.context !== undefined) {\n this.context = options.context;\n }\n\n // Maintains proper stack trace for where our error was thrown (V8 only)\n captureStackTrace(this, this.constructor);\n }\n\n /**\n * Returns a JSON representation of the error\n */\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n statusCode: this.statusCode,\n context: this.context,\n cause: this.cause?.message,\n stack: this.stack,\n };\n }\n}\n","import { JiraSdkError } from './base.error.js';\n\n/**\n * Error thrown when a network-level error occurs.\n */\nexport class NetworkError extends JiraSdkError {\n readonly code = 'NETWORK_ERROR';\n\n constructor(message: string, options?: { cause?: unknown }) {\n super(message, { cause: options?.cause as Error | undefined });\n }\n\n /**\n * Check if this error indicates a connection failure\n */\n isConnectionError(): boolean {\n const msg = this.message.toLowerCase();\n return (\n msg.includes('econnrefused') ||\n msg.includes('econnreset') ||\n msg.includes('enotfound') ||\n msg.includes('fetch failed')\n );\n }\n\n /**\n * Check if this error might be retryable\n */\n isRetryable(): boolean {\n const msg = this.message.toLowerCase();\n return msg.includes('econnreset') || msg.includes('etimedout') || msg.includes('temporary');\n }\n}\n\n/**\n * Error thrown when a request times out.\n */\nexport class TimeoutError extends JiraSdkError {\n readonly code = 'TIMEOUT_ERROR';\n\n /** The timeout duration in milliseconds */\n readonly timeoutMs: number | undefined;\n\n constructor(message: string, options?: { cause?: unknown; timeoutMs?: number }) {\n super(message, { cause: options?.cause as Error | undefined });\n this.timeoutMs = options?.timeoutMs;\n }\n}\n\n/**\n * Error thrown when a request is aborted.\n */\nexport class AbortError extends JiraSdkError {\n readonly code = 'ABORT_ERROR';\n\n constructor(message = 'Request was aborted', options?: { cause?: unknown }) {\n super(message, { cause: options?.cause as Error | undefined });\n }\n}\n","import { JiraSdkError } from './base.error.js';\n\n/**\n * Error details returned by Jira API\n */\nexport interface JiraErrorDetail {\n errorMessages?: string[] | undefined;\n errors?: Record<string, string> | undefined;\n warningMessages?: string[] | undefined;\n}\n\n/**\n * Error thrown when Jira API returns an error response.\n */\nexport class ApiError extends JiraSdkError {\n readonly code: string = 'JIRA_API_ERROR';\n\n /** Parsed error details from Jira response */\n readonly details: JiraErrorDetail | undefined;\n\n /** Raw response body */\n readonly responseBody: unknown;\n\n constructor(message: string, statusCode: number, responseBody?: unknown) {\n const details = parseErrorBody(responseBody);\n const finalMessage = details ? buildErrorMessage(message, details) : message;\n super(finalMessage, { statusCode, context: { responseBody } });\n this.details = details;\n this.responseBody = responseBody;\n }\n\n /**\n * Returns all error messages as a single array\n */\n getAllMessages(): string[] {\n const messages: string[] = [];\n\n if (this.details?.errorMessages) {\n messages.push(...this.details.errorMessages);\n }\n\n if (this.details?.errors) {\n for (const [field, msg] of Object.entries(this.details.errors)) {\n messages.push(`${field}: ${msg}`);\n }\n }\n\n if (messages.length === 0) {\n messages.push(this.message);\n }\n\n return messages;\n }\n}\n\n/**\n * Error thrown when user is not authenticated\n */\nexport class UnauthorizedError extends ApiError {\n override readonly code: string = 'JIRA_UNAUTHORIZED';\n\n constructor(message = 'Authentication required', responseBody?: unknown) {\n super(message, 401, responseBody);\n }\n}\n\n/**\n * Error thrown when user lacks required permissions\n */\nexport class ForbiddenError extends ApiError {\n override readonly code: string = 'JIRA_FORBIDDEN';\n\n constructor(message = 'Permission denied', responseBody?: unknown) {\n super(message, 403, responseBody);\n }\n}\n\n/**\n * Error thrown when requested resource is not found\n */\nexport class NotFoundError extends ApiError {\n override readonly code: string = 'JIRA_NOT_FOUND';\n\n constructor(message = 'Resource not found', responseBody?: unknown) {\n super(message, 404, responseBody);\n }\n}\n\n/**\n * Rate limit error options\n */\nexport interface RateLimitErrorOptions {\n retryAfter?: number | undefined;\n}\n\n/**\n * Error thrown when rate limit is exceeded\n */\nexport class RateLimitError extends ApiError {\n override readonly code: string = 'JIRA_RATE_LIMITED';\n\n /** When to retry (in milliseconds) */\n readonly retryAfter: number | undefined;\n\n constructor(\n message = 'Rate limit exceeded',\n responseBody?: unknown,\n options?: RateLimitErrorOptions\n ) {\n super(message, 429, responseBody);\n this.retryAfter = options?.retryAfter;\n }\n}\n\n/**\n * Error thrown when server encounters an internal error\n */\nexport class ServerError extends ApiError {\n override readonly code: string = 'JIRA_SERVER_ERROR';\n\n constructor(message = 'Internal server error', responseBody?: unknown, statusCode = 500) {\n super(message, statusCode, responseBody);\n }\n}\n\n// Helper functions\nfunction parseErrorBody(body: unknown): JiraErrorDetail | undefined {\n if (!body || typeof body !== 'object') {\n return undefined;\n }\n\n const obj = body as Record<string, unknown>;\n\n return {\n errorMessages: Array.isArray(obj['errorMessages'])\n ? (obj['errorMessages'] as string[])\n : undefined,\n errors:\n typeof obj['errors'] === 'object' && obj['errors'] !== null\n ? (obj['errors'] as Record<string, string>)\n : undefined,\n warningMessages: Array.isArray(obj['warningMessages'])\n ? (obj['warningMessages'] as string[])\n : undefined,\n };\n}\n\nfunction buildErrorMessage(baseMessage: string, details: JiraErrorDetail): string {\n // First, try to use error messages from the response\n if (details.errorMessages?.length) {\n return details.errorMessages.join('; ');\n }\n\n // Then, try field-specific errors\n if (details.errors && Object.keys(details.errors).length > 0) {\n const fieldErrors = Object.entries(details.errors)\n .map(([field, msg]) => `${field}: ${msg}`)\n .join('; ');\n return `${baseMessage}: ${fieldErrors}`;\n }\n\n return baseMessage;\n}\n","/**\n * Utility functions for the SDK.\n */\n\n/**\n * Sleep for a specified duration\n */\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Create a timeout promise that rejects after the specified duration\n */\nexport function timeout(ms: number, message?: string): Promise<never> {\n return new Promise((_, reject) => {\n setTimeout(() => {\n reject(new Error(message ?? `Timeout after ${ms}ms`));\n }, ms);\n });\n}\n\n/**\n * Race a promise against a timeout\n */\nexport function promiseWithTimeout<T>(\n promise: Promise<T>,\n ms: number,\n message?: string\n): Promise<T> {\n return Promise.race([promise, timeout(ms, message)]);\n}\n\n/**\n * Build a URL query string from a parameters object.\n *\n * Returns the encoded pairs **without** a leading `?` (for example\n * `a=1&b=2`), so callers stay in control of the separator. Returns an empty\n * string when there is nothing to encode.\n *\n * Note: this previously returned a leading `?`, while the only caller also\n * prepended its own separator. The result was a doubled `??`, which made the\n * first parameter's name `?jql` rather than `jql` — so the first query\n * parameter of every request was silently dropped by Jira.\n */\nexport function buildQueryString(params: Record<string, unknown>): string {\n const filtered = Object.entries(params).filter(\n ([, value]) => value !== undefined && value !== null && value !== ''\n );\n\n if (filtered.length === 0) {\n return '';\n }\n\n const searchParams = new URLSearchParams();\n\n for (const [key, value] of filtered) {\n if (Array.isArray(value)) {\n for (const item of value) {\n searchParams.append(key, String(item));\n }\n } else {\n searchParams.set(key, String(value));\n }\n }\n\n return searchParams.toString();\n}\n\n/**\n * Join path segments into a URL path\n */\nexport function joinPath(...segments: Array<string | number>): string {\n return segments\n .map(String)\n .map((s) => s.replace(/^\\/+|\\/+$/g, ''))\n .filter(Boolean)\n .join('/');\n}\n\n/**\n * Build a Jira REST API path\n */\nexport function buildApiPath(version: '2' | '3', ...segments: Array<string | number>): string {\n return joinPath('rest', 'api', version, ...segments);\n}\n\n/**\n * Build a Jira Agile API path\n */\nexport function buildAgileApiPath(...segments: Array<string | number>): string {\n return joinPath('rest', 'agile', '1.0', ...segments);\n}\n\n/**\n * Safely parse JSON, returning undefined on error\n */\nexport function safeJsonParse<T = unknown>(json: string): T | undefined {\n try {\n return JSON.parse(json) as T;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Check if a value is a non-null object\n */\nexport function isObject(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\n/**\n * Check if a value is a non-empty string\n */\nexport function isNonEmptyString(value: unknown): value is string {\n return typeof value === 'string' && value.length > 0;\n}\n\n/**\n * Clamp a number between min and max\n */\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\n/**\n * Calculate exponential backoff delay\n */\nexport function exponentialBackoff(\n attempt: number,\n baseDelay: number,\n maxDelay: number,\n multiplier = 2,\n jitter = true\n): number {\n const delay = Math.min(baseDelay * Math.pow(multiplier, attempt), maxDelay);\n if (jitter) {\n // Add random jitter of +/- 25%\n const jitterAmount = delay * 0.25;\n return delay + (Math.random() * 2 - 1) * jitterAmount;\n }\n return delay;\n}\n\n/**\n * Generate a random request ID for tracing\n */\nexport function generateRequestId(): string {\n return `${Date.now().toString(36)}-${Math.random().toString(36).substring(2, 11)}`;\n}\n\n/**\n * Sanitize headers for logging (redact sensitive values)\n */\nexport function sanitizeHeaders(headers: Record<string, string>): Record<string, string> {\n const sensitiveKeys = new Set([\n 'authorization',\n 'x-api-key',\n 'cookie',\n 'set-cookie',\n 'x-auth-token',\n ]);\n\n const sanitized: Record<string, string> = {};\n\n for (const [key, value] of Object.entries(headers)) {\n if (sensitiveKeys.has(key.toLowerCase())) {\n sanitized[key] = '***REDACTED***';\n } else {\n sanitized[key] = value;\n }\n }\n\n return sanitized;\n}\n\n/**\n * Retry a function with exponential backoff\n */\nexport async function retry<T>(\n fn: () => Promise<T>,\n options: {\n maxAttempts: number;\n baseDelay: number;\n maxDelay: number;\n shouldRetry?: (error: unknown, attempt: number) => boolean;\n }\n): Promise<T> {\n const { maxAttempts, baseDelay, maxDelay, shouldRetry } = options;\n let lastError: unknown;\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error;\n\n if (attempt === maxAttempts - 1) {\n throw error;\n }\n\n if (shouldRetry && !shouldRetry(error, attempt)) {\n throw error;\n }\n\n const delay = exponentialBackoff(attempt, baseDelay, maxDelay);\n await sleep(delay);\n }\n }\n\n throw lastError;\n}\n\n/**\n * Create a deferred promise\n */\nexport function createDeferred<T>(): {\n promise: Promise<T>;\n resolve: (value: T) => void;\n reject: (error: unknown) => void;\n} {\n let resolve!: (value: T) => void;\n let reject!: (error: unknown) => void;\n\n const promise = new Promise<T>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n\n return { promise, resolve, reject };\n}\n\n/**\n * Seconds per Jira duration unit.\n *\n * Note: these are calendar units (1d = 24h, 1w = 7d), matching the Go SDK's\n * `FormatDuration`. A Jira site configured with a working day of 8h and a\n * working week of 5d will render the same number of seconds differently in its\n * UI — convert with the site's `timeTrackingConfiguration` if that matters.\n */\nconst DURATION_UNITS = {\n w: 7 * 24 * 3600,\n d: 24 * 3600,\n h: 3600,\n m: 60,\n s: 1,\n} as const;\n\nconst DURATION_SYNTAX = /^(?:\\d+(?:\\.\\d+)?\\s*[wdhms]?\\s*)+$/i;\nconst DURATION_TOKEN = /(\\d+(?:\\.\\d+)?)\\s*([wdhms])?/gi;\n\n/**\n * Parse a Jira duration string into seconds.\n *\n * Accepts the units Jira uses — `w`, `d`, `h`, `m`, `s` — in any order, with\n * or without spaces. A bare number is interpreted as minutes, as Jira does.\n *\n * @param value - Duration string, e.g. `'3h 30m'`, `'1d4h'`, `'90'`\n * @returns The duration in whole seconds\n * @throws {Error} If the string is empty or not a valid duration\n *\n * @example\n * ```ts\n * parseDuration('3h 30m'); // 12600\n * parseDuration('1d 4h'); // 100800\n * ```\n */\nexport function parseDuration(value: string): number {\n const trimmed = value.trim();\n\n if (trimmed === '' || !DURATION_SYNTAX.test(trimmed)) {\n throw new Error(`Invalid duration: ${JSON.stringify(value)}. Expected a string like \"3h 30m\".`);\n }\n\n let total = 0;\n DURATION_TOKEN.lastIndex = 0;\n\n for (const match of trimmed.matchAll(DURATION_TOKEN)) {\n const amount = Number(match[1]);\n const unit = (match[2] ?? 'm').toLowerCase() as keyof typeof DURATION_UNITS;\n total += amount * DURATION_UNITS[unit];\n }\n\n return Math.round(total);\n}\n\n/**\n * Format a number of seconds as a Jira duration string.\n *\n * Uses the same calendar units as {@link parseDuration}, so the two round-trip.\n * Components that would be zero are omitted; sub-minute remainders are dropped.\n *\n * @param seconds - A non-negative duration in seconds\n * @returns The duration string, e.g. `'3h 30m'`; `'0m'` for zero\n * @throws {Error} If `seconds` is negative or not a finite number\n *\n * @example\n * ```ts\n * formatDuration(12600); // '3h 30m'\n * formatDuration(100800); // '1d 4h'\n * ```\n */\nexport function formatDuration(seconds: number): string {\n if (!Number.isFinite(seconds) || seconds < 0) {\n throw new Error(\n `Invalid duration in seconds: ${String(seconds)}. Expected a non-negative number.`\n );\n }\n\n let remaining = Math.floor(seconds);\n const parts: string[] = [];\n\n for (const unit of ['w', 'd', 'h', 'm'] as const) {\n const size = DURATION_UNITS[unit];\n const count = Math.floor(remaining / size);\n if (count > 0) {\n parts.push(`${count}${unit}`);\n remaining -= count * size;\n }\n }\n\n return parts.length > 0 ? parts.join(' ') : '0m';\n}\n\n/**\n * Parse environment variable as number\n */\nexport function parseEnvNumber(value: string | undefined, defaultValue: number): number {\n if (!value) {\n return defaultValue;\n }\n\n const parsed = parseInt(value, 10);\n return isNaN(parsed) ? defaultValue : parsed;\n}\n\n/**\n * Parse environment variable as boolean\n */\nexport function parseEnvBoolean(value: string | undefined, defaultValue: boolean): boolean {\n if (!value) {\n return defaultValue;\n }\n\n return value.toLowerCase() === 'true' || value === '1';\n}\n","import type {\n HttpClientConfig,\n HttpRequest,\n HttpResponse,\n HttpMethod,\n RequestOptions,\n Middleware,\n MiddlewareContext,\n MiddlewareNext,\n QueryParamValue,\n} from './types.js';\nimport type { AuthProvider } from '../auth/types.js';\nimport type { Logger } from '../logging/types.js';\nimport { NoopLogger } from '../logging/noop-logger.js';\nimport { NetworkError, TimeoutError, AbortError } from '../errors/network.error.js';\nimport {\n ApiError,\n UnauthorizedError,\n ForbiddenError,\n NotFoundError,\n RateLimitError,\n ServerError,\n} from '../errors/api.error.js';\nimport { buildQueryString, joinPath } from '../utils/index.js';\nimport { readEnvVar, warn } from '../utils/runtime.js';\n\n/**\n * Default request timeout (30 seconds)\n */\nconst DEFAULT_TIMEOUT_MS = 30_000;\n\n/**\n * Validates that the URL uses HTTPS in production environments\n * @throws Error if HTTP is used in production without explicit opt-in\n */\nfunction validateSecureUrl(url: string, allowInsecure: boolean | undefined): void {\n const isHttps = url.startsWith('https://');\n const isLocalhost = url.includes('localhost') || url.includes('127.0.0.1');\n const isProduction = readEnvVar('NODE_ENV') === 'production';\n\n if (!isHttps && !isLocalhost && !allowInsecure) {\n if (isProduction) {\n throw new Error(\n `Security Error: HTTPS is required for production environments. ` +\n `URL \"${url}\" uses HTTP. Use HTTPS or set allowInsecureHttp: true for testing.`\n );\n }\n // Warn in non-production environments\n warn(\n `[SDK Warning] Using insecure HTTP connection to \"${url}\". ` +\n `HTTPS is strongly recommended for production use.`\n );\n }\n}\n\n/**\n * HTTP client for making API requests\n *\n * Features:\n * - Middleware support for request/response processing\n * - Automatic authentication header injection\n * - Request timeout handling\n * - AbortSignal support for cancellation\n * - Automatic JSON serialization/deserialization\n * - Error classification (API errors, network errors, etc.)\n *\n * @example\n * ```typescript\n * const client = new HttpClient({\n * baseUrl: 'https://your-domain.atlassian.net',\n * auth: new ApiTokenAuth({ email: '...', apiToken: '...' }),\n * middleware: [loggingMiddleware, retryMiddleware],\n * });\n *\n * const response = await client.get('/rest/api/3/myself');\n * ```\n */\nexport class HttpClient {\n private readonly baseUrl: string;\n private readonly auth: AuthProvider | undefined;\n private readonly logger: Logger;\n private readonly timeout: number;\n private readonly defaultHeaders: Record<string, string>;\n private readonly middleware: Middleware[];\n private readonly fetchFn: typeof fetch;\n private middlewareChain: MiddlewareNext | undefined;\n\n constructor(config: HttpClientConfig) {\n // Validate URL security\n validateSecureUrl(config.baseUrl, config.allowInsecureHttp);\n\n this.baseUrl = config.baseUrl.replace(/\\/$/, ''); // Remove trailing slash\n this.auth = config.auth;\n this.logger = config.logger ?? new NoopLogger();\n this.timeout = config.timeout ?? DEFAULT_TIMEOUT_MS;\n this.defaultHeaders = {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n ...config.defaultHeaders,\n };\n this.middleware = config.middleware ?? [];\n this.fetchFn = config.fetch ?? globalThis.fetch.bind(globalThis);\n\n // Pre-build middleware chain for better performance\n this.middlewareChain = this.buildMiddlewareChain();\n }\n\n /**\n * Make a GET request\n */\n async get<T = unknown>(\n path: string,\n params?: Record<string, QueryParamValue | undefined>,\n options?: RequestOptions\n ): Promise<HttpResponse<T>> {\n return this.request<T>({\n ...options,\n method: 'GET',\n url: path,\n // Merge rather than let one clobber the other: callers may pass params\n // positionally and additionally supply some via options.\n params: { ...params, ...options?.params },\n });\n }\n\n /**\n * Make a POST request\n */\n async post<T = unknown>(\n path: string,\n body?: unknown,\n options?: RequestOptions\n ): Promise<HttpResponse<T>> {\n return this.request<T>({\n method: 'POST',\n url: path,\n body,\n ...options,\n });\n }\n\n /**\n * Make a PUT request\n */\n async put<T = unknown>(\n path: string,\n body?: unknown,\n options?: RequestOptions\n ): Promise<HttpResponse<T>> {\n return this.request<T>({\n method: 'PUT',\n url: path,\n body,\n ...options,\n });\n }\n\n /**\n * Make a PATCH request\n */\n async patch<T = unknown>(\n path: string,\n body?: unknown,\n options?: RequestOptions\n ): Promise<HttpResponse<T>> {\n return this.request<T>({\n method: 'PATCH',\n url: path,\n body,\n ...options,\n });\n }\n\n /**\n * Make a DELETE request\n */\n async delete<T = unknown>(path: string, options?: RequestOptions): Promise<HttpResponse<T>> {\n return this.request<T>({\n method: 'DELETE',\n url: path,\n ...options,\n });\n }\n\n /**\n * Make a request with full control over the configuration\n */\n async request<T = unknown>(\n requestConfig: Omit<HttpRequest, 'method'> & {\n method?: HttpMethod;\n } & RequestOptions\n ): Promise<HttpResponse<T>> {\n const {\n method = 'GET',\n url,\n headers,\n body,\n params,\n timeout,\n signal,\n metadata,\n skipAuth,\n } = requestConfig;\n\n const httpRequest: HttpRequest = {\n method,\n url,\n headers: { ...this.defaultHeaders, ...headers },\n body,\n params,\n timeout: timeout ?? this.timeout,\n signal,\n metadata,\n };\n\n const context: MiddlewareContext = {\n request: httpRequest,\n auth: skipAuth ? undefined : this.auth,\n logger: this.logger,\n retryCount: 0,\n };\n\n // Use pre-built middleware chain for better performance\n const chain = this.middlewareChain ?? this.buildMiddlewareChain();\n\n return chain(context) as Promise<HttpResponse<T>>;\n }\n\n /**\n * Build the middleware chain with the final request handler\n */\n private buildMiddlewareChain(): MiddlewareNext {\n // The final handler that actually makes the HTTP request\n const finalHandler: MiddlewareNext = async (context) => {\n return this.executeRequest(context);\n };\n\n // Build chain from right to left\n return this.middleware.reduceRight<MiddlewareNext>((next, middleware) => {\n return async (ctx) => middleware(ctx, next);\n }, finalHandler);\n }\n\n /**\n * Execute the actual HTTP request\n */\n private async executeRequest(context: MiddlewareContext): Promise<HttpResponse> {\n const { request, auth } = context;\n const startTime = Date.now();\n\n // Build full URL\n let fullUrl = request.url.startsWith('http')\n ? request.url\n : joinPath(this.baseUrl, request.url);\n\n // Add query parameters\n if (request.params) {\n const queryString = buildQueryString(request.params);\n if (queryString) {\n fullUrl += (fullUrl.includes('?') ? '&' : '?') + queryString;\n }\n }\n\n // Build headers\n const headers = new Headers(request.headers);\n\n // Add auth headers if provider is available\n if (auth) {\n const authHeaders = await auth.getAuthHeaders();\n for (const [key, value] of Object.entries(authHeaders)) {\n headers.set(key, value);\n }\n }\n\n // Prepare request body\n let bodyContent: BodyInit | undefined;\n if (request.body !== undefined) {\n if (request.body instanceof FormData || request.body instanceof Blob) {\n bodyContent = request.body;\n // Remove Content-Type so browser/runtime sets it with boundary for FormData\n headers.delete('Content-Type');\n } else if (typeof request.body === 'string') {\n bodyContent = request.body;\n } else {\n bodyContent = JSON.stringify(request.body);\n }\n }\n\n // Create AbortController for timeout\n const controller = new AbortController();\n const timeoutId = setTimeout(() => {\n controller.abort();\n }, request.timeout ?? this.timeout);\n\n // Combine with external signal if provided\n const combinedSignal = request.signal\n ? this.combineSignals(request.signal, controller.signal)\n : controller.signal;\n\n try {\n const response = await this.fetchFn(fullUrl, {\n method: request.method,\n headers,\n ...(bodyContent !== undefined && { body: bodyContent }),\n signal: combinedSignal,\n });\n\n clearTimeout(timeoutId);\n\n const responseTime = Date.now() - startTime;\n\n // Parse response body\n const contentType = response.headers.get('content-type');\n let data: unknown;\n\n // Check if raw blob response is requested\n const wantBlob = request.metadata?.['rawResponse'] === true;\n\n if (wantBlob) {\n data = await response.blob();\n } else if (contentType?.includes('application/json')) {\n const text = await response.text();\n data = text ? JSON.parse(text) : null;\n } else {\n data = await response.text();\n }\n\n // Handle error responses\n if (!response.ok) {\n this.handleErrorResponse(response, data);\n }\n\n return {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n data,\n request,\n responseTime,\n };\n } catch (error) {\n clearTimeout(timeoutId);\n\n if (error instanceof ApiError) {\n throw error;\n }\n\n if (error instanceof Error) {\n if (error.name === 'AbortError') {\n if (request.signal?.aborted) {\n throw new AbortError('Request was aborted', { cause: error });\n }\n throw new TimeoutError(`Request timed out after ${request.timeout ?? this.timeout}ms`, {\n cause: error,\n });\n }\n\n throw new NetworkError(`Network error: ${error.message}`, {\n cause: error,\n });\n }\n\n throw new NetworkError('Unknown network error', { cause: error });\n }\n }\n\n /**\n * Handle error responses and throw appropriate errors\n */\n private handleErrorResponse(response: Response, data: unknown): never {\n const status = response.status;\n\n switch (status) {\n case 401:\n throw new UnauthorizedError('Authentication required', data);\n case 403:\n throw new ForbiddenError('Access denied', data);\n case 404:\n throw new NotFoundError('Resource not found', data);\n case 429: {\n const retryAfter = this.parseRetryAfter(response.headers);\n throw new RateLimitError(\n 'Rate limit exceeded',\n data,\n retryAfter !== undefined ? { retryAfter } : undefined\n );\n }\n default:\n if (status >= 500) {\n throw new ServerError(`Server error: ${response.statusText}`, data, status);\n }\n throw new ApiError(`API error: ${response.statusText}`, status, data);\n }\n }\n\n /**\n * Parse Retry-After header\n */\n private parseRetryAfter(headers: Headers): number | undefined {\n const retryAfter = headers.get('retry-after');\n if (!retryAfter) return undefined;\n\n const seconds = parseInt(retryAfter, 10);\n if (!isNaN(seconds)) {\n return seconds * 1000;\n }\n\n // Try parsing as date\n const date = Date.parse(retryAfter);\n if (!isNaN(date)) {\n return Math.max(0, date - Date.now());\n }\n\n return undefined;\n }\n\n /**\n * Combine multiple AbortSignals\n */\n private combineSignals(signal1: AbortSignal, signal2: AbortSignal): AbortSignal {\n const controller = new AbortController();\n\n const abort = (): void => {\n controller.abort();\n };\n\n if (signal1.aborted || signal2.aborted) {\n controller.abort();\n return controller.signal;\n }\n\n signal1.addEventListener('abort', abort);\n signal2.addEventListener('abort', abort);\n\n return controller.signal;\n }\n\n /**\n * Add middleware to the chain\n * Note: This rebuilds the middleware chain for the new configuration\n */\n use(middleware: Middleware): this {\n this.middleware.push(middleware);\n // Rebuild middleware chain to include new middleware\n this.middlewareChain = this.buildMiddlewareChain();\n return this;\n }\n\n /**\n * Get the base URL\n */\n getBaseUrl(): string {\n return this.baseUrl;\n }\n\n /**\n * Get the auth provider\n */\n getAuth(): AuthProvider | undefined {\n return this.auth;\n }\n}\n\n/**\n * Factory function to create HTTP client\n */\nexport function createHttpClient(config: HttpClientConfig): HttpClient {\n return new HttpClient(config);\n}\n","import type { Middleware, MiddlewareContext, MiddlewareNext, HttpResponse } from './types.js';\nimport { RateLimitError, ServerError, ApiError } from '../errors/api.error.js';\nimport { NetworkError } from '../errors/network.error.js';\nimport { sleep, exponentialBackoff } from '../utils/index.js';\nimport { randomId } from '../utils/runtime.js';\n\n/**\n * Logging middleware configuration\n */\nexport interface LoggingMiddlewareConfig {\n /**\n * Log request details\n */\n logRequests?: boolean;\n\n /**\n * Log response details\n */\n logResponses?: boolean;\n\n /**\n * Log errors\n */\n logErrors?: boolean;\n\n /**\n * Redact sensitive headers (authorization, etc.)\n */\n redactHeaders?: string[];\n}\n\n/**\n * Create a logging middleware\n *\n * @example\n * ```typescript\n * const client = new HttpClient({\n * baseUrl: '...',\n * middleware: [\n * createLoggingMiddleware({ logRequests: true, logResponses: true }),\n * ],\n * });\n * ```\n */\nexport function createLoggingMiddleware(config: LoggingMiddlewareConfig = {}): Middleware {\n const {\n logRequests = true,\n logResponses = true,\n logErrors = true,\n redactHeaders = ['authorization', 'x-api-key'],\n } = config;\n\n const redactHeadersLower = redactHeaders.map((h) => h.toLowerCase());\n\n return async (context: MiddlewareContext, next: MiddlewareNext): Promise<HttpResponse> => {\n const { request, logger } = context;\n\n if (logRequests) {\n const headers = { ...request.headers };\n for (const key of Object.keys(headers)) {\n if (redactHeadersLower.includes(key.toLowerCase())) {\n headers[key] = '[REDACTED]';\n }\n }\n\n logger.debug('HTTP Request', {\n method: request.method,\n url: request.url,\n headers,\n params: request.params,\n });\n }\n\n try {\n const response = await next(context);\n\n if (logResponses) {\n logger.debug('HTTP Response', {\n status: response.status,\n statusText: response.statusText,\n responseTime: response.responseTime,\n });\n }\n\n return response;\n } catch (error) {\n if (logErrors) {\n logger.error('HTTP Error', {\n method: request.method,\n url: request.url,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n throw error;\n }\n };\n}\n\n/**\n * Retry middleware configuration\n */\nexport interface RetryMiddlewareConfig {\n /**\n * Maximum number of retries (default: 3)\n */\n maxRetries?: number;\n\n /**\n * Initial delay in ms (default: 1000)\n */\n initialDelayMs?: number;\n\n /**\n * Maximum delay in ms (default: 30000)\n */\n maxDelayMs?: number;\n\n /**\n * Backoff multiplier (default: 2)\n */\n multiplier?: number;\n\n /**\n * Add random jitter (default: true)\n */\n jitter?: boolean;\n\n /**\n * Custom retry condition\n */\n shouldRetry?: (error: unknown, context: MiddlewareContext) => boolean;\n}\n\n/**\n * Default retry condition\n */\nfunction defaultShouldRetry(error: unknown): boolean {\n // Retry on rate limit errors\n if (error instanceof RateLimitError) {\n return true;\n }\n\n // Retry on 5xx errors\n if (error instanceof ServerError) {\n return true;\n }\n\n // Retry on network errors\n if (error instanceof NetworkError) {\n return true;\n }\n\n // Don't retry on other API errors (4xx except 429)\n if (error instanceof ApiError) {\n return false;\n }\n\n return false;\n}\n\n/**\n * Create a retry middleware with exponential backoff\n *\n * @example\n * ```typescript\n * const client = new HttpClient({\n * baseUrl: '...',\n * middleware: [\n * createRetryMiddleware({ maxRetries: 3 }),\n * ],\n * });\n * ```\n */\nexport function createRetryMiddleware(config: RetryMiddlewareConfig = {}): Middleware {\n const {\n maxRetries = 3,\n initialDelayMs = 1000,\n maxDelayMs = 30000,\n multiplier = 2,\n jitter = true,\n shouldRetry = defaultShouldRetry,\n } = config;\n\n return async (context: MiddlewareContext, next: MiddlewareNext): Promise<HttpResponse> => {\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n context.retryCount = attempt;\n return await next(context);\n } catch (error) {\n lastError = error;\n\n // Check if we should retry\n if (attempt >= maxRetries || !shouldRetry(error, context)) {\n throw error;\n }\n\n // Calculate delay\n let delayMs: number;\n\n // Use Retry-After header if available\n if (error instanceof RateLimitError && error.retryAfter) {\n delayMs = error.retryAfter;\n } else {\n delayMs = exponentialBackoff(attempt, initialDelayMs, maxDelayMs, multiplier, jitter);\n }\n\n context.logger.debug('Retrying request', {\n attempt: attempt + 1,\n maxRetries,\n delayMs,\n error: error instanceof Error ? error.message : String(error),\n });\n\n await sleep(delayMs);\n }\n }\n\n throw lastError;\n };\n}\n\n/**\n * Rate limit middleware configuration\n */\nexport interface RateLimitMiddlewareConfig {\n /**\n * Maximum requests per window\n */\n maxRequests: number;\n\n /**\n * Window duration in ms\n */\n windowMs: number;\n\n /**\n * Wait for slot instead of throwing error\n */\n waitForSlot?: boolean;\n}\n\n/**\n * Create a client-side rate limiting middleware\n *\n * @example\n * ```typescript\n * const client = new HttpClient({\n * baseUrl: '...',\n * middleware: [\n * createRateLimitMiddleware({ maxRequests: 100, windowMs: 60000 }),\n * ],\n * });\n * ```\n */\nexport function createRateLimitMiddleware(config: RateLimitMiddlewareConfig): Middleware {\n const { maxRequests, windowMs, waitForSlot = true } = config;\n const timestamps: number[] = [];\n\n return async (context: MiddlewareContext, next: MiddlewareNext): Promise<HttpResponse> => {\n const now = Date.now();\n\n // Remove old timestamps outside the window\n const cutoff = now - windowMs;\n for (\n let oldest = timestamps[0];\n oldest !== undefined && oldest < cutoff;\n oldest = timestamps[0]\n ) {\n timestamps.shift();\n }\n\n // Check if we're at the limit\n if (timestamps.length >= maxRequests) {\n if (waitForSlot) {\n // The length check above guarantees at least one entry.\n const oldestTimestamp = timestamps[0] ?? now;\n const waitTime = oldestTimestamp + windowMs - now;\n\n if (waitTime > 0) {\n context.logger.debug('Rate limit reached, waiting', { waitTime });\n await sleep(waitTime);\n }\n\n // Remove the oldest after waiting\n timestamps.shift();\n } else {\n throw new RateLimitError('Client-side rate limit exceeded', undefined, {\n retryAfter: (timestamps[0] ?? now) + windowMs - now,\n });\n }\n }\n\n timestamps.push(now);\n return next(context);\n };\n}\n\n/**\n * Request ID middleware - adds a unique ID to each request\n */\nexport function createRequestIdMiddleware(headerName = 'X-Request-ID'): Middleware {\n return async (context: MiddlewareContext, next: MiddlewareNext): Promise<HttpResponse> => {\n const requestId = generateRequestId();\n context.request.headers = {\n ...context.request.headers,\n [headerName]: requestId,\n };\n context.requestId = requestId;\n return next(context);\n };\n}\n\n/**\n * Generate a unique request ID\n */\nfunction generateRequestId(): string {\n // randomId() prefers crypto.randomUUID and falls back where it is absent.\n return randomId();\n}\n\n/**\n * User-Agent middleware configuration\n */\nexport interface UserAgentMiddlewareConfig {\n /**\n * SDK name\n */\n sdkName: string;\n\n /**\n * SDK version\n */\n sdkVersion: string;\n\n /**\n * Additional user agent suffix\n */\n suffix?: string;\n}\n\n/**\n * Create a User-Agent middleware\n */\nexport function createUserAgentMiddleware(config: UserAgentMiddlewareConfig): Middleware {\n const { sdkName, sdkVersion, suffix } = config;\n let userAgent = `${sdkName}/${sdkVersion}`;\n\n // Add runtime info\n if (typeof process !== 'undefined' && process.version) {\n userAgent += ` Node.js/${process.version.slice(1)}`;\n } else if (typeof navigator !== 'undefined') {\n userAgent += ' Browser';\n }\n\n if (suffix) {\n userAgent += ` ${suffix}`;\n }\n\n return async (context: MiddlewareContext, next: MiddlewareNext): Promise<HttpResponse> => {\n context.request.headers = {\n ...context.request.headers,\n 'User-Agent': userAgent,\n };\n return next(context);\n };\n}\n\n/**\n * Compose multiple middleware into a single middleware\n */\nexport function composeMiddleware(...middlewares: Middleware[]): Middleware {\n return async (context: MiddlewareContext, next: MiddlewareNext): Promise<HttpResponse> => {\n // Build chain from right to left\n const chain = middlewares.reduceRight<MiddlewareNext>((nextFn, middleware) => {\n return async (ctx) => middleware(ctx, nextFn);\n }, next);\n\n return chain(context);\n };\n}\n","import type { Middleware, MiddlewareContext, MiddlewareNext, HttpResponse } from './types.js';\nimport { NetworkError } from '../errors/network.error.js';\nimport { ApiError, ServerError, RateLimitError } from '../errors/api.error.js';\n\n/**\n * Circuit breaker states\n */\nexport enum CircuitState {\n CLOSED = 'CLOSED', // Normal operation, requests flow through\n OPEN = 'OPEN', // Circuit is open, requests fail fast\n HALF_OPEN = 'HALF_OPEN', // Testing if service is recovered\n}\n\n/**\n * Circuit breaker configuration\n */\nexport interface CircuitBreakerConfig {\n /**\n * Number of failures before opening the circuit (default: 5)\n */\n failureThreshold?: number;\n\n /**\n * Time in ms to wait before testing recovery (default: 30000)\n */\n resetTimeoutMs?: number;\n\n /**\n * Time window in ms to count failures (default: 60000)\n */\n failureWindowMs?: number;\n\n /**\n * Number of successful requests in half-open state to close circuit (default: 1)\n */\n successThreshold?: number;\n\n /**\n * Custom function to determine if an error should count as a failure\n */\n isFailure?: (error: unknown) => boolean;\n\n /**\n * Callback when state changes\n */\n onStateChange?: (from: CircuitState, to: CircuitState) => void;\n}\n\n/**\n * Circuit breaker error thrown when circuit is open\n */\nexport class CircuitBreakerOpenError extends Error {\n readonly code = 'CIRCUIT_BREAKER_OPEN';\n readonly remainingMs: number;\n\n constructor(message: string, remainingMs: number) {\n super(message);\n this.name = 'CircuitBreakerOpenError';\n this.remainingMs = remainingMs;\n }\n}\n\n/**\n * Circuit breaker state manager\n */\nexport class CircuitBreaker {\n private state: CircuitState = CircuitState.CLOSED;\n private failures: number[] = [];\n private lastFailureTime: number = 0;\n private successCount: number = 0;\n\n private readonly failureThreshold: number;\n private readonly resetTimeoutMs: number;\n private readonly failureWindowMs: number;\n private readonly successThreshold: number;\n private readonly isFailure: (error: unknown) => boolean;\n private readonly onStateChange: ((from: CircuitState, to: CircuitState) => void) | undefined;\n\n constructor(config: CircuitBreakerConfig = {}) {\n this.failureThreshold = config.failureThreshold ?? 5;\n this.resetTimeoutMs = config.resetTimeoutMs ?? 30000;\n this.failureWindowMs = config.failureWindowMs ?? 60000;\n this.successThreshold = config.successThreshold ?? 1;\n this.isFailure = config.isFailure ?? defaultIsFailure;\n this.onStateChange = config.onStateChange;\n }\n\n /**\n * Get current circuit state\n */\n getState(): CircuitState {\n this.updateState();\n return this.state;\n }\n\n /**\n * Check if request is allowed\n */\n canExecute(): boolean {\n this.updateState();\n return this.state !== CircuitState.OPEN;\n }\n\n /**\n * Record a successful request\n */\n recordSuccess(): void {\n if (this.state === CircuitState.HALF_OPEN) {\n this.successCount++;\n if (this.successCount >= this.successThreshold) {\n this.transitionTo(CircuitState.CLOSED);\n this.reset();\n }\n } else if (this.state === CircuitState.CLOSED) {\n // Clear old failures on success\n this.cleanupFailures();\n }\n }\n\n /**\n * Record a failed request\n */\n recordFailure(error: unknown): void {\n if (!this.isFailure(error)) {\n return;\n }\n\n const now = Date.now();\n this.failures.push(now);\n this.lastFailureTime = now;\n this.cleanupFailures();\n\n if (this.state === CircuitState.HALF_OPEN) {\n // Failure in half-open state reopens the circuit\n this.transitionTo(CircuitState.OPEN);\n this.successCount = 0;\n } else if (this.state === CircuitState.CLOSED) {\n if (this.failures.length >= this.failureThreshold) {\n this.transitionTo(CircuitState.OPEN);\n }\n }\n }\n\n /**\n * Get remaining time until circuit can transition to half-open\n */\n getRemainingOpenTime(): number {\n if (this.state !== CircuitState.OPEN) {\n return 0;\n }\n const elapsed = Date.now() - this.lastFailureTime;\n return Math.max(0, this.resetTimeoutMs - elapsed);\n }\n\n /**\n * Force reset the circuit breaker\n */\n reset(): void {\n this.failures = [];\n this.successCount = 0;\n this.lastFailureTime = 0;\n if (this.state !== CircuitState.CLOSED) {\n this.transitionTo(CircuitState.CLOSED);\n }\n }\n\n /**\n * Get circuit breaker statistics\n */\n getStats(): {\n state: CircuitState;\n failureCount: number;\n successCount: number;\n remainingOpenTimeMs: number;\n } {\n this.cleanupFailures();\n return {\n state: this.getState(),\n failureCount: this.failures.length,\n successCount: this.successCount,\n remainingOpenTimeMs: this.getRemainingOpenTime(),\n };\n }\n\n private updateState(): void {\n if (this.state === CircuitState.OPEN) {\n const elapsed = Date.now() - this.lastFailureTime;\n if (elapsed >= this.resetTimeoutMs) {\n this.transitionTo(CircuitState.HALF_OPEN);\n this.successCount = 0;\n }\n }\n }\n\n private transitionTo(newState: CircuitState): void {\n if (this.state !== newState) {\n const oldState = this.state;\n this.state = newState;\n this.onStateChange?.(oldState, newState);\n }\n }\n\n private cleanupFailures(): void {\n const cutoff = Date.now() - this.failureWindowMs;\n this.failures = this.failures.filter((t) => t > cutoff);\n }\n}\n\n/**\n * Default failure detection - network errors, server errors, and rate limits\n */\nfunction defaultIsFailure(error: unknown): boolean {\n if (error instanceof NetworkError) {\n return true;\n }\n if (error instanceof ServerError) {\n return true;\n }\n if (error instanceof RateLimitError) {\n return true;\n }\n // Don't count client errors (4xx except 429) as circuit breaker failures\n if (error instanceof ApiError && error.statusCode !== undefined) {\n return error.statusCode >= 500;\n }\n return false;\n}\n\n/**\n * Create a circuit breaker middleware\n *\n * The circuit breaker pattern prevents cascading failures by:\n * 1. Tracking failures within a time window\n * 2. Opening the circuit when failure threshold is reached\n * 3. Failing fast while circuit is open\n * 4. Testing recovery with half-open state\n *\n * @example\n * ```typescript\n * const circuitBreaker = new CircuitBreaker({\n * failureThreshold: 5,\n * resetTimeoutMs: 30000,\n * onStateChange: (from, to) => console.log(`Circuit: ${from} -> ${to}`),\n * });\n *\n * const client = new HttpClient({\n * baseUrl: '...',\n * middleware: [\n * createCircuitBreakerMiddleware(circuitBreaker),\n * ],\n * });\n * ```\n */\nexport function createCircuitBreakerMiddleware(circuitBreaker: CircuitBreaker): Middleware {\n return async (context: MiddlewareContext, next: MiddlewareNext): Promise<HttpResponse> => {\n // Check if circuit allows the request\n if (!circuitBreaker.canExecute()) {\n const remainingMs = circuitBreaker.getRemainingOpenTime();\n context.logger.warn('Circuit breaker open, rejecting request', {\n remainingMs,\n url: context.request.url,\n });\n throw new CircuitBreakerOpenError(\n `Circuit breaker is open. Retry after ${remainingMs}ms`,\n remainingMs\n );\n }\n\n try {\n const response = await next(context);\n circuitBreaker.recordSuccess();\n return response;\n } catch (error) {\n circuitBreaker.recordFailure(error);\n throw error;\n }\n };\n}\n\n/**\n * Create a circuit breaker with default configuration\n */\nexport function createDefaultCircuitBreaker(\n config?: Partial<CircuitBreakerConfig>\n): CircuitBreaker {\n return new CircuitBreaker(config);\n}\n","import type { Middleware } from './types.js';\n\n/**\n * Rate-limit budget advertised by Jira's `Beta-RateLimit-Policy` header.\n */\nexport interface RateLimitPolicy {\n /** Total cost budget for the window. */\n limit: number;\n /** Window length in seconds. */\n windowSeconds: number;\n}\n\n/**\n * A point-in-time read of the rate-limit headers on a single response.\n *\n * Every field is optional: Jira does not send these headers on all endpoints,\n * and the beta headers in particular are only present on APIs enrolled in the\n * cost-based rate-limiting rollout (Atlassian CHANGE-3045).\n */\nexport interface RateLimitSnapshot {\n /** `X-RateLimit-Remaining` — legacy request-count budget. */\n remainingRequests?: number;\n /** `Retry-After` — seconds to wait, present on 429 responses. */\n retryAfterSeconds?: number;\n /** Parsed `Beta-RateLimit-Policy`. */\n policy?: RateLimitPolicy;\n /** Parsed `r=` value from `Beta-RateLimit` — remaining cost points. */\n remainingPoints?: number;\n}\n\n/**\n * Parse the `Beta-RateLimit-Policy` header.\n *\n * Format: `\"100;w=60\"` — a limit followed by `;w=<window seconds>`.\n *\n * @param header Raw header value.\n * @returns The parsed policy, or `undefined` if absent or malformed.\n */\nexport function parseBetaRateLimitPolicy(\n header: string | null | undefined\n): RateLimitPolicy | undefined {\n if (header === null || header === undefined || header === '') {\n return undefined;\n }\n\n const parts = header.split(';');\n const rawLimit = parts[0]?.trim();\n if (rawLimit === undefined || rawLimit === '') {\n return undefined;\n }\n\n const limit = Number.parseInt(rawLimit, 10);\n if (!Number.isFinite(limit)) {\n return undefined;\n }\n\n let windowSeconds = 0;\n for (const part of parts.slice(1)) {\n const [key, value] = part.trim().split('=', 2);\n if (key === 'w' && value !== undefined) {\n const parsed = Number.parseInt(value, 10);\n if (Number.isFinite(parsed)) {\n windowSeconds = parsed;\n }\n }\n }\n\n return { limit, windowSeconds };\n}\n\n/**\n * Parse the `Beta-RateLimit` header.\n *\n * Format: `r=85;policy=\"100;w=60\"` — `r` is the remaining cost points.\n *\n * @param header Raw header value.\n * @returns Remaining points, or `undefined` if absent or malformed.\n */\nexport function parseBetaRateLimit(header: string | null | undefined): number | undefined {\n if (header === null || header === undefined || header === '') {\n return undefined;\n }\n\n for (const part of header.split(';')) {\n const [key, value] = part.trim().split('=', 2);\n if (key === 'r' && value !== undefined) {\n const remaining = Number.parseInt(value, 10);\n if (Number.isFinite(remaining)) {\n return remaining;\n }\n }\n }\n\n return undefined;\n}\n\n/**\n * Parse a `Retry-After` header, which may be either a number of seconds or an\n * HTTP-date.\n *\n * @param header Raw header value.\n * @param now Reference time for HTTP-date values; defaults to the current time.\n * @returns Seconds to wait, or `undefined` if absent or malformed.\n */\nexport function parseRetryAfterSeconds(\n header: string | null | undefined,\n now: number = Date.now()\n): number | undefined {\n if (header === null || header === undefined || header === '') {\n return undefined;\n }\n\n const seconds = Number.parseInt(header.trim(), 10);\n if (Number.isFinite(seconds) && String(seconds) === header.trim()) {\n return Math.max(0, seconds);\n }\n\n const date = Date.parse(header);\n if (Number.isFinite(date)) {\n return Math.max(0, Math.ceil((date - now) / 1000));\n }\n\n return undefined;\n}\n\n/**\n * Read every rate-limit signal Jira exposes from a response's headers.\n *\n * @param headers Response headers.\n * @returns A snapshot with whichever fields were present.\n */\nexport function readRateLimitHeaders(headers: Headers): RateLimitSnapshot {\n const snapshot: RateLimitSnapshot = {};\n\n const remaining = headers.get('x-ratelimit-remaining');\n if (remaining !== null) {\n const parsed = Number.parseInt(remaining, 10);\n if (Number.isFinite(parsed)) {\n snapshot.remainingRequests = parsed;\n }\n }\n\n const retryAfter = parseRetryAfterSeconds(headers.get('retry-after'));\n if (retryAfter !== undefined) {\n snapshot.retryAfterSeconds = retryAfter;\n }\n\n const policy = parseBetaRateLimitPolicy(headers.get('beta-ratelimit-policy'));\n if (policy !== undefined) {\n snapshot.policy = policy;\n }\n\n const points = parseBetaRateLimit(headers.get('beta-ratelimit'));\n if (points !== undefined) {\n snapshot.remainingPoints = points;\n }\n\n return snapshot;\n}\n\n/**\n * Configuration for {@link createRateLimitHeaderMiddleware}.\n */\nexport interface RateLimitHeaderMiddlewareConfig {\n /**\n * Called after every response that carries at least one rate-limit header.\n *\n * Use it to drive adaptive throttling, emit metrics, or warn as the budget\n * runs low. Errors thrown here are swallowed so observability never breaks a\n * request.\n */\n onRateLimit: (snapshot: RateLimitSnapshot) => void;\n}\n\n/**\n * Observe Jira's rate-limit headers on every response.\n *\n * The Go SDK parses these headers and only logs them. This middleware hands\n * them to a callback instead, so a consumer can react — for example by backing\n * off before Jira starts returning 429s.\n *\n * @example\n * ```typescript\n * const client = createJiraClient({\n * host,\n * auth,\n * middleware: [\n * createRateLimitHeaderMiddleware({\n * onRateLimit: (snapshot) => {\n * if (snapshot.remainingPoints !== undefined && snapshot.remainingPoints < 10) {\n * logger.warn('Jira rate-limit budget nearly exhausted', snapshot);\n * }\n * },\n * }),\n * ],\n * });\n * ```\n */\nexport function createRateLimitHeaderMiddleware(\n config: RateLimitHeaderMiddlewareConfig\n): Middleware {\n return async (ctx, next) => {\n const response = await next(ctx);\n\n const snapshot = readRateLimitHeaders(response.headers);\n if (Object.keys(snapshot).length > 0) {\n try {\n config.onRateLimit(snapshot);\n } catch {\n // Observability must never fail a request.\n }\n }\n\n return response;\n };\n}\n"]}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Authentication provider interface
|
|
5
|
+
* All auth providers must implement this interface
|
|
6
|
+
*/
|
|
7
|
+
interface AuthProvider {
|
|
8
|
+
/**
|
|
9
|
+
* Returns the authentication headers to be added to requests
|
|
10
|
+
*/
|
|
11
|
+
getAuthHeaders(): Promise<Record<string, string>> | Record<string, string>;
|
|
12
|
+
/**
|
|
13
|
+
* Returns the auth type identifier
|
|
14
|
+
*/
|
|
15
|
+
readonly type: AuthType;
|
|
16
|
+
/**
|
|
17
|
+
* Optional: Check if the auth is still valid
|
|
18
|
+
*/
|
|
19
|
+
isValid?(): Promise<boolean> | boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Optional: Refresh the authentication (for OAuth2)
|
|
22
|
+
*/
|
|
23
|
+
refresh?(): Promise<void>;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Auth type enum
|
|
27
|
+
*/
|
|
28
|
+
type AuthType = 'api-token' | 'pat' | 'basic' | 'oauth2' | 'none';
|
|
29
|
+
/**
|
|
30
|
+
* API Token auth configuration schema
|
|
31
|
+
*/
|
|
32
|
+
declare const ApiTokenAuthConfigSchema: z.ZodObject<{
|
|
33
|
+
email: z.ZodEmail;
|
|
34
|
+
apiToken: z.ZodString;
|
|
35
|
+
}, z.core.$strip>;
|
|
36
|
+
type ApiTokenAuthConfig = z.infer<typeof ApiTokenAuthConfigSchema>;
|
|
37
|
+
/**
|
|
38
|
+
* Personal Access Token (PAT) auth configuration schema
|
|
39
|
+
*/
|
|
40
|
+
declare const PatAuthConfigSchema: z.ZodObject<{
|
|
41
|
+
token: z.ZodString;
|
|
42
|
+
}, z.core.$strip>;
|
|
43
|
+
type PatAuthConfig = z.infer<typeof PatAuthConfigSchema>;
|
|
44
|
+
/**
|
|
45
|
+
* Basic auth configuration schema
|
|
46
|
+
*/
|
|
47
|
+
declare const BasicAuthConfigSchema: z.ZodObject<{
|
|
48
|
+
username: z.ZodString;
|
|
49
|
+
password: z.ZodString;
|
|
50
|
+
}, z.core.$strip>;
|
|
51
|
+
type BasicAuthConfig = z.infer<typeof BasicAuthConfigSchema>;
|
|
52
|
+
/**
|
|
53
|
+
* OAuth2 auth configuration schema
|
|
54
|
+
*/
|
|
55
|
+
declare const OAuth2AuthConfigSchema: z.ZodObject<{
|
|
56
|
+
clientId: z.ZodString;
|
|
57
|
+
clientSecret: z.ZodString;
|
|
58
|
+
accessToken: z.ZodOptional<z.ZodString>;
|
|
59
|
+
refreshToken: z.ZodOptional<z.ZodString>;
|
|
60
|
+
tokenEndpoint: z.ZodOptional<z.ZodURL>;
|
|
61
|
+
scopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
62
|
+
expiresAt: z.ZodOptional<z.ZodNumber>;
|
|
63
|
+
}, z.core.$strip>;
|
|
64
|
+
type OAuth2AuthConfig = z.infer<typeof OAuth2AuthConfigSchema>;
|
|
65
|
+
/**
|
|
66
|
+
* OAuth2 token response schema
|
|
67
|
+
*/
|
|
68
|
+
declare const OAuth2TokenResponseSchema: z.ZodObject<{
|
|
69
|
+
access_token: z.ZodString;
|
|
70
|
+
token_type: z.ZodString;
|
|
71
|
+
expires_in: z.ZodOptional<z.ZodNumber>;
|
|
72
|
+
refresh_token: z.ZodOptional<z.ZodString>;
|
|
73
|
+
scope: z.ZodOptional<z.ZodString>;
|
|
74
|
+
}, z.core.$strip>;
|
|
75
|
+
type OAuth2TokenResponse = z.infer<typeof OAuth2TokenResponseSchema>;
|
|
76
|
+
/**
|
|
77
|
+
* Union of all auth configs
|
|
78
|
+
*/
|
|
79
|
+
type AuthConfig = {
|
|
80
|
+
type: 'api-token';
|
|
81
|
+
config: ApiTokenAuthConfig;
|
|
82
|
+
} | {
|
|
83
|
+
type: 'pat';
|
|
84
|
+
config: PatAuthConfig;
|
|
85
|
+
} | {
|
|
86
|
+
type: 'basic';
|
|
87
|
+
config: BasicAuthConfig;
|
|
88
|
+
} | {
|
|
89
|
+
type: 'oauth2';
|
|
90
|
+
config: OAuth2AuthConfig;
|
|
91
|
+
} | {
|
|
92
|
+
type: 'none';
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export { type AuthProvider as A, type BasicAuthConfig as B, type OAuth2AuthConfig as O, type PatAuthConfig as P, type ApiTokenAuthConfig as a, ApiTokenAuthConfigSchema as b, type AuthConfig as c, type AuthType as d, BasicAuthConfigSchema as e, OAuth2AuthConfigSchema as f, type OAuth2TokenResponse as g, OAuth2TokenResponseSchema as h, PatAuthConfigSchema as i };
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Authentication provider interface
|
|
5
|
+
* All auth providers must implement this interface
|
|
6
|
+
*/
|
|
7
|
+
interface AuthProvider {
|
|
8
|
+
/**
|
|
9
|
+
* Returns the authentication headers to be added to requests
|
|
10
|
+
*/
|
|
11
|
+
getAuthHeaders(): Promise<Record<string, string>> | Record<string, string>;
|
|
12
|
+
/**
|
|
13
|
+
* Returns the auth type identifier
|
|
14
|
+
*/
|
|
15
|
+
readonly type: AuthType;
|
|
16
|
+
/**
|
|
17
|
+
* Optional: Check if the auth is still valid
|
|
18
|
+
*/
|
|
19
|
+
isValid?(): Promise<boolean> | boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Optional: Refresh the authentication (for OAuth2)
|
|
22
|
+
*/
|
|
23
|
+
refresh?(): Promise<void>;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Auth type enum
|
|
27
|
+
*/
|
|
28
|
+
type AuthType = 'api-token' | 'pat' | 'basic' | 'oauth2' | 'none';
|
|
29
|
+
/**
|
|
30
|
+
* API Token auth configuration schema
|
|
31
|
+
*/
|
|
32
|
+
declare const ApiTokenAuthConfigSchema: z.ZodObject<{
|
|
33
|
+
email: z.ZodEmail;
|
|
34
|
+
apiToken: z.ZodString;
|
|
35
|
+
}, z.core.$strip>;
|
|
36
|
+
type ApiTokenAuthConfig = z.infer<typeof ApiTokenAuthConfigSchema>;
|
|
37
|
+
/**
|
|
38
|
+
* Personal Access Token (PAT) auth configuration schema
|
|
39
|
+
*/
|
|
40
|
+
declare const PatAuthConfigSchema: z.ZodObject<{
|
|
41
|
+
token: z.ZodString;
|
|
42
|
+
}, z.core.$strip>;
|
|
43
|
+
type PatAuthConfig = z.infer<typeof PatAuthConfigSchema>;
|
|
44
|
+
/**
|
|
45
|
+
* Basic auth configuration schema
|
|
46
|
+
*/
|
|
47
|
+
declare const BasicAuthConfigSchema: z.ZodObject<{
|
|
48
|
+
username: z.ZodString;
|
|
49
|
+
password: z.ZodString;
|
|
50
|
+
}, z.core.$strip>;
|
|
51
|
+
type BasicAuthConfig = z.infer<typeof BasicAuthConfigSchema>;
|
|
52
|
+
/**
|
|
53
|
+
* OAuth2 auth configuration schema
|
|
54
|
+
*/
|
|
55
|
+
declare const OAuth2AuthConfigSchema: z.ZodObject<{
|
|
56
|
+
clientId: z.ZodString;
|
|
57
|
+
clientSecret: z.ZodString;
|
|
58
|
+
accessToken: z.ZodOptional<z.ZodString>;
|
|
59
|
+
refreshToken: z.ZodOptional<z.ZodString>;
|
|
60
|
+
tokenEndpoint: z.ZodOptional<z.ZodURL>;
|
|
61
|
+
scopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
62
|
+
expiresAt: z.ZodOptional<z.ZodNumber>;
|
|
63
|
+
}, z.core.$strip>;
|
|
64
|
+
type OAuth2AuthConfig = z.infer<typeof OAuth2AuthConfigSchema>;
|
|
65
|
+
/**
|
|
66
|
+
* OAuth2 token response schema
|
|
67
|
+
*/
|
|
68
|
+
declare const OAuth2TokenResponseSchema: z.ZodObject<{
|
|
69
|
+
access_token: z.ZodString;
|
|
70
|
+
token_type: z.ZodString;
|
|
71
|
+
expires_in: z.ZodOptional<z.ZodNumber>;
|
|
72
|
+
refresh_token: z.ZodOptional<z.ZodString>;
|
|
73
|
+
scope: z.ZodOptional<z.ZodString>;
|
|
74
|
+
}, z.core.$strip>;
|
|
75
|
+
type OAuth2TokenResponse = z.infer<typeof OAuth2TokenResponseSchema>;
|
|
76
|
+
/**
|
|
77
|
+
* Union of all auth configs
|
|
78
|
+
*/
|
|
79
|
+
type AuthConfig = {
|
|
80
|
+
type: 'api-token';
|
|
81
|
+
config: ApiTokenAuthConfig;
|
|
82
|
+
} | {
|
|
83
|
+
type: 'pat';
|
|
84
|
+
config: PatAuthConfig;
|
|
85
|
+
} | {
|
|
86
|
+
type: 'basic';
|
|
87
|
+
config: BasicAuthConfig;
|
|
88
|
+
} | {
|
|
89
|
+
type: 'oauth2';
|
|
90
|
+
config: OAuth2AuthConfig;
|
|
91
|
+
} | {
|
|
92
|
+
type: 'none';
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export { type AuthProvider as A, type BasicAuthConfig as B, type OAuth2AuthConfig as O, type PatAuthConfig as P, type ApiTokenAuthConfig as a, ApiTokenAuthConfigSchema as b, type AuthConfig as c, type AuthType as d, BasicAuthConfigSchema as e, OAuth2AuthConfigSchema as f, type OAuth2TokenResponse as g, OAuth2TokenResponseSchema as h, PatAuthConfigSchema as i };
|