new license file version [CI SKIP]
This commit is contained in:
@@ -0,0 +1 @@
|
||||
import 'rxjs-compat/add/operator/share';
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"single.js","sources":["../src/operator/single.ts"],"names":[],"mappings":";;;;;AAAA,iDAA4C"}
|
||||
@@ -0,0 +1 @@
|
||||
import 'rxjs-compat/add/observable/concat';
|
||||
@@ -0,0 +1,7 @@
|
||||
"use strict";
|
||||
function __export(m) {
|
||||
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
|
||||
}
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
__export(require("rxjs-compat/util/ArgumentOutOfRangeError"));
|
||||
//# sourceMappingURL=ArgumentOutOfRangeError.js.map
|
||||
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"name": "import-lazy",
|
||||
"version": "2.1.0",
|
||||
"description": "Import modules lazily",
|
||||
"license": "MIT",
|
||||
"repository": "sindresorhus/import-lazy",
|
||||
"author": {
|
||||
"name": "Sindre Sorhus",
|
||||
"email": "sindresorhus@gmail.com",
|
||||
"url": "sindresorhus.com"
|
||||
},
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Jorge Bucaran",
|
||||
"email": "jbucaran@me.com"
|
||||
}
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "xo && ava"
|
||||
},
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"keywords": [
|
||||
"import",
|
||||
"require",
|
||||
"load",
|
||||
"module",
|
||||
"modules",
|
||||
"lazy",
|
||||
"lazily",
|
||||
"defer",
|
||||
"deferred",
|
||||
"proxy",
|
||||
"proxies"
|
||||
],
|
||||
"devDependencies": {
|
||||
"ava": "*",
|
||||
"xo": "*"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import { AsyncAction } from './AsyncAction';
|
||||
import { AsyncScheduler } from './AsyncScheduler';
|
||||
|
||||
export class AsapScheduler extends AsyncScheduler {
|
||||
public flush(action?: AsyncAction<any>): void {
|
||||
|
||||
this.active = true;
|
||||
this.scheduled = undefined;
|
||||
|
||||
const {actions} = this;
|
||||
let error: any;
|
||||
let index: number = -1;
|
||||
let count: number = actions.length;
|
||||
action = action || actions.shift();
|
||||
|
||||
do {
|
||||
if (error = action.execute(action.state, action.delay)) {
|
||||
break;
|
||||
}
|
||||
} while (++index < count && (action = actions.shift()));
|
||||
|
||||
this.active = false;
|
||||
|
||||
if (error) {
|
||||
while (++index < count && (action = actions.shift())) {
|
||||
action.unsubscribe();
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
{
|
||||
"name": "globby",
|
||||
"version": "11.0.3",
|
||||
"description": "User-friendly glob matching",
|
||||
"license": "MIT",
|
||||
"repository": "sindresorhus/globby",
|
||||
"funding": "https://github.com/sponsors/sindresorhus",
|
||||
"author": {
|
||||
"email": "sindresorhus@gmail.com",
|
||||
"name": "Sindre Sorhus",
|
||||
"url": "https://sindresorhus.com"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"scripts": {
|
||||
"bench": "npm update glob-stream fast-glob && matcha bench.js",
|
||||
"test": "xo && ava && tsd"
|
||||
},
|
||||
"files": [
|
||||
"index.js",
|
||||
"index.d.ts",
|
||||
"gitignore.js",
|
||||
"stream-utils.js"
|
||||
],
|
||||
"keywords": [
|
||||
"all",
|
||||
"array",
|
||||
"directories",
|
||||
"expand",
|
||||
"files",
|
||||
"filesystem",
|
||||
"filter",
|
||||
"find",
|
||||
"fnmatch",
|
||||
"folders",
|
||||
"fs",
|
||||
"glob",
|
||||
"globbing",
|
||||
"globs",
|
||||
"gulpfriendly",
|
||||
"match",
|
||||
"matcher",
|
||||
"minimatch",
|
||||
"multi",
|
||||
"multiple",
|
||||
"paths",
|
||||
"pattern",
|
||||
"patterns",
|
||||
"traverse",
|
||||
"util",
|
||||
"utility",
|
||||
"wildcard",
|
||||
"wildcards",
|
||||
"promise",
|
||||
"gitignore",
|
||||
"git"
|
||||
],
|
||||
"dependencies": {
|
||||
"array-union": "^2.1.0",
|
||||
"dir-glob": "^3.0.1",
|
||||
"fast-glob": "^3.1.1",
|
||||
"ignore": "^5.1.4",
|
||||
"merge2": "^1.3.0",
|
||||
"slash": "^3.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"ava": "^3.13.0",
|
||||
"get-stream": "^6.0.0",
|
||||
"glob-stream": "^6.1.0",
|
||||
"globby": "sindresorhus/globby#main",
|
||||
"matcha": "^0.7.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"tsd": "^0.13.1",
|
||||
"xo": "^0.33.1"
|
||||
},
|
||||
"xo": {
|
||||
"ignores": [
|
||||
"fixtures"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from 'rxjs-compat/observable/generate';
|
||||
@@ -0,0 +1 @@
|
||||
module.exports={A:{A:{"2":"J E F G A B BC"},B:{"2":"C K L H M","164":"P Q R S T U V W X Y Z a b c d f g h i j k l m n o p q r s D t","3138":"N","12292":"O"},C:{"1":"TB UB VB WB XB YB uB ZB vB aB bB cB dB eB fB gB hB iB jB kB e lB mB nB oB pB P Q R wB S T U V W X Y Z a b c d f g h i j k l m n o p q r s D t xB yB","2":"CC tB","260":"0 1 2 3 4 5 6 7 8 9 I u J E F G A B C K L H M N O v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB DC EC"},D:{"164":"0 1 2 3 4 5 6 7 8 9 I u J E F G A B C K L H M N O v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB VB WB XB YB uB ZB vB aB bB cB dB eB fB gB hB iB jB kB e lB mB nB oB pB P Q R S T U V W X Y Z a b c d f g h i j k l m n o p q r s D t xB yB FC"},E:{"1":"3B 4B 5B sB 6B 7B 8B NC","2":"GC zB","164":"I u J E F G A B C K L H HC IC JC KC 0B qB rB 1B LC MC 2B"},F:{"2":"G B C OC PC QC RC qB 9B SC rB","164":"0 1 2 3 4 5 6 7 8 9 H M N O v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB VB WB XB YB ZB aB bB cB dB eB fB gB hB iB jB kB e lB mB nB oB pB P Q R wB S T U V W X Y Z a b c d"},G:{"1":"3B 4B 5B sB 6B 7B 8B","164":"F zB TC AC UC VC WC XC YC ZC aC bC cC dC eC fC gC hC iC jC kC lC mC 2B"},H:{"2":"nC"},I:{"164":"D sC tC","676":"tB I oC pC qC rC AC"},J:{"164":"E A"},K:{"2":"A B C qB 9B rB","164":"e"},L:{"164":"D"},M:{"1":"D"},N:{"2":"A B"},O:{"164":"uC"},P:{"164":"I vC wC xC yC zC 0B 0C 1C 2C 3C 4C sB 5C 6C 7C"},Q:{"164":"1B"},R:{"164":"8C"},S:{"260":"9C"}},B:4,C:"CSS Masks"};
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"subscribeToResult.js","sources":["../src/util/subscribeToResult.ts"],"names":[],"mappings":";;;;;AAAA,wDAAmD"}
|
||||
@@ -0,0 +1 @@
|
||||
export * from 'rxjs-compat/Observer';
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"timestamp.js","sources":["../../../src/internal/operators/timestamp.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAoC5B,MAAM,UAAU,SAAS,CAAI,YAA2B,KAAK;IAC3D,OAAO,GAAG,CAAC,CAAC,KAAQ,EAAE,EAAE,CAAC,IAAI,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;AAElE,CAAC;AAED,MAAM,OAAO,SAAS;IACpB,YAAmB,KAAQ,EAAS,SAAiB;QAAlC,UAAK,GAAL,KAAK,CAAG;QAAS,cAAS,GAAT,SAAS,CAAQ;IACrD,CAAC;CACF"}
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Observable } from '../Observable';
|
||||
import { from } from './from';
|
||||
import { empty } from './empty';
|
||||
export function defer(observableFactory) {
|
||||
return new Observable(subscriber => {
|
||||
let input;
|
||||
try {
|
||||
input = observableFactory();
|
||||
}
|
||||
catch (err) {
|
||||
subscriber.error(err);
|
||||
return undefined;
|
||||
}
|
||||
const source = input ? from(input) : empty();
|
||||
return source.subscribe(subscriber);
|
||||
});
|
||||
}
|
||||
//# sourceMappingURL=defer.js.map
|
||||
@@ -0,0 +1,559 @@
|
||||
'use strict'
|
||||
|
||||
let Declaration = require('./declaration')
|
||||
let tokenizer = require('./tokenize')
|
||||
let Comment = require('./comment')
|
||||
let AtRule = require('./at-rule')
|
||||
let Root = require('./root')
|
||||
let Rule = require('./rule')
|
||||
|
||||
class Parser {
|
||||
constructor(input) {
|
||||
this.input = input
|
||||
|
||||
this.root = new Root()
|
||||
this.current = this.root
|
||||
this.spaces = ''
|
||||
this.semicolon = false
|
||||
this.customProperty = false
|
||||
|
||||
this.createTokenizer()
|
||||
this.root.source = { input, start: { offset: 0, line: 1, column: 1 } }
|
||||
}
|
||||
|
||||
createTokenizer() {
|
||||
this.tokenizer = tokenizer(this.input)
|
||||
}
|
||||
|
||||
parse() {
|
||||
let token
|
||||
while (!this.tokenizer.endOfFile()) {
|
||||
token = this.tokenizer.nextToken()
|
||||
|
||||
switch (token[0]) {
|
||||
case 'space':
|
||||
this.spaces += token[1]
|
||||
break
|
||||
|
||||
case ';':
|
||||
this.freeSemicolon(token)
|
||||
break
|
||||
|
||||
case '}':
|
||||
this.end(token)
|
||||
break
|
||||
|
||||
case 'comment':
|
||||
this.comment(token)
|
||||
break
|
||||
|
||||
case 'at-word':
|
||||
this.atrule(token)
|
||||
break
|
||||
|
||||
case '{':
|
||||
this.emptyRule(token)
|
||||
break
|
||||
|
||||
default:
|
||||
this.other(token)
|
||||
break
|
||||
}
|
||||
}
|
||||
this.endFile()
|
||||
}
|
||||
|
||||
comment(token) {
|
||||
let node = new Comment()
|
||||
this.init(node, token[2])
|
||||
node.source.end = this.getPosition(token[3] || token[2])
|
||||
|
||||
let text = token[1].slice(2, -2)
|
||||
if (/^\s*$/.test(text)) {
|
||||
node.text = ''
|
||||
node.raws.left = text
|
||||
node.raws.right = ''
|
||||
} else {
|
||||
let match = text.match(/^(\s*)([^]*\S)(\s*)$/)
|
||||
node.text = match[2]
|
||||
node.raws.left = match[1]
|
||||
node.raws.right = match[3]
|
||||
}
|
||||
}
|
||||
|
||||
emptyRule(token) {
|
||||
let node = new Rule()
|
||||
this.init(node, token[2])
|
||||
node.selector = ''
|
||||
node.raws.between = ''
|
||||
this.current = node
|
||||
}
|
||||
|
||||
other(start) {
|
||||
let end = false
|
||||
let type = null
|
||||
let colon = false
|
||||
let bracket = null
|
||||
let brackets = []
|
||||
let customProperty = start[1].startsWith('--')
|
||||
|
||||
let tokens = []
|
||||
let token = start
|
||||
while (token) {
|
||||
type = token[0]
|
||||
tokens.push(token)
|
||||
|
||||
if (type === '(' || type === '[') {
|
||||
if (!bracket) bracket = token
|
||||
brackets.push(type === '(' ? ')' : ']')
|
||||
} else if (customProperty && colon && type === '{') {
|
||||
if (!bracket) bracket = token
|
||||
brackets.push('}')
|
||||
} else if (brackets.length === 0) {
|
||||
if (type === ';') {
|
||||
if (colon) {
|
||||
this.decl(tokens, customProperty)
|
||||
return
|
||||
} else {
|
||||
break
|
||||
}
|
||||
} else if (type === '{') {
|
||||
this.rule(tokens)
|
||||
return
|
||||
} else if (type === '}') {
|
||||
this.tokenizer.back(tokens.pop())
|
||||
end = true
|
||||
break
|
||||
} else if (type === ':') {
|
||||
colon = true
|
||||
}
|
||||
} else if (type === brackets[brackets.length - 1]) {
|
||||
brackets.pop()
|
||||
if (brackets.length === 0) bracket = null
|
||||
}
|
||||
|
||||
token = this.tokenizer.nextToken()
|
||||
}
|
||||
|
||||
if (this.tokenizer.endOfFile()) end = true
|
||||
if (brackets.length > 0) this.unclosedBracket(bracket)
|
||||
|
||||
if (end && colon) {
|
||||
while (tokens.length) {
|
||||
token = tokens[tokens.length - 1][0]
|
||||
if (token !== 'space' && token !== 'comment') break
|
||||
this.tokenizer.back(tokens.pop())
|
||||
}
|
||||
this.decl(tokens, customProperty)
|
||||
} else {
|
||||
this.unknownWord(tokens)
|
||||
}
|
||||
}
|
||||
|
||||
rule(tokens) {
|
||||
tokens.pop()
|
||||
|
||||
let node = new Rule()
|
||||
this.init(node, tokens[0][2])
|
||||
|
||||
node.raws.between = this.spacesAndCommentsFromEnd(tokens)
|
||||
this.raw(node, 'selector', tokens)
|
||||
this.current = node
|
||||
}
|
||||
|
||||
decl(tokens, customProperty) {
|
||||
let node = new Declaration()
|
||||
this.init(node, tokens[0][2])
|
||||
|
||||
let last = tokens[tokens.length - 1]
|
||||
if (last[0] === ';') {
|
||||
this.semicolon = true
|
||||
tokens.pop()
|
||||
}
|
||||
node.source.end = this.getPosition(last[3] || last[2])
|
||||
|
||||
while (tokens[0][0] !== 'word') {
|
||||
if (tokens.length === 1) this.unknownWord(tokens)
|
||||
node.raws.before += tokens.shift()[1]
|
||||
}
|
||||
node.source.start = this.getPosition(tokens[0][2])
|
||||
|
||||
node.prop = ''
|
||||
while (tokens.length) {
|
||||
let type = tokens[0][0]
|
||||
if (type === ':' || type === 'space' || type === 'comment') {
|
||||
break
|
||||
}
|
||||
node.prop += tokens.shift()[1]
|
||||
}
|
||||
|
||||
node.raws.between = ''
|
||||
|
||||
let token
|
||||
while (tokens.length) {
|
||||
token = tokens.shift()
|
||||
|
||||
if (token[0] === ':') {
|
||||
node.raws.between += token[1]
|
||||
break
|
||||
} else {
|
||||
if (token[0] === 'word' && /\w/.test(token[1])) {
|
||||
this.unknownWord([token])
|
||||
}
|
||||
node.raws.between += token[1]
|
||||
}
|
||||
}
|
||||
|
||||
if (node.prop[0] === '_' || node.prop[0] === '*') {
|
||||
node.raws.before += node.prop[0]
|
||||
node.prop = node.prop.slice(1)
|
||||
}
|
||||
let firstSpaces = this.spacesAndCommentsFromStart(tokens)
|
||||
this.precheckMissedSemicolon(tokens)
|
||||
|
||||
for (let i = tokens.length - 1; i >= 0; i--) {
|
||||
token = tokens[i]
|
||||
if (token[1].toLowerCase() === '!important') {
|
||||
node.important = true
|
||||
let string = this.stringFrom(tokens, i)
|
||||
string = this.spacesFromEnd(tokens) + string
|
||||
if (string !== ' !important') node.raws.important = string
|
||||
break
|
||||
} else if (token[1].toLowerCase() === 'important') {
|
||||
let cache = tokens.slice(0)
|
||||
let str = ''
|
||||
for (let j = i; j > 0; j--) {
|
||||
let type = cache[j][0]
|
||||
if (str.trim().indexOf('!') === 0 && type !== 'space') {
|
||||
break
|
||||
}
|
||||
str = cache.pop()[1] + str
|
||||
}
|
||||
if (str.trim().indexOf('!') === 0) {
|
||||
node.important = true
|
||||
node.raws.important = str
|
||||
tokens = cache
|
||||
}
|
||||
}
|
||||
|
||||
if (token[0] !== 'space' && token[0] !== 'comment') {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
let hasWord = tokens.some(i => i[0] !== 'space' && i[0] !== 'comment')
|
||||
this.raw(node, 'value', tokens)
|
||||
if (hasWord) {
|
||||
node.raws.between += firstSpaces
|
||||
} else {
|
||||
node.value = firstSpaces + node.value
|
||||
}
|
||||
|
||||
if (node.value.includes(':') && !customProperty) {
|
||||
this.checkMissedSemicolon(tokens)
|
||||
}
|
||||
}
|
||||
|
||||
atrule(token) {
|
||||
let node = new AtRule()
|
||||
node.name = token[1].slice(1)
|
||||
if (node.name === '') {
|
||||
this.unnamedAtrule(node, token)
|
||||
}
|
||||
this.init(node, token[2])
|
||||
|
||||
let type
|
||||
let prev
|
||||
let shift
|
||||
let last = false
|
||||
let open = false
|
||||
let params = []
|
||||
let brackets = []
|
||||
|
||||
while (!this.tokenizer.endOfFile()) {
|
||||
token = this.tokenizer.nextToken()
|
||||
type = token[0]
|
||||
|
||||
if (type === '(' || type === '[') {
|
||||
brackets.push(type === '(' ? ')' : ']')
|
||||
} else if (type === '{' && brackets.length > 0) {
|
||||
brackets.push('}')
|
||||
} else if (type === brackets[brackets.length - 1]) {
|
||||
brackets.pop()
|
||||
}
|
||||
|
||||
if (brackets.length === 0) {
|
||||
if (type === ';') {
|
||||
node.source.end = this.getPosition(token[2])
|
||||
this.semicolon = true
|
||||
break
|
||||
} else if (type === '{') {
|
||||
open = true
|
||||
break
|
||||
} else if (type === '}') {
|
||||
if (params.length > 0) {
|
||||
shift = params.length - 1
|
||||
prev = params[shift]
|
||||
while (prev && prev[0] === 'space') {
|
||||
prev = params[--shift]
|
||||
}
|
||||
if (prev) {
|
||||
node.source.end = this.getPosition(prev[3] || prev[2])
|
||||
}
|
||||
}
|
||||
this.end(token)
|
||||
break
|
||||
} else {
|
||||
params.push(token)
|
||||
}
|
||||
} else {
|
||||
params.push(token)
|
||||
}
|
||||
|
||||
if (this.tokenizer.endOfFile()) {
|
||||
last = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
node.raws.between = this.spacesAndCommentsFromEnd(params)
|
||||
if (params.length) {
|
||||
node.raws.afterName = this.spacesAndCommentsFromStart(params)
|
||||
this.raw(node, 'params', params)
|
||||
if (last) {
|
||||
token = params[params.length - 1]
|
||||
node.source.end = this.getPosition(token[3] || token[2])
|
||||
this.spaces = node.raws.between
|
||||
node.raws.between = ''
|
||||
}
|
||||
} else {
|
||||
node.raws.afterName = ''
|
||||
node.params = ''
|
||||
}
|
||||
|
||||
if (open) {
|
||||
node.nodes = []
|
||||
this.current = node
|
||||
}
|
||||
}
|
||||
|
||||
end(token) {
|
||||
if (this.current.nodes && this.current.nodes.length) {
|
||||
this.current.raws.semicolon = this.semicolon
|
||||
}
|
||||
this.semicolon = false
|
||||
|
||||
this.current.raws.after = (this.current.raws.after || '') + this.spaces
|
||||
this.spaces = ''
|
||||
|
||||
if (this.current.parent) {
|
||||
this.current.source.end = this.getPosition(token[2])
|
||||
this.current = this.current.parent
|
||||
} else {
|
||||
this.unexpectedClose(token)
|
||||
}
|
||||
}
|
||||
|
||||
endFile() {
|
||||
if (this.current.parent) this.unclosedBlock()
|
||||
if (this.current.nodes && this.current.nodes.length) {
|
||||
this.current.raws.semicolon = this.semicolon
|
||||
}
|
||||
this.current.raws.after = (this.current.raws.after || '') + this.spaces
|
||||
}
|
||||
|
||||
freeSemicolon(token) {
|
||||
this.spaces += token[1]
|
||||
if (this.current.nodes) {
|
||||
let prev = this.current.nodes[this.current.nodes.length - 1]
|
||||
if (prev && prev.type === 'rule' && !prev.raws.ownSemicolon) {
|
||||
prev.raws.ownSemicolon = this.spaces
|
||||
this.spaces = ''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Helpers
|
||||
|
||||
getPosition(offset) {
|
||||
let pos = this.input.fromOffset(offset)
|
||||
return {
|
||||
offset,
|
||||
line: pos.line,
|
||||
column: pos.col
|
||||
}
|
||||
}
|
||||
|
||||
init(node, offset) {
|
||||
this.current.push(node)
|
||||
node.source = {
|
||||
start: this.getPosition(offset),
|
||||
input: this.input
|
||||
}
|
||||
node.raws.before = this.spaces
|
||||
this.spaces = ''
|
||||
if (node.type !== 'comment') this.semicolon = false
|
||||
}
|
||||
|
||||
raw(node, prop, tokens) {
|
||||
let token, type
|
||||
let length = tokens.length
|
||||
let value = ''
|
||||
let clean = true
|
||||
let next, prev
|
||||
let pattern = /^([#.|])?(\w)+/i
|
||||
|
||||
for (let i = 0; i < length; i += 1) {
|
||||
token = tokens[i]
|
||||
type = token[0]
|
||||
|
||||
if (type === 'comment' && node.type === 'rule') {
|
||||
prev = tokens[i - 1]
|
||||
next = tokens[i + 1]
|
||||
|
||||
if (
|
||||
prev[0] !== 'space' &&
|
||||
next[0] !== 'space' &&
|
||||
pattern.test(prev[1]) &&
|
||||
pattern.test(next[1])
|
||||
) {
|
||||
value += token[1]
|
||||
} else {
|
||||
clean = false
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
if (type === 'comment' || (type === 'space' && i === length - 1)) {
|
||||
clean = false
|
||||
} else {
|
||||
value += token[1]
|
||||
}
|
||||
}
|
||||
if (!clean) {
|
||||
let raw = tokens.reduce((all, i) => all + i[1], '')
|
||||
node.raws[prop] = { value, raw }
|
||||
}
|
||||
node[prop] = value
|
||||
}
|
||||
|
||||
spacesAndCommentsFromEnd(tokens) {
|
||||
let lastTokenType
|
||||
let spaces = ''
|
||||
while (tokens.length) {
|
||||
lastTokenType = tokens[tokens.length - 1][0]
|
||||
if (lastTokenType !== 'space' && lastTokenType !== 'comment') break
|
||||
spaces = tokens.pop()[1] + spaces
|
||||
}
|
||||
return spaces
|
||||
}
|
||||
|
||||
spacesAndCommentsFromStart(tokens) {
|
||||
let next
|
||||
let spaces = ''
|
||||
while (tokens.length) {
|
||||
next = tokens[0][0]
|
||||
if (next !== 'space' && next !== 'comment') break
|
||||
spaces += tokens.shift()[1]
|
||||
}
|
||||
return spaces
|
||||
}
|
||||
|
||||
spacesFromEnd(tokens) {
|
||||
let lastTokenType
|
||||
let spaces = ''
|
||||
while (tokens.length) {
|
||||
lastTokenType = tokens[tokens.length - 1][0]
|
||||
if (lastTokenType !== 'space') break
|
||||
spaces = tokens.pop()[1] + spaces
|
||||
}
|
||||
return spaces
|
||||
}
|
||||
|
||||
stringFrom(tokens, from) {
|
||||
let result = ''
|
||||
for (let i = from; i < tokens.length; i++) {
|
||||
result += tokens[i][1]
|
||||
}
|
||||
tokens.splice(from, tokens.length - from)
|
||||
return result
|
||||
}
|
||||
|
||||
colon(tokens) {
|
||||
let brackets = 0
|
||||
let token, type, prev
|
||||
for (let [i, element] of tokens.entries()) {
|
||||
token = element
|
||||
type = token[0]
|
||||
|
||||
if (type === '(') {
|
||||
brackets += 1
|
||||
}
|
||||
if (type === ')') {
|
||||
brackets -= 1
|
||||
}
|
||||
if (brackets === 0 && type === ':') {
|
||||
if (!prev) {
|
||||
this.doubleColon(token)
|
||||
} else if (prev[0] === 'word' && prev[1] === 'progid') {
|
||||
continue
|
||||
} else {
|
||||
return i
|
||||
}
|
||||
}
|
||||
|
||||
prev = token
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Errors
|
||||
|
||||
unclosedBracket(bracket) {
|
||||
throw this.input.error('Unclosed bracket', bracket[2])
|
||||
}
|
||||
|
||||
unknownWord(tokens) {
|
||||
throw this.input.error('Unknown word', tokens[0][2])
|
||||
}
|
||||
|
||||
unexpectedClose(token) {
|
||||
throw this.input.error('Unexpected }', token[2])
|
||||
}
|
||||
|
||||
unclosedBlock() {
|
||||
let pos = this.current.source.start
|
||||
throw this.input.error('Unclosed block', pos.line, pos.column)
|
||||
}
|
||||
|
||||
doubleColon(token) {
|
||||
throw this.input.error('Double colon', token[2])
|
||||
}
|
||||
|
||||
unnamedAtrule(node, token) {
|
||||
throw this.input.error('At-rule without name', token[2])
|
||||
}
|
||||
|
||||
precheckMissedSemicolon(/* tokens */) {
|
||||
// Hook for Safe Parser
|
||||
}
|
||||
|
||||
checkMissedSemicolon(tokens) {
|
||||
let colon = this.colon(tokens)
|
||||
if (colon === false) return
|
||||
|
||||
let founded = 0
|
||||
let token
|
||||
for (let j = colon - 1; j >= 0; j--) {
|
||||
token = tokens[j]
|
||||
if (token[0] !== 'space') {
|
||||
founded += 1
|
||||
if (founded === 2) break
|
||||
}
|
||||
}
|
||||
throw this.input.error('Missed semicolon', token[2])
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Parser
|
||||
@@ -0,0 +1,15 @@
|
||||
import { Observable } from '../Observable';
|
||||
import { BehaviorSubject } from '../BehaviorSubject';
|
||||
import { multicast } from './multicast';
|
||||
import { ConnectableObservable } from '../observable/ConnectableObservable';
|
||||
import { UnaryFunction } from '../types';
|
||||
|
||||
/**
|
||||
* @param value
|
||||
* @return {ConnectableObservable<T>}
|
||||
* @method publishBehavior
|
||||
* @owner Observable
|
||||
*/
|
||||
export function publishBehavior<T>(value: T): UnaryFunction<Observable<T>, ConnectableObservable<T>> {
|
||||
return (source: Observable<T>) => multicast(new BehaviorSubject<T>(value))(source) as ConnectableObservable<T>;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
import 'rxjs-compat/add/operator/concatMap';
|
||||
@@ -0,0 +1,501 @@
|
||||
var CombinedStream = require('combined-stream');
|
||||
var util = require('util');
|
||||
var path = require('path');
|
||||
var http = require('http');
|
||||
var https = require('https');
|
||||
var parseUrl = require('url').parse;
|
||||
var fs = require('fs');
|
||||
var Stream = require('stream').Stream;
|
||||
var mime = require('mime-types');
|
||||
var asynckit = require('asynckit');
|
||||
var populate = require('./populate.js');
|
||||
|
||||
// Public API
|
||||
module.exports = FormData;
|
||||
|
||||
// make it a Stream
|
||||
util.inherits(FormData, CombinedStream);
|
||||
|
||||
/**
|
||||
* Create readable "multipart/form-data" streams.
|
||||
* Can be used to submit forms
|
||||
* and file uploads to other web applications.
|
||||
*
|
||||
* @constructor
|
||||
* @param {Object} options - Properties to be added/overriden for FormData and CombinedStream
|
||||
*/
|
||||
function FormData(options) {
|
||||
if (!(this instanceof FormData)) {
|
||||
return new FormData(options);
|
||||
}
|
||||
|
||||
this._overheadLength = 0;
|
||||
this._valueLength = 0;
|
||||
this._valuesToMeasure = [];
|
||||
|
||||
CombinedStream.call(this);
|
||||
|
||||
options = options || {};
|
||||
for (var option in options) {
|
||||
this[option] = options[option];
|
||||
}
|
||||
}
|
||||
|
||||
FormData.LINE_BREAK = '\r\n';
|
||||
FormData.DEFAULT_CONTENT_TYPE = 'application/octet-stream';
|
||||
|
||||
FormData.prototype.append = function(field, value, options) {
|
||||
|
||||
options = options || {};
|
||||
|
||||
// allow filename as single option
|
||||
if (typeof options == 'string') {
|
||||
options = {filename: options};
|
||||
}
|
||||
|
||||
var append = CombinedStream.prototype.append.bind(this);
|
||||
|
||||
// all that streamy business can't handle numbers
|
||||
if (typeof value == 'number') {
|
||||
value = '' + value;
|
||||
}
|
||||
|
||||
// https://github.com/felixge/node-form-data/issues/38
|
||||
if (util.isArray(value)) {
|
||||
// Please convert your array into string
|
||||
// the way web server expects it
|
||||
this._error(new Error('Arrays are not supported.'));
|
||||
return;
|
||||
}
|
||||
|
||||
var header = this._multiPartHeader(field, value, options);
|
||||
var footer = this._multiPartFooter();
|
||||
|
||||
append(header);
|
||||
append(value);
|
||||
append(footer);
|
||||
|
||||
// pass along options.knownLength
|
||||
this._trackLength(header, value, options);
|
||||
};
|
||||
|
||||
FormData.prototype._trackLength = function(header, value, options) {
|
||||
var valueLength = 0;
|
||||
|
||||
// used w/ getLengthSync(), when length is known.
|
||||
// e.g. for streaming directly from a remote server,
|
||||
// w/ a known file a size, and not wanting to wait for
|
||||
// incoming file to finish to get its size.
|
||||
if (options.knownLength != null) {
|
||||
valueLength += +options.knownLength;
|
||||
} else if (Buffer.isBuffer(value)) {
|
||||
valueLength = value.length;
|
||||
} else if (typeof value === 'string') {
|
||||
valueLength = Buffer.byteLength(value);
|
||||
}
|
||||
|
||||
this._valueLength += valueLength;
|
||||
|
||||
// @check why add CRLF? does this account for custom/multiple CRLFs?
|
||||
this._overheadLength +=
|
||||
Buffer.byteLength(header) +
|
||||
FormData.LINE_BREAK.length;
|
||||
|
||||
// empty or either doesn't have path or not an http response or not a stream
|
||||
if (!value || ( !value.path && !(value.readable && value.hasOwnProperty('httpVersion')) && !(value instanceof Stream))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// no need to bother with the length
|
||||
if (!options.knownLength) {
|
||||
this._valuesToMeasure.push(value);
|
||||
}
|
||||
};
|
||||
|
||||
FormData.prototype._lengthRetriever = function(value, callback) {
|
||||
|
||||
if (value.hasOwnProperty('fd')) {
|
||||
|
||||
// take read range into a account
|
||||
// `end` = Infinity –> read file till the end
|
||||
//
|
||||
// TODO: Looks like there is bug in Node fs.createReadStream
|
||||
// it doesn't respect `end` options without `start` options
|
||||
// Fix it when node fixes it.
|
||||
// https://github.com/joyent/node/issues/7819
|
||||
if (value.end != undefined && value.end != Infinity && value.start != undefined) {
|
||||
|
||||
// when end specified
|
||||
// no need to calculate range
|
||||
// inclusive, starts with 0
|
||||
callback(null, value.end + 1 - (value.start ? value.start : 0));
|
||||
|
||||
// not that fast snoopy
|
||||
} else {
|
||||
// still need to fetch file size from fs
|
||||
fs.stat(value.path, function(err, stat) {
|
||||
|
||||
var fileSize;
|
||||
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
// update final size based on the range options
|
||||
fileSize = stat.size - (value.start ? value.start : 0);
|
||||
callback(null, fileSize);
|
||||
});
|
||||
}
|
||||
|
||||
// or http response
|
||||
} else if (value.hasOwnProperty('httpVersion')) {
|
||||
callback(null, +value.headers['content-length']);
|
||||
|
||||
// or request stream http://github.com/mikeal/request
|
||||
} else if (value.hasOwnProperty('httpModule')) {
|
||||
// wait till response come back
|
||||
value.on('response', function(response) {
|
||||
value.pause();
|
||||
callback(null, +response.headers['content-length']);
|
||||
});
|
||||
value.resume();
|
||||
|
||||
// something else
|
||||
} else {
|
||||
callback('Unknown stream');
|
||||
}
|
||||
};
|
||||
|
||||
FormData.prototype._multiPartHeader = function(field, value, options) {
|
||||
// custom header specified (as string)?
|
||||
// it becomes responsible for boundary
|
||||
// (e.g. to handle extra CRLFs on .NET servers)
|
||||
if (typeof options.header == 'string') {
|
||||
return options.header;
|
||||
}
|
||||
|
||||
var contentDisposition = this._getContentDisposition(value, options);
|
||||
var contentType = this._getContentType(value, options);
|
||||
|
||||
var contents = '';
|
||||
var headers = {
|
||||
// add custom disposition as third element or keep it two elements if not
|
||||
'Content-Disposition': ['form-data', 'name="' + field + '"'].concat(contentDisposition || []),
|
||||
// if no content type. allow it to be empty array
|
||||
'Content-Type': [].concat(contentType || [])
|
||||
};
|
||||
|
||||
// allow custom headers.
|
||||
if (typeof options.header == 'object') {
|
||||
populate(headers, options.header);
|
||||
}
|
||||
|
||||
var header;
|
||||
for (var prop in headers) {
|
||||
if (!headers.hasOwnProperty(prop)) continue;
|
||||
header = headers[prop];
|
||||
|
||||
// skip nullish headers.
|
||||
if (header == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// convert all headers to arrays.
|
||||
if (!Array.isArray(header)) {
|
||||
header = [header];
|
||||
}
|
||||
|
||||
// add non-empty headers.
|
||||
if (header.length) {
|
||||
contents += prop + ': ' + header.join('; ') + FormData.LINE_BREAK;
|
||||
}
|
||||
}
|
||||
|
||||
return '--' + this.getBoundary() + FormData.LINE_BREAK + contents + FormData.LINE_BREAK;
|
||||
};
|
||||
|
||||
FormData.prototype._getContentDisposition = function(value, options) {
|
||||
|
||||
var filename
|
||||
, contentDisposition
|
||||
;
|
||||
|
||||
if (typeof options.filepath === 'string') {
|
||||
// custom filepath for relative paths
|
||||
filename = path.normalize(options.filepath).replace(/\\/g, '/');
|
||||
} else if (options.filename || value.name || value.path) {
|
||||
// custom filename take precedence
|
||||
// formidable and the browser add a name property
|
||||
// fs- and request- streams have path property
|
||||
filename = path.basename(options.filename || value.name || value.path);
|
||||
} else if (value.readable && value.hasOwnProperty('httpVersion')) {
|
||||
// or try http response
|
||||
filename = path.basename(value.client._httpMessage.path || '');
|
||||
}
|
||||
|
||||
if (filename) {
|
||||
contentDisposition = 'filename="' + filename + '"';
|
||||
}
|
||||
|
||||
return contentDisposition;
|
||||
};
|
||||
|
||||
FormData.prototype._getContentType = function(value, options) {
|
||||
|
||||
// use custom content-type above all
|
||||
var contentType = options.contentType;
|
||||
|
||||
// or try `name` from formidable, browser
|
||||
if (!contentType && value.name) {
|
||||
contentType = mime.lookup(value.name);
|
||||
}
|
||||
|
||||
// or try `path` from fs-, request- streams
|
||||
if (!contentType && value.path) {
|
||||
contentType = mime.lookup(value.path);
|
||||
}
|
||||
|
||||
// or if it's http-reponse
|
||||
if (!contentType && value.readable && value.hasOwnProperty('httpVersion')) {
|
||||
contentType = value.headers['content-type'];
|
||||
}
|
||||
|
||||
// or guess it from the filepath or filename
|
||||
if (!contentType && (options.filepath || options.filename)) {
|
||||
contentType = mime.lookup(options.filepath || options.filename);
|
||||
}
|
||||
|
||||
// fallback to the default content type if `value` is not simple value
|
||||
if (!contentType && typeof value == 'object') {
|
||||
contentType = FormData.DEFAULT_CONTENT_TYPE;
|
||||
}
|
||||
|
||||
return contentType;
|
||||
};
|
||||
|
||||
FormData.prototype._multiPartFooter = function() {
|
||||
return function(next) {
|
||||
var footer = FormData.LINE_BREAK;
|
||||
|
||||
var lastPart = (this._streams.length === 0);
|
||||
if (lastPart) {
|
||||
footer += this._lastBoundary();
|
||||
}
|
||||
|
||||
next(footer);
|
||||
}.bind(this);
|
||||
};
|
||||
|
||||
FormData.prototype._lastBoundary = function() {
|
||||
return '--' + this.getBoundary() + '--' + FormData.LINE_BREAK;
|
||||
};
|
||||
|
||||
FormData.prototype.getHeaders = function(userHeaders) {
|
||||
var header;
|
||||
var formHeaders = {
|
||||
'content-type': 'multipart/form-data; boundary=' + this.getBoundary()
|
||||
};
|
||||
|
||||
for (header in userHeaders) {
|
||||
if (userHeaders.hasOwnProperty(header)) {
|
||||
formHeaders[header.toLowerCase()] = userHeaders[header];
|
||||
}
|
||||
}
|
||||
|
||||
return formHeaders;
|
||||
};
|
||||
|
||||
FormData.prototype.setBoundary = function(boundary) {
|
||||
this._boundary = boundary;
|
||||
};
|
||||
|
||||
FormData.prototype.getBoundary = function() {
|
||||
if (!this._boundary) {
|
||||
this._generateBoundary();
|
||||
}
|
||||
|
||||
return this._boundary;
|
||||
};
|
||||
|
||||
FormData.prototype.getBuffer = function() {
|
||||
var dataBuffer = new Buffer.alloc( 0 );
|
||||
var boundary = this.getBoundary();
|
||||
|
||||
// Create the form content. Add Line breaks to the end of data.
|
||||
for (var i = 0, len = this._streams.length; i < len; i++) {
|
||||
if (typeof this._streams[i] !== 'function') {
|
||||
|
||||
// Add content to the buffer.
|
||||
if(Buffer.isBuffer(this._streams[i])) {
|
||||
dataBuffer = Buffer.concat( [dataBuffer, this._streams[i]]);
|
||||
}else {
|
||||
dataBuffer = Buffer.concat( [dataBuffer, Buffer.from(this._streams[i])]);
|
||||
}
|
||||
|
||||
// Add break after content.
|
||||
if (typeof this._streams[i] !== 'string' || this._streams[i].substring( 2, boundary.length + 2 ) !== boundary) {
|
||||
dataBuffer = Buffer.concat( [dataBuffer, Buffer.from(FormData.LINE_BREAK)] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add the footer and return the Buffer object.
|
||||
return Buffer.concat( [dataBuffer, Buffer.from(this._lastBoundary())] );
|
||||
};
|
||||
|
||||
FormData.prototype._generateBoundary = function() {
|
||||
// This generates a 50 character boundary similar to those used by Firefox.
|
||||
// They are optimized for boyer-moore parsing.
|
||||
var boundary = '--------------------------';
|
||||
for (var i = 0; i < 24; i++) {
|
||||
boundary += Math.floor(Math.random() * 10).toString(16);
|
||||
}
|
||||
|
||||
this._boundary = boundary;
|
||||
};
|
||||
|
||||
// Note: getLengthSync DOESN'T calculate streams length
|
||||
// As workaround one can calculate file size manually
|
||||
// and add it as knownLength option
|
||||
FormData.prototype.getLengthSync = function() {
|
||||
var knownLength = this._overheadLength + this._valueLength;
|
||||
|
||||
// Don't get confused, there are 3 "internal" streams for each keyval pair
|
||||
// so it basically checks if there is any value added to the form
|
||||
if (this._streams.length) {
|
||||
knownLength += this._lastBoundary().length;
|
||||
}
|
||||
|
||||
// https://github.com/form-data/form-data/issues/40
|
||||
if (!this.hasKnownLength()) {
|
||||
// Some async length retrievers are present
|
||||
// therefore synchronous length calculation is false.
|
||||
// Please use getLength(callback) to get proper length
|
||||
this._error(new Error('Cannot calculate proper length in synchronous way.'));
|
||||
}
|
||||
|
||||
return knownLength;
|
||||
};
|
||||
|
||||
// Public API to check if length of added values is known
|
||||
// https://github.com/form-data/form-data/issues/196
|
||||
// https://github.com/form-data/form-data/issues/262
|
||||
FormData.prototype.hasKnownLength = function() {
|
||||
var hasKnownLength = true;
|
||||
|
||||
if (this._valuesToMeasure.length) {
|
||||
hasKnownLength = false;
|
||||
}
|
||||
|
||||
return hasKnownLength;
|
||||
};
|
||||
|
||||
FormData.prototype.getLength = function(cb) {
|
||||
var knownLength = this._overheadLength + this._valueLength;
|
||||
|
||||
if (this._streams.length) {
|
||||
knownLength += this._lastBoundary().length;
|
||||
}
|
||||
|
||||
if (!this._valuesToMeasure.length) {
|
||||
process.nextTick(cb.bind(this, null, knownLength));
|
||||
return;
|
||||
}
|
||||
|
||||
asynckit.parallel(this._valuesToMeasure, this._lengthRetriever, function(err, values) {
|
||||
if (err) {
|
||||
cb(err);
|
||||
return;
|
||||
}
|
||||
|
||||
values.forEach(function(length) {
|
||||
knownLength += length;
|
||||
});
|
||||
|
||||
cb(null, knownLength);
|
||||
});
|
||||
};
|
||||
|
||||
FormData.prototype.submit = function(params, cb) {
|
||||
var request
|
||||
, options
|
||||
, defaults = {method: 'post'}
|
||||
;
|
||||
|
||||
// parse provided url if it's string
|
||||
// or treat it as options object
|
||||
if (typeof params == 'string') {
|
||||
|
||||
params = parseUrl(params);
|
||||
options = populate({
|
||||
port: params.port,
|
||||
path: params.pathname,
|
||||
host: params.hostname,
|
||||
protocol: params.protocol
|
||||
}, defaults);
|
||||
|
||||
// use custom params
|
||||
} else {
|
||||
|
||||
options = populate(params, defaults);
|
||||
// if no port provided use default one
|
||||
if (!options.port) {
|
||||
options.port = options.protocol == 'https:' ? 443 : 80;
|
||||
}
|
||||
}
|
||||
|
||||
// put that good code in getHeaders to some use
|
||||
options.headers = this.getHeaders(params.headers);
|
||||
|
||||
// https if specified, fallback to http in any other case
|
||||
if (options.protocol == 'https:') {
|
||||
request = https.request(options);
|
||||
} else {
|
||||
request = http.request(options);
|
||||
}
|
||||
|
||||
// get content length and fire away
|
||||
this.getLength(function(err, length) {
|
||||
if (err && err !== 'Unknown stream') {
|
||||
this._error(err);
|
||||
return;
|
||||
}
|
||||
|
||||
// add content length
|
||||
if (length) {
|
||||
request.setHeader('Content-Length', length);
|
||||
}
|
||||
|
||||
this.pipe(request);
|
||||
if (cb) {
|
||||
var onResponse;
|
||||
|
||||
var callback = function (error, responce) {
|
||||
request.removeListener('error', callback);
|
||||
request.removeListener('response', onResponse);
|
||||
|
||||
return cb.call(this, error, responce);
|
||||
};
|
||||
|
||||
onResponse = callback.bind(this, null);
|
||||
|
||||
request.on('error', callback);
|
||||
request.on('response', onResponse);
|
||||
}
|
||||
}.bind(this));
|
||||
|
||||
return request;
|
||||
};
|
||||
|
||||
FormData.prototype._error = function(err) {
|
||||
if (!this.error) {
|
||||
this.error = err;
|
||||
this.pause();
|
||||
this.emit('error', err);
|
||||
}
|
||||
};
|
||||
|
||||
FormData.prototype.toString = function () {
|
||||
return '[object FormData]';
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
export * from 'rxjs-compat/operator/isEmpty';
|
||||
@@ -0,0 +1,206 @@
|
||||
# cacheable-request
|
||||
|
||||
> Wrap native HTTP requests with RFC compliant cache support
|
||||
|
||||
[](https://travis-ci.org/lukechilds/cacheable-request)
|
||||
[](https://coveralls.io/github/lukechilds/cacheable-request?branch=master)
|
||||
[](https://www.npmjs.com/package/cacheable-request)
|
||||
[](https://www.npmjs.com/package/cacheable-request)
|
||||
|
||||
[RFC 7234](http://httpwg.org/specs/rfc7234.html) compliant HTTP caching for native Node.js HTTP/HTTPS requests. Caching works out of the box in memory or is easily pluggable with a wide range of storage adapters.
|
||||
|
||||
**Note:** This is a low level wrapper around the core HTTP modules, it's not a high level request library.
|
||||
|
||||
## Features
|
||||
|
||||
- Only stores cacheable responses as defined by RFC 7234
|
||||
- Fresh cache entries are served directly from cache
|
||||
- Stale cache entries are revalidated with `If-None-Match`/`If-Modified-Since` headers
|
||||
- 304 responses from revalidation requests use cached body
|
||||
- Updates `Age` header on cached responses
|
||||
- Can completely bypass cache on a per request basis
|
||||
- In memory cache by default
|
||||
- Official support for Redis, MongoDB, SQLite, PostgreSQL and MySQL storage adapters
|
||||
- Easily plug in your own or third-party storage adapters
|
||||
- If DB connection fails, cache is automatically bypassed ([disabled by default](#optsautomaticfailover))
|
||||
- Adds cache support to any existing HTTP code with minimal changes
|
||||
- Uses [http-cache-semantics](https://github.com/pornel/http-cache-semantics) internally for HTTP RFC 7234 compliance
|
||||
|
||||
## Install
|
||||
|
||||
```shell
|
||||
npm install cacheable-request
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
const http = require('http');
|
||||
const CacheableRequest = require('cacheable-request');
|
||||
|
||||
// Then instead of
|
||||
const req = http.request('http://example.com', cb);
|
||||
req.end();
|
||||
|
||||
// You can do
|
||||
const cacheableRequest = new CacheableRequest(http.request);
|
||||
const cacheReq = cacheableRequest('http://example.com', cb);
|
||||
cacheReq.on('request', req => req.end());
|
||||
// Future requests to 'example.com' will be returned from cache if still valid
|
||||
|
||||
// You pass in any other http.request API compatible method to be wrapped with cache support:
|
||||
const cacheableRequest = new CacheableRequest(https.request);
|
||||
const cacheableRequest = new CacheableRequest(electron.net);
|
||||
```
|
||||
|
||||
## Storage Adapters
|
||||
|
||||
`cacheable-request` uses [Keyv](https://github.com/lukechilds/keyv) to support a wide range of storage adapters.
|
||||
|
||||
For example, to use Redis as a cache backend, you just need to install the official Redis Keyv storage adapter:
|
||||
|
||||
```
|
||||
npm install @keyv/redis
|
||||
```
|
||||
|
||||
And then you can pass `CacheableRequest` your connection string:
|
||||
|
||||
```js
|
||||
const cacheableRequest = new CacheableRequest(http.request, 'redis://user:pass@localhost:6379');
|
||||
```
|
||||
|
||||
[View all official Keyv storage adapters.](https://github.com/lukechilds/keyv#official-storage-adapters)
|
||||
|
||||
Keyv also supports anything that follows the Map API so it's easy to write your own storage adapter or use a third-party solution.
|
||||
|
||||
e.g The following are all valid storage adapters
|
||||
|
||||
```js
|
||||
const storageAdapter = new Map();
|
||||
// or
|
||||
const storageAdapter = require('./my-storage-adapter');
|
||||
// or
|
||||
const QuickLRU = require('quick-lru');
|
||||
const storageAdapter = new QuickLRU({ maxSize: 1000 });
|
||||
|
||||
const cacheableRequest = new CacheableRequest(http.request, storageAdapter);
|
||||
```
|
||||
|
||||
View the [Keyv docs](https://github.com/lukechilds/keyv) for more information on how to use storage adapters.
|
||||
|
||||
## API
|
||||
|
||||
### new cacheableRequest(request, [storageAdapter])
|
||||
|
||||
Returns the provided request function wrapped with cache support.
|
||||
|
||||
#### request
|
||||
|
||||
Type: `function`
|
||||
|
||||
Request function to wrap with cache support. Should be [`http.request`](https://nodejs.org/api/http.html#http_http_request_options_callback) or a similar API compatible request function.
|
||||
|
||||
#### storageAdapter
|
||||
|
||||
Type: `Keyv storage adapter`<br>
|
||||
Default: `new Map()`
|
||||
|
||||
A [Keyv](https://github.com/lukechilds/keyv) storage adapter instance, or connection string if using with an official Keyv storage adapter.
|
||||
|
||||
### Instance
|
||||
|
||||
#### cacheableRequest(opts, [cb])
|
||||
|
||||
Returns an event emitter.
|
||||
|
||||
##### opts
|
||||
|
||||
Type: `object`, `string`
|
||||
|
||||
- Any of the default request functions options.
|
||||
- Any [`http-cache-semantics`](https://github.com/kornelski/http-cache-semantics#constructor-options) options.
|
||||
- Any of the following:
|
||||
|
||||
###### opts.cache
|
||||
|
||||
Type: `boolean`<br>
|
||||
Default: `true`
|
||||
|
||||
If the cache should be used. Setting this to false will completely bypass the cache for the current request.
|
||||
|
||||
###### opts.strictTtl
|
||||
|
||||
Type: `boolean`<br>
|
||||
Default: `false`
|
||||
|
||||
If set to `true` once a cached resource has expired it is deleted and will have to be re-requested.
|
||||
|
||||
If set to `false` (default), after a cached resource's TTL expires it is kept in the cache and will be revalidated on the next request with `If-None-Match`/`If-Modified-Since` headers.
|
||||
|
||||
###### opts.maxTtl
|
||||
|
||||
Type: `number`<br>
|
||||
Default: `undefined`
|
||||
|
||||
Limits TTL. The `number` represents milliseconds.
|
||||
|
||||
###### opts.automaticFailover
|
||||
|
||||
Type: `boolean`<br>
|
||||
Default: `false`
|
||||
|
||||
When set to `true`, if the DB connection fails we will automatically fallback to a network request. DB errors will still be emitted to notify you of the problem even though the request callback may succeed.
|
||||
|
||||
###### opts.forceRefresh
|
||||
|
||||
Type: `boolean`<br>
|
||||
Default: `false`
|
||||
|
||||
Forces refreshing the cache. If the response could be retrieved from the cache, it will perform a new request and override the cache instead.
|
||||
|
||||
##### cb
|
||||
|
||||
Type: `function`
|
||||
|
||||
The callback function which will receive the response as an argument.
|
||||
|
||||
The response can be either a [Node.js HTTP response stream](https://nodejs.org/api/http.html#http_class_http_incomingmessage) or a [responselike object](https://github.com/lukechilds/responselike). The response will also have a `fromCache` property set with a boolean value.
|
||||
|
||||
##### .on('request', request)
|
||||
|
||||
`request` event to get the request object of the request.
|
||||
|
||||
**Note:** This event will only fire if an HTTP request is actually made, not when a response is retrieved from cache. However, you should always handle the `request` event to end the request and handle any potential request errors.
|
||||
|
||||
##### .on('response', response)
|
||||
|
||||
`response` event to get the response object from the HTTP request or cache.
|
||||
|
||||
##### .on('error', error)
|
||||
|
||||
`error` event emitted in case of an error with the cache.
|
||||
|
||||
Errors emitted here will be an instance of `CacheableRequest.RequestError` or `CacheableRequest.CacheError`. You will only ever receive a `RequestError` if the request function throws (normally caused by invalid user input). Normal request errors should be handled inside the `request` event.
|
||||
|
||||
To properly handle all error scenarios you should use the following pattern:
|
||||
|
||||
```js
|
||||
cacheableRequest('example.com', cb)
|
||||
.on('error', err => {
|
||||
if (err instanceof CacheableRequest.CacheError) {
|
||||
handleCacheError(err); // Cache error
|
||||
} else if (err instanceof CacheableRequest.RequestError) {
|
||||
handleRequestError(err); // Request function thrown
|
||||
}
|
||||
})
|
||||
.on('request', req => {
|
||||
req.on('error', handleRequestError); // Request error emitted
|
||||
req.end();
|
||||
});
|
||||
```
|
||||
|
||||
**Note:** Database connection errors are emitted here, however `cacheable-request` will attempt to re-request the resource and bypass the cache on a connection error. Therefore a database connection error doesn't necessarily mean the request won't be fulfilled.
|
||||
|
||||
## License
|
||||
|
||||
MIT © Luke Childs
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"buffer.js","sources":["../../../src/internal/operators/buffer.ts"],"names":[],"mappings":";AAIA,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AA0CjG,MAAM,UAAU,MAAM,CAAI,eAAgC;IACxD,OAAO,SAAS,sBAAsB,CAAC,MAAqB;QAC1D,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,cAAc,CAAI,eAAe,CAAC,CAAC,CAAC;IAC7D,CAAC,CAAC;AACJ,CAAC;AAED;IAEE,wBAAoB,eAAgC;QAAhC,oBAAe,GAAf,eAAe,CAAiB;IACpD,CAAC;IAED,6BAAI,GAAJ,UAAK,UAA2B,EAAE,MAAW;QAC3C,OAAO,MAAM,CAAC,SAAS,CAAC,IAAI,gBAAgB,CAAC,UAAU,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;IAClF,CAAC;IACH,qBAAC;AAAD,CAAC,AARD,IAQC;AAOD;IAAkC,4CAA6B;IAG7D,0BAAY,WAA4B,EAAE,eAAgC;QAA1E,YACE,kBAAM,WAAW,CAAC,SAEnB;QALO,YAAM,GAAQ,EAAE,CAAC;QAIvB,KAAI,CAAC,GAAG,CAAC,cAAc,CAAC,eAAe,EAAE,IAAI,qBAAqB,CAAC,KAAI,CAAC,CAAC,CAAC,CAAC;;IAC7E,CAAC;IAES,gCAAK,GAAf,UAAgB,KAAQ;QACtB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;IAED,qCAAU,GAAV;QACE,IAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC3B,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;QACjB,IAAI,CAAC,WAAW,CAAC,IAAK,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;IACH,uBAAC;AAAD,CAAC,AAjBD,CAAkC,qBAAqB,GAiBtD"}
|
||||
@@ -0,0 +1 @@
|
||||
module.exports={A:{A:{"2":"J E F G A B BC"},B:{"1":"M N O P Q R S T U V W X Y Z a b c d f g h i j k l m n o p q r s D t","2":"C K L","260":"H"},C:{"1":"7 8 9 AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB VB WB XB YB uB ZB vB aB bB cB dB eB fB gB hB iB jB kB e lB mB nB oB pB P Q R wB S T U V W X Y Z a b c d f g h i j k l m n o p q r s D t xB yB","2":"0 1 2 3 4 5 6 CC tB I u J E F G A B C K L H M N O v w x y z DC EC"},D:{"1":"PB QB RB SB TB UB VB WB XB YB uB ZB vB aB bB cB dB eB fB gB hB iB jB kB e lB mB nB oB pB P Q R S T U V W X Y Z a b c d f g h i j k l m n o p q r s D t xB yB FC","2":"0 1 2 3 4 5 6 7 8 9 I u J E F G A B C K L H M N O v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB","194":"OB"},E:{"1":"A B C K L H 0B qB rB 1B LC MC 2B 3B 4B 5B sB 6B 7B 8B NC","2":"I u J E F G GC zB HC IC JC","260":"KC"},F:{"1":"CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB VB WB XB YB ZB aB bB cB dB eB fB gB hB iB jB kB e lB mB nB oB pB P Q R wB S T U V W X Y Z a b c d","2":"0 1 2 3 4 5 6 7 8 9 G B C H M N O v w x y z AB OC PC QC RC qB 9B SC rB","194":"BB"},G:{"1":"aC bC cC dC eC fC gC hC iC jC kC lC mC 2B 3B 4B 5B sB 6B 7B 8B","2":"F zB TC AC UC VC WC XC YC","260":"ZC"},H:{"2":"nC"},I:{"1":"D","2":"tB I oC pC qC rC AC sC tC"},J:{"2":"E A"},K:{"1":"e","2":"A B C qB 9B rB"},L:{"1":"D"},M:{"1":"D"},N:{"2":"A B"},O:{"1":"uC"},P:{"1":"vC wC xC yC zC 0B 0C 1C 2C 3C 4C sB 5C 6C 7C","2":"I"},Q:{"1":"1B"},R:{"1":"8C"},S:{"1":"9C"}},B:4,C:"CSS Variables (Custom Properties)"};
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
module.exports={C:{"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0,"29":0,"30":0,"31":0,"32":0,"33":0,"34":0,"35":0,"36":0,"37":0,"38":0,"39":0,"40":0,"41":0,"42":0,"43":0,"44":0,"45":0,"46":0,"47":0,"48":0,"49":0,"50":0,"51":0.00254,"52":0.01522,"53":0,"54":0,"55":0.00254,"56":0.00254,"57":0,"58":0,"59":0,"60":0,"61":0,"62":0,"63":0,"64":0,"65":0,"66":0,"67":0,"68":0,"69":0,"70":0,"71":0,"72":0.00254,"73":0,"74":0,"75":0,"76":0,"77":0,"78":0.00254,"79":0,"80":0,"81":0,"82":0,"83":0,"84":0,"85":0,"86":0,"87":0.00254,"88":0,"89":0,"90":0,"91":0,"92":0,"93":0,"94":0,"95":0,"96":0,"97":0,"98":0,"99":0.00254,"100":0,"101":0.00254,"102":0.00761,"103":0.00254,"104":0.00254,"105":0.00254,"106":0.00507,"107":0.01014,"108":0.27642,"109":0.16738,"110":0.00254,"111":0,"3.5":0,"3.6":0},D:{"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0.00254,"27":0,"28":0,"29":0,"30":0,"31":0,"32":0,"33":0.00254,"34":0,"35":0,"36":0,"37":0,"38":0,"39":0,"40":0.00507,"41":0,"42":0,"43":0.04311,"44":0,"45":0,"46":0.00254,"47":0,"48":0.00254,"49":0.00761,"50":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":0,"58":0,"59":0,"60":0.00254,"61":0,"62":0,"63":0.00254,"64":0.00254,"65":0,"66":0,"67":0,"68":0.00254,"69":0.00507,"70":0.00254,"71":0.00254,"72":0.00254,"73":0.00254,"74":0.00507,"75":0.00254,"76":0.00507,"77":0.00254,"78":0.00254,"79":0.02029,"80":0.00761,"81":0.01775,"83":0.00507,"84":0.00761,"85":0.01014,"86":0.01268,"87":0.00761,"88":0.00507,"89":0.00761,"90":0.01522,"91":0.02029,"92":0.0279,"93":0.01775,"94":0.01775,"95":0.01014,"96":0.00507,"97":0.00507,"98":0.01775,"99":0.00507,"100":0.01268,"101":0.00761,"102":0.01775,"103":0.02282,"104":0.01522,"105":0.02536,"106":0.01775,"107":0.04818,"108":2.21646,"109":2.03894,"110":0.00254,"111":0.00254,"112":0},F:{"9":0,"11":0,"12":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0,"29":0,"30":0,"31":0,"32":0,"33":0,"34":0,"35":0,"36":0,"37":0,"38":0,"39":0,"40":0,"41":0,"42":0,"43":0,"44":0,"45":0,"46":0,"47":0,"48":0,"49":0,"50":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":0,"58":0,"60":0,"62":0,"63":0,"64":0.00761,"65":0,"66":0,"67":0,"68":0,"69":0,"70":0.00254,"71":0,"72":0.00254,"73":0.01014,"74":0,"75":0,"76":0.00254,"77":0,"78":0.00254,"79":0.00761,"80":0.00254,"81":0.00507,"82":0.00507,"83":0.00507,"84":0.00254,"85":0.00254,"86":0.00254,"87":0,"88":0.00254,"89":0.00254,"90":0.00254,"91":0.00254,"92":0.00761,"93":0.02536,"94":0.01268,"9.5-9.6":0,"10.0-10.1":0,"10.5":0,"10.6":0,"11.1":0,"11.5":0,"11.6":0,"12.1":0},B:{"12":0,"13":0,"14":0.00254,"15":0,"16":0,"17":0,"18":0.00254,"79":0,"80":0,"81":0,"83":0,"84":0,"85":0,"86":0,"87":0,"88":0,"89":0,"90":0,"91":0,"92":0.00507,"93":0,"94":0,"95":0,"96":0,"97":0,"98":0,"99":0,"100":0,"101":0,"102":0,"103":0,"104":0,"105":0.00254,"106":0.00254,"107":0.00761,"108":0.25106,"109":0.24853},E:{"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0.00507,"15":0.00254,_:"0","3.1":0,"3.2":0,"5.1":0.06086,"6.1":0,"7.1":0,"9.1":0,"10.1":0,"11.1":0,"12.1":0,"13.1":0.00507,"14.1":0.00761,"15.1":0.00254,"15.2-15.3":0.00254,"15.4":0.00507,"15.5":0.00761,"15.6":0.03043,"16.0":0.00507,"16.1":0.01268,"16.2":0.02029,"16.3":0.00254},G:{"8":0,"3.2":0,"4.0-4.1":0,"4.2-4.3":0,"5.0-5.1":0.00094,"6.0-6.1":0.00094,"7.0-7.1":0.01223,"8.1-8.4":0,"9.0-9.2":0.00094,"9.3":0.02917,"10.0-10.2":0,"10.3":0.03481,"11.0-11.2":0.00282,"11.3-11.4":0.00376,"12.0-12.1":0.01411,"12.2-12.5":0.59744,"13.0-13.1":0.00753,"13.2":0.00282,"13.3":0.05833,"13.4-13.7":0.08374,"14.0-14.4":0.23239,"14.5-14.8":0.32647,"15.0-15.1":0.0922,"15.2-15.3":0.11949,"15.4":0.1543,"15.5":0.30766,"15.6":0.91074,"16.0":1.26544,"16.1":2.14889,"16.2":1.87604,"16.3":0.22392},P:{"4":0.24658,"5.0-5.4":0,"6.2-6.4":0.01027,"7.2-7.4":0.09247,"8.2":0,"9.2":0.01027,"10.1":0,"11.1-11.2":0.05137,"12.0":0.01027,"13.0":0.06164,"14.0":0.06164,"15.0":0.03082,"16.0":0.10274,"17.0":0.13356,"18.0":0.09247,"19.0":1.70548},I:{"0":0,"3":0,"4":0,"2.1":0,"2.2":0,"2.3":0,"4.1":0.01078,"4.2-4.3":0.02155,"4.4":0,"4.4.3-4.4.4":0.25505},K:{_:"0 10 11 12 11.1 11.5 12.1"},A:{"6":0,"7":0,"8":0.00575,"9":0.00287,"10":0.00287,"11":0.03162,"5.5":0},J:{"7":0,"10":0},N:{"10":0,"11":0},R:{_:"0"},M:{"0":0.17167},Q:{"13.1":0},O:{"0":0.41798},H:{"0":0.45932},L:{"0":80.07046},S:{"2.5":0.00746}};
|
||||
@@ -0,0 +1 @@
|
||||
module.exports={A:{A:{"2":"BC","8":"J E F","129":"G A B"},B:{"1":"N O P Q R S T U V W X Y Z a b c d f g h i j k l m n o p q r s D t","129":"C K L H M"},C:{"1":"0 1 2 3 4 5 6 7 8 9 I u J E F G A B C K L H M N O v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB VB WB XB YB uB ZB vB aB bB cB dB eB fB gB hB iB jB kB e lB mB nB oB pB P Q R wB S T U V W X Y Z a b c d f g h i j k l m n o p q r s D t xB yB","8":"CC tB DC EC"},D:{"1":"0 1 2 3 4 5 6 7 8 9 E F G A B C K L H M N O v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB VB WB XB YB uB ZB vB aB bB cB dB eB fB gB hB iB jB kB e lB mB nB oB pB P Q R S T U V W X Y Z a b c d f g h i j k l m n o p q r s D t xB yB FC","8":"I u J"},E:{"1":"G A B C K L H KC 0B qB rB 1B LC MC 2B 3B 4B 5B sB 6B 7B 8B NC","8":"I u GC zB","129":"J E F HC IC JC"},F:{"1":"0 1 2 3 4 5 6 7 8 9 C H M N O v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB VB WB XB YB ZB aB bB cB dB eB fB gB hB iB jB kB e lB mB nB oB pB P Q R wB S T U V W X Y Z a b c d SC rB","2":"B RC qB 9B","8":"G OC PC QC"},G:{"1":"YC ZC aC bC cC dC eC fC gC hC iC jC kC lC mC 2B 3B 4B 5B sB 6B 7B 8B","8":"zB TC AC","129":"F UC VC WC XC"},H:{"1":"nC"},I:{"1":"D sC tC","2":"oC pC qC","129":"tB I rC AC"},J:{"1":"A","129":"E"},K:{"1":"C e rB","8":"A B qB 9B"},L:{"1":"D"},M:{"1":"D"},N:{"129":"A B"},O:{"1":"uC"},P:{"1":"I vC wC xC yC zC 0B 0C 1C 2C 3C 4C sB 5C 6C 7C"},Q:{"1":"1B"},R:{"1":"8C"},S:{"1":"9C"}},B:1,C:"Inline SVG in HTML5"};
|
||||
@@ -0,0 +1 @@
|
||||
module.exports={A:{A:{"1":"G A B","2":"J E F BC"},B:{"1":"C K L H M N O P Q R S T U V W X Y Z a b c d f g h i j k l m n o p q r s D t"},C:{"1":"0 1 2 3 4 5 6 7 8 9 CC tB I u J E F G A B C K L H M N O v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB VB WB XB YB uB ZB vB aB bB cB dB eB fB gB hB iB jB kB e lB mB nB oB pB P Q R wB S T U V W X Y Z a b c d f g h i j k l m n o p q r s D t xB yB DC EC"},D:{"1":"0 1 2 3 4 5 6 7 8 9 I u J E F G A B C K L H M N O v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB VB WB XB YB uB ZB vB aB bB cB dB eB fB gB hB iB jB kB e lB mB nB oB pB P Q R S T U V W X Y Z a b c d f g h i j k l m n o p q r s D t xB yB FC"},E:{"1":"I u J E F G A B C K L H HC IC JC KC 0B qB rB 1B LC MC 2B 3B 4B 5B sB 6B 7B 8B NC","16":"GC zB"},F:{"1":"0 1 2 3 4 5 6 7 8 9 G B C H M N O v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB VB WB XB YB ZB aB bB cB dB eB fB gB hB iB jB kB e lB mB nB oB pB P Q R wB S T U V W X Y Z a b c d OC PC QC RC qB 9B SC rB"},G:{"1":"F AC UC VC WC XC YC ZC aC bC cC dC eC fC gC hC iC jC kC lC mC 2B 3B 4B 5B sB 6B 7B 8B","16":"zB TC"},H:{"1":"nC"},I:{"1":"tB I D oC pC qC rC AC sC tC"},J:{"1":"E A"},K:{"1":"A B C e qB 9B rB"},L:{"1":"D"},M:{"1":"D"},N:{"1":"A B"},O:{"1":"uC"},P:{"1":"I vC wC xC yC zC 0B 0C 1C 2C 3C 4C sB 5C 6C 7C"},Q:{"1":"1B"},R:{"1":"8C"},S:{"1":"9C"}},B:2,C:"CSS namespaces"};
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
// binaryType is truthy if there is support.. returns "blob" in new-ish chrome.
|
||||
// plus.google.com/115535723976198353696/posts/ERN6zYozENV
|
||||
// github.com/Modernizr/Modernizr/issues/370
|
||||
|
||||
Modernizr.addTest('websocketsbinary', function() {
|
||||
var protocol = 'https:'==location.protocol?'wss':'ws',
|
||||
protoBin;
|
||||
|
||||
if('WebSocket' in window) {
|
||||
if( protoBin = 'binaryType' in WebSocket.prototype ) {
|
||||
return protoBin;
|
||||
}
|
||||
try {
|
||||
return !!(new WebSocket(protocol+'://.').binaryType);
|
||||
} catch (e){}
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
@@ -0,0 +1 @@
|
||||
module.exports={A:{A:{"2":"J E F G A BC","132":"B"},B:{"132":"C K L H M N O","1028":"P Q R S T U V W X Y Z a b c d f g h i j k l m n o p q r s D t"},C:{"2":"0 1 2 3 4 5 6 7 8 9 CC tB I u J E F G A B C K L H M N O v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB VB WB XB YB uB ZB vB aB bB cB dB eB fB gB hB iB jB kB e lB mB nB oB pB P Q R wB S T U V W X Y Z a b c d f g h i j k l m n o p q r s D t xB yB DC EC"},D:{"2":"0 1 2 3 4 5 6 7 8 9 I u J E F G A B C K L H M N O v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB VB WB XB YB uB ZB vB aB bB cB dB eB fB gB hB iB jB kB e lB mB nB oB pB P Q R S T U V W X Y Z a b c d f g h i j k l m n o p q","2052":"r s D t xB yB FC"},E:{"1":"K L H 1B LC MC 2B 3B 4B 5B sB 6B 7B 8B NC","2":"I u J E F G A GC zB HC IC JC KC 0B","516":"B C qB rB"},F:{"2":"0 1 2 3 4 5 6 7 8 9 G B C H M N O v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB VB WB XB YB ZB aB bB cB dB eB fB gB hB iB jB kB e lB mB nB oB pB P Q R wB S T U V W X Y Z a b c OC PC QC RC qB 9B SC rB","2052":"d"},G:{"1":"cC dC eC fC gC hC iC jC kC lC mC 2B 3B 4B 5B sB 6B 7B 8B","2":"F zB TC AC UC VC WC XC YC ZC aC bC"},H:{"2":"nC"},I:{"2":"tB I oC pC qC rC AC sC tC","2052":"D"},J:{"2":"E A"},K:{"2":"A B C qB 9B rB","258":"e"},L:{"2052":"D"},M:{"2":"D"},N:{"2":"A B"},O:{"2":"uC"},P:{"2":"I","258":"vC wC xC yC zC 0B 0C 1C 2C 3C 4C sB 5C 6C 7C"},Q:{"2":"1B"},R:{"1":"8C"},S:{"2":"9C"}},B:6,C:"HEVC/H.265 video format"};
|
||||
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
Custom protocol handler support
|
||||
http://developers.whatwg.org/timers.html#custom-handlers
|
||||
|
||||
Added by @benschwarz
|
||||
*/
|
||||
|
||||
Modernizr.addTest('customprotocolhandler', function () {
|
||||
return !!navigator.registerProtocolHandler;
|
||||
});
|
||||
@@ -0,0 +1 @@
|
||||
module.exports={A:{A:{"2":"J E F G A B BC"},B:{"2":"C K L H M N O P","1537":"Q R S T U V W X Y Z a b c d f g h i j k l m n o p q r s D t"},C:{"2":"CC tB DC EC","260":"0 1 2 3 4 5 6 7 8 9 I u J E F G A B C K L H M N O v w x y z AB BB CB DB EB FB GB","513":"HB IB JB KB LB MB NB OB PB QB RB SB TB UB VB WB XB YB uB ZB vB aB bB cB dB eB fB gB hB iB jB kB e lB mB nB oB pB P Q R wB S T U V W X Y Z a b c d f g h i j k l m n o p q r s D t xB yB"},D:{"2":"0 1 2 3 4 5 6 7 8 9 I u J E F G A B C K L H M N O v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB VB WB XB YB uB ZB vB aB bB cB dB eB fB gB hB iB jB kB e lB mB nB oB pB P","1537":"Q R S T U V W X Y Z a b c d f g h i j k l m n o p q r s D t xB yB FC"},E:{"2":"I u J E F G A B C K L H GC zB HC IC JC KC 0B qB rB 1B LC MC 2B 3B 4B 5B sB 6B 7B 8B NC"},F:{"1":"KB LB MB NB OB PB QB RB SB TB","2":"0 1 2 3 4 5 6 7 8 9 G B C H M N O v w x y z AB BB CB DB EB FB GB HB IB JB UB VB WB XB YB ZB aB bB cB dB eB OC PC QC RC qB 9B SC rB","1537":"fB gB hB iB jB kB e lB mB nB oB pB P Q R wB S T U V W X Y Z a b c d"},G:{"2":"eC fC gC hC iC jC kC lC mC 2B 3B 4B 5B sB 6B 7B 8B","130":"F zB TC AC UC VC WC XC YC ZC aC bC cC dC"},H:{"130":"nC"},I:{"2":"tB I D oC pC qC rC AC sC tC"},J:{"2":"E","130":"A"},K:{"130":"A B C qB 9B rB","1537":"e"},L:{"1537":"D"},M:{"2":"D"},N:{"130":"A B"},O:{"2":"uC"},P:{"2":"I vC wC xC yC zC 0B 0C 1C","1537":"2C 3C 4C sB 5C 6C 7C"},Q:{"2":"1B"},R:{"1537":"8C"},S:{"513":"9C"}},B:1,C:"SVG favicons"};
|
||||
Reference in New Issue
Block a user