UNPKG

@redocly/cli

Version:

[@Redocly](https://redocly.com) CLI is your all-in-one OpenAPI utility. It builds, manages, improves, and quality-checks your OpenAPI descriptions, all of which comes in handy for various phases of the API Lifecycle. Create your own rulesets to make API g

142 lines 5.91 kB
import * as os from 'node:os'; import * as fs from 'node:fs'; import { execSync } from 'node:child_process'; import { isAbsoluteUrl } from '@redocly/openapi-core'; import { version } from './package.js'; import { getReuniteUrl } from '../reunite/api/index.js'; import { respondWithinMs } from './network-check.js'; export async function sendTelemetry({ config, argv, exit_code, spec_version, spec_keyword, spec_full_version, respect_x_security_auth_types, }) { try { if (!argv) { return; } const hasInternet = await respondWithinMs(1000); if (!hasInternet) { return; } const { _: [command], $0: _, ...args } = argv; const event_time = new Date().toISOString(); const residency = args.residency || config?.resolvedConfig?.residency; const { RedoclyOAuthClient } = await import('../auth/oauth-client.js'); const oauthClient = new RedoclyOAuthClient('redocly-cli', version); const reuniteUrl = getReuniteUrl(residency); const logged_in = await oauthClient.isAuthorized(reuniteUrl); const data = { event: 'cli_command', event_time, logged_in: logged_in ? 'yes' : 'no', command: `${command}`, ...cleanArgs(args, process.argv.slice(2)), node_version: process.version, npm_version: execSync('npm -v').toString().replace('\n', ''), os_platform: os.platform(), version, exit_code, environment: process.env.REDOCLY_ENVIRONMENT, metadata: process.env.REDOCLY_CLI_TELEMETRY_METADATA, environment_ci: process.env.CI, has_config: typeof config?.document?.parsed === 'undefined' ? 'no' : 'yes', spec_version, spec_keyword, spec_full_version, respect_x_security_auth_types: spec_version === 'arazzo1' && respect_x_security_auth_types?.length ? JSON.stringify(respect_x_security_auth_types) : undefined, }; const { otelTelemetry } = await import('./otel.js'); otelTelemetry.send(data.command, data); } catch (err) { // Do nothing. } } export function collectXSecurityAuthTypes(document, respectXSecurityAuthTypesAndSchemeName) { for (const workflow of document.workflows ?? []) { // Collect auth types from workflow-level x-security for (const security of workflow['x-security'] ?? []) { const scheme = security.scheme; if (scheme?.type) { const authType = scheme.type === 'http' ? scheme.scheme : scheme.type; if (authType && !respectXSecurityAuthTypesAndSchemeName.includes(authType)) { respectXSecurityAuthTypesAndSchemeName.push(authType); } } } // Collect auth types from step-level x-security for (const step of workflow.steps ?? []) { for (const security of step['x-security'] ?? []) { // Handle scheme case const scheme = security.scheme; if (scheme?.type) { const authType = scheme.type === 'http' ? scheme.scheme : scheme.type; if (authType && !respectXSecurityAuthTypesAndSchemeName.includes(authType)) { respectXSecurityAuthTypesAndSchemeName.push(authType); } } // Handle schemeName case const schemeName = security.schemeName; if (schemeName && !respectXSecurityAuthTypesAndSchemeName.includes(schemeName)) { respectXSecurityAuthTypesAndSchemeName.push(schemeName); } } } } } function isFile(value) { return fs.existsSync(value) && fs.statSync(value).isFile(); } function isDirectory(value) { return fs.existsSync(value) && fs.statSync(value).isDirectory(); } function cleanString(value) { if (!value) { return value; } if (isAbsoluteUrl(value)) { return value.split('://')[0] + '://url'; } if (isFile(value)) { return value.replace(/.+\.([^.]+)$/, (_, ext) => 'file-' + ext); } if (isDirectory(value)) { return 'folder'; } return value; } function replaceArgs(commandInput, targets, replacement) { const targetValues = Array.isArray(targets) ? targets : [targets]; for (const target of targetValues) { commandInput = commandInput.replaceAll(target, replacement); } return commandInput; } export function cleanArgs(parsedArgs, rawArgv) { const KEYS_TO_CLEAN = ['organization', 'o', 'input', 'i', 'client-cert', 'client-key', 'ca-cert']; let commandInput = rawArgv.join(' '); const commandArguments = {}; for (const [key, value] of Object.entries(parsedArgs)) { if (KEYS_TO_CLEAN.includes(key)) { commandArguments[key] = '***'; commandInput = replaceArgs(commandInput, value, '***'); } else if (typeof value === 'string') { const cleanedValue = cleanString(value); commandArguments[key] = cleanedValue; commandInput = replaceArgs(commandInput, value, cleanedValue); } else if (Array.isArray(value)) { commandArguments[key] = value.map(cleanString); for (const replacedValue of value) { const newValue = cleanString(replacedValue); if (commandInput.includes(replacedValue)) { commandInput = commandInput.replaceAll(replacedValue, newValue); } } } else { commandArguments[key] = value; } } return { arguments: JSON.stringify(commandArguments), raw_input: commandInput }; } //# sourceMappingURL=telemetry.js.map