Skip to content

Commit 5826950

Browse files
feat: adding support for child lookups
1 parent 8a03c5e commit 5826950

File tree

9 files changed

+1090
-44
lines changed

9 files changed

+1090
-44
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ cjs
22
mjs
33
node_modules
44
*.tgz
5+
coverage

index.ts

Lines changed: 30 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { spawn } from 'child_process'
33
import { mkdir, readFile, writeFile, stat, utimes } from 'fs/promises'
44
import dbg from 'debug'
55
import * as path from 'path'
6+
import { getMatcher, normalize } from './util'
67

78
const debug = dbg('@tradle/lambda-plugins')
89

@@ -199,47 +200,24 @@ async function assertInstalled (plugins: FNOrResult<string[]>, { tmpDir, maxAge
199200
}
200201
}
201202

202-
type Cause = {
203-
useImport: boolean,
204-
cause: string
205-
}
206-
207-
const CAUSE_FALLBACK: Cause = { cause: 'require', useImport: false }
208-
const CAUSE_TYPE: Cause = { cause: 'import because of type=module', useImport: true }
209-
const CAUSE_MODULE: Cause = { cause: 'import because of a defined module', useImport: true }
210-
const CAUSE_DOT_EXPORT: Cause = { cause: 'import because of exports["."]', useImport: true }
211-
const CAUSE_DOT_ANY: Cause = { cause: 'import because of exports["./*"]', useImport: true }
212-
213-
function fuzzyChooseImport (pkg: any): Cause {
214-
if (pkg.type === 'module') return CAUSE_TYPE
215-
if (pkg.module !== undefined) return CAUSE_MODULE
216-
if (pkg.exports) {
217-
if (pkg.exports['.']?.import !== undefined)
218-
return CAUSE_DOT_EXPORT
219-
if (pkg.exports['./*']?.import !== undefined)
220-
return CAUSE_DOT_ANY
221-
}
222-
return CAUSE_FALLBACK
223-
}
224-
225-
async function loadData (name: string, depPath: string, pkg: any): Promise<any> {
226-
const { cause, useImport } = fuzzyChooseImport(pkg)
227-
debug('Loading package for %s from %s (%s)', name, depPath, cause)
228-
return useImport ? await import(depPath) : require(depPath)
229-
}
230-
231203
async function loadPackage (name: string, depPath: string): Promise<any> {
232204
const pkgPath = path.join(depPath, 'package.json')
233-
debug('Loading package.json for %s from %s', name, pkgPath)
234-
const data = await readFile(pkgPath, 'utf-8')
235-
return JSON.parse(data)
205+
let raw = '{}'
206+
try {
207+
raw = await readFile(pkgPath, 'utf-8')
208+
debug('Using package.json for %s from %s', name, pkgPath)
209+
} catch (err) {
210+
// Package json is optional
211+
debug('No package.json found at %s, using regular lookup', pkgPath)
212+
}
213+
return JSON.parse(raw)
236214
}
237215

238216
export class Plugin {
239217
readonly name: string
240218
readonly path: string
241219

242-
#data: Promise<any> | undefined
220+
#data: { [child: string]: Promise<any> } | undefined
243221
#pkg: Promise<any> | undefined
244222

245223
constructor (name: string, path: string) {
@@ -256,13 +234,26 @@ export class Plugin {
256234
return pkg
257235
}
258236

259-
data (opts?: { force?: boolean }): Promise<any> {
260-
let data = this.#data
261-
if (data === undefined || opts?.force) {
262-
data = this.package(opts).then(pkg => loadData(this.name, this.path, pkg))
263-
this.#data = data
237+
async #loadData (child: string, force: boolean) {
238+
const pkg = await this.package({ force })
239+
const matcher = getMatcher(this.path, pkg)
240+
const mjs = matcher(child, 'module')
241+
if (mjs !== undefined && mjs.location !== null) {
242+
debug('Importing package for %s from %s (%s)', this.name, mjs.location, mjs.cause)
243+
return await import(mjs.location)
264244
}
265-
return data
245+
const cjs = matcher(child, 'commonjs')
246+
if (cjs !== undefined && cjs.location !== null) {
247+
debug('Requiring package for %s from %s (%s)', this.name, cjs.location, cjs.cause)
248+
return require(cjs.location)
249+
}
250+
throw new Error(`Can not require or import a package for ${this.name} at ${this.path}`)
251+
}
252+
253+
data (opts?: { force?: boolean, child?: string }): Promise<any> {
254+
const all = this.#data ?? (this.#data = {})
255+
const child = normalize(opts?.child)
256+
return all[child] ?? (all[child] = this.#loadData(child, opts?.force ?? false))
266257
}
267258
}
268259

0 commit comments

Comments
 (0)