Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: mfsdk #699

Merged
merged 15 commits into from
Dec 19, 2024
Merged

feat: mfsdk #699

merged 15 commits into from
Dec 19, 2024

Conversation

lovegaoshi
Copy link
Owner

@lovegaoshi lovegaoshi commented Dec 19, 2024

Summary by CodeRabbit

  • New Features

    • Introduced a search functionality for music and albums through a new module.
    • Added a Music Free button in the developer settings for easy access to the Music Free feature.
    • Implemented a new Skin Searchbar component for loading custom skins.
    • Added a developer settings interface with navigation capabilities.
  • Bug Fixes

    • Updated error handling in file operations and cookie management.
  • Documentation

    • Updated localization files to reflect new descriptions for the Music Free plugin.
  • Chores

    • Removed deprecated code related to the Music Free plugin and its associated functionalities.
    • Updated various dependencies to maintain compatibility and improve performance.

Copy link

vercel bot commented Dec 19, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
azusa-player-mobile ✅ Ready (Inspect) Visit Preview 💬 Add feedback Dec 19, 2024 7:50pm

Copy link

coderabbitai bot commented Dec 19, 2024

Walkthrough

This pull request introduces significant changes to the Azusa Player Mobile project, focusing on restructuring the MusicFree plugin system. The modifications include removing existing MusicFree-related modules, introducing new utility functions for SDK management, updating type definitions, and refactoring components to handle dynamic music source plugins. The changes aim to provide a more flexible and modular approach to integrating music search and playback functionality from various sources.

Changes

File/Directory Change Summary
.gitmodules Removed submodule reference to MusicFreePlugins
__tests__/musicfree/ Added new test files for MusicFree SDK interactions
package.json Updated dependency versions and added new type definitions
src/components/ Restructured components related to search and settings
src/enums/Storage.ts Modified storage and search option enums
src/stores/ Added new store for managing MusicFree SDKs
src/utils/mediafetch/ Introduced new utility functions for SDK management
Localization files Updated warning messages for MusicFree plugins

Sequence Diagram

sequenceDiagram
    participant User
    participant SearchBar
    participant MFsdkStore
    participant EvalSDK
    participant MediaFetcher

    User->>SearchBar: Initiate Search
    SearchBar->>MFsdkStore: Retrieve Available SDKs
    MFsdkStore-->>SearchBar: Return SDK List
    SearchBar->>EvalSDK: Load Plugin
    EvalSDK->>MediaFetcher: Fetch Media
    MediaFetcher-->>SearchBar: Return Search Results
    SearchBar->>User: Display Results
Loading

Poem

🎵 A rabbit's tale of code so bright,
Where plugins dance with pure delight,
MusicFree plugins, once confined,
Now dynamic, unaligned!
Hop, hop, hooray for flexible might! 🐰🎶

Tip

CodeRabbit's docstrings feature is now available as part of our Early Access Program! Simply use the command @coderabbitai generate docstrings to have CodeRabbit automatically generate docstrings for your pull request. We would love to hear your feedback on Discord.


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

__tests__/musicfree/mfexample.js Dismissed Show dismissed Hide dismissed
Copy link

sonarqubecloud bot commented Dec 19, 2024

Quality Gate Passed Quality Gate passed

Issues
4 New issues
0 Accepted issues

Measures
0 Security Hotspots
No data about Coverage
0.0% Duplication on New Code

See analysis details on SonarQube Cloud

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 20

🔭 Outside diff range comments (1)
src/types/request.d.ts (1)

Line range hint 11-17: Remove duplicate interface declaration

The UpdateLyricMapping interface is declared twice in the NoxLyric namespace. Remove the duplicate declaration to avoid potential confusion.

- interface UpdateLyricMapping {
-   resolvedLrc?: NoxLyric.NoxFetchedLyric;
-   newLrcDetail?: Partial<NoxMedia.LyricDetail>;
-   lrc: string;
-   song: NoxMedia.Song;
-   currentTimeOffset: number;
- }

Also applies to: 46-52

♻️ Duplicate comments (1)
__tests__/musicfree/mfexample.js (1)

97-97: ⚠️ Potential issue

Hard-coded credentials detected.
This repeats a previously noted security concern about the exposed API key. Consider moving the key to a secure location (e.g., environment variable).

🧰 Tools
🪛 Gitleaks (8.21.2)

97-97: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🪛 GitHub Check: CodeQL

[failure] 97-97: Hard-coded credentials
The hard-coded value "f3ac5b086f3eab260520d8e3049561e6" is used as key.

🧹 Nitpick comments (27)
src/utils/mfsdk.ts (3)

8-9: Use a more self-documenting subfolder constant name, if possible.
Though not a pressing matter, consider renaming "mfsdkSubFolder" to something that clarifies its purpose, for example, "MFSDK_SUBDIRECTORY".


21-24: Consider concurrency or chunked addition of SDK paths.
If the number of paths grows large, saving them all at once might cause performance issues in some storage engines. Think about splitting large arrays or handling concurrency if needed.


26-40: Validate partial load errors during initialization.
When partially successful in loading some SDKs, you return only the non-undefined ones. For clarity, consider logging which ones failed to load to aid debugging.

src/utils/mediafetch/evalsdk.ts (2)

12-36: Document the difference between missing or partial implementations.
The commented-out methods (lines 24–35) hint that these functionalities are not needed for your app, but consider adding short doc comments to clarify that they are intentionally not used.


73-91: Handle failing URL resolution gracefully.
Currently, if all qualities fail, you throw an error. Consider returning a fallback or letting the calling function handle partial fallbacks (like trying direct links or skipping the track).

src/components/setting/appearances/SkinSettings.tsx (2)

126-127: Avoid duplicating getThemeID.
You define getThemeID in multiple places (SkinItem and again here). Consider extracting it into a shared utility to reduce duplication.

- const getThemeID = (skin: NoxTheme.Style) =>
-   `${skin.metaData.themeName}.${skin.metaData.themeAuthor}`;
+ // Example in a shared utility file, e.g. useThemeUtils.ts
+ export function getThemeID(skin: NoxTheme.Style): string {
+   return `${skin.metaData.themeName}.${skin.metaData.themeAuthor}`;
+ }

170-170: Review the search bar’s responsibilities.
Check for duplication with other search bars or if additional props might unify the approach across the app.

src/components/setting/developer/DeveloperSettings.tsx (1)

82-82: Consolidate or rename the Home component.
“Home” is fairly generic. If this is specifically “DeveloperHome,” renaming might improve clarity.

__tests__/musicfree/mfexample.js (5)

1-1: Remove redundant 'use strict' directive.
Modern JavaScript modules automatically run in strict mode.

- 'use strict';
🧰 Tools
🪛 Biome (1.9.4)

[error] 1-1: Redundant use strict directive.

The entire contents of JavaScript modules are automatically in strict mode, with no statement needed to initiate it.
Safe fix: Remove the redundant use strict directive.

(lint/suspicious/noRedundantUseStrict)


51-51: Use Array.isArray(e) instead of e instanceof Array.
This is generally more reliable across different contexts.

- e instanceof Array
+ Array.isArray(e)

63-63: Avoid direct usage of hasOwnProperty from target object.
Prefer using Object.hasOwn() or a safer approach.

- if (e.hasOwnProperty(n)) {
+ if (Object.hasOwn(e, n)) {
🧰 Tools
🪛 Biome (1.9.4)

[error] 63-63: Do not access Object.prototype method 'hasOwnProperty' from target object.

It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty().
See MDN web docs for more details.

(lint/suspicious/noPrototypeBuiltins)

🪛 eslint

[error] 63-63: Do not access Object.prototype method 'hasOwnProperty' from target object.

(no-prototype-builtins)


86-86: Avoid assignments in expressions to improve clarity.
Separate the assignment into its own statement.

- this._parameters[e] || (this._parameters[e] = []),
-   this._parameters[e].push(n);
+ if (!this._parameters[e]) {
+   this._parameters[e] = [];
+ }
+ this._parameters[e].push(n);
🧰 Tools
🪛 Biome (1.9.4)

[error] 86-86: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)

🪛 eslint

[error] 86-87: Expected an assignment or function call and instead saw an expression.

(@typescript-eslint/no-unused-expressions)


523-533: Review unhandled branch in switch-like construct.
Here we only handle 'music', 'album', 'sheet', 'artist'. If new types are introduced later, consider how they should be handled by this function.

src/hooks/useNavigation.ts (1)

25-28: Consider consolidating navigation methods

Having two navigation methods with similar functionality increases maintenance overhead. Consider making the icon setting optional in the main navigate method instead.

-  const navigate2 = (route: unknown) =>
-    navigationGlobal.navigate(route as never);
-
-  return { navigate, navigate2, getState: navigationGlobal.getState };
+  return { navigate, getState: navigationGlobal.getState };

Then update the navigate method to make setIcon truly optional:

   const navigate = ({ route, setIcon = true, options }: NavigateProps) => {
     // @ts-expect-error nav v7 hasnt fixed this type yet
     navigationGlobal.navigate(route as never, options);
-    if (setIcon) {
+    if (setIcon && IconMap[route]) {
       setRoute(IconMap[route]);
     }
   };
src/components/setting/developer/plugins/musicfree/MusicFreeButton.tsx (1)

27-34: Consider using theme-based styling

Hardcoded dimensions and margins might not scale well across different device sizes.

 const style = StyleSheet.create({
   musicFreeIcon: {
-    width: 50,
-    height: 50,
-    marginLeft: 20,
-    marginTop: 4,
+    width: theme.iconSizes.large,
+    height: theme.iconSizes.large,
+    margin: theme.spacing.medium,
   },
 });
src/stores/useMFsdk.ts (2)

18-23: Consider adding error handling for failed replacements

While the null check for empty array is good, consider handling cases where the replacement operation might fail.

 replaceMFsdks: mf => {
   if (mf.length === 0) return;
+  try {
     set(s => ({
       MFsdks: s.MFsdks.map(sdk => mf.find(v => v.srcUrl === sdk.srcUrl) ?? sdk),
     }));
+  } catch (error) {
+    console.error('Failed to replace MFsdks:', error);
+  }
 },

24-30: Consider consolidating storage operations

The addMFsdks and rmMFsdks methods both handle storage operations before state updates. Consider extracting this pattern into a utility function to ensure consistent error handling.

+const handleStorageOperation = async (
+  operation: (paths: string[]) => Promise<void>,
+  sdks: MFsdk[],
+  paths: string[]
+) => {
+  try {
+    await operation(paths);
+    return true;
+  } catch (error) {
+    console.error('Storage operation failed:', error);
+    return false;
+  }
+};

 addMFsdks: async mf => {
   if (mf.length === 0) return;
-  addMFsdks(mf.map(v => v.path));
+  const success = await handleStorageOperation(
+    addMFsdks,
+    mf,
+    mf.map(v => v.path)
+  );
+  if (!success) return;
   set(s => ({
     MFsdks: getUniqObjects([...mf, ...s.MFsdks], sdk => sdk.srcUrl),
   }));
 },

Also applies to: 31-39

src/components/setting/developer/View.tsx (2)

13-24: Consider extracting styles to a separate constant

The inline styles in HomeWrapper could be extracted to improve readability and reusability.

+const styles = {
+  wrapper: {
+    flex: 1,
+  },
+};

 const HomeWrapper = ({ navigation }: NoxComponent.StackNavigationProps) => {
   const playerStyle = useNoxSetting(state => state.playerStyle);
   return (
     <SelectDialogWrapper
       viewStyle={{
         backgroundColor: playerStyle.customColors.maskedBackgroundColor,
-        flex: 1,
+        ...styles.wrapper,
       }}
       Children={p => Home({ ...p, navigation })}
     />
   );
 };

26-46: Consider adding screen options type safety

The screen options could benefit from stronger typing to prevent potential configuration errors.

+type ScreenOptions = {
+  headerShown: boolean;
+};

+const defaultScreenOptions: ScreenOptions = {
+  headerShown: false,
+};

 export default () => {
   return (
     <Stack.Navigator>
       <Stack.Screen
         name={Route.HOME}
         component={HomeWrapper}
-        options={{ headerShown: false }}
+        options={defaultScreenOptions}
       />
       <Stack.Screen
         name={Route.PLUGINS}
         component={PluginSettings}
-        options={{ headerShown: false }}
+        options={defaultScreenOptions}
       />
       <Stack.Screen
         name={Route.MUSICFREE}
         component={MFSettings}
-        options={{ headerShown: false }}
+        options={defaultScreenOptions}
       />
     </Stack.Navigator>
   );
 };
src/utils/fs.ts (1)

13-13: Consider using path.join for robust path construction

While the path construction works, using path.join would make it more robust across different platforms.

-      `${fsdirs.DocumentDir}/${subfolder}/${filename}`,
+      path.join(fsdirs.DocumentDir, subfolder, filename),
src/components/commonui/SearchBar.tsx (1)

9-13: Consider enhancing OnSearchProps interface documentation

The new interface provides good error handling and progress tracking capabilities. However, it would benefit from JSDoc comments explaining the purpose of each property.

+/**
+ * Props for the search operation
+ */
 interface OnSearchProps {
+  /** The search query string */
   v: string;
+  /** Callback to update search progress (0-1) */
   progressEmitter: (v: number) => void;
+  /** Callback to show error/success messages */
   setSnack: (v: SetSnack) => unknown;
 }
src/components/setting/developer/plugins/musicfree/View.tsx (1)

73-80: Consider adding empty state and loading indicators

The FlashList should handle empty states and loading states appropriately.

 <FlashList
   ref={scrollViewRef}
   data={MFsdks}
   renderItem={({ item }) => (
     <RenderItem sdk={item} listRef={scrollViewRef} />
   )}
   estimatedItemSize={100}
+  ListEmptyComponent={<Text>No SDKs installed</Text>}
+  onRefresh={onRefresh}
+  refreshing={isRefreshing}
 />
src/utils/mediafetch/resolveURL.ts (1)

73-81: Consider memoizing the SDK lookup

The current implementation accesses state and performs SDK lookup on every call. Consider memoizing the SDK lookup or moving it outside the fallback function.

Here's a suggested approach:

+ const getMemoizedSDK = (source: string) => {
+   const mfsdks = useNoxSetting.getState().MFsdks;
+   return mfsdks.find(sdk => sdk.platform === source);
+ };

  const fallback = () => {
-   const mfsdks = useNoxSetting.getState().MFsdks;
-   for (const mfsdk of mfsdks) {
-     if (mfsdk.platform === song.source) {
-       return mfsdk.resolveURL(song);
-     }
-   }
+   const sdk = getMemoizedSDK(song.source);
+   if (sdk) {
+     return sdk.resolveURL(song);
+   }
    return fetchBiliUrlPromise({ bvid, cid: String(cid), iOS, noBiliR128Gain });
  };
src/components/playlist/BiliSearch/BiliSearchbar.tsx (1)

46-46: Consider optimizing state subscription

The current implementation subscribes to the entire MFsdks array, which could cause unnecessary re-renders when any SDK is updated. Consider subscribing only to the length if that's all you need.

Here's a suggested optimization:

- const mfsdks = useNoxSetting(state => state.MFsdks);
+ const hasMFSDKs = useNoxSetting(state => state.MFsdks.length > 0);

  const handleMenuPress = (event: GestureResponderEvent) => {
-   setShowMusicFree(mfsdks.length > 0);
+   setShowMusicFree(hasMFSDKs);
    setDialogOpen(true);
    setMenuCoords({
      x: event.nativeEvent.pageX,
      y: event.nativeEvent.pageY,
    });
  };

Also applies to: 69-69

src/components/style.ts (1)

184-224: Consider extracting magic numbers into named constants

The style definitions look well-structured, but there are some hardcoded values that could be extracted into named constants for better maintainability:

+const SKIN_ITEM_DIMENSIONS = {
+  SIZE: 72,
+  BORDER_RADIUS: 40
+};

 export const ItemSelectStyles = StyleSheet.create({
   // ...
   skinItemImage: {
-    width: 72,
-    height: 72,
-    borderRadius: 40,
+    width: SKIN_ITEM_DIMENSIONS.SIZE,
+    height: SKIN_ITEM_DIMENSIONS.SIZE,
+    borderRadius: SKIN_ITEM_DIMENSIONS.BORDER_RADIUS,
   },
   // ...
 });
src/stores/useApp.ts (1)

Line range hint 169-183: Consider adding loading state management

The initialization of MFsdk and other resources could benefit from loading state management to improve user experience.

Consider adding a loading state:

 interface NoxSetting extends BottomTabStore, APMUIStore, UIStore, PlaylistsStore, MFsdkStore {
+  isInitializing: boolean;
   // ... other properties
 }

 export const useNoxSetting = create<NoxSetting>((set, get, storeApi) => ({
   // ... other implementations
   initPlayer: async val => {
+    set({ isInitializing: true });
     try {
       // ... initialization logic
+    } finally {
+      set({ isInitializing: false });
     }
   },
 }));
src/stores/useSlices.ts (1)

8-8: Consider adding documentation for the store's intended usage.

The store is currently empty but appears to be a template. Consider adding JSDoc comments to document:

  • The store's purpose
  • Expected state structure
  • How it should be extended
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 690065c and 5c2fc3e.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (46)
  • .gitmodules (0 hunks)
  • MusicFreePlugins (0 hunks)
  • __tests__/musicfree/mfexample.js (1 hunks)
  • __tests__/musicfree/musicfree.test.js (1 hunks)
  • package.json (5 hunks)
  • scripts/fixHTTP.py (1 hunks)
  • src/components/commonui/SearchBar.tsx (1 hunks)
  • src/components/playlist/BiliSearch/BiliSearchbar.tsx (2 hunks)
  • src/components/playlist/BiliSearch/SearchMenu.tsx (2 hunks)
  • src/components/setting/View.tsx (1 hunks)
  • src/components/setting/appearances/SkinSearchbar.tsx (1 hunks)
  • src/components/setting/appearances/SkinSettings.tsx (5 hunks)
  • src/components/setting/developer/DeveloperSettings.tsx (3 hunks)
  • src/components/setting/developer/View.tsx (1 hunks)
  • src/components/setting/developer/enums.ts (1 hunks)
  • src/components/setting/developer/plugins/View.tsx (1 hunks)
  • src/components/setting/developer/plugins/musicfree/MusicFreeButton.tsx (1 hunks)
  • src/components/setting/developer/plugins/musicfree/Searchbar.tsx (1 hunks)
  • src/components/setting/developer/plugins/musicfree/View.tsx (1 hunks)
  • src/components/setting/plugins/MusicFreeButton.tsx (0 hunks)
  • src/components/style.ts (1 hunks)
  • src/enums/Storage.ts (2 hunks)
  • src/hooks/useLyricRN.ts (2 hunks)
  • src/hooks/useNavigation.ts (1 hunks)
  • src/localization/en/translation.json (1 hunks)
  • src/localization/zhcn/translation.json (1 hunks)
  • src/objects/Song.ts (1 hunks)
  • src/objects/Storage.ts (2 hunks)
  • src/stores/useAPMUI.ts (1 hunks)
  • src/stores/useApp.ts (3 hunks)
  • src/stores/useMFsdk.ts (1 hunks)
  • src/stores/useSlices.ts (1 hunks)
  • src/stores/useSnack.ts (1 hunks)
  • src/types/media.d.ts (1 hunks)
  • src/types/request.d.ts (1 hunks)
  • src/utils/BiliSearch.ts (3 hunks)
  • src/utils/Bilibili/biliCookies.ts (1 hunks)
  • src/utils/ChromeStorage.ts (1 hunks)
  • src/utils/fs.ts (2 hunks)
  • src/utils/mediafetch/bilisearch.ts (2 hunks)
  • src/utils/mediafetch/evalsdk.ts (1 hunks)
  • src/utils/mediafetch/mfsdk.ts (0 hunks)
  • src/utils/mediafetch/musicfree.ts (0 hunks)
  • src/utils/mediafetch/resolveURL.ts (2 hunks)
  • src/utils/mediafetch/ytbChannel.ytbi.ts (1 hunks)
  • src/utils/mfsdk.ts (1 hunks)
💤 Files with no reviewable changes (5)
  • MusicFreePlugins
  • src/utils/mediafetch/mfsdk.ts
  • .gitmodules
  • src/components/setting/plugins/MusicFreeButton.tsx
  • src/utils/mediafetch/musicfree.ts
✅ Files skipped from review due to trivial changes (3)
  • scripts/fixHTTP.py
  • src/utils/mediafetch/ytbChannel.ytbi.ts
  • src/components/setting/developer/plugins/View.tsx
🧰 Additional context used
🪛 eslint
src/components/setting/developer/View.tsx

[error] 1-1: Resolve error: Cannot find module 'babel-plugin-module-resolver'
Require stack:

  • /home/jailuser/git/node_modules/eslint-import-resolver-babel-module/lib/index.js
  • /home/jailuser/git/node_modules/eslint-module-utils/resolve.js
  • /home/jailuser/git/node_modules/eslint-plugin-import/lib/rules/no-unresolved.js
  • /home/jailuser/git/node_modules/eslint-plugin-import/lib/index.js
  • /home/jailuser/git/node_modules/@eslint/eslintrc/dist/eslintrc.cjs
    at Module._resolveFilename (node:internal/modules/cjs/loader:1248:15)
    at Module._load (node:internal/modules/cjs/loader:1074:27)
    at TracingChannel.traceSync (node:diagnostics_channel:315:14)
    at wrapModuleLoad (node:internal/modules/cjs/loader:217:24)
    at Module.require (node:internal/modules/cjs/loader:1339:12)
    at require (node:internal/modules/helpers:135:16)
    at Object. (/home/jailuser/git/node_modules/eslint-import-resolver-babel-module/lib/index.js:8:5)
    at Module._compile (node:internal/modules/cjs/loader:1546:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1691:10)
    at Module.load (node:internal/modules/cjs/loader:1317:32)

(import/namespace)

__tests__/musicfree/musicfree.test.js

[error] 1-1: Resolve error: Cannot find module 'babel-plugin-module-resolver'
Require stack:

  • /home/jailuser/git/node_modules/eslint-import-resolver-babel-module/lib/index.js
  • /home/jailuser/git/node_modules/eslint-module-utils/resolve.js
  • /home/jailuser/git/node_modules/eslint-plugin-import/lib/rules/no-unresolved.js
  • /home/jailuser/git/node_modules/eslint-plugin-import/lib/index.js
  • /home/jailuser/git/node_modules/@eslint/eslintrc/dist/eslintrc.cjs
    at Module._resolveFilename (node:internal/modules/cjs/loader:1248:15)
    at Module._load (node:internal/modules/cjs/loader:1074:27)
    at TracingChannel.traceSync (node:diagnostics_channel:315:14)
    at wrapModuleLoad (node:internal/modules/cjs/loader:217:24)
    at Module.require (node:internal/modules/cjs/loader:1339:12)
    at require (node:internal/modules/helpers:135:16)
    at Object. (/home/jailuser/git/node_modules/eslint-import-resolver-babel-module/lib/index.js:8:5)
    at Module._compile (node:internal/modules/cjs/loader:1546:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1691:10)
    at Module.load (node:internal/modules/cjs/loader:1317:32)

(import/namespace)


[error] 1-1: Resolve error: Cannot find module 'babel-plugin-module-resolver'
Require stack:

  • /home/jailuser/git/node_modules/eslint-import-resolver-babel-module/lib/index.js
  • /home/jailuser/git/node_modules/eslint-module-utils/resolve.js
  • /home/jailuser/git/node_modules/eslint-plugin-import/lib/rules/no-unresolved.js
  • /home/jailuser/git/node_modules/eslint-plugin-import/lib/index.js
  • /home/jailuser/git/node_modules/@eslint/eslintrc/dist/eslintrc.cjs
    at Module._resolveFilename (node:internal/modules/cjs/loader:1248:15)
    at Module._load (node:internal/modules/cjs/loader:1074:27)
    at TracingChannel.traceSync (node:diagnostics_channel:315:14)
    at wrapModuleLoad (node:internal/modules/cjs/loader:217:24)
    at Module.require (node:internal/modules/cjs/loader:1339:12)
    at require (node:internal/modules/helpers:135:16)
    at Object. (/home/jailuser/git/node_modules/eslint-import-resolver-babel-module/lib/index.js:8:5)
    at Module._compile (node:internal/modules/cjs/loader:1546:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1691:10)
    at Module.load (node:internal/modules/cjs/loader:1317:32)

(import/named)


[error] 4-4: 'test' is not defined.

(no-undef)


[error] 8-8: 'expect' is not defined.

(no-undef)


[error] 11-11: 'expect' is not defined.

(no-undef)

src/components/setting/developer/plugins/musicfree/Searchbar.tsx

[error] 1-1: Resolve error: Cannot find module 'babel-plugin-module-resolver'
Require stack:

  • /home/jailuser/git/node_modules/eslint-import-resolver-babel-module/lib/index.js
  • /home/jailuser/git/node_modules/eslint-module-utils/resolve.js
  • /home/jailuser/git/node_modules/eslint-plugin-import/lib/rules/no-unresolved.js
  • /home/jailuser/git/node_modules/eslint-plugin-import/lib/index.js
  • /home/jailuser/git/node_modules/@eslint/eslintrc/dist/eslintrc.cjs
    at Module._resolveFilename (node:internal/modules/cjs/loader:1248:15)
    at Module._load (node:internal/modules/cjs/loader:1074:27)
    at TracingChannel.traceSync (node:diagnostics_channel:315:14)
    at wrapModuleLoad (node:internal/modules/cjs/loader:217:24)
    at Module.require (node:internal/modules/cjs/loader:1339:12)
    at require (node:internal/modules/helpers:135:16)
    at Object. (/home/jailuser/git/node_modules/eslint-import-resolver-babel-module/lib/index.js:8:5)
    at Module._compile (node:internal/modules/cjs/loader:1546:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1691:10)
    at Module.load (node:internal/modules/cjs/loader:1317:32)

(import/namespace)

src/components/setting/developer/plugins/musicfree/View.tsx

[error] 1-1: Resolve error: Cannot find module 'babel-plugin-module-resolver'
Require stack:

  • /home/jailuser/git/node_modules/eslint-import-resolver-babel-module/lib/index.js
  • /home/jailuser/git/node_modules/eslint-module-utils/resolve.js
  • /home/jailuser/git/node_modules/eslint-plugin-import/lib/rules/no-unresolved.js
  • /home/jailuser/git/node_modules/eslint-plugin-import/lib/index.js
  • /home/jailuser/git/node_modules/@eslint/eslintrc/dist/eslintrc.cjs
    at Module._resolveFilename (node:internal/modules/cjs/loader:1248:15)
    at Module._load (node:internal/modules/cjs/loader:1074:27)
    at TracingChannel.traceSync (node:diagnostics_channel:315:14)
    at wrapModuleLoad (node:internal/modules/cjs/loader:217:24)
    at Module.require (node:internal/modules/cjs/loader:1339:12)
    at require (node:internal/modules/helpers:135:16)
    at Object. (/home/jailuser/git/node_modules/eslint-import-resolver-babel-module/lib/index.js:8:5)
    at Module._compile (node:internal/modules/cjs/loader:1546:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1691:10)
    at Module.load (node:internal/modules/cjs/loader:1317:32)

(import/namespace)

src/utils/mediafetch/evalsdk.ts

[error] 1-1: Resolve error: Cannot find module 'babel-plugin-module-resolver'
Require stack:

  • /home/jailuser/git/node_modules/eslint-import-resolver-babel-module/lib/index.js
  • /home/jailuser/git/node_modules/eslint-module-utils/resolve.js
  • /home/jailuser/git/node_modules/eslint-plugin-import/lib/rules/no-unresolved.js
  • /home/jailuser/git/node_modules/eslint-plugin-import/lib/index.js
  • /home/jailuser/git/node_modules/@eslint/eslintrc/dist/eslintrc.cjs
    at Module._resolveFilename (node:internal/modules/cjs/loader:1248:15)
    at Module._load (node:internal/modules/cjs/loader:1074:27)
    at TracingChannel.traceSync (node:diagnostics_channel:315:14)
    at wrapModuleLoad (node:internal/modules/cjs/loader:217:24)
    at Module.require (node:internal/modules/cjs/loader:1339:12)
    at require (node:internal/modules/helpers:135:16)
    at Object. (/home/jailuser/git/node_modules/eslint-import-resolver-babel-module/lib/index.js:8:5)
    at Module._compile (node:internal/modules/cjs/loader:1546:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1691:10)
    at Module.load (node:internal/modules/cjs/loader:1317:32)

(import/namespace)

src/components/setting/appearances/SkinSearchbar.tsx

[error] 1-1: Resolve error: Cannot find module 'babel-plugin-module-resolver'
Require stack:

  • /home/jailuser/git/node_modules/eslint-import-resolver-babel-module/lib/index.js
  • /home/jailuser/git/node_modules/eslint-module-utils/resolve.js
  • /home/jailuser/git/node_modules/eslint-plugin-import/lib/rules/no-unresolved.js
  • /home/jailuser/git/node_modules/eslint-plugin-import/lib/index.js
  • /home/jailuser/git/node_modules/@eslint/eslintrc/dist/eslintrc.cjs
    at Module._resolveFilename (node:internal/modules/cjs/loader:1248:15)
    at Module._load (node:internal/modules/cjs/loader:1074:27)
    at TracingChannel.traceSync (node:diagnostics_channel:315:14)
    at wrapModuleLoad (node:internal/modules/cjs/loader:217:24)
    at Module.require (node:internal/modules/cjs/loader:1339:12)
    at require (node:internal/modules/helpers:135:16)
    at Object. (/home/jailuser/git/node_modules/eslint-import-resolver-babel-module/lib/index.js:8:5)
    at Module._compile (node:internal/modules/cjs/loader:1546:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1691:10)
    at Module.load (node:internal/modules/cjs/loader:1317:32)

(import/namespace)

src/components/setting/developer/plugins/musicfree/MusicFreeButton.tsx

[error] 1-1: Resolve error: Cannot find module 'babel-plugin-module-resolver'
Require stack:

  • /home/jailuser/git/node_modules/eslint-import-resolver-babel-module/lib/index.js
  • /home/jailuser/git/node_modules/eslint-module-utils/resolve.js
  • /home/jailuser/git/node_modules/eslint-plugin-import/lib/rules/no-unresolved.js
  • /home/jailuser/git/node_modules/eslint-plugin-import/lib/index.js
  • /home/jailuser/git/node_modules/@eslint/eslintrc/dist/eslintrc.cjs
    at Module._resolveFilename (node:internal/modules/cjs/loader:1248:15)
    at Module._load (node:internal/modules/cjs/loader:1074:27)
    at TracingChannel.traceSync (node:diagnostics_channel:315:14)
    at wrapModuleLoad (node:internal/modules/cjs/loader:217:24)
    at Module.require (node:internal/modules/cjs/loader:1339:12)
    at require (node:internal/modules/helpers:135:16)
    at Object. (/home/jailuser/git/node_modules/eslint-import-resolver-babel-module/lib/index.js:8:5)
    at Module._compile (node:internal/modules/cjs/loader:1546:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1691:10)
    at Module.load (node:internal/modules/cjs/loader:1317:32)

(import/namespace)

src/stores/useMFsdk.ts

[error] 1-1: Resolve error: Cannot find module 'babel-plugin-module-resolver'
Require stack:

  • /home/jailuser/git/node_modules/eslint-import-resolver-babel-module/lib/index.js
  • /home/jailuser/git/node_modules/eslint-module-utils/resolve.js
  • /home/jailuser/git/node_modules/eslint-plugin-import/lib/rules/no-unresolved.js
  • /home/jailuser/git/node_modules/eslint-plugin-import/lib/index.js
  • /home/jailuser/git/node_modules/@eslint/eslintrc/dist/eslintrc.cjs
    at Module._resolveFilename (node:internal/modules/cjs/loader:1248:15)
    at Module._load (node:internal/modules/cjs/loader:1074:27)
    at TracingChannel.traceSync (node:diagnostics_channel:315:14)
    at wrapModuleLoad (node:internal/modules/cjs/loader:217:24)
    at Module.require (node:internal/modules/cjs/loader:1339:12)
    at require (node:internal/modules/helpers:135:16)
    at Object. (/home/jailuser/git/node_modules/eslint-import-resolver-babel-module/lib/index.js:8:5)
    at Module._compile (node:internal/modules/cjs/loader:1546:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1691:10)
    at Module.load (node:internal/modules/cjs/loader:1317:32)

(import/namespace)

__tests__/musicfree/mfexample.js

[error] 33-33: Expected an assignment or function call and instead saw an expression.

(@typescript-eslint/no-unused-expressions)


[error] 48-48: Expected an assignment or function call and instead saw an expression.

(@typescript-eslint/no-unused-expressions)


[error] 63-63: Do not access Object.prototype method 'hasOwnProperty' from target object.

(no-prototype-builtins)


[error] 82-82: 'e' is defined but never used.

(@typescript-eslint/no-unused-vars)


[error] 82-82: Empty block statement.

(no-empty)


[error] 86-87: Expected an assignment or function call and instead saw an expression.

(@typescript-eslint/no-unused-expressions)


[error] 302-302: 'page' is defined but never used.

(@typescript-eslint/no-unused-vars)

src/utils/mfsdk.ts

[error] 1-1: Resolve error: Cannot find module 'babel-plugin-module-resolver'
Require stack:

  • /home/jailuser/git/node_modules/eslint-import-resolver-babel-module/lib/index.js
  • /home/jailuser/git/node_modules/eslint-module-utils/resolve.js
  • /home/jailuser/git/node_modules/eslint-plugin-import/lib/rules/no-unresolved.js
  • /home/jailuser/git/node_modules/eslint-plugin-import/lib/index.js
  • /home/jailuser/git/node_modules/@eslint/eslintrc/dist/eslintrc.cjs
    at Module._resolveFilename (node:internal/modules/cjs/loader:1248:15)
    at Module._load (node:internal/modules/cjs/loader:1074:27)
    at TracingChannel.traceSync (node:diagnostics_channel:315:14)
    at wrapModuleLoad (node:internal/modules/cjs/loader:217:24)
    at Module.require (node:internal/modules/cjs/loader:1339:12)
    at require (node:internal/modules/helpers:135:16)
    at Object. (/home/jailuser/git/node_modules/eslint-import-resolver-babel-module/lib/index.js:8:5)
    at Module._compile (node:internal/modules/cjs/loader:1546:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1691:10)
    at Module.load (node:internal/modules/cjs/loader:1317:32)

(import/namespace)

src/stores/useSlices.ts

[error] 1-1: Resolve error: Cannot find module 'babel-plugin-module-resolver'
Require stack:

  • /home/jailuser/git/node_modules/eslint-import-resolver-babel-module/lib/index.js
  • /home/jailuser/git/node_modules/eslint-module-utils/resolve.js
  • /home/jailuser/git/node_modules/eslint-plugin-import/lib/rules/no-unresolved.js
  • /home/jailuser/git/node_modules/eslint-plugin-import/lib/index.js
  • /home/jailuser/git/node_modules/@eslint/eslintrc/dist/eslintrc.cjs
    at Module._resolveFilename (node:internal/modules/cjs/loader:1248:15)
    at Module._load (node:internal/modules/cjs/loader:1074:27)
    at TracingChannel.traceSync (node:diagnostics_channel:315:14)
    at wrapModuleLoad (node:internal/modules/cjs/loader:217:24)
    at Module.require (node:internal/modules/cjs/loader:1339:12)
    at require (node:internal/modules/helpers:135:16)
    at Object. (/home/jailuser/git/node_modules/eslint-import-resolver-babel-module/lib/index.js:8:5)
    at Module._compile (node:internal/modules/cjs/loader:1546:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1691:10)
    at Module.load (node:internal/modules/cjs/loader:1317:32)

(import/namespace)

🪛 Gitleaks (8.21.2)
__tests__/musicfree/mfexample.js

97-97: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🪛 Biome (1.9.4)
__tests__/musicfree/mfexample.js

[error] 1-1: Redundant use strict directive.

The entire contents of JavaScript modules are automatically in strict mode, with no statement needed to initiate it.
Safe fix: Remove the redundant use strict directive.

(lint/suspicious/noRedundantUseStrict)


[error] 63-63: Do not access Object.prototype method 'hasOwnProperty' from target object.

It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty().
See MDN web docs for more details.

(lint/suspicious/noPrototypeBuiltins)


[error] 81-81: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)


[error] 86-86: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)


[error] 131-135: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)


[error] 132-132: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)


[error] 153-153: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)


[error] 156-156: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)


[error] 158-158: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)


[error] 159-159: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)


[error] 160-160: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)


[error] 162-162: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)


[error] 475-475: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)


[error] 485-485: The assignment should not be in an expression.

The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.

(lint/suspicious/noAssignInExpressions)


[error] 52-52: Use Array.isArray() instead of instanceof Array.

instanceof Array returns false for array-like objects and arrays from other execution contexts.
Unsafe fix: Use Array.isArray() instead.

(lint/suspicious/useIsArray)


[error] 70-70: Use Array.isArray() instead of instanceof Array.

instanceof Array returns false for array-like objects and arrays from other execution contexts.
Unsafe fix: Use Array.isArray() instead.

(lint/suspicious/useIsArray)

src/stores/useSlices.ts

[error] 6-6: An empty interface is equivalent to {}.

Safe fix: Use a type alias instead.

(lint/suspicious/noEmptyInterface)

🪛 GitHub Check: CodeQL
__tests__/musicfree/mfexample.js

[failure] 97-97: Hard-coded credentials
The hard-coded value "f3ac5b086f3eab260520d8e3049561e6" is used as key.

🔇 Additional comments (35)
src/utils/mfsdk.ts (1)

12-19: Ensure external references to removed SDK paths are handled.
When removing SDK paths, confirm that no active references exist in the system. If so, handle them gracefully to prevent missing resource errors.

✅ Verification successful

Let me gather more information about how these SDK paths are used in the system.

The first command will help us understand how SDK paths are retrieved and used, while the second will look for any direct path assignments that might reference these SDKs.


Let me check one more aspect to understand how these SDKs are loaded and used in the system.


Based on the gathered information, I can now provide the final response:

The SDK removal implementation is safe and properly handled
The implementation in rmMFsdks correctly manages SDK removal by:

  • Updating the stored paths in StorageKeys.MFSDK_PATHS
  • Removing the physical files using rmTxtFile
  • Properly updating the application state through the useMFsdk store
  • SDKs are loaded on-demand through loadEvalPlugin, which gracefully handles failures

The system maintains consistency between the stored paths, physical files, and runtime state, preventing any dangling references.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Verify the usage of removed SDK paths in the codebase.
rg -A 2 -B 2 'rmMFsdks'

Length of output: 2348


Script:

#!/bin/bash
# Check how MFsdk paths are used in the codebase
rg -A 5 "getMFsdk"

# Check for any direct path references
ast-grep --pattern 'path = $_'

Length of output: 1149


Script:

#!/bin/bash
# Check how these SDKs are loaded and used
rg -A 5 "loadEvalPlugin"

# Check the implementation of rmTxtFile
rg -A 3 "rmTxtFile"

Length of output: 3062

src/utils/mediafetch/evalsdk.ts (1)

57-71: Catch potential multi-page search expansions.
Your searchWrapper calls "search" with fixed parameters. If the original plugin supports paging, ensure you're not ignoring multi-page search results unintentionally.

src/components/setting/appearances/SkinSettings.tsx (4)

3-3: Minor note on platform imports.
Ensure that React Native's built-in modules offer everything needed. Avoid incomplete imports for animations or other cross-platform functionalities.


12-12: Potential circular dependencies?
Be mindful of import paths referencing each other across subfolders. If there's a risk of cyclical references, consider consolidating or reorganizing these modules.


136-136: Ref usage is correct.
Using a RefObject for FlashList is a good approach to handle layout animations and scrolling references.


184-184: Proper item sizing for improved performance.
With FlashList, "estimatedItemSize" is presumably correct. Keep an eye on metrics to ensure it’s not drastically under/overestimated, which could affect scroll performance.

src/components/setting/developer/DeveloperSettings.tsx (1)

12-13: Check correct usage of newly imported components.
Confirm that these imports still point to the correct modules after the reorganization.

Also applies to: 15-15, 20-21, 29-31

__tests__/musicfree/mfexample.js (2)

168-189: Check error handling for external HTTP request.
In case of network failure or malformed data, ensure the calling code has robust fallback or error messages.


326-359: Validate media source logic.
If no or unexpected data is returned from the third-party API, ensure the calling modules handle the null/undefined URL gracefully.

src/components/setting/developer/enums.ts (2)

1-5: Enums look good.
This is a clean approach to keep route constants organized. No immediate issues spotted.


7-19: Icons enum is well-defined.
No issues here.

__tests__/musicfree/musicfree.test.js (1)

4-12: Ensure Jest environment is properly configured.
You may see no-undef errors for 'test' and 'expect' if linting is not configured for Jest. Confirm your ESLint and jest config integration.

🧰 Tools
🪛 eslint

[error] 4-4: 'test' is not defined.

(no-undef)


[error] 8-8: 'expect' is not defined.

(no-undef)


[error] 11-11: 'expect' is not defined.

(no-undef)

src/utils/Bilibili/biliCookies.ts (3)

8-8: Enum usage for default parameter is clearer.
This improves consistency and maintainability.


11-11: Refactored getBiliJct function is concise.
No issues spotted.


16-16: Cookie header usage.
This approach is straightforward; just ensure the cookie value is always present.

src/enums/Storage.ts (2)

26-26: LGTM: Storage key for MusicFree paths

The new storage key follows the established naming convention and clearly indicates its purpose.


37-37: LGTM: New search option for MusicFree

The addition aligns with the PR's objective of restructuring the MusicFree plugin system.

src/stores/useMFsdk.ts (1)

7-13: LGTM: Well-defined store interface

The interface is clean, well-typed, and provides a comprehensive set of operations for managing MFsdk instances.

src/objects/Storage.ts (1)

Line range hint 25-42: Verify migration strategy for default setting changes

Several default settings have been changed from false to true:

  • noCookieBiliSearch
  • trackCoverArtCard
  • karaokeLyrics
  • memoryEfficiency

These changes could affect existing users' experience. Please ensure there's a migration strategy in place to handle these changes gracefully.

✅ Verification successful

Let me gather more information about the storage implementation and any potential migrations.


Let me try a different approach to check the storage implementation and any migration-related code.


Let me check one more aspect to see how settings are loaded and applied in the application.


Based on the gathered information, I can now provide the final response:

Default settings changes are handled safely through persistence layer

The changes to default settings are safe because:

  1. The app uses a layered approach to settings through AsyncStorage:
    • DefaultSetting serves as the base layer
    • Persisted settings are loaded and merged on top via ChromeStorage.ts
    • An OverrideSetting layer exists for runtime overrides
  2. Existing user settings are preserved as they are stored separately and merged with defaults during initialization
  3. The changes only affect the base defaults, which are only used for new installations or when a setting is not found in storage
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for migration code handling these setting changes
rg -A 5 "migration|upgrade|setting.*update" src/

Length of output: 464


Script:

#!/bin/bash
# Check storage implementation and initialization
ast-grep --pattern 'class Storage {
  $$$
}'

# Check for any storage version or initialization code
rg -A 10 "initialize|init.*storage|version" src/objects/Storage.ts

# Look for any code that handles storage updates
rg -A 5 "storage.*update|update.*storage" src/

Length of output: 164


Script:

#!/bin/bash
# Get the full content of Storage.ts to understand the implementation
cat src/objects/Storage.ts

# Check for any storage-related changes in recent commits
rg -A 5 "Storage" src/migrations/ || echo "No migrations directory found"

# Look for any persistence or storage loading code
rg -A 5 "load.*settings|save.*settings|persist.*settings" src/

Length of output: 1919


Script:

#!/bin/bash
# Look for settings initialization and loading in the codebase
rg -A 10 "DefaultSetting|OverrideSetting" src/

# Check for any persistence mechanism
rg -A 10 "AsyncStorage|localStorage|Storage\.set" src/

Length of output: 11471

src/types/media.d.ts (1)

7-7: Verify the impact of removing MUSICFREE from SongSource type

This is a breaking change that could affect existing code using the MUSICFREE source type. Please ensure all consumers of this type have been updated accordingly.

Consider adding a comment documenting this breaking change and migration steps for downstream consumers.

src/stores/useAPMUI.ts (1)

16-17: Verify SearchOptions enum values after MUSICFREE removal

The searchOption type has been updated to remove MUSICFREE. Please ensure:

  1. The SearchOptions enum has been updated accordingly
  2. The default value BILIBILI is still valid
  3. The saveDefaultSearch function handles the updated type
src/objects/Song.ts (1)

28-28: Verify removal of MUSICFREE source type

The simplification of the source property type aligns with the PR's objective of restructuring the MusicFree plugin system. However, we should verify that this change doesn't break existing code.

✅ Verification successful

Let me check the actual usage of MUSICFREE in these files to understand if they're related to the source type.


Based on the search results, I can now generate the final response as I have enough context. The MUSICFREE references found are not related to the Source type in Song.ts, but rather to enum values, route names, and plugin-specific functionality. Let me check the Source type definition to be completely certain.


No issues with Source type change - MUSICFREE was never a valid Source enum value

The verification shows that the MUSICFREE type was never part of the Source enum in MediaFetch.ts. The Source enum only contains 'biliaudio', 'bilivideo', and 'steriatk' as valid values. The MUSICFREE references found in the codebase are used in different contexts (routes, plugin names, search options) and are not related to the Song's source property type. This change is safe and correct.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining MUSICFREE type usage that might need updating
rg -l "MUSICFREE" --type ts

# Search for direct assignments of MUSICFREE to source property
ast-grep --pattern 'source: MUSICFREE'

Length of output: 398


Script:

#!/bin/bash
# Check content of files containing MUSICFREE
rg "MUSICFREE" -C 2 --type ts

# Also search for any Source type usage
rg "Source\s*[:{]" --type ts

Length of output: 3774


Script:

#!/bin/bash
# Check Source type definition and usage in objects/Song.ts context
rg "Source" -C 3 src/enums/MediaFetch.ts
rg "Source" -C 3 src/objects/Song.ts

Length of output: 575

src/types/request.d.ts (1)

98-98: LGTM: Improved type safety with NoxMedia namespace

The update to use explicit NoxMedia namespace types improves type safety and consistency.

src/stores/useSnack.ts (1)

Line range hint 5-11: LGTM: Improved modularity with exported interface

The addition of the export keyword to SetSnack interface improves code modularity and reusability, particularly for its use in the SearchBar component.

src/components/playlist/BiliSearch/SearchMenu.tsx (1)

35-35: Verify MusicFree search option handling

The changes to setDefaultSearch and MusicFree menu item look correct, but we should verify that all callers of this function have been updated to use SearchOptions.MUSICFREE.

Also applies to: 76-77

✅ Verification successful

All callers of setDefaultSearch are using SearchOptions enum correctly

The verification shows that:

  • All calls to setDefaultSearch consistently use the SearchOptions enum, including SearchOptions.MUSICFREE
  • The SearchOptions enum is used properly throughout the codebase for MusicFree handling
  • The only raw "MUSICFREE" string usage is in a test file and refers to a different constant, unrelated to the search options
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining usage of MUSICFREE type or direct string literals
rg -l "MUSICFREE\." --type ts
rg -l "'MUSICFREE'" --type ts
rg -l "\"MUSICFREE\"" --type ts

Length of output: 136


Script:

#!/bin/bash
# Let's check the actual usage context of setDefaultSearch function
ast-grep --pattern 'setDefaultSearch($_)'

# Also search for SearchOptions enum usage
ast-grep --pattern 'SearchOptions.$_'

# And check the test file content that matched MUSICFREE
cat __tests__/mediafetch/mfsdk.test.ts

Length of output: 2832

src/hooks/useLyricRN.ts (1)

26-26: Verify path handling consistency and data migration

The change from 'lrc/' to 'lrc' directory path needs careful consideration:

  1. Ensure all other file operations use consistent path format
  2. Consider existing files in the old path format

Consider implementing a path normalization utility to ensure consistent path handling across the application.

Also applies to: 44-44

✅ Verification successful

Based on the search results, I can now generate the final response:

Path handling is consistent across the codebase

The codebase shows consistent path handling:

  • All file operations use the same pattern where subfolder is passed as a separate parameter to readTxtFile/writeTxtFile
  • The implementation in fs.ts correctly joins paths using ${fsdirs.DocumentDir}/${subfolder}/${filename}
  • No other instances of hardcoded 'lrc/' paths were found that would need updates
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other instances of lrc path usage
rg -A 2 "('|\")lrc/?" --type ts

# Search for file operations that might need similar updates
rg -A 2 "(readTxtFile|writeTxtFile)" --type ts

Length of output: 2538

src/utils/mediafetch/bilisearch.ts (1)

4-4: LGTM! Good improvement in cookie management

The change to use BILICOOKIES.SESSDATA enum instead of string literals is a good practice that centralizes cookie key management and reduces maintenance overhead.

Also applies to: 22-22

src/components/style.ts (1)

208-213: Review negative margins usage

The use of negative margins could lead to layout inconsistencies across different screen sizes and devices. Consider using positive margins/padding with flex layout instead.

src/components/setting/View.tsx (1)

8-8: LGTM! Good structural improvement

The reorganization of developer settings into a dedicated folder improves code organization.

src/stores/useApp.ts (1)

22-23: LGTM! Clean integration of MFsdk store

The integration of MFsdk store through interface extension and import is well-structured.

Also applies to: 29-30

package.json (1)

34-35: Verify compatibility with downgraded CLI platform packages

The React Native CLI platform packages for Android and iOS have been downgraded from 16.0.2 to 15.1.3. This could potentially impact the build process.

✅ Verification successful

CLI platform packages downgrade is safe to proceed

The downgrade from 16.0.2 to 15.1.3 for React Native CLI platform packages appears safe because:

  1. The project uses standard React Native CLI commands without custom platform-specific configurations
  2. The metro configuration is using the default setup with Sentry integration
  3. The react-native.config.js is minimal without platform-specific customizations
  4. Build configurations in android/build.gradle use standard React Native Gradle plugin setup
  5. The project is on React Native 0.76.5, which is compatible with CLI platform packages version 15.x
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for any breaking changes or known issues between versions

# Check package.json for React Native version compatibility
rg -A 5 '"react-native":\s*"[^"]*"' package.json

# Check for any migration guides or breaking changes in the repository
rg -i -A 5 'migration|breaking.?changes?' .github/ docs/ CHANGELOG.md README.md

Length of output: 495


Script:

#!/bin/bash
# Let's check the React Native version and CLI compatibility by examining the repository

# Check if there are any direct dependencies on these CLI packages in the code
rg -l "@react-native-community/cli-platform-" --type js --type ts

# Check for any build configurations that might be affected
fd "build.gradle|project.pbxproj|metro.config.js"

# Check for any CLI-related configurations
fd "react-native.config.js"

# Look for any CLI-related scripts in package.json
rg '"scripts":\s*{' -A 20 package.json

Length of output: 397


Script:

#!/bin/bash
# Let's check the content of key configuration files

# Check metro config for any CLI-specific settings
cat metro.config.js

# Check react-native config for any platform-specific settings
cat react-native.config.js

# Check package.json scripts (with fixed regex)
rg '"scripts":' -A 20 package.json

# Check the root build.gradle for any CLI-related configurations
cat android/build.gradle

Length of output: 2306

src/utils/ChromeStorage.ts (1)

56-57: LGTM! Type signature update is consistent

The removal of MUSICFREE type from saveDefaultSearch is consistent with the broader refactoring of the MusicFree plugin system.

src/localization/zhcn/translation.json (1)

270-270: LGTM! Warning message is consistent with English translation.

The warning message change from "启用 MusicFree 插件" to "不要使用 后果自负" aligns with the English translation and effectively communicates the risks to users.

src/localization/en/translation.json (1)

256-256: LGTM! Warning message effectively communicates the risk.

The warning message change from "Enable MusicFree plugins" to "Do NOT use, uve been warned." is clear and consistent with the Chinese translation.

src/stores/useSlices.ts (1)

1-10: Verify integration with MFsdk store.

This template appears to be part of the MusicFree SDK restructuring. Consider documenting how this slice template integrates with the new MFsdk store mentioned in the changes.

Run this script to understand the relationship with other stores:

🧰 Tools
🪛 Biome (1.9.4)

[error] 6-6: An empty interface is equivalent to {}.

Safe fix: Use a type alias instead.

(lint/suspicious/noEmptyInterface)

🪛 eslint

[error] 1-1: Resolve error: Cannot find module 'babel-plugin-module-resolver'
Require stack:

  • /home/jailuser/git/node_modules/eslint-import-resolver-babel-module/lib/index.js
  • /home/jailuser/git/node_modules/eslint-module-utils/resolve.js
  • /home/jailuser/git/node_modules/eslint-plugin-import/lib/rules/no-unresolved.js
  • /home/jailuser/git/node_modules/eslint-plugin-import/lib/index.js
  • /home/jailuser/git/node_modules/@eslint/eslintrc/dist/eslintrc.cjs
    at Module._resolveFilename (node:internal/modules/cjs/loader:1248:15)
    at Module._load (node:internal/modules/cjs/loader:1074:27)
    at TracingChannel.traceSync (node:diagnostics_channel:315:14)
    at wrapModuleLoad (node:internal/modules/cjs/loader:217:24)
    at Module.require (node:internal/modules/cjs/loader:1339:12)
    at require (node:internal/modules/helpers:135:16)
    at Object. (/home/jailuser/git/node_modules/eslint-import-resolver-babel-module/lib/index.js:8:5)
    at Module._compile (node:internal/modules/cjs/loader:1546:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1691:10)
    at Module.load (node:internal/modules/cjs/loader:1317:32)

(import/namespace)

Comment on lines +42 to +62
export const fetchMFsdk = async (url: string): Promise<MFsdk[]> => {
try {
const res = await bFetch(url);
const text = await res.text();
try {
const json = JSON.parse(text) as { plugins: { url: string }[] };
const sdks = await Promise.all(json.plugins.map(p => fetchMFsdk(p.url)));
return sdks.flat();
} catch {
// do nothing
}
const loadedSDK = loadEvalPlugin(text, url);
const sdkLocalPath = `${loadedSDK.platform}.${loadedSDK.version}.js`;
loadedSDK.path = sdkLocalPath;
writeTxtFile(sdkLocalPath, [text], mfsdkSubFolder);
return [loadedSDK];
} catch (e) {
logger.warn(`[mfsdk] failed to fetch and parse ${url}: ${e}`);
}
return [];
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Add recursion depth limit to prevent potential stack overflow

The current implementation of fetchMFsdk has no safeguards against deep recursion. While the code handles nested plugin structures, it could potentially lead to a stack overflow or performance issues if malicious or poorly structured JSON is provided. Consider adding a depth parameter with a reasonable limit (e.g., 3-5 levels).

Example locations that need attention:

  • src/utils/mfsdk.ts:42: Add depth parameter to fetchMFsdk function
  • src/utils/mfsdk.ts:48: Check depth limit before recursive calls
🔗 Analysis chain

Gracefully handle deeply nested JSON structures.
In line 48, you recursively call fetchMFsdk on nested plugin URLs. While it looks correct, ensure there's no infinite recursion or extremely deep nesting scenario that might degrade performance.


Let me analyze the code further to check for any safeguards against deep recursion.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
#!/bin/bash
# Check if there's any potential unbounded recursion in fetchMFsdk usage.
rg -A 5 -B 5 'fetchMFsdk'

Length of output: 4885


Script:

#!/bin/bash
# Check the structure of plugin files to understand nesting patterns
ast-grep --pattern 'const json = JSON.parse($_) as { plugins: { url: string }[] }'

Length of output: 177

Comment on lines +129 to +163
export const loadEvalPlugin = (plugin: string, path = 'MEMORY'): MFsdk => {
const env = {
getUserVariables: () => ({}),
os: 'android',
};

const _module: any = { exports: {} };
let _instance: any;
// eslint-disable-next-line no-new-func
_instance = Function(`
'use strict';
return function(require, __musicfree_require, module, exports, console, env, URL) {
${plugin}
}
`)()(
_require,
_require,
_module,
_module.exports,
_console,
env,
URL,
);
if (_module.exports.default) {
_instance = _module.exports.default;
} else {
_instance = _module.exports;
}
return {
..._instance,
path,
regexFetch: searchWrapper(_instance.search, _instance),
resolveURL: resolveURLWrapper(_instance.getMediaSource, _instance),
};
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Ensure plugin code is sandboxed and safe.
You dynamically evaluate plugin code using Function(). Double-check that no malicious code can break out of this environment. You might want to implement additional sandbox checks or constraints.

@@ -224,7 +200,7 @@ const Home = ({
<SettingListItem
icon={Icons.plugins}
settingName="PluginsSetting"
onPress={() => navigation.navigate(VIEW.PLUGINS)}
onPress={() => navigation.navigate(Route.PLUGINS)}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Route refactor alignment.
You are navigating with Route.PLUGINS. Ensure that old references to VIEW.PLUGINS or other enumerations have been fully removed to prevent mismatch.

#!/bin/bash
# Searching entire codebase for references to old "VIEW.PLUGINS"
rg 'VIEW\.PLUGINS'

Comment on lines +25 to +26
const navigate2 = (route: unknown) =>
navigationGlobal.navigate(route as never);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Consider improving type safety of navigate2

The use of unknown type with casting to never bypasses TypeScript's type checking. This could lead to runtime errors if invalid routes are passed.

Consider using a proper type for the route parameter:

-  const navigate2 = (route: unknown) =>
-    navigationGlobal.navigate(route as never);
+  const navigate2 = (route: NoxRoutes) =>
+    navigationGlobal.navigate(route);

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +15 to +24
onSearch={async ({ v, setSnack }) => {
try {
addMFsdks(await fetchMFsdk(v));
} catch (e) {
logger.warn(`[mfsdk] failed to search ${v}: ${e}`);
setSnack({
snackMsg: { success: t('MFSDK.SearchFailMsg') },
});
}
}}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider improving error handling and UX

The error handling could be more informative, and the search operation lacks loading state feedback.

Consider these improvements:

   <SearchBar
     defaultSearchText=""
+    loading={isLoading}
     onSearch={async ({ v, setSnack }) => {
+      if (!v.trim()) {
+        setSnack({
+          snackMsg: { error: t('MFSDK.EmptySearchMsg') },
+        });
+        return;
+      }
+      setIsLoading(true);
       try {
         addMFsdks(await fetchMFsdk(v));
+        setSnack({
+          snackMsg: { success: t('MFSDK.SearchSuccessMsg') },
+        });
       } catch (e) {
         logger.warn(`[mfsdk] failed to search ${v}: ${e}`);
         setSnack({
-          snackMsg: { success: t('MFSDK.SearchFailMsg') },
+          snackMsg: { error: t('MFSDK.SearchFailMsg', { error: e.message }) },
         });
+      } finally {
+        setIsLoading(false);
       }
     }}

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +51 to +55
<IconButton
icon="sync"
style={styles.deleteButton}
onPress={() => fetchMFsdk(sdk.srcUrl).then(replaceMFsdks)}
/>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add loading state and error handling for SDK refresh

The refresh operation should show loading state and handle potential fetch failures.

+const [isRefreshing, setIsRefreshing] = React.useState(false);

 <IconButton
   icon="sync"
   style={styles.deleteButton}
+  disabled={isRefreshing}
   onPress={() => {
+    setIsRefreshing(true);
     fetchMFsdk(sdk.srcUrl)
       .then(replaceMFsdks)
+      .catch(error => {
+        console.error('Failed to refresh SDK:', error);
+        // Consider showing a user-friendly error message
+      })
+      .finally(() => setIsRefreshing(false));
   }}
 />

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +73 to +81
const fallback = () => {
const mfsdks = useNoxSetting.getState().MFsdks;
for (const mfsdk of mfsdks) {
if (mfsdk.platform === song.source) {
return mfsdk.resolveURL(song);
}
}
return result;
}
return fetchBiliUrlPromise({ bvid, cid: String(cid), iOS, noBiliR128Gain });
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add error handling for SDK resolution

The fallback mechanism needs to handle potential failures in SDK URL resolution. Consider wrapping the SDK call in a try-catch block.

Here's a suggested improvement:

  const fallback = () => {
    const mfsdks = useNoxSetting.getState().MFsdks;
    for (const mfsdk of mfsdks) {
      if (mfsdk.platform === song.source) {
-       return mfsdk.resolveURL(song);
+       try {
+         return mfsdk.resolveURL(song);
+       } catch (error) {
+         logger.error(`Failed to resolve URL using ${mfsdk.platform} SDK:`, error);
+         continue;
+       }
      }
    }
    return fetchBiliUrlPromise({ bvid, cid: String(cid), iOS, noBiliR128Gain });
  };

Committable suggestion skipped: line range outside the PR's diff.

@@ -162,6 +166,7 @@ export const useNoxSetting = create<NoxSetting>((set, get, storeApi) => ({
});
const initializedPlayerSetting = val.settings;
set({
MFsdks: await initMFsdk(),
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add error handling for MFsdk initialization

The initMFsdk() call should include error handling to manage initialization failures gracefully.

Consider wrapping the initialization in a try-catch block:

-      MFsdks: await initMFsdk(),
+      MFsdks: await initMFsdk().catch(error => {
+        console.error('Failed to initialize MFsdk:', error);
+        return [];
+      }),
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
MFsdks: await initMFsdk(),
MFsdks: await initMFsdk().catch(error => {
console.error('Failed to initialize MFsdk:', error);
return [];
}),

Comment on lines +131 to +139
case SearchOptions.MUSICFREE: {
const songLists = await Promise.all(
useNoxSetting
.getState()
.MFsdks.map(sdk => sdk.regexFetch({ url: input })),
);
results.songList = songLists.map(v => v.songList).flat();
break;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider error handling for individual SDK failures

The current implementation using Promise.all will fail entirely if any single SDK fetch fails. Consider using Promise.allSettled to handle partial failures gracefully.

-          const songLists = await Promise.all(
-            useNoxSetting
-              .getState()
-              .MFsdks.map(sdk => sdk.regexFetch({ url: input })),
-          );
-          results.songList = songLists.map(v => v.songList).flat();
+          const songLists = await Promise.allSettled(
+            useNoxSetting
+              .getState()
+              .MFsdks.map(sdk => sdk.regexFetch({ url: input })),
+          );
+          results.songList = songLists
+            .filter((result): result is PromiseFulfilledResult<any> => result.status === 'fulfilled')
+            .map(result => result.value.songList)
+            .flat();
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
case SearchOptions.MUSICFREE: {
const songLists = await Promise.all(
useNoxSetting
.getState()
.MFsdks.map(sdk => sdk.regexFetch({ url: input })),
);
results.songList = songLists.map(v => v.songList).flat();
break;
}
case SearchOptions.MUSICFREE: {
const songLists = await Promise.allSettled(
useNoxSetting
.getState()
.MFsdks.map(sdk => sdk.regexFetch({ url: input })),
);
results.songList = songLists
.filter((result): result is PromiseFulfilledResult<any> => result.status === 'fulfilled')
.map(result => result.value.songList)
.flat();
break;
}

Comment on lines +5 to +6
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
export interface Slice {}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider using a type alias instead of an empty interface.

An empty interface is equivalent to {}. Consider using a type alias for better TypeScript practices:

-// eslint-disable-next-line @typescript-eslint/no-empty-object-type
-export interface Slice {}
+export type Slice = Record<string, unknown>;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
export interface Slice {}
export type Slice = Record<string, unknown>;
🧰 Tools
🪛 Biome (1.9.4)

[error] 6-6: An empty interface is equivalent to {}.

Safe fix: Use a type alias instead.

(lint/suspicious/noEmptyInterface)

@lovegaoshi lovegaoshi merged commit 8045ae3 into master Dec 19, 2024
9 of 10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant