diff --git a/package.json b/package.json index da8d498..af01fe7 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "type": "opencollective", "url": "https://opencollective.com/unified" }, + "types": "types/index.d.ts", "author": "Titus Wormer (https://wooorm.com)", "contributors": [ "Titus Wormer (https://wooorm.com)" @@ -27,12 +28,14 @@ "main": "index.js", "files": [ "index.js", - "convert.js" + "convert.js", + "types/index.d.ts" ], "dependencies": { "vfile": "^4.0.0" }, "devDependencies": { + "dtslint": "^4.0.6", "nyc": "^15.0.0", "prettier": "^2.0.0", "remark-cli": "^9.0.0", @@ -45,7 +48,8 @@ "format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix", "test-api": "node test", "test-coverage": "nyc --reporter lcov tape test.js", - "test": "npm run format && npm run test-coverage" + "test-types": "dtslint types", + "test": "npm run format && npm run test-coverage && npm run test-types" }, "nyc": { "check-coverage": true, diff --git a/types/index.d.ts b/types/index.d.ts new file mode 100644 index 0000000..5a07299 --- /dev/null +++ b/types/index.d.ts @@ -0,0 +1,54 @@ +// TypeScript Version: 3.7 + +import {VFile, VFileCompatible, VFileOptions} from 'vfile' + +export = rename + +/** + * Renames the given `file` with `renames` + * @param file VFile to rename + * @param renames Rename instructions + * @returns The renamed `file` + */ +declare function rename(file?: VFileCompatible, renames?: rename.Renames): VFile + +declare namespace rename { + interface SpecAffix { + prefix?: string + suffix?: string + } + + /** + * A spec is an object describing path properties to values. + * For each property in spec, if its value is string, the value of the path property on the given file is set. + * If the value is object, it can have a prefix or suffix key, the value of the path property on the given file is prefixed and/or suffixed. + */ + interface Spec { + path?: VFileOptions['path'] | SpecAffix + basename?: VFileOptions['basename'] | SpecAffix + stem?: VFileOptions['stem'] | SpecAffix + extname?: VFileOptions['extname'] | SpecAffix + dirname?: VFileOptions['dirname'] | SpecAffix + } + + /** + * When given something, returns a vfile from that, and changes its path properties. + * - If there is no bound rename (it’s null or undefined), makes sure file is a VFile + * - If the bound rename is a normal string starting with a dot (.), sets file.extname + * - Otherwise, if the bound rename is a normal string, sets file.basename + * - If the bound test is an array, all renames in it are performed + * - Otherwise, if the bound rename is an object, renames according to the Spec + * @param file VFile to rename + * @returns The renamed `file` + */ + type Move = (file: VFile) => VFile + + type Renames = string | Move | Spec | Renames[] + + /** + * Create a function (the [move](https://github.com/vfile/vfile-rename#movefile)) from `renames`, that when given a file changes its path properties. + * @param renames Rename instructions + * @returns A [move](https://github.com/vfile/vfile-rename#movefile) + */ + function convert(renames: Renames): Move +} diff --git a/types/tsconfig.json b/types/tsconfig.json new file mode 100644 index 0000000..07a0344 --- /dev/null +++ b/types/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "lib": ["es2015"], + "strict": true, + "baseUrl": ".", + "paths": { + "vfile-rename": ["index.d.ts"] + } + } +} diff --git a/types/tslint.json b/types/tslint.json new file mode 100644 index 0000000..70c4494 --- /dev/null +++ b/types/tslint.json @@ -0,0 +1,7 @@ +{ + "extends": "dtslint/dtslint.json", + "rules": { + "semicolon": false, + "whitespace": false + } +} diff --git a/types/vfile-rename-tests.ts b/types/vfile-rename-tests.ts new file mode 100644 index 0000000..4d904a3 --- /dev/null +++ b/types/vfile-rename-tests.ts @@ -0,0 +1,28 @@ +import vfile = require('vfile') +import rename = require('vfile-rename') + +const convert = rename.convert +const move = convert('!') +const file = vfile('index.js') + +rename() // $ExpectType VFile +rename('!') // $ExpectType VFile +rename({path: '/'}) // $ExpectType VFile +rename(file, 'main.js') // $ExpectType VFile +rename(file, move) // $ExpectType VFile +rename(file, {stem: 'main'}) // $ExpectType VFile +rename(file, {stem: 'readme', extname: '.md'}) // $ExpectType VFile +rename(file, {stem: {suffix: '-1'}, dirname: {prefix: 'an-'}}) // $ExpectType VFile +rename(file, ['readme.htm', {stem: 'index', extname: {suffix: 'l'}}]) // $ExpectType VFile +rename(file, 1) // $ExpectError +rename(file, {other: '!'}) // $ExpectError + +convert('!') // $ExpectType Move +convert({path: '/'}) // $ExpectType Move +convert(move) // $ExpectType Move +convert({stem: 'main'}) // $ExpectType Move +convert({stem: 'readme', extname: '.md'}) // $ExpectType Move +convert({stem: {suffix: '-1'}, dirname: {prefix: 'an-'}}) // $ExpectType Move +convert(['readme.htm', {stem: 'index', extname: {suffix: 'l'}}]) // $ExpectType Move +convert(1) // $ExpectError +convert({other: '!'}) // $ExpectError