From 81c12af219abc7b86cc551605e8eace96debb497 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Fri, 23 Jul 2021 12:12:24 +0200 Subject: [PATCH] feat: json support --- README.md | 53 ++++++++++++++++++++++++-------------------------- lib/index.d.ts | 6 +++--- lib/index.mjs | 48 +++++++++++++++++++++++---------------------- test/eval.mjs | 2 ++ test/hello.mjs | 4 +++- 5 files changed, 58 insertions(+), 55 deletions(-) diff --git a/README.md b/README.md index bb17cb2..00b2243 100644 --- a/README.md +++ b/README.md @@ -134,21 +134,6 @@ await loadModule('./hello.mjs', { from: import.meta.url }) Options are same as `evalModule`. -### `readModule` - -Resolve module path and read source contents. (currently only file protocol supported) - -```js -import { resolve, readModule } from 'mlly' - -const indexPath = await resolve('./index.mjs', { from: import.meta.url }) - -// { code: '...", url: '...' } -console.log(await readModule(indexPath)) -``` - -Options are same as `resolve`. - ### `transformModule` - Resolves all relative imports will be resolved @@ -161,20 +146,8 @@ console.log(transformModule(`console.log(import.meta.url)`), { url: 'test.mjs' } Options are same as `evalModule`. -### `toDataURL` - -Convert code to [`data:`](https://nodejs.org/api/esm.html#esm_data_imports) URL using base64 encoding. - -```js -import { toDataURL } from 'mlly' - -console.log(toDataURL(` - // This is an example - console.log('Hello world') -`)) -``` -## Other utils +## Other Utils ### `fileURLToPath` @@ -201,6 +174,30 @@ import { ensureProtocol } from 'mlly' console.log(normalizeid('/foo/bar.js')) ``` +### `loadURL` + +Read source contents of a URL. (currently only file protocol supported) + +```js +import { resolve, loadURL } from 'mlly' + +const url = await resolve('./index.mjs', { from: import.meta.url }) +console.log(await loadURL(url)) +``` + +### `toDataURL` + +Convert code to [`data:`](https://nodejs.org/api/esm.html#esm_data_imports) URL using base64 encoding. + +```js +import { toDataURL } from 'mlly' + +console.log(toDataURL(` + // This is an example + console.log('Hello world') +`)) +``` + ## License MIT diff --git a/lib/index.d.ts b/lib/index.d.ts index d8e4d0c..254543b 100644 --- a/lib/index.d.ts +++ b/lib/index.d.ts @@ -28,13 +28,13 @@ export interface EvaluateOptions extends ResolveOptions { url?: string } -export function loadModule (id: string, opts?: EvaluateOptions) : Promise +export function loadModule (url: string, opts?: EvaluateOptions) : Promise export function evalModule (code: string, opts?: EvaluateOptions) : Promise -export function readModule (id: string, opts?: EvaluateOptions) : Promise<{ url: string, code: string}> export function transformModule(code: string, opts?: EvaluateOptions) : Promise -export function toDataURL(code: string) : string // Utils export function fileURLToPath (id: URL | string) : string export function normalizeid (id: URL | string) : string +export function loadURL (id: string) : Promise +export function toDataURL(code: string) : string diff --git a/lib/index.mjs b/lib/index.mjs index 66ac035..ccfa4a0 100644 --- a/lib/index.mjs +++ b/lib/index.mjs @@ -112,11 +112,9 @@ export function createResolve (defaults) { const ESM_IMPORT_RE = /(?<=import .* from ['"])([^'"]+)(?=['"])|(?<=export .* from ['"])([^'"]+)(?=['"])|(?<=import\s*['"])([^'"]+)(?=['"])|(?<=import\s*\(['"])([^'"]+)(?=['"]\))/g export async function loadModule (id, opts = {}) { - const { url, code } = await readModule(id, opts) - return evalModule(code, { - url, - ...opts - }) + const url = await resolve(id, opts) + const code = await loadURL(url, opts) + return evalModule(code, { url, ...opts }) } export async function evalModule (code, opts = {}) { @@ -124,18 +122,10 @@ export async function evalModule (code, opts = {}) { return import(toDataURL(transformed, opts)) } -export async function readModule (id, opts) { - const url = await resolve(id, opts) - const code = await fsp.readFile(fileURLToPath(url), 'utf-8') - return { url, code } -} - export async function transformModule (code, opts) { - // Use url <> from as defaults of each other - if (!opts.url && opts.from) { - opts.url = opts.from - } else if (opts.url && !opts.from) { - opts.from = opts.url + // Convert JSON to module + if (opts.url && opts.url.endsWith('.json')) { + return 'export default ' + code } // Resolve relative imports @@ -149,11 +139,6 @@ export async function transformModule (code, opts) { return code } -export function toDataURL (code) { - const base64 = Buffer.from(code).toString('base64') - return `data:text/javascript;base64,${base64}` -} - export async function resolveImports (code, opts) { const imports = Array.from(code.matchAll(ESM_IMPORT_RE)).map(m => m[0]) if (!imports.length) { @@ -162,8 +147,15 @@ export async function resolveImports (code, opts) { const uniqueImports = Array.from(new Set(imports)) const resolved = new Map() - const resolveOpts = { ...opts, from: opts.url } - await Promise.all(uniqueImports.map(async (id) => { resolved.set(id, await resolve(id, resolveOpts)) })) + const resolveOpts = { from: opts.from || opts.url, ...opts } + await Promise.all(uniqueImports.map(async (id) => { + let url = await resolve(id, resolveOpts) + if (url.endsWith('.json')) { + const code = await loadURL(url) + url = toDataURL(await transformModule(code, { url })) + } + resolved.set(id, url) + })) const re = new RegExp(uniqueImports.map(i => `(${i})`).join('|'), 'g') return code.replace(re, id => resolved.get(id)) @@ -191,6 +183,16 @@ export function normalizeid (id) { return 'file://' + normalizeSlash(id) } +export async function loadURL (url) { + const code = await fsp.readFile(fileURLToPath(url), 'utf-8') + return code +} + +export function toDataURL (code) { + const base64 = Buffer.from(code).toString('base64') + return `data:text/javascript;base64,${base64}` +} + function normalizeSlash (str) { return str.replace(/\\/g, '/') } diff --git a/test/eval.mjs b/test/eval.mjs index fe94bdb..1dcb9c7 100644 --- a/test/eval.mjs +++ b/test/eval.mjs @@ -10,3 +10,5 @@ await evalModule(` }) await loadModule('./hello.mjs', { from: import.meta.url }) + +console.log(await loadModule('../package.json', { from: import.meta.url }).then(r => r.default.name)) diff --git a/test/hello.mjs b/test/hello.mjs index c1ab03b..9360819 100644 --- a/test/hello.mjs +++ b/test/hello.mjs @@ -1 +1,3 @@ -console.log('Hello world from', import.meta.url) +import pkg from '../package.json' + +console.log('Hello world from', pkg.name, import.meta.url)