Skip to content

Commit

Permalink
Add support for importing external modules via HTTP and HTTPS
Browse files Browse the repository at this point in the history
Signed-off-by: William So <polyipseity@gmail.com>
  • Loading branch information
polyipseity committed Aug 15, 2023
1 parent 70662d3 commit a0bea02
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .changeset/dry-ladybugs-pretend.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"obsidian-modules": minor
---

Add support for importing external modules via HTTP and HTTPS.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ This file is automatically opened on first install. You can reopen it in setting

- Reuse JavaScript and TypeScript code from anywhere in your vault on all platforms.
- No configuration needed.
- Resolves relative paths, vault paths, Markdown links, and wikilinks.
- Resolves relative paths, vault paths, Markdown links, wikilinks, and external links.
- Loads Markdown files as code.
- Supports using other modules inside modules.
- Loads CommonJS (`module.exports`) and ES modules (`export`).
Expand Down
2 changes: 2 additions & 0 deletions sources/require/require.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
} from "@polyipseity/obsidian-plugin-library"
import {
CompositeResolve,
ExternalResolve,
InternalModulesResolve,
MarkdownLinkResolve,
RelativePathResolve,
Expand Down Expand Up @@ -50,6 +51,7 @@ export function loadRequire(context: ModulesPlugin): void {
new VaultPathResolve(context, transpiles),
new WikilinkResolve(context, transpiles),
new MarkdownLinkResolve(context, transpiles),
new ExternalResolve(context),
])
context.register(patchWindows(workspace, self0 =>
patchRequire(context, self0, resolve)))
Expand Down
51 changes: 50 additions & 1 deletion sources/require/resolve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
dynamicRequireSync,
} from "@polyipseity/obsidian-plugin-library"
import type { Context, Resolve, Resolved } from "obsidian-modules"
import { TFile, getLinkpath, normalizePath } from "obsidian"
import { TFile, getLinkpath, normalizePath, requestUrl } from "obsidian"
import type { AsyncOrSync } from "ts-essentials"
import type { ModulesPlugin } from "../main.js"
import type { Transpile } from "./transpile.js"
Expand Down Expand Up @@ -508,3 +508,52 @@ function parseWikilink(
if (str !== link || isUndefined(path) || isUndefined(display)) { return null }
return { display: display || (str.includes("|") ? "" : path), path }
}

export class ExternalResolve
extends AbstractResolve
implements Resolve {
protected readonly identities: Record<string, {
readonly code: string
} | null | undefined> = {}

public constructor(context: ModulesPlugin) {
super(context)
}

public override resolve(id: string, _1: Context): Resolved | null {
const href = this.normalizeURL(id)
if (href === null) { return null }
const { identities: { [href]: identity } } = this
return (identity && { code: identity.code, id: href, identity }) ?? null
}

public override async aresolve(
id: string,
_1: Context,
): Promise<Resolved | null> {
const href = this.normalizeURL(id)
if (href === null) { return null }
let { identities: { [href]: identity } } = this
if (isUndefined(identity)) {
let code = null
try {
({ text: code } = await requestUrl(href))
} catch (error) {
self.console.debug(error)
}
// eslint-disable-next-line no-multi-assign
this.identities[href] = identity = code === null ? null : { code }
}
return identity && { code: identity.code, id: href, identity }
}

protected normalizeURL(id: string): string | null {
try {
const { href, protocol } = new URL(id)
if ((/^https?:$/u).test(protocol)) { return href }
} catch (error) {
self.console.debug(error)
}
return null
}
}

0 comments on commit a0bea02

Please sign in to comment.