chore(providence-analytics): allow deprecated export map notation

This commit is contained in:
Thijs Louisse 2022-09-21 21:48:16 +02:00 committed by Thijs Louisse
parent 2028277cd1
commit ba16e23b00
2 changed files with 76 additions and 19 deletions

View file

@ -218,18 +218,17 @@ function normalizeLocalPathWithDotSlash(localPathWithoutDotSlash) {
/** /**
* @param {{val:object|string;nodeResolveMode:string}} opts * @param {{val:object|string;nodeResolveMode:string}} opts
* @returns {string} * @returns {string|null}
*/ */
function getStringOrObjectValOfExportMapEntry({ val, nodeResolveMode, packageRootPath }) { function getStringOrObjectValOfExportMapEntry({ valObjOrStr, nodeResolveMode }) {
if (typeof val !== 'object') { if (typeof valObjOrStr !== 'object') {
return val; return valObjOrStr;
} }
if (!val[nodeResolveMode]) { if (!valObjOrStr[nodeResolveMode]) {
throw new Error( // This is allowed: it makes sense to have an entrypoint on the root for typescript, not for others
`[getExportMapExports]: nodeResolveMode "${nodeResolveMode}" not found in package.json of package ${packageRootPath}`, return null;
);
} }
return val[nodeResolveMode]; return valObjOrStr[nodeResolveMode];
} }
/** /**
@ -355,7 +354,12 @@ class InputDataService {
/** @type {ProjectInputDataWithMeta['entries'][]} */ /** @type {ProjectInputDataWithMeta['entries'][]} */
const newEntries = []; const newEntries = [];
projectObj.entries.forEach(entry => { projectObj.entries.forEach(entry => {
const code = fs.readFileSync(entry, 'utf8'); let code;
try {
code = fs.readFileSync(entry, 'utf8');
} catch (e) {
LogService.error(`Could not find "${entry}"`);
}
const file = getFilePathRelativeFromRoot( const file = getFilePathRelativeFromRoot(
toPosixPath(entry), toPosixPath(entry),
toPosixPath(projectObj.project.path), toPosixPath(projectObj.project.path),
@ -613,7 +617,7 @@ class InputDataService {
} }
/** /**
* @param {object} exports * @param {{[key:string]: string|object}} exports
* @param {object} opts * @param {object} opts
* @param {'default'|'development'|string} [opts.nodeResolveMode='default'] * @param {'default'|'development'|string} [opts.nodeResolveMode='default']
* @param {string} opts.packageRootPath * @param {string} opts.packageRootPath
@ -622,23 +626,36 @@ class InputDataService {
static getPathsFromExportMap(exports, { nodeResolveMode = 'default', packageRootPath }) { static getPathsFromExportMap(exports, { nodeResolveMode = 'default', packageRootPath }) {
const exportMapPaths = []; const exportMapPaths = [];
for (const [key, val] of Object.entries(exports)) { for (const [key, valObjOrStr] of Object.entries(exports)) {
if (!key.includes('*')) { let resolvedKey = key;
let resolvedVal = getStringOrObjectValOfExportMapEntry({ valObjOrStr, nodeResolveMode });
if (resolvedVal === null) {
// eslint-disable-next-line no-continue
continue;
}
// Allow older specs like "./__element-definitions/" : "./__element-definitions/" to also work,
// so we normalize them to the new spec
if (resolvedVal.endsWith?.('/') && resolvedKey.endsWith('/')) {
resolvedVal += '*';
resolvedKey += '*';
}
if (!resolvedKey.includes('*')) {
exportMapPaths.push({ exportMapPaths.push({
internal: getStringOrObjectValOfExportMapEntry({ val, nodeResolveMode, packageRootPath }), internal: resolvedVal,
exposed: key, exposed: resolvedKey,
}); });
// eslint-disable-next-line no-continue // eslint-disable-next-line no-continue
continue; continue;
} }
const valueToUseForGlob = stripDotSlashFromLocalPath( const valueToUseForGlob = stripDotSlashFromLocalPath(resolvedVal);
getStringOrObjectValOfExportMapEntry({ val, nodeResolveMode, packageRootPath }),
);
// Generate all possible entries via glob, first strip './' // Generate all possible entries via glob, first strip './'
const internalExportMapPathsForKeyRaw = glob.sync(valueToUseForGlob, { const internalExportMapPathsForKeyRaw = glob.sync(valueToUseForGlob, {
cwd: packageRootPath, cwd: packageRootPath,
nodir: true,
}); });
const exposedExportMapPathsForKeyRaw = internalExportMapPathsForKeyRaw.map(pathInside => { const exposedExportMapPathsForKeyRaw = internalExportMapPathsForKeyRaw.map(pathInside => {
@ -648,7 +665,7 @@ class InputDataService {
const [, variablePart] = pathInside.match( const [, variablePart] = pathInside.match(
new RegExp(valueToUseForGlob.replace('*', '(.*)')), new RegExp(valueToUseForGlob.replace('*', '(.*)')),
); );
return key.replace('*', variablePart); return resolvedKey.replace('*', variablePart);
}); });
const internalExportMapPathsForKey = internalExportMapPathsForKeyRaw.map(filePath => const internalExportMapPathsForKey = internalExportMapPathsForKeyRaw.map(filePath =>
normalizeLocalPathWithDotSlash(filePath), normalizeLocalPathWithDotSlash(filePath),

View file

@ -655,6 +655,46 @@ build/
]); ]);
}); });
}); });
describe('Deprecated root mappings ("/" instead of "/*")', () => {
it('works for values defined as strings', async () => {
const fakeFs = {
'/my/proj/internal-folder/file-a.js': 'export const a = 1;',
'/my/proj/internal-folder/file-b.js': 'export const b = 2;',
};
mock(fakeFs);
const exports = {
// An old spec that
'./exposed-folder/': './internal-folder/',
};
const exportMapPaths = await InputDataService.getPathsFromExportMap(exports, {
packageRootPath: '/my/proj',
});
expect(exportMapPaths).to.eql([
{ internal: './internal-folder/file-a.js', exposed: './exposed-folder/file-a.js' },
{ internal: './internal-folder/file-b.js', exposed: './exposed-folder/file-b.js' },
]);
});
it('works for values defined as objects', async () => {
const fakeFs = {
'/my/proj/internal-folder/file-a.js': 'export const a = 1;',
'/my/proj/internal-folder/file-b.js': 'export const b = 2;',
};
mock(fakeFs);
const exports = {
// An old spec that
'./exposed-folder/': { default: './internal-folder/' },
};
const exportMapPaths = await InputDataService.getPathsFromExportMap(exports, {
packageRootPath: '/my/proj',
});
expect(exportMapPaths).to.eql([
{ internal: './internal-folder/file-a.js', exposed: './exposed-folder/file-a.js' },
{ internal: './internal-folder/file-b.js', exposed: './exposed-folder/file-b.js' },
]);
});
});
}); });
}); });
}); });