This commit is contained in:
xiaoyu
2023-05-22 14:23:20 +08:00
parent 27f83c9959
commit ac8f91d4d3
4244 changed files with 743880 additions and 0 deletions
@@ -0,0 +1,20 @@
Copyright Mathias Bynens <https://mathiasbynens.be/>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+58
View File
@@ -0,0 +1,58 @@
# unicode-canonical-property-names-ecmascript [![Build status](https://travis-ci.org/mathiasbynens/unicode-canonical-property-names-ecmascript.svg?branch=main)](https://travis-ci.org/mathiasbynens/unicode-canonical-property-names-ecmascript) [![unicode-canonical-property-names-ecmascript on npm](https://img.shields.io/npm/v/unicode-canonical-property-names-ecmascript)](https://www.npmjs.com/package/unicode-canonical-property-names-ecmascript)
_unicode-canonical-property-names-ecmascript_ exports the set of canonical Unicode property names that are supported in [ECMAScript RegExp property escapes](https://github.com/tc39/proposal-regexp-unicode-property-escapes).
## Installation
To use _unicode-canonical-property-names-ecmascript_, install it as a dependency via [npm](https://www.npmjs.com/):
```bash
$ npm install unicode-canonical-property-names-ecmascript
```
Then, `require` it:
```js
const properties = require('unicode-canonical-property-names-ecmascript');
```
## Example
```js
properties.has('ID_Start');
// → true
properties.has('IDS');
// → false
```
## For maintainers
### How to publish a new release
1. On the `main` branch, bump the version number in `package.json`:
```sh
npm version patch -m 'Release v%s'
```
Instead of `patch`, use `minor` or `major` [as needed](https://semver.org/).
Note that this produces a Git commit + tag.
1. Push the release commit and tag:
```sh
git push && git push --tags
```
Our CI then automatically publishes the new release to npm.
## Author
| [![twitter/mathias](https://gravatar.com/avatar/24e08a9ea84deb17ae121074d0f17125?s=70)](https://twitter.com/mathias "Follow @mathias on Twitter") |
|---|
| [Mathias Bynens](https://mathiasbynens.be/) |
## License
_unicode-canonical-property-names-ecmascript_ is available under the [MIT](https://mths.be/mit) license.
+60
View File
@@ -0,0 +1,60 @@
module.exports = new Set([
// Non-binary properties:
'General_Category',
'Script',
'Script_Extensions',
// Binary properties:
'Alphabetic',
'Any',
'ASCII',
'ASCII_Hex_Digit',
'Assigned',
'Bidi_Control',
'Bidi_Mirrored',
'Case_Ignorable',
'Cased',
'Changes_When_Casefolded',
'Changes_When_Casemapped',
'Changes_When_Lowercased',
'Changes_When_NFKC_Casefolded',
'Changes_When_Titlecased',
'Changes_When_Uppercased',
'Dash',
'Default_Ignorable_Code_Point',
'Deprecated',
'Diacritic',
'Emoji',
'Emoji_Component',
'Emoji_Modifier',
'Emoji_Modifier_Base',
'Emoji_Presentation',
'Extended_Pictographic',
'Extender',
'Grapheme_Base',
'Grapheme_Extend',
'Hex_Digit',
'ID_Continue',
'ID_Start',
'Ideographic',
'IDS_Binary_Operator',
'IDS_Trinary_Operator',
'Join_Control',
'Logical_Order_Exception',
'Lowercase',
'Math',
'Noncharacter_Code_Point',
'Pattern_Syntax',
'Pattern_White_Space',
'Quotation_Mark',
'Radical',
'Regional_Indicator',
'Sentence_Terminal',
'Soft_Dotted',
'Terminal_Punctuation',
'Unified_Ideograph',
'Uppercase',
'Variation_Selector',
'White_Space',
'XID_Continue',
'XID_Start'
]);
+34
View File
@@ -0,0 +1,34 @@
{
"name": "unicode-canonical-property-names-ecmascript",
"version": "2.0.0",
"description": "The set of canonical Unicode property names supported in ECMAScript RegExp property escapes.",
"homepage": "https://github.com/mathiasbynens/unicode-canonical-property-names-ecmascript",
"main": "index.js",
"engines": {
"node": ">=4"
},
"files": [
"LICENSE-MIT.txt",
"index.js"
],
"keywords": [
"unicode",
"unicode properties"
],
"license": "MIT",
"author": {
"name": "Mathias Bynens",
"url": "https://mathiasbynens.be/"
},
"repository": {
"type": "git",
"url": "https://github.com/mathiasbynens/unicode-canonical-property-names-ecmascript.git"
},
"bugs": "https://github.com/mathiasbynens/unicode-canonical-property-names-ecmascript/issues",
"devDependencies": {
"ava": "*"
},
"scripts": {
"test": "ava tests/tests.js"
}
}
+20
View File
@@ -0,0 +1,20 @@
Copyright Mathias Bynens <https://mathiasbynens.be/>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+69
View File
@@ -0,0 +1,69 @@
# unicode-match-property-ecmascript [![Build status](https://travis-ci.org/mathiasbynens/unicode-match-property-ecmascript.svg?branch=main)](https://travis-ci.org/mathiasbynens/unicode-match-property-ecmascript) [![unicode-match-property-ecmascript on npm](https://img.shields.io/npm/v/unicode-match-property-ecmascript)](https://www.npmjs.com/package/unicode-match-property-ecmascript)
_unicode-match-property-ecmascript_ matches a given Unicode property or [property alias](https://github.com/mathiasbynens/unicode-property-aliases-ecmascript) to its canonical property name without applying [loose matching](https://github.com/mathiasbynens/unicode-loose-match) per the algorithm used for [RegExp Unicode property escapes in ECMAScript](https://github.com/tc39/proposal-regexp-unicode-property-escapes). Consider it a strict alternative to loose matching.
## Installation
To use _unicode-match-property-ecmascript_ programmatically, install it as a dependency via [npm](https://www.npmjs.com/):
```bash
$ npm install unicode-match-property-ecmascript
```
Then, `require` it:
```js
const matchProperty = require('unicode-match-property-ecmascript');
```
## API
This module exports a single function named `matchProperty`.
### `matchProperty(value)`
This function takes a string `value` and attempts to match it to a canonical Unicode property name. If theres a match, it returns the canonical property name. Otherwise, it throws an exception.
```js
// Find the canonical property name:
matchProperty('sc')
// → 'Script'
matchProperty('Script')
// → 'Script'
matchProperty('script') // Note: incorrect casing.
// → throws
```
## For maintainers
### How to publish a new release
1. On the `main` branch, bump the version number in `package.json`:
```sh
npm version patch -m 'Release v%s'
```
Instead of `patch`, use `minor` or `major` [as needed](https://semver.org/).
Note that this produces a Git commit + tag.
1. Push the release commit and tag:
```sh
git push && git push --tags
```
Our CI then automatically publishes the new release to npm.
## Author
| [![twitter/mathias](https://gravatar.com/avatar/24e08a9ea84deb17ae121074d0f17125?s=70)](https://twitter.com/mathias "Follow @mathias on Twitter") |
|---|
| [Mathias Bynens](https://mathiasbynens.be/) |
## License
_unicode-match-property-ecmascript_ is available under the [MIT](https://mths.be/mit) license.
+16
View File
@@ -0,0 +1,16 @@
'use strict';
const canonicalProperties = require('unicode-canonical-property-names-ecmascript');
const propertyAliases = require('unicode-property-aliases-ecmascript');
const matchProperty = function(property) {
if (canonicalProperties.has(property)) {
return property;
}
if (propertyAliases.has(property)) {
return propertyAliases.get(property);
}
throw new Error(`Unknown property: ${ property }`);
};
module.exports = matchProperty;
+39
View File
@@ -0,0 +1,39 @@
{
"name": "unicode-match-property-ecmascript",
"version": "2.0.0",
"description": "Match a Unicode property or property alias to its canonical property name per the algorithm used for RegExp Unicode property escapes in ECMAScript.",
"homepage": "https://github.com/mathiasbynens/unicode-match-property-ecmascript",
"main": "index.js",
"engines": {
"node": ">=4"
},
"files": [
"LICENSE-MIT.txt",
"index.js"
],
"keywords": [
"unicode",
"unicode properties",
"unicode property aliases"
],
"license": "MIT",
"author": {
"name": "Mathias Bynens",
"url": "https://mathiasbynens.be/"
},
"repository": {
"type": "git",
"url": "https://github.com/mathiasbynens/unicode-match-property-ecmascript.git"
},
"bugs": "https://github.com/mathiasbynens/unicode-match-property-ecmascript/issues",
"dependencies": {
"unicode-canonical-property-names-ecmascript": "^2.0.0",
"unicode-property-aliases-ecmascript": "^2.0.0"
},
"devDependencies": {
"ava": "*"
},
"scripts": {
"test": "ava ./tests/*"
}
}
+20
View File
@@ -0,0 +1,20 @@
Copyright Mathias Bynens <https://mathiasbynens.be/>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+72
View File
@@ -0,0 +1,72 @@
# unicode-match-property-value-ecmascript [![Build status](https://travis-ci.org/mathiasbynens/unicode-match-property-value-ecmascript.svg?branch=main)](https://travis-ci.org/mathiasbynens/unicode-match-property-value-ecmascript) [![unicode-match-property-value-ecmascript on npm](https://img.shields.io/npm/v/unicode-match-property-value-ecmascript)](https://www.npmjs.com/package/unicode-match-property-value-ecmascript)
_unicode-match-property-value-ecmascript_ matches a given Unicode property value or [property value alias](https://github.com/mathiasbynens/unicode-property-value-aliases) to its canonical property value without applying [loose matching](https://github.com/mathiasbynens/unicode-loose-match), per the algorithm used for [RegExp Unicode property escapes in ECMAScript](https://github.com/tc39/proposal-regexp-unicode-property-escapes). Consider it a strict alternative to loose matching.
## Installation
To use _unicode-match-property-value-ecmascript_ programmatically, install it as a dependency via [npm](https://www.npmjs.com/):
```bash
$ npm install unicode-match-property-value-ecmascript
```
Then, `require` it:
```js
const matchPropertyValue = require('unicode-match-property-value-ecmascript');
```
## API
This module exports a single function named `matchPropertyValue`.
### `matchPropertyValue(property, value)`
This function takes a string `property` that is a canonical/unaliased Unicode property name, and a string `value`. It attemps to match `value` to a canonical Unicode property value for the given property. If theres a match, it returns the canonical property value. Otherwise, it throws an exception.
```js
// Find the canonical property value:
matchPropertyValue('Script_Extensions', 'Aghb')
// → 'Caucasian_Albanian'
matchPropertyValue('Script_Extensions', 'Caucasian_Albanian')
// → 'Caucasian_Albanian'
matchPropertyValue('script_extensions', 'Caucasian_Albanian') // Note: incorrect casing.
// → throws
matchPropertyValue('Script_Extensions', 'caucasian_albanian') // Note: incorrect casing.
// → throws
```
## For maintainers
### How to publish a new release
1. On the `main` branch, bump the version number in `package.json`:
```sh
npm version patch -m 'Release v%s'
```
Instead of `patch`, use `minor` or `major` [as needed](https://semver.org/).
Note that this produces a Git commit + tag.
1. Push the release commit and tag:
```sh
git push && git push --tags
```
Our CI then automatically publishes the new release to npm.
## Author
| [![twitter/mathias](https://gravatar.com/avatar/24e08a9ea84deb17ae121074d0f17125?s=70)](https://twitter.com/mathias "Follow @mathias on Twitter") |
|---|
| [Mathias Bynens](https://mathiasbynens.be/) |
## License
_unicode-match-property-value-ecmascript_ is available under the [MIT](https://mths.be/mit) license.
+730
View File
@@ -0,0 +1,730 @@
module.exports = new Map([
['General_Category', new Map([
['C', 'Other'],
['Cc', 'Control'],
['cntrl', 'Control'],
['Cf', 'Format'],
['Cn', 'Unassigned'],
['Co', 'Private_Use'],
['Cs', 'Surrogate'],
['L', 'Letter'],
['LC', 'Cased_Letter'],
['Ll', 'Lowercase_Letter'],
['Lm', 'Modifier_Letter'],
['Lo', 'Other_Letter'],
['Lt', 'Titlecase_Letter'],
['Lu', 'Uppercase_Letter'],
['M', 'Mark'],
['Combining_Mark', 'Mark'],
['Mc', 'Spacing_Mark'],
['Me', 'Enclosing_Mark'],
['Mn', 'Nonspacing_Mark'],
['N', 'Number'],
['Nd', 'Decimal_Number'],
['digit', 'Decimal_Number'],
['Nl', 'Letter_Number'],
['No', 'Other_Number'],
['P', 'Punctuation'],
['punct', 'Punctuation'],
['Pc', 'Connector_Punctuation'],
['Pd', 'Dash_Punctuation'],
['Pe', 'Close_Punctuation'],
['Pf', 'Final_Punctuation'],
['Pi', 'Initial_Punctuation'],
['Po', 'Other_Punctuation'],
['Ps', 'Open_Punctuation'],
['S', 'Symbol'],
['Sc', 'Currency_Symbol'],
['Sk', 'Modifier_Symbol'],
['Sm', 'Math_Symbol'],
['So', 'Other_Symbol'],
['Z', 'Separator'],
['Zl', 'Line_Separator'],
['Zp', 'Paragraph_Separator'],
['Zs', 'Space_Separator'],
['Other', 'Other'],
['Control', 'Control'],
['Format', 'Format'],
['Unassigned', 'Unassigned'],
['Private_Use', 'Private_Use'],
['Surrogate', 'Surrogate'],
['Letter', 'Letter'],
['Cased_Letter', 'Cased_Letter'],
['Lowercase_Letter', 'Lowercase_Letter'],
['Modifier_Letter', 'Modifier_Letter'],
['Other_Letter', 'Other_Letter'],
['Titlecase_Letter', 'Titlecase_Letter'],
['Uppercase_Letter', 'Uppercase_Letter'],
['Mark', 'Mark'],
['Spacing_Mark', 'Spacing_Mark'],
['Enclosing_Mark', 'Enclosing_Mark'],
['Nonspacing_Mark', 'Nonspacing_Mark'],
['Number', 'Number'],
['Decimal_Number', 'Decimal_Number'],
['Letter_Number', 'Letter_Number'],
['Other_Number', 'Other_Number'],
['Punctuation', 'Punctuation'],
['Connector_Punctuation', 'Connector_Punctuation'],
['Dash_Punctuation', 'Dash_Punctuation'],
['Close_Punctuation', 'Close_Punctuation'],
['Final_Punctuation', 'Final_Punctuation'],
['Initial_Punctuation', 'Initial_Punctuation'],
['Other_Punctuation', 'Other_Punctuation'],
['Open_Punctuation', 'Open_Punctuation'],
['Symbol', 'Symbol'],
['Currency_Symbol', 'Currency_Symbol'],
['Modifier_Symbol', 'Modifier_Symbol'],
['Math_Symbol', 'Math_Symbol'],
['Other_Symbol', 'Other_Symbol'],
['Separator', 'Separator'],
['Line_Separator', 'Line_Separator'],
['Paragraph_Separator', 'Paragraph_Separator'],
['Space_Separator', 'Space_Separator']
])],
['Script', new Map([
['Adlm', 'Adlam'],
['Aghb', 'Caucasian_Albanian'],
['Ahom', 'Ahom'],
['Arab', 'Arabic'],
['Armi', 'Imperial_Aramaic'],
['Armn', 'Armenian'],
['Avst', 'Avestan'],
['Bali', 'Balinese'],
['Bamu', 'Bamum'],
['Bass', 'Bassa_Vah'],
['Batk', 'Batak'],
['Beng', 'Bengali'],
['Bhks', 'Bhaiksuki'],
['Bopo', 'Bopomofo'],
['Brah', 'Brahmi'],
['Brai', 'Braille'],
['Bugi', 'Buginese'],
['Buhd', 'Buhid'],
['Cakm', 'Chakma'],
['Cans', 'Canadian_Aboriginal'],
['Cari', 'Carian'],
['Cham', 'Cham'],
['Cher', 'Cherokee'],
['Chrs', 'Chorasmian'],
['Copt', 'Coptic'],
['Qaac', 'Coptic'],
['Cpmn', 'Cypro_Minoan'],
['Cprt', 'Cypriot'],
['Cyrl', 'Cyrillic'],
['Deva', 'Devanagari'],
['Diak', 'Dives_Akuru'],
['Dogr', 'Dogra'],
['Dsrt', 'Deseret'],
['Dupl', 'Duployan'],
['Egyp', 'Egyptian_Hieroglyphs'],
['Elba', 'Elbasan'],
['Elym', 'Elymaic'],
['Ethi', 'Ethiopic'],
['Geor', 'Georgian'],
['Glag', 'Glagolitic'],
['Gong', 'Gunjala_Gondi'],
['Gonm', 'Masaram_Gondi'],
['Goth', 'Gothic'],
['Gran', 'Grantha'],
['Grek', 'Greek'],
['Gujr', 'Gujarati'],
['Guru', 'Gurmukhi'],
['Hang', 'Hangul'],
['Hani', 'Han'],
['Hano', 'Hanunoo'],
['Hatr', 'Hatran'],
['Hebr', 'Hebrew'],
['Hira', 'Hiragana'],
['Hluw', 'Anatolian_Hieroglyphs'],
['Hmng', 'Pahawh_Hmong'],
['Hmnp', 'Nyiakeng_Puachue_Hmong'],
['Hrkt', 'Katakana_Or_Hiragana'],
['Hung', 'Old_Hungarian'],
['Ital', 'Old_Italic'],
['Java', 'Javanese'],
['Kali', 'Kayah_Li'],
['Kana', 'Katakana'],
['Khar', 'Kharoshthi'],
['Khmr', 'Khmer'],
['Khoj', 'Khojki'],
['Kits', 'Khitan_Small_Script'],
['Knda', 'Kannada'],
['Kthi', 'Kaithi'],
['Lana', 'Tai_Tham'],
['Laoo', 'Lao'],
['Latn', 'Latin'],
['Lepc', 'Lepcha'],
['Limb', 'Limbu'],
['Lina', 'Linear_A'],
['Linb', 'Linear_B'],
['Lisu', 'Lisu'],
['Lyci', 'Lycian'],
['Lydi', 'Lydian'],
['Mahj', 'Mahajani'],
['Maka', 'Makasar'],
['Mand', 'Mandaic'],
['Mani', 'Manichaean'],
['Marc', 'Marchen'],
['Medf', 'Medefaidrin'],
['Mend', 'Mende_Kikakui'],
['Merc', 'Meroitic_Cursive'],
['Mero', 'Meroitic_Hieroglyphs'],
['Mlym', 'Malayalam'],
['Modi', 'Modi'],
['Mong', 'Mongolian'],
['Mroo', 'Mro'],
['Mtei', 'Meetei_Mayek'],
['Mult', 'Multani'],
['Mymr', 'Myanmar'],
['Nand', 'Nandinagari'],
['Narb', 'Old_North_Arabian'],
['Nbat', 'Nabataean'],
['Newa', 'Newa'],
['Nkoo', 'Nko'],
['Nshu', 'Nushu'],
['Ogam', 'Ogham'],
['Olck', 'Ol_Chiki'],
['Orkh', 'Old_Turkic'],
['Orya', 'Oriya'],
['Osge', 'Osage'],
['Osma', 'Osmanya'],
['Ougr', 'Old_Uyghur'],
['Palm', 'Palmyrene'],
['Pauc', 'Pau_Cin_Hau'],
['Perm', 'Old_Permic'],
['Phag', 'Phags_Pa'],
['Phli', 'Inscriptional_Pahlavi'],
['Phlp', 'Psalter_Pahlavi'],
['Phnx', 'Phoenician'],
['Plrd', 'Miao'],
['Prti', 'Inscriptional_Parthian'],
['Rjng', 'Rejang'],
['Rohg', 'Hanifi_Rohingya'],
['Runr', 'Runic'],
['Samr', 'Samaritan'],
['Sarb', 'Old_South_Arabian'],
['Saur', 'Saurashtra'],
['Sgnw', 'SignWriting'],
['Shaw', 'Shavian'],
['Shrd', 'Sharada'],
['Sidd', 'Siddham'],
['Sind', 'Khudawadi'],
['Sinh', 'Sinhala'],
['Sogd', 'Sogdian'],
['Sogo', 'Old_Sogdian'],
['Sora', 'Sora_Sompeng'],
['Soyo', 'Soyombo'],
['Sund', 'Sundanese'],
['Sylo', 'Syloti_Nagri'],
['Syrc', 'Syriac'],
['Tagb', 'Tagbanwa'],
['Takr', 'Takri'],
['Tale', 'Tai_Le'],
['Talu', 'New_Tai_Lue'],
['Taml', 'Tamil'],
['Tang', 'Tangut'],
['Tavt', 'Tai_Viet'],
['Telu', 'Telugu'],
['Tfng', 'Tifinagh'],
['Tglg', 'Tagalog'],
['Thaa', 'Thaana'],
['Thai', 'Thai'],
['Tibt', 'Tibetan'],
['Tirh', 'Tirhuta'],
['Tnsa', 'Tangsa'],
['Toto', 'Toto'],
['Ugar', 'Ugaritic'],
['Vaii', 'Vai'],
['Vith', 'Vithkuqi'],
['Wara', 'Warang_Citi'],
['Wcho', 'Wancho'],
['Xpeo', 'Old_Persian'],
['Xsux', 'Cuneiform'],
['Yezi', 'Yezidi'],
['Yiii', 'Yi'],
['Zanb', 'Zanabazar_Square'],
['Zinh', 'Inherited'],
['Qaai', 'Inherited'],
['Zyyy', 'Common'],
['Zzzz', 'Unknown'],
['Adlam', 'Adlam'],
['Caucasian_Albanian', 'Caucasian_Albanian'],
['Arabic', 'Arabic'],
['Imperial_Aramaic', 'Imperial_Aramaic'],
['Armenian', 'Armenian'],
['Avestan', 'Avestan'],
['Balinese', 'Balinese'],
['Bamum', 'Bamum'],
['Bassa_Vah', 'Bassa_Vah'],
['Batak', 'Batak'],
['Bengali', 'Bengali'],
['Bhaiksuki', 'Bhaiksuki'],
['Bopomofo', 'Bopomofo'],
['Brahmi', 'Brahmi'],
['Braille', 'Braille'],
['Buginese', 'Buginese'],
['Buhid', 'Buhid'],
['Chakma', 'Chakma'],
['Canadian_Aboriginal', 'Canadian_Aboriginal'],
['Carian', 'Carian'],
['Cherokee', 'Cherokee'],
['Chorasmian', 'Chorasmian'],
['Coptic', 'Coptic'],
['Cypro_Minoan', 'Cypro_Minoan'],
['Cypriot', 'Cypriot'],
['Cyrillic', 'Cyrillic'],
['Devanagari', 'Devanagari'],
['Dives_Akuru', 'Dives_Akuru'],
['Dogra', 'Dogra'],
['Deseret', 'Deseret'],
['Duployan', 'Duployan'],
['Egyptian_Hieroglyphs', 'Egyptian_Hieroglyphs'],
['Elbasan', 'Elbasan'],
['Elymaic', 'Elymaic'],
['Ethiopic', 'Ethiopic'],
['Georgian', 'Georgian'],
['Glagolitic', 'Glagolitic'],
['Gunjala_Gondi', 'Gunjala_Gondi'],
['Masaram_Gondi', 'Masaram_Gondi'],
['Gothic', 'Gothic'],
['Grantha', 'Grantha'],
['Greek', 'Greek'],
['Gujarati', 'Gujarati'],
['Gurmukhi', 'Gurmukhi'],
['Hangul', 'Hangul'],
['Han', 'Han'],
['Hanunoo', 'Hanunoo'],
['Hatran', 'Hatran'],
['Hebrew', 'Hebrew'],
['Hiragana', 'Hiragana'],
['Anatolian_Hieroglyphs', 'Anatolian_Hieroglyphs'],
['Pahawh_Hmong', 'Pahawh_Hmong'],
['Nyiakeng_Puachue_Hmong', 'Nyiakeng_Puachue_Hmong'],
['Katakana_Or_Hiragana', 'Katakana_Or_Hiragana'],
['Old_Hungarian', 'Old_Hungarian'],
['Old_Italic', 'Old_Italic'],
['Javanese', 'Javanese'],
['Kayah_Li', 'Kayah_Li'],
['Katakana', 'Katakana'],
['Kharoshthi', 'Kharoshthi'],
['Khmer', 'Khmer'],
['Khojki', 'Khojki'],
['Khitan_Small_Script', 'Khitan_Small_Script'],
['Kannada', 'Kannada'],
['Kaithi', 'Kaithi'],
['Tai_Tham', 'Tai_Tham'],
['Lao', 'Lao'],
['Latin', 'Latin'],
['Lepcha', 'Lepcha'],
['Limbu', 'Limbu'],
['Linear_A', 'Linear_A'],
['Linear_B', 'Linear_B'],
['Lycian', 'Lycian'],
['Lydian', 'Lydian'],
['Mahajani', 'Mahajani'],
['Makasar', 'Makasar'],
['Mandaic', 'Mandaic'],
['Manichaean', 'Manichaean'],
['Marchen', 'Marchen'],
['Medefaidrin', 'Medefaidrin'],
['Mende_Kikakui', 'Mende_Kikakui'],
['Meroitic_Cursive', 'Meroitic_Cursive'],
['Meroitic_Hieroglyphs', 'Meroitic_Hieroglyphs'],
['Malayalam', 'Malayalam'],
['Mongolian', 'Mongolian'],
['Mro', 'Mro'],
['Meetei_Mayek', 'Meetei_Mayek'],
['Multani', 'Multani'],
['Myanmar', 'Myanmar'],
['Nandinagari', 'Nandinagari'],
['Old_North_Arabian', 'Old_North_Arabian'],
['Nabataean', 'Nabataean'],
['Nko', 'Nko'],
['Nushu', 'Nushu'],
['Ogham', 'Ogham'],
['Ol_Chiki', 'Ol_Chiki'],
['Old_Turkic', 'Old_Turkic'],
['Oriya', 'Oriya'],
['Osage', 'Osage'],
['Osmanya', 'Osmanya'],
['Old_Uyghur', 'Old_Uyghur'],
['Palmyrene', 'Palmyrene'],
['Pau_Cin_Hau', 'Pau_Cin_Hau'],
['Old_Permic', 'Old_Permic'],
['Phags_Pa', 'Phags_Pa'],
['Inscriptional_Pahlavi', 'Inscriptional_Pahlavi'],
['Psalter_Pahlavi', 'Psalter_Pahlavi'],
['Phoenician', 'Phoenician'],
['Miao', 'Miao'],
['Inscriptional_Parthian', 'Inscriptional_Parthian'],
['Rejang', 'Rejang'],
['Hanifi_Rohingya', 'Hanifi_Rohingya'],
['Runic', 'Runic'],
['Samaritan', 'Samaritan'],
['Old_South_Arabian', 'Old_South_Arabian'],
['Saurashtra', 'Saurashtra'],
['SignWriting', 'SignWriting'],
['Shavian', 'Shavian'],
['Sharada', 'Sharada'],
['Siddham', 'Siddham'],
['Khudawadi', 'Khudawadi'],
['Sinhala', 'Sinhala'],
['Sogdian', 'Sogdian'],
['Old_Sogdian', 'Old_Sogdian'],
['Sora_Sompeng', 'Sora_Sompeng'],
['Soyombo', 'Soyombo'],
['Sundanese', 'Sundanese'],
['Syloti_Nagri', 'Syloti_Nagri'],
['Syriac', 'Syriac'],
['Tagbanwa', 'Tagbanwa'],
['Takri', 'Takri'],
['Tai_Le', 'Tai_Le'],
['New_Tai_Lue', 'New_Tai_Lue'],
['Tamil', 'Tamil'],
['Tangut', 'Tangut'],
['Tai_Viet', 'Tai_Viet'],
['Telugu', 'Telugu'],
['Tifinagh', 'Tifinagh'],
['Tagalog', 'Tagalog'],
['Thaana', 'Thaana'],
['Tibetan', 'Tibetan'],
['Tirhuta', 'Tirhuta'],
['Tangsa', 'Tangsa'],
['Ugaritic', 'Ugaritic'],
['Vai', 'Vai'],
['Vithkuqi', 'Vithkuqi'],
['Warang_Citi', 'Warang_Citi'],
['Wancho', 'Wancho'],
['Old_Persian', 'Old_Persian'],
['Cuneiform', 'Cuneiform'],
['Yezidi', 'Yezidi'],
['Yi', 'Yi'],
['Zanabazar_Square', 'Zanabazar_Square'],
['Inherited', 'Inherited'],
['Common', 'Common'],
['Unknown', 'Unknown']
])],
['Script_Extensions', new Map([
['Adlm', 'Adlam'],
['Aghb', 'Caucasian_Albanian'],
['Ahom', 'Ahom'],
['Arab', 'Arabic'],
['Armi', 'Imperial_Aramaic'],
['Armn', 'Armenian'],
['Avst', 'Avestan'],
['Bali', 'Balinese'],
['Bamu', 'Bamum'],
['Bass', 'Bassa_Vah'],
['Batk', 'Batak'],
['Beng', 'Bengali'],
['Bhks', 'Bhaiksuki'],
['Bopo', 'Bopomofo'],
['Brah', 'Brahmi'],
['Brai', 'Braille'],
['Bugi', 'Buginese'],
['Buhd', 'Buhid'],
['Cakm', 'Chakma'],
['Cans', 'Canadian_Aboriginal'],
['Cari', 'Carian'],
['Cham', 'Cham'],
['Cher', 'Cherokee'],
['Chrs', 'Chorasmian'],
['Copt', 'Coptic'],
['Qaac', 'Coptic'],
['Cpmn', 'Cypro_Minoan'],
['Cprt', 'Cypriot'],
['Cyrl', 'Cyrillic'],
['Deva', 'Devanagari'],
['Diak', 'Dives_Akuru'],
['Dogr', 'Dogra'],
['Dsrt', 'Deseret'],
['Dupl', 'Duployan'],
['Egyp', 'Egyptian_Hieroglyphs'],
['Elba', 'Elbasan'],
['Elym', 'Elymaic'],
['Ethi', 'Ethiopic'],
['Geor', 'Georgian'],
['Glag', 'Glagolitic'],
['Gong', 'Gunjala_Gondi'],
['Gonm', 'Masaram_Gondi'],
['Goth', 'Gothic'],
['Gran', 'Grantha'],
['Grek', 'Greek'],
['Gujr', 'Gujarati'],
['Guru', 'Gurmukhi'],
['Hang', 'Hangul'],
['Hani', 'Han'],
['Hano', 'Hanunoo'],
['Hatr', 'Hatran'],
['Hebr', 'Hebrew'],
['Hira', 'Hiragana'],
['Hluw', 'Anatolian_Hieroglyphs'],
['Hmng', 'Pahawh_Hmong'],
['Hmnp', 'Nyiakeng_Puachue_Hmong'],
['Hrkt', 'Katakana_Or_Hiragana'],
['Hung', 'Old_Hungarian'],
['Ital', 'Old_Italic'],
['Java', 'Javanese'],
['Kali', 'Kayah_Li'],
['Kana', 'Katakana'],
['Khar', 'Kharoshthi'],
['Khmr', 'Khmer'],
['Khoj', 'Khojki'],
['Kits', 'Khitan_Small_Script'],
['Knda', 'Kannada'],
['Kthi', 'Kaithi'],
['Lana', 'Tai_Tham'],
['Laoo', 'Lao'],
['Latn', 'Latin'],
['Lepc', 'Lepcha'],
['Limb', 'Limbu'],
['Lina', 'Linear_A'],
['Linb', 'Linear_B'],
['Lisu', 'Lisu'],
['Lyci', 'Lycian'],
['Lydi', 'Lydian'],
['Mahj', 'Mahajani'],
['Maka', 'Makasar'],
['Mand', 'Mandaic'],
['Mani', 'Manichaean'],
['Marc', 'Marchen'],
['Medf', 'Medefaidrin'],
['Mend', 'Mende_Kikakui'],
['Merc', 'Meroitic_Cursive'],
['Mero', 'Meroitic_Hieroglyphs'],
['Mlym', 'Malayalam'],
['Modi', 'Modi'],
['Mong', 'Mongolian'],
['Mroo', 'Mro'],
['Mtei', 'Meetei_Mayek'],
['Mult', 'Multani'],
['Mymr', 'Myanmar'],
['Nand', 'Nandinagari'],
['Narb', 'Old_North_Arabian'],
['Nbat', 'Nabataean'],
['Newa', 'Newa'],
['Nkoo', 'Nko'],
['Nshu', 'Nushu'],
['Ogam', 'Ogham'],
['Olck', 'Ol_Chiki'],
['Orkh', 'Old_Turkic'],
['Orya', 'Oriya'],
['Osge', 'Osage'],
['Osma', 'Osmanya'],
['Ougr', 'Old_Uyghur'],
['Palm', 'Palmyrene'],
['Pauc', 'Pau_Cin_Hau'],
['Perm', 'Old_Permic'],
['Phag', 'Phags_Pa'],
['Phli', 'Inscriptional_Pahlavi'],
['Phlp', 'Psalter_Pahlavi'],
['Phnx', 'Phoenician'],
['Plrd', 'Miao'],
['Prti', 'Inscriptional_Parthian'],
['Rjng', 'Rejang'],
['Rohg', 'Hanifi_Rohingya'],
['Runr', 'Runic'],
['Samr', 'Samaritan'],
['Sarb', 'Old_South_Arabian'],
['Saur', 'Saurashtra'],
['Sgnw', 'SignWriting'],
['Shaw', 'Shavian'],
['Shrd', 'Sharada'],
['Sidd', 'Siddham'],
['Sind', 'Khudawadi'],
['Sinh', 'Sinhala'],
['Sogd', 'Sogdian'],
['Sogo', 'Old_Sogdian'],
['Sora', 'Sora_Sompeng'],
['Soyo', 'Soyombo'],
['Sund', 'Sundanese'],
['Sylo', 'Syloti_Nagri'],
['Syrc', 'Syriac'],
['Tagb', 'Tagbanwa'],
['Takr', 'Takri'],
['Tale', 'Tai_Le'],
['Talu', 'New_Tai_Lue'],
['Taml', 'Tamil'],
['Tang', 'Tangut'],
['Tavt', 'Tai_Viet'],
['Telu', 'Telugu'],
['Tfng', 'Tifinagh'],
['Tglg', 'Tagalog'],
['Thaa', 'Thaana'],
['Thai', 'Thai'],
['Tibt', 'Tibetan'],
['Tirh', 'Tirhuta'],
['Tnsa', 'Tangsa'],
['Toto', 'Toto'],
['Ugar', 'Ugaritic'],
['Vaii', 'Vai'],
['Vith', 'Vithkuqi'],
['Wara', 'Warang_Citi'],
['Wcho', 'Wancho'],
['Xpeo', 'Old_Persian'],
['Xsux', 'Cuneiform'],
['Yezi', 'Yezidi'],
['Yiii', 'Yi'],
['Zanb', 'Zanabazar_Square'],
['Zinh', 'Inherited'],
['Qaai', 'Inherited'],
['Zyyy', 'Common'],
['Zzzz', 'Unknown'],
['Adlam', 'Adlam'],
['Caucasian_Albanian', 'Caucasian_Albanian'],
['Arabic', 'Arabic'],
['Imperial_Aramaic', 'Imperial_Aramaic'],
['Armenian', 'Armenian'],
['Avestan', 'Avestan'],
['Balinese', 'Balinese'],
['Bamum', 'Bamum'],
['Bassa_Vah', 'Bassa_Vah'],
['Batak', 'Batak'],
['Bengali', 'Bengali'],
['Bhaiksuki', 'Bhaiksuki'],
['Bopomofo', 'Bopomofo'],
['Brahmi', 'Brahmi'],
['Braille', 'Braille'],
['Buginese', 'Buginese'],
['Buhid', 'Buhid'],
['Chakma', 'Chakma'],
['Canadian_Aboriginal', 'Canadian_Aboriginal'],
['Carian', 'Carian'],
['Cherokee', 'Cherokee'],
['Chorasmian', 'Chorasmian'],
['Coptic', 'Coptic'],
['Cypro_Minoan', 'Cypro_Minoan'],
['Cypriot', 'Cypriot'],
['Cyrillic', 'Cyrillic'],
['Devanagari', 'Devanagari'],
['Dives_Akuru', 'Dives_Akuru'],
['Dogra', 'Dogra'],
['Deseret', 'Deseret'],
['Duployan', 'Duployan'],
['Egyptian_Hieroglyphs', 'Egyptian_Hieroglyphs'],
['Elbasan', 'Elbasan'],
['Elymaic', 'Elymaic'],
['Ethiopic', 'Ethiopic'],
['Georgian', 'Georgian'],
['Glagolitic', 'Glagolitic'],
['Gunjala_Gondi', 'Gunjala_Gondi'],
['Masaram_Gondi', 'Masaram_Gondi'],
['Gothic', 'Gothic'],
['Grantha', 'Grantha'],
['Greek', 'Greek'],
['Gujarati', 'Gujarati'],
['Gurmukhi', 'Gurmukhi'],
['Hangul', 'Hangul'],
['Han', 'Han'],
['Hanunoo', 'Hanunoo'],
['Hatran', 'Hatran'],
['Hebrew', 'Hebrew'],
['Hiragana', 'Hiragana'],
['Anatolian_Hieroglyphs', 'Anatolian_Hieroglyphs'],
['Pahawh_Hmong', 'Pahawh_Hmong'],
['Nyiakeng_Puachue_Hmong', 'Nyiakeng_Puachue_Hmong'],
['Katakana_Or_Hiragana', 'Katakana_Or_Hiragana'],
['Old_Hungarian', 'Old_Hungarian'],
['Old_Italic', 'Old_Italic'],
['Javanese', 'Javanese'],
['Kayah_Li', 'Kayah_Li'],
['Katakana', 'Katakana'],
['Kharoshthi', 'Kharoshthi'],
['Khmer', 'Khmer'],
['Khojki', 'Khojki'],
['Khitan_Small_Script', 'Khitan_Small_Script'],
['Kannada', 'Kannada'],
['Kaithi', 'Kaithi'],
['Tai_Tham', 'Tai_Tham'],
['Lao', 'Lao'],
['Latin', 'Latin'],
['Lepcha', 'Lepcha'],
['Limbu', 'Limbu'],
['Linear_A', 'Linear_A'],
['Linear_B', 'Linear_B'],
['Lycian', 'Lycian'],
['Lydian', 'Lydian'],
['Mahajani', 'Mahajani'],
['Makasar', 'Makasar'],
['Mandaic', 'Mandaic'],
['Manichaean', 'Manichaean'],
['Marchen', 'Marchen'],
['Medefaidrin', 'Medefaidrin'],
['Mende_Kikakui', 'Mende_Kikakui'],
['Meroitic_Cursive', 'Meroitic_Cursive'],
['Meroitic_Hieroglyphs', 'Meroitic_Hieroglyphs'],
['Malayalam', 'Malayalam'],
['Mongolian', 'Mongolian'],
['Mro', 'Mro'],
['Meetei_Mayek', 'Meetei_Mayek'],
['Multani', 'Multani'],
['Myanmar', 'Myanmar'],
['Nandinagari', 'Nandinagari'],
['Old_North_Arabian', 'Old_North_Arabian'],
['Nabataean', 'Nabataean'],
['Nko', 'Nko'],
['Nushu', 'Nushu'],
['Ogham', 'Ogham'],
['Ol_Chiki', 'Ol_Chiki'],
['Old_Turkic', 'Old_Turkic'],
['Oriya', 'Oriya'],
['Osage', 'Osage'],
['Osmanya', 'Osmanya'],
['Old_Uyghur', 'Old_Uyghur'],
['Palmyrene', 'Palmyrene'],
['Pau_Cin_Hau', 'Pau_Cin_Hau'],
['Old_Permic', 'Old_Permic'],
['Phags_Pa', 'Phags_Pa'],
['Inscriptional_Pahlavi', 'Inscriptional_Pahlavi'],
['Psalter_Pahlavi', 'Psalter_Pahlavi'],
['Phoenician', 'Phoenician'],
['Miao', 'Miao'],
['Inscriptional_Parthian', 'Inscriptional_Parthian'],
['Rejang', 'Rejang'],
['Hanifi_Rohingya', 'Hanifi_Rohingya'],
['Runic', 'Runic'],
['Samaritan', 'Samaritan'],
['Old_South_Arabian', 'Old_South_Arabian'],
['Saurashtra', 'Saurashtra'],
['SignWriting', 'SignWriting'],
['Shavian', 'Shavian'],
['Sharada', 'Sharada'],
['Siddham', 'Siddham'],
['Khudawadi', 'Khudawadi'],
['Sinhala', 'Sinhala'],
['Sogdian', 'Sogdian'],
['Old_Sogdian', 'Old_Sogdian'],
['Sora_Sompeng', 'Sora_Sompeng'],
['Soyombo', 'Soyombo'],
['Sundanese', 'Sundanese'],
['Syloti_Nagri', 'Syloti_Nagri'],
['Syriac', 'Syriac'],
['Tagbanwa', 'Tagbanwa'],
['Takri', 'Takri'],
['Tai_Le', 'Tai_Le'],
['New_Tai_Lue', 'New_Tai_Lue'],
['Tamil', 'Tamil'],
['Tangut', 'Tangut'],
['Tai_Viet', 'Tai_Viet'],
['Telugu', 'Telugu'],
['Tifinagh', 'Tifinagh'],
['Tagalog', 'Tagalog'],
['Thaana', 'Thaana'],
['Tibetan', 'Tibetan'],
['Tirhuta', 'Tirhuta'],
['Tangsa', 'Tangsa'],
['Ugaritic', 'Ugaritic'],
['Vai', 'Vai'],
['Vithkuqi', 'Vithkuqi'],
['Warang_Citi', 'Warang_Citi'],
['Wancho', 'Wancho'],
['Old_Persian', 'Old_Persian'],
['Cuneiform', 'Cuneiform'],
['Yezidi', 'Yezidi'],
['Yi', 'Yi'],
['Zanabazar_Square', 'Zanabazar_Square'],
['Inherited', 'Inherited'],
['Common', 'Common'],
['Unknown', 'Unknown']
])]
]);
+19
View File
@@ -0,0 +1,19 @@
'use strict';
const propertyToValueAliases = require('./data/mappings.js');
const matchPropertyValue = function(property, value) {
const aliasToValue = propertyToValueAliases.get(property);
if (!aliasToValue) {
throw new Error(`Unknown property \`${ property }\`.`);
}
const canonicalValue = aliasToValue.get(value);
if (canonicalValue) {
return canonicalValue;
}
throw new Error(
`Unknown value \`${ value }\` for property \`${ property }\`.`
);
};
module.exports = matchPropertyValue;
+39
View File
@@ -0,0 +1,39 @@
{
"name": "unicode-match-property-value-ecmascript",
"version": "2.0.0",
"description": "Match a Unicode property or property alias to its canonical property name per the algorithm used for RegExp Unicode property escapes in ECMAScript.",
"homepage": "https://github.com/mathiasbynens/unicode-match-property-value-ecmascript",
"main": "index.js",
"engines": {
"node": ">=4"
},
"files": [
"LICENSE-MIT.txt",
"data/mappings.js",
"index.js"
],
"keywords": [
"unicode",
"unicode property values",
"unicode property value aliases"
],
"license": "MIT",
"author": {
"name": "Mathias Bynens",
"url": "https://mathiasbynens.be/"
},
"repository": {
"type": "git",
"url": "https://github.com/mathiasbynens/unicode-match-property-value-ecmascript.git"
},
"bugs": "https://github.com/mathiasbynens/unicode-match-property-value-ecmascript/issues",
"devDependencies": {
"ava": "*",
"jsesc": "^3.0.2",
"unicode-property-value-aliases-ecmascript": "^2.0.0"
},
"scripts": {
"build": "node scripts/build.js",
"test": "ava tests/tests.js"
}
}
+20
View File
@@ -0,0 +1,20 @@
Copyright Mathias Bynens <https://mathiasbynens.be/>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+60
View File
@@ -0,0 +1,60 @@
# unicode-property-aliases-ecmascript [![Build status](https://travis-ci.org/mathiasbynens/unicode-property-aliases-ecmascript.svg?branch=main)](https://travis-ci.org/mathiasbynens/unicode-property-aliases-ecmascript) [![unicode-property-aliases-ecmascript on npm](https://img.shields.io/npm/v/unicode-property-aliases-ecmascript)](https://www.npmjs.com/package/unicode-property-aliases-ecmascript)
_unicode-property-aliases-ecmascript_ offers Unicode property alias mappings in an easy-to-consume JavaScript format. It only contains the Unicode property names that are supported in [ECMAScript RegExp property escapes](https://github.com/tc39/proposal-regexp-unicode-property-escapes).
Its based on Unicodes `PropertyAliases.txt`.
## Installation
To use _unicode-property-aliases-ecmascript_ programmatically, install it as a dependency via [npm](https://www.npmjs.com/):
```bash
$ npm install unicode-property-aliases-ecmascript
```
Then, `require` it:
```js
const propertyAliases = require('unicode-property-aliases-ecmascript');
```
## Usage
This module exports a `Map` object. The most common usage is to convert a property alias to its canonical form:
```js
propertyAliases.get('scx')
// → 'Script_Extensions'
```
## For maintainers
### How to publish a new release
1. On the `main` branch, bump the version number in `package.json`:
```sh
npm version patch -m 'Release v%s'
```
Instead of `patch`, use `minor` or `major` [as needed](https://semver.org/).
Note that this produces a Git commit + tag.
1. Push the release commit and tag:
```sh
git push && git push --tags
```
Our CI then automatically publishes the new release to npm.
## Author
| [![twitter/mathias](https://gravatar.com/avatar/24e08a9ea84deb17ae121074d0f17125?s=70)](https://twitter.com/mathias "Follow @mathias on Twitter") |
|---|
| [Mathias Bynens](https://mathiasbynens.be/) |
## License
_unicode-property-aliases-ecmascript_ is available under the [MIT](https://mths.be/mit) license.
+57
View File
@@ -0,0 +1,57 @@
// Generated using `npm run build`. Do not edit!
module.exports = new Map([
['scx', 'Script_Extensions'],
['sc', 'Script'],
['gc', 'General_Category'],
['AHex', 'ASCII_Hex_Digit'],
['Alpha', 'Alphabetic'],
['Bidi_C', 'Bidi_Control'],
['Bidi_M', 'Bidi_Mirrored'],
['Cased', 'Cased'],
['CI', 'Case_Ignorable'],
['CWCF', 'Changes_When_Casefolded'],
['CWCM', 'Changes_When_Casemapped'],
['CWKCF', 'Changes_When_NFKC_Casefolded'],
['CWL', 'Changes_When_Lowercased'],
['CWT', 'Changes_When_Titlecased'],
['CWU', 'Changes_When_Uppercased'],
['Dash', 'Dash'],
['Dep', 'Deprecated'],
['DI', 'Default_Ignorable_Code_Point'],
['Dia', 'Diacritic'],
['EBase', 'Emoji_Modifier_Base'],
['EComp', 'Emoji_Component'],
['EMod', 'Emoji_Modifier'],
['Emoji', 'Emoji'],
['EPres', 'Emoji_Presentation'],
['Ext', 'Extender'],
['ExtPict', 'Extended_Pictographic'],
['Gr_Base', 'Grapheme_Base'],
['Gr_Ext', 'Grapheme_Extend'],
['Hex', 'Hex_Digit'],
['IDC', 'ID_Continue'],
['Ideo', 'Ideographic'],
['IDS', 'ID_Start'],
['IDSB', 'IDS_Binary_Operator'],
['IDST', 'IDS_Trinary_Operator'],
['Join_C', 'Join_Control'],
['LOE', 'Logical_Order_Exception'],
['Lower', 'Lowercase'],
['Math', 'Math'],
['NChar', 'Noncharacter_Code_Point'],
['Pat_Syn', 'Pattern_Syntax'],
['Pat_WS', 'Pattern_White_Space'],
['QMark', 'Quotation_Mark'],
['Radical', 'Radical'],
['RI', 'Regional_Indicator'],
['SD', 'Soft_Dotted'],
['STerm', 'Sentence_Terminal'],
['Term', 'Terminal_Punctuation'],
['UIdeo', 'Unified_Ideograph'],
['Upper', 'Uppercase'],
['VS', 'Variation_Selector'],
['WSpace', 'White_Space'],
['space', 'White_Space'],
['XIDC', 'XID_Continue'],
['XIDS', 'XID_Start']
]);
+41
View File
@@ -0,0 +1,41 @@
{
"name": "unicode-property-aliases-ecmascript",
"version": "2.0.0",
"description": "Unicode property alias mappings in JavaScript format for property names that are supported in ECMAScript RegExp property escapes.",
"homepage": "https://github.com/mathiasbynens/unicode-property-aliases-ecmascript",
"main": "index.js",
"engines": {
"node": ">=4"
},
"files": [
"LICENSE-MIT.txt",
"index.js"
],
"keywords": [
"unicode",
"unicode-data",
"alias",
"aliases",
"property alias"
],
"license": "MIT",
"author": {
"name": "Mathias Bynens",
"url": "https://mathiasbynens.be/"
},
"repository": {
"type": "git",
"url": "https://github.com/mathiasbynens/unicode-property-aliases-ecmascript.git"
},
"bugs": "https://github.com/mathiasbynens/unicode-property-aliases-ecmascript/issues",
"devDependencies": {
"ava": "*",
"jsesc": "^2.5.2",
"unicode-canonical-property-names-ecmascript": "^1.0.4"
},
"scripts": {
"download": "curl http://unicode.org/Public/14.0.0/ucd/PropertyAliases.txt > data/PropertyAliases.txt",
"build": "node scripts/build.js",
"test": "ava tests/tests.js"
}
}
+57
View File
@@ -0,0 +1,57 @@
# Unidragger
_Base draggable class_
Used in [Flickity](http://flickity.metafizzy.co) and [Draggabilly](http://draggabilly.desandro.com).
Unidragger handles all the event binding and handling to support a draggable library.
## Features
+ Touch device support: iOS, Android, Microsoft Surface
+ Handles click events in `input` elements
## Install
Bower: `bower install unidragger --save`
npm: `npm install unidragger --save`
## Demo code
``` js
// your draggable class
function Dragger( elem ) {
this.element = elem;
}
// use Unidragger as a mixin
extend( Dragger.prototype, Unidragger.prototype );
Dragger.prototype.create = function() {
// set drag handles
this.handles = [ this.element ];
this.bindHandles();
};
Dragger.prototype.dragStart = function( event, pointer ) {
console.log('drag start');
};
Dragger.prototype.dragMove = function( event, pointer, moveVector ) {
var dragX = this.dragStartPoint.x + moveVector.x;
var dragY = this.dragStartPoint.y + moveVector.y;
this.element.style.left = dragX + 'px';
this.element.style.top = dragY + 'px';
};
Dragger.prototype.dragEnd = function( event, pointer ) {
console.log('drag end');
};
```
---
MIT license
By [Metafizzy 🌈🐻](https://metafizzy.co)
+30
View File
@@ -0,0 +1,30 @@
{
"name": "unidragger",
"main": "unidragger.js",
"dependencies": {
"unipointer": "^2.4.0"
},
"authors": [
"David DeSandro <desandrocodes@gmail.com>"
],
"description": "Draggable base class",
"moduleType": [
"amd",
"globals",
"node"
],
"keywords": [
"draggable",
"flickity",
"draggabilly"
],
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests",
"package.json"
]
}
+30
View File
@@ -0,0 +1,30 @@
{
"name": "unidragger",
"version": "2.4.0",
"description": "Base draggable class",
"main": "unidragger.js",
"dependencies": {
"unipointer": "^2.4.0"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"draggable",
"flickity",
"draggabilly",
"browser",
"dom"
],
"author": "David DeSandro",
"license": "MIT",
"devDependencies": {},
"repository": {
"type": "git",
"url": "git://github.com/metafizzy/unidragger.git"
},
"bugs": {
"url": "https://github.com/metafizzy/unidragger/issues"
},
"homepage": "https://github.com/metafizzy/unidragger"
}
+283
View File
@@ -0,0 +1,283 @@
/*!
* Unidragger v2.4.0
* Draggable base class
* MIT license
*/
/*jshint browser: true, unused: true, undef: true, strict: true */
( function( window, factory ) {
// universal module definition
/*jshint strict: false */ /*globals define, module, require */
if ( typeof define == 'function' && define.amd ) {
// AMD
define( [
'unipointer/unipointer'
], function( Unipointer ) {
return factory( window, Unipointer );
});
} else if ( typeof module == 'object' && module.exports ) {
// CommonJS
module.exports = factory(
window,
require('unipointer')
);
} else {
// browser global
window.Unidragger = factory(
window,
window.Unipointer
);
}
}( window, function factory( window, Unipointer ) {
'use strict';
// -------------------------- Unidragger -------------------------- //
function Unidragger() {}
// inherit Unipointer & EvEmitter
var proto = Unidragger.prototype = Object.create( Unipointer.prototype );
// ----- bind start ----- //
proto.bindHandles = function() {
this._bindHandles( true );
};
proto.unbindHandles = function() {
this._bindHandles( false );
};
/**
* Add or remove start event
* @param {Boolean} isAdd
*/
proto._bindHandles = function( isAdd ) {
// munge isAdd, default to true
isAdd = isAdd === undefined ? true : isAdd;
// bind each handle
var bindMethod = isAdd ? 'addEventListener' : 'removeEventListener';
var touchAction = isAdd ? this._touchActionValue : '';
for ( var i=0; i < this.handles.length; i++ ) {
var handle = this.handles[i];
this._bindStartEvent( handle, isAdd );
handle[ bindMethod ]( 'click', this );
// touch-action: none to override browser touch gestures. metafizzy/flickity#540
if ( window.PointerEvent ) {
handle.style.touchAction = touchAction;
}
}
};
// prototype so it can be overwriteable by Flickity
proto._touchActionValue = 'none';
// ----- start event ----- //
/**
* pointer start
* @param {Event} event
* @param {Event or Touch} pointer
*/
proto.pointerDown = function( event, pointer ) {
var isOkay = this.okayPointerDown( event );
if ( !isOkay ) {
return;
}
// track start event position
// Safari 9 overrides pageX and pageY. These values needs to be copied. flickity#842
this.pointerDownPointer = {
pageX: pointer.pageX,
pageY: pointer.pageY,
};
event.preventDefault();
this.pointerDownBlur();
// bind move and end events
this._bindPostStartEvents( event );
this.emitEvent( 'pointerDown', [ event, pointer ] );
};
// nodes that have text fields
var cursorNodes = {
TEXTAREA: true,
INPUT: true,
SELECT: true,
OPTION: true,
};
// input types that do not have text fields
var clickTypes = {
radio: true,
checkbox: true,
button: true,
submit: true,
image: true,
file: true,
};
// dismiss inputs with text fields. flickity#403, flickity#404
proto.okayPointerDown = function( event ) {
var isCursorNode = cursorNodes[ event.target.nodeName ];
var isClickType = clickTypes[ event.target.type ];
var isOkay = !isCursorNode || isClickType;
if ( !isOkay ) {
this._pointerReset();
}
return isOkay;
};
// kludge to blur previously focused input
proto.pointerDownBlur = function() {
var focused = document.activeElement;
// do not blur body for IE10, metafizzy/flickity#117
var canBlur = focused && focused.blur && focused != document.body;
if ( canBlur ) {
focused.blur();
}
};
// ----- move event ----- //
/**
* drag move
* @param {Event} event
* @param {Event or Touch} pointer
*/
proto.pointerMove = function( event, pointer ) {
var moveVector = this._dragPointerMove( event, pointer );
this.emitEvent( 'pointerMove', [ event, pointer, moveVector ] );
this._dragMove( event, pointer, moveVector );
};
// base pointer move logic
proto._dragPointerMove = function( event, pointer ) {
var moveVector = {
x: pointer.pageX - this.pointerDownPointer.pageX,
y: pointer.pageY - this.pointerDownPointer.pageY
};
// start drag if pointer has moved far enough to start drag
if ( !this.isDragging && this.hasDragStarted( moveVector ) ) {
this._dragStart( event, pointer );
}
return moveVector;
};
// condition if pointer has moved far enough to start drag
proto.hasDragStarted = function( moveVector ) {
return Math.abs( moveVector.x ) > 3 || Math.abs( moveVector.y ) > 3;
};
// ----- end event ----- //
/**
* pointer up
* @param {Event} event
* @param {Event or Touch} pointer
*/
proto.pointerUp = function( event, pointer ) {
this.emitEvent( 'pointerUp', [ event, pointer ] );
this._dragPointerUp( event, pointer );
};
proto._dragPointerUp = function( event, pointer ) {
if ( this.isDragging ) {
this._dragEnd( event, pointer );
} else {
// pointer didn't move enough for drag to start
this._staticClick( event, pointer );
}
};
// -------------------------- drag -------------------------- //
// dragStart
proto._dragStart = function( event, pointer ) {
this.isDragging = true;
// prevent clicks
this.isPreventingClicks = true;
this.dragStart( event, pointer );
};
proto.dragStart = function( event, pointer ) {
this.emitEvent( 'dragStart', [ event, pointer ] );
};
// dragMove
proto._dragMove = function( event, pointer, moveVector ) {
// do not drag if not dragging yet
if ( !this.isDragging ) {
return;
}
this.dragMove( event, pointer, moveVector );
};
proto.dragMove = function( event, pointer, moveVector ) {
event.preventDefault();
this.emitEvent( 'dragMove', [ event, pointer, moveVector ] );
};
// dragEnd
proto._dragEnd = function( event, pointer ) {
// set flags
this.isDragging = false;
// re-enable clicking async
setTimeout( function() {
delete this.isPreventingClicks;
}.bind( this ) );
this.dragEnd( event, pointer );
};
proto.dragEnd = function( event, pointer ) {
this.emitEvent( 'dragEnd', [ event, pointer ] );
};
// ----- onclick ----- //
// handle all clicks and prevent clicks when dragging
proto.onclick = function( event ) {
if ( this.isPreventingClicks ) {
event.preventDefault();
}
};
// ----- staticClick ----- //
// triggered after pointer down & up with no/tiny movement
proto._staticClick = function( event, pointer ) {
// ignore emulated mouse up clicks
if ( this.isIgnoringMouseUp && event.type == 'mouseup' ) {
return;
}
this.staticClick( event, pointer );
// set flag for emulated clicks 300ms after touchend
if ( event.type != 'mouseup' ) {
this.isIgnoringMouseUp = true;
// reset flag after 300ms
setTimeout( function() {
delete this.isIgnoringMouseUp;
}.bind( this ), 400 );
}
};
proto.staticClick = function( event, pointer ) {
this.emitEvent( 'staticClick', [ event, pointer ] );
};
// ----- utils ----- //
Unidragger.getPointerPoint = Unipointer.getPointerPoint;
// ----- ----- //
return Unidragger;
}));
+863
View File
@@ -0,0 +1,863 @@
// TypeScript Version: 4.0
// Note: this is a `.d.ts` file because it is not possible to have default type
// parameters in JSDoc-based TypeScript, which is a feature we use to type that:
//
// ```js
// .use(somePlugin, theOptions)
// ```
//
// `theOptions` matches the options that `somePlugin` expects and thus is very
// important for making unified usable in TypeScript.
//
// Furthermore, this is places in the root of the project because types that
// accept type parameters cannot be re-exported as such easily.
import {Node} from 'unist'
import {VFile, VFileCompatible} from 'vfile'
/* eslint-disable @typescript-eslint/naming-convention */
type VFileWithOutput<Result> = Result extends Uint8Array // Buffer.
? VFile
: Result extends object // Custom result type
? VFile & {result: Result}
: VFile
// Get the right most non-void thing.
type Specific<Left = void, Right = void> = Right extends void ? Left : Right
// Create a processor based on the input/output of a plugin.
type UsePlugin<
ParseTree extends Node | void = void,
CurrentTree extends Node | void = void,
CompileTree extends Node | void = void,
CompileResult = void,
Input = void,
Output = void
> = Output extends Node
? Input extends string
? // If `Input` is `string` and `Output` is `Node`, then this plugin
// defines a parser, so set `ParseTree`.
Processor<
Output,
Specific<Output, CurrentTree>,
Specific<Output, CompileTree>,
CompileResult
>
: Input extends Node
? // If `Input` is `Node` and `Output` is `Node`, then this plugin defines a
// transformer, its output defines the input of the next, so set
// `CurrentTree`.
Processor<
Specific<Input, ParseTree>,
Output,
Specific<CompileTree, Output>,
CompileResult
>
: // Else, `Input` is something else and `Output` is `Node`:
never
: Input extends Node
? // If `Input` is `Node` and `Output` is not a `Node`, then this plugin
// defines a compiler, so set `CompileTree` and `CompileResult`
Processor<
Specific<Input, ParseTree>,
Specific<Input, CurrentTree>,
Input,
Output
>
: // Else, `Input` is not a `Node` and `Output` is not a `Node`.
// Maybe its untyped, or the plugin throws an error (`never`), so lets
// just keep it as it was.
Processor<ParseTree, CurrentTree, CompileTree, CompileResult>
/* eslint-enable @typescript-eslint/naming-convention */
/**
* Processor allows plugins to be chained together to transform content.
* The chain of plugins defines how content flows through it.
*
* @typeParam ParseTree
* The node that the parser yields (and `run` receives).
* @typeParam CurrentTree
* The node that the last attached plugin yields.
* @typeParam CompileTree
* The node that the compiler receives (and `run` yields).
* @typeParam CompileResult
* The thing that the compiler yields.
*/
export interface Processor<
ParseTree extends Node | void = void,
CurrentTree extends Node | void = void,
CompileTree extends Node | void = void,
CompileResult = void
> extends FrozenProcessor<ParseTree, CurrentTree, CompileTree, CompileResult> {
/**
* Configure the processor to use a plugin.
*
* @typeParam PluginParameters
* Plugin settings.
* @typeParam Input
* Value that is accepted by the plugin.
*
* * If the plugin returns a transformer, then this should be the node
* type that the transformer expects.
* * If the plugin sets a parser, then this should be `string`.
* * If the plugin sets a compiler, then this should be the node type that
* the compiler expects.
* @typeParam Output
* Value that the plugin yields.
*
* * If the plugin returns a transformer, then this should be the node
* type that the transformer yields, and defaults to `Input`.
* * If the plugin sets a parser, then this should be the node type that
* the parser yields.
* * If the plugin sets a compiler, then this should be the result that
* the compiler yields (`string`, `Buffer`, or something else).
* @param plugin
* Plugin (function) to use.
* Plugins are deduped based on identity: passing a function in twice will
* cause it to run only once.
* @param settings
* Configuration for plugin, optional.
* Plugins typically receive one options object, but could receive other and
* more values.
* Its also possible to pass a boolean instead of settings: `true` (to turn
* a plugin on) or `false` (to turn a plugin off).
* @returns
* Current processor.
*/
use<
PluginParameters extends any[] = any[],
Input = Specific<Node, CurrentTree>,
Output = Input
>(
plugin: Plugin<PluginParameters, Input, Output>,
...settings: PluginParameters | [boolean]
): UsePlugin<
ParseTree,
CurrentTree,
CompileTree,
CompileResult,
Input,
Output
>
/**
* Configure the processor with a tuple of a plugin and setting(s).
*
* @typeParam PluginParameters
* Plugin settings.
* @typeParam Input
* Value that is accepted by the plugin.
*
* * If the plugin returns a transformer, then this should be the node
* type that the transformer expects.
* * If the plugin sets a parser, then this should be `string`.
* * If the plugin sets a compiler, then this should be the node type that
* the compiler expects.
* @typeParam Output
* Value that the plugin yields.
*
* * If the plugin returns a transformer, then this should be the node
* type that the transformer yields, and defaults to `Input`.
* * If the plugin sets a parser, then this should be the node type that
* the parser yields.
* * If the plugin sets a compiler, then this should be the result that
* the compiler yields (`string`, `Buffer`, or something else).
* @param tuple
* A tuple where the first item is a plugin (function) to use and other
* items are options.
* Plugins are deduped based on identity: passing a function in twice will
* cause it to run only once.
* Its also possible to pass a boolean instead of settings: `true` (to turn
* a plugin on) or `false` (to turn a plugin off).
* @returns
* Current processor.
*/
use<
PluginParameters extends any[] = any[],
Input = Specific<Node, CurrentTree>,
Output = Input
>(
tuple:
| PluginTuple<PluginParameters, Input, Output>
| [Plugin<PluginParameters, Input, Output>, boolean]
): UsePlugin<
ParseTree,
CurrentTree,
CompileTree,
CompileResult,
Input,
Output
>
/**
* Configure the processor with a preset or list of plugins and presets.
*
* @param presetOrList
* Either a list of plugins, presets, and tuples, or a single preset: an
* object with a `plugins` (list) and/or `settings`
* (`Record<string, unknown>`).
* @returns
* Current processor.
*/
use(
presetOrList: Preset | PluggableList
): Processor<ParseTree, CurrentTree, CompileTree, CompileResult>
}
/**
* A frozen processor is just like a regular processor, except no additional
* plugins can be added.
* A frozen processor can be created by calling `.freeze()` on a processor.
* An unfrozen processor can be created by calling a processor.
*/
export interface FrozenProcessor<
ParseTree extends Node | void = void,
CurrentTree extends Node | void = void,
CompileTree extends Node | void = void,
CompileResult = void
> {
/**
* Clone current processor
*
* @returns
* New unfrozen processor that is configured to function the same as its
* ancestor.
* But when the descendant processor is configured it does not affect the
* ancestral processor.
*/
(): Processor<ParseTree, CurrentTree, CompileTree, CompileResult>
/**
* Internal list of configured plugins.
*
* @private
*/
attachers: Array<[Plugin, ...unknown[]]>
Parser?: Parser<Specific<Node, ParseTree>> | undefined
Compiler?:
| Compiler<Specific<Node, CompileTree>, Specific<unknown, CompileResult>>
| undefined
/**
* Parse a file.
*
* @param file
* File to parse.
* `VFile` or anything that can be given to `new VFile()`, optional.
* @returns
* Resulting tree.
*/
parse(file?: VFileCompatible | undefined): Specific<Node, ParseTree>
/**
* Compile a file.
*
* @param node
* Node to compile.
* @param file
* `VFile` or anything that can be given to `new VFile()`, optional.
* @returns
* New content: compiled text (`string` or `Buffer`) or something else.
* This depends on which plugins you use: typically text, but could for
* example be a React node.
*/
stringify(
node: Specific<Node, CompileTree>,
file?: VFileCompatible | undefined
): CompileTree extends Node ? CompileResult : unknown
/**
* Run transforms on the given tree.
*
* @param node
* Tree to transform.
* @param callback
* Callback called with an error or the resulting node.
* @returns
* Nothing.
*/
run(
node: Specific<Node, ParseTree>,
callback: RunCallback<Specific<Node, CompileTree>>
): void
/**
* Run transforms on the given node.
*
* @param node
* Tree to transform.
* @param file
* File associated with `node`.
* `VFile` or anything that can be given to `new VFile()`.
* @param callback
* Callback called with an error or the resulting node.
* @returns
* Nothing.
*/
run(
node: Specific<Node, ParseTree>,
file: VFileCompatible | undefined,
callback: RunCallback<Specific<Node, CompileTree>>
): void
/**
* Run transforms on the given node.
*
* @param node
* Tree to transform.
* @param file
* File associated with `node`.
* `VFile` or anything that can be given to `new VFile()`.
* @returns
* Promise that resolves to the resulting tree.
*/
run(
node: Specific<Node, ParseTree>,
file?: VFileCompatible | undefined
): Promise<Specific<Node, CompileTree>>
/**
* Run transforms on the given node, synchronously.
* Throws when asynchronous transforms are configured.
*
* @param node
* Tree to transform.
* @param file
* File associated with `node`.
* `VFile` or anything that can be given to `new VFile()`, optional.
* @returns
* Resulting tree.
*/
runSync(
node: Specific<Node, ParseTree>,
file?: VFileCompatible | undefined
): Specific<Node, CompileTree>
/**
* Process a file.
*
* This performs all phases of the processor:
*
* 1. Parse a file into a unist node using the configured `Parser`
* 2. Run transforms on that node
* 3. Compile the resulting node using the `Compiler`
*
* The result from the compiler is stored on the file.
* What the result is depends on which plugins you use.
* The result is typically text (`string` or `Buffer`), which can be retrieved
* with `file.toString()` (or `String(file)`).
* In some cases, such as when using `rehypeReact` to create a React node,
* the result is stored on `file.result`.
*
* @param file
* `VFile` or anything that can be given to `new VFile()`.
* @param callback
* Callback called with an error or the resulting file.
* @returns
* Nothing.
*/
process(
file: VFileCompatible | undefined,
callback: ProcessCallback<VFileWithOutput<CompileResult>>
): void
/**
* Process a file.
*
* This performs all phases of the processor:
*
* 1. Parse a file into a unist node using the configured `Parser`
* 2. Run transforms on that node
* 3. Compile the resulting node using the `Compiler`
*
* The result from the compiler is stored on the file.
* What the result is depends on which plugins you use.
* The result is typically text (`string` or `Buffer`), which can be retrieved
* with `file.toString()` (or `String(file)`).
* In some cases, such as when using `rehypeReact` to create a React node,
* the result is stored on `file.result`.
*
* @param file
* `VFile` or anything that can be given to `new VFile()`.
* @returns
* Promise that resolves to the resulting `VFile`.
*/
process(file: VFileCompatible): Promise<VFileWithOutput<CompileResult>>
/**
* Process a file, synchronously.
* Throws when asynchronous transforms are configured.
*
* This performs all phases of the processor:
*
* 1. Parse a file into a unist node using the configured `Parser`
* 2. Run transforms on that node
* 3. Compile the resulting node using the `Compiler`
*
* The result from the compiler is stored on the file.
* What the result is depends on which plugins you use.
* The result is typically text (`string` or `Buffer`), which can be retrieved
* with `file.toString()` (or `String(file)`).
* In some cases, such as when using `rehypeReact` to create a React node,
* the result is stored on `file.result`.
*
* @param file
* `VFile` or anything that can be given to `new VFile()`, optional.
* @returns
* Resulting file.
*/
processSync(
file?: VFileCompatible | undefined
): VFileWithOutput<CompileResult>
/**
* Get an in-memory key-value store accessible to all phases of the process.
*
* @returns
* Key-value store.
*/
data(): Record<string, unknown>
/**
* Set an in-memory key-value store accessible to all phases of the process.
*
* @param data
* Key-value store.
* @returns
* Current processor.
*/
data(
data: Record<string, unknown>
): Processor<ParseTree, CurrentTree, CompileTree, CompileResult>
/**
* Get an in-memory value by key.
*
* @param key
* Key to get.
* @returns
* The value at `key`.
*/
data(key: string): unknown
/**
* Set an in-memory value by key.
*
* @param key
* Key to set.
* @param value
* Value to set.
* @returns
* Current processor.
*/
data(
key: string,
value: unknown
): Processor<ParseTree, CurrentTree, CompileTree, CompileResult>
/**
* Freeze a processor.
* Frozen processors are meant to be extended and not to be configured or
* processed directly.
*
* Once a processor is frozen it cannot be unfrozen.
* New processors working just like it can be created by calling the
* processor.
*
* Its possible to freeze processors explicitly, by calling `.freeze()`, but
* `.parse()`, `.run()`, `.stringify()`, and `.process()` call `.freeze()` to
* freeze a processor too.
*
* @returns
* Frozen processor.
*/
freeze(): FrozenProcessor<ParseTree, CurrentTree, CompileTree, CompileResult>
}
/**
* A plugin is a function.
* It configures the processor and in turn can receive options.
* Plugins can configure processors by interacting with parsers and compilers
* (at `this.Parser` or `this.Compiler`) or by specifying how the syntax tree
* is handled (by returning a `Transformer`).
*
* @typeParam PluginParameters
* Plugin settings.
* @typeParam Input
* Value that is accepted by the plugin.
*
* * If the plugin returns a transformer, then this should be the node
* type that the transformer expects.
* * If the plugin sets a parser, then this should be `string`.
* * If the plugin sets a compiler, then this should be the node type that
* the compiler expects.
* @typeParam Output
* Value that the plugin yields.
*
* * If the plugin returns a transformer, then this should be the node
* type that the transformer yields, and defaults to `Input`.
* * If the plugin sets a parser, then this should be the node type that
* the parser yields.
* * If the plugin sets a compiler, then this should be the result that
* the compiler yields (`string`, `Buffer`, or something else).
* @this
* The current processor.
* Plugins can configure the processor by interacting with `this.Parser` or
* `this.Compiler`, or by accessing the data associated with the whole process
* (`this.data`).
* @param settings
* Configuration for plugin.
* Plugins typically receive one options object, but could receive other and
* more values.
* Users can also pass a boolean instead of settings: `true` (to turn
* a plugin on) or `false` (to turn a plugin off).
* When a plugin is turned off, it wont be called.
*
* When creating your own plugins, please accept only a single object!
* It allows plugins to be reconfigured and it helps users to know that every
* plugin accepts one options object.
* @returns
* Plugins can return a `Transformer` to specify how the syntax tree is
* handled.
*/
export type Plugin<
PluginParameters extends any[] = any[],
Input = Node,
Output = Input
> = (
this: Input extends Node
? Output extends Node
? // This is a transform, so define `Input` as the current tree.
Processor<void, Input>
: // Compiler.
Processor<void, Input, Input, Output>
: Output extends Node
? // Parser.
Processor<Output, Output>
: // No clue.
Processor,
...settings: PluginParameters
) => // If both `Input` and `Output` are `Node`, expect an optional `Transformer`.
Input extends Node
? Output extends Node
? Transformer<Input, Output> | void
: void
: void
/**
* Presets provide a sharable way to configure processors with multiple plugins
* and/or settings.
*/
export interface Preset {
plugins?: PluggableList
settings?: Record<string, unknown>
}
/**
* A tuple of a plugin and its setting(s).
* The first item is a plugin (function) to use and other items are options.
* Plugins are deduped based on identity: passing a function in twice will
* cause it to run only once.
*
* @typeParam PluginParameters
* Plugin settings.
* @typeParam Input
* Value that is accepted by the plugin.
*
* * If the plugin returns a transformer, then this should be the node
* type that the transformer expects.
* * If the plugin sets a parser, then this should be `string`.
* * If the plugin sets a compiler, then this should be the node type that
* the compiler expects.
* @typeParam Output
* Value that the plugin yields.
*
* * If the plugin returns a transformer, then this should be the node
* type that the transformer yields, and defaults to `Input`.
* * If the plugin sets a parser, then this should be the node type that
* the parser yields.
* * If the plugin sets a compiler, then this should be the result that
* the compiler yields (`string`, `Buffer`, or something else).
*/
export type PluginTuple<
PluginParameters extends any[] = any[],
Input = Node,
Output = Input
> = [Plugin<PluginParameters, Input, Output>, ...PluginParameters]
/**
* A union of the different ways to add plugins and settings.
*
* @typeParam PluginParameters
* Plugin settings.
*/
export type Pluggable<PluginParameters extends any[] = any[]> =
| PluginTuple<PluginParameters, any, any>
| Plugin<PluginParameters, any, any>
| Preset
/**
* A list of plugins and presets.
*/
export type PluggableList = Pluggable[]
/**
* @deprecated
* Please use `Plugin`.
*/
export type Attacher<
PluginParameters extends any[] = any[],
Input = Node,
Output = Input
> = Plugin<PluginParameters, Input, Output>
/**
* Transformers modify the syntax tree or metadata of a file.
* A transformer is a function that is called each time a file is passed
* through the transform phase.
* If an error occurs (either because its thrown, returned, rejected, or passed
* to `next`), the process stops.
*
* @typeParam Input
* Node type that the transformer expects.
* @typeParam Output
* Node type that the transformer yields.
* @param node
* Tree to be transformed.
* @param file
* File associated with node.
* @param next
* Callback that you must call when done.
* Note: this is given if you accept three parameters in your transformer.
* If you accept up to two parameters, its not given, and you can return
* a promise.
* @returns
* Any of the following:
*
* * `void` — If nothing is returned, the next transformer keeps using same
* tree.
* * `Error` — Can be returned to stop the process.
* * `Node` — Can be returned and results in further transformations and
* `stringify`s to be performed on the new tree.
* * `Promise` — If a promise is returned, the function is asynchronous, and
* must be resolved (optionally with a `Node`) or rejected (optionally with
* an `Error`).
*
* If you accept a `next` callback, nothing should be returned.
*/
export type Transformer<
Input extends Node = Node,
Output extends Node = Input
> = (
node: Input,
file: VFile,
next: TransformCallback<Output>
) => Promise<Output | undefined | void> | Output | Error | undefined | void
/**
* Callback you must call when a transformer is done.
*
* @typeParam Tree
* Node that the plugin yields.
* @param error
* Pass an error to stop the process.
* @param node
* Pass a tree to continue transformations (and `stringify`) on the new tree.
* @param file
* Pass a file to continue transformations (and `stringify`) on the new file.
* @returns
* Nothing.
*/
export type TransformCallback<Tree extends Node = Node> = (
error?: Error | null | undefined,
node?: Tree | undefined,
file?: VFile | undefined
) => void
/**
* Function handling the parsing of text to a syntax tree.
* Used in the parse phase in the process and called with a `string` and
* `VFile` representation of the document to parse.
*
* `Parser` can be a normal function, in which case it must return a `Node`:
* the syntax tree representation of the given file.
*
* `Parser` can also be a constructor function (a function with keys in its
* `prototype`), in which case its called with `new`.
* Instances must have a parse method that is called without arguments and
* must return a `Node`.
*
* @typeParam Tree
* The node that the parser yields (and `run` receives).
*/
export type Parser<Tree extends Node = Node> =
| ParserClass<Tree>
| ParserFunction<Tree>
/**
* A class to parse files.
*
* @typeParam Tree
* The node that the parser yields.
*/
export class ParserClass<Tree extends Node = Node> {
prototype: {
/**
* Parse a file.
*
* @returns
* Parsed tree.
*/
parse(): Tree
}
/**
* Constructor.
*
* @param document
* Document to parse.
* @param file
* File associated with `document`.
* @returns
* Instance.
*/
constructor(document: string, file: VFile)
}
/**
* Normal function to parse a file.
*
* @typeParam Tree
* The node that the parser yields.
* @param document
* Document to parse.
* @param file
* File associated with `document`.
* @returns
* Node representing the given file.
*/
export type ParserFunction<Tree extends Node = Node> = (
document: string,
file: VFile
) => Tree
/**
* Function handling the compilation of syntax tree to a text.
* Used in the stringify phase in the process and called with a `Node` and
* `VFile` representation of the document to stringify.
*
* `Compiler` can be a normal function, in which case it must return a
* `string`: the text representation of the given syntax tree.
*
* `Compiler` can also be a constructor function (a function with keys in its
* `prototype`), in which case its called with `new`.
* Instances must have a `compile` method that is called without arguments
* and must return a `string`.
*
* @typeParam Tree
* The node that the compiler receives.
* @typeParam Result
* The thing that the compiler yields.
*/
export type Compiler<Tree extends Node = Node, Result = unknown> =
| CompilerClass<Tree, Result>
| CompilerFunction<Tree, Result>
/**
* A class to compile trees.
*
* @typeParam Tree
* The node that the compiler receives.
* @typeParam Result
* The thing that the compiler yields.
*/
export class CompilerClass<Tree extends Node = Node, Result = unknown> {
prototype: {
/**
* Compile a tree.
*
* @returns
* New content: compiled text (`string` or `Buffer`, for `file.value`) or
* something else (for `file.result`).
*/
compile(): Result
}
/**
* Constructor.
*
* @param tree
* Tree to compile.
* @param file
* File associated with `tree`.
* @returns
* Instance.
*/
constructor(tree: Tree, file: VFile)
}
/**
* Normal function to compile a tree.
*
* @typeParam Tree
* The node that the compiler receives.
* @typeParam Result
* The thing that the compiler yields.
* @param tree
* Tree to compile.
* @param file
* File associated with `tree`.
* @returns
* New content: compiled text (`string` or `Buffer`, for `file.value`) or
* something else (for `file.result`).
*/
export type CompilerFunction<Tree extends Node = Node, Result = unknown> = (
tree: Tree,
file: VFile
) => Result
/**
* Callback called when a done running.
*
* @typeParam Tree
* The tree that the callback receives.
* @param error
* Error passed when unsuccessful.
* @param node
* Tree to transform.
* @param file
* File passed when successful.
* @returns
* Nothing.
*/
export type RunCallback<Tree extends Node = Node> = (
error?: Error | null | undefined,
node?: Tree | undefined,
file?: VFile | undefined
) => void
/**
* Callback called when a done processing.
*
* @typeParam File
* The file that the callback receives.
* @param error
* Error passed when unsuccessful.
* @param file
* File passed when successful.
* @returns
* Nothing.
*/
export type ProcessCallback<File extends VFile = VFile> = (
error?: Error | null | undefined,
file?: File | undefined
) => void
/**
* A frozen processor.
*/
export function unified(): Processor
+1
View File
@@ -0,0 +1 @@
export {unified} from './lib/index.js'
+19
View File
@@ -0,0 +1,19 @@
export const unified: import('..').FrozenProcessor<void, void, void, void>
export type Node = import('unist').Node
export type VFileCompatible = import('vfile').VFileCompatible
export type VFileValue = import('vfile').VFileValue
export type Processor = import('..').Processor
export type Plugin = import('..').Plugin
export type Preset = import('..').Preset
export type Pluggable = import('..').Pluggable
export type PluggableList = import('..').PluggableList
export type Transformer = import('..').Transformer
export type Parser = import('..').Parser
export type Compiler = import('..').Compiler
export type RunCallback = import('..').RunCallback
export type ProcessCallback = import('..').ProcessCallback
export type Context = {
tree: Node
file: VFile
}
import {VFile} from 'vfile'
+599
View File
@@ -0,0 +1,599 @@
/**
* @typedef {import('unist').Node} Node
* @typedef {import('vfile').VFileCompatible} VFileCompatible
* @typedef {import('vfile').VFileValue} VFileValue
* @typedef {import('..').Processor} Processor
* @typedef {import('..').Plugin} Plugin
* @typedef {import('..').Preset} Preset
* @typedef {import('..').Pluggable} Pluggable
* @typedef {import('..').PluggableList} PluggableList
* @typedef {import('..').Transformer} Transformer
* @typedef {import('..').Parser} Parser
* @typedef {import('..').Compiler} Compiler
* @typedef {import('..').RunCallback} RunCallback
* @typedef {import('..').ProcessCallback} ProcessCallback
*
* @typedef Context
* @property {Node} tree
* @property {VFile} file
*/
import {bail} from 'bail'
import isBuffer from 'is-buffer'
import extend from 'extend'
import isPlainObj from 'is-plain-obj'
import {trough} from 'trough'
import {VFile} from 'vfile'
// Expose a frozen processor.
export const unified = base().freeze()
const own = {}.hasOwnProperty
// Function to create the first processor.
/**
* @returns {Processor}
*/
function base() {
const transformers = trough()
/** @type {Processor['attachers']} */
const attachers = []
/** @type {Record<string, unknown>} */
let namespace = {}
/** @type {boolean|undefined} */
let frozen
let freezeIndex = -1
// Data management.
// @ts-expect-error: overloads are handled.
processor.data = data
processor.Parser = undefined
processor.Compiler = undefined
// Lock.
processor.freeze = freeze
// Plugins.
processor.attachers = attachers
// @ts-expect-error: overloads are handled.
processor.use = use
// API.
processor.parse = parse
processor.stringify = stringify
// @ts-expect-error: overloads are handled.
processor.run = run
processor.runSync = runSync
// @ts-expect-error: overloads are handled.
processor.process = process
processor.processSync = processSync
// Expose.
return processor
// Create a new processor based on the processor in the current scope.
/** @type {Processor} */
function processor() {
const destination = base()
let index = -1
while (++index < attachers.length) {
destination.use(...attachers[index])
}
destination.data(extend(true, {}, namespace))
return destination
}
/**
* @param {string|Record<string, unknown>} [key]
* @param {unknown} [value]
* @returns {unknown}
*/
function data(key, value) {
if (typeof key === 'string') {
// Set `key`.
if (arguments.length === 2) {
assertUnfrozen('data', frozen)
namespace[key] = value
return processor
}
// Get `key`.
return (own.call(namespace, key) && namespace[key]) || null
}
// Set space.
if (key) {
assertUnfrozen('data', frozen)
namespace = key
return processor
}
// Get space.
return namespace
}
/** @type {Processor['freeze']} */
function freeze() {
if (frozen) {
return processor
}
while (++freezeIndex < attachers.length) {
const [attacher, ...options] = attachers[freezeIndex]
if (options[0] === false) {
continue
}
if (options[0] === true) {
options[0] = undefined
}
/** @type {Transformer|void} */
const transformer = attacher.call(processor, ...options)
if (typeof transformer === 'function') {
transformers.use(transformer)
}
}
frozen = true
freezeIndex = Number.POSITIVE_INFINITY
return processor
}
/**
* @param {Pluggable|null|undefined} [value]
* @param {...unknown} options
* @returns {Processor}
*/
function use(value, ...options) {
/** @type {Record<string, unknown>|undefined} */
let settings
assertUnfrozen('use', frozen)
if (value === null || value === undefined) {
// Empty.
} else if (typeof value === 'function') {
addPlugin(value, ...options)
} else if (typeof value === 'object') {
if (Array.isArray(value)) {
addList(value)
} else {
addPreset(value)
}
} else {
throw new TypeError('Expected usable value, not `' + value + '`')
}
if (settings) {
namespace.settings = Object.assign(namespace.settings || {}, settings)
}
return processor
/**
* @param {import('..').Pluggable<unknown[]>} value
* @returns {void}
*/
function add(value) {
if (typeof value === 'function') {
addPlugin(value)
} else if (typeof value === 'object') {
if (Array.isArray(value)) {
const [plugin, ...options] = value
addPlugin(plugin, ...options)
} else {
addPreset(value)
}
} else {
throw new TypeError('Expected usable value, not `' + value + '`')
}
}
/**
* @param {Preset} result
* @returns {void}
*/
function addPreset(result) {
addList(result.plugins)
if (result.settings) {
settings = Object.assign(settings || {}, result.settings)
}
}
/**
* @param {PluggableList|null|undefined} [plugins]
* @returns {void}
*/
function addList(plugins) {
let index = -1
if (plugins === null || plugins === undefined) {
// Empty.
} else if (Array.isArray(plugins)) {
while (++index < plugins.length) {
const thing = plugins[index]
add(thing)
}
} else {
throw new TypeError('Expected a list of plugins, not `' + plugins + '`')
}
}
/**
* @param {Plugin} plugin
* @param {...unknown} [value]
* @returns {void}
*/
function addPlugin(plugin, value) {
let index = -1
/** @type {Processor['attachers'][number]|undefined} */
let entry
while (++index < attachers.length) {
if (attachers[index][0] === plugin) {
entry = attachers[index]
break
}
}
if (entry) {
if (isPlainObj(entry[1]) && isPlainObj(value)) {
value = extend(true, entry[1], value)
}
entry[1] = value
} else {
// @ts-expect-error: fine.
attachers.push([...arguments])
}
}
}
/** @type {Processor['parse']} */
function parse(doc) {
processor.freeze()
const file = vfile(doc)
const Parser = processor.Parser
assertParser('parse', Parser)
if (newable(Parser, 'parse')) {
// @ts-expect-error: `newable` checks this.
return new Parser(String(file), file).parse()
}
// @ts-expect-error: `newable` checks this.
return Parser(String(file), file) // eslint-disable-line new-cap
}
/** @type {Processor['stringify']} */
function stringify(node, doc) {
processor.freeze()
const file = vfile(doc)
const Compiler = processor.Compiler
assertCompiler('stringify', Compiler)
assertNode(node)
if (newable(Compiler, 'compile')) {
// @ts-expect-error: `newable` checks this.
return new Compiler(node, file).compile()
}
// @ts-expect-error: `newable` checks this.
return Compiler(node, file) // eslint-disable-line new-cap
}
/**
* @param {Node} node
* @param {VFileCompatible|RunCallback} [doc]
* @param {RunCallback} [callback]
* @returns {Promise<Node>|void}
*/
function run(node, doc, callback) {
assertNode(node)
processor.freeze()
if (!callback && typeof doc === 'function') {
callback = doc
doc = undefined
}
if (!callback) {
return new Promise(executor)
}
executor(null, callback)
/**
* @param {null|((node: Node) => void)} resolve
* @param {(error: Error) => void} reject
* @returns {void}
*/
function executor(resolve, reject) {
// @ts-expect-error: `doc` cant be a callback anymore, we checked.
transformers.run(node, vfile(doc), done)
/**
* @param {Error|null} error
* @param {Node} tree
* @param {VFile} file
* @returns {void}
*/
function done(error, tree, file) {
tree = tree || node
if (error) {
reject(error)
} else if (resolve) {
resolve(tree)
} else {
// @ts-expect-error: `callback` is defined if `resolve` is not.
callback(null, tree, file)
}
}
}
}
/** @type {Processor['runSync']} */
function runSync(node, file) {
/** @type {Node|undefined} */
let result
/** @type {boolean|undefined} */
let complete
processor.run(node, file, done)
assertDone('runSync', 'run', complete)
// @ts-expect-error: we either bailed on an error or have a tree.
return result
/**
* @param {Error|null} [error]
* @param {Node} [tree]
* @returns {void}
*/
function done(error, tree) {
bail(error)
result = tree
complete = true
}
}
/**
* @param {VFileCompatible} doc
* @param {ProcessCallback} [callback]
* @returns {Promise<VFile>|undefined}
*/
function process(doc, callback) {
processor.freeze()
assertParser('process', processor.Parser)
assertCompiler('process', processor.Compiler)
if (!callback) {
return new Promise(executor)
}
executor(null, callback)
/**
* @param {null|((file: VFile) => void)} resolve
* @param {(error?: Error|null|undefined) => void} reject
* @returns {void}
*/
function executor(resolve, reject) {
const file = vfile(doc)
processor.run(processor.parse(file), file, (error, tree, file) => {
if (error || !tree || !file) {
done(error)
} else {
/** @type {unknown} */
const result = processor.stringify(tree, file)
if (result === undefined || result === null) {
// Empty.
} else if (looksLikeAVFileValue(result)) {
file.value = result
} else {
file.result = result
}
done(error, file)
}
})
/**
* @param {Error|null|undefined} [error]
* @param {VFile|undefined} [file]
* @returns {void}
*/
function done(error, file) {
if (error || !file) {
reject(error)
} else if (resolve) {
resolve(file)
} else {
// @ts-expect-error: `callback` is defined if `resolve` is not.
callback(null, file)
}
}
}
}
/** @type {Processor['processSync']} */
function processSync(doc) {
/** @type {boolean|undefined} */
let complete
processor.freeze()
assertParser('processSync', processor.Parser)
assertCompiler('processSync', processor.Compiler)
const file = vfile(doc)
processor.process(file, done)
assertDone('processSync', 'process', complete)
return file
/**
* @param {Error|null|undefined} [error]
* @returns {void}
*/
function done(error) {
complete = true
bail(error)
}
}
}
/**
* Check if `value` is a constructor.
*
* @param {unknown} value
* @param {string} name
* @returns {boolean}
*/
function newable(value, name) {
return (
typeof value === 'function' &&
// Prototypes do exist.
// type-coverage:ignore-next-line
value.prototype &&
// A function with keys in its prototype is probably a constructor.
// Classes prototype methods are not enumerable, so we check if some value
// exists in the prototype.
// type-coverage:ignore-next-line
(keys(value.prototype) || name in value.prototype)
)
}
/**
* Check if `value` is an object with keys.
*
* @param {Record<string, unknown>} value
* @returns {boolean}
*/
function keys(value) {
/** @type {string} */
let key
for (key in value) {
if (own.call(value, key)) {
return true
}
}
return false
}
/**
* Assert a parser is available.
*
* @param {string} name
* @param {unknown} value
* @returns {asserts value is Parser}
*/
function assertParser(name, value) {
if (typeof value !== 'function') {
throw new TypeError('Cannot `' + name + '` without `Parser`')
}
}
/**
* Assert a compiler is available.
*
* @param {string} name
* @param {unknown} value
* @returns {asserts value is Compiler}
*/
function assertCompiler(name, value) {
if (typeof value !== 'function') {
throw new TypeError('Cannot `' + name + '` without `Compiler`')
}
}
/**
* Assert the processor is not frozen.
*
* @param {string} name
* @param {unknown} frozen
* @returns {asserts frozen is false}
*/
function assertUnfrozen(name, frozen) {
if (frozen) {
throw new Error(
'Cannot call `' +
name +
'` on a frozen processor.\nCreate a new processor first, by calling it: use `processor()` instead of `processor`.'
)
}
}
/**
* Assert `node` is a unist node.
*
* @param {unknown} node
* @returns {asserts node is Node}
*/
function assertNode(node) {
// `isPlainObj` unfortunately uses `any` instead of `unknown`.
// type-coverage:ignore-next-line
if (!isPlainObj(node) || typeof node.type !== 'string') {
throw new TypeError('Expected node, got `' + node + '`')
// Fine.
}
}
/**
* Assert that `complete` is `true`.
*
* @param {string} name
* @param {string} asyncName
* @param {unknown} complete
* @returns {asserts complete is true}
*/
function assertDone(name, asyncName, complete) {
if (!complete) {
throw new Error(
'`' + name + '` finished async. Use `' + asyncName + '` instead'
)
}
}
/**
* @param {VFileCompatible} [value]
* @returns {VFile}
*/
function vfile(value) {
return looksLikeAVFile(value) ? value : new VFile(value)
}
/**
* @param {VFileCompatible} [value]
* @returns {value is VFile}
*/
function looksLikeAVFile(value) {
return Boolean(
value &&
typeof value === 'object' &&
'message' in value &&
'messages' in value
)
}
/**
* @param {unknown} [value]
* @returns {value is VFileValue}
*/
function looksLikeAVFileValue(value) {
return typeof value === 'string' || isBuffer(value)
}
+21
View File
@@ -0,0 +1,21 @@
(The MIT License)
Copyright (c) 2015 Titus Wormer <tituswormer@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
+107
View File
@@ -0,0 +1,107 @@
{
"name": "unified",
"version": "10.1.2",
"description": "Interface for parsing, inspecting, transforming, and serializing content through syntax trees",
"license": "MIT",
"keywords": [
"unified",
"process",
"parse",
"transform",
"compile",
"stringify",
"serialize",
"ast",
"cst",
"syntax",
"tree",
"content",
"rehype",
"retext",
"remark"
],
"homepage": "https://unifiedjs.com",
"repository": "unifiedjs/unified",
"bugs": "https://github.com/unifiedjs/unified/issues",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
},
"author": "Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)",
"contributors": [
"Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)",
"Junyoung Choi <fluke8259@gmail.com>",
"Hernan Rajchert <hrajchert@gmail.com>",
"Christian Murphy <christian.murphy.42@gmail.com>",
"Vse Mozhet Byt <vsemozhetbyt@gmail.com>",
"Richard Littauer <richard.littauer@gmail.com>"
],
"sideEffects": false,
"type": "module",
"main": "index.js",
"types": "index.d.ts",
"files": [
"lib/",
"index.d.ts",
"index.js"
],
"dependencies": {
"@types/unist": "^2.0.0",
"bail": "^2.0.0",
"extend": "^3.0.0",
"is-buffer": "^2.0.0",
"is-plain-obj": "^4.0.0",
"trough": "^2.0.0",
"vfile": "^5.0.0"
},
"devDependencies": {
"@types/extend": "^3.0.0",
"@types/tape": "^4.0.0",
"c8": "^7.0.0",
"prettier": "^2.0.0",
"remark-cli": "^10.0.0",
"remark-preset-wooorm": "^9.0.0",
"rimraf": "^3.0.0",
"tape": "^5.0.0",
"tsd": "^0.19.0",
"type-coverage": "^2.0.0",
"typescript": "^4.0.0",
"xo": "^0.48.0"
},
"scripts": {
"build": "rimraf \"test/**/*.d.ts\" && tsc && tsd && type-coverage",
"format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix",
"test-api": "node --unhandled-rejections=strict --conditions development test/index.js",
"test-coverage": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 --reporter lcov node --unhandled-rejections=strict --conditions development test/index.js",
"test": "npm run build && npm run format && npm run test-coverage"
},
"prettier": {
"tabWidth": 2,
"useTabs": false,
"singleQuote": true,
"bracketSpacing": false,
"semi": false,
"trailingComma": "none"
},
"xo": {
"prettier": true,
"rules": {
"@typescript-eslint/ban-types": "off",
"promise/param-names": "off"
},
"ignores": [
"types/"
]
},
"remarkConfig": {
"plugins": [
"preset-wooorm"
]
},
"typeCoverage": {
"atLeast": 100,
"detail": true,
"strict": true,
"ignoreCatch": true
}
}
+1450
View File
File diff suppressed because it is too large Load Diff
+52
View File
@@ -0,0 +1,52 @@
# Unipointer
Base class for doing one thing with pointer event
Used with [Unidragger](https://github.com/metafizzy/unidragger) and [TapListener](https://github.com/metafizzy/tap-listener)
## Install
Bower: `bower install unipointer`
npm: `npm install unipointer`
## Usage
``` js
// create new class
function PointerFun( elem ) {
this.element = elem;
// binds mousedown/touchstart/pointerdown event
this._bindStartEvent( this.element, true );
}
// inherit Unipointer
PointerFun.prototype = new Unipointer();
// overwrite public pointer methods
PointerFun.prototype.pointerDown = function( event, pointer ) {
console.log('pointer down');
};
PointerFun.prototype.pointerMove = function( event, pointer ) {
console.log('pointer move');
};
PointerFun.prototype.pointerUp = function( event, pointer ) {
console.log('pointer up');
};
PointerFun.prototype.pointerCancel = function( event, pointer ) {
console.log('pointer cancel');
};
// triggered on pointerUp and pointerCancel
PointerFun.prototype.pointerDone = function( event, pointer ) {
console.log('pointer done');
};
```
---
MIT license
By [Metafizzy](https://metafizzy.co)
+31
View File
@@ -0,0 +1,31 @@
{
"name": "unipointer",
"main": "unipointer.js",
"dependencies": {
"ev-emitter": "^1.0.1"
},
"homepage": "https://github.com/metafizzy/unipointer",
"authors": [
"David DeSandro <desandrocodes@gmail.com>"
],
"description": "Do one thing with one pointer",
"moduleType": [
"amd",
"globals",
"node"
],
"keywords": [
"pointer",
"touch",
"mouse"
],
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests",
"package.json"
]
}
+29
View File
@@ -0,0 +1,29 @@
{
"name": "unipointer",
"version": "2.4.0",
"description": "Do one thing with one pointer",
"main": "unipointer.js",
"dependencies": {
"ev-emitter": "^1.0.1"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git://github.com/metafizzy/unipointer.git"
},
"keywords": [
"pointer",
"touch",
"mouse",
"browser",
"DOM"
],
"author": "David DeSandro",
"license": "MIT",
"bugs": {
"url": "https://github.com/metafizzy/unipointer/issues"
},
"homepage": "https://github.com/metafizzy/unipointer"
}
+302
View File
@@ -0,0 +1,302 @@
/*!
* Unipointer v2.4.0
* base class for doing one thing with pointer event
* MIT license
*/
/*jshint browser: true, undef: true, unused: true, strict: true */
( function( window, factory ) {
// universal module definition
/* jshint strict: false */ /*global define, module, require */
if ( typeof define == 'function' && define.amd ) {
// AMD
define( [
'ev-emitter/ev-emitter'
], function( EvEmitter ) {
return factory( window, EvEmitter );
});
} else if ( typeof module == 'object' && module.exports ) {
// CommonJS
module.exports = factory(
window,
require('ev-emitter')
);
} else {
// browser global
window.Unipointer = factory(
window,
window.EvEmitter
);
}
}( window, function factory( window, EvEmitter ) {
'use strict';
function noop() {}
function Unipointer() {}
// inherit EvEmitter
var proto = Unipointer.prototype = Object.create( EvEmitter.prototype );
proto.bindStartEvent = function( elem ) {
this._bindStartEvent( elem, true );
};
proto.unbindStartEvent = function( elem ) {
this._bindStartEvent( elem, false );
};
/**
* Add or remove start event
* @param {Boolean} isAdd - remove if falsey
*/
proto._bindStartEvent = function( elem, isAdd ) {
// munge isAdd, default to true
isAdd = isAdd === undefined ? true : isAdd;
var bindMethod = isAdd ? 'addEventListener' : 'removeEventListener';
// default to mouse events
var startEvent = 'mousedown';
if ( 'ontouchstart' in window ) {
// HACK prefer Touch Events as you can preventDefault on touchstart to
// disable scroll in iOS & mobile Chrome metafizzy/flickity#1177
startEvent = 'touchstart';
} else if ( window.PointerEvent ) {
// Pointer Events
startEvent = 'pointerdown';
}
elem[ bindMethod ]( startEvent, this );
};
// trigger handler methods for events
proto.handleEvent = function( event ) {
var method = 'on' + event.type;
if ( this[ method ] ) {
this[ method ]( event );
}
};
// returns the touch that we're keeping track of
proto.getTouch = function( touches ) {
for ( var i=0; i < touches.length; i++ ) {
var touch = touches[i];
if ( touch.identifier == this.pointerIdentifier ) {
return touch;
}
}
};
// ----- start event ----- //
proto.onmousedown = function( event ) {
// dismiss clicks from right or middle buttons
var button = event.button;
if ( button && ( button !== 0 && button !== 1 ) ) {
return;
}
this._pointerDown( event, event );
};
proto.ontouchstart = function( event ) {
this._pointerDown( event, event.changedTouches[0] );
};
proto.onpointerdown = function( event ) {
this._pointerDown( event, event );
};
/**
* pointer start
* @param {Event} event
* @param {Event or Touch} pointer
*/
proto._pointerDown = function( event, pointer ) {
// dismiss right click and other pointers
// button = 0 is okay, 1-4 not
if ( event.button || this.isPointerDown ) {
return;
}
this.isPointerDown = true;
// save pointer identifier to match up touch events
this.pointerIdentifier = pointer.pointerId !== undefined ?
// pointerId for pointer events, touch.indentifier for touch events
pointer.pointerId : pointer.identifier;
this.pointerDown( event, pointer );
};
proto.pointerDown = function( event, pointer ) {
this._bindPostStartEvents( event );
this.emitEvent( 'pointerDown', [ event, pointer ] );
};
// hash of events to be bound after start event
var postStartEvents = {
mousedown: [ 'mousemove', 'mouseup' ],
touchstart: [ 'touchmove', 'touchend', 'touchcancel' ],
pointerdown: [ 'pointermove', 'pointerup', 'pointercancel' ],
};
proto._bindPostStartEvents = function( event ) {
if ( !event ) {
return;
}
// get proper events to match start event
var events = postStartEvents[ event.type ];
// bind events to node
events.forEach( function( eventName ) {
window.addEventListener( eventName, this );
}, this );
// save these arguments
this._boundPointerEvents = events;
};
proto._unbindPostStartEvents = function() {
// check for _boundEvents, in case dragEnd triggered twice (old IE8 bug)
if ( !this._boundPointerEvents ) {
return;
}
this._boundPointerEvents.forEach( function( eventName ) {
window.removeEventListener( eventName, this );
}, this );
delete this._boundPointerEvents;
};
// ----- move event ----- //
proto.onmousemove = function( event ) {
this._pointerMove( event, event );
};
proto.onpointermove = function( event ) {
if ( event.pointerId == this.pointerIdentifier ) {
this._pointerMove( event, event );
}
};
proto.ontouchmove = function( event ) {
var touch = this.getTouch( event.changedTouches );
if ( touch ) {
this._pointerMove( event, touch );
}
};
/**
* pointer move
* @param {Event} event
* @param {Event or Touch} pointer
* @private
*/
proto._pointerMove = function( event, pointer ) {
this.pointerMove( event, pointer );
};
// public
proto.pointerMove = function( event, pointer ) {
this.emitEvent( 'pointerMove', [ event, pointer ] );
};
// ----- end event ----- //
proto.onmouseup = function( event ) {
this._pointerUp( event, event );
};
proto.onpointerup = function( event ) {
if ( event.pointerId == this.pointerIdentifier ) {
this._pointerUp( event, event );
}
};
proto.ontouchend = function( event ) {
var touch = this.getTouch( event.changedTouches );
if ( touch ) {
this._pointerUp( event, touch );
}
};
/**
* pointer up
* @param {Event} event
* @param {Event or Touch} pointer
* @private
*/
proto._pointerUp = function( event, pointer ) {
this._pointerDone();
this.pointerUp( event, pointer );
};
// public
proto.pointerUp = function( event, pointer ) {
this.emitEvent( 'pointerUp', [ event, pointer ] );
};
// ----- pointer done ----- //
// triggered on pointer up & pointer cancel
proto._pointerDone = function() {
this._pointerReset();
this._unbindPostStartEvents();
this.pointerDone();
};
proto._pointerReset = function() {
// reset properties
this.isPointerDown = false;
delete this.pointerIdentifier;
};
proto.pointerDone = noop;
// ----- pointer cancel ----- //
proto.onpointercancel = function( event ) {
if ( event.pointerId == this.pointerIdentifier ) {
this._pointerCancel( event, event );
}
};
proto.ontouchcancel = function( event ) {
var touch = this.getTouch( event.changedTouches );
if ( touch ) {
this._pointerCancel( event, touch );
}
};
/**
* pointer cancel
* @param {Event} event
* @param {Event or Touch} pointer
* @private
*/
proto._pointerCancel = function( event, pointer ) {
this._pointerDone();
this.pointerCancel( event, pointer );
};
// public
proto.pointerCancel = function( event, pointer ) {
this.emitEvent( 'pointerCancel', [ event, pointer ] );
};
// ----- ----- //
// utility function for getting x/y coords from event
Unipointer.getPointerPoint = function( pointer ) {
return {
x: pointer.pageX,
y: pointer.pageY
};
};
// ----- ----- //
return Unipointer;
}));
+78
View File
@@ -0,0 +1,78 @@
/**
* @typedef {import('unist').Node} Node
* @typedef {import('unist').Parent} Parent
* @typedef {import('unist').Literal} Literal
* @typedef {Object.<string, unknown>} Props
* @typedef {Array.<Node>|string} ChildrenOrValue
*
* @typedef {(<T extends string, P extends Record<string, unknown>, C extends Node[]>(type: T, props: P, children: C) => {type: T, children: C} & P)} BuildParentWithProps
* @typedef {(<T extends string, P extends Record<string, unknown>>(type: T, props: P, value: string) => {type: T, value: string} & P)} BuildLiteralWithProps
* @typedef {(<T extends string, P extends Record<string, unknown>>(type: T, props: P) => {type: T} & P)} BuildVoidWithProps
* @typedef {(<T extends string, C extends Node[]>(type: T, children: C) => {type: T, children: C})} BuildParent
* @typedef {(<T extends string>(type: T, value: string) => {type: T, value: string})} BuildLiteral
* @typedef {(<T extends string>(type: T) => {type: T})} BuildVoid
*/
export var u: BuildVoid &
BuildVoidWithProps &
BuildLiteral &
BuildLiteralWithProps &
BuildParent &
BuildParentWithProps
export type Node = import('unist').Node
export type Parent = import('unist').Parent
export type Literal = import('unist').Literal
export type Props = {
[x: string]: unknown
}
export type ChildrenOrValue = Array<Node> | string
export type BuildParentWithProps = <
T extends string,
P extends Record<string, unknown>,
C extends import('unist').Node[]
>(
type: T,
props: P,
children: C
) => {
type: T
children: C
} & P
export type BuildLiteralWithProps = <
T extends string,
P extends Record<string, unknown>
>(
type: T,
props: P,
value: string
) => {
type: T
value: string
} & P
export type BuildVoidWithProps = <
T extends string,
P extends Record<string, unknown>
>(
type: T,
props: P
) => {
type: T
} & P
export type BuildParent = <T extends string, C extends import('unist').Node[]>(
type: T,
children: C
) => {
type: T
children: C
}
export type BuildLiteral = <T extends string>(
type: T,
value: string
) => {
type: T
value: string
}
export type BuildVoid = <T extends string>(
type: T
) => {
type: T
}
+46
View File
@@ -0,0 +1,46 @@
/**
* @typedef {import('unist').Node} Node
* @typedef {import('unist').Parent} Parent
* @typedef {import('unist').Literal} Literal
* @typedef {Object.<string, unknown>} Props
* @typedef {Array.<Node>|string} ChildrenOrValue
*
* @typedef {(<T extends string, P extends Record<string, unknown>, C extends Node[]>(type: T, props: P, children: C) => {type: T, children: C} & P)} BuildParentWithProps
* @typedef {(<T extends string, P extends Record<string, unknown>>(type: T, props: P, value: string) => {type: T, value: string} & P)} BuildLiteralWithProps
* @typedef {(<T extends string, P extends Record<string, unknown>>(type: T, props: P) => {type: T} & P)} BuildVoidWithProps
* @typedef {(<T extends string, C extends Node[]>(type: T, children: C) => {type: T, children: C})} BuildParent
* @typedef {(<T extends string>(type: T, value: string) => {type: T, value: string})} BuildLiteral
* @typedef {(<T extends string>(type: T) => {type: T})} BuildVoid
*/
export var u = /**
* @type {BuildVoid & BuildVoidWithProps & BuildLiteral & BuildLiteralWithProps & BuildParent & BuildParentWithProps}
*/ (
/**
* @param {string} type Type of node
* @param {Props|ChildrenOrValue} [props] Additional properties for node (or `children` or `value`)
* @param {ChildrenOrValue} [value] `children` or `value` of node
* @returns {Node}
*/
function (type, props, value) {
/** @type {Node} */
var node = {type: String(type)}
if (
(value === undefined || value === null) &&
(typeof props === 'string' || Array.isArray(props))
) {
value = props
} else {
Object.assign(node, props)
}
if (Array.isArray(value)) {
node.children = value
} else if (value !== undefined && value !== null) {
node.value = String(value)
}
return node
}
)
+21
View File
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2015 Eugene Sharygin
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+93
View File
@@ -0,0 +1,93 @@
{
"name": "unist-builder",
"version": "3.0.0",
"description": "unist utility to create a new trees with a nice syntax",
"license": "MIT",
"keywords": [
"unist",
"unist-util",
"util",
"utility",
"tree",
"ast",
"build",
"builder",
"create",
"dsl",
"hyperscript",
"sugar",
"syntax"
],
"repository": "syntax-tree/unist-builder",
"bugs": "https://github.com/syntax-tree/unist-builder/issues",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
},
"author": "Eugene Sharygin <eush77@gmail.com>",
"contributors": [
"Eugene Sharygin <eush77@gmail.com>",
"Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)",
"Christian Murphy <christian.murphy.42@gmail.com>"
],
"sideEffects": false,
"type": "module",
"main": "index.js",
"types": "index.d.ts",
"files": [
"index.d.ts",
"index.js"
],
"dependencies": {
"@types/unist": "^2.0.0"
},
"devDependencies": {
"@types/mdast": "^3.0.0",
"@types/tape": "^4.0.0",
"c8": "^7.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",
"tsd": "^0.14.0",
"type-coverage": "^2.0.0",
"typescript": "^4.0.0",
"xo": "^0.38.0"
},
"scripts": {
"prepack": "npm run build && npm run format",
"build": "rimraf \"*.d.ts\" && tsc && tsd && 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 build && npm run format && npm run test-coverage"
},
"prettier": {
"tabWidth": 2,
"useTabs": false,
"singleQuote": true,
"bracketSpacing": false,
"semi": false,
"trailingComma": "none"
},
"xo": {
"prettier": true,
"rules": {
"capitalized-comments": "off",
"import/no-mutable-exports": "off",
"no-var": "off",
"prefer-arrow-callback": "off"
}
},
"remarkConfig": {
"plugins": [
"preset-wooorm"
]
},
"typeCoverage": {
"atLeast": 100,
"detail": true,
"strict": true
}
}
+171
View File
@@ -0,0 +1,171 @@
# unist-builder
[![Build][build-badge]][build]
[![Coverage][coverage-badge]][coverage]
[![Downloads][downloads-badge]][downloads]
[![Size][size-badge]][size]
[![Sponsors][sponsors-badge]][collective]
[![Backers][backers-badge]][collective]
[![Chat][chat-badge]][chat]
[**unist**][unist] utility to create a new [tree][]s with [hyperscript][]-like
syntax.
## Install
This package is [ESM only](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c):
Node 12+ is needed to use it and it must be `import`ed instead of `require`d.
[npm][]:
```bash
npm install unist-builder
```
## Use
```js
import {u} from 'unist-builder'
var tree = u('root', [
u('subtree', {id: 1}),
u('subtree', {id: 2}, [
u('node', [u('leaf', 'leaf 1'), u('leaf', 'leaf 2')]),
u('leaf', {id: 3}, 'leaf 3'),
u('void', {id: 4})
])
])
console.dir(tree, {depth: null})
```
results in the following tree:
```js
{
type: 'root',
children: [
{type: 'subtree', id: 1},
{
type: 'subtree',
id: 2,
children: [
{
type: 'node',
children: [
{type: 'leaf', value: 'leaf 1'},
{type: 'leaf', value: 'leaf 2'}
]
},
{type: 'leaf', id: 3, value: 'leaf 3'},
{type: 'void', id: 4}
]
}
]
}
```
## API
This package exports the following identifiers: `u`.
There is no default export.
### `u(type[, props][, children|value])`
Creates a node from `props`, `children`, and optionally `value`.
###### Signatures
* `u(type[, props], children)` — create a [parent][]
* `u(type[, props], value)` — create a [literal][]
* `u(type[, props])` — create a void node
###### Parameters
* `type` (`string`) — node [type][]
* `props` (`Object`) — other values assigned to `node`
* `children` ([`Array.<Node>`][node]) — children of `node`
* `value` (`*`) — value of `node` (cast to string)
###### Returns
[`Node`][node].
## Related
* [`unist-builder-blueprint`](https://github.com/syntax-tree/unist-builder-blueprint)
— Convert unist trees to `unist-builder` notation
* [`hastscript`](https://github.com/syntax-tree/hastscript)
— Create [hast][] elements
* [`xastscript`](https://github.com/syntax-tree/xastscript)
— Create [xast][] elements
## Contribute
See [`contributing.md` in `syntax-tree/.github`][contributing] for ways to get
started.
See [`support.md`][support] for ways to get help.
This project has a [code of conduct][coc].
By interacting with this repository, organization, or community you agree to
abide by its terms.
## License
[MIT][license] © Eugene Sharygin
<!-- Definitions -->
[build-badge]: https://github.com/syntax-tree/unist-builder/workflows/main/badge.svg
[build]: https://github.com/syntax-tree/unist-builder/actions
[coverage-badge]: https://img.shields.io/codecov/c/github/syntax-tree/unist-builder.svg
[coverage]: https://codecov.io/github/syntax-tree/unist-builder
[downloads-badge]: https://img.shields.io/npm/dm/unist-builder.svg
[downloads]: https://www.npmjs.com/package/unist-builder
[size-badge]: https://img.shields.io/bundlephobia/minzip/unist-builder.svg
[size]: https://bundlephobia.com/result?p=unist-builder
[sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg
[backers-badge]: https://opencollective.com/unified/backers/badge.svg
[collective]: https://opencollective.com/unified
[chat-badge]: https://img.shields.io/badge/chat-discussions-success.svg
[chat]: https://github.com/syntax-tree/unist/discussions
[npm]: https://docs.npmjs.com/cli/install
[license]: license
[contributing]: https://github.com/syntax-tree/.github/blob/HEAD/contributing.md
[support]: https://github.com/syntax-tree/.github/blob/HEAD/support.md
[coc]: https://github.com/syntax-tree/.github/blob/HEAD/code-of-conduct.md
[unist]: https://github.com/syntax-tree/unist
[hast]: https://github.com/syntax-tree/hast
[xast]: https://github.com/syntax-tree/xast
[hyperscript]: https://github.com/dominictarr/hyperscript
[node]: https://github.com/syntax-tree/unist#node
[tree]: https://github.com/syntax-tree/unist#tree
[parent]: https://github.com/syntax-tree/unist#parent
[literal]: https://github.com/syntax-tree/unist#literal
[type]: https://github.com/syntax-tree/unist#type
+32
View File
@@ -0,0 +1,32 @@
/**
* @typedef {Object} PointLike
* @property {number} [line]
* @property {number} [column]
* @property {number} [offset]
*
* @typedef {Object} PositionLike
* @property {PointLike} [start]
* @property {PointLike} [end]
*
* @typedef {Object} NodeLike
* @property {PositionLike} [position]
*/
/**
* Check if `node` is *generated*.
*
* @param {NodeLike} [node]
* @returns {boolean}
*/
export function generated(node?: NodeLike): boolean
export type PointLike = {
line?: number
column?: number
offset?: number
}
export type PositionLike = {
start?: PointLike
end?: PointLike
}
export type NodeLike = {
position?: PositionLike
}
+32
View File
@@ -0,0 +1,32 @@
/**
* @typedef {Object} PointLike
* @property {number} [line]
* @property {number} [column]
* @property {number} [offset]
*
* @typedef {Object} PositionLike
* @property {PointLike} [start]
* @property {PointLike} [end]
*
* @typedef {Object} NodeLike
* @property {PositionLike} [position]
*/
/**
* Check if `node` is *generated*.
*
* @param {NodeLike} [node]
* @returns {boolean}
*/
export function generated(node) {
return (
!node ||
!node.position ||
!node.position.start ||
!node.position.start.line ||
!node.position.start.column ||
!node.position.end ||
!node.position.end.line ||
!node.position.end.column
)
}
+22
View File
@@ -0,0 +1,22 @@
(The MIT License)
Copyright (c) 2016 Titus Wormer <tituswormer@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+78
View File
@@ -0,0 +1,78 @@
{
"name": "unist-util-generated",
"version": "2.0.0",
"description": "unist utility to check if a node is generated",
"license": "MIT",
"keywords": [
"unist",
"unist-util",
"util",
"utility",
"position",
"location",
"generated"
],
"repository": "syntax-tree/unist-util-generated",
"bugs": "https://github.com/syntax-tree/unist-util-generated/issues",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
},
"author": "Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)",
"contributors": [
"Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)"
],
"sideEffects": false,
"type": "module",
"main": "index.js",
"types": "index.d.ts",
"files": [
"index.d.ts",
"index.js"
],
"devDependencies": {
"@types/tape": "^4.0.0",
"c8": "^7.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",
"xo": "^0.38.0"
},
"scripts": {
"prepack": "npm run build && npm run format",
"build": "rimraf \"*.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 build && npm run format && npm run test-coverage"
},
"prettier": {
"tabWidth": 2,
"useTabs": false,
"singleQuote": true,
"bracketSpacing": false,
"semi": false,
"trailingComma": "none"
},
"xo": {
"prettier": true,
"rules": {
"no-var": "off",
"prefer-arrow-callback": "off"
}
},
"remarkConfig": {
"plugins": [
"preset-wooorm"
]
},
"typeCoverage": {
"atLeast": 100,
"detail": true,
"strict": true
}
}
+124
View File
@@ -0,0 +1,124 @@
# unist-util-generated
[![Build][build-badge]][build]
[![Coverage][coverage-badge]][coverage]
[![Downloads][downloads-badge]][downloads]
[![Size][size-badge]][size]
[![Sponsors][sponsors-badge]][collective]
[![Backers][backers-badge]][collective]
[![Chat][chat-badge]][chat]
[**unist**][unist] utility to check if a [node][] is [*generated*][generated].
## Install
This package is [ESM only](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c):
Node 12+ is needed to use it and it must be `import`ed instead of `require`d.
[npm][]:
```sh
npm install unist-util-generated
```
## Use
```js
import {generated} from 'unist-util-generated'
generated({}) // => true
generated({position: {start: {}, end: {}}}) // => true
generated({
position: {start: {line: 1, column: 1}, end: {line: 1, column: 2}}
}) // => false
```
## API
This package exports the following identifiers: `generated`.
There is no default export.
### `generated(node)`
Check if [`node`][node] is [*generated*][generated].
###### Parameters
* `node` ([`Node`][node]) — Node to check.
###### Returns
`boolean` — Whether `node` is generated.
## Related
* [`unist-util-position`](https://github.com/syntax-tree/unist-util-position)
— Get the position of nodes
* [`unist-util-source`](https://github.com/syntax-tree/unist-util-source)
— Get the source of a node or position
* [`unist-util-remove-position`](https://github.com/syntax-tree/unist-util-remove-position)
— Remove `position`s from a tree
* [`unist-util-stringify-position`](https://github.com/syntax-tree/unist-util-stringify-position)
— Stringify a node, position, or point
## Contribute
See [`contributing.md` in `syntax-tree/.github`][contributing] for ways to get
started.
See [`support.md`][support] for ways to get help.
This project has a [code of conduct][coc].
By interacting with this repository, organization, or community you agree to
abide by its terms.
## License
[MIT][license] © [Titus Wormer][author]
<!-- Definition -->
[build-badge]: https://github.com/syntax-tree/unist-util-generated/workflows/main/badge.svg
[build]: https://github.com/syntax-tree/unist-util-generated/actions
[coverage-badge]: https://img.shields.io/codecov/c/github/syntax-tree/unist-util-generated.svg
[coverage]: https://codecov.io/github/syntax-tree/unist-util-generated
[downloads-badge]: https://img.shields.io/npm/dm/unist-util-generated.svg
[downloads]: https://www.npmjs.com/package/unist-util-generated
[size-badge]: https://img.shields.io/bundlephobia/minzip/unist-util-generated.svg
[size]: https://bundlephobia.com/result?p=unist-util-generated
[sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg
[backers-badge]: https://opencollective.com/unified/backers/badge.svg
[collective]: https://opencollective.com/unified
[chat-badge]: https://img.shields.io/badge/chat-discussions-success.svg
[chat]: https://github.com/syntax-tree/unist/discussions
[npm]: https://docs.npmjs.com/cli/install
[license]: license
[author]: https://wooorm.com
[contributing]: https://github.com/syntax-tree/.github/blob/HEAD/contributing.md
[support]: https://github.com/syntax-tree/.github/blob/HEAD/support.md
[coc]: https://github.com/syntax-tree/.github/blob/HEAD/code-of-conduct.md
[unist]: https://github.com/syntax-tree/unist
[node]: https://github.com/syntax-tree/unist#node
[generated]: https://github.com/syntax-tree/unist#generated
+113
View File
@@ -0,0 +1,113 @@
/**
* @typedef {import('unist').Node} Node
* @typedef {import('unist').Parent} Parent
*
* @typedef {string} Type
* @typedef {Object<string, unknown>} Props
*
* @typedef {null|undefined|Type|Props|TestFunctionAnything|Array.<Type|Props|TestFunctionAnything>} Test
*/
/**
* Check if a node passes a test
*
* @callback TestFunctionAnything
* @param {Node} node
* @param {number|null|undefined} [index]
* @param {Parent|null|undefined} [parent]
* @returns {boolean|void}
*/
/**
* Check if a node passes a certain node test
*
* @template {Node} X
* @callback TestFunctionPredicate
* @param {Node} node
* @param {number|null|undefined} [index]
* @param {Parent|null|undefined} [parent]
* @returns {node is X}
*/
/**
* @callback AssertAnything
* @param {unknown} [node]
* @param {number|null|undefined} [index]
* @param {Parent|null|undefined} [parent]
* @returns {boolean}
*/
/**
* Check if a node passes a certain node test
*
* @template {Node} Y
* @callback AssertPredicate
* @param {unknown} [node]
* @param {number|null|undefined} [index]
* @param {Parent|null|undefined} [parent]
* @returns {node is Y}
*/
export const is: (<T extends import('unist').Node<import('unist').Data>>(
node: unknown,
test:
| T['type']
| Partial<T>
| TestFunctionPredicate<T>
| (T['type'] | Partial<T> | TestFunctionPredicate<T>)[],
index?: number | null | undefined,
parent?: Parent | null | undefined,
context?: unknown
) => node is T) &
((
node?: unknown,
test?: Test,
index?: number | null | undefined,
parent?: Parent | null | undefined,
context?: unknown
) => boolean)
export const convert: (<T extends import('unist').Node<import('unist').Data>>(
test: T['type'] | Partial<T> | TestFunctionPredicate<T>
) => AssertPredicate<T>) &
((test?: Test) => AssertAnything)
export type Node = import('unist').Node
export type Parent = import('unist').Parent
export type Type = string
export type Props = {
[x: string]: unknown
}
export type Test =
| null
| undefined
| Type
| Props
| TestFunctionAnything
| Array<Type | Props | TestFunctionAnything>
/**
* Check if a node passes a test
*/
export type TestFunctionAnything = (
node: Node,
index?: number | null | undefined,
parent?: Parent | null | undefined
) => boolean | void
/**
* Check if a node passes a certain node test
*/
export type TestFunctionPredicate<
X extends import('unist').Node<import('unist').Data>
> = (
node: Node,
index?: number | null | undefined,
parent?: Parent | null | undefined
) => node is X
export type AssertAnything = (
node?: unknown,
index?: number | null | undefined,
parent?: Parent | null | undefined
) => boolean
/**
* Check if a node passes a certain node test
*/
export type AssertPredicate<
Y extends import('unist').Node<import('unist').Data>
> = (
node?: unknown,
index?: number | null | undefined,
parent?: Parent | null | undefined
) => node is Y
+251
View File
@@ -0,0 +1,251 @@
/**
* @typedef {import('unist').Node} Node
* @typedef {import('unist').Parent} Parent
*
* @typedef {string} Type
* @typedef {Object<string, unknown>} Props
*
* @typedef {null|undefined|Type|Props|TestFunctionAnything|Array.<Type|Props|TestFunctionAnything>} Test
*/
/**
* Check if a node passes a test
*
* @callback TestFunctionAnything
* @param {Node} node
* @param {number|null|undefined} [index]
* @param {Parent|null|undefined} [parent]
* @returns {boolean|void}
*/
/**
* Check if a node passes a certain node test
*
* @template {Node} X
* @callback TestFunctionPredicate
* @param {Node} node
* @param {number|null|undefined} [index]
* @param {Parent|null|undefined} [parent]
* @returns {node is X}
*/
/**
* @callback AssertAnything
* @param {unknown} [node]
* @param {number|null|undefined} [index]
* @param {Parent|null|undefined} [parent]
* @returns {boolean}
*/
/**
* Check if a node passes a certain node test
*
* @template {Node} Y
* @callback AssertPredicate
* @param {unknown} [node]
* @param {number|null|undefined} [index]
* @param {Parent|null|undefined} [parent]
* @returns {node is Y}
*/
export const is =
/**
* Check if a node passes a test.
* When a `parent` node is known the `index` of node should also be given.
*
* @type {(
* (<T extends Node>(node: unknown, test: T['type']|Partial<T>|TestFunctionPredicate<T>|Array.<T['type']|Partial<T>|TestFunctionPredicate<T>>, index?: number|null|undefined, parent?: Parent|null|undefined, context?: unknown) => node is T) &
* ((node?: unknown, test?: Test, index?: number|null|undefined, parent?: Parent|null|undefined, context?: unknown) => boolean)
* )}
*/
(
/**
* Check if a node passes a test.
* When a `parent` node is known the `index` of node should also be given.
*
* @param {unknown} [node] Node to check
* @param {Test} [test]
* When nullish, checks if `node` is a `Node`.
* When `string`, works like passing `function (node) {return node.type === test}`.
* When `function` checks if function passed the node is true.
* When `object`, checks that all keys in test are in node, and that they have (strictly) equal values.
* When `array`, checks any one of the subtests pass.
* @param {number|null|undefined} [index] Position of `node` in `parent`
* @param {Parent|null|undefined} [parent] Parent of `node`
* @param {unknown} [context] Context object to invoke `test` with
* @returns {boolean} Whether test passed and `node` is a `Node` (object with `type` set to non-empty `string`).
*/
// eslint-disable-next-line max-params
function is(node, test, index, parent, context) {
const check = convert(test)
if (
index !== undefined &&
index !== null &&
(typeof index !== 'number' ||
index < 0 ||
index === Number.POSITIVE_INFINITY)
) {
throw new Error('Expected positive finite index')
}
if (
parent !== undefined &&
parent !== null &&
(!is(parent) || !parent.children)
) {
throw new Error('Expected parent node')
}
if (
(parent === undefined || parent === null) !==
(index === undefined || index === null)
) {
throw new Error('Expected both parent and index')
}
// @ts-expect-error Looks like a node.
return node && node.type && typeof node.type === 'string'
? Boolean(check.call(context, node, index, parent))
: false
}
)
export const convert =
/**
* @type {(
* (<T extends Node>(test: T['type']|Partial<T>|TestFunctionPredicate<T>) => AssertPredicate<T>) &
* ((test?: Test) => AssertAnything)
* )}
*/
(
/**
* Generate an assertion from a check.
* @param {Test} [test]
* When nullish, checks if `node` is a `Node`.
* When `string`, works like passing `function (node) {return node.type === test}`.
* When `function` checks if function passed the node is true.
* When `object`, checks that all keys in test are in node, and that they have (strictly) equal values.
* When `array`, checks any one of the subtests pass.
* @returns {AssertAnything}
*/
function (test) {
if (test === undefined || test === null) {
return ok
}
if (typeof test === 'string') {
return typeFactory(test)
}
if (typeof test === 'object') {
return Array.isArray(test) ? anyFactory(test) : propsFactory(test)
}
if (typeof test === 'function') {
return castFactory(test)
}
throw new Error('Expected function, string, or object as test')
}
)
/**
* @param {Array.<Type|Props|TestFunctionAnything>} tests
* @returns {AssertAnything}
*/
function anyFactory(tests) {
/** @type {Array.<AssertAnything>} */
const checks = []
let index = -1
while (++index < tests.length) {
checks[index] = convert(tests[index])
}
return castFactory(any)
/**
* @this {unknown}
* @param {unknown[]} parameters
* @returns {boolean}
*/
function any(...parameters) {
let index = -1
while (++index < checks.length) {
if (checks[index].call(this, ...parameters)) return true
}
return false
}
}
/**
* Utility to assert each property in `test` is represented in `node`, and each
* values are strictly equal.
*
* @param {Props} check
* @returns {AssertAnything}
*/
function propsFactory(check) {
return castFactory(all)
/**
* @param {Node} node
* @returns {boolean}
*/
function all(node) {
/** @type {string} */
let key
for (key in check) {
// @ts-expect-error: hush, it sure works as an index.
if (node[key] !== check[key]) return false
}
return true
}
}
/**
* Utility to convert a string into a function which checks a given nodes type
* for said string.
*
* @param {Type} check
* @returns {AssertAnything}
*/
function typeFactory(check) {
return castFactory(type)
/**
* @param {Node} node
*/
function type(node) {
return node && node.type === check
}
}
/**
* Utility to convert a string into a function which checks a given nodes type
* for said string.
* @param {TestFunctionAnything} check
* @returns {AssertAnything}
*/
function castFactory(check) {
return assertion
/**
* @this {unknown}
* @param {Array.<unknown>} parameters
* @returns {boolean}
*/
function assertion(...parameters) {
// @ts-expect-error: spreading is fine.
return Boolean(check.call(this, ...parameters))
}
}
// Utility to return true.
function ok() {
return true
}
+22
View File
@@ -0,0 +1,22 @@
(The MIT license)
Copyright (c) 2015 Titus Wormer <tituswormer@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+86
View File
@@ -0,0 +1,86 @@
{
"name": "unist-util-is",
"version": "5.1.1",
"description": "unist utility to check if a node passes a test",
"license": "MIT",
"keywords": [
"unist",
"unist-util",
"util",
"utility",
"tree",
"node",
"is",
"equal",
"check",
"test",
"type"
],
"repository": "syntax-tree/unist-util-is",
"bugs": "https://github.com/syntax-tree/unist-util-is/issues",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
},
"author": "Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)",
"contributors": [
"Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)",
"Christian Murphy <christian.murphy.42@gmail.com>",
"Lucas Brandstaetter <lucas@brandstaetter.tech> (https://github.com/Roang-zero1)"
],
"sideEffects": false,
"type": "module",
"main": "index.js",
"types": "index.d.ts",
"files": [
"index.d.ts",
"index.js"
],
"devDependencies": {
"@types/lodash": "^4.0.0",
"@types/mdast": "^3.0.0",
"@types/tape": "^4.0.0",
"c8": "^7.0.0",
"fast-check": "^2.0.0",
"lodash": "^4.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",
"tsd": "^0.14.0",
"type-coverage": "^2.0.0",
"typescript": "^4.0.0",
"unified": "^9.0.0",
"xo": "^0.42.0"
},
"scripts": {
"prepack": "npm run build && npm run format",
"build": "rimraf \"{test/**,}*.d.ts\" && tsc && tsd && type-coverage",
"format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix",
"test-api": "node test/index.js",
"test-coverage": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 --reporter lcov node test/index.js",
"test": "npm run build && npm run format && npm run test-coverage"
},
"prettier": {
"tabWidth": 2,
"useTabs": false,
"singleQuote": true,
"bracketSpacing": false,
"semi": false,
"trailingComma": "none"
},
"xo": {
"prettier": true
},
"remarkConfig": {
"plugins": [
"preset-wooorm"
]
},
"typeCoverage": {
"atLeast": 100,
"detail": true,
"strict": true
}
}
+207
View File
@@ -0,0 +1,207 @@
# unist-util-is
[![Build][build-badge]][build]
[![Coverage][coverage-badge]][coverage]
[![Downloads][downloads-badge]][downloads]
[![Size][size-badge]][size]
[![Sponsors][sponsors-badge]][collective]
[![Backers][backers-badge]][collective]
[![Chat][chat-badge]][chat]
[**unist**][unist] utility to check if a node passes a test.
## Install
This package is [ESM only](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c):
Node 12+ is needed to use it and it must be `import`ed instead of `require`d.
[npm][]:
```sh
npm install unist-util-is
```
## Use
```js
import {is} from 'unist-util-is'
const node = {type: 'strong'}
const parent = {type: 'paragraph', children: [node]}
function test(node, n) {
return n === 5
}
is() // => false
is({children: []}) // => false
is(node) // => true
is(node, 'strong') // => true
is(node, 'emphasis') // => false
is(node, node) // => true
is(parent, {type: 'paragraph'}) // => true
is(parent, {type: 'strong'}) // => false
is(node, test) // => false
is(node, test, 4, parent) // => false
is(node, test, 5, parent) // => true
```
## API
This package exports the following identifiers: `is`, `convert`.
There is no default export.
### `is(node[, test[, index, parent[, context]]])`
###### Parameters
* `node` ([`Node`][node]) — Node to check.
* `test` ([`Function`][test], `string`, `Object`, or `Array.<Test>`, optional)
— When nullish, checks if `node` is a [`Node`][node].
When `string`, works like passing `node => node.type === test`.
When `array`, checks if any one of the subtests pass.
When `object`, checks that all keys in `test` are in `node`,
and that they have strictly equal values
* `index` (`number`, optional) — [Index][] of `node` in `parent`
* `parent` ([`Node`][node], optional) — [Parent][] of `node`
* `context` (`*`, optional) — Context object to invoke `test` with
###### Returns
`boolean` — Whether `test` passed *and* `node` is a [`Node`][node] (object with
`type` set to a non-empty `string`).
#### `function test(node[, index, parent])`
###### Parameters
* `node` ([`Node`][node]) — Node to check
* `index` (`number?`) — [Index][] of `node` in `parent`
* `parent` ([`Node?`][node]) — [Parent][] of `node`
###### Context
`*` — The to `is` given `context`.
###### Returns
`boolean?` — Whether `node` matches.
### `convert(test)`
Create a test function from `test`, that can later be called with a `node`,
`index`, and `parent`.
Useful if youre going to test many nodes, for example when creating a utility
where something else passes an is-compatible test.
The created function is slightly faster because it expects valid input only.
Therefore, passing invalid input, yields unexpected results.
For example:
```js
import u from 'unist-builder'
import {convert} from 'unist-util-is'
var test = convert('leaf')
var tree = u('tree', [
u('node', [u('leaf', '1')]),
u('leaf', '2'),
u('node', [u('leaf', '3'), u('leaf', '4')]),
u('leaf', '5')
])
var leafs = tree.children.filter((child, index) => test(child, index, tree))
console.log(leafs)
```
Yields:
```js
[{type: 'leaf', value: '2'}, {type: 'leaf', value: '5'}]
```
## Related
* [`unist-util-find-after`](https://github.com/syntax-tree/unist-util-find-after)
— Find a node after another node
* [`unist-util-find-before`](https://github.com/syntax-tree/unist-util-find-before)
— Find a node before another node
* [`unist-util-find-all-after`](https://github.com/syntax-tree/unist-util-find-all-after)
— Find all nodes after another node
* [`unist-util-find-all-before`](https://github.com/syntax-tree/unist-util-find-all-before)
— Find all nodes before another node
* [`unist-util-find-all-between`](https://github.com/mrzmmr/unist-util-find-all-between)
— Find all nodes between two nodes
* [`unist-util-filter`](https://github.com/syntax-tree/unist-util-filter)
— Create a new tree with nodes that pass a check
* [`unist-util-remove`](https://github.com/syntax-tree/unist-util-remove)
— Remove nodes from tree
## Contribute
See [`contributing.md` in `syntax-tree/.github`][contributing] for ways to get
started.
See [`support.md`][support] for ways to get help.
This project has a [code of conduct][coc].
By interacting with this repository, organization, or community you agree to
abide by its terms.
## License
[MIT][license] © [Titus Wormer][author]
<!-- Definitions -->
[build-badge]: https://github.com/syntax-tree/unist-util-is/workflows/main/badge.svg
[build]: https://github.com/syntax-tree/unist-util-is/actions
[coverage-badge]: https://img.shields.io/codecov/c/github/syntax-tree/unist-util-is.svg
[coverage]: https://codecov.io/github/syntax-tree/unist-util-is
[downloads-badge]: https://img.shields.io/npm/dm/unist-util-is.svg
[downloads]: https://www.npmjs.com/package/unist-util-is
[size-badge]: https://img.shields.io/bundlephobia/minzip/unist-util-is.svg
[size]: https://bundlephobia.com/result?p=unist-util-is
[sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg
[backers-badge]: https://opencollective.com/unified/backers/badge.svg
[collective]: https://opencollective.com/unified
[chat-badge]: https://img.shields.io/badge/chat-discussions-success.svg
[chat]: https://github.com/syntax-tree/unist/discussions
[npm]: https://docs.npmjs.com/cli/install
[license]: license
[author]: https://wooorm.com
[contributing]: https://github.com/syntax-tree/.github/blob/HEAD/contributing.md
[support]: https://github.com/syntax-tree/.github/blob/HEAD/support.md
[coc]: https://github.com/syntax-tree/.github/blob/HEAD/code-of-conduct.md
[unist]: https://github.com/syntax-tree/unist
[node]: https://github.com/syntax-tree/unist#node
[parent]: https://github.com/syntax-tree/unist#parent-1
[index]: https://github.com/syntax-tree/unist#index
[test]: #function-testnode-index-parent
+33
View File
@@ -0,0 +1,33 @@
/**
* Get the positional info of `node`.
*
* @param {NodeLike|Node} [node]
* @returns {Position}
*/
export function position(node?: NodeLike | Node): Position
/**
* Get the positional info of `node`.
*
* @param {NodeLike|Node} [node]
* @returns {Point}
*/
export function pointStart(node?: NodeLike | Node): Point
/**
* Get the positional info of `node`.
*
* @param {NodeLike|Node} [node]
* @returns {Point}
*/
export function pointEnd(node?: NodeLike | Node): Point
export type Position = import('unist').Position
export type Node = import('unist').Node
export type NodeLike = Record<string, unknown> & {
type: string
position?: PositionLike | undefined
}
export type Point = import('unist').Point
export type PointLike = Partial<Point>
export type PositionLike = {
start?: PointLike
end?: PointLike
}
+50
View File
@@ -0,0 +1,50 @@
/**
* @typedef {import('unist').Position} Position
* @typedef {import('unist').Node} Node
* @typedef {Record<string, unknown> & {type: string, position?: PositionLike|undefined}} NodeLike
* @typedef {import('unist').Point} Point
*
* @typedef {Partial<Point>} PointLike
*
* @typedef PositionLike
* @property {PointLike} [start]
* @property {PointLike} [end]
*/
export const pointStart = point('start')
export const pointEnd = point('end')
/**
* Get the positional info of `node`.
*
* @param {NodeLike|Node} [node]
* @returns {Position}
*/
export function position(node) {
return {start: pointStart(node), end: pointEnd(node)}
}
/**
* Get the positional info of `node`.
*
* @param {'start'|'end'} type
*/
function point(type) {
return point
/**
* Get the positional info of `node`.
*
* @param {NodeLike|Node} [node]
* @returns {Point}
*/
function point(node) {
const point = (node && node.position && node.position[type]) || {}
return {
line: point.line || null,
column: point.column || null,
offset: point.offset > -1 ? point.offset : null
}
}
}
+22
View File
@@ -0,0 +1,22 @@
(The MIT License)
Copyright (c) 2015 Titus Wormer <tituswormer@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+77
View File
@@ -0,0 +1,77 @@
{
"name": "unist-util-position",
"version": "4.0.3",
"description": "unist utility to get the position of a node",
"license": "MIT",
"keywords": [
"unist",
"unist-util",
"util",
"utility",
"node",
"position",
"point"
],
"repository": "syntax-tree/unist-util-position",
"bugs": "https://github.com/syntax-tree/unist-util-position/issues",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
},
"author": "Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)",
"contributors": [
"Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)"
],
"sideEffects": false,
"type": "module",
"main": "index.js",
"types": "index.d.ts",
"files": [
"index.d.ts",
"index.js"
],
"dependencies": {
"@types/unist": "^2.0.0"
},
"devDependencies": {
"@types/tape": "^4.0.0",
"c8": "^7.0.0",
"prettier": "^2.0.0",
"remark-cli": "^10.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"
},
"scripts": {
"prepack": "npm run build && npm run format",
"build": "rimraf \"*.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 build && npm run format && npm run test-coverage"
},
"prettier": {
"tabWidth": 2,
"useTabs": false,
"singleQuote": true,
"bracketSpacing": false,
"semi": false,
"trailingComma": "none"
},
"xo": {
"prettier": true
},
"remarkConfig": {
"plugins": [
"preset-wooorm"
]
},
"typeCoverage": {
"atLeast": 100,
"detail": true,
"strict": true
}
}
+130
View File
@@ -0,0 +1,130 @@
# unist-util-position
[![Build][build-badge]][build]
[![Coverage][coverage-badge]][coverage]
[![Downloads][downloads-badge]][downloads]
[![Size][size-badge]][size]
[![Sponsors][sponsors-badge]][collective]
[![Backers][backers-badge]][collective]
[![Chat][chat-badge]][chat]
[**unist**][unist] utility to get the positional info of nodes.
## Install
This package is [ESM only](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c):
Node 12+ is needed to use it and it must be `import`ed instead of `require`d.
[npm][]:
```sh
npm install unist-util-position
```
## Use
```js
import {remark} from 'remark'
import {position, pointStart, pointEnd} from 'unist-util-position'
const tree = remark().parse('# foo\n\n* bar\n')
console.log(position(tree))
console.log(pointStart(tree))
console.log(pointEnd(tree))
console.log(position())
console.log(pointStart())
console.log(pointEnd())
```
Yields:
```js
{start: {line: 1, column: 1, offset: 0}, end: {line: 4, column: 1, offset: 13}}
{line: 1, column: 1, offset: 0}
{line: 4, column: 1, offset: 13}
{start: {line: null, column: null, offset: null}, end: {line: null, column: null, offset: null}}
{line: null, column: null, offset: null}
{line: null, column: null, offset: null}
```
## API
This package exports the following identifiers: `position`, `pointStart`, and
`pointEnd`.
There is no default export.
### `position(node?)`
Get the positional info of `node` ([`Node?`][node]).
Returns [`Position`][position].
### `pointStart(node?)`
### `pointEnd(node?)`
Get the start or end points in the positional info of `node` ([`Node?`][node]).
Returns [`Point`][point].
## Contribute
See [`contributing.md` in `syntax-tree/.github`][contributing] for ways to get
started.
See [`support.md`][support] for ways to get help.
This project has a [code of conduct][coc].
By interacting with this repository, organization, or community you agree to
abide by its terms.
## License
[MIT][license] © [Titus Wormer][author]
<!-- Definitions -->
[build-badge]: https://github.com/syntax-tree/unist-util-position/workflows/main/badge.svg
[build]: https://github.com/syntax-tree/unist-util-position/actions
[coverage-badge]: https://img.shields.io/codecov/c/github/syntax-tree/unist-util-position.svg
[coverage]: https://codecov.io/github/syntax-tree/unist-util-position
[downloads-badge]: https://img.shields.io/npm/dm/unist-util-position.svg
[downloads]: https://www.npmjs.com/package/unist-util-position
[size-badge]: https://img.shields.io/bundlephobia/minzip/unist-util-position.svg
[size]: https://bundlephobia.com/result?p=unist-util-position
[sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg
[backers-badge]: https://opencollective.com/unified/backers/badge.svg
[collective]: https://opencollective.com/unified
[chat-badge]: https://img.shields.io/badge/chat-discussions-success.svg
[chat]: https://github.com/syntax-tree/unist/discussions
[license]: license
[author]: https://wooorm.com
[npm]: https://docs.npmjs.com/cli/install
[contributing]: https://github.com/syntax-tree/.github/blob/HEAD/contributing.md
[support]: https://github.com/syntax-tree/.github/blob/HEAD/support.md
[coc]: https://github.com/syntax-tree/.github/blob/HEAD/code-of-conduct.md
[unist]: https://github.com/syntax-tree/unist
[node]: https://github.com/syntax-tree/unist#node
[position]: https://github.com/syntax-tree/unist#position
[point]: https://github.com/syntax-tree/unist#point
+35
View File
@@ -0,0 +1,35 @@
/**
* @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 nodes
* positional information.
*
* @param {Node|NodeLike|Position|Point|null} [value]
* @returns {string}
*/
export function stringifyPosition(
value?:
| import('unist').Point
| import('unist').Node<import('unist').Data>
| import('unist').Position
| NodeLike
| null
| undefined
): string
export type Point = import('unist').Point
export type Node = import('unist').Node
export type Position = import('unist').Position
export type NodeLike = object & {
type: string
position?: Position | undefined
}
/**
* @param {Position|undefined} pos
* @returns {string}
*/
declare function position(pos: Position | undefined): string
export {}
+62
View File
@@ -0,0 +1,62 @@
/**
* @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 nodes
* 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
}
+22
View File
@@ -0,0 +1,22 @@
(The MIT License)
Copyright (c) 2016 Titus Wormer <tituswormer@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+81
View File
@@ -0,0 +1,81 @@
{
"name": "unist-util-stringify-position",
"version": "3.0.2",
"description": "unist utility to serialize a node, position, or point as a human readable location",
"license": "MIT",
"keywords": [
"unist",
"unist-util",
"util",
"utility",
"position",
"location",
"point",
"node",
"stringify",
"tostring"
],
"repository": "syntax-tree/unist-util-stringify-position",
"bugs": "https://github.com/syntax-tree/unist-util-stringify-position/issues",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
},
"author": "Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)",
"contributors": [
"Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)"
],
"sideEffects": false,
"type": "module",
"main": "index.js",
"types": "index.d.ts",
"files": [
"index.d.ts",
"index.js"
],
"dependencies": {
"@types/unist": "^2.0.0"
},
"devDependencies": {
"@types/mdast": "^3.0.0",
"@types/tape": "^4.0.0",
"c8": "^7.0.0",
"prettier": "^2.0.0",
"remark-cli": "^10.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"
},
"scripts": {
"prepack": "npm run build && npm run format",
"build": "rimraf \"*.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 build && npm run format && npm run test-coverage"
},
"prettier": {
"tabWidth": 2,
"useTabs": false,
"singleQuote": true,
"bracketSpacing": false,
"semi": false,
"trailingComma": "none"
},
"xo": {
"prettier": true
},
"remarkConfig": {
"plugins": [
"preset-wooorm"
]
},
"typeCoverage": {
"atLeast": 100,
"detail": true,
"strict": true
}
}
+198
View File
@@ -0,0 +1,198 @@
# unist-util-stringify-position
[![Build][build-badge]][build]
[![Coverage][coverage-badge]][coverage]
[![Downloads][downloads-badge]][downloads]
[![Size][size-badge]][size]
[![Sponsors][sponsors-badge]][collective]
[![Backers][backers-badge]][collective]
[![Chat][chat-badge]][chat]
**[unist][]** utility to pretty print the positional information of a node.
## Contents
* [What is this?](#what-is-this)
* [When should I use this?](#when-should-i-use-this)
* [Install](#install)
* [Use](#use)
* [API](#api)
* [`stringifyPosition(node|position|point)`](#stringifypositionnodepositionpoint)
* [Types](#types)
* [Compatibility](#compatibility)
* [Security](#security)
* [Related](#related)
* [Contribute](#contribute)
* [License](#license)
## What is this?
This package is a utility that takes any [unist][] (whether mdast, hast, etc)
node, position, or point, and serializes its positional info.
## When should I use this?
This utility is useful to display where something occurred in the original
document, in one standard way, for humans.
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][]:
```sh
npm install unist-util-stringify-position
```
In Deno with [`esm.sh`][esmsh]:
```js
import {stringifyPosition} from 'https://esm.sh/unist-util-stringify-position@3'
```
In browsers with [`esm.sh`][esmsh]:
```html
<script type="module">
import {stringifyPosition} from 'https://esm.sh/unist-util-stringify-position@3?bundle'
</script>
```
## Use
```js
import {stringifyPosition} from 'unist-util-stringify-position'
stringifyPosition({line: 2, column: 3}) // => '2:3' (point)
stringifyPosition({start: {line: 2}, end: {line: 3}}) // => '2:1-3:1' (position)
stringifyPosition({
type: 'text',
value: '!',
position: {
start: {line: 5, column: 11},
end: {line: 5, column: 12}
}
}) // => '5:11-5:12' (node)
```
## API
This package exports the identifier `stringifyPosition`.
There is no default export.
### `stringifyPosition(node|position|point)`
Stringify a [point][], [position][], or a [node][].
###### Parameters
* `node` ([`Node`][node])
— node whose `'position'` property to stringify
* `position` ([`Position`][position])
— position whose `'start'` and `'end'` points to stringify
* `point` ([`Point`][point])
— point whose `'line'` and `'column'` to stringify
###### 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.
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.
## 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+.
Our projects sometimes work with older versions, but this is not guaranteed.
## Security
This project is safe.
## Related
* [`unist-util-generated`](https://github.com/syntax-tree/unist-util-generated)
— check if a node is generated
* [`unist-util-position`](https://github.com/syntax-tree/unist-util-position)
— get positional info of nodes
* [`unist-util-remove-position`](https://github.com/syntax-tree/unist-util-remove-position)
— remove positional info from trees
* [`unist-util-source`](https://github.com/syntax-tree/unist-util-source)
— get the source of a value (node or position) in a file
## Contribute
See [`contributing.md` in `syntax-tree/.github`][contributing] for ways to get
started.
See [`support.md`][support] for ways to get help.
This project has a [code of conduct][coc].
By interacting with this repository, organization, or community you agree to
abide by its terms.
## License
[MIT][license] © [Titus Wormer][author]
<!-- Definition -->
[build-badge]: https://github.com/syntax-tree/unist-util-stringify-position/workflows/main/badge.svg
[build]: https://github.com/syntax-tree/unist-util-stringify-position/actions
[coverage-badge]: https://img.shields.io/codecov/c/github/syntax-tree/unist-util-stringify-position.svg
[coverage]: https://codecov.io/github/syntax-tree/unist-util-stringify-position
[downloads-badge]: https://img.shields.io/npm/dm/unist-util-stringify-position.svg
[downloads]: https://www.npmjs.com/package/unist-util-stringify-position
[size-badge]: https://img.shields.io/bundlephobia/minzip/unist-util-stringify-position.svg
[size]: https://bundlephobia.com/result?p=unist-util-stringify-position
[sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg
[backers-badge]: https://opencollective.com/unified/backers/badge.svg
[collective]: https://opencollective.com/unified
[chat-badge]: https://img.shields.io/badge/chat-discussions-success.svg
[chat]: https://github.com/syntax-tree/unist/discussions
[npm]: https://docs.npmjs.com/cli/install
[license]: license
[author]: https://wooorm.com
[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
[esmsh]: https://esm.sh
[typescript]: https://www.typescriptlang.org
[contributing]: https://github.com/syntax-tree/.github/blob/HEAD/contributing.md
[support]: https://github.com/syntax-tree/.github/blob/HEAD/support.md
[coc]: https://github.com/syntax-tree/.github/blob/HEAD/code-of-conduct.md
[unist]: https://github.com/syntax-tree/unist
[node]: https://github.com/syntax-tree/unist#node
[position]: https://github.com/syntax-tree/unist#position
[point]: https://github.com/syntax-tree/unist#point
+5
View File
@@ -0,0 +1,5 @@
/**
* @param {string} d
* @returns {string}
*/
export function color(d: string): string
+7
View File
@@ -0,0 +1,7 @@
/**
* @param {string} d
* @returns {string}
*/
export function color(d) {
return d
}
+5
View File
@@ -0,0 +1,5 @@
/**
* @param {string} d
* @returns {string}
*/
export function color(d: string): string
+7
View File
@@ -0,0 +1,7 @@
/**
* @param {string} d
* @returns {string}
*/
export function color(d) {
return '\u001B[33m' + d + '\u001B[39m'
}
+112
View File
@@ -0,0 +1,112 @@
/* eslint-disable @typescript-eslint/ban-types */
import type {Node, Parent} from 'unist'
import type {Test} from 'unist-util-is'
/**
* Union of the action types
*/
export type Action = boolean | 'skip'
/**
* Move to the sibling at index next (after node itself is completely
* traversed).
* Useful if mutating the tree, such as removing the node the visitor is
* currently on, or any of its previous siblings (or next siblings, in case of
* reverse) Results less than 0 or greater than or equal to `children.length`
* stop traversing the parent.
*/
export type Index = number
/**
* List with one or two values, the first an action, the second an index.
*/
export type ActionTuple = [
(Action | null | undefined | void)?,
(Index | null | undefined)?
]
/**
* Any value that can be returned from a visitor
*/
export type VisitorResult =
| null
| undefined
| Action
| Index
| ActionTuple
| void
/**
* Internal utility to collect all descendants of in `Tree`.
*/
export type InclusiveDescendant<
Tree extends Node = never,
Found = void
> = Tree extends Parent
?
| Tree
| InclusiveDescendant<
Exclude<Tree['children'][number], Found | Tree>,
Found | Tree
>
: Tree
type Predicate<Fn, Fallback = never> = Fn extends (
value: any
) => value is infer Thing
? Thing
: Fallback
type MatchesOne<Value, Check> =
// Is this a node?
Value extends Node
? // No test.
Check extends null
? Value
: // No test.
Check extends undefined
? Value
: // Function test.
Check extends Function
? Extract<Value, Predicate<Check, Value>>
: // String (type) test.
Value['type'] extends Check
? Value
: // Partial test.
Value extends Check
? Value
: never
: never
export type Matches<Value, Check> =
// Is this a list?
Check extends Array<any>
? MatchesOne<Value, Check[keyof Check]>
: MatchesOne<Value, Check>
/**
* Called when a node (matching test, if given) is found.
* Visitors are free to transform node.
* They can also transform the parent of node (the last of ancestors).
* Replacing node itself, if `SKIP` is not returned, still causes its descendants to be visited.
* If adding or removing previous siblings (or next siblings, in case of reverse) of node,
* visitor should return a new index (number) to specify the sibling to traverse after node is traversed.
* Adding or removing next siblings of node (or previous siblings, in case of reverse)
* is handled as expected without needing to return a new index.
* Removing the children property of an ancestor still results in them being traversed.
*/
export type Visitor<
Visited extends Node = Node,
Ancestor extends Parent = Parent
> = (node: Visited, ancestors: Array<Ancestor>) => VisitorResult
export type BuildVisitor<
Tree extends Node = Node,
Check extends Test = string
> = Visitor<
Matches<InclusiveDescendant<Tree>, Check>,
Extract<InclusiveDescendant<Tree>, Parent>
>
/* eslint-enable @typescript-eslint/ban-types */
+46
View File
@@ -0,0 +1,46 @@
/**
* Continue traversing as normal
*/
export const CONTINUE: true
/**
* Do not traverse this nodes children
*/
export const SKIP: 'skip'
/**
* Stop traversing immediately
*/
export const EXIT: false
/**
* Visit children of tree which pass test.
*
* @param tree
* Tree to walk
* @param [test]
* `unist-util-is`-compatible test
* @param visitor
* Function called for nodes that pass `test`.
* @param [reverse=false]
* Traverse in reverse preorder (NRL) instead of preorder (NLR) (default).
*/
export const visitParents: (<
Tree extends import('unist').Node<import('unist').Data>,
Check extends import('unist-util-is').Test
>(
tree: Tree,
test: Check,
visitor: import('./complex-types.js').BuildVisitor<Tree, Check>,
reverse?: boolean
) => void) &
(<Tree_1 extends import('unist').Node<import('unist').Data>>(
tree: Tree_1,
visitor: import('./complex-types.js').BuildVisitor<Tree_1, string>,
reverse?: boolean
) => void)
export type Node = import('unist').Node
export type Parent = import('unist').Parent
export type Test = import('unist-util-is').Test
export type Action = import('./complex-types.js').Action
export type Index = import('./complex-types.js').Index
export type ActionTuple = import('./complex-types.js').ActionTuple
export type VisitorResult = import('./complex-types.js').VisitorResult
export type Visitor = import('./complex-types.js').Visitor
+156
View File
@@ -0,0 +1,156 @@
/**
* @typedef {import('unist').Node} Node
* @typedef {import('unist').Parent} Parent
* @typedef {import('unist-util-is').Test} Test
* @typedef {import('./complex-types.js').Action} Action
* @typedef {import('./complex-types.js').Index} Index
* @typedef {import('./complex-types.js').ActionTuple} ActionTuple
* @typedef {import('./complex-types.js').VisitorResult} VisitorResult
* @typedef {import('./complex-types.js').Visitor} Visitor
*/
import {convert} from 'unist-util-is'
import {color} from './color.js'
/**
* Continue traversing as normal
*/
export const CONTINUE = true
/**
* Do not traverse this nodes children
*/
export const SKIP = 'skip'
/**
* Stop traversing immediately
*/
export const EXIT = false
/**
* Visit children of tree which pass test.
*
* @param tree
* Tree to walk
* @param [test]
* `unist-util-is`-compatible test
* @param visitor
* Function called for nodes that pass `test`.
* @param [reverse=false]
* Traverse in reverse preorder (NRL) instead of preorder (NLR) (default).
*/
export const visitParents =
/**
* @type {(
* (<Tree extends Node, Check extends Test>(tree: Tree, test: Check, visitor: import('./complex-types.js').BuildVisitor<Tree, Check>, reverse?: boolean) => void) &
* (<Tree extends Node>(tree: Tree, visitor: import('./complex-types.js').BuildVisitor<Tree>, reverse?: boolean) => void)
* )}
*/
(
/**
* @param {Node} tree
* @param {Test} test
* @param {import('./complex-types.js').Visitor<Node>} visitor
* @param {boolean} [reverse=false]
*/
function (tree, test, visitor, reverse) {
if (typeof test === 'function' && typeof visitor !== 'function') {
reverse = visitor
// @ts-expect-error no visitor given, so `visitor` is test.
visitor = test
test = null
}
const is = convert(test)
const step = reverse ? -1 : 1
factory(tree, null, [])()
/**
* @param {Node} node
* @param {number?} index
* @param {Array<Parent>} parents
*/
function factory(node, index, parents) {
/** @type {Record<string, unknown>} */
// @ts-expect-error: hush
const value = typeof node === 'object' && node !== null ? node : {}
/** @type {string|undefined} */
let name
if (typeof value.type === 'string') {
name =
typeof value.tagName === 'string'
? value.tagName
: typeof value.name === 'string'
? value.name
: undefined
Object.defineProperty(visit, 'name', {
value:
'node (' +
color(value.type + (name ? '<' + name + '>' : '')) +
')'
})
}
return visit
function visit() {
/** @type {ActionTuple} */
let result = []
/** @type {ActionTuple} */
let subresult
/** @type {number} */
let offset
/** @type {Array<Parent>} */
let grandparents
if (!test || is(node, index, parents[parents.length - 1] || null)) {
result = toResult(visitor(node, parents))
if (result[0] === EXIT) {
return result
}
}
// @ts-expect-error looks like a parent.
if (node.children && result[0] !== SKIP) {
// @ts-expect-error looks like a parent.
offset = (reverse ? node.children.length : -1) + step
// @ts-expect-error looks like a parent.
grandparents = parents.concat(node)
// @ts-expect-error looks like a parent.
while (offset > -1 && offset < node.children.length) {
// @ts-expect-error looks like a parent.
subresult = factory(node.children[offset], offset, grandparents)()
if (subresult[0] === EXIT) {
return subresult
}
offset =
typeof subresult[1] === 'number' ? subresult[1] : offset + step
}
}
return result
}
}
}
)
/**
* @param {VisitorResult} value
* @returns {ActionTuple}
*/
function toResult(value) {
if (Array.isArray(value)) {
return value
}
if (typeof value === 'number') {
return [CONTINUE, value]
}
return [value]
}
+22
View File
@@ -0,0 +1,22 @@
(The MIT License)
Copyright (c) 2016 Titus Wormer <tituswormer@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+109
View File
@@ -0,0 +1,109 @@
{
"name": "unist-util-visit-parents",
"version": "5.1.1",
"description": "unist utility to recursively walk over nodes, with ancestral information",
"license": "MIT",
"keywords": [
"unist",
"unist-util",
"util",
"utility",
"tree",
"ast",
"visit",
"traverse",
"walk",
"check",
"parent",
"parents"
],
"repository": "syntax-tree/unist-util-visit-parents",
"bugs": "https://github.com/syntax-tree/unist-util-visit-parents/issues",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
},
"author": "Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)",
"contributors": [
"Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)"
],
"sideEffects": false,
"type": "module",
"main": "index.js",
"browser": {
"./color.js": "./color.browser.js"
},
"react-native": {
"./color.js": "./color.browser.js"
},
"types": "index.d.ts",
"files": [
"color.d.ts",
"color.js",
"color.browser.d.ts",
"color.browser.js",
"complex-types.d.ts",
"index.d.ts",
"index.js"
],
"dependencies": {
"@types/unist": "^2.0.0",
"unist-util-is": "^5.0.0"
},
"devDependencies": {
"@types/hast": "^2.0.0",
"@types/mdast": "^3.0.0",
"@types/tape": "^4.0.0",
"c8": "^7.0.0",
"mdast-util-from-markdown": "^1.0.0",
"mdast-util-gfm": "^2.0.0",
"micromark-extension-gfm": "^2.0.0",
"prettier": "^2.0.0",
"remark-cli": "^11.0.0",
"remark-preset-wooorm": "^9.0.0",
"rimraf": "^3.0.0",
"strip-ansi": "^7.0.0",
"tape": "^5.0.0",
"tsd": "^0.22.0",
"type-coverage": "^2.0.0",
"typescript": "^4.7.0",
"xo": "^0.51.0"
},
"scripts": {
"prepack": "npm run build && npm run format",
"build": "rimraf \"{color,color.browser,index,test}.d.ts\" && tsc && tsd && type-coverage",
"format": "remark . -qfo && prettier . --write --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 build && npm run format && npm run test-coverage"
},
"prettier": {
"tabWidth": 2,
"useTabs": false,
"singleQuote": true,
"bracketSpacing": false,
"semi": false,
"trailingComma": "none"
},
"xo": {
"prettier": true,
"rules": {
"@typescript-eslint/array-type": "off"
}
},
"remarkConfig": {
"plugins": [
"preset-wooorm"
]
},
"typeCoverage": {
"atLeast": 100,
"detail": true,
"strict": true,
"ignoreCatch": true,
"#": "needed `any`s",
"ignoreFiles": [
"complex-types.d.ts"
]
}
}
+290
View File
@@ -0,0 +1,290 @@
# unist-util-visit-parents
[![Build][build-badge]][build]
[![Coverage][coverage-badge]][coverage]
[![Downloads][downloads-badge]][downloads]
[![Size][size-badge]][size]
[![Sponsors][sponsors-badge]][collective]
[![Backers][backers-badge]][collective]
[![Chat][chat-badge]][chat]
[unist][] utility to walk the tree with a stack of parents.
## Contents
* [What is this?](#what-is-this)
* [When should I use this?](#when-should-i-use-this)
* [Install](#install)
* [Use](#use)
* [API](#api)
* [`visitParents(tree[, test], visitor[, reverse])`](#visitparentstree-test-visitor-reverse)
* [Types](#types)
* [Compatibility](#compatibility)
* [Related](#related)
* [Contribute](#contribute)
* [License](#license)
## What is this?
This is a very important utility for working with unist as it lets you walk the
tree.
## When should I use this?
You can use this utility when you want to walk the tree and want to know about
every parent of each node.
You can use [`unist-util-visit`][unist-util-visit] if you dont care about the
entire stack of parents.
## Install
This package is [ESM only][esm].
In Node.js (version 12.20+, 14.14+, 16.0+, 18.0+), install with [npm][]:
```sh
npm install unist-util-visit-parents
```
In Deno with [`esm.sh`][esmsh]:
```js
import {visitParents} from "https://esm.sh/unist-util-visit-parents@5"
```
In browsers with [`esm.sh`][esmsh]:
```html
<script type="module">
import {visitParents} from "https://esm.sh/unist-util-visit-parents@5?bundle"
</script>
```
## Use
```js
import {visitParents} from 'unist-util-visit-parents'
import {fromMarkdown} from 'mdast-util-from-markdown'
const tree = fromMarkdown('Some *emphasis*, **strong**, and `code`.')
visitParents(tree, 'strong', (node, ancestors) => {
console.log(node.type, ancestors.map(ancestor => ancestor.type))
})
```
Yields:
```js
strong ['root', 'paragraph']
```
## API
This package exports the identifiers `visitParents`, `SKIP`, `CONTINUE`, and
`EXIT`.
There is no default export.
### `visitParents(tree[, test], visitor[, reverse])`
Walk the `tree` ([`Node`][node]) and visit [*inclusive descendants*][descendant]
with ancestral information.
This algorithm performs *[depth-first][]* *[tree traversal][tree-traversal]* in
*[preorder][]* (**NLR**), or if `reverse` is given, in *reverse preorder*
(**NRL**).
You can choose for which nodes `visitor` is called by passing a `test`.
Walking the tree is an intensive task.
Make use of the return values of the visitor when possible.
Instead of walking a tree multiple times with different `test`s, walk it once
without a test, and use [`unist-util-is`][unist-util-is] to check if a node
matches a test, and then perform different operations.
You can change the tree.
See `visitor` below for more info.
###### Parameters
* `tree` ([`Node`][node])
— tree to traverse
* `test` ([`Test`][test], optional)
— [`unist-util-is`][unist-util-is]-compatible test
* `visitor` ([Function][visitor])
— function called for nodes that pass `test`
* `reverse` (`boolean`, default: `false`)
— traverse in reverse preorder (NRL) instead of preorder (NLR) (default
#### `next? = visitor(node, ancestors)`
Called when a node (matching `test`, if given) is entered.
Visitors are free to change `node`.
They can also transform the [parent][] of node (the last of `ancestors`).
Replacing `node` itself is okay if `SKIP` is returned.
When adding or removing previous [sibling][]s (or next siblings, in case of
`reverse`) of `node`, `visitor` must return a new [`index`][index] (`number`)
to specify the sibling to move to after `node` is traversed.
Adding or removing next siblings of `node` (or previous siblings, in case of
`reverse`) is fine without needing to return a new `index`.
Replacing the `children` of a node is fine, but replacing them on an ancestor
is not okay and still causes them to be visited.
###### Parameters
* `node` ([`Node`][node]) — found node
* `ancestors` (`Array<Node>`) — [ancestor][]s of `node`
##### Returns
The return value can have the following forms:
* [`index`][index] (`number`) — like a tuple of `[CONTINUE, index]`
* `action` (`*`) — like a tuple of `[action]`
* `tuple` (`[action, index?]`) — array with one or two values, the first an
`action`, the second and `index`.
> 👉 **Note**: yielding a tuple only makes sense if the `action` is `SKIP`.
> Otherwise, if the `action` is `EXIT`, that action can be returned.
> Or if the `action` is `CONTINUE`, `index` can be returned.
###### `action`
An action can have the following values:
* `EXIT` (`false`) — stop traversing immediately
* `CONTINUE` (`true`) — continue traversing as normal
* `SKIP` (`'skip'`) — do not traverse this nodes children
###### `index`
Next [`index`][index] (`number`).
Defines that the sibling at `index` should be moved to (after `node` itself is
completely traversed).
Useful if mutating the tree, such as removing the node the visitor is currently
on, or any of its previous siblings (or next siblings, in case of `reverse`).
Results less than `0` or greater than or equal to `children.length` stop
traversing the parent
## Types
This package is fully typed with [TypeScript][].
It exports the additional types `Test`, `Action`, `Index`, `ActionTuple`,
`VisitorResult`, and `Visitor`.
It also exports the types `BuildVisitor<Tree extends Node = Node, Check extends
Test = string>` to properly type visitors from a tree and a test, and
`Visitor<Visited extends Node = Node, Ancestor extends Parent = Parent>` to
build an arbitrary visitor, from `unist-util-visit-parents/complex-types.d.ts`.
## 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+, 16.0+, and 18.0+.
Our projects sometimes work with older versions, but this is not guaranteed.
## Related
* [`unist-util-visit`](https://github.com/syntax-tree/unist-util-visit)
— walk the tree with one parent
* [`unist-util-filter`](https://github.com/syntax-tree/unist-util-filter)
— create a new tree with all nodes that pass a test
* [`unist-util-map`](https://github.com/syntax-tree/unist-util-map)
— create a new tree with all nodes mapped by a given function
* [`unist-util-flatmap`](https://gitlab.com/staltz/unist-util-flatmap)
— create a new tree by mapping (to an array) with the given function
* [`unist-util-remove`](https://github.com/syntax-tree/unist-util-remove)
— remove nodes from a tree that pass a test
* [`unist-util-select`](https://github.com/syntax-tree/unist-util-select)
— select nodes with CSS-like selectors
## Contribute
See [`contributing.md`][contributing] in [`syntax-tree/.github`][health] for
ways to get started.
See [`support.md`][support] for ways to get help.
This project has a [code of conduct][coc].
By interacting with this repository, organization, or community you agree to
abide by its terms.
## License
[MIT][license] © [Titus Wormer][author]
<!-- Definition -->
[build-badge]: https://github.com/syntax-tree/unist-util-visit-parents/workflows/main/badge.svg
[build]: https://github.com/syntax-tree/unist-util-visit-parents/actions
[coverage-badge]: https://img.shields.io/codecov/c/github/syntax-tree/unist-util-visit-parents.svg
[coverage]: https://codecov.io/github/syntax-tree/unist-util-visit-parents
[downloads-badge]: https://img.shields.io/npm/dm/unist-util-visit-parents.svg
[downloads]: https://www.npmjs.com/package/unist-util-visit-parents
[size-badge]: https://img.shields.io/bundlephobia/minzip/unist-util-visit-parents.svg
[size]: https://bundlephobia.com/result?p=unist-util-visit-parents
[sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg
[backers-badge]: https://opencollective.com/unified/backers/badge.svg
[collective]: https://opencollective.com/unified
[chat-badge]: https://img.shields.io/badge/chat-discussions-success.svg
[chat]: https://github.com/syntax-tree/unist/discussions
[npm]: https://docs.npmjs.com/cli/install
[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
[esmsh]: https://esm.sh
[typescript]: https://www.typescriptlang.org
[license]: license
[author]: https://wooorm.com
[health]: https://github.com/syntax-tree/.github
[contributing]: https://github.com/syntax-tree/.github/blob/HEAD/contributing.md
[support]: https://github.com/syntax-tree/.github/blob/HEAD/support.md
[coc]: https://github.com/syntax-tree/.github/blob/HEAD/code-of-conduct.md
[unist]: https://github.com/syntax-tree/unist
[node]: https://github.com/syntax-tree/unist#node
[depth-first]: https://github.com/syntax-tree/unist#depth-first-traversal
[tree-traversal]: https://github.com/syntax-tree/unist#tree-traversal
[preorder]: https://github.com/syntax-tree/unist#preorder
[descendant]: https://github.com/syntax-tree/unist#descendant
[parent]: https://github.com/syntax-tree/unist#parent-1
[sibling]: https://github.com/syntax-tree/unist#sibling
[index]: https://github.com/syntax-tree/unist#index
[ancestor]: https://github.com/syntax-tree/unist#ancestor
[unist-util-visit]: https://github.com/syntax-tree/unist-util-visit
[unist-util-is]: https://github.com/syntax-tree/unist-util-is
[test]: https://github.com/syntax-tree/unist-util-is#test
[visitor]: #next--visitornode-ancestors
+54
View File
@@ -0,0 +1,54 @@
import type {Node, Parent} from 'unist'
import type {Test} from 'unist-util-is'
import type {
VisitorResult,
Matches,
InclusiveDescendant
} from 'unist-util-visit-parents/complex-types.js'
/**
* Called when a node (matching test, if given) is found.
* Visitors are free to transform node.
* They can also transform the parent of node (the last of ancestors).
* Replacing node itself, if `SKIP` is not returned, still causes its descendants to be visited.
* If adding or removing previous siblings (or next siblings, in case of reverse) of node,
* visitor should return a new index (number) to specify the sibling to traverse after node is traversed.
* Adding or removing next siblings of node (or previous siblings, in case of reverse)
* is handled as expected without needing to return a new index.
* Removing the children property of an ancestor still results in them being traversed.
*/
export type Visitor<
Visited extends Node = Node,
Ancestor extends Parent = Parent
> = (
node: Visited,
index: Visited extends Node ? number | null : never,
parent: Ancestor extends Node ? Ancestor | null : Ancestor
) => VisitorResult
type ParentsOf<
Ancestor extends Node,
Child extends Node
> = Ancestor extends Parent
? Child extends Ancestor['children'][number]
? Ancestor
: never
: never
type BuildVisitorFromMatch<
Visited extends Node,
Ancestor extends Parent
> = Visitor<Visited, ParentsOf<Ancestor, Visited>>
type BuildVisitorFromDescendants<
Descendant extends Node,
Check extends Test
> = BuildVisitorFromMatch<
Matches<Descendant, Check>,
Extract<Descendant, Parent>
>
export type BuildVisitor<
Tree extends Node = Node,
Check extends Test = string
> = BuildVisitorFromDescendants<InclusiveDescendant<Tree>, Check>
+32
View File
@@ -0,0 +1,32 @@
/**
* Visit children of tree which pass test.
*
* @param tree
* Tree to walk
* @param [test]
* `unist-util-is`-compatible test
* @param visitor
* Function called for nodes that pass `test`.
* @param reverse
* Traverse in reverse preorder (NRL) instead of preorder (NLR) (default).
*/
export const visit: (<
Tree extends import('unist').Node<import('unist').Data>,
Check extends import('unist-util-is').Test
>(
tree: Tree,
test: Check,
visitor: import('./complex-types.js').BuildVisitor<Tree, Check>,
reverse?: boolean
) => void) &
(<Tree_1 extends import('unist').Node<import('unist').Data>>(
tree: Tree_1,
visitor: import('./complex-types.js').BuildVisitor<Tree_1, string>,
reverse?: boolean
) => void)
export type Node = import('unist').Node
export type Parent = import('unist').Parent
export type Test = import('unist-util-is').Test
export type VisitorResult = import('unist-util-visit-parents').VisitorResult
export type Visitor = import('./complex-types.js').Visitor
export {CONTINUE, EXIT, SKIP} from 'unist-util-visit-parents'
+61
View File
@@ -0,0 +1,61 @@
/**
* @typedef {import('unist').Node} Node
* @typedef {import('unist').Parent} Parent
* @typedef {import('unist-util-is').Test} Test
* @typedef {import('unist-util-visit-parents').VisitorResult} VisitorResult
* @typedef {import('./complex-types.js').Visitor} Visitor
*/
import {visitParents} from 'unist-util-visit-parents'
/**
* Visit children of tree which pass test.
*
* @param tree
* Tree to walk
* @param [test]
* `unist-util-is`-compatible test
* @param visitor
* Function called for nodes that pass `test`.
* @param reverse
* Traverse in reverse preorder (NRL) instead of preorder (NLR) (default).
*/
export const visit =
/**
* @type {(
* (<Tree extends Node, Check extends Test>(tree: Tree, test: Check, visitor: import('./complex-types.js').BuildVisitor<Tree, Check>, reverse?: boolean) => void) &
* (<Tree extends Node>(tree: Tree, visitor: import('./complex-types.js').BuildVisitor<Tree>, reverse?: boolean) => void)
* )}
*/
(
/**
* @param {Node} tree
* @param {Test} test
* @param {import('./complex-types.js').Visitor} visitor
* @param {boolean} [reverse]
*/
function (tree, test, visitor, reverse) {
if (typeof test === 'function' && typeof visitor !== 'function') {
reverse = visitor
visitor = test
test = null
}
visitParents(tree, test, overload, reverse)
/**
* @param {Node} node
* @param {Array<Parent>} parents
*/
function overload(node, parents) {
const parent = parents[parents.length - 1]
return visitor(
node,
parent ? parent.children.indexOf(node) : null,
parent
)
}
}
)
export {CONTINUE, EXIT, SKIP} from 'unist-util-visit-parents'
+22
View File
@@ -0,0 +1,22 @@
(The MIT License)
Copyright (c) 2015 Titus Wormer <tituswormer@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+104
View File
@@ -0,0 +1,104 @@
{
"name": "unist-util-visit",
"version": "4.1.1",
"description": "unist utility to visit nodes",
"license": "MIT",
"keywords": [
"unist",
"unist-util",
"util",
"utility",
"remark",
"retext",
"rehype",
"mdast",
"hast",
"xast",
"nlcst",
"natural",
"language",
"markdown",
"html",
"xml",
"tree",
"ast",
"node",
"visit",
"walk"
],
"repository": "syntax-tree/unist-util-visit",
"bugs": "https://github.com/syntax-tree/unist-util-visit/issues",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
},
"author": "Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)",
"contributors": [
"Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)",
"Eugene Sharygin <eush77@gmail.com>",
"Richard Gibson <richard.gibson@gmail.com>"
],
"sideEffects": false,
"type": "module",
"main": "index.js",
"types": "index.d.ts",
"files": [
"complex-types.d.ts",
"index.d.ts",
"index.js"
],
"dependencies": {
"@types/unist": "^2.0.0",
"unist-util-is": "^5.0.0",
"unist-util-visit-parents": "^5.1.1"
},
"devDependencies": {
"@types/tape": "^4.0.0",
"c8": "^7.0.0",
"mdast-util-from-markdown": "^1.0.0",
"mdast-util-gfm": "^2.0.0",
"micromark-extension-gfm": "^2.0.0",
"prettier": "^2.0.0",
"remark-cli": "^11.0.0",
"remark-preset-wooorm": "^9.0.0",
"rimraf": "^3.0.0",
"tape": "^5.0.0",
"tsd": "^0.22.0",
"type-coverage": "^2.0.0",
"typescript": "^4.7.0",
"xo": "^0.51.0"
},
"scripts": {
"prepack": "npm run build && npm run format",
"build": "rimraf \"{index,test}.d.ts\" && tsc && tsd && 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 build && npm run format && npm run test-coverage"
},
"prettier": {
"tabWidth": 2,
"useTabs": false,
"singleQuote": true,
"bracketSpacing": false,
"semi": false,
"trailingComma": "none"
},
"xo": {
"prettier": true,
"rules": {
"@typescript-eslint/ban-types": "off",
"@typescript-eslint/array-type": "off"
}
},
"remarkConfig": {
"plugins": [
"preset-wooorm"
]
},
"typeCoverage": {
"atLeast": 100,
"detail": true,
"strict": true
}
}
+203
View File
@@ -0,0 +1,203 @@
# unist-util-visit
[![Build][build-badge]][build]
[![Coverage][coverage-badge]][coverage]
[![Downloads][downloads-badge]][downloads]
[![Size][size-badge]][size]
[![Sponsors][sponsors-badge]][collective]
[![Backers][backers-badge]][collective]
[![Chat][chat-badge]][chat]
[unist][] utility to walk the tree.
## Contents
* [What is this?](#what-is-this)
* [When should I use this?](#when-should-i-use-this)
* [Install](#install)
* [Use](#use)
* [API](#api)
* [`visit(tree[, test], visitor[, reverse])`](#visittree-test-visitor-reverse)
* [Types](#types)
* [Compatibility](#compatibility)
* [Related](#related)
* [Contribute](#contribute)
* [License](#license)
## What is this?
This is a very important utility for working with unist as it lets you walk the
tree.
## When should I use this?
You can use this utility when you want to walk the tree.
You can use [`unist-util-visit-parents`][vp] if you care about the entire stack
of parents.
## Install
This package is [ESM only][esm].
In Node.js (version 12.20+, 14.14+, 16.0+, 18.0+), install with [npm][]:
```sh
npm install unist-util-visit
```
In Deno with [`esm.sh`][esmsh]:
```js
import {visit} from "https://esm.sh/unist-util-visit@4"
```
In browsers with [`esm.sh`][esmsh]:
```html
<script type="module">
import {visit} from "https://esm.sh/unist-util-visit@4?bundle"
</script>
```
## Use
```js
import {u} from 'unist-builder'
import {visit} from 'unist-util-visit'
const tree = u('tree', [
u('leaf', '1'),
u('node', [u('leaf', '2')]),
u('void'),
u('leaf', '3')
])
visit(tree, 'leaf', (node) => {
console.log(node)
})
```
Yields:
```js
{type: 'leaf', value: '1'}
{type: 'leaf', value: '2'}
{type: 'leaf', value: '3'}
```
## API
This package exports the identifiers `visit`, `CONTINUE`, `SKIP`, and `EXIT`.
There is no default export.
### `visit(tree[, test], visitor[, reverse])`
This function works exactly the same as [`unist-util-visit-parents`][vp],
but `visitor` has a different signature.
#### `next? = visitor(node, index, parent)`
Instead of being passed an array of ancestors, `visitor` is called with the
`node`s [`index`][index] and its [`parent`][parent].
Please see [`unist-util-visit-parents`][vp].
## Types
This package is fully typed with [TypeScript][].
It exports the additional types `Test`, `VisitorResult`, and `Visitor`.
It also exports the types `BuildVisitor<Tree extends Node = Node, Check extends
Test = string>` to properly type visitors from a tree and a test, from
`unist-util-visit-parents/complex-types.d.ts`.
## 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+, 16.0+, and 18.0+.
Our projects sometimes work with older versions, but this is not guaranteed.
## Related
* [`unist-util-visit-parents`][vp]
— walk the tree with a stack of parents
* [`unist-util-filter`](https://github.com/syntax-tree/unist-util-filter)
— create a new tree with all nodes that pass a test
* [`unist-util-map`](https://github.com/syntax-tree/unist-util-map)
— create a new tree with all nodes mapped by a given function
* [`unist-util-flatmap`](https://gitlab.com/staltz/unist-util-flatmap)
— create a new tree by mapping (to an array) with the given function
* [`unist-util-remove`](https://github.com/syntax-tree/unist-util-remove)
— remove nodes from a tree that pass a test
* [`unist-util-select`](https://github.com/syntax-tree/unist-util-select)
— select nodes with CSS-like selectors
## Contribute
See [`contributing.md`][contributing] in [`syntax-tree/.github`][health] for
ways to get started.
See [`support.md`][support] for ways to get help.
This project has a [code of conduct][coc].
By interacting with this repository, organization, or community you agree to
abide by its terms.
## License
[MIT][license] © [Titus Wormer][author]
<!-- Definition -->
[build-badge]: https://github.com/syntax-tree/unist-util-visit/workflows/main/badge.svg
[build]: https://github.com/syntax-tree/unist-util-visit/actions
[coverage-badge]: https://img.shields.io/codecov/c/github/syntax-tree/unist-util-visit.svg
[coverage]: https://codecov.io/github/syntax-tree/unist-util-visit
[downloads-badge]: https://img.shields.io/npm/dm/unist-util-visit.svg
[downloads]: https://www.npmjs.com/package/unist-util-visit
[size-badge]: https://img.shields.io/bundlephobia/minzip/unist-util-visit.svg
[size]: https://bundlephobia.com/result?p=unist-util-visit
[sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg
[backers-badge]: https://opencollective.com/unified/backers/badge.svg
[collective]: https://opencollective.com/unified
[chat-badge]: https://img.shields.io/badge/chat-discussions-success.svg
[chat]: https://github.com/syntax-tree/unist/discussions
[npm]: https://docs.npmjs.com/cli/install
[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
[esmsh]: https://esm.sh
[typescript]: https://www.typescriptlang.org
[license]: license
[author]: https://wooorm.com
[health]: https://github.com/syntax-tree/.github
[contributing]: https://github.com/syntax-tree/.github/blob/main/contributing.md
[support]: https://github.com/syntax-tree/.github/blob/main/support.md
[coc]: https://github.com/syntax-tree/.github/blob/main/code-of-conduct.md
[unist]: https://github.com/syntax-tree/unist
[vp]: https://github.com/syntax-tree/unist-util-visit-parents
[index]: https://github.com/syntax-tree/unist#index
[parent]: https://github.com/syntax-tree/unist#parent-1
+20
View File
@@ -0,0 +1,20 @@
(The MIT License)
Copyright (c) 2017, Ryan Zimmerman <opensrc@ryanzim.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the 'Software'), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+76
View File
@@ -0,0 +1,76 @@
# universalify
[![Travis branch](https://img.shields.io/travis/RyanZim/universalify/master.svg)](https://travis-ci.org/RyanZim/universalify)
![Coveralls github branch](https://img.shields.io/coveralls/github/RyanZim/universalify/master.svg)
![npm](https://img.shields.io/npm/dm/universalify.svg)
![npm](https://img.shields.io/npm/l/universalify.svg)
Make a callback- or promise-based function support both promises and callbacks.
Uses the native promise implementation.
## Installation
```bash
npm install universalify
```
## API
### `universalify.fromCallback(fn)`
Takes a callback-based function to universalify, and returns the universalified function.
Function must take a callback as the last parameter that will be called with the signature `(error, result)`. `universalify` does not support calling the callback with three or more arguments, and does not ensure that the callback is only called once.
```js
function callbackFn (n, cb) {
setTimeout(() => cb(null, n), 15)
}
const fn = universalify.fromCallback(callbackFn)
// Works with Promises:
fn('Hello World!')
.then(result => console.log(result)) // -> Hello World!
.catch(error => console.error(error))
// Works with Callbacks:
fn('Hi!', (error, result) => {
if (error) return console.error(error)
console.log(result)
// -> Hi!
})
```
### `universalify.fromPromise(fn)`
Takes a promise-based function to universalify, and returns the universalified function.
Function must return a valid JS promise. `universalify` does not ensure that a valid promise is returned.
```js
function promiseFn (n) {
return new Promise(resolve => {
setTimeout(() => resolve(n), 15)
})
}
const fn = universalify.fromPromise(promiseFn)
// Works with Promises:
fn('Hello World!')
.then(result => console.log(result)) // -> Hello World!
.catch(error => console.error(error))
// Works with Callbacks:
fn('Hi!', (error, result) => {
if (error) return console.error(error)
console.log(result)
// -> Hi!
})
```
## License
MIT
+24
View File
@@ -0,0 +1,24 @@
'use strict'
exports.fromCallback = function (fn) {
return Object.defineProperty(function (...args) {
if (typeof args[args.length - 1] === 'function') fn.apply(this, args)
else {
return new Promise((resolve, reject) => {
fn.call(
this,
...args,
(err, res) => (err != null) ? reject(err) : resolve(res)
)
})
}
}, 'name', { value: fn.name })
}
exports.fromPromise = function (fn) {
return Object.defineProperty(function (...args) {
const cb = args[args.length - 1]
if (typeof cb !== 'function') return fn.apply(this, args)
else fn.apply(this, args.slice(0, -1)).then(r => cb(null, r), cb)
}, 'name', { value: fn.name })
}
+34
View File
@@ -0,0 +1,34 @@
{
"name": "universalify",
"version": "2.0.0",
"description": "Make a callback- or promise-based function support both promises and callbacks.",
"keywords": [
"callback",
"native",
"promise"
],
"homepage": "https://github.com/RyanZim/universalify#readme",
"bugs": "https://github.com/RyanZim/universalify/issues",
"license": "MIT",
"author": "Ryan Zimmerman <opensrc@ryanzim.com>",
"files": [
"index.js"
],
"repository": {
"type": "git",
"url": "git+https://github.com/RyanZim/universalify.git"
},
"scripts": {
"test": "standard && nyc tape test/*.js | colortape"
},
"devDependencies": {
"colortape": "^0.1.2",
"coveralls": "^3.0.1",
"nyc": "^15.0.0",
"standard": "^14.3.1",
"tape": "^5.0.1"
},
"engines": {
"node": ">= 10.0.0"
}
}
+4
View File
@@ -0,0 +1,4 @@
1.0.0 / 2015-06-14
==================
* Initial release
+22
View File
@@ -0,0 +1,22 @@
(The MIT License)
Copyright (c) 2015 Douglas Christopher Wilson <doug@somethingdoug.com>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+43
View File
@@ -0,0 +1,43 @@
# unpipe
[![NPM Version][npm-image]][npm-url]
[![NPM Downloads][downloads-image]][downloads-url]
[![Node.js Version][node-image]][node-url]
[![Build Status][travis-image]][travis-url]
[![Test Coverage][coveralls-image]][coveralls-url]
Unpipe a stream from all destinations.
## Installation
```sh
$ npm install unpipe
```
## API
```js
var unpipe = require('unpipe')
```
### unpipe(stream)
Unpipes all destinations from a given stream. With stream 2+, this is
equivalent to `stream.unpipe()`. When used with streams 1 style streams
(typically Node.js 0.8 and below), this module attempts to undo the
actions done in `stream.pipe(dest)`.
## License
[MIT](LICENSE)
[npm-image]: https://img.shields.io/npm/v/unpipe.svg
[npm-url]: https://npmjs.org/package/unpipe
[node-image]: https://img.shields.io/node/v/unpipe.svg
[node-url]: http://nodejs.org/download/
[travis-image]: https://img.shields.io/travis/stream-utils/unpipe.svg
[travis-url]: https://travis-ci.org/stream-utils/unpipe
[coveralls-image]: https://img.shields.io/coveralls/stream-utils/unpipe.svg
[coveralls-url]: https://coveralls.io/r/stream-utils/unpipe?branch=master
[downloads-image]: https://img.shields.io/npm/dm/unpipe.svg
[downloads-url]: https://npmjs.org/package/unpipe
+69
View File
@@ -0,0 +1,69 @@
/*!
* unpipe
* Copyright(c) 2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module exports.
* @public
*/
module.exports = unpipe
/**
* Determine if there are Node.js pipe-like data listeners.
* @private
*/
function hasPipeDataListeners(stream) {
var listeners = stream.listeners('data')
for (var i = 0; i < listeners.length; i++) {
if (listeners[i].name === 'ondata') {
return true
}
}
return false
}
/**
* Unpipe a stream from all destinations.
*
* @param {object} stream
* @public
*/
function unpipe(stream) {
if (!stream) {
throw new TypeError('argument stream is required')
}
if (typeof stream.unpipe === 'function') {
// new-style
stream.unpipe()
return
}
// Node.js 0.8 hack
if (!hasPipeDataListeners(stream)) {
return
}
var listener
var listeners = stream.listeners('close')
for (var i = 0; i < listeners.length; i++) {
listener = listeners[i]
if (listener.name !== 'cleanup' && listener.name !== 'onclose') {
continue
}
// invoke the listener
listener.call(stream)
}
}
+27
View File
@@ -0,0 +1,27 @@
{
"name": "unpipe",
"description": "Unpipe a stream from all destinations",
"version": "1.0.0",
"author": "Douglas Christopher Wilson <doug@somethingdoug.com>",
"license": "MIT",
"repository": "stream-utils/unpipe",
"devDependencies": {
"istanbul": "0.3.15",
"mocha": "2.2.5",
"readable-stream": "1.1.13"
},
"files": [
"HISTORY.md",
"LICENSE",
"README.md",
"index.js"
],
"engines": {
"node": ">= 0.8"
},
"scripts": {
"test": "mocha --reporter spec --bail --check-leaks test/",
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/",
"test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/"
}
}
+20
View File
@@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright 2022 Andrey Sitnik <andrey@sitnik.ru> and other contributors
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+23
View File
@@ -0,0 +1,23 @@
# Update Browserslist DB
<img width="120" height="120" alt="Browserslist logo by Anton Lovchikov"
src="https://browserslist.github.io/browserslist/logo.svg" align="right">
CLI tool to update `caniuse-lite` with browsers DB
from [Browserslist](https://github.com/browserslist/browserslist/) config.
Some queries like `last 2 version` or `>1%` depends on actual data
from `caniuse-lite`.
```sh
npx update-browserslist-db@latest
```
<a href="https://evilmartians.com/?utm_source=update-browserslist-db">
<img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg"
alt="Sponsored by Evil Martians" width="236" height="54">
</a>
## Docs
Read **[full docs](https://github.com/browserslist/update-db#readme)** on GitHub.
+16
View File
@@ -0,0 +1,16 @@
let { execSync } = require('child_process')
let pico = require('picocolors')
try {
let version = parseInt(execSync('npm -v'))
if (version <= 6) {
process.stderr.write(
pico.red(
'Update npm or call ' +
pico.yellow('npx browserslist@latest --update-db') +
'\n'
)
)
process.exit(1)
}
} catch (e) {}
Generated Vendored Executable
+42
View File
@@ -0,0 +1,42 @@
#!/usr/bin/env node
let { readFileSync } = require('fs')
let { join } = require('path')
require('./check-npm-version')
let updateDb = require('./')
const ROOT = __dirname
function getPackage() {
return JSON.parse(readFileSync(join(ROOT, 'package.json')))
}
let args = process.argv.slice(2)
let USAGE = 'Usage:\n npx update-browserslist-db\n'
function isArg(arg) {
return args.some(i => i === arg)
}
function error(msg) {
process.stderr.write('update-browserslist-db: ' + msg + '\n')
process.exit(1)
}
if (isArg('--help') || isArg('-h')) {
process.stdout.write(getPackage().description + '.\n\n' + USAGE + '\n')
} else if (isArg('--version') || isArg('-v')) {
process.stdout.write('browserslist-lint ' + getPackage().version + '\n')
} else {
try {
updateDb()
} catch (e) {
if (e.name === 'BrowserslistUpdateError') {
error(e.message)
} else {
throw e
}
}
}
+6
View File
@@ -0,0 +1,6 @@
/**
* Run update and print output to terminal.
*/
declare function updateDb(print?: (str: string) => void): Promise<void>
export = updateDb
+301
View File
@@ -0,0 +1,301 @@
let childProcess = require('child_process')
let escalade = require('escalade/sync')
let pico = require('picocolors')
let path = require('path')
let fs = require('fs')
function BrowserslistUpdateError(message) {
this.name = 'BrowserslistUpdateError'
this.message = message
this.browserslist = true
if (Error.captureStackTrace) {
Error.captureStackTrace(this, BrowserslistUpdateError)
}
}
BrowserslistUpdateError.prototype = Error.prototype
/* c8 ignore next 3 */
function defaultPrint(str) {
process.stdout.write(str)
}
function detectLockfile() {
let packageDir = escalade('.', (dir, names) => {
return names.indexOf('package.json') !== -1 ? dir : ''
})
if (!packageDir) {
throw new BrowserslistUpdateError(
'Cannot find package.json. ' +
'Is this the right directory to run `npx update-browserslist-db` in?'
)
}
let lockfileNpm = path.join(packageDir, 'package-lock.json')
let lockfileShrinkwrap = path.join(packageDir, 'npm-shrinkwrap.json')
let lockfileYarn = path.join(packageDir, 'yarn.lock')
let lockfilePnpm = path.join(packageDir, 'pnpm-lock.yaml')
if (fs.existsSync(lockfilePnpm)) {
return { mode: 'pnpm', file: lockfilePnpm }
} else if (fs.existsSync(lockfileNpm)) {
return { mode: 'npm', file: lockfileNpm }
} else if (fs.existsSync(lockfileYarn)) {
let lock = { mode: 'yarn', file: lockfileYarn }
lock.content = fs.readFileSync(lock.file).toString()
lock.version = /# yarn lockfile v1/.test(lock.content) ? 1 : 2
return lock
} else if (fs.existsSync(lockfileShrinkwrap)) {
return { mode: 'npm', file: lockfileShrinkwrap }
}
throw new BrowserslistUpdateError(
'No lockfile found. Run "npm install", "yarn install" or "pnpm install"'
)
}
function getLatestInfo(lock) {
if (lock.mode === 'yarn') {
if (lock.version === 1) {
return JSON.parse(
childProcess.execSync('yarn info caniuse-lite --json').toString()
).data
} else {
return JSON.parse(
childProcess.execSync('yarn npm info caniuse-lite --json').toString()
)
}
}
return JSON.parse(
childProcess.execSync('npm show caniuse-lite --json').toString()
)
}
function getBrowsers() {
let browserslist = require('browserslist')
return browserslist().reduce((result, entry) => {
if (!result[entry[0]]) {
result[entry[0]] = []
}
result[entry[0]].push(entry[1])
return result
}, {})
}
function diffBrowsers(old, current) {
let browsers = Object.keys(old).concat(
Object.keys(current).filter(browser => old[browser] === undefined)
)
return browsers
.map(browser => {
let oldVersions = old[browser] || []
let currentVersions = current[browser] || []
let common = oldVersions.filter(v => currentVersions.includes(v))
let added = currentVersions.filter(v => !common.includes(v))
let removed = oldVersions.filter(v => !common.includes(v))
return removed
.map(v => pico.red('- ' + browser + ' ' + v))
.concat(added.map(v => pico.green('+ ' + browser + ' ' + v)))
})
.reduce((result, array) => result.concat(array), [])
.join('\n')
}
function updateNpmLockfile(lock, latest) {
let metadata = { latest, versions: [] }
let content = deletePackage(JSON.parse(lock.content), metadata)
metadata.content = JSON.stringify(content, null, ' ')
return metadata
}
function deletePackage(node, metadata) {
if (node.dependencies) {
if (node.dependencies['caniuse-lite']) {
let version = node.dependencies['caniuse-lite'].version
metadata.versions[version] = true
delete node.dependencies['caniuse-lite']
}
for (let i in node.dependencies) {
node.dependencies[i] = deletePackage(node.dependencies[i], metadata)
}
}
return node
}
let yarnVersionRe = /version "(.*?)"/
function updateYarnLockfile(lock, latest) {
let blocks = lock.content.split(/(\n{2,})/).map(block => {
return block.split('\n')
})
let versions = {}
blocks.forEach(lines => {
if (lines[0].indexOf('caniuse-lite@') !== -1) {
let match = yarnVersionRe.exec(lines[1])
versions[match[1]] = true
if (match[1] !== latest.version) {
lines[1] = lines[1].replace(
/version "[^"]+"/,
'version "' + latest.version + '"'
)
lines[2] = lines[2].replace(
/resolved "[^"]+"/,
'resolved "' + latest.dist.tarball + '"'
)
if (lines.length === 4) {
lines[3] = latest.dist.integrity
? lines[3].replace(
/integrity .+/,
'integrity ' + latest.dist.integrity
)
: ''
}
}
}
})
let content = blocks.map(lines => lines.join('\n')).join('')
return { content, versions }
}
function updateLockfile(lock, latest) {
if (!lock.content) lock.content = fs.readFileSync(lock.file).toString()
if (lock.mode === 'yarn') {
return updateYarnLockfile(lock, latest)
} else {
return updateNpmLockfile(lock, latest)
}
}
function updatePackageManually(print, lock, latest) {
let lockfileData = updateLockfile(lock, latest)
let caniuseVersions = Object.keys(lockfileData.versions).sort()
if (caniuseVersions.length === 1 && caniuseVersions[0] === latest.version) {
print(
'Installed version: ' +
pico.bold(pico.green(latest.version)) +
'\n' +
pico.bold(pico.green('caniuse-lite is up to date')) +
'\n'
)
return
}
if (caniuseVersions.length === 0) {
caniuseVersions[0] = 'none'
}
print(
'Installed version' +
(caniuseVersions.length === 1 ? ': ' : 's: ') +
pico.bold(pico.red(caniuseVersions.join(', '))) +
'\n' +
'Removing old caniuse-lite from lock file\n'
)
fs.writeFileSync(lock.file, lockfileData.content)
let install = lock.mode === 'yarn' ? 'yarn add -W' : lock.mode + ' install'
print(
'Installing new caniuse-lite version\n' +
pico.yellow('$ ' + install + ' caniuse-lite') +
'\n'
)
try {
childProcess.execSync(install + ' caniuse-lite')
} catch (e) /* c8 ignore start */ {
print(
pico.red(
'\n' +
e.stack +
'\n\n' +
'Problem with `' +
install +
' caniuse-lite` call. ' +
'Run it manually.\n'
)
)
process.exit(1)
} /* c8 ignore end */
let del = lock.mode === 'yarn' ? 'yarn remove -W' : lock.mode + ' uninstall'
print(
'Cleaning package.json dependencies from caniuse-lite\n' +
pico.yellow('$ ' + del + ' caniuse-lite') +
'\n'
)
childProcess.execSync(del + ' caniuse-lite')
}
function updateWith(print, cmd) {
print('Updating caniuse-lite version\n' + pico.yellow('$ ' + cmd) + '\n')
try {
childProcess.execSync(cmd)
} catch (e) /* c8 ignore start */ {
print(pico.red(e.stdout.toString()))
print(
pico.red(
'\n' +
e.stack +
'\n\n' +
'Problem with `' +
cmd +
'` call. ' +
'Run it manually.\n'
)
)
process.exit(1)
} /* c8 ignore end */
}
module.exports = function updateDB(print = defaultPrint) {
let lock = detectLockfile()
let latest = getLatestInfo(lock)
let listError
let oldList
try {
oldList = getBrowsers()
} catch (e) {
listError = e
}
print('Latest version: ' + pico.bold(pico.green(latest.version)) + '\n')
if (lock.mode === 'yarn' && lock.version !== 1) {
updateWith(print, 'yarn up -R caniuse-lite')
} else if (lock.mode === 'pnpm') {
updateWith(print, 'pnpm up caniuse-lite')
} else {
updatePackageManually(print, lock, latest)
}
print('caniuse-lite has been successfully updated\n')
let newList
if (!listError) {
try {
newList = getBrowsers()
} catch (e) /* c8 ignore start */ {
listError = e
} /* c8 ignore end */
}
if (listError) {
print(
pico.red(
'\n' +
listError.stack +
'\n\n' +
'Problem with browser list retrieval.\n' +
'Target browser changes wont be shown.\n'
)
)
} else {
let changes = diffBrowsers(oldList, newList)
if (changes) {
print('\nTarget browser changes:\n')
print(changes + '\n')
} else {
print('\n' + pico.green('No target browser changes') + '\n')
}
}
}
+38
View File
@@ -0,0 +1,38 @@
{
"name": "update-browserslist-db",
"version": "1.0.5",
"description": "CLI tool to update caniuse-lite to refresh target browsers from Browserslist config",
"keywords": [
"caniuse",
"browsers",
"target"
],
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/browserslist"
},
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/browserslist"
}
],
"author": "Andrey Sitnik <andrey@sitnik.ru>",
"license": "MIT",
"repository": "browserslist/update-db",
"types": "./index.d.ts",
"exports": {
".": "./index.js",
"./package.json": "./package.json"
},
"dependencies": {
"escalade": "^3.1.1",
"picocolors": "^1.0.0"
},
"peerDependencies": {
"browserslist": ">= 4.21.0"
},
"bin": {
"browserslist-lint": "cli.js"
}
}
Generated Vendored Executable
+11
View File
@@ -0,0 +1,11 @@
Copyright 2011 Gary Court. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY GARY COURT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GARY COURT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of Gary Court.
Generated Vendored Executable
+203
View File
@@ -0,0 +1,203 @@
# URI.js
URI.js is an [RFC 3986](http://www.ietf.org/rfc/rfc3986.txt) compliant, scheme extendable URI parsing/validating/resolving library for all JavaScript environments (browsers, Node.js, etc).
It is also compliant with the IRI ([RFC 3987](http://www.ietf.org/rfc/rfc3987.txt)), IDNA ([RFC 5890](http://www.ietf.org/rfc/rfc5890.txt)), IPv6 Address ([RFC 5952](http://www.ietf.org/rfc/rfc5952.txt)), IPv6 Zone Identifier ([RFC 6874](http://www.ietf.org/rfc/rfc6874.txt)) specifications.
URI.js has an extensive test suite, and works in all (Node.js, web) environments. It weighs in at 6.4kb (gzipped, 17kb deflated).
## API
### Parsing
URI.parse("uri://user:pass@example.com:123/one/two.three?q1=a1&q2=a2#body");
//returns:
//{
// scheme : "uri",
// userinfo : "user:pass",
// host : "example.com",
// port : 123,
// path : "/one/two.three",
// query : "q1=a1&q2=a2",
// fragment : "body"
//}
### Serializing
URI.serialize({scheme : "http", host : "example.com", fragment : "footer"}) === "http://example.com/#footer"
### Resolving
URI.resolve("uri://a/b/c/d?q", "../../g") === "uri://a/g"
### Normalizing
URI.normalize("HTTP://ABC.com:80/%7Esmith/home.html") === "http://abc.com/~smith/home.html"
### Comparison
URI.equal("example://a/b/c/%7Bfoo%7D", "eXAMPLE://a/./b/../b/%63/%7bfoo%7d") === true
### IP Support
//IPv4 normalization
URI.normalize("//192.068.001.000") === "//192.68.1.0"
//IPv6 normalization
URI.normalize("//[2001:0:0DB8::0:0001]") === "//[2001:0:db8::1]"
//IPv6 zone identifier support
URI.parse("//[2001:db8::7%25en1]");
//returns:
//{
// host : "2001:db8::7%en1"
//}
### IRI Support
//convert IRI to URI
URI.serialize(URI.parse("http://examplé.org/rosé")) === "http://xn--exampl-gva.org/ros%C3%A9"
//convert URI to IRI
URI.serialize(URI.parse("http://xn--exampl-gva.org/ros%C3%A9"), {iri:true}) === "http://examplé.org/rosé"
### Options
All of the above functions can accept an additional options argument that is an object that can contain one or more of the following properties:
* `scheme` (string)
Indicates the scheme that the URI should be treated as, overriding the URI's normal scheme parsing behavior.
* `reference` (string)
If set to `"suffix"`, it indicates that the URI is in the suffix format, and the validator will use the option's `scheme` property to determine the URI's scheme.
* `tolerant` (boolean, false)
If set to `true`, the parser will relax URI resolving rules.
* `absolutePath` (boolean, false)
If set to `true`, the serializer will not resolve a relative `path` component.
* `iri` (boolean, false)
If set to `true`, the serializer will unescape non-ASCII characters as per [RFC 3987](http://www.ietf.org/rfc/rfc3987.txt).
* `unicodeSupport` (boolean, false)
If set to `true`, the parser will unescape non-ASCII characters in the parsed output as per [RFC 3987](http://www.ietf.org/rfc/rfc3987.txt).
* `domainHost` (boolean, false)
If set to `true`, the library will treat the `host` component as a domain name, and convert IDNs (International Domain Names) as per [RFC 5891](http://www.ietf.org/rfc/rfc5891.txt).
## Scheme Extendable
URI.js supports inserting custom [scheme](http://en.wikipedia.org/wiki/URI_scheme) dependent processing rules. Currently, URI.js has built in support for the following schemes:
* http \[[RFC 2616](http://www.ietf.org/rfc/rfc2616.txt)\]
* https \[[RFC 2818](http://www.ietf.org/rfc/rfc2818.txt)\]
* ws \[[RFC 6455](http://www.ietf.org/rfc/rfc6455.txt)\]
* wss \[[RFC 6455](http://www.ietf.org/rfc/rfc6455.txt)\]
* mailto \[[RFC 6068](http://www.ietf.org/rfc/rfc6068.txt)\]
* urn \[[RFC 2141](http://www.ietf.org/rfc/rfc2141.txt)\]
* urn:uuid \[[RFC 4122](http://www.ietf.org/rfc/rfc4122.txt)\]
### HTTP/HTTPS Support
URI.equal("HTTP://ABC.COM:80", "http://abc.com/") === true
URI.equal("https://abc.com", "HTTPS://ABC.COM:443/") === true
### WS/WSS Support
URI.parse("wss://example.com/foo?bar=baz");
//returns:
//{
// scheme : "wss",
// host: "example.com",
// resourceName: "/foo?bar=baz",
// secure: true,
//}
URI.equal("WS://ABC.COM:80/chat#one", "ws://abc.com/chat") === true
### Mailto Support
URI.parse("mailto:alpha@example.com,bravo@example.com?subject=SUBSCRIBE&body=Sign%20me%20up!");
//returns:
//{
// scheme : "mailto",
// to : ["alpha@example.com", "bravo@example.com"],
// subject : "SUBSCRIBE",
// body : "Sign me up!"
//}
URI.serialize({
scheme : "mailto",
to : ["alpha@example.com"],
subject : "REMOVE",
body : "Please remove me",
headers : {
cc : "charlie@example.com"
}
}) === "mailto:alpha@example.com?cc=charlie@example.com&subject=REMOVE&body=Please%20remove%20me"
### URN Support
URI.parse("urn:example:foo");
//returns:
//{
// scheme : "urn",
// nid : "example",
// nss : "foo",
//}
#### URN UUID Support
URI.parse("urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6");
//returns:
//{
// scheme : "urn",
// nid : "uuid",
// uuid : "f81d4fae-7dec-11d0-a765-00a0c91e6bf6",
//}
## Usage
To load in a browser, use the following tag:
<script type="text/javascript" src="uri-js/dist/es5/uri.all.min.js"></script>
To load in a CommonJS/Module environment, first install with npm/yarn by running on the command line:
npm install uri-js
# OR
yarn add uri-js
Then, in your code, load it using:
const URI = require("uri-js");
If you are writing your code in ES6+ (ESNEXT) or TypeScript, you would load it using:
import * as URI from "uri-js";
Or you can load just what you need using named exports:
import { parse, serialize, resolve, resolveComponents, normalize, equal, removeDotSegments, pctEncChar, pctDecChars, escapeComponent, unescapeComponent } from "uri-js";
## Breaking changes
### Breaking changes from 3.x
URN parsing has been completely changed to better align with the specification. Scheme is now always `urn`, but has two new properties: `nid` which contains the Namspace Identifier, and `nss` which contains the Namespace Specific String. The `nss` property will be removed by higher order scheme handlers, such as the UUID URN scheme handler.
The UUID of a URN can now be found in the `uuid` property.
### Breaking changes from 2.x
URI validation has been removed as it was slow, exposed a vulnerabilty, and was generally not useful.
### Breaking changes from 1.x
The `errors` array on parsed components is now an `error` string.
Generated Vendored Executable
+59
View File
@@ -0,0 +1,59 @@
export interface URIComponents {
scheme?: string;
userinfo?: string;
host?: string;
port?: number | string;
path?: string;
query?: string;
fragment?: string;
reference?: string;
error?: string;
}
export interface URIOptions {
scheme?: string;
reference?: string;
tolerant?: boolean;
absolutePath?: boolean;
iri?: boolean;
unicodeSupport?: boolean;
domainHost?: boolean;
}
export interface URISchemeHandler<Components extends URIComponents = URIComponents, Options extends URIOptions = URIOptions, ParentComponents extends URIComponents = URIComponents> {
scheme: string;
parse(components: ParentComponents, options: Options): Components;
serialize(components: Components, options: Options): ParentComponents;
unicodeSupport?: boolean;
domainHost?: boolean;
absolutePath?: boolean;
}
export interface URIRegExps {
NOT_SCHEME: RegExp;
NOT_USERINFO: RegExp;
NOT_HOST: RegExp;
NOT_PATH: RegExp;
NOT_PATH_NOSCHEME: RegExp;
NOT_QUERY: RegExp;
NOT_FRAGMENT: RegExp;
ESCAPE: RegExp;
UNRESERVED: RegExp;
OTHER_CHARS: RegExp;
PCT_ENCODED: RegExp;
IPV4ADDRESS: RegExp;
IPV6ADDRESS: RegExp;
}
export declare const SCHEMES: {
[scheme: string]: URISchemeHandler;
};
export declare function pctEncChar(chr: string): string;
export declare function pctDecChars(str: string): string;
export declare function parse(uriString: string, options?: URIOptions): URIComponents;
export declare function removeDotSegments(input: string): string;
export declare function serialize(components: URIComponents, options?: URIOptions): string;
export declare function resolveComponents(base: URIComponents, relative: URIComponents, options?: URIOptions, skipNormalization?: boolean): URIComponents;
export declare function resolve(baseURI: string, relativeURI: string, options?: URIOptions): string;
export declare function normalize(uri: string, options?: URIOptions): string;
export declare function normalize(uri: URIComponents, options?: URIOptions): URIComponents;
export declare function equal(uriA: string, uriB: string, options?: URIOptions): boolean;
export declare function equal(uriA: URIComponents, uriB: URIComponents, options?: URIOptions): boolean;
export declare function escapeComponent(str: string, options?: URIOptions): string;
export declare function unescapeComponent(str: string, options?: URIOptions): string;
Generated Vendored Executable
+1443
View File
File diff suppressed because it is too large Load Diff
Generated Vendored Executable
+1
View File
File diff suppressed because one or more lines are too long
+59
View File
@@ -0,0 +1,59 @@
export interface URIComponents {
scheme?: string;
userinfo?: string;
host?: string;
port?: number | string;
path?: string;
query?: string;
fragment?: string;
reference?: string;
error?: string;
}
export interface URIOptions {
scheme?: string;
reference?: string;
tolerant?: boolean;
absolutePath?: boolean;
iri?: boolean;
unicodeSupport?: boolean;
domainHost?: boolean;
}
export interface URISchemeHandler<Components extends URIComponents = URIComponents, Options extends URIOptions = URIOptions, ParentComponents extends URIComponents = URIComponents> {
scheme: string;
parse(components: ParentComponents, options: Options): Components;
serialize(components: Components, options: Options): ParentComponents;
unicodeSupport?: boolean;
domainHost?: boolean;
absolutePath?: boolean;
}
export interface URIRegExps {
NOT_SCHEME: RegExp;
NOT_USERINFO: RegExp;
NOT_HOST: RegExp;
NOT_PATH: RegExp;
NOT_PATH_NOSCHEME: RegExp;
NOT_QUERY: RegExp;
NOT_FRAGMENT: RegExp;
ESCAPE: RegExp;
UNRESERVED: RegExp;
OTHER_CHARS: RegExp;
PCT_ENCODED: RegExp;
IPV4ADDRESS: RegExp;
IPV6ADDRESS: RegExp;
}
export declare const SCHEMES: {
[scheme: string]: URISchemeHandler;
};
export declare function pctEncChar(chr: string): string;
export declare function pctDecChars(str: string): string;
export declare function parse(uriString: string, options?: URIOptions): URIComponents;
export declare function removeDotSegments(input: string): string;
export declare function serialize(components: URIComponents, options?: URIOptions): string;
export declare function resolveComponents(base: URIComponents, relative: URIComponents, options?: URIOptions, skipNormalization?: boolean): URIComponents;
export declare function resolve(baseURI: string, relativeURI: string, options?: URIOptions): string;
export declare function normalize(uri: string, options?: URIOptions): string;
export declare function normalize(uri: URIComponents, options?: URIOptions): URIComponents;
export declare function equal(uriA: string, uriB: string, options?: URIOptions): boolean;
export declare function equal(uriA: URIComponents, uriB: URIComponents, options?: URIOptions): boolean;
export declare function escapeComponent(str: string, options?: URIOptions): string;
export declare function unescapeComponent(str: string, options?: URIOptions): string;
Generated Vendored Executable
+3
View File
File diff suppressed because one or more lines are too long
+1
View File
File diff suppressed because one or more lines are too long
Generated Vendored Executable
+1
View File
@@ -0,0 +1 @@
export * from "./uri";
Generated Vendored Executable
+17
View File
@@ -0,0 +1,17 @@
import { SCHEMES } from "./uri";
import http from "./schemes/http";
SCHEMES[http.scheme] = http;
import https from "./schemes/https";
SCHEMES[https.scheme] = https;
import ws from "./schemes/ws";
SCHEMES[ws.scheme] = ws;
import wss from "./schemes/wss";
SCHEMES[wss.scheme] = wss;
import mailto from "./schemes/mailto";
SCHEMES[mailto.scheme] = mailto;
import urn from "./schemes/urn";
SCHEMES[urn.scheme] = urn;
import uuid from "./schemes/urn-uuid";
SCHEMES[uuid.scheme] = uuid;
export * from "./uri";
//# sourceMappingURL=index.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAEhC,OAAO,IAAI,MAAM,gBAAgB,CAAC;AAClC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;AAE5B,OAAO,KAAK,MAAM,iBAAiB,CAAC;AACpC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC;AAE9B,OAAO,EAAE,MAAM,cAAc,CAAC;AAC9B,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;AAExB,OAAO,GAAG,MAAM,eAAe,CAAC;AAChC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC;AAE1B,OAAO,MAAM,MAAM,kBAAkB,CAAC;AACtC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;AAEhC,OAAO,GAAG,MAAM,eAAe,CAAC;AAChC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC;AAE1B,OAAO,IAAI,MAAM,oBAAoB,CAAC;AACtC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;AAE5B,cAAc,OAAO,CAAC"}

Some files were not shown because too many files have changed in this diff Show More