2025-06-07 15:14:28 +07:00
|
|
|
import { getAssetByName } from '@revenge-mod/assets'
|
2025-05-09 21:52:36 +07:00
|
|
|
import { TokensModuleId } from '@revenge-mod/discord/common'
|
2025-08-13 01:27:49 +07:00
|
|
|
import { lookupModule } from '@revenge-mod/modules/finders'
|
2025-07-18 02:04:01 +07:00
|
|
|
import {
|
|
|
|
|
createFilterGenerator,
|
feat!: module finders refactor (#6)
- Renamed `byX` filters to `withX`.
It is more correct. For example: You don't lookup, wait for, or get modules **BY** props. You lookup, wait for, and get modules **WITH** props.
- Renamed `*byImportedPath` to `*withImportedPath`
For consistency with the above change.
- Renamed `getModule` to `getModules`.
The API allows getting multiple modules and not just a single one. Types are renamed as well.
`getModuleByImportedPath` remains the same as it only gets one single module with a unique imported path.
- `withX` filter **helpers** removed.
They can now be replaced with the new capability-based `and` filter.
- `preferExports` and `moduleStateAware` filters removed.
They can now be replaced with the new capability-based `and` filter.
- Composite finders renamed.
`some` -> `or`, `every` -> `and`
- Composite finders takes a capability-based approach.
- Filter generators now need to attach runtime flag to let the system know whether the generated filter can be used to filter modules without proper exports or not.
## Misc.
- Removed useless unsub call in Profile Badges
- Use `queueMicrotask` with `asap`
# Features
## Capability-based approach to composite filters
```js
// Old
byProps(...).withDependencies(...)
// Old, same as: preferExports(byProps(...), byDependencies(...))
every(byDependencies(...), byProps(...))
// Old, ordering matters, this would fail unexpectedly!
every(byProps(...), byDependencies(...))
// New
withProps(...).and(withDependencies(...))
// New (as well), ordering doesn't matter, this has the same result as above
withDependencies(...).and(withProps(...))
```
2025-08-30 09:19:57 +07:00
|
|
|
withDependencies,
|
2025-07-18 02:04:01 +07:00
|
|
|
} from '@revenge-mod/modules/finders/filters'
|
2025-06-03 16:24:58 +07:00
|
|
|
import {
|
2025-07-10 21:23:39 +07:00
|
|
|
ReactJSXRuntimeModuleId,
|
2025-06-03 16:24:58 +07:00
|
|
|
ReactModuleId,
|
|
|
|
|
ReactNativeModuleId,
|
|
|
|
|
} from '@revenge-mod/react'
|
2025-10-28 01:01:17 +07:00
|
|
|
import {
|
|
|
|
|
FilterFlag,
|
|
|
|
|
FilterScopes,
|
|
|
|
|
} from '../../modules/src/finders/filters/constants'
|
2025-07-18 02:04:01 +07:00
|
|
|
import type {
|
|
|
|
|
Filter,
|
|
|
|
|
FilterGenerator,
|
|
|
|
|
} from '@revenge-mod/modules/finders/filters'
|
2025-05-08 18:52:57 +07:00
|
|
|
import type { FC } from 'react'
|
|
|
|
|
|
2025-05-10 01:15:21 +07:00
|
|
|
// [React, ReactJsxRuntime, (Tokens), (BaseIconImage), (Asset), 2]
|
2025-05-08 18:52:57 +07:00
|
|
|
// Asset = relativeDep(1)
|
2025-06-03 16:24:58 +07:00
|
|
|
const IconComponentFilter = [
|
|
|
|
|
ReactModuleId,
|
2025-07-10 21:23:39 +07:00
|
|
|
ReactJSXRuntimeModuleId,
|
2025-06-03 16:24:58 +07:00
|
|
|
TokensModuleId,
|
2025-08-25 20:55:01 +07:00
|
|
|
null,
|
|
|
|
|
null,
|
2025-06-03 16:24:58 +07:00
|
|
|
2,
|
|
|
|
|
]
|
2025-05-08 18:52:57 +07:00
|
|
|
|
2025-05-10 01:15:21 +07:00
|
|
|
// Generated IconComponents that have multiple assets, there is no specific length, so the filter has to be generated on-the-fly.
|
|
|
|
|
// [React, ReactNative, ReactJsxRuntime, (Tokens), (BaseIconImage), (...Assets), 2]
|
|
|
|
|
// ...Assets = relativeDep(1..n)
|
|
|
|
|
const MultiIconComponentFilterBase = [
|
|
|
|
|
ReactModuleId,
|
|
|
|
|
ReactNativeModuleId,
|
2025-07-10 21:23:39 +07:00
|
|
|
ReactJSXRuntimeModuleId,
|
2025-05-10 01:15:21 +07:00
|
|
|
TokensModuleId,
|
2025-08-25 20:55:01 +07:00
|
|
|
null,
|
2025-05-10 01:15:21 +07:00
|
|
|
]
|
|
|
|
|
|
feat!: module finders refactor (#6)
- Renamed `byX` filters to `withX`.
It is more correct. For example: You don't lookup, wait for, or get modules **BY** props. You lookup, wait for, and get modules **WITH** props.
- Renamed `*byImportedPath` to `*withImportedPath`
For consistency with the above change.
- Renamed `getModule` to `getModules`.
The API allows getting multiple modules and not just a single one. Types are renamed as well.
`getModuleByImportedPath` remains the same as it only gets one single module with a unique imported path.
- `withX` filter **helpers** removed.
They can now be replaced with the new capability-based `and` filter.
- `preferExports` and `moduleStateAware` filters removed.
They can now be replaced with the new capability-based `and` filter.
- Composite finders renamed.
`some` -> `or`, `every` -> `and`
- Composite finders takes a capability-based approach.
- Filter generators now need to attach runtime flag to let the system know whether the generated filter can be used to filter modules without proper exports or not.
## Misc.
- Removed useless unsub call in Profile Badges
- Use `queueMicrotask` with `asap`
# Features
## Capability-based approach to composite filters
```js
// Old
byProps(...).withDependencies(...)
// Old, same as: preferExports(byProps(...), byDependencies(...))
every(byDependencies(...), byProps(...))
// Old, ordering matters, this would fail unexpectedly!
every(byProps(...), byDependencies(...))
// New
withProps(...).and(withDependencies(...))
// New (as well), ordering doesn't matter, this has the same result as above
withDependencies(...).and(withProps(...))
```
2025-08-30 09:19:57 +07:00
|
|
|
export type WithGeneratedIconComponent = FilterGenerator<
|
2025-07-18 02:04:01 +07:00
|
|
|
<N extends string>(
|
|
|
|
|
name: N,
|
|
|
|
|
...assets: string[]
|
2025-10-28 01:01:17 +07:00
|
|
|
) => Filter<{
|
|
|
|
|
Result: { [K in N]: FC<any> }
|
|
|
|
|
RequiresExports: boolean
|
|
|
|
|
Scopes: [
|
|
|
|
|
typeof FilterScopes.Uninitialized,
|
|
|
|
|
typeof FilterScopes.Initialized,
|
|
|
|
|
]
|
|
|
|
|
}>
|
2025-07-18 02:04:01 +07:00
|
|
|
>
|
2025-05-08 18:52:57 +07:00
|
|
|
|
2025-07-18 02:04:01 +07:00
|
|
|
/**
|
|
|
|
|
* Filter by icon component name and asset names.
|
|
|
|
|
*
|
|
|
|
|
* @param names The component name, then the asset names if the component has multiple assets. *
|
|
|
|
|
* @example
|
|
|
|
|
* ```ts
|
|
|
|
|
* const [CopyIconModule] = lookupModule(
|
feat!: module finders refactor (#6)
- Renamed `byX` filters to `withX`.
It is more correct. For example: You don't lookup, wait for, or get modules **BY** props. You lookup, wait for, and get modules **WITH** props.
- Renamed `*byImportedPath` to `*withImportedPath`
For consistency with the above change.
- Renamed `getModule` to `getModules`.
The API allows getting multiple modules and not just a single one. Types are renamed as well.
`getModuleByImportedPath` remains the same as it only gets one single module with a unique imported path.
- `withX` filter **helpers** removed.
They can now be replaced with the new capability-based `and` filter.
- `preferExports` and `moduleStateAware` filters removed.
They can now be replaced with the new capability-based `and` filter.
- Composite finders renamed.
`some` -> `or`, `every` -> `and`
- Composite finders takes a capability-based approach.
- Filter generators now need to attach runtime flag to let the system know whether the generated filter can be used to filter modules without proper exports or not.
## Misc.
- Removed useless unsub call in Profile Badges
- Use `queueMicrotask` with `asap`
# Features
## Capability-based approach to composite filters
```js
// Old
byProps(...).withDependencies(...)
// Old, same as: preferExports(byProps(...), byDependencies(...))
every(byDependencies(...), byProps(...))
// Old, ordering matters, this would fail unexpectedly!
every(byProps(...), byDependencies(...))
// New
withProps(...).and(withDependencies(...))
// New (as well), ordering doesn't matter, this has the same result as above
withDependencies(...).and(withProps(...))
```
2025-08-30 09:19:57 +07:00
|
|
|
* withGeneratedIconComponent('CopyIcon'),
|
2025-07-18 02:04:01 +07:00
|
|
|
* )
|
|
|
|
|
* if (CopyIconModule) {
|
|
|
|
|
* const { CopyIcon } = CopyIconModule
|
|
|
|
|
* // Use CopyIcon as a React component
|
|
|
|
|
* }
|
|
|
|
|
* ```
|
|
|
|
|
* @example
|
|
|
|
|
* ```ts
|
|
|
|
|
* const [CircleXIconModule] = lookupModule(
|
feat!: module finders refactor (#6)
- Renamed `byX` filters to `withX`.
It is more correct. For example: You don't lookup, wait for, or get modules **BY** props. You lookup, wait for, and get modules **WITH** props.
- Renamed `*byImportedPath` to `*withImportedPath`
For consistency with the above change.
- Renamed `getModule` to `getModules`.
The API allows getting multiple modules and not just a single one. Types are renamed as well.
`getModuleByImportedPath` remains the same as it only gets one single module with a unique imported path.
- `withX` filter **helpers** removed.
They can now be replaced with the new capability-based `and` filter.
- `preferExports` and `moduleStateAware` filters removed.
They can now be replaced with the new capability-based `and` filter.
- Composite finders renamed.
`some` -> `or`, `every` -> `and`
- Composite finders takes a capability-based approach.
- Filter generators now need to attach runtime flag to let the system know whether the generated filter can be used to filter modules without proper exports or not.
## Misc.
- Removed useless unsub call in Profile Badges
- Use `queueMicrotask` with `asap`
# Features
## Capability-based approach to composite filters
```js
// Old
byProps(...).withDependencies(...)
// Old, same as: preferExports(byProps(...), byDependencies(...))
every(byDependencies(...), byProps(...))
// Old, ordering matters, this would fail unexpectedly!
every(byProps(...), byDependencies(...))
// New
withProps(...).and(withDependencies(...))
// New (as well), ordering doesn't matter, this has the same result as above
withDependencies(...).and(withProps(...))
```
2025-08-30 09:19:57 +07:00
|
|
|
* withGeneratedIconComponent(
|
2025-07-18 02:04:01 +07:00
|
|
|
* 'CircleXIcon',
|
|
|
|
|
* 'CircleXIcon-secondary',
|
|
|
|
|
* 'CircleXIcon-primary',
|
|
|
|
|
* ),
|
|
|
|
|
* )
|
|
|
|
|
* ```
|
|
|
|
|
*/
|
feat!: module finders refactor (#6)
- Renamed `byX` filters to `withX`.
It is more correct. For example: You don't lookup, wait for, or get modules **BY** props. You lookup, wait for, and get modules **WITH** props.
- Renamed `*byImportedPath` to `*withImportedPath`
For consistency with the above change.
- Renamed `getModule` to `getModules`.
The API allows getting multiple modules and not just a single one. Types are renamed as well.
`getModuleByImportedPath` remains the same as it only gets one single module with a unique imported path.
- `withX` filter **helpers** removed.
They can now be replaced with the new capability-based `and` filter.
- `preferExports` and `moduleStateAware` filters removed.
They can now be replaced with the new capability-based `and` filter.
- Composite finders renamed.
`some` -> `or`, `every` -> `and`
- Composite finders takes a capability-based approach.
- Filter generators now need to attach runtime flag to let the system know whether the generated filter can be used to filter modules without proper exports or not.
## Misc.
- Removed useless unsub call in Profile Badges
- Use `queueMicrotask` with `asap`
# Features
## Capability-based approach to composite filters
```js
// Old
byProps(...).withDependencies(...)
// Old, same as: preferExports(byProps(...), byDependencies(...))
every(byDependencies(...), byProps(...))
// Old, ordering matters, this would fail unexpectedly!
every(byProps(...), byDependencies(...))
// New
withProps(...).and(withDependencies(...))
// New (as well), ordering doesn't matter, this has the same result as above
withDependencies(...).and(withProps(...))
```
2025-08-30 09:19:57 +07:00
|
|
|
export const withGeneratedIconComponent = createFilterGenerator<
|
|
|
|
|
Parameters<WithGeneratedIconComponent>
|
2025-07-18 02:04:01 +07:00
|
|
|
>(
|
|
|
|
|
(names, id, exports) => {
|
2025-07-22 19:00:20 +07:00
|
|
|
if (typeof exports === 'object') {
|
2025-07-27 16:33:33 +07:00
|
|
|
if (typeof exports[names[0]] === 'function')
|
|
|
|
|
return Object.keys(exports).length === 1
|
2025-07-18 02:04:01 +07:00
|
|
|
} else {
|
|
|
|
|
let filter = IconComponentFilter
|
2025-05-08 18:52:57 +07:00
|
|
|
|
2025-07-18 02:04:01 +07:00
|
|
|
if (names.length > 1) {
|
|
|
|
|
const mids = []
|
2025-05-10 01:15:21 +07:00
|
|
|
|
2025-07-18 02:04:01 +07:00
|
|
|
for (let i = 1; i < names.length; i++) {
|
|
|
|
|
const name = names[i]
|
|
|
|
|
const mid = getAssetByName(name)?.moduleId
|
2025-07-23 13:46:31 +07:00
|
|
|
// Module ID can never be zero, so if it's falsy, it means the asset was not found.
|
|
|
|
|
if (!mid) return false
|
2025-07-18 02:04:01 +07:00
|
|
|
|
|
|
|
|
mids.push(mid)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
filter = [...MultiIconComponentFilterBase, ...mids, 2]
|
|
|
|
|
} else {
|
|
|
|
|
const [name] = names
|
|
|
|
|
|
|
|
|
|
const mid = getAssetByName(name)?.moduleId
|
2025-07-23 13:46:31 +07:00
|
|
|
// Module ID can never be zero, so if it's falsy, it means the asset was not found.
|
|
|
|
|
if (!mid) return false
|
2025-05-10 01:15:21 +07:00
|
|
|
|
2025-07-18 02:04:01 +07:00
|
|
|
IconComponentFilter[4] = mid
|
|
|
|
|
}
|
2025-05-10 01:15:21 +07:00
|
|
|
|
feat!: module finders refactor (#6)
- Renamed `byX` filters to `withX`.
It is more correct. For example: You don't lookup, wait for, or get modules **BY** props. You lookup, wait for, and get modules **WITH** props.
- Renamed `*byImportedPath` to `*withImportedPath`
For consistency with the above change.
- Renamed `getModule` to `getModules`.
The API allows getting multiple modules and not just a single one. Types are renamed as well.
`getModuleByImportedPath` remains the same as it only gets one single module with a unique imported path.
- `withX` filter **helpers** removed.
They can now be replaced with the new capability-based `and` filter.
- `preferExports` and `moduleStateAware` filters removed.
They can now be replaced with the new capability-based `and` filter.
- Composite finders renamed.
`some` -> `or`, `every` -> `and`
- Composite finders takes a capability-based approach.
- Filter generators now need to attach runtime flag to let the system know whether the generated filter can be used to filter modules without proper exports or not.
## Misc.
- Removed useless unsub call in Profile Badges
- Use `queueMicrotask` with `asap`
# Features
## Capability-based approach to composite filters
```js
// Old
byProps(...).withDependencies(...)
// Old, same as: preferExports(byProps(...), byDependencies(...))
every(byDependencies(...), byProps(...))
// Old, ordering matters, this would fail unexpectedly!
every(byProps(...), byDependencies(...))
// New
withProps(...).and(withDependencies(...))
// New (as well), ordering doesn't matter, this has the same result as above
withDependencies(...).and(withProps(...))
```
2025-08-30 09:19:57 +07:00
|
|
|
return withDependencies(filter)(id, exports)
|
2025-07-18 02:04:01 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false
|
|
|
|
|
},
|
feat!: module finders refactor (#6)
- Renamed `byX` filters to `withX`.
It is more correct. For example: You don't lookup, wait for, or get modules **BY** props. You lookup, wait for, and get modules **WITH** props.
- Renamed `*byImportedPath` to `*withImportedPath`
For consistency with the above change.
- Renamed `getModule` to `getModules`.
The API allows getting multiple modules and not just a single one. Types are renamed as well.
`getModuleByImportedPath` remains the same as it only gets one single module with a unique imported path.
- `withX` filter **helpers** removed.
They can now be replaced with the new capability-based `and` filter.
- `preferExports` and `moduleStateAware` filters removed.
They can now be replaced with the new capability-based `and` filter.
- Composite finders renamed.
`some` -> `or`, `every` -> `and`
- Composite finders takes a capability-based approach.
- Filter generators now need to attach runtime flag to let the system know whether the generated filter can be used to filter modules without proper exports or not.
## Misc.
- Removed useless unsub call in Profile Badges
- Use `queueMicrotask` with `asap`
# Features
## Capability-based approach to composite filters
```js
// Old
byProps(...).withDependencies(...)
// Old, same as: preferExports(byProps(...), byDependencies(...))
every(byDependencies(...), byProps(...))
// Old, ordering matters, this would fail unexpectedly!
every(byProps(...), byDependencies(...))
// New
withProps(...).and(withDependencies(...))
// New (as well), ordering doesn't matter, this has the same result as above
withDependencies(...).and(withProps(...))
```
2025-08-30 09:19:57 +07:00
|
|
|
names => `revenge.utils.discord.generatedIconComponent(${names.join(',')})`,
|
|
|
|
|
FilterFlag.Dynamic,
|
2025-10-28 01:01:17 +07:00
|
|
|
FilterScopes.Uninitialized | FilterScopes.Initialized,
|
feat!: module finders refactor (#6)
- Renamed `byX` filters to `withX`.
It is more correct. For example: You don't lookup, wait for, or get modules **BY** props. You lookup, wait for, and get modules **WITH** props.
- Renamed `*byImportedPath` to `*withImportedPath`
For consistency with the above change.
- Renamed `getModule` to `getModules`.
The API allows getting multiple modules and not just a single one. Types are renamed as well.
`getModuleByImportedPath` remains the same as it only gets one single module with a unique imported path.
- `withX` filter **helpers** removed.
They can now be replaced with the new capability-based `and` filter.
- `preferExports` and `moduleStateAware` filters removed.
They can now be replaced with the new capability-based `and` filter.
- Composite finders renamed.
`some` -> `or`, `every` -> `and`
- Composite finders takes a capability-based approach.
- Filter generators now need to attach runtime flag to let the system know whether the generated filter can be used to filter modules without proper exports or not.
## Misc.
- Removed useless unsub call in Profile Badges
- Use `queueMicrotask` with `asap`
# Features
## Capability-based approach to composite filters
```js
// Old
byProps(...).withDependencies(...)
// Old, same as: preferExports(byProps(...), byDependencies(...))
every(byDependencies(...), byProps(...))
// Old, ordering matters, this would fail unexpectedly!
every(byProps(...), byDependencies(...))
// New
withProps(...).and(withDependencies(...))
// New (as well), ordering doesn't matter, this has the same result as above
withDependencies(...).and(withProps(...))
```
2025-08-30 09:19:57 +07:00
|
|
|
) as WithGeneratedIconComponent
|
2025-05-10 01:15:21 +07:00
|
|
|
|
2025-07-18 02:04:01 +07:00
|
|
|
/**
|
|
|
|
|
* Looks up a generated icon component by its name and asset names.
|
|
|
|
|
*
|
|
|
|
|
* @param names The component name, then the asset names if the component has multiple assets.
|
|
|
|
|
* @returns The icon component, or `undefined` if it could not be found.
|
|
|
|
|
*/
|
|
|
|
|
export function lookupGeneratedIconComponent<N extends string>(
|
|
|
|
|
...names: [N, ...string[]]
|
|
|
|
|
) {
|
2025-07-23 13:46:31 +07:00
|
|
|
for (const name of names) {
|
|
|
|
|
let badFind = false
|
|
|
|
|
if (__DEV__) {
|
|
|
|
|
if (!getAssetByName(name)) {
|
|
|
|
|
badFind = true
|
|
|
|
|
warnUnregisteredAsset(name)
|
|
|
|
|
}
|
|
|
|
|
} else if (!getAssetByName(name)) return
|
|
|
|
|
if (__DEV__ && badFind) return
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-28 01:01:17 +07:00
|
|
|
const [module] = lookupModule(withGeneratedIconComponent(...names))
|
2025-07-18 02:04:01 +07:00
|
|
|
|
|
|
|
|
return module?.[names[0]] as FC<any> | undefined
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function warnUnregisteredAsset(name: string) {
|
|
|
|
|
nativeLoggingHook(
|
|
|
|
|
`\u001b[31mAsset "${name}" is not registered. Cannot get module ID to filter by.\u001b[0m`,
|
|
|
|
|
2,
|
|
|
|
|
)
|
2025-05-08 18:52:57 +07:00
|
|
|
}
|