Skip to main content

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}