From 624d03b95cebfab16dc836322d49f24b285deb63 Mon Sep 17 00:00:00 2001 From: Daniel Ayala <14967941+danielayala94@users.noreply.github.com> Date: Wed, 8 Jan 2025 15:09:42 -0800 Subject: [PATCH 1/2] [Telemetry] Address package name limitations - Take 2 (#14259) * Introducing package name processing * Add trimming if string length > 100 * Change files --- ...-f67eede7-8e2c-46b7-9ce9-5d664dfcd76e.json | 7 +++ .../telemetry/src/telemetry.ts | 10 ++- .../telemetry/src/test/nameUtils.test.ts | 62 +++++++++++++++++++ .../telemetry/src/utils/nameUtils.ts | 18 ++++++ 4 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 change/@react-native-windows-telemetry-f67eede7-8e2c-46b7-9ce9-5d664dfcd76e.json create mode 100644 packages/@react-native-windows/telemetry/src/test/nameUtils.test.ts create mode 100644 packages/@react-native-windows/telemetry/src/utils/nameUtils.ts diff --git a/change/@react-native-windows-telemetry-f67eede7-8e2c-46b7-9ce9-5d664dfcd76e.json b/change/@react-native-windows-telemetry-f67eede7-8e2c-46b7-9ce9-5d664dfcd76e.json new file mode 100644 index 00000000000..bb7d5e44ef6 --- /dev/null +++ b/change/@react-native-windows-telemetry-f67eede7-8e2c-46b7-9ce9-5d664dfcd76e.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "Address package name limitations for telemetry", + "packageName": "@react-native-windows/telemetry", + "email": "14967941+danielayala94@users.noreply.github.com", + "dependentChangeType": "patch" +} diff --git a/packages/@react-native-windows/telemetry/src/telemetry.ts b/packages/@react-native-windows/telemetry/src/telemetry.ts index 00303817482..eb51e9e8cec 100644 --- a/packages/@react-native-windows/telemetry/src/telemetry.ts +++ b/packages/@react-native-windows/telemetry/src/telemetry.ts @@ -11,6 +11,7 @@ import * as basePropUtils from './utils/basePropUtils'; import * as versionUtils from './utils/versionUtils'; import * as errorUtils from './utils/errorUtils'; import * as projectUtils from './utils/projectUtils'; +import * as nameUtils from './utils/nameUtils'; export interface TelemetryOptions { setupString: string; @@ -246,10 +247,15 @@ export class Telemetry { return true; } - if (forceRefresh === true || !Telemetry.versionsProp[name]) { + // Process the package name to comply with the backend requirements + const packageName = nameUtils.isValidTelemetryPackageName(name) + ? name + : nameUtils.cleanTelemetryPackageName(name); + + if (forceRefresh === true || !Telemetry.versionsProp[packageName]) { const value = await getValue(); if (value) { - Telemetry.versionsProp[name] = value; + Telemetry.versionsProp[packageName] = value; return true; } } diff --git a/packages/@react-native-windows/telemetry/src/test/nameUtils.test.ts b/packages/@react-native-windows/telemetry/src/test/nameUtils.test.ts new file mode 100644 index 00000000000..e5c3cf49789 --- /dev/null +++ b/packages/@react-native-windows/telemetry/src/test/nameUtils.test.ts @@ -0,0 +1,62 @@ +/** + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT License. + * + * @format + */ + +import * as nameUtils from '../utils/nameUtils'; + +test('Verify telemetry package name is valid', () => { + expect(nameUtils.isValidTelemetryPackageName('package')).toBe(true); + expect(nameUtils.isValidTelemetryPackageName('@react')).toBe(false); + expect(nameUtils.isValidTelemetryPackageName('react-native')).toBe(false); + expect(nameUtils.isValidTelemetryPackageName('react_native')).toBe(true); + expect(nameUtils.isValidTelemetryPackageName('react_native/cli')).toBe(false); + + // Check for size limits. A valid package name has 100 characters or less. + expect( + nameUtils.isValidTelemetryPackageName( + 'react_native_react_native_react_native_react_native_react_native_react_native_react_native_react_nat', + ), + ).toBe(true); + expect( + nameUtils.isValidTelemetryPackageName( + 'react_native_react_native_react_native_react_native_react_native_react_native_react_native_react_nati', + ), + ).toBe(false); +}); + +test('Verify telemetry package name cleaning', () => { + expect(nameUtils.cleanTelemetryPackageName('package')).toBe('package'); + expect(nameUtils.cleanTelemetryPackageName('@react')).toBe('_react'); + expect(nameUtils.cleanTelemetryPackageName('react-native')).toBe( + 'react_native', + ); + expect(nameUtils.cleanTelemetryPackageName('react_native')).toBe( + 'react_native', + ); + expect(nameUtils.cleanTelemetryPackageName('react_native/cli')).toBe( + 'react_native_cli', + ); + expect(nameUtils.cleanTelemetryPackageName('@react-native-windows/cli')).toBe( + '_react_native_windows_cli', + ); + + expect( + nameUtils.cleanTelemetryPackageName( + 'react_native_react_native_react_native_react_native_react_native_react_native_react_native_react_nat', + ), + ).toBe( + 'react_native_react_native_react_native_react_native_react_native_react_native_react_native_react_nat', + ); + + // Truncate a package name with 101 characters, to the first 100. + expect( + nameUtils.cleanTelemetryPackageName( + 'react_native_react_native_react_native_react_native_react_native_react_native_react_native_react_nati', + ), + ).toBe( + 'react_native_react_native_react_native_react_native_react_native_react_native_react_native_react_nat', + ); +}); diff --git a/packages/@react-native-windows/telemetry/src/utils/nameUtils.ts b/packages/@react-native-windows/telemetry/src/utils/nameUtils.ts new file mode 100644 index 00000000000..31c5c563ce1 --- /dev/null +++ b/packages/@react-native-windows/telemetry/src/utils/nameUtils.ts @@ -0,0 +1,18 @@ +/** + * Copyright (c) Microsoft Corporation. + * Licensed under the MIT License. + * @format + */ + +export function isValidTelemetryPackageName(name: string): boolean { + // Accepted characters: alphanumeric, underscore, dot, starts with letter. + // Size: 1-100 characters. + if (name.match(/^[a-zA-Z][a-zA-Z0-9_.]{0,99}$/gi)) { + return true; + } + return false; +} + +export function cleanTelemetryPackageName(str: string): string { + return str.replace(/[^a-zA-Z0-9_.]/g, '_').slice(0, 100); +} From 7e74474f5c5c427d74f53ed6bdb332788f50391d Mon Sep 17 00:00:00 2001 From: Daniel Ayala <14967941+danielayala94@users.noreply.github.com> Date: Wed, 8 Jan 2025 15:41:21 -0800 Subject: [PATCH 2/2] Change files --- ...windows-telemetry-6c5902e1-6010-4dc5-b994-e44525a9aca1.json} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename change/{@react-native-windows-telemetry-f67eede7-8e2c-46b7-9ce9-5d664dfcd76e.json => @react-native-windows-telemetry-6c5902e1-6010-4dc5-b994-e44525a9aca1.json} (89%) diff --git a/change/@react-native-windows-telemetry-f67eede7-8e2c-46b7-9ce9-5d664dfcd76e.json b/change/@react-native-windows-telemetry-6c5902e1-6010-4dc5-b994-e44525a9aca1.json similarity index 89% rename from change/@react-native-windows-telemetry-f67eede7-8e2c-46b7-9ce9-5d664dfcd76e.json rename to change/@react-native-windows-telemetry-6c5902e1-6010-4dc5-b994-e44525a9aca1.json index bb7d5e44ef6..64d738e852f 100644 --- a/change/@react-native-windows-telemetry-f67eede7-8e2c-46b7-9ce9-5d664dfcd76e.json +++ b/change/@react-native-windows-telemetry-6c5902e1-6010-4dc5-b994-e44525a9aca1.json @@ -1,5 +1,5 @@ { - "type": "prerelease", + "type": "patch", "comment": "Address package name limitations for telemetry", "packageName": "@react-native-windows/telemetry", "email": "14967941+danielayala94@users.noreply.github.com",