diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index fe284ad..fb63387 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -7,15 +7,15 @@ jobs: name: ${{matrix.node}} runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: dcodeIO/setup-node-nvm@master + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 with: node-version: ${{matrix.node}} - run: npm install - run: npm test - - uses: codecov/codecov-action@v1 + - uses: codecov/codecov-action@v3 strategy: matrix: node: - - lts/erbium + - lts/gallium - node diff --git a/.npmrc b/.npmrc index 43c97e7..9951b11 100644 --- a/.npmrc +++ b/.npmrc @@ -1 +1,2 @@ package-lock=false +ignore-scripts=true diff --git a/index.js b/index.js index 848978f..93163ea 100644 --- a/index.js +++ b/index.js @@ -1,62 +1 @@ -/** - * @typedef {import('unist').Point} Point - * @typedef {import('unist').Node} Node - * @typedef {import('unist').Position} Position - * @typedef {object & {type: string, position?: Position|undefined}} NodeLike - */ - -/** - * Stringify one point, a position (start and end points), or a node’s - * positional information. - * - * @param {Node|NodeLike|Position|Point|null} [value] - * @returns {string} - */ -export function stringifyPosition(value) { - // Nothing. - if (!value || typeof value !== 'object') { - return '' - } - - // Node. - if ('position' in value || 'type' in value) { - return position(value.position) - } - - // Position. - if ('start' in value || 'end' in value) { - return position(value) - } - - // Point. - if ('line' in value || 'column' in value) { - return point(value) - } - - // ? - return '' -} - -/** - * @param {Point|undefined} point - * @returns {string} - */ -function point(point) { - return index(point && point.line) + ':' + index(point && point.column) -} - -/** - * @param {Position|undefined} pos - * @returns {string} - */ -function position(pos) { - return point(pos && pos.start) + '-' + point(pos && pos.end) -} - -/** - * @param {number|undefined} value - * @returns {number} - */ -function index(value) { - return value && typeof value === 'number' ? value : 1 -} +export {stringifyPosition} from './lib/index.js' diff --git a/lib/index.js b/lib/index.js new file mode 100644 index 0000000..7474343 --- /dev/null +++ b/lib/index.js @@ -0,0 +1,84 @@ +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Point} Point + * @typedef {import('unist').Position} Position + */ + +/** + * @typedef NodeLike + * @property {string} type + * @property {PositionLike | null | undefined} [position] + * + * @typedef PositionLike + * @property {PointLike | null | undefined} [start] + * @property {PointLike | null | undefined} [end] + * + * @typedef PointLike + * @property {number | null | undefined} [line] + * @property {number | null | undefined} [column] + * @property {number | null | undefined} [offset] + */ + +/** + * Serialize the positional info of a point, position (start and end points), + * or node. + * + * @param {Node | NodeLike | Position | PositionLike | Point | PointLike | null | undefined} [value] + * Node, position, or point. + * @returns {string} + * Pretty printed positional info of a node (`string`). + * + * In the format of a range `ls:cs-le:ce` (when given `node` or `position`) + * or a point `l:c` (when given `point`), where `l` stands for line, `c` for + * column, `s` for `start`, and `e` for end. + * An empty string (`''`) is returned if the given value is neither `node`, + * `position`, nor `point`. + */ +export function stringifyPosition(value) { + // Nothing. + if (!value || typeof value !== 'object') { + return '' + } + + // Node. + if ('position' in value || 'type' in value) { + return position(value.position) + } + + // Position. + if ('start' in value || 'end' in value) { + return position(value) + } + + // Point. + if ('line' in value || 'column' in value) { + return point(value) + } + + // ? + return '' +} + +/** + * @param {Point | PointLike | null | undefined} point + * @returns {string} + */ +function point(point) { + return index(point && point.line) + ':' + index(point && point.column) +} + +/** + * @param {Position | PositionLike | null | undefined} pos + * @returns {string} + */ +function position(pos) { + return point(pos && pos.start) + '-' + point(pos && pos.end) +} + +/** + * @param {number | null | undefined} value + * @returns {number} + */ +function index(value) { + return value && typeof value === 'number' ? value : 1 +} diff --git a/package.json b/package.json index 5d23327..51e32c2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "unist-util-stringify-position", - "version": "3.0.2", + "version": "3.0.3", "description": "unist utility to serialize a node, position, or point as a human readable location", "license": "MIT", "keywords": [ @@ -30,6 +30,7 @@ "main": "index.js", "types": "index.d.ts", "files": [ + "lib/", "index.d.ts", "index.js" ], @@ -38,23 +39,21 @@ }, "devDependencies": { "@types/mdast": "^3.0.0", - "@types/tape": "^4.0.0", + "@types/node": "^18.0.0", "c8": "^7.0.0", "prettier": "^2.0.0", - "remark-cli": "^10.0.0", + "remark-cli": "^11.0.0", "remark-preset-wooorm": "^9.0.0", - "rimraf": "^3.0.0", - "tape": "^5.0.0", "type-coverage": "^2.0.0", "typescript": "^4.0.0", - "xo": "^0.48.0" + "xo": "^0.53.0" }, "scripts": { "prepack": "npm run build && npm run format", - "build": "rimraf \"*.d.ts\" && tsc && type-coverage", + "build": "tsc --build --clean && tsc --build && type-coverage", "format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix", - "test-api": "node test.js", - "test-coverage": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 --reporter lcov node test.js", + "test-api": "node --conditions development test.js", + "test-coverage": "c8 --check-coverage --100 --reporter lcov npm run test-api", "test": "npm run build && npm run format && npm run test-coverage" }, "prettier": { diff --git a/readme.md b/readme.md index 5fe2e1d..323f960 100644 --- a/readme.md +++ b/readme.md @@ -8,7 +8,7 @@ [![Backers][backers-badge]][collective] [![Chat][chat-badge]][chat] -**[unist][]** utility to pretty print the positional information of a node. +[unist][] utility to pretty print the positional info of a node. ## Contents @@ -39,7 +39,7 @@ For example, when throwing errors or warning messages about something. ## Install This package is [ESM only][esm]. -In Node.js (version 12.20+, 14.14+, or 16.0+), install with [npm][]: +In Node.js (version 14.14+ and 16.0+), install with [npm][]: ```sh npm install unist-util-stringify-position @@ -78,40 +78,43 @@ stringifyPosition({ ## API -This package exports the identifier `stringifyPosition`. +This package exports the identifier [`stringifyPosition`][stringifyposition]. There is no default export. ### `stringifyPosition(node|position|point)` -Stringify a [point][], [position][], or a [node][]. +Serialize the positional info of a point, position (start and end points), or +node. ###### Parameters * `node` ([`Node`][node]) - — node whose `'position'` property to stringify + — node whose `position` fields to serialize * `position` ([`Position`][position]) - — position whose `'start'` and `'end'` points to stringify + — position whose `start` and `end` points to serialize * `point` ([`Point`][point]) - — point whose `'line'` and `'column'` to stringify + — point whose `line` and `column` fields to serialize ###### Returns -`string?` — A range `ls:cs-le:ce` (when given `node` or `position`) or a point -`l:c` (when given `point`), where `l` stands for line, `c` for column, `s` for -`start`, and `e` for end. +Pretty printed positional info of a node (`string`). + +In the format of a range `ls:cs-le:ce` (when given `node` or `position`) or a +point `l:c` (when given `point`), where `l` stands for line, `c` for column, `s` +for `start`, and `e` for end. An empty string (`''`) is returned if the given value is neither `node`, `position`, nor `point`. ## Types This package is fully typed with [TypeScript][]. -There are no additional types exported. +It exports no additional types. ## Compatibility Projects maintained by the unified collective are compatible with all maintained versions of Node.js. -As of now, that is Node.js 12.20+, 14.14+, and 16.0+. +As of now, that is Node.js 14.14+ and 16.0+. Our projects sometimes work with older versions, but this is not guaranteed. ## Security @@ -196,3 +199,5 @@ abide by its terms. [position]: https://github.com/syntax-tree/unist#position [point]: https://github.com/syntax-tree/unist#point + +[stringifyposition]: #stringifypositionnodepositionpoint diff --git a/test.js b/test.js index 921e87c..9681c10 100644 --- a/test.js +++ b/test.js @@ -1,66 +1,70 @@ -import test from 'tape' +import assert from 'node:assert/strict' +import test from 'node:test' import {stringifyPosition} from './index.js' +import * as mod from './index.js' -test('stringifyPosition', function (t) { - t.equal( +test('stringifyPosition', function () { + assert.deepEqual( + Object.keys(mod).sort(), + ['stringifyPosition'], + 'should expose the public api' + ) + + assert.equal( stringifyPosition(), '', 'should return empty `string` with `undefined`' ) - t.equal( + assert.equal( stringifyPosition(null), '', 'should return empty `string` with `null`' ) - t.equal( + assert.equal( // @ts-expect-error runtime. stringifyPosition('foo'), '', 'should return empty `string` with `string`' ) - t.equal( + assert.equal( // @ts-expect-error runtime. stringifyPosition(5), '', 'should return empty `string` with `number`' ) - t.equal( - // @ts-expect-error runtime. + assert.equal( stringifyPosition({}), '', 'should return empty `string` with `{}`' ) - t.equal( + assert.equal( stringifyPosition({type: 'text'}), '1:1-1:1', 'should return a range for a `node` without `position`' ) - t.equal( + assert.equal( // @ts-expect-error runtime. stringifyPosition({type: 'text', position: 3}), '1:1-1:1', 'should return a range for `node` with invalid `position` #1' ) - t.equal( + assert.equal( stringifyPosition({ type: 'text', - // @ts-expect-error runtime. position: {start: {}, end: {}} }), '1:1-1:1', 'should return a range for `node` with invalid `position` #2' ) - t.equal( + assert.equal( stringifyPosition({ type: 'text', position: { - // @ts-expect-error runtime. start: {line: null, column: null}, - // @ts-expect-error runtime. end: {line: null, column: null} } }), @@ -68,7 +72,7 @@ test('stringifyPosition', function (t) { 'should return a range for `node` with invalid `position` #3' ) - t.equal( + assert.equal( stringifyPosition({ type: 'text', position: { @@ -80,7 +84,7 @@ test('stringifyPosition', function (t) { 'should return a range for `node` with valid `position` (types: literal object)' ) - t.equal( + assert.equal( stringifyPosition( /** @type {import('mdast').Root} */ ({ type: 'root', @@ -95,39 +99,35 @@ test('stringifyPosition', function (t) { 'should return a range for `node` with valid `position` (types: explicit instance of node)' ) - t.equal( - // @ts-expect-error runtime. + assert.equal( stringifyPosition({start: null, end: null}), '1:1-1:1', 'should return a range for a `position` without `point`s' ) - t.equal( + assert.equal( // @ts-expect-error runtime. stringifyPosition({start: 3, end: 6}), '1:1-1:1', 'should return a range for `position` with invalid `point`s #1' ) - t.equal( - // @ts-expect-error runtime. + assert.equal( stringifyPosition({start: {}, end: {}}), '1:1-1:1', 'should return range for `position` with invalid `point`s #1' ) - t.equal( + assert.equal( stringifyPosition({ - // @ts-expect-error runtime. start: {line: null, column: null}, - // @ts-expect-error runtime. end: {line: null, column: null} }), '1:1-1:1', 'should return range for `position` with invalid `point`s #3' ) - t.equal( + assert.equal( stringifyPosition({ start: {line: 2, column: 5}, end: {line: 2, column: 6} @@ -136,39 +136,34 @@ test('stringifyPosition', function (t) { 'should return range for `position` with valid `point`s' ) - t.equal( - // @ts-expect-error runtime. + assert.equal( stringifyPosition({line: null, column: null}), '1:1', 'should return a point for a `point` without indices' ) - t.equal( + assert.equal( // @ts-expect-error runtime. stringifyPosition({line: 'foo', column: 'bar'}), '1:1', 'should return a point for a `point` with invalid indices #1' ) - t.equal( - // @ts-expect-error runtime. + assert.equal( stringifyPosition({line: 4}), '4:1', 'should return a point for a partially valid `point` #1' ) - t.equal( - // @ts-expect-error runtime. + assert.equal( stringifyPosition({column: 12}), '1:12', 'should return a point for a partially valid `point` #1' ) - t.equal( + assert.equal( stringifyPosition({line: 5, column: 2}), '5:2', 'should return a point for a valid `point`' ) - - t.end() }) diff --git a/tsconfig.json b/tsconfig.json index e31adf8..ebe8889 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,16 +1,17 @@ { - "include": ["*.js"], + "include": ["**/*.js"], + "exclude": ["coverage/", "node_modules/"], "compilerOptions": { - "target": "ES2020", - "lib": ["ES2020"], - "module": "ES2020", - "moduleResolution": "node", - "allowJs": true, "checkJs": true, "declaration": true, "emitDeclarationOnly": true, - "allowSyntheticDefaultImports": true, + "exactOptionalPropertyTypes": true, + "forceConsistentCasingInFileNames": true, + "lib": ["es2020"], + "module": "node16", + "newLine": "lf", "skipLibCheck": true, - "strict": true + "strict": true, + "target": "es2020" } } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy