Skip to content

Commit

Permalink
improve wildcard expansion for exported nested wildcard
Browse files Browse the repository at this point in the history
  • Loading branch information
bumblehead committed Feb 25, 2024
1 parent b0c9660 commit b8a87bd
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 15 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# changelog

* 2.1.5 _Tbd.23.2024_
* 2.1.5 _Feb.24.2024_
* [add tests](https://github.com/iambumblehead/resolvewithplus/pull/66) for path pattern resolver
* [resolve more nested export](https://github.com/iambumblehead/resolvewithplus/pull/66) wildcard-scenarious
* 2.1.4 _Jan.23.2024_
* [resolve nested exports defined on named-properties](https://github.com/iambumblehead/resolvewithplus/pull/65) with wildcards, eg `exports: { './*': { default: './src/*/index.js' } }` resolves [this issue at esmock](https://github.com/iambumblehead/esmock/issues/289)
* 2.1.3 _Oct.20.2023_
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "resolvewithplus",
"version": "2.1.4",
"version": "2.1.5",
"description": "resolvewith with extra power",
"readmeFilename": "README.md",
"license": "ISC",
Expand Down
63 changes: 50 additions & 13 deletions resolvewithplus.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,54 @@ const getesmkeyvalglobreplaced = (esmkey, esmval, pathlocal) => {
return globmatch && esmval.replace('*', globmatch)
}

// inherently complex to explain, this function "expands" the
// requested idpath to include exported wildcard path parts
//
// imagine this idpath is imported,
// 'thepackage/myfile'
//
// imagine 'thepackage' exports the following,
// {
// "exports": {
// "./*": {
// "require": "./src/*.js",
// "import": "./types/*.d.ts"
// }
// }
// }
//
// this function returns the path './src/myfile.js'
//
// this is done in the following way,
// * ensure esmkey './*' matches idpath './myfile'
// * calculate idpath's substring matching the wildcard, eg 'myfile'
// * split the esmkey around the asterisk to get './' and ''
// * remove the matches from idpath './myfile' to get 'myfile'
// * replace glob refpath './src/*.js" with matched 'myfile', './src/myfile.js'
//
// ex,
// ('./mystuff', './*', './src/*/index.js') => './src/mystuff/index.js'
// ('./mystuff/index', './*', './src/*.js') => './src/mystuff/index.js'
const getesmkeyidpathrefpathexpanded = (idpath, esmkey, refpath, xp = null) => {
const asteriskIndex = esmkey.indexOf('*') || 0
const asteriskBefore = esmkey.slice(0, asteriskIndex)
const asteriskAfter = esmkey.slice(asteriskIndex + 1)

if (!(idpath.startsWith(asteriskBefore)
&& idpath.endsWith(asteriskAfter)))
return null

// strip esmkey before and after from idpath,
// put remaining idpath inside refpath asterisk
const asteriskFromIdPath = idpath
.slice(-asteriskAfter)
.slice(asteriskBefore.length)

xp = refpath.replace('*', asteriskFromIdPath)

return xp
}

// esm patterns may have globby key AND path values as in this example,
//
// "exports": { "./features/*.js": "./src/features/*.js" },
Expand Down Expand Up @@ -203,20 +251,9 @@ const getesmkeyvalmatch = (esmkey, esmval, idpath, opts, keyvalmx = false) => {
// }
// ```
if (isobj(esmval) && esmkey.includes('*')) {
const resolvedkey = idpath // 'mystuff'
const expandedkey = path.posix.join(idpath, esmkey) // 'mystuff/*'
const expandedspec = Object.keys(esmval).reduce((exp, nestkey) => {
const pathfirstdir = esmval[nestkey] // ./src/a/b.js -> 'src'
.split(/\.?\//).find(e => e)

// eg,
// getesmkeyvalglobreplaced(
// 'mystuff/*', 'src/mystuff/*', 'mystuff/index.js')
// 'src/mystuff/index.js'
exp[nestkey] = getesmkeyvalglobreplaced(
expandedkey,
path.posix.join(pathfirstdir, expandedkey),
path.posix.join(resolvedkey, esmval[nestkey].split('*')[1]))
exp[nestkey] = getesmkeyidpathrefpathexpanded(
idpath, esmkey, esmval[nestkey])

return exp
}, {})
Expand Down
14 changes: 14 additions & 0 deletions tests/tests-basic/nodejsexample_14_exports/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "nodejsexample_14_exports",
"type": "module",
"repository": {
"type": "git",
"url": "git+https://github.com/iambumblehead/resolvewithplus.git"
},
"exports": {
"./*": {
"require": "./src/*.js",
"import": "./src/*.js"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default 'mystuff'
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
declare const mystuff: string

export {
mystuff as default
}
1 change: 1 addition & 0 deletions tests/tests-basic/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"nodejsexample_11_exports": "file:nodejsexample_11_exports",
"nodejsexample_12_exports": "file:nodejsexample_12_exports",
"nodejsexample_13_exports": "file:nodejsexample_13_exports",
"nodejsexample_14_exports": "file:nodejsexample_14_exports",
"resolvewithplus": "file:.."
},
"workspaces": [
Expand Down
20 changes: 20 additions & 0 deletions tests/tests-basic/tests-export-patterns.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,25 @@ test('should mock exports from nodejsexample_13_exports, asterisk dir', () => {
noderesolvedindex)
})

// "asterisk-directory named-property wildcard exports"
// from: https://github.com/iambumblehead/esmock/issues/293 @Jeff-Tham
// {
// "exports": {
// "./*": {
// "require": "./src/*.js",
// "import": "./types/*.d.ts"
// }
// }
// }
test('should mock exports from nodejsexample_14_exports, asterisk dir', () => {
const noderesolvedindex = toresolvefileurl(
'./nodejsexample_14_exports/src/mystuff/index.js')

assert.strictEqual(
resolvewithplus('nodejsexample_14_exports/mystuff/index'),
noderesolvedindex)
})

// "exports": './lib/index.js',
// "exports": { "import": "./lib/index.js" },
// "exports": { ".": "./lib/index.js" },
Expand All @@ -315,3 +334,4 @@ test('should return exports sugar', () => {
resolvewithplus.esmparse({ '.': { import: './lib/index.js' } }, 'import'),
'./lib/index.js')
})

0 comments on commit b8a87bd

Please sign in to comment.