-
Notifications
You must be signed in to change notification settings - Fork 255
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
core: move to src, add TypeScript and rollup #2296
Merged
Merged
Changes from all commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
7a50c55
core: move to src, add TypeScript and rollup
4fd507b
core: move to src, add TypeScript and rollup
8c184e9
core: move to src, add TypeScript and rollup
0364394
core: move to src, add TypeScript and rollup
9d14f59
core: move to src, add TypeScript and rollup
12ddb22
add export @bugsnag/core/clone-client
92d4e9e
add jest custom resolver to handle packager.exports field
07cb860
copy jest dir into container
43995bc
fix test:types
2235492
remove jest-node-exports-resolver
076402b
Merge branch 'integration/typescript' into plat-12947
5765a17
add missing types package to test fixture
5c128f3
test: :adhesive_bandage: fix location when packing plugin-angular
gingerbenw 1a68b71
add missing types package to test fixture
5249614
Merge branch 'bump-typescript' into plat-12947
3bd3332
update Dockerfile.ci eslint config location
cb227a1
Merge branch 'dash-13423-2' into plat-12947
470f373
fix imports
c46c43a
fix imports
bab00de
fix jest resolution
4bea0c0
Merge branch 'dash-13423-2' into plat-12947
13e28c4
Merge branch 'dash-13423-2' into plat-12947
7a842ec
add core to local-test-util install steps
63df48b
avoid ref to @bugsnag/core/event in generated types
a50c977
core: move tests from src to test
24f08b7
Merge branch 'integration/typescript' into plat-12947
ae50436
Merge pull request #2304 from bugsnag/plat-12947-3
djskinner File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
const fs = require('fs') | ||
const path = require('path') | ||
const packageUp = require('pkg-up') | ||
|
||
const defaultConditions = ['require', 'node', 'default'] | ||
|
||
function findMainPackageJson (entryPath, packageName) { | ||
entryPath = entryPath.replace(/\//g, path.sep) | ||
|
||
let directoryName = path.dirname(entryPath) | ||
|
||
let suspect = packageUp.sync({ cwd: directoryName }) | ||
if (fs.existsSync(suspect)) { | ||
return JSON.parse(fs.readFileSync(suspect).toString()) | ||
} | ||
|
||
while (directoryName && !directoryName.endsWith(packageName)) { | ||
const parentDirectoryName = path.resolve(directoryName, '..') | ||
|
||
if (parentDirectoryName === directoryName) break | ||
|
||
directoryName = parentDirectoryName | ||
} | ||
|
||
suspect = path.resolve(directoryName, 'package.json') | ||
if (fs.existsSync(suspect)) { | ||
return JSON.parse(fs.readFileSync(suspect).toString()) | ||
} | ||
|
||
return null | ||
} | ||
|
||
function getSelfReferencePath (packageName) { | ||
let parentDirectoryName = __dirname | ||
let directoryName | ||
|
||
while (directoryName !== parentDirectoryName) { | ||
directoryName = parentDirectoryName | ||
|
||
try { | ||
const { name } = require(path.resolve(directoryName, 'package.json')) | ||
|
||
if (name === packageName) return directoryName | ||
} catch {} | ||
|
||
parentDirectoryName = path.resolve(directoryName, '..') | ||
} | ||
} | ||
|
||
function getPackageJson (packageName) { | ||
// Require `package.json` from the package, both from exported `exports` field | ||
// in ESM packages, or directly from the file itself in CommonJS packages. | ||
try { | ||
return require(`${packageName}/package.json`) | ||
} catch (requireError) { | ||
if (requireError.code === 'MODULE_NOT_FOUND') { | ||
throw requireError | ||
} | ||
if (requireError.code !== 'ERR_PACKAGE_PATH_NOT_EXPORTED') { | ||
return console.error( | ||
`Unexpected error while requiring ${packageName}:`, requireError | ||
) | ||
} | ||
} | ||
|
||
// modules's `package.json` does not provide the "./package.json" path at it's | ||
// "exports" field. Get package level export or main field and try to resolve | ||
// the package.json from it. | ||
try { | ||
const requestPath = require.resolve(packageName) | ||
|
||
return requestPath && findMainPackageJson(requestPath, packageName) | ||
} catch (resolveError) { | ||
if (resolveError.code !== 'ERR_PACKAGE_PATH_NOT_EXPORTED') { | ||
console.log( | ||
`Unexpected error while performing require.resolve(${packageName}):` | ||
) | ||
|
||
return console.error(resolveError) | ||
} | ||
} | ||
|
||
// modules's `package.json` does not provide a package level export nor main | ||
// field. Try to find the package manually from `node_modules` folder. | ||
const suspect = path.resolve(__dirname, '..', packageName, 'package.json') | ||
if (fs.existsSync(suspect)) { | ||
return JSON.parse(fs.readFileSync(suspect).toString()) | ||
} | ||
|
||
console.warn( | ||
'Could not retrieve package.json neither through require (package.json ' + | ||
'itself is not within "exports" field), nor through require.resolve ' + | ||
'(package.json does not specify "main" field) - falling back to default ' + | ||
'resolver logic' | ||
) | ||
} | ||
|
||
module.exports = (request, options) => { | ||
const { conditions = defaultConditions, defaultResolver } = options | ||
|
||
// NOTE: jest-sequencer is a special prefixed jest request | ||
const isNodeModuleRequest = | ||
!( | ||
request.startsWith('.') || | ||
path.isAbsolute(request) || | ||
request.startsWith('jest-sequencer') | ||
) | ||
|
||
if (isNodeModuleRequest) { | ||
const pkgPathParts = request.split('/') | ||
const { length } = pkgPathParts | ||
|
||
let packageName | ||
let submoduleName | ||
|
||
if (!request.startsWith('@')) { | ||
packageName = pkgPathParts.shift() | ||
submoduleName = length > 1 ? `./${pkgPathParts.join('/')}` : '.' | ||
} else if (length >= 2) { | ||
packageName = `${pkgPathParts.shift()}/${pkgPathParts.shift()}` | ||
submoduleName = length > 2 ? `./${pkgPathParts.join('/')}` : '.' | ||
} | ||
|
||
if (packageName && submoduleName !== '.') { | ||
const selfReferencePath = getSelfReferencePath(packageName) | ||
if (selfReferencePath) packageName = selfReferencePath | ||
|
||
const packageJson = getPackageJson(packageName) | ||
|
||
if (!packageJson) { | ||
console.error(`Failed to find package.json for ${packageName}`) | ||
} | ||
|
||
const { exports } = packageJson || {} | ||
if (exports) { | ||
let targetFilePath | ||
|
||
if (typeof exports === 'string') { targetFilePath = exports } else if (Object.keys(exports).every((k) => k.startsWith('.'))) { | ||
const [exportKey, exportValue] = Object.entries(exports) | ||
.find(([k]) => { | ||
if (k === submoduleName) return true | ||
if (k.endsWith('*')) return submoduleName.startsWith(k.slice(0, -1)) | ||
|
||
return false | ||
}) || [] | ||
|
||
if (typeof exportValue === 'string') { | ||
targetFilePath = exportKey.endsWith('*') | ||
? exportValue.replace( | ||
/\*/, submoduleName.slice(exportKey.length - 1) | ||
) | ||
: exportValue | ||
} else if ( | ||
conditions && exportValue != null && typeof exportValue === 'object' | ||
) { | ||
function resolveExport (exportValue, prevKeys) { | ||
for (const [key, value] of Object.entries(exportValue)) { | ||
// Duplicated nested conditions are undefined behaviour (and | ||
// probably a format error or spec loop-hole), abort and | ||
// delegate to Jest default resolver | ||
if (prevKeys.includes(key)) return | ||
|
||
if (!conditions.includes(key)) continue | ||
|
||
if (typeof value === 'string') return value | ||
|
||
return resolveExport(value, prevKeys.concat(key)) | ||
} | ||
} | ||
|
||
targetFilePath = resolveExport(exportValue, []) | ||
} | ||
} | ||
|
||
if (targetFilePath) { | ||
request = targetFilePath.replace('./', `${packageName}/`) | ||
} | ||
} | ||
} | ||
} | ||
|
||
return defaultResolver(request, options) | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the jest version being used doesn't support
package.exports
so we need to use a custom resolver. This is largely based on https://www.npmjs.com/package/jest-node-exports-resolver but required further changes:jest-node-exports-resolver
out of the box no longer supports our version of jest (see Doesn't work for older versions of Jest k-g-a/jest-node-exports-resolver#17)An attempt to update jest was previously made (#2231) but there were issues because the helpers we use to run electron tests are no longer maintained and do not work with newwer versions of jest.
As alluded to in the previous PR its possible we could work around this by using multiple versions of jest (if a particular package needs a different version temporarily) rather than the single centralized way it is managed now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I personally prefer the de-centralised approach to running the tests, but I think it was harder to track changes in test coverage? if we can get around that I'd be happy to take that approach in the future