Skip to content

Commit e162298

Browse files
committed
feat(models): ERR_INVALID_PACKAGE_TARGET
Signed-off-by: Lexus Drumgold <[email protected]>
1 parent 6637aaa commit e162298

File tree

4 files changed

+177
-1
lines changed

4 files changed

+177
-1
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
"typecheck:watch": "vitest typecheck"
6969
},
7070
"dependencies": {
71+
"@flex-development/pkg-types": "1.0.0",
7172
"@flex-development/tutils": "6.0.0-alpha.7",
7273
"node-inspect-extracted": "2.0.0"
7374
},
@@ -77,7 +78,6 @@
7778
"@commitlint/types": "17.0.0",
7879
"@faker-js/faker": "7.6.0",
7980
"@flex-development/mkbuild": "1.0.0-alpha.9",
80-
"@flex-development/pkg-types": "1.0.0",
8181
"@graphql-eslint/eslint-plugin": "3.13.0",
8282
"@types/chai": "4.3.4",
8383
"@types/chai-string": "1.4.2",
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/**
2+
* @file Unit Tests - ERR_INVALID_PACKAGE_TARGET
3+
* @module errnode/models/tests/unit/ERR_INVALID_PACKAGE_TARGET
4+
*/
5+
6+
import { ErrorCode } from '#src/enums'
7+
import type pkg from '@flex-development/pkg-types'
8+
import TestSubject from '../err-invalid-package-target'
9+
10+
describe('unit:models/ERR_INVALID_PACKAGE_TARGET', () => {
11+
let base: string
12+
let dir: string
13+
let key: string
14+
let target: pkg.Exports
15+
16+
beforeEach(() => {
17+
base = import.meta.url
18+
dir = process.cwd() + '/'
19+
key = '.'
20+
target = 'dist/index.mjs'
21+
})
22+
23+
it('should return Error instance', () => {
24+
// Act
25+
const result = new TestSubject(dir, key, target)
26+
27+
// Expect
28+
expect(result).to.be.instanceof(Error)
29+
expect(result).to.have.property('name').equal('Error')
30+
})
31+
32+
it('should set error code', () => {
33+
expect(new TestSubject(dir, key, target))
34+
.to.have.property('code')
35+
.equal(ErrorCode.ERR_INVALID_PACKAGE_TARGET)
36+
})
37+
38+
it('should set error message', () => {
39+
// Arrange
40+
const cases: [...ConstructorParameters<typeof TestSubject>, string][] = [
41+
[
42+
dir,
43+
key,
44+
target,
45+
undefined,
46+
undefined,
47+
`Invalid "exports" main target "${target}" defined in the package config ${dir}package.json; targets must start with "./"`
48+
],
49+
[
50+
dir,
51+
key + '/utils',
52+
'dist/utils.mjs',
53+
undefined,
54+
undefined,
55+
`Invalid "exports" target "dist/utils.mjs" defined for './utils' in the package config ${dir}package.json; targets must start with "./"`
56+
],
57+
[
58+
'',
59+
'#src',
60+
'src/index.ts',
61+
true,
62+
base,
63+
`Invalid "imports" target "src/index.ts" defined for '#src' in the package config package.json imported from ${base}`
64+
]
65+
]
66+
67+
// Act + Expect
68+
cases.forEach(([dir, key, target, internal, base, expected]) => {
69+
expect(new TestSubject(dir, key, target, internal, base))
70+
.to.have.property('message')
71+
.equal(expected)
72+
})
73+
})
74+
})
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/**
2+
* @file Error Models - ERR_INVALID_PACKAGE_TARGET
3+
* @module errnode/models/ERR_INVALID_PACKAGE_TARGET
4+
* @see https://github.com/nodejs/node/blob/v19.3.0/lib/internal/errors.js#L1331-L1346
5+
*/
6+
7+
import { ErrorCode } from '#src/enums'
8+
import type { MessageFn, NodeError, NodeErrorConstructor } from '#src/types'
9+
import { createNodeError } from '#src/utils'
10+
import type pkg from '@flex-development/pkg-types'
11+
12+
/**
13+
* `ERR_INVALID_PACKAGE_TARGET` model.
14+
*
15+
* Thrown when a `package.json` [`"exports"`][1] or [`"imports"`][2] field
16+
* contains an invalid target mapping value for the attempted module resolution.
17+
*
18+
* [1]: https://nodejs.org/api/packages.html#exports
19+
* [2]: https://nodejs.org/api/packages.html#imports
20+
*
21+
* @see https://nodejs.org/api/errors.html#err_invalid_package_target
22+
*
23+
* @class
24+
*
25+
* @param {string} dir - Directory containing `package.json` file
26+
* @param {string} key - `exports` or `imports` key
27+
* @param {pkg.Exports} target - Invalid package target
28+
* @param {boolean?} [internal=false] - `target` is package [`imports`][2]?
29+
* @param {string?} [base=''] - Id of module package was imported from
30+
* @return {NodeError} `Error` instance
31+
*/
32+
const ERR_INVALID_PACKAGE_TARGET: NodeErrorConstructor<
33+
ErrorConstructor,
34+
MessageFn<[string, string, pkg.Exports, boolean?, string?]>
35+
> = createNodeError(
36+
ErrorCode.ERR_INVALID_PACKAGE_TARGET,
37+
Error,
38+
/**
39+
* Creates a [`ERR_INVALID_PACKAGE_TARGET`][1] message.
40+
*
41+
* [1]: https://nodejs.org/api/errors.html#err_invalid_package_target
42+
* [2]: https://nodejs.org/api/packages.html#imports
43+
*
44+
* @param {string} dir - Directory containing `package.json` file
45+
* @param {string} key - `exports` or `imports` key
46+
* @param {pkg.Exports} target - Invalid package target
47+
* @param {boolean?} [internal=false] - `target` is package [`imports`][2]?
48+
* @param {string?} [base=''] - Id of module package was imported from
49+
* @return {string} Error message
50+
*/
51+
(
52+
dir: string,
53+
key: string,
54+
target: pkg.Exports,
55+
internal: boolean = false,
56+
base: string = ''
57+
): string => {
58+
/**
59+
* [`"exports"`][1] main target check.
60+
*
61+
* [1]: https://nodejs.org/api/packages.html#exports
62+
*
63+
* @see https://nodejs.org/api/packages.html#subpath-exports
64+
*
65+
* @const {boolean} main
66+
*/
67+
const main: boolean = !internal && key === '.'
68+
69+
/**
70+
* Error message.
71+
*
72+
* @var {string} ret
73+
*/
74+
let ret: string = `Invalid "${internal ? 'imports' : 'exports'}"`
75+
76+
// include if package target is main entry point
77+
if (main) ret += ' main'
78+
79+
// add invalid package target
80+
ret += ` target ${JSON.stringify(target)} defined`
81+
82+
// add key of invalid package target if target is not main entry point
83+
if (!main) ret += ` for '${key}'`
84+
85+
// add package.json location
86+
ret += ` in the package config ${dir}package.json`
87+
88+
// add import location
89+
if (base) ret += ` imported from ${base}`
90+
91+
// add reason package target is invalid
92+
ret +=
93+
typeof target === 'string' && !internal && !target.startsWith('./')
94+
? '; targets must start with "./"'
95+
: ''
96+
97+
return ret
98+
}
99+
)
100+
101+
export default ERR_INVALID_PACKAGE_TARGET

src/models/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export { default as ERR_INCOMPATIBLE_OPTION_PAIR } from './err-incompatible-opti
1515
export { default as ERR_INVALID_ARG_VALUE } from './err-invalid-arg-value'
1616
export { default as ERR_INVALID_MODULE_SPECIFIER } from './err-invalid-module-specifier'
1717
export { default as ERR_INVALID_PACKAGE_CONFIG } from './err-invalid-package-config'
18+
export { default as ERR_INVALID_PACKAGE_TARGET } from './err-invalid-package-target'
1819
export { default as ERR_METHOD_NOT_IMPLEMENTED } from './err-method-not-implemented'
1920
export { default as ERR_MISSING_OPTION } from './err-missing-option'
2021
export { default as ERR_MODULE_NOT_FOUND } from './err-module-not-found'

0 commit comments

Comments
 (0)