turbopack_core/resolve/
plugin.rs1use anyhow::Result;
2use rustc_hash::FxHashSet;
3use turbo_rcstr::RcStr;
4use turbo_tasks::{ResolvedVc, Value, Vc};
5use turbo_tasks_fs::{FileSystemPath, glob::Glob};
6
7use crate::{
8 reference_type::ReferenceType,
9 resolve::{ResolveResultOption, parse::Request},
10};
11
12#[turbo_tasks::value]
14pub struct AfterResolvePluginCondition {
15 root: ResolvedVc<FileSystemPath>,
16 glob: ResolvedVc<Glob>,
17}
18
19#[turbo_tasks::value_impl]
20impl AfterResolvePluginCondition {
21 #[turbo_tasks::function]
22 pub fn new(root: ResolvedVc<FileSystemPath>, glob: ResolvedVc<Glob>) -> Vc<Self> {
23 AfterResolvePluginCondition { root, glob }.cell()
24 }
25
26 #[turbo_tasks::function]
27 pub async fn matches(&self, fs_path: Vc<FileSystemPath>) -> Result<Vc<bool>> {
28 let root = self.root.await?;
29 let glob = self.glob.await?;
30
31 let path = fs_path.await?;
32
33 if let Some(path) = root.get_path_to(&path) {
34 if glob.matches(path) {
35 return Ok(Vc::cell(true));
36 }
37 }
38
39 Ok(Vc::cell(false))
40 }
41}
42
43#[turbo_tasks::value]
45pub enum BeforeResolvePluginCondition {
46 Request(ResolvedVc<Glob>),
47 Modules(FxHashSet<RcStr>),
48}
49
50#[turbo_tasks::value_impl]
51impl BeforeResolvePluginCondition {
52 #[turbo_tasks::function]
53 pub async fn from_modules(modules: ResolvedVc<Vec<RcStr>>) -> Result<Vc<Self>> {
54 Ok(BeforeResolvePluginCondition::Modules(modules.await?.iter().cloned().collect()).cell())
55 }
56
57 #[turbo_tasks::function]
58 pub fn from_request_glob(glob: ResolvedVc<Glob>) -> Vc<Self> {
59 BeforeResolvePluginCondition::Request(glob).cell()
60 }
61}
62
63#[turbo_tasks::value_impl]
64impl BeforeResolvePluginCondition {
65 #[turbo_tasks::function]
66 pub async fn matches(&self, request: Vc<Request>) -> Result<Vc<bool>> {
67 Ok(Vc::cell(match self {
68 BeforeResolvePluginCondition::Request(glob) => match request.await?.request() {
69 Some(request) => glob.await?.matches(request.as_str()),
70 None => false,
71 },
72 BeforeResolvePluginCondition::Modules(modules) => {
73 if let Request::Module { module, .. } = &*request.await? {
74 modules.contains(module)
75 } else {
76 false
77 }
78 }
79 }))
80 }
81}
82
83#[turbo_tasks::value_trait]
84pub trait BeforeResolvePlugin {
85 fn before_resolve_condition(self: Vc<Self>) -> Vc<BeforeResolvePluginCondition>;
86
87 fn before_resolve(
88 self: Vc<Self>,
89 lookup_path: Vc<FileSystemPath>,
90 reference_type: Value<ReferenceType>,
91 request: Vc<Request>,
92 ) -> Vc<ResolveResultOption>;
93}
94
95#[turbo_tasks::value_trait]
96pub trait AfterResolvePlugin {
97 fn after_resolve_condition(self: Vc<Self>) -> Vc<AfterResolvePluginCondition>;
99
100 fn after_resolve(
104 self: Vc<Self>,
105 fs_path: Vc<FileSystemPath>,
106 lookup_path: Vc<FileSystemPath>,
107 reference_type: Value<ReferenceType>,
108 request: Vc<Request>,
109 ) -> Vc<ResolveResultOption>;
110}