turbopack_core/resolve/
plugin.rs1use anyhow::Result;
2use turbo_rcstr::RcStr;
3use turbo_tasks::{ReadRef, ResolvedVc, Vc};
4use turbo_tasks_fs::{FileSystemPath, glob::Glob};
5
6use crate::{
7 reference_type::ReferenceType,
8 resolve::{ResolveResultOption, parse::Request},
9};
10
11#[turbo_tasks::value(serialization = "skip")]
17pub enum AfterResolvePluginCondition {
18 Glob {
19 root: FileSystemPath,
20 glob: ReadRef<Glob>,
21 },
22 Always,
24 Never,
25}
26
27#[turbo_tasks::value_impl]
28impl AfterResolvePluginCondition {
29 #[turbo_tasks::function]
30 pub async fn new_with_glob(root: FileSystemPath, glob: ResolvedVc<Glob>) -> Result<Vc<Self>> {
31 let glob = glob.await?;
32 Ok(AfterResolvePluginCondition::Glob { root, glob }.cell())
33 }
34}
35
36impl AfterResolvePluginCondition {
37 pub fn matches(&self, fs_path: &FileSystemPath) -> bool {
39 match self {
40 AfterResolvePluginCondition::Glob { root, glob } => {
41 root.get_path_to(fs_path).is_some_and(|p| glob.matches(p))
42 }
43 AfterResolvePluginCondition::Always => true,
44 AfterResolvePluginCondition::Never => false,
45 }
46 }
47}
48
49#[turbo_tasks::value(shared, serialization = "skip")]
51pub enum BeforeResolvePluginCondition {
52 Request(ReadRef<Glob>),
53 Modules(ReadRef<Vec<RcStr>>),
54 Always,
56 Never,
57}
58
59#[turbo_tasks::value_impl]
60impl BeforeResolvePluginCondition {
61 #[turbo_tasks::function]
62 pub async fn from_modules(modules: ResolvedVc<Vec<RcStr>>) -> Result<Vc<Self>> {
63 Ok(BeforeResolvePluginCondition::Modules(modules.await?).cell())
64 }
65
66 #[turbo_tasks::function]
67 pub async fn from_request_glob(glob: ResolvedVc<Glob>) -> Result<Vc<Self>> {
68 Ok(BeforeResolvePluginCondition::Request(glob.await?).cell())
69 }
70}
71
72impl BeforeResolvePluginCondition {
73 pub fn matches(&self, request: &Request) -> bool {
75 match self {
76 BeforeResolvePluginCondition::Request(glob) => match request.request() {
77 Some(request) => glob.matches(request.as_str()),
78 None => false,
79 },
80 BeforeResolvePluginCondition::Modules(modules) => {
81 if let Request::Module { module, .. } = request {
82 modules.iter().any(|m| module.is_match(m))
83 } else {
84 false
85 }
86 }
87 BeforeResolvePluginCondition::Always => true,
88 BeforeResolvePluginCondition::Never => false,
89 }
90 }
91}
92
93#[turbo_tasks::value_trait]
94pub trait BeforeResolvePlugin {
95 fn before_resolve_condition(&self) -> Vc<BeforeResolvePluginCondition>;
96
97 #[turbo_tasks::function]
98 fn before_resolve(
99 self: Vc<Self>,
100 lookup_path: FileSystemPath,
101 reference_type: ReferenceType,
102 request: Vc<Request>,
103 ) -> Vc<ResolveResultOption>;
104}
105
106#[turbo_tasks::value_trait]
107pub trait AfterResolvePlugin {
108 fn after_resolve_condition(&self) -> Vc<AfterResolvePluginCondition>;
110
111 #[turbo_tasks::function]
115 fn after_resolve(
116 self: Vc<Self>,
117 fs_path: FileSystemPath,
118 lookup_path: FileSystemPath,
119 reference_type: ReferenceType,
120 request: Vc<Request>,
121 ) -> Vc<ResolveResultOption>;
122}