Skip to content

Commit 4eb7aa0

Browse files
committed
Change to throw errors for removed props
1 parent e12b5e9 commit 4eb7aa0

File tree

3 files changed

+64
-123
lines changed

3 files changed

+64
-123
lines changed

lib/index.js

+45-30
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,12 @@
2727
*
2828
* @typedef Deprecation
2929
* Deprecation.
30+
* @property {string} from
31+
* Old field.
3032
* @property {string} id
3133
* ID in readme.
32-
* @property {string} [to]
33-
* Field to use instead (optional).
34+
* @property {keyof Options} [to]
35+
* New field.
3436
*
3537
* @typedef Options
3638
* Configuration.
@@ -93,6 +95,7 @@
9395
* Transformed URL (optional).
9496
*/
9597

98+
import {unreachable} from 'devlop'
9699
import {toJsxRuntime} from 'hast-util-to-jsx-runtime'
97100
// @ts-expect-error: untyped.
98101
import {Fragment, jsx, jsxs} from 'react/jsx-runtime'
@@ -114,31 +117,37 @@ const emptyPlugins = []
114117
const emptyRemarkRehypeOptions = {allowDangerousHtml: true}
115118

116119
// Mutable because we `delete` any time it’s used and a message is sent.
117-
/** @type {Record<string, Readonly<Deprecation>>} */
118-
const deprecated = {
119-
astPlugins: {id: 'remove-buggy-html-in-markdown-parser'},
120-
allowDangerousHtml: {id: 'remove-buggy-html-in-markdown-parser'},
121-
allowNode: {
120+
/** @type {ReadonlyArray<Readonly<Deprecation>>} */
121+
const deprecations = [
122+
{from: 'astPlugins', id: 'remove-buggy-html-in-markdown-parser'},
123+
{from: 'allowDangerousHtml', id: 'remove-buggy-html-in-markdown-parser'},
124+
{
125+
from: 'allowNode',
122126
id: 'replace-allownode-allowedtypes-and-disallowedtypes',
123127
to: 'allowElement'
124128
},
125-
allowedTypes: {
129+
{
130+
from: 'allowedTypes',
126131
id: 'replace-allownode-allowedtypes-and-disallowedtypes',
127132
to: 'allowedElements'
128133
},
129-
disallowedTypes: {
134+
{
135+
from: 'disallowedTypes',
130136
id: 'replace-allownode-allowedtypes-and-disallowedtypes',
131137
to: 'disallowedElements'
132138
},
133-
escapeHtml: {id: 'remove-buggy-html-in-markdown-parser'},
134-
includeElementIndex: {id: '#remove-includeelementindex-option'},
135-
includeNodeIndex: {id: 'change-includenodeindex-to-includeelementindex'},
136-
plugins: {id: 'change-plugins-to-remarkplugins', to: 'remarkPlugins'},
137-
rawSourcePos: {id: '#remove-rawsourcepos-option'},
138-
renderers: {id: 'change-renderers-to-components', to: 'components'},
139-
source: {id: 'change-source-to-children', to: 'children'},
140-
sourcePos: {id: '#remove-sourcepos-option'}
141-
}
139+
{from: 'escapeHtml', id: 'remove-buggy-html-in-markdown-parser'},
140+
{from: 'includeElementIndex', id: '#remove-includeelementindex-option'},
141+
{
142+
from: 'includeNodeIndex',
143+
id: 'change-includenodeindex-to-includeelementindex'
144+
},
145+
{from: 'plugins', id: 'change-plugins-to-remarkplugins', to: 'remarkPlugins'},
146+
{from: 'rawSourcePos', id: '#remove-rawsourcepos-option'},
147+
{from: 'renderers', id: 'change-renderers-to-components', to: 'components'},
148+
{from: 'source', id: 'change-source-to-children', to: 'children'},
149+
{from: 'sourcePos', id: '#remove-sourcepos-option'}
150+
]
142151

143152
/**
144153
* Component to render markdown.
@@ -183,29 +192,35 @@ export function Markdown(options) {
183192
if (typeof children === 'string') {
184193
file.value = children
185194
} else {
186-
console.warn(
187-
'[react-markdown] Warning: please pass a string as `children` (not: `' +
195+
unreachable(
196+
'Unexpected value `' +
188197
children +
189-
'`)'
198+
'` for `children` prop, expected `string`'
190199
)
191200
}
192201

193202
if (allowedElements && disallowedElements) {
194-
throw new TypeError(
203+
unreachable(
195204
'Unexpected combined `allowedElements` and `disallowedElements`, expected one or the other'
196205
)
197206
}
198207

199-
for (const key in deprecated) {
208+
for (const deprecation of deprecations) {
200209
// To do: use `Object.hasOwn`.
201-
if (own.call(deprecated, key) && own.call(options, key)) {
202-
const deprecation = deprecated[key]
203-
console.warn(
204-
`[react-markdown] Warning: please ${
205-
deprecation.to ? `use \`${deprecation.to}\` instead of` : 'remove'
206-
} \`${key}\` (see <${changelog}#${deprecation.id}> for more info)`
210+
if (own.call(options, deprecation.from)) {
211+
unreachable(
212+
'Unexpected `' +
213+
deprecation.from +
214+
'` prop, ' +
215+
(deprecation.to
216+
? 'use `' + deprecation.to + '` instead'
217+
: 'remove it') +
218+
' (see <' +
219+
changelog +
220+
'#' +
221+
deprecation.id +
222+
'> for more info)'
207223
)
208-
delete deprecated[key]
209224
}
210225
}
211226

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
"dependencies": {
8282
"@types/hast": "^3.0.0",
8383
"@types/prop-types": "^15.0.0",
84+
"devlop": "^1.0.0",
8485
"hast-util-to-jsx-runtime": "^2.0.0",
8586
"mdast-util-to-hast": "^13.0.0",
8687
"prop-types": "^15.0.0",

test.jsx

+18-93
Original file line numberDiff line numberDiff line change
@@ -25,79 +25,25 @@ test('react-markdown', async function (t) {
2525
assert.equal(asHtml(<Markdown children="a" />), '<p>a</p>')
2626
})
2727

28-
await t.test('should warn w/ `source`', function () {
29-
const warn = console.warn
30-
/** @type {unknown} */
31-
let message
32-
33-
console.warn = capture
34-
35-
// @ts-expect-error: check how the runtime handles untyped `source`.
36-
assert.equal(asHtml(<Markdown source="a" />), '')
37-
assert.equal(
38-
message,
39-
'[react-markdown] Warning: please use `children` instead of `source` (see <https://github.com/remarkjs/react-markdown/blob/main/changelog.md#change-source-to-children> for more info)'
40-
)
41-
42-
console.warn = warn
43-
44-
/**
45-
* @param {unknown} d
46-
* @returns {undefined}
47-
*/
48-
function capture(d) {
49-
message = d
50-
}
28+
await t.test('should throw w/ `source`', function () {
29+
assert.throws(function () {
30+
// @ts-expect-error: check how the runtime handles untyped `source`.
31+
asHtml(<Markdown source="a" />)
32+
}, /Unexpected `source` prop, use `children` instead/)
5133
})
5234

53-
await t.test('should warn w/ non-string children (number)', function () {
54-
const {error, warn} = console
55-
/** @type {unknown} */
56-
let message
57-
58-
console.warn = capture
59-
60-
// @ts-expect-error: check how the runtime handles invalid `children`.
61-
assert.equal(asHtml(<Markdown children={1} />), '')
62-
assert.equal(
63-
message,
64-
'[react-markdown] Warning: please pass a string as `children` (not: `1`)'
65-
)
66-
67-
console.warn = warn
68-
69-
/**
70-
* @param {unknown} d
71-
* @returns {undefined}
72-
*/
73-
function capture(d) {
74-
message = d
75-
}
35+
await t.test('should throw w/ non-string children (number)', function () {
36+
assert.throws(function () {
37+
// @ts-expect-error: check how the runtime handles invalid `children`.
38+
asHtml(<Markdown children={1} />)
39+
}, /Unexpected value `1` for `children` prop, expected `string`/)
7640
})
7741

78-
await t.test('should warn w/ non-string children (boolean)', function () {
79-
const {error, warn} = console
80-
/** @type {unknown} */
81-
let message
82-
83-
console.warn = capture
84-
85-
// @ts-expect-error: check how the runtime handles invalid `children`.
86-
assert.equal(asHtml(<Markdown children={true} />), '')
87-
assert.equal(
88-
message,
89-
'[react-markdown] Warning: please pass a string as `children` (not: `true`)'
90-
)
91-
92-
console.warn = warn
93-
94-
/**
95-
* @param {unknown} d
96-
* @returns {undefined}
97-
*/
98-
function capture(d) {
99-
message = d
100-
}
42+
await t.test('should throw w/ non-string children (boolean)', function () {
43+
assert.throws(function () {
44+
// @ts-expect-error: check how the runtime handles invalid `children`.
45+
asHtml(<Markdown children={true} />)
46+
}, /Unexpected value `true` for `children` prop, expected `string`/)
10147
})
10248

10349
await t.test('should support `null` as children', function () {
@@ -109,31 +55,10 @@ test('react-markdown', async function (t) {
10955
})
11056

11157
await t.test('should warn w/ `allowDangerousHtml`', function () {
112-
const warn = console.warn
113-
/** @type {unknown} */
114-
let message
115-
116-
console.warn = capture
117-
118-
assert.equal(
58+
assert.throws(function () {
11959
// @ts-expect-error: check how the runtime handles deprecated `allowDangerousHtml`.
120-
asHtml(<Markdown allowDangerousHtml children="a" />),
121-
'<p>a</p>'
122-
)
123-
assert.equal(
124-
message,
125-
'[react-markdown] Warning: please remove `allowDangerousHtml` (see <https://github.com/remarkjs/react-markdown/blob/main/changelog.md#remove-buggy-html-in-markdown-parser> for more info)'
126-
)
127-
128-
console.warn = warn
129-
130-
/**
131-
* @param {unknown} d
132-
* @returns {undefined}
133-
*/
134-
function capture(d) {
135-
message = d
136-
}
60+
asHtml(<Markdown allowDangerousHtml />)
61+
}, /Unexpected `allowDangerousHtml` prop, remove it/)
13762
})
13863

13964
await t.test('should support `className`', function () {

0 commit comments

Comments
 (0)