diff --git a/react-native-libraries.json b/react-native-libraries.json index 6a9e121de..4673de92c 100644 --- a/react-native-libraries.json +++ b/react-native-libraries.json @@ -10791,7 +10791,7 @@ }, { "githubUrl": "https://github.com/Richou/react-native-android-location-enabler", - "example": [ + "examples": [ "https://github.com/Richou/react-native-android-location-enabler/tree/main/example" ], "images": [ @@ -13729,7 +13729,7 @@ "examples": ["https://github.com/liveakshay/expo-spellchecker/tree/main/example"], "ios": true, "android": true, - "expo": true, + "expoGo": true, "newArchitecture": true }, { @@ -13750,7 +13750,7 @@ "ios": true, "android": true, "web": true, - "expo": true, + "expoGo": true, "newArchitecture": true }, { @@ -13762,7 +13762,7 @@ "ios": true, "android": true, "web": true, - "expo": true, + "expoGo": true, "newArchitecture": true, "fireos": true }, @@ -13772,7 +13772,7 @@ "ios": true, "android": true, "web": true, - "expo": true, + "expoGo": true, "newArchitecture": true, "fireos": true }, @@ -13781,7 +13781,7 @@ "ios": true, "android": true, "web": true, - "expo": true, + "expoGo": true, "newArchitecture": true, "fireos": true }, @@ -13791,7 +13791,7 @@ "android": true, "web": true, "fireos": true, - "expo": true, + "expoGo": true, "newArchitecture": true }, { @@ -13800,7 +13800,7 @@ "ios": true, "android": true, "web": true, - "expo": true, + "expoGo": true, "newArchitecture": true }, { @@ -13809,7 +13809,7 @@ "ios": true, "android": true, "web": true, - "expo": true + "expoGo": true }, { "githubUrl": "https://github.com/FortAwesome/Font-Awesome/tree/6.x/js-packages/@fortawesome/free-regular-svg-icons", @@ -13817,7 +13817,7 @@ "ios": true, "android": true, "web": true, - "expo": true + "expoGo": true }, { "githubUrl": "https://github.com/FortAwesome/Font-Awesome/tree/6.x/js-packages/@fortawesome/free-solid-svg-icons", @@ -13825,20 +13825,20 @@ "ios": true, "android": true, "web": true, - "expo": true + "expoGo": true }, { "githubUrl": "https://github.com/FilipiRafael/react-native-motion-tabs", "ios": true, "android": true, - "expo": true, + "expoGo": true, "newArchitecture": true }, { "githubUrl": "https://github.com/vantuan88291/react-native-ota-hot-update", "ios": true, "android": true, - "expo": true, + "expoGo": true, "newArchitecture": true, "configPlugin": true }, @@ -17428,7 +17428,7 @@ { "githubUrl": "https://github.com/avas-app/react-native-android-otp-autofill", "npmPkg": "@avasapp/react-native-otp-autofill", - "example": ["https://github.com/avas-app/react-native-android-otp-autofill/tree/main/example"], + "examples": ["https://github.com/avas-app/react-native-android-otp-autofill/tree/main/example"], "ios": true, "android": true, "newArchitecture": true, @@ -17732,20 +17732,16 @@ }, { "githubUrl": "https://github.com/orcunorcun/react-native-cookie-handler", - "npmPkg": "react-native-cookie-handler", - "examples": [ - "https://github.com/orcunorcun/react-native-cookie-handler/tree/master/example" - ], + "examples": ["https://github.com/orcunorcun/react-native-cookie-handler/tree/master/example"], "ios": true, "android": true }, { "githubUrl": "https://github.com/mCodex/react-native-nitro-sfsymbols", - "npmPkg": "react-native-nitro-sfsymbols", - "examples": [ - "https://github.com/mCodex/react-native-nitro-sfsymbols/tree/main/example" + "examples": ["https://github.com/mCodex/react-native-nitro-sfsymbols/tree/main/example"], + "images": [ + "https://raw.githubusercontent.com/mCodex/react-native-nitro-sfsymbols/refs/heads/main/example.gif" ], - "images": ["https://raw.githubusercontent.com/mCodex/react-native-nitro-sfsymbols/refs/heads/main/example.gif"], "ios": true, "macos": true, "tvos": true, @@ -17754,16 +17750,20 @@ }, { "githubUrl": "https://github.com/sbaiahmed1/react-native-menus", - "npmPkg": "react-native-menus", - "examples": [ - "https://github.com/sbaiahmed1/react-native-menus/tree/main/example" - ], + "examples": ["https://github.com/sbaiahmed1/react-native-menus/tree/main/example"], "images": [ "https://raw.githubusercontent.com/sbaiahmed1/react-native-menus/refs/heads/main/android-image.png", "https://raw.githubusercontent.com/sbaiahmed1/react-native-menus/refs/heads/main/ios-image.png" ], "ios": true, - "expo": true, + "android": true, + "newArchitecture": true, + "expoGo": true + }, + { + "githubUrl": "https://github.com/software-mansion-labs/react-native-shine", + "examples": ["https://github.com/software-mansion-labs/react-native-shine/tree/main/example"], + "ios": true, "android": true, "newArchitecture": true, "expoGo": true diff --git a/scripts/cleanup-libraries-json.ts b/scripts/cleanup-libraries-json.ts index 73426d56c..905742586 100644 --- a/scripts/cleanup-libraries-json.ts +++ b/scripts/cleanup-libraries-json.ts @@ -4,6 +4,7 @@ import path from 'node:path'; import libraries from '~/react-native-libraries.json'; import { type LibraryDataEntryType } from '~/types'; +import { VALID_ENTRY_KEYS } from '~/util/Constants'; const LIBRARIES_JSON_PATH = path.join('react-native-libraries.json'); @@ -14,6 +15,16 @@ function removeEmptyArray(lib: LibraryDataEntryType, key: 'examples' | 'images') } const processedLibraries = libraries + // Remove invalid keys in entry + .map(lib => { + const invalidKeys = Object.keys(lib).filter(key => !VALID_ENTRY_KEYS.has(key)); + + if (invalidKeys.length > 0) { + return omit(lib, invalidKeys); + } + + return lib; + }) // Remove redundant `npmPkg` for libraries with the correct GitHub repository name .map((lib: LibraryDataEntryType) => lib.npmPkg && !lib.npmPkg.includes('/') && lib.githubUrl.endsWith(`/${lib.npmPkg}`) diff --git a/scripts/validate-libraries.ts b/scripts/validate-libraries.ts index d3e2aaf5c..a0b43f112 100644 --- a/scripts/validate-libraries.ts +++ b/scripts/validate-libraries.ts @@ -1,4 +1,6 @@ +import { fillNpmName } from '~/scripts/helpers'; import { type LibraryType } from '~/types'; +import { VALID_ENTRY_KEYS } from '~/util/Constants'; import libraries from '../react-native-libraries.json'; @@ -11,19 +13,28 @@ function validateLibrariesFormat(libraries: LibraryType[]) { const errorsList = libraries.reduce>((errors, library, index) => { const libraryErrors = []; const libraryProperties = Object.keys(library); + const libraryWithNpmName = fillNpmName(library); // Check that it has the githubUrl property and that it is in the correct format if (!libraryProperties.includes('githubUrl')) { - libraryErrors.push('Must contain a githubUrl property'); + libraryErrors.push(`- Must contain a 'githubUrl' property`); } else if (!library.githubUrl.match(GITHUB_URL_PATTERN)) { libraryErrors.push( - `The githubUrl of ${library.githubUrl} must be in the format:\nhttps://github.com/owner/repo-name or https://github.com/owner/repo-name/tree/default-branch/name for monorepos` + `- The 'githubUrl' of ${library.githubUrl} must be in the format:\nhttps://github.com/owner/repo-name or https://github.com/owner/repo-name/tree/default-branch/name for monorepos` ); } + const invalidKeys = libraryProperties.filter(key => !VALID_ENTRY_KEYS.has(key)); + + if (invalidKeys.length > 0) { + invalidKeys.forEach(key => { + libraryErrors.push(`- Uses invalid key - ${key}`); + }); + } + // If there were errors, add them to the object if (libraryErrors.length > 0) { - errors[index] = libraryErrors; + errors[libraryWithNpmName.npmPkg] = libraryErrors; } return errors; @@ -31,7 +42,8 @@ function validateLibrariesFormat(libraries: LibraryType[]) { if (Object.keys(errorsList).length > 0) { const errorDescriptions = Object.entries(errorsList).map( - ([index, libraryErrors]) => `Library at index ${index}:\n${libraryErrors.join('\n')}` + ([npmPkg, libraryErrors], index) => + `Library entry for '${npmPkg}' contains errors:\n${libraryErrors.join('\n')}` ); console.error('āŒ Malformed libraries found:\n' + errorDescriptions.join('\n')); process.exit(1); diff --git a/scripts/validate-new-entries.ts b/scripts/validate-new-entries.ts index cfbd30e0c..f99c5470d 100644 --- a/scripts/validate-new-entries.ts +++ b/scripts/validate-new-entries.ts @@ -1,6 +1,8 @@ import { fetch } from 'bun'; import { differenceWith, isEqual } from 'es-toolkit'; +import { VALID_ENTRY_KEYS } from '~/util/Constants'; + import { fetchGithubData } from './fetch-github-data'; import { fetchNpmDownloadData } from './fetch-npm-download-data'; import { fillNpmName, hasMismatchedPackageData } from './helpers'; @@ -20,7 +22,7 @@ if (libraries.length === mainData.length) { process.exit(0); } -console.log('šŸ”ļø Detected changes in data entries, checking!'); +console.log('šŸš©ļø Detected changes in data entries, checking!'); const modifiedEntries = differenceWith(libraries, mainData, isEqual); @@ -80,6 +82,16 @@ const checkResults = await Promise.all( return false; } + + const invalidKeys = Object.keys(entry).filter(key => !VALID_ENTRY_KEYS.has(key)); + + if (invalidKeys.length > 0) { + console.error( + `Package entry for '${entryWithGitHubData.npmPkg}' contains invalid fields: ${invalidKeys.map(key => `'${key}'`).join(', ')}. Correct or remove the listed keys to fix the definition.` + ); + return false; + } + return true; }) ); @@ -88,4 +100,5 @@ if (checkResults.filter(result => !result).length > 0) { console.error('\nāŒ There were errors spotted during new entries check!'); process.exit(1); } + console.log('āœ… All checks have passed!'); diff --git a/util/Constants.ts b/util/Constants.ts index 34ded04e0..e5bd8bec2 100644 --- a/util/Constants.ts +++ b/util/Constants.ts @@ -1 +1,24 @@ export const NUM_PER_PAGE = 30; + +export const VALID_ENTRY_KEYS = new Set([ + 'githubUrl', + 'ios', + 'android', + 'web', + 'expoGo', + 'windows', + 'macos', + 'fireos', + 'tvos', + 'visionos', + 'unmaintained', + 'dev', + 'template', + 'newArchitecture', + 'newArchitectureNote', + 'configPlugin', + 'alternatives', + 'npmPkg', + 'examples', + 'images', +]);