Skip to content

Commit f4edd0d

Browse files
authored
Change to replace Buffer with Uint8Array
Previously, this project depended on Node’s buffer. This commit changes that: it replaces that support with `Uint8Array`. In most cases, this will be fine, because the Node `Buffer` class subclasses `Uint8Array`. However, there are differences in which encodings are supported when turning this binary data into a string, and there are differences in how methods work. Closes GH-85. Reviewed-by: Christian Murphy <christian.murphy.42@gmail.com>
1 parent f72469b commit f4edd0d

File tree

5 files changed

+60
-80
lines changed

5 files changed

+60
-80
lines changed

index.d.ts

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,9 @@
1-
/**
2-
* This is the same as `Buffer` if node types are included, `never` otherwise.
3-
*/
4-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment, @typescript-eslint/prefer-ts-expect-error
5-
// @ts-ignore It’s important to preserve this ignore statement. This makes sure
6-
// it works both with and without node types.
7-
// eslint-disable-next-line n/prefer-global/buffer
8-
type MaybeBuffer = any extends Buffer ? never : Buffer
9-
101
/**
112
* Contents of the file.
123
*
13-
* Can either be text or a `Buffer` structure.
4+
* Can either be text or a `Uint8Array` structure.
145
*/
15-
// Note: this does not directly use type `Buffer`, because it can also be used
16-
// in a browser context.
17-
// Instead this leverages `Uint8Array` which is the base type for `Buffer`,
18-
// and a native JavaScript construct.
19-
export type Value = MaybeBuffer | string
6+
export type Value = Uint8Array | string
207

218
/**
229
* This map registers the type of the `data` key of a `VFile`.
@@ -49,7 +36,6 @@ export type {Data as VFileData, DataMap as VFileDataMap, Value as VFileValue}
4936
export {VFile} from './lib/index.js'
5037

5138
export type {
52-
BufferEncoding,
5339
Compatible,
5440
Map,
5541
MessageOptions,

lib/index.js

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,6 @@
1010
/**
1111
* @typedef {object & {type: string, position?: Position | undefined}} NodeLike
1212
*
13-
* @typedef {'ascii' | 'base64' | 'base64url' | 'binary' | 'hex' | 'latin1' | 'ucs-2' | 'ucs2' | 'utf-8' | 'utf16le' | 'utf8'} BufferEncoding
14-
* Encodings supported by the buffer class.
15-
*
16-
* This is a copy of the types from Node, copied to prevent Node globals from
17-
* being needed.
18-
* Copied from: <https://github.com/DefinitelyTyped/DefinitelyTyped/blob/1761eec/types/node/buffer.d.ts#L223>
19-
*
2013
* @typedef {Options | URL | VFile | Value} Compatible
2114
* Things that can be passed to the constructor.
2215
*
@@ -83,7 +76,6 @@
8376
* Report.
8477
*/
8578

86-
import bufferLike from 'is-buffer'
8779
import {VFileMessage} from 'vfile-message'
8880
import {path} from 'vfile/do-not-use-conditional-minpath'
8981
import {proc} from 'vfile/do-not-use-conditional-minproc'
@@ -109,7 +101,7 @@ export class VFile {
109101
*
110102
* `options` is treated as:
111103
*
112-
* * `string` or `Buffer` — `{value: options}`
104+
* * `string` or `Uint8Array` — `{value: options}`
113105
* * `URL` — `{path: options}`
114106
* * `VFile` — shallow copies its data over to the new file
115107
* * `object` — all fields are shallow copied over to the new file
@@ -132,10 +124,10 @@ export class VFile {
132124

133125
if (!value) {
134126
options = {}
135-
} else if (typeof value === 'string' || buffer(value)) {
136-
options = {value}
137127
} else if (isUrl(value)) {
138128
options = {path: value}
129+
} else if (typeof value === 'string' || isUint8Array(value)) {
130+
options = {value}
139131
} else {
140132
options = value
141133
}
@@ -619,14 +611,27 @@ export class VFile {
619611
/**
620612
* Serialize the file.
621613
*
622-
* @param {BufferEncoding | null | undefined} [encoding='utf8']
623-
* Character encoding to understand `value` as when it’s a `Buffer`
624-
* (default: `'utf8'`).
614+
* > **Note**: which encodings are supported depends on the engine.
615+
* > For info on Node.js, see:
616+
* > <https://nodejs.org/api/util.html#whatwg-supported-encodings>.
617+
*
618+
* @param {string | null | undefined} [encoding='utf8']
619+
* Character encoding to understand `value` as when it’s a `Uint8Array`
620+
* (default: `'utf-8'`).
625621
* @returns {string}
626622
* Serialized file.
627623
*/
628624
toString(encoding) {
629-
return (this.value || '').toString(encoding || undefined)
625+
if (this.value === undefined) {
626+
return ''
627+
}
628+
629+
if (typeof this.value === 'string') {
630+
return this.value
631+
}
632+
633+
const decoder = new TextDecoder(encoding || undefined)
634+
return decoder.decode(this.value)
630635
}
631636
}
632637

@@ -681,13 +686,18 @@ function assertPath(path, name) {
681686
}
682687

683688
/**
684-
* Assert `value` is a buffer.
689+
* Assert `value` is an `Uint8Array`.
685690
*
686691
* @param {unknown} value
687692
* thing.
688-
* @returns {value is Buffer}
689-
* Whether `value` is a Node.js buffer.
693+
* @returns {value is Uint8Array}
694+
* Whether `value` is an `Uint8Array`.
690695
*/
691-
function buffer(value) {
692-
return bufferLike(value)
696+
function isUint8Array(value) {
697+
return Boolean(
698+
value &&
699+
typeof value === 'object' &&
700+
'byteLength' in value &&
701+
'byteOffset' in value
702+
)
693703
}

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@
5555
],
5656
"dependencies": {
5757
"@types/unist": "^2.0.0",
58-
"is-buffer": "^2.0.0",
5958
"unist-util-stringify-position": "^3.0.0",
6059
"vfile-message": "^4.0.0"
6160
},

readme.md

Lines changed: 12 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ metadata about files (such as its `path` and `value`) and lint
3737
* [`VFile#info(reason[, options])`](#vfileinforeason-options)
3838
* [`VFile#message(reason[, options])`](#vfilemessagereason-options)
3939
* [`VFile#toString(encoding?)`](#vfiletostringencoding)
40-
* [`BufferEncoding`](#bufferencoding)
4140
* [`Compatible`](#compatible)
4241
* [`Data`](#data)
4342
* [`DataMap`](#datamap)
@@ -170,7 +169,7 @@ Create a new virtual file.
170169

171170
`options` is treated as:
172171

173-
* `string` or [`Buffer`][buffer]`{value: options}`
172+
* `string` or [`Uint8Array`][mdn-uint8-array]`{value: options}`
174173
* `URL``{path: options}`
175174
* `VFile` — shallow copies its data over to the new file
176175
* `object` — all fields are shallow copied over to the new file
@@ -196,7 +195,7 @@ New instance (`VFile`).
196195
```js
197196
new VFile()
198197
new VFile('console.log("alpha");')
199-
new VFile(Buffer.from('exit 1'))
198+
new VFile(new Uint8Array([0x65, 0x78, 0x69, 0x74, 0x20, 0x31]))
200199
new VFile({path: path.join('path', 'to', 'readme.md')})
201200
new VFile({stem: 'readme', extname: '.md', dirname: path.join('path', 'to')})
202201
new VFile({other: 'properties', are: 'copied', ov: {e: 'r'}})
@@ -226,7 +225,7 @@ List of messages associated with the file
226225

227226
### `file.value`
228227

229-
Raw value ([`Buffer`][buffer], `string`, `undefined`).
228+
Raw value ([`Uint8Array`][mdn-uint8-array], `string`, `undefined`).
230229

231230
### `file.basename`
232231

@@ -337,39 +336,20 @@ Message ([`VFileMessage`][vmessage]).
337336

338337
Serialize the file.
339338

339+
> **Note**: which encodings are supported depends on the engine.
340+
> For info on Node.js, see:
341+
> <https://nodejs.org/api/util.html#whatwg-supported-encodings>.
342+
340343
###### Parameters
341344

342-
* `encoding` ([`BufferEncoding`][api-buffer-encoding], default: `'utf8'`)
345+
* `encoding` (`string`, default: `'utf8'`)
343346
— character encoding to understand `value` as when it’s a
344-
[`Buffer`][buffer]
347+
[`Uint8Array`][mdn-uint8-array]
345348

346349
###### Returns
347350

348351
Serialized file (`string`).
349352

350-
### `BufferEncoding`
351-
352-
[Encodings][encoding] supported by the [buffer][] class (TypeScript type).
353-
354-
This is a copy of the types from Node.
355-
356-
###### Type
357-
358-
```ts
359-
type BufferEncoding =
360-
| 'ascii'
361-
| 'base64'
362-
| 'base64url'
363-
| 'binary'
364-
| 'hex'
365-
| 'latin1'
366-
| 'ucs-2'
367-
| 'ucs2'
368-
| 'utf-8'
369-
| 'utf16le'
370-
| 'utf8'
371-
```
372-
373353
### `Compatible`
374354

375355
Things that can be passed to the constructor (TypeScript type).
@@ -497,12 +477,12 @@ type ReporterSettings = Record<string, unknown>
497477
498478
Contents of the file (TypeScript type).
499479
500-
Can either be text or a `Buffer` structure.
480+
Can either be text or a [`Uint8Array`][mdn-uint8-array] structure.
501481
502482
###### Type
503483
504484
```ts
505-
type Value = Buffer | string
485+
type Value = Uint8Array | string
506486
```
507487
508488
### Well-known
@@ -586,7 +566,6 @@ There are also well-known fields on messages, see
586566
587567
This package is fully typed with [TypeScript][].
588568
It exports the additional types
589-
[`BufferEncoding`][api-buffer-encoding],
590569
[`Compatible`][api-compatible],
591570
[`Data`][api-data],
592571
[`DataMap`][api-data-map],
@@ -773,9 +752,7 @@ for contributing commits since!
773752
774753
[vfile-message-options]: https://github.com/vfile/vfile-message#options
775754
776-
[encoding]: https://nodejs.org/api/buffer.html#buffer_buffers_and_character_encodings
777-
778-
[buffer]: https://nodejs.org/api/buffer.html
755+
[mdn-uint8-array]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array
779756
780757
[source-map]: https://github.com/mozilla/source-map/blob/58819f0/source-map.d.ts#L15-L23
781758
@@ -789,8 +766,6 @@ for contributing commits since!
789766
790767
[api-vfile]: #vfileoptions
791768
792-
[api-buffer-encoding]: #bufferencoding
793-
794769
[api-compatible]: #compatible
795770
796771
[api-data]: #data

test.js

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -160,15 +160,25 @@ test('new VFile(options?)', async function (t) {
160160
)
161161

162162
assert.equal(
163-
new VFile(Buffer.from('bar')).toString(),
164-
'bar',
165-
'buffer: should return the internal value'
163+
new VFile(Buffer.from([0xef, 0xbb, 0xbf, 0x61, 0x62, 0x63])).toString(),
164+
'abc',
165+
'should return the internal value (`Buffer`, default: utf8)'
166166
)
167167

168168
assert.equal(
169-
new VFile(Buffer.from('bar')).toString('hex'),
170-
'626172',
171-
'buffer encoding: should return the internal value'
169+
new VFile(
170+
new Uint8Array([0xfe, 0xff, 0x00, 0x61, 0x00, 0x62, 0x00, 0x63])
171+
).toString('utf-16be'),
172+
'abc',
173+
'should return the internal value (`Uint8Array`, explicit utf-16be)'
174+
)
175+
176+
assert.equal(
177+
new VFile(
178+
new Uint8Array([0xff, 0xfe, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00])
179+
).toString('utf-16le'),
180+
'abc',
181+
'should return the internal value (`Uint8Array`, explicit utf-16le)'
172182
)
173183
})
174184

0 commit comments

Comments
 (0)