Skip to content

Commit

Permalink
Add JSDoc based types
Browse files Browse the repository at this point in the history
  • Loading branch information
wooorm committed Aug 9, 2021
1 parent 4b47c47 commit b579e27
Show file tree
Hide file tree
Showing 14 changed files with 1,278 additions and 1,357 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
coverage/
node_modules/
.DS_Store
*.d.ts
*.log
yarn.lock
18 changes: 15 additions & 3 deletions lib/check/check-files.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,35 @@
import {promises as fs} from 'fs'
/**
* @typedef {import('../types.js').VFile} VFile
* @typedef {import('../types.js').Landmarks} Landmarks
* @typedef {import('../types.js').References} References
*/

import {constants, promises as fs} from 'fs'

/**
* @param {{files: VFile[], landmarks: Landmarks, references: References}} ctx
*/
export async function checkFiles(ctx) {
const landmarks = ctx.landmarks
const references = ctx.references
/** @type {Array.<Promise<void>>} */
const promises = []
/** @type {string} */
let filePath

for (filePath in references) {
if (landmarks[filePath] === undefined) {
/** @type {Record<string, boolean>} */
const map = Object.create(null)

landmarks[filePath] = map

promises.push(
fs.access(filePath, fs.F_OK).then(
fs.access(filePath, constants.F_OK).then(
() => {
map[''] = true
},
(error) => {
(/** @type {NodeJS.ErrnoException} */ error) => {
map[''] = error.code !== 'ENOENT' && error.code !== 'ENOTDIR'
}
)
Expand Down
14 changes: 13 additions & 1 deletion lib/check/merge-landmarks.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,27 @@
/**
* @typedef {import('../types.js').VFile} VFile
* @typedef {import('../types.js').Landmarks} Landmarks
*/

import {constants} from '../constants.js'

const own = {}.hasOwnProperty

/**
* @param {{files: VFile[], landmarks?: Landmarks}} ctx
*/
export function mergeLandmarks(ctx) {
/** @type {Landmarks} */
const result = Object.create(null)
const files = ctx.files
let index = -1

while (++index < files.length) {
const file = files[index]
const landmarks = file.data[constants.landmarkId]
const landmarks = /** @type {Landmarks|undefined} */ (
file.data[constants.landmarkId]
)
/** @type {string} */
let landmark

if (landmarks) {
Expand Down
23 changes: 21 additions & 2 deletions lib/check/merge-references.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,31 @@
/**
* @typedef {import('../types.js').VFile} VFile
* @typedef {import('../types.js').Landmarks} Landmarks
* @typedef {import('../types.js').References} References
* @typedef {import('../types.js').ReferenceMap} ReferenceMap
* @typedef {import('../types.js').Resource} Resource
*/

import {constants} from '../constants.js'

const own = {}.hasOwnProperty

/**
* @param {{files: VFile[], landmarks: Landmarks, references?: References}} ctx
*/
export function mergeReferences(ctx) {
/** @type {References} */
const result = {}
const files = ctx.files
let index = -1

while (++index < files.length) {
const file = files[index]
const references = file.data[constants.referenceId]
const references =
/** @type {Record<string, Record<string, Resource[]>>|undefined} */ (
file.data[constants.referenceId]
)
/** @type {string} */
let reference

if (!references) {
Expand All @@ -19,16 +35,19 @@ export function mergeReferences(ctx) {
for (reference in references) {
if (own.call(references, reference)) {
const internal = references[reference]
/** @type {Record<string, ReferenceMap[]>} */
const all =
reference in result
? result[reference]
: (result[reference] = Object.create(null))
/** @type {string} */
let hash

for (hash in internal) {
// eslint-disable-next-line max-depth
if (own.call(internal, hash)) {
;(all[hash] || (all[hash] = [])).push({
const list = all[hash] || (all[hash] = [])
list.push({
file,
reference: {filePath: reference, hash},
nodes: internal[hash]
Expand Down
59 changes: 43 additions & 16 deletions lib/check/validate.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,42 @@
/**
* @typedef {import('../types.js').VFile} VFile
* @typedef {import('../types.js').Landmarks} Landmarks
* @typedef {import('../types.js').References} References
* @typedef {import('../types.js').ReferenceMap} ReferenceMap
*/

import path from 'path'
// @ts-expect-error: untyped.
import propose from 'propose'
import {constants} from '../constants.js'

const own = {}.hasOwnProperty

/**
* @param {{files: VFile[], landmarks: Landmarks, references: References}} ctx
*/
export function validate(ctx) {
const landmarks = ctx.landmarks
const references = ctx.references
let missing = []
let reference

for (reference in references) {
if (own.call(references, reference)) {
const refs = references[reference]
/** @type {ReferenceMap[]} */
const missing = []
/** @type {string} */
let key

for (key in references) {
if (own.call(references, key)) {
const refs = references[key]
/** @type {Landmarks} */
const lands =
// `else` could happen in browser.
/* c8 ignore next */
reference in landmarks ? landmarks[reference] : Object.create(null)
key in landmarks ? landmarks[key] : Object.create(null)
/** @type {string} */
let hash

for (hash in refs) {
if (!lands[hash]) {
missing = missing.concat(refs[hash])
missing.push(...refs[hash])
}
}
}
Expand All @@ -30,19 +45,29 @@ export function validate(ctx) {
let index = -1

while (++index < missing.length) {
reference = missing[index]
warn(ctx, reference.reference, reference.file, reference.nodes)
warn(ctx, missing[index])
}
}

function warn(ctx, info, file, nodes) {
/**
* @param {{files: VFile[], landmarks: Landmarks, references: References}} ctx
* @param {ReferenceMap} reference
*/
function warn(ctx, reference) {
const landmarks = ctx.landmarks
const absolute = file.path ? path.resolve(file.cwd, file.path) : ''
const absolute = reference.file.path
? path.resolve(reference.file.cwd, reference.file.path)
: ''
const base = absolute ? path.dirname(absolute) : null
const filePath = base ? path.relative(base, info.filePath) : info.filePath
const hash = info.hash
const filePath = base
? path.relative(base, reference.reference.filePath)
: reference.reference.filePath
const hash = reference.reference.hash
/** @type {string[]} */
const dictionary = []
/** @type {string} */
let reason
/** @type {string} */
let ruleId

if (hash) {
Expand All @@ -61,6 +86,7 @@ function warn(ctx, info, file, nodes) {
}

const origin = [constants.sourceId, ruleId].join(':')
/** @type {string} */
let landmark

for (landmark in landmarks) {
Expand All @@ -80,6 +106,7 @@ function warn(ctx, info, file, nodes) {
continue
}

/** @type {string} */
let subhash

for (subhash in landmarks[landmark]) {
Expand All @@ -99,7 +126,7 @@ function warn(ctx, info, file, nodes) {

let index = -1

while (++index < nodes.length) {
file.message(reason, nodes[index], origin)
while (++index < reference.nodes.length) {
reference.file.message(reason, reference.nodes[index], origin)
}
}
29 changes: 23 additions & 6 deletions lib/find/config.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,50 @@
/**
* @typedef {import('mdast').Root} Root
* @typedef {import('vfile').VFile} VFile
* @typedef {import('unified-engine').FileSet} FileSet
* @typedef {import('hosted-git-info').Hosts} Hosts
* @typedef {import('../index.js').Options} Options
* @typedef {import('../index.js').UrlConfig} UrlConfig
*/

import hostedGitInfo from 'hosted-git-info'

/** @type {Partial<Record<Hosts, string>>} */
const viewPaths = {github: 'blob', gitlab: 'blob', bitbucket: 'src'}
/** @type {Partial<Record<Hosts, string>>} */
const headingPrefixes = {
github: '#',
gitlab: '#',
bitbucket: '#markdown-header-'
}
/** @type {Partial<Record<Hosts, string>>} */
const topAnchors = {github: '#readme', gitlab: '#readme'}
/** @type {Partial<Record<Hosts, boolean>>} */
const lineLinks = {github: true, gitlab: true}

/**
* @param {{tree: Root, file: VFile, fileSet?: FileSet, options: Options}} ctx
*/
export function config(ctx) {
const repo = ctx.repository
const repo = ctx.options.repository

if (ctx.urlConfig) {
if (ctx.options.urlConfig) {
return
}

/** @type {UrlConfig} */
const urlConfig = {
prefix: '',
headingPrefix: '#',
lines: false,
hostname: null,
topAnchor: null
hostname: undefined,
topAnchor: undefined
}

if (repo) {
const info = hostedGitInfo.fromUrl(repo)

if (info) {
if (info && info.type !== 'gist') {
if (info.type in viewPaths) {
urlConfig.prefix = '/' + info.path() + '/' + viewPaths[info.type] + '/'
}
Expand All @@ -48,5 +65,5 @@ export function config(ctx) {
}
}

ctx.urlConfig = urlConfig
ctx.options.urlConfig = urlConfig
}
Loading

0 comments on commit b579e27

Please sign in to comment.