2025-04-10 02:03:56 +07:00
|
|
|
import { isModuleExportBad } from '../metro'
|
2025-03-30 23:32:17 +07:00
|
|
|
|
2025-04-05 20:52:09 +07:00
|
|
|
import type { If } from '@revenge-mod/utils/types'
|
2025-04-29 18:41:22 +07:00
|
|
|
import type { Metro } from '../../types'
|
2025-03-30 23:32:17 +07:00
|
|
|
import type { Filter } from './filters'
|
|
|
|
|
|
2025-04-05 20:52:09 +07:00
|
|
|
export type RunFilterOptions = {
|
2025-03-30 23:32:17 +07:00
|
|
|
/**
|
2025-04-30 23:46:21 +07:00
|
|
|
* Whether to skip checking the default export.
|
2025-04-05 20:52:09 +07:00
|
|
|
*
|
|
|
|
|
* @default false
|
|
|
|
|
*/
|
2025-04-30 23:46:21 +07:00
|
|
|
skipDefault?: boolean
|
2025-04-05 20:52:09 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export type RunFilterReturnExportsOptions<ReturnNamespace extends boolean = boolean> = RunFilterOptions &
|
|
|
|
|
If<
|
|
|
|
|
ReturnNamespace,
|
|
|
|
|
{
|
|
|
|
|
/**
|
2025-04-30 23:46:21 +07:00
|
|
|
* Whether to return the whole module with all exports instead of just the default export **if the default export matches**.
|
2025-04-05 20:52:09 +07:00
|
|
|
*
|
|
|
|
|
* @default false
|
|
|
|
|
*/
|
2025-04-30 23:46:21 +07:00
|
|
|
returnNamespace: true
|
2025-04-05 20:52:09 +07:00
|
|
|
},
|
|
|
|
|
{
|
2025-04-30 23:46:21 +07:00
|
|
|
returnNamespace?: false
|
2025-04-05 20:52:09 +07:00
|
|
|
}
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
const FilterResultFlags = {
|
|
|
|
|
/**
|
2025-04-30 23:46:21 +07:00
|
|
|
* A module was found, without exports filtering.
|
2025-03-30 23:32:17 +07:00
|
|
|
*/
|
|
|
|
|
Found: 1,
|
|
|
|
|
/**
|
2025-04-05 20:52:09 +07:00
|
|
|
* A module was found, and it is an ES module, and the filter matched the module namespace.
|
2025-03-30 23:32:17 +07:00
|
|
|
*/
|
|
|
|
|
ESModuleNamespace: 2,
|
|
|
|
|
/**
|
2025-04-05 20:52:09 +07:00
|
|
|
* A module was found, and it is an ES module, and the filter matched the default export.
|
2025-03-30 23:32:17 +07:00
|
|
|
*/
|
|
|
|
|
ESModuleDefault: 3,
|
2025-04-30 23:46:21 +07:00
|
|
|
/**
|
|
|
|
|
* A module was found, and it is a CommonJS module, and the filter matched the module namespace.
|
|
|
|
|
*/
|
|
|
|
|
CJSModuleNamespace: 4,
|
|
|
|
|
/**
|
|
|
|
|
* A module was found, and it is a CommonJS module, and the filter matched the default export.
|
|
|
|
|
*/
|
|
|
|
|
CJSModuleDefault: 5,
|
2025-03-30 23:32:17 +07:00
|
|
|
}
|
|
|
|
|
|
2025-04-05 20:52:09 +07:00
|
|
|
export type FilterResultFlag = (typeof FilterResultFlags)[keyof typeof FilterResultFlags]
|
2025-03-30 23:32:17 +07:00
|
|
|
|
2025-04-05 20:52:09 +07:00
|
|
|
// The reason this returns a flag is because flags are never falsy, while exports may be falsy when using ID-only filters (eg. `byDependencies`).
|
2025-04-09 03:42:06 +07:00
|
|
|
|
|
|
|
|
// Currently, we only have options that are relevant for checking exports
|
|
|
|
|
// If we add more options later on, do NOT forget about
|
|
|
|
|
// adding them here, and passing them in the lookup* functions
|
2025-04-27 14:42:24 +07:00
|
|
|
export function runFilter(filter: Filter<any, false>, id: Metro.ModuleID): FilterResultFlag | undefined
|
2025-04-09 03:42:06 +07:00
|
|
|
|
|
|
|
|
export function runFilter(
|
|
|
|
|
filter: Filter,
|
|
|
|
|
id: Metro.ModuleID,
|
|
|
|
|
exports: Metro.ModuleExports,
|
|
|
|
|
options?: RunFilterOptions,
|
2025-04-27 14:42:24 +07:00
|
|
|
): FilterResultFlag | undefined
|
2025-04-09 03:42:06 +07:00
|
|
|
|
|
|
|
|
export function runFilter(
|
|
|
|
|
filter: Filter,
|
2025-03-30 23:32:17 +07:00
|
|
|
id: Metro.ModuleID,
|
2025-04-09 03:42:06 +07:00
|
|
|
exports?: Metro.ModuleExports,
|
2025-04-05 20:52:09 +07:00
|
|
|
options?: RunFilterOptions,
|
2025-04-27 14:42:24 +07:00
|
|
|
): FilterResultFlag | undefined {
|
2025-04-30 23:46:21 +07:00
|
|
|
if (exports == null) {
|
|
|
|
|
if ((filter as Filter<any, false>)(id)) {
|
|
|
|
|
// TODO(modules/finders/caches)
|
|
|
|
|
return FilterResultFlags.Found
|
|
|
|
|
}
|
2025-03-30 23:32:17 +07:00
|
|
|
|
2025-04-30 23:46:21 +07:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const defaultExport = exports.default
|
|
|
|
|
if (!options?.skipDefault && !isModuleExportBad(defaultExport) && filter(id, defaultExport)) {
|
|
|
|
|
if (exports.__esModule) {
|
2025-03-30 23:32:17 +07:00
|
|
|
// TODO(modules/finders/caches::esm::default)
|
2025-04-05 20:52:09 +07:00
|
|
|
return FilterResultFlags.ESModuleDefault
|
2025-03-30 23:32:17 +07:00
|
|
|
}
|
|
|
|
|
|
2025-04-30 23:46:21 +07:00
|
|
|
// TODO(modules/finders/caches::cjs::default)
|
|
|
|
|
return FilterResultFlags.CJSModuleDefault
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (filter(id, exports)) {
|
|
|
|
|
if (exports.__esModule) {
|
2025-03-30 23:32:17 +07:00
|
|
|
// TODO(modules/finders/caches::esm::namespace)
|
2025-04-05 20:52:09 +07:00
|
|
|
return FilterResultFlags.ESModuleNamespace
|
2025-03-30 23:32:17 +07:00
|
|
|
}
|
2025-04-30 23:46:21 +07:00
|
|
|
|
|
|
|
|
// TODO(modules/finders/caches::cjs::namespace)
|
|
|
|
|
return FilterResultFlags.CJSModuleNamespace
|
2025-03-30 23:32:17 +07:00
|
|
|
}
|
|
|
|
|
}
|
2025-04-05 20:52:09 +07:00
|
|
|
|
2025-04-16 14:23:48 +07:00
|
|
|
export function exportsFromFilterResultFlag(
|
|
|
|
|
flag: FilterResultFlag,
|
2025-04-05 20:52:09 +07:00
|
|
|
exports: Metro.ModuleExports,
|
|
|
|
|
options?: RunFilterReturnExportsOptions,
|
|
|
|
|
) {
|
2025-04-30 23:46:21 +07:00
|
|
|
if (
|
|
|
|
|
(flag === FilterResultFlags.ESModuleDefault || flag === FilterResultFlags.CJSModuleDefault) &&
|
|
|
|
|
!options?.returnNamespace
|
|
|
|
|
)
|
|
|
|
|
return exports.default
|
|
|
|
|
|
2025-04-16 14:23:48 +07:00
|
|
|
return exports
|
2025-04-05 20:52:09 +07:00
|
|
|
}
|