yapi_core/extensions/discovery.rs
1//! Which files load as extensions: pi's extension entry rules
2//! (`core/extensions/loader.ts` in pi `v1.0.0`).
3
4use std::path::{Path, PathBuf};
5
6use crate::packages::resolve::{Manifest, ResourceType};
7
8/// Whether the extension entry `path` is a native extension, a WebAssembly
9/// component, rather than a pi extension that runs in yapi-js.
10pub fn is_native(path: &Path) -> bool {
11 path.extension()
12 .is_some_and(|extension| extension == "wasm")
13}
14
15/// The entry points of extension directory `dir`: what its manifest declares,
16/// else `index.ts` or `index.js`.
17pub fn entries(dir: &Path) -> Option<Vec<PathBuf>> {
18 // shortcut: a chest.toml that does not parse is left out here unreported,
19 // and the resolver reports only a package root's. Pass the problems
20 // through when a discovered extension folder's need reporting too.
21 if let (Some(manifest), _) = Manifest::read(dir) {
22 let declared: Vec<PathBuf> = manifest
23 .get(ResourceType::Extensions)
24 .into_iter()
25 .flatten()
26 .map(|entry| crate::tools::path::resolve_lexically(dir, Path::new(entry)))
27 .filter(|path| path.exists())
28 .collect();
29 if !declared.is_empty() {
30 return Some(declared);
31 }
32 }
33 ["index.ts", "index.js"]
34 .iter()
35 .map(|name| dir.join(name))
36 .find(|path| path.exists())
37 .map(|path| vec![path])
38}