Skip to content

Commit

Permalink
Merge pull request #65 from iambumblehead/resolve-asterisk-folder-name
Browse files Browse the repository at this point in the history
resolve named-properties that are also asterisk folder name
  • Loading branch information
iambumblehead authored Jan 23, 2024
2 parents f22a56d + 749f131 commit d3e2912
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 14 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# changelog

* 2.1.4 _Jan.01.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_
* resolve full path from package.json "main", "browser" and "module" definitions. resolves [this issue at esmock.](https://github.com/iambumblehead/esmock/issues/260)
* 2.1.2 _Oct.19.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.3",
"version": "2.1.4",
"description": "resolvewith with extra power",
"readmeFilename": "README.md",
"license": "ISC",
Expand Down
60 changes: 47 additions & 13 deletions resolvewithplus.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,33 +183,67 @@ const getesmkeyvalglobreplaced = (esmkey, esmval, pathlocal) => {
//
// All instances of * on the right hand side will then be replaced
// with this value, including if it contains any / separators.
const getesmkeyvalmatch = (esmkey, esmval, path, keyvalmatch = false) => {
if (ispathesmmatch(esmkey, path)) {
if (esmval.includes('*')) {
if (ispathesmmatch(esmval, path)) {
keyvalmatch = path
const getesmkeyvalmatch = (esmkey, esmval, idpath, opts, keyvalmx = false) => {
if (ispathesmmatch(esmkey, idpath)) {
if (String(esmval).includes('*')) {
if (ispathesmmatch(esmval, idpath)) {
keyvalmx = idpath
} else if (esmkey.includes('*') && esmkey !== esmval) {
keyvalmatch = getesmkeyvalglobreplaced(esmkey, esmval, path)
keyvalmx = getesmkeyvalglobreplaced(esmkey, esmval, idpath)
}
} else {
keyvalmatch = esmval
// if below condition is true, assume exports look this way and,
// * the namespace defined on the key is valid for the moduleId,
// * expanded key used as replacement for nested path value wildcard
// ```
// "exports": {
// "./*": {
// "default": "./src/*/index.js",
// "types": "./types/*/index.d.ts"
// }
// }
// ```
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]))

return exp
}, {})

// eslint-disable-next-line no-use-before-define
return esmparse(expandedspec, idpath, opts)
}

keyvalmx = keyvalmx || esmval
}
}

return keyvalmatch
return keyvalmx
}

const esmparselist = (list, spec, specifier, key = list[0]) => {
const esmparselist = (list, spec, specifier, opts, key = list[0]) => {
if (!list.length) return null

const isKeyValid = isESMImportSubpathRe.test(specifier)
? isESMImportSubpathRe.test(key)
: isRelPathRe.test(key)

return (isKeyValid
&& typeof spec[key] === 'string'
&& getesmkeyvalmatch(key, spec[key], specifier))
|| esmparselist(list.slice(1), spec, specifier)
&& (typeof spec[key] === 'string' || isobj(spec[key]))
&& getesmkeyvalmatch(key, spec[key], specifier, opts))
|| esmparselist(list.slice(1), spec, specifier, opts)
}

const esmparse = (spec, specifier, opts = {}) => {
Expand Down Expand Up @@ -266,7 +300,7 @@ const esmparse = (spec, specifier, opts = {}) => {
// "./lib/*": "./lib/*.js"
// }
if (!indexval)
indexval = esmparselist(Object.keys(spec), spec, specifier)
indexval = esmparselist(Object.keys(spec), spec, specifier, opts)

// "exports": "./lib/index.js",
// "exports": { "import": "./lib/index.js" },
Expand Down
14 changes: 14 additions & 0 deletions tests/tests-basic/nodejsexample_13_exports/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "nodejsexample_13_exports",
"type": "module",
"repository": {
"type": "git",
"url": "git+https://github.com/iambumblehead/resolvewithplus.git"
},
"exports": {
"./*": {
"default": "./src/*/index.js",
"types": "./types/*/index.d.ts"
}
}
}
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 @@ -18,6 +18,7 @@
"nodejsexample_10_exports": "file:nodejsexample_10_exports",
"nodejsexample_11_exports": "file:nodejsexample_11_exports",
"nodejsexample_12_exports": "file:nodejsexample_12_exports",
"nodejsexample_13_exports": "file:nodejsexample_13_exports",
"resolvewithplus": "file:.."
},
"workspaces": [
Expand Down
19 changes: 19 additions & 0 deletions tests/tests-basic/tests-export-patterns.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,25 @@ test('should mock exports from nodejsexample_12_exports, nested cond', () => {
noderesolvedfeaturenode)
})

// "asterisk-directory named-property exports"
// from: https://github.com/iambumblehead/esmock/issues/289 @dschnare
// {
// "exports": {
// "./*": {
// "default": "./src/*/index.js",
// "types": "./types/*/index.d.ts"
// }
// }
// }
test('should mock exports from nodejsexample_13_exports, asterisk dir', () => {
const noderesolvedindex = toresolvefileurl(
'./nodejsexample_13_exports/src/mystuff/index.js')

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

// "exports": './lib/index.js',
// "exports": { "import": "./lib/index.js" },
// "exports": { ".": "./lib/index.js" },
Expand Down

0 comments on commit d3e2912

Please sign in to comment.