Skip to content

Commit 7d9083f

Browse files
feat: add expanded version of spec version in telemetry
1 parent 1850867 commit 7d9083f

File tree

3 files changed

+101
-4
lines changed

3 files changed

+101
-4
lines changed

packages/cli/src/__tests__/utils/telemetry.test.ts

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { collectXSecurityAuthTypes } from '../../utils/telemetry.js';
1+
import { collectXSecurityAuthTypes, transformSpecVersionError } from '../../utils/telemetry.js';
22

33
import type { ArazzoDefinition } from '@redocly/openapi-core';
44

@@ -87,3 +87,57 @@ describe('collectXSecurityAuthTypes', () => {
8787
]);
8888
});
8989
});
90+
91+
describe('transformSpecVersionError', () => {
92+
it('should transform "Unsupported specification" error', () => {
93+
const result = transformSpecVersionError('Unsupported specification');
94+
expect(result).toBe('unsupported');
95+
});
96+
97+
it('should transform AsyncAPI version errors', () => {
98+
const result1 = transformSpecVersionError('Unsupported AsyncAPI version: 2.1.1');
99+
expect(result1).toBe('unsupported-async-2.1.1');
100+
101+
const result2 = transformSpecVersionError('Unsupported AsyncAPI version: 1.2.0');
102+
expect(result2).toBe('unsupported-async-1.2.0');
103+
});
104+
105+
it('should transform OpenAPI version errors', () => {
106+
const result1 = transformSpecVersionError('Unsupported OpenAPI version: 3.2.0');
107+
expect(result1).toBe('unsupported-openapi-3.2.0');
108+
109+
const result2 = transformSpecVersionError('Unsupported OpenAPI version: 2.1');
110+
expect(result2).toBe('unsupported-openapi-2.1');
111+
});
112+
113+
it('should handle generic unsupported version errors', () => {
114+
const result = transformSpecVersionError('Unsupported Some API version: 1.0');
115+
expect(result).toBe('unsupported');
116+
});
117+
118+
it('should transform invalid document errors', () => {
119+
const result = transformSpecVersionError('Document must be JSON object, got string');
120+
expect(result).toBe('unknown');
121+
});
122+
123+
it('should transform invalid OpenAPI version format errors', () => {
124+
const result = transformSpecVersionError(
125+
'Invalid OpenAPI version: should be a string but got "number"'
126+
);
127+
expect(result).toBe('invalid-openapi-version');
128+
});
129+
130+
it('should return "unknown" for empty or invalid input', () => {
131+
expect(transformSpecVersionError('')).toBe('unknown');
132+
expect(transformSpecVersionError(null as any)).toBe('unknown');
133+
expect(transformSpecVersionError(undefined as any)).toBe('unknown');
134+
});
135+
136+
it('should be case insensitive', () => {
137+
const result1 = transformSpecVersionError('UNSUPPORTED SPECIFICATION');
138+
expect(result1).toBe('unsupported');
139+
140+
const result2 = transformSpecVersionError('unsupported asyncapi version: 2.1.1');
141+
expect(result2).toBe('unsupported-async-2.1.1');
142+
});
143+
});

packages/cli/src/utils/telemetry.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,42 @@ export async function sendTelemetry({
102102
}
103103
}
104104

105+
export function transformSpecVersionError(errorMessage: string): string {
106+
if (!errorMessage || typeof errorMessage !== 'string') {
107+
return 'unknown';
108+
}
109+
110+
const lowerMessage = errorMessage.toLowerCase();
111+
112+
if (lowerMessage.includes('invalid openapi version')) {
113+
return 'invalid-openapi-version';
114+
}
115+
116+
if (
117+
(lowerMessage.includes('unsupported') && lowerMessage.includes('version')) ||
118+
lowerMessage.includes('specification')
119+
) {
120+
const extractUnsupportedVersion = (apiType: string, prefix: string) => {
121+
const match = errorMessage.match(new RegExp(`Unsupported ${apiType} version:\\s*(.+)`, 'i'));
122+
if (match && match[1]) {
123+
const version = match[1].trim();
124+
return `unsupported-${prefix}-${version}`;
125+
}
126+
return null;
127+
};
128+
129+
const asyncApiResult = extractUnsupportedVersion('AsyncAPI', 'async');
130+
if (asyncApiResult) return asyncApiResult;
131+
132+
const openApiResult = extractUnsupportedVersion('OpenAPI', 'openapi');
133+
if (openApiResult) return openApiResult;
134+
135+
return 'unsupported';
136+
}
137+
138+
return 'unknown';
139+
}
140+
105141
export function collectXSecurityAuthTypes(
106142
document: Partial<ArazzoDefinition>,
107143
respectXSecurityAuthTypesAndSchemeName: string[]

packages/cli/src/wrapper.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@ import {
77
} from '@redocly/openapi-core';
88
import { version } from './utils/package.js';
99
import { loadConfigAndHandleErrors } from './utils/miscellaneous.js';
10-
import { sendTelemetry, collectXSecurityAuthTypes } from './utils/telemetry.js';
10+
import {
11+
sendTelemetry,
12+
collectXSecurityAuthTypes,
13+
transformSpecVersionError,
14+
} from './utils/telemetry.js';
1115
import { AbortFlowError, exitWithError } from './utils/error.js';
1216

1317
import type { Arguments } from 'yargs';
@@ -34,7 +38,11 @@ export function commandWrapper<T extends CommandArgv>(
3438
let config: Config | undefined;
3539
const respectXSecurityAuthTypes: string[] = [];
3640
const collectSpecData: CollectFn = (document) => {
37-
specVersion = detectSpec(document);
41+
try {
42+
specVersion = detectSpec(document);
43+
} catch (err) {
44+
specVersion = transformSpecVersionError(err.message);
45+
}
3846
if (!isPlainObject(document)) return;
3947
specKeyword = document?.openapi
4048
? 'openapi'
@@ -71,7 +79,6 @@ export function commandWrapper<T extends CommandArgv>(
7179
if (err instanceof AbortFlowError) {
7280
// do nothing
7381
} else if (err instanceof HandledError) {
74-
if (err.message.includes('Unsupported specification')) specVersion = 'undefined';
7582
logger.error(err.message + '\n\n');
7683
} else {
7784
logger.error(

0 commit comments

Comments
 (0)