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 May 9, 2021
1 parent dff2e38 commit 2fbfe3f
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 13 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.DS_Store
*.d.ts
*.log
coverage/
node_modules/
Expand Down
56 changes: 46 additions & 10 deletions build.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
/**
* @typedef {import('xast').Element} Element
*
* @typedef {{field: string, value: string}} FromTuple
* @typedef {{from: FromTuple, to: FromTuple}} Field
* @typedef {{from: string, to: string}} Match
*/

import fs from 'fs'
import path from 'path'
import fetch from 'node-fetch'
Expand All @@ -14,11 +22,18 @@ fetch(endpoint)
.then((response) => response.text())
.then(onbody, console.error)

/**
* @param {string} doc
*/
function onbody(doc) {
/** @type {Array.<Field>} */
var fields = []
var match = []
/** @type {Array.<string>} */
var defaults = []
/** @type {Object.<string, Object.<string, Array.<string>>>} */
var many = {}
/** @type {Array.<Match>} */
var match = []
var suffix = 'Alias'
var seenHeploc = false
var ignore = [
Expand All @@ -38,11 +53,18 @@ function onbody(doc) {
write('many', many)
write('matches', match)

/** @type {import('unist-util-visit').Visitor<Element>} */
/* eslint-disable-next-line complexity */
function onelement(node) {
var name = node.name
var pos = name.indexOf(suffix)
/** @type {Array.<string>} */
var allFrom
/** @type {Array.<string>} */
var allTo
/** @type {string} */
var from
/** @type {string} */
var to

if (name === 'defaultContent') {
Expand All @@ -67,27 +89,27 @@ function onbody(doc) {
return
}

from = clean(node.attributes.type)
to = clean(node.attributes.replacement)
allFrom = clean(node.attributes.type)
allTo = clean(node.attributes.replacement)

if (from.length === 1) {
from = from[0]
if (allFrom.length === 1) {
from = allFrom[0]
} else {
throw new Error('Cannot map from many: ' + from)
throw new Error('Cannot map from many: ' + allFrom)
}

if (to.length === 1) {
to = to[0]
if (allTo.length === 1) {
to = allTo[0]
} else {
if (!many[name]) {
many[name] = {}
}

many[name][from] = to
many[name][from] = allTo
return
}

if (name === 'region' && from.length === 3 && isNaN(from)) {
if (name === 'region' && from.length === 3 && Number.isNaN(Number(from))) {
console.log(
'ISO 3166-1 alpha 3 codes cannot be represented in BCP 47: %s',
from
Expand Down Expand Up @@ -144,6 +166,10 @@ function onbody(doc) {
}
}

/**
* @param {string} value
* @returns {Array.<string>}
*/
function clean(value) {
return value
.toLowerCase()
Expand All @@ -153,13 +179,23 @@ function clean(value) {
.split(' ')
}

/**
* @param {string} name
* @param {unknown} values
* @returns {void}
*/
function write(name, values) {
fs.writeFileSync(
path.join('lib', name + '.js'),
'export const ' + name + ' = ' + JSON.stringify(values, null, 2) + '\n'
)
}

/**
* @param {string} a
* @param {string} b
* @returns {number}
*/
function sort(a, b) {
return b.length - a.length || a.localeCompare(b)
}
49 changes: 49 additions & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
/**
* @typedef {import('bcp-47/lib/parse.js').ParseOptions['warning']} Warning
* @typedef {import('bcp-47/lib/parse.js').Schema} Schema
* @typedef {import('bcp-47/lib/parse.js').Extension} Extension
*
* @typedef Options
* @property {boolean} [forgiving]
* @property {Warning} [warning]
*/

import {parse, stringify} from 'bcp-47'
import {extendedFilter} from 'bcp-47-match'
import {matches} from './matches.js'
Expand All @@ -9,6 +19,7 @@ var own = {}.hasOwnProperty

var collator = new Intl.Collator()

/** @type {Partial<Schema>} */
var emptyExtraFields = {
variants: [],
extensions: [],
Expand All @@ -17,12 +28,18 @@ var emptyExtraFields = {
regular: null
}

/**
* @param {string} value
* @param {Options} [options]
* @returns {string}
*/
export function bcp47Normalize(value, options) {
var settings = options || {}
// 1. normalize and lowercase the tag (`sgn-be-fr` -> `sfb`).
var schema = parse(String(value || '').toLowerCase(), settings)
var tag = stringify(schema)
var index = -1
/** @type {string} */
var key

if (!tag) {
Expand Down Expand Up @@ -100,10 +117,18 @@ export function bcp47Normalize(value, options) {
return stringify(schema)
}

/**
* @param {Schema} schema
* @param {string} from
* @param {string} to
* @returns {void}
*/
function replace(schema, from, to) {
var left = parse(from)
var right = parse(to)
/** @type {Array.<string>} */
var removed = []
/** @type {string} */
var key

// Remove values from `from`:
Expand All @@ -127,11 +152,21 @@ function replace(schema, from, to) {
}
}

/**
* @param {Schema} object
* @param {string} key
* @param {string|Array.<string>} value
* @returns {boolean}
*/
function remove(object, key, value) {
var removed = false
/** @type {string|Array.<string>} */
var current
/** @type {string|Array.<string>} */
var result
/** @type {number} */
var index
/** @type {string} */
var item

/* istanbul ignore else - this is currently done by wrapping code, so else is
Expand Down Expand Up @@ -165,10 +200,19 @@ function remove(object, key, value) {
return removed
}

/**
* @param {Schema} object
* @param {string} key
* @param {string|Array.<string>} value
* @returns {void}
*/
function add(object, key, value) {
var current = object[key]
/** @type {Array.<string>} */
var list
/** @type {number} */
var index
/** @type {string} */
var item

if (current && typeof current === 'object') {
Expand All @@ -189,6 +233,11 @@ function add(object, key, value) {
}
}

/**
* @param {Extension} left
* @param {Extension} right
* @returns {number}
*/
function compareSingleton(left, right) {
return collator.compare(left.singleton, right.singleton)
}
21 changes: 18 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,30 +31,40 @@
"sideEffects": false,
"type": "module",
"main": "index.js",
"types": "index.d.ts",
"files": [
"index.js",
"lib/"
"lib/",
"index.d.ts",
"index.js"
],
"dependencies": {
"bcp-47": "^2.0.0",
"bcp-47-match": "^2.0.0"
},
"devDependencies": {
"@types/node-fetch": "^2.0.0",
"@types/tape": "^4.0.0",
"@types/xast": "^1.0.0",
"c8": "^7.0.0",
"node-fetch": "^2.0.0",
"prettier": "^2.0.0",
"remark-cli": "^9.0.0",
"remark-preset-wooorm": "^8.0.0",
"rimraf": "^3.0.0",
"tape": "^5.0.0",
"type-coverage": "^2.0.0",
"typescript": "^4.0.0",
"unist-util-visit": "^3.0.0",
"xast-util-from-xml": "^2.0.0",
"xo": "^0.39.0"
},
"scripts": {
"prepack": "npm run build && npm run format",
"build": "rimraf \"{lib/**,}*.d.ts\" && tsc && 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": "npm run format && npm run test-coverage"
"test": "npm run build && npm run format && npm run test-coverage"
},
"prettier": {
"tabWidth": 2,
Expand All @@ -79,5 +89,10 @@
"plugins": [
"preset-wooorm"
]
},
"typeCoverage": {
"atLeast": 100,
"detail": true,
"strict": true
}
}
9 changes: 9 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
/**
* @typedef {import('bcp-47/lib/parse.js').ParseOptions['warning']} Warning
*/

import test from 'tape'
import {bcp47Normalize as normalize} from './index.js'

var own = {}.hasOwnProperty

test('bcp-47-normalize', function (t) {
t.test('basic', function (t) {
// @ts-ignore runtime.
t.equal(normalize(), '', 'should not fail on without a value')
t.equal(normalize(''), '', 'should not fail on an empty string')
t.equal(normalize('en-us'), 'en', 'should normalize')
Expand All @@ -27,6 +32,7 @@ test('bcp-47-normalize', function (t) {

normalize('en-aaa-bbb-ccc-ddd', {warning})

/** @type {Warning} */
function warning(reason, code, offset) {
t.deepEqual(
[reason, code, offset],
Expand All @@ -45,6 +51,7 @@ test('bcp-47-normalize', function (t) {

normalize('pap-an', {warning})

/** @type {Warning} */
function warning(reason, code, offset) {
t.deepEqual(
[reason, code, offset],
Expand Down Expand Up @@ -257,7 +264,9 @@ test('bcp-47-normalize', function (t) {
'zh-hans-tw': 'zh-Hans-TW',
'zh-tw': 'zh-Hant'
}
/** @type {string} */
var from
/** @type {string} */
var to

for (from in fixtures) {
Expand Down
15 changes: 15 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"include": ["lib/**/*.js", "*.js"],
"compilerOptions": {
"target": "ES2020",
"lib": ["ES2020"],
"module": "ES2020",
"moduleResolution": "node",
"allowJs": true,
"checkJs": true,
"declaration": true,
"emitDeclarationOnly": true,
"allowSyntheticDefaultImports": true,
"skipLibCheck": true
}
}

0 comments on commit 2fbfe3f

Please sign in to comment.