use std::rc::Rc;
use deno_core::{
ModuleLoadOptions, ModuleLoadReferrer, ModuleLoadResponse, ModuleLoader, ModuleResolveResponse,
ModuleSource, ModuleSourceCode, ModuleSpecifier, ModuleType, ResolutionKind,
};
use deno_error::JsErrorBox;
pub(crate) const NAME: &str = "apiplant";
const URL: &str = "apiplant:module";
pub(crate) const SOURCE: &str = include_str!("../assets/apiplant.js");
pub(crate) struct Loader;
impl Loader {
pub(crate) fn shared() -> Rc<dyn ModuleLoader> {
Rc::new(Loader)
}
}
impl ModuleLoader for Loader {
fn resolve(
&self,
specifier: &str,
referrer: &str,
kind: ResolutionKind,
) -> ModuleResolveResponse {
if specifier == NAME || specifier == URL {
return ModuleSpecifier::parse(URL).map_err(JsErrorBox::from_err);
}
if kind == ResolutionKind::MainModule {
return deno_core::resolve_import(specifier, referrer).map_err(JsErrorBox::from_err);
}
Err(JsErrorBox::generic(format!(
"cannot import `{specifier}`: apiplant does not bundle TypeScript \
functions, so `apiplant` is the only module a function can import"
)))
}
fn load(
&self,
module_specifier: &ModuleSpecifier,
_maybe_referrer: Option<&ModuleLoadReferrer>,
_options: ModuleLoadOptions,
) -> ModuleLoadResponse {
if module_specifier.as_str() != URL {
return ModuleLoadResponse::Sync(Err(JsErrorBox::generic(format!(
"cannot load `{module_specifier}`: only `apiplant` is available"
))));
}
ModuleLoadResponse::Sync(Ok(ModuleSource::new(
ModuleType::JavaScript,
ModuleSourceCode::String(deno_core::FastString::from_static(SOURCE)),
module_specifier,
None,
)))
}
}