Added gulp

This commit is contained in:
Lukas Obermann
2016-10-22 20:54:56 +02:00
parent b10c51c094
commit 01e9ea30d5
2041 changed files with 166826 additions and 5113 deletions
+9 -29
View File
@@ -131,55 +131,35 @@ p {
margin: 0;
}
margin: 36px 0 0;
margin: 10px 0 0;
&.small {
margin: 18px 0 0;
&.featured {
font-weight: 500;
color: #f1e6d4;
}
}
.featured {
color: white;
}
h2, h3, h4, h5, h6 {
font-weight: normal;
text-align: left;
letter-spacing: normal;
text-transform: none;
padding: 0;
color: white;
color: #f1e6d4;
font: bold 18px/28px Alegreya;
margin: 20px 0 0;
letter-spacing: 0.05em;
&:first-child {
margin-top: 0 !important;
}
+ p {
margin-top: 20px;
}
}
h2 {
font: bold 18px/28px Alegreya;
margin: 20px 0 0;
color: #f1e6d4;
letter-spacing: 0.05em;
text-transform: uppercase;
}
h3 {
font: bold 18px/28px Alegreya;
margin: 20px 0 0;
color: #f1e6d4;
letter-spacing: 0.05em;
text-transform: none;
}
h4 {
font: bold 14px/22px Alegreya;
margin: 20px 0 0;
font-size: bold 14px/22px Alegreya;
color: #878683;
letter-spacing: 0.025em;
text-transform: uppercase;
+811 -652
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
File diff suppressed because one or more lines are too long
+23 -26
View File
@@ -1,37 +1,34 @@
'use strict';
// "gulp": "^3.9.1",
// "gulp-util": "^3.0.7",
// "vinyl-source-stream": "^1.1.0"
var gulp = require('gulp');
var gutil = require('gulp-util');
var source = require('vinyl-source-stream');
var browserify = require('browserify');
var watchify = require('watchify');
var babelify = require('babelify');
var babelify = require('babelify');
"watch": "watchify -t [babelify] js/AppBootstrap.js -o dist/bundle.js -v",
"build": "browserify -t [babelify] js/AppBootstrap.js | uglifyjs -mc > dist/bundle.min.js",
// "watch": "watchify -t [babelify] js/AppBootstrap.js -o dist/bundle.js -v",
// "build": "browserify -t [babelify] js/AppBootstrap.js | uglifyjs -mc > dist/bundle.min.js",
var customOpts = {
entries: ['./js/AppBootstrap.js'],
transform: [babelify],
debug: true
};
var opts = Object.assign({}, watchify.args, customOpts);
var b = watchify(browserify(opts));
var bundler = browserify('./js/AppBootstrap.js').transform(babelify);
gulp.task('default', function() {
gulp.task('watch', function() {
var watcher = watchify(bundler);
return watcher.on('update', function(){
function bundle() {
watcher.bundle()
.on('error', function(e) {
gutil.log(e);
})
.pipe(source('bundle.js'))
.pipe(gulp.dest('./dist'));
}
watcher.on('update', function() {
var updateStart = Date.now();
b.bundle() // Create new bundle that uses the cache for high performance
.pipe(source('main.js'))
// This is where you add uglifying etc.
.pipe(gulp.dest('./build/'));
bundle();
console.log('Updated!', (Date.now() - updateStart) + 'ms');
})
.bundle() // Create the initial bundle when starting the task
.pipe(source('main.js'))
.pipe(gulp.dest('./build/'));
});
bundle();
});
gulp.task('default', ['watch']);
+20
View File
@@ -1,6 +1,7 @@
import AppDispatcher from '../dispatcher/AppDispatcher';
import ActionTypes from '../constants/ActionTypes';
import createOverlay from '../utils/createOverlay';
import ELStore from '../stores/ELStore';
import HeroCreation from '../components/content/herolist/HeroCreation';
import React from 'react';
import reactAlert from '../utils/reactAlert';
@@ -24,6 +25,25 @@ var HerolistActions = {
});
},
load: function(id) {
if (ELStore.getStartID() !== 'EL_0') {
reactAlert(
'Nicht gespeicherter Held',
'Du hast offenbar bereits einen Helden geöffnet, der noch nicht vollständig gespeichert wurde. Möchtest du trotzdem fortfahren oder vorher den anderen Helden speichern, damit keine Änderungen verloren gehen?',
[
{
label: 'Laden',
onClick: this.loadFx.bind(null, id)
},
{
label: 'Abbrechen'
}
]
);
} else {
this.loadFx(id);
}
},
loadFx: function(id) {
AppDispatcher.dispatch({
actionType: ActionTypes.CLEAR_HERO
});
+26 -15
View File
@@ -16,41 +16,52 @@ class About extends Component {
<h2>Impressum</h2>
<h3>Thore Schuchardt</h3>
<div>
<p>
Backend-Dev<br/>
Lehmberg 7b<br/>
24361 Groß Wittensee<br/>
<a href="mailto:schuchi@dsa-sh.de">schuchi@dsa-sh.de</a>
</div>
</p>
<h3>Lukas Obermann</h3>
<div>
<p>
Frontend-Dev<br/>
Eekholl 11<br/>
24361 Groß Wittensee<br/>
<a href="mailto:lukas@dsa-sh.de">lukas@dsa-sh.de</a>
</div>
</p>
<h2>Haftungsausschluss</h2>
<h3>Urheberrecht</h3>
Die Betreiber der Seiten sind bemüht, stets die Urheberrechte anderer zu beachten bzw. auf selbst erstellte sowie lizenzfreie Werke zurückzugreifen.<br/>
<br/>
Die durch die Seitenbetreiber erstellten Inhalte und Werke auf diesen Seiten unterliegen dem deutschen Urheberrecht. Beiträge Dritter sind als solche gekennzeichnet. Die Vervielfältigung, Bearbeitung, Verbreitung und jede Art der Verwertung außerhalb der Grenzen des Urheberrechtes bedürfen der schriftlichen Zustimmung des jeweiligen Autors bzw. Erstellers. Downloads und Kopien dieser Seite sind nur für den privaten, nicht kommerziellen Gebrauch gestattet.<br/>
<br/>
DAS SCHWARZE AUGE, AVENTURIEN, DERE, MYRANOR, THARUN, UTHURIA und RIESLAND sind eingetragene Marken der Significant Fantasy Medienrechte GbR.<br/>
Ohne vorherige schriftliche Genehmigung der Ulisses Medien und Spiel Distribution GmbH ist eine Verwendung der genannten Markenzeichen nicht gestattet.
<p>
Die Betreiber der Seiten sind bemüht, stets die Urheberrechte anderer zu beachten bzw. auf selbst erstellte sowie lizenzfreie Werke zurückzugreifen.
</p>
<p>
Die durch die Seitenbetreiber erstellten Inhalte und Werke auf diesen Seiten unterliegen dem deutschen Urheberrecht. Beiträge Dritter sind als solche gekennzeichnet. Die Vervielfältigung, Bearbeitung, Verbreitung und jede Art der Verwertung außerhalb der Grenzen des Urheberrechtes bedürfen der schriftlichen Zustimmung des jeweiligen Autors bzw. Erstellers. Downloads und Kopien dieser Seite sind nur für den privaten, nicht kommerziellen Gebrauch gestattet.
</p>
<p className="featured">
DAS SCHWARZE AUGE, AVENTURIEN, DERE, MYRANOR, THARUN, UTHURIA und RIESLAND sind eingetragene Marken der Significant Fantasy Medienrechte GbR.<br/>
Ohne vorherige schriftliche Genehmigung der Ulisses Medien und Spiel Distribution GmbH ist eine Verwendung der genannten Markenzeichen nicht gestattet.
</p>
<h3>Datenschutz</h3>
Soweit auf unseren Seiten personenbezogene Daten (beispielsweise Name, Anschrift oder E-Mail-Adressen) erhoben werden, erfolgt dies soweit möglich stets auf freiwilliger Basis. Die Nutzung der Angebote und Dienste ist, soweit möglich, stets ohne Angabe personenbezogener Daten möglich.<br/>
<br/>
Der Nutzung von im Rahmen der Impressumspflicht veröffentlichten Kontaktdaten durch Dritte zur Übersendung von nicht ausdrücklich angeforderter Werbung und Informationsmaterialien wird hiermit ausdrücklich widersprochen. Die Betreiber der Seiten behalten sich ausdrücklich rechtliche Schritte im Falle der unverlangten Zusendung von Werbeinformationen, etwa durch Spam-Mails, vor.
<p>
Soweit auf unseren Seiten personenbezogene Daten (beispielsweise Name, Anschrift oder E-Mail-Adressen) erhoben werden, erfolgt dies soweit möglich stets auf freiwilliger Basis. Die Nutzung der Angebote und Dienste ist, soweit möglich, stets ohne Angabe personenbezogener Daten möglich.
</p>
<p>
Der Nutzung von im Rahmen der Impressumspflicht veröffentlichten Kontaktdaten durch Dritte zur Übersendung von nicht ausdrücklich angeforderter Werbung und Informationsmaterialien wird hiermit ausdrücklich widersprochen. Die Betreiber der Seiten behalten sich ausdrücklich rechtliche Schritte im Falle der unverlangten Zusendung von Werbeinformationen, etwa durch Spam-Mails, vor.
</p>
<h3>Haftung für Links</h3>
Unser Angebot enthält Links zu externen Webseiten Dritter, auf deren Inhalte wir keinen Einfluss haben. Deshalb können wir für diese fremden Inhalte auch keine Gewähr übernehmen. Für die Inhalte der verlinkten Seiten ist stets der jeweilige Anbieter oder Betreiber der Seiten verantwortlich. Die verlinkten Seiten wurden zum Zeitpunkt der Verlinkung auf mögliche Rechtsverstöße überprüft. Rechtswidrige Inhalte waren zum Zeitpunkt der Verlinkung nicht erkennbar. Eine permanente inhaltliche Kontrolle der verlinkten Seiten ist jedoch ohne konkrete Anhaltspunkte einer Rechtsverletzung nicht zumutbar. Bei Bekanntwerden von Rechtsverletzungen werden wir derartige Links umgehend entfernen.
<p>
Unser Angebot enthält Links zu externen Webseiten Dritter, auf deren Inhalte wir keinen Einfluss haben. Deshalb können wir für diese fremden Inhalte auch keine Gewähr übernehmen. Für die Inhalte der verlinkten Seiten ist stets der jeweilige Anbieter oder Betreiber der Seiten verantwortlich. Die verlinkten Seiten wurden zum Zeitpunkt der Verlinkung auf mögliche Rechtsverstöße überprüft. Rechtswidrige Inhalte waren zum Zeitpunkt der Verlinkung nicht erkennbar. Eine permanente inhaltliche Kontrolle der verlinkten Seiten ist jedoch ohne konkrete Anhaltspunkte einer Rechtsverletzung nicht zumutbar. Bei Bekanntwerden von Rechtsverletzungen werden wir derartige Links umgehend entfernen.
</p>
<h3>Haftung für Inhalte</h3>
Die Inhalte unserer Seiten wurden mit größter Sorgfalt erstellt. Für die Richtigkeit, Vollständigkeit und Aktualität der Inhalte können wir jedoch keine Gewähr übernehmen.
<p>
Die Inhalte unserer Seiten wurden mit größter Sorgfalt erstellt. Für die Richtigkeit, Vollständigkeit und Aktualität der Inhalte können wir jedoch keine Gewähr übernehmen.
</p>
<h2>Cha5App Browser Client v{this.state.version}</h2>
<h2>Drittanbietersoftware</h2>
+21 -5
View File
@@ -10,16 +10,32 @@ class Home extends Component {
<h2>Willkommen im neuen Heldengenerator und Verwaltungstool für DSA5!</h2>
<h3>Viele Anpassungsmöglichkeiten</h3>
Die Cha5App hat viele Einstellungen zur Darstellung zu bieten. Dazu zählen u.A. Sortierfilter. Somit könnt ihr euch die Listen immer so anzeigen lassen, wie ihr sie gerade braucht. Aber auch empfohlene Fähigkeiten zählen dazu.
<p>
Die Cha5App hat viele Einstellungen zur Darstellung zu bieten. Dazu zählen u.A. Sortierfilter. Somit könnt ihr euch die Listen immer so anzeigen lassen, wie ihr sie gerade braucht. Aber auch empfohlene Fähigkeiten zählen dazu.
</p>
<h3>Helden teilen</h3>
Du wollt, dass auch mal jemand anderes einen Blick auf deinen Helden werfen kann, ohne dir über die Schulter zu schauen? Du wirst seinem Account in einem späteren Patch die Erlaubnis erteilen können, dies zu tun. Aber keine Angst, er wird nichts an ihm verändern können. OP bleibt OP.
<p>
Du wollt, dass auch mal jemand anderes einen Blick auf deinen Helden werfen kann, ohne dir über die Schulter zu schauen? Du wirst seinem Account in einem späteren Patch die Erlaubnis erteilen können, dies zu tun. Aber keine Angst, er wird nichts an ihm verändern können. OP bleibt OP.
</p>
<h3>Gruppen</h3>
Wir werden in einem späteren Patch eine Gruppenverwaltung hinzufügen. Dadurch können Gruppenmitglieder übersichtlich angezeigt und verglichen werden. Außerdem kann dieses Tool auch in-game dazu genutzt werden, die INI-Tabelle in Kombination mit Zustands- und Energieanzeigen darzustellen. Diese Ingame-Tabelle hatten wir vorher einmal unter dem Namen "GameApp" veröffentlicht. Wir werden dieses Tool für DSA5 umschreiben.
<p>
Wir werden in einem späteren Patch eine Gruppenverwaltung hinzufügen. Dadurch können Gruppenmitglieder übersichtlich angezeigt und verglichen werden. Außerdem kann dieses Tool auch in-game dazu genutzt werden, die INI-Tabelle in Kombination mit Zustands- und Energieanzeigen darzustellen. Diese Ingame-Tabelle hatten wir vorher einmal unter dem Namen "GameApp" veröffentlicht. Wir werden dieses Tool für DSA5 umschreiben.
</p>
<h3>Ein Wort zur Browserkompatibilität</h3>
Der Browser wurde mit den neuesten Versionen von Edge, Firefox und Chrome getestet. Die Software ist grundsätzlich darauf ausgelegt, dass der jeweilige Browser die Sprachenspezifikation ES5 (ECMAScript 5) vollständig unterstützt.
<p>
Der Browser wurde mit den neuesten Versionen von Edge, Firefox und Chrome getestet. Die Software ist grundsätzlich darauf ausgelegt, dass der jeweilige Browser die Sprachenspezifikation ES5 (ECMAScript 5) vollständig unterstützt.
</p>
<h3>Testen</h3>
<p>
Du möchtest dir nicht sofort ein Konto erstellen, sondern erstmal die Funktionen testen? Kein Problem! Wähle oben rechts einfach "Testen" aus. Du kannst dir damit testweise einen Helden erstellen, allerdings nicht speichern, drucken oder ein Avatarbild hochladen.
</p>
<p>
Wenn du dich dazu entscheidest, ein Konto zu erstellen, kannst du deinen soeben erstellten auch speichern und damit dann alle weiteren Funktionen nutzen. Du darfst vorher nur nicht diese Seite verlassen oder neu geladen haben!
</p>
</Scroll>
</div>
</section>
+1 -1
View File
@@ -32,7 +32,7 @@ var _heroes = {
phase: 2,
name: 'Yendan Keres',
avatar: 'images/portrait2.png',
ap: { _max: 1160, _used: 936 },
ap: { _max: 1160, _used: 937 },
el: 'EL_3',
r: 'R_1',
c: 'C_8',
+15
View File
@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../JSONStream/index.js" "$@"
ret=$?
else
node "$basedir/../JSONStream/index.js" "$@"
ret=$?
fi
exit $ret
+7
View File
@@ -0,0 +1,7 @@
@IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0\..\JSONStream\index.js" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\..\JSONStream\index.js" %*
)
+15
View File
@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../browser-pack/bin/cmd.js" "$@"
ret=$?
else
node "$basedir/../browser-pack/bin/cmd.js" "$@"
ret=$?
fi
exit $ret
+7
View File
@@ -0,0 +1,7 @@
@IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0\..\browser-pack\bin\cmd.js" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\..\browser-pack\bin\cmd.js" %*
)
+15
View File
@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../browserify/bin/cmd.js" "$@"
ret=$?
else
node "$basedir/../browserify/bin/cmd.js" "$@"
ret=$?
fi
exit $ret
+7
View File
@@ -0,0 +1,7 @@
@IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0\..\browserify\bin\cmd.js" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\..\browserify\bin\cmd.js" %*
)
+15
View File
@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../deps-sort/bin/cmd.js" "$@"
ret=$?
else
node "$basedir/../deps-sort/bin/cmd.js" "$@"
ret=$?
fi
exit $ret
+7
View File
@@ -0,0 +1,7 @@
@IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0\..\deps-sort\bin\cmd.js" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\..\deps-sort\bin\cmd.js" %*
)
+15
View File
@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../insert-module-globals/bin/cmd.js" "$@"
ret=$?
else
node "$basedir/../insert-module-globals/bin/cmd.js" "$@"
ret=$?
fi
exit $ret
+7
View File
@@ -0,0 +1,7 @@
@IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0\..\insert-module-globals\bin\cmd.js" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\..\insert-module-globals\bin\cmd.js" %*
)
+15
View File
@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../miller-rabin/bin/miller-rabin" "$@"
ret=$?
else
node "$basedir/../miller-rabin/bin/miller-rabin" "$@"
ret=$?
fi
exit $ret
+7
View File
@@ -0,0 +1,7 @@
@IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0\..\miller-rabin\bin\miller-rabin" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\..\miller-rabin\bin\miller-rabin" %*
)
+15
View File
@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../module-deps/bin/cmd.js" "$@"
ret=$?
else
node "$basedir/../module-deps/bin/cmd.js" "$@"
ret=$?
fi
exit $ret
+7
View File
@@ -0,0 +1,7 @@
@IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0\..\module-deps\bin\cmd.js" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\..\module-deps\bin\cmd.js" %*
)
Generated Vendored
+15
View File
@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../sha.js/bin.js" "$@"
ret=$?
else
node "$basedir/../sha.js/bin.js" "$@"
ret=$?
fi
exit $ret
+7
View File
@@ -0,0 +1,7 @@
@IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0\..\sha.js\bin.js" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\..\sha.js\bin.js" %*
)
Generated Vendored
+15
View File
@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../umd/bin/cli.js" "$@"
ret=$?
else
node "$basedir/../umd/bin/cli.js" "$@"
ret=$?
fi
exit $ret
Generated Vendored
+7
View File
@@ -0,0 +1,7 @@
@IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0\..\umd\bin\cli.js" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\..\umd\bin\cli.js" %*
)
Generated Vendored
+15
View File
@@ -0,0 +1,15 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/../watchify/bin/cmd.js" "$@"
ret=$?
else
node "$basedir/../watchify/bin/cmd.js" "$@"
ret=$?
fi
exit $ret
+7
View File
@@ -0,0 +1,7 @@
@IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0\..\watchify\bin\cmd.js" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\..\watchify\bin\cmd.js" %*
)
+2
View File
@@ -0,0 +1,2 @@
node_modules/*
node_modules
+7
View File
@@ -0,0 +1,7 @@
language: node_js
node_js:
- 4
- 5
- 6
+15
View File
@@ -0,0 +1,15 @@
Apache License, Version 2.0
Copyright (c) 2011 Dominic Tarr
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+24
View File
@@ -0,0 +1,24 @@
The MIT License
Copyright (c) 2011 Dominic Tarr
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.
+13
View File
@@ -0,0 +1,13 @@
var request = require('request')
, JSONStream = require('JSONStream')
, es = require('event-stream')
var parser = JSONStream.parse(['rows', true]) //emit parts that match this path (any element of the rows array)
, req = request({url: 'http://isaacs.couchone.com/registry/_all_docs'})
, logger = es.mapSync(function (data) { //create a stream that logs to stderr,
console.error(data)
return data
})
req.pipe(parser)
parser.pipe(logger)
+244
View File
@@ -0,0 +1,244 @@
#! /usr/bin/env node
'use strict'
var Parser = require('jsonparse')
, through = require('through')
/*
the value of this.stack that creationix's jsonparse has is weird.
it makes this code ugly, but his problem is way harder that mine,
so i'll forgive him.
*/
exports.parse = function (path, map) {
var header, footer
var parser = new Parser()
var stream = through(function (chunk) {
if('string' === typeof chunk)
chunk = new Buffer(chunk)
parser.write(chunk)
},
function (data) {
if(data)
stream.write(data)
if (header)
stream.emit('header', header)
if (footer)
stream.emit('footer', footer)
stream.queue(null)
})
if('string' === typeof path)
path = path.split('.').map(function (e) {
if (e === '$*')
return {emitKey: true}
else if (e === '*')
return true
else if (e === '') // '..'.split('.') returns an empty string
return {recurse: true}
else
return e
})
var count = 0, _key
if(!path || !path.length)
path = null
parser.onValue = function (value) {
if (!this.root)
stream.root = value
if(! path) return
var i = 0 // iterates on path
var j = 0 // iterates on stack
var emitKey = false;
while (i < path.length) {
var key = path[i]
var c
j++
if (key && !key.recurse) {
c = (j === this.stack.length) ? this : this.stack[j]
if (!c) return
if (! check(key, c.key)) {
setHeaderFooter(c.key, value)
return
}
emitKey = !!key.emitKey;
i++
} else {
i++
var nextKey = path[i]
if (! nextKey) return
while (true) {
c = (j === this.stack.length) ? this : this.stack[j]
if (!c) return
if (check(nextKey, c.key)) {
i++;
if (!Object.isFrozen(this.stack[j]))
this.stack[j].value = null
break
} else {
setHeaderFooter(c.key, value)
}
j++
}
}
}
if (j !== this.stack.length) return
count ++
var actualPath = this.stack.slice(1).map(function(element) { return element.key }).concat([this.key])
var data = this.value[this.key]
if(null != data)
if(null != (data = map ? map(data, actualPath) : data)) {
data = emitKey ? { value: data, key: this.key } : data;
stream.queue(data)
}
delete this.value[this.key]
for(var k in this.stack)
if (!Object.isFrozen(this.stack[k]))
this.stack[k].value = null
// emit header
if (header) {
stream.emit('header', header);
header = false;
}
}
parser._onToken = parser.onToken;
parser.onToken = function (token, value) {
parser._onToken(token, value);
if (this.stack.length === 0) {
if (stream.root) {
if(!path)
stream.queue(stream.root)
count = 0;
stream.root = null;
}
}
}
parser.onError = function (err) {
if(err.message.indexOf("at position") > -1)
err.message = "Invalid JSON (" + err.message + ")";
stream.emit('error', err)
}
return stream
function setHeaderFooter(key, value) {
// header has not been emitted yet
if (header !== false) {
header = header || {}
header[key] = value
}
// footer has not been emitted yet but header has
if (footer !== false && header === false) {
footer = footer || {}
footer[key] = value
}
}
}
function check (x, y) {
if ('string' === typeof x)
return y == x
else if (x && 'function' === typeof x.exec)
return x.exec(y)
else if ('boolean' === typeof x || 'object' === typeof x)
return x
else if ('function' === typeof x)
return x(y)
return false
}
exports.stringify = function (op, sep, cl, indent) {
indent = indent || 0
if (op === false){
op = ''
sep = '\n'
cl = ''
} else if (op == null) {
op = '[\n'
sep = '\n,\n'
cl = '\n]\n'
}
//else, what ever you like
var stream
, first = true
, anyData = false
stream = through(function (data) {
anyData = true
try {
var json = JSON.stringify(data, null, indent)
} catch (err) {
return stream.emit('error', err)
}
if(first) { first = false ; stream.queue(op + json)}
else stream.queue(sep + json)
},
function (data) {
if(!anyData)
stream.queue(op)
stream.queue(cl)
stream.queue(null)
})
return stream
}
exports.stringifyObject = function (op, sep, cl, indent) {
indent = indent || 0
if (op === false){
op = ''
sep = '\n'
cl = ''
} else if (op == null) {
op = '{\n'
sep = '\n,\n'
cl = '\n}\n'
}
//else, what ever you like
var first = true
var anyData = false
var stream = through(function (data) {
anyData = true
var json = JSON.stringify(data[0]) + ':' + JSON.stringify(data[1], null, indent)
if(first) { first = false ; this.queue(op + json)}
else this.queue(sep + json)
},
function (data) {
if(!anyData) this.queue(op)
this.queue(cl)
this.queue(null)
})
return stream
}
if(!module.parent && process.title !== 'browser') {
process.stdin
.pipe(exports.parse(process.argv[2]))
.pipe(exports.stringify('[', ',\n', ']\n', 2))
.pipe(process.stdout)
}
+108
View File
@@ -0,0 +1,108 @@
{
"_args": [
[
"JSONStream@^1.0.3",
"C:\\Users\\Lukas Obermann\\Projekte\\Cha5App\\code\\git\\node_modules\\browserify"
]
],
"_from": "JSONStream@>=1.0.3 <2.0.0",
"_id": "JSONStream@1.2.1",
"_inCache": true,
"_installable": true,
"_location": "/JSONStream",
"_nodeVersion": "6.4.0",
"_npmOperationalInternal": {
"host": "packages-16-east.internal.npmjs.com",
"tmp": "tmp/JSONStream-1.2.1.tgz_1474751953169_0.9057570598088205"
},
"_npmUser": {
"email": "dominic.tarr@gmail.com",
"name": "dominictarr"
},
"_npmVersion": "3.9.3",
"_phantomChildren": {},
"_requested": {
"name": "JSONStream",
"raw": "JSONStream@^1.0.3",
"rawSpec": "^1.0.3",
"scope": null,
"spec": ">=1.0.3 <2.0.0",
"type": "range"
},
"_requiredBy": [
"/browser-pack",
"/browserify",
"/deps-sort",
"/insert-module-globals",
"/module-deps"
],
"_resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.2.1.tgz",
"_shasum": "32aa5790e799481083b49b4b7fa94e23bae69bf9",
"_shrinkwrap": null,
"_spec": "JSONStream@^1.0.3",
"_where": "C:\\Users\\Lukas Obermann\\Projekte\\Cha5App\\code\\git\\node_modules\\browserify",
"author": {
"email": "dominic.tarr@gmail.com",
"name": "Dominic Tarr",
"url": "http://bit.ly/dominictarr"
},
"bin": {
"JSONStream": "./index.js"
},
"bugs": {
"url": "https://github.com/dominictarr/JSONStream/issues"
},
"dependencies": {
"jsonparse": "^1.2.0",
"through": ">=2.2.7 <3"
},
"description": "rawStream.pipe(JSONStream.parse()).pipe(streamOfObjects)",
"devDependencies": {
"assertions": "~2.2.2",
"event-stream": "~0.7.0",
"it-is": "~1",
"render": "~0.1.1",
"tape": "~2.12.3",
"trees": "~0.0.3"
},
"directories": {},
"dist": {
"shasum": "32aa5790e799481083b49b4b7fa94e23bae69bf9",
"tarball": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.2.1.tgz"
},
"engines": {
"node": "*"
},
"gitHead": "641402b48dbf3db5380e9bc857753c237d4ee9d9",
"homepage": "http://github.com/dominictarr/JSONStream",
"keywords": [
"json",
"stream",
"streaming",
"parser",
"async",
"parsing"
],
"license": "(MIT OR Apache-2.0)",
"maintainers": [
{
"email": "dominic.tarr@gmail.com",
"name": "dominictarr"
},
{
"email": "brian.woodward@gmail.com",
"name": "doowb"
}
],
"name": "JSONStream",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git://github.com/dominictarr/JSONStream.git"
},
"scripts": {
"test": "set -e; for t in test/*.js; do echo '***' $t '***'; node $t; done"
},
"version": "1.2.1"
}
+195
View File
@@ -0,0 +1,195 @@
# JSONStream
streaming JSON.parse and stringify
![](https://secure.travis-ci.org/dominictarr/JSONStream.png?branch=master)
## install
```npm install JSONStream```
## example
``` js
var request = require('request')
, JSONStream = require('JSONStream')
, es = require('event-stream')
request({url: 'http://isaacs.couchone.com/registry/_all_docs'})
.pipe(JSONStream.parse('rows.*'))
.pipe(es.mapSync(function (data) {
console.error(data)
return data
}))
```
## JSONStream.parse(path)
parse stream of values that match a path
``` js
JSONStream.parse('rows.*.doc')
```
The `..` operator is the recursive descent operator from [JSONPath](http://goessner.net/articles/JsonPath/), which will match a child at any depth (see examples below).
If your keys have keys that include `.` or `*` etc, use an array instead.
`['row', true, /^doc/]`.
If you use an array, `RegExp`s, booleans, and/or functions. The `..` operator is also available in array representation, using `{recurse: true}`.
any object that matches the path will be emitted as 'data' (and `pipe`d down stream)
If `path` is empty or null, no 'data' events are emitted.
If you want to have keys emitted, you can prefix your `*` operator with `$`: `obj.$*` - in this case the data passed to the stream is an object with a `key` holding the key and a `value` property holding the data.
### Examples
query a couchdb view:
``` bash
curl -sS localhost:5984/tests/_all_docs&include_docs=true
```
you will get something like this:
``` js
{"total_rows":129,"offset":0,"rows":[
{ "id":"change1_0.6995461115147918"
, "key":"change1_0.6995461115147918"
, "value":{"rev":"1-e240bae28c7bb3667f02760f6398d508"}
, "doc":{
"_id": "change1_0.6995461115147918"
, "_rev": "1-e240bae28c7bb3667f02760f6398d508","hello":1}
},
{ "id":"change2_0.6995461115147918"
, "key":"change2_0.6995461115147918"
, "value":{"rev":"1-13677d36b98c0c075145bb8975105153"}
, "doc":{
"_id":"change2_0.6995461115147918"
, "_rev":"1-13677d36b98c0c075145bb8975105153"
, "hello":2
}
},
]}
```
we are probably most interested in the `rows.*.doc`
create a `Stream` that parses the documents from the feed like this:
``` js
var stream = JSONStream.parse(['rows', true, 'doc']) //rows, ANYTHING, doc
stream.on('data', function(data) {
console.log('received:', data);
});
//emits anything from _before_ the first match
stream.on('header', function (data) {
console.log('header:', data) // => {"total_rows":129,"offset":0}
})
```
awesome!
In case you wanted the contents the doc emitted:
``` js
var stream = JSONStream.parse(['rows', true, 'doc', {emitKey: true}]) //rows, ANYTHING, doc, items in docs with keys
stream.on('data', function(data) {
console.log('key:', data.key);
console.log('value:', data.value);
});
```
### recursive patterns (..)
`JSONStream.parse('docs..value')`
(or `JSONStream.parse(['docs', {recurse: true}, 'value'])` using an array)
will emit every `value` object that is a child, grand-child, etc. of the
`docs` object. In this example, it will match exactly 5 times at various depth
levels, emitting 0, 1, 2, 3 and 4 as results.
```js
{
"total": 5,
"docs": [
{
"key": {
"value": 0,
"some": "property"
}
},
{"value": 1},
{"value": 2},
{"blbl": [{}, {"a":0, "b":1, "value":3}, 10]},
{"value": 4}
]
}
```
## JSONStream.parse(pattern, map)
provide a function that can be used to map or filter
the json output. `map` is passed the value at that node of the pattern,
if `map` return non-nullish (anything but `null` or `undefined`)
that value will be emitted in the stream. If it returns a nullish value,
nothing will be emitted.
`JSONStream` also emits `'header'` and `'footer'` events,
the `'header'` event contains anything in the output that was before
the first match, and the `'footer'`, is anything after the last match.
## JSONStream.stringify(open, sep, close)
Create a writable stream.
you may pass in custom `open`, `close`, and `seperator` strings.
But, by default, `JSONStream.stringify()` will create an array,
(with default options `open='[\n', sep='\n,\n', close='\n]\n'`)
If you call `JSONStream.stringify(false)`
the elements will only be seperated by a newline.
If you only write one item this will be valid JSON.
If you write many items,
you can use a `RegExp` to split it into valid chunks.
## JSONStream.stringifyObject(open, sep, close)
Very much like `JSONStream.stringify`,
but creates a writable stream for objects instead of arrays.
Accordingly, `open='{\n', sep='\n,\n', close='\n}\n'`.
When you `.write()` to the stream you must supply an array with `[ key, data ]`
as the first argument.
## unix tool
query npm to see all the modules that browserify has ever depended on.
``` bash
curl https://registry.npmjs.org/browserify | JSONStream 'versions.*.dependencies'
```
## numbers
numbers will be emitted as numbers.
huge numbers that cannot be represented in memory as javascript numbers will be emitted as strings.
cf https://github.com/creationix/jsonparse/commit/044b268f01c4b8f97fb936fc85d3bcfba179e5bb for details.
## Acknowlegements
this module depends on https://github.com/creationix/jsonparse
by Tim Caswell
and also thanks to Florent Jaby for teaching me about parsing with:
https://github.com/Floby/node-json-streams
## license
Dual-licensed under the MIT License or the Apache License, version 2.0
+41
View File
@@ -0,0 +1,41 @@
var fs = require ('fs')
, join = require('path').join
, file = join(__dirname, 'fixtures','all_npm.json')
, JSONStream = require('../')
, it = require('it-is').style('colour')
function randomObj () {
return (
Math.random () < 0.4
? {hello: 'eonuhckmqjk',
whatever: 236515,
lies: true,
nothing: [null],
// stuff: [Math.random(),Math.random(),Math.random()]
}
: ['AOREC', 'reoubaor', {ouec: 62642}, [[[], {}, 53]]]
)
}
var expected = []
, stringify = JSONStream.stringify()
, es = require('event-stream')
, stringified = ''
, called = 0
, count = 10
, ended = false
while (count --)
expected.push(randomObj())
es.connect(
es.readArray(expected),
stringify,
JSONStream.parse([true]),
es.writeArray(function (err, lines) {
it(lines).has(expected)
console.error('PASSED')
})
)
+18
View File
@@ -0,0 +1,18 @@
var test = require('tape')
var JSONStream = require('../')
var testData = '{"rows":[{"hello":"world"}, {"foo": "bar"}]}'
test('basic parsing', function (t) {
t.plan(2)
var parsed = JSONStream.parse("rows.*")
var parsedKeys = {}
parsed.on('data', function(match) {
parsedKeys[Object.keys(match)[0]] = true
})
parsed.on('end', function() {
t.equal(!!parsedKeys['hello'], true)
t.equal(!!parsedKeys['foo'], true)
})
parsed.write(testData)
parsed.end()
})
+27
View File
@@ -0,0 +1,27 @@
var fs = require ('fs');
var net = require('net');
var join = require('path').join;
var file = join(__dirname, 'fixtures','all_npm.json');
var JSONStream = require('../');
var server = net.createServer(function(client) {
var parser = JSONStream.parse([]);
parser.on('end', function() {
console.log('close')
console.error('PASSED');
server.close();
});
client.pipe(parser);
var n = 4
client.on('data', function () {
if(--n) return
client.end();
})
});
server.listen(9999);
var client = net.connect({ port : 9999 }, function() {
fs.createReadStream(file).pipe(client).on('data', console.log) //.resume();
});
+29
View File
@@ -0,0 +1,29 @@
var fs = require ('fs')
, join = require('path').join
, file = join(__dirname, 'fixtures','all_npm.json')
, JSONStream = require('../')
, it = require('it-is')
var expected = JSON.parse(fs.readFileSync(file))
, parser = JSONStream.parse('rows..rev')
, called = 0
, ended = false
, parsed = []
fs.createReadStream(file).pipe(parser)
parser.on('data', function (data) {
called ++
parsed.push(data)
})
parser.on('end', function () {
ended = true
})
process.on('exit', function () {
it(called).equal(expected.rows.length)
for (var i = 0 ; i < expected.rows.length ; i++)
it(parsed[i]).deepEqual(expected.rows[i].value.rev)
console.error('PASSED')
})
+29
View File
@@ -0,0 +1,29 @@
var fs = require ('fs')
, join = require('path').join
, file = join(__dirname, 'fixtures','depth.json')
, JSONStream = require('../')
, it = require('it-is')
var expected = JSON.parse(fs.readFileSync(file))
, parser = JSONStream.parse(['docs', {recurse: true}, 'value'])
, called = 0
, ended = false
, parsed = []
fs.createReadStream(file).pipe(parser)
parser.on('data', function (data) {
called ++
parsed.push(data)
})
parser.on('end', function () {
ended = true
})
process.on('exit', function () {
it(called).equal(5)
for (var i = 0 ; i < 5 ; i++)
it(parsed[i]).deepEqual(i)
console.error('PASSED')
})
+44
View File
@@ -0,0 +1,44 @@
var JSONStream = require('../')
, stream = require('stream')
, it = require('it-is')
var output = [ [], [] ]
var parser1 = JSONStream.parse(['docs', /./])
parser1.on('data', function(data) {
output[0].push(data)
})
var parser2 = JSONStream.parse(['docs', /./])
parser2.on('data', function(data) {
output[1].push(data)
})
var pending = 2
function onend () {
if (--pending > 0) return
it(output).deepEqual([
[], [{hello: 'world'}]
])
console.error('PASSED')
}
parser1.on('end', onend)
parser2.on('end', onend)
function makeReadableStream() {
var readStream = new stream.Stream()
readStream.readable = true
readStream.write = function (data) { this.emit('data', data) }
readStream.end = function (data) { this.emit('end') }
return readStream
}
var emptyArray = makeReadableStream()
emptyArray.pipe(parser1)
emptyArray.write('{"docs":[]}')
emptyArray.end()
var objectArray = makeReadableStream()
objectArray.pipe(parser2)
objectArray.write('{"docs":[{"hello":"world"}]}')
objectArray.end()
+45
View File
@@ -0,0 +1,45 @@
var fs = require ('fs')
, join = require('path').join
, file = join(__dirname, 'fixtures','error.json')
, JSONStream = require('../')
, it = require('it-is')
var expected = JSON.parse(fs.readFileSync(file))
, parser = JSONStream.parse(['rows'])
, called = 0
, headerCalled = 0
, footerCalled = 0
, ended = false
, parsed = []
fs.createReadStream(file).pipe(parser)
parser.on('header', function (data) {
headerCalled ++
it(data).deepEqual({
error: 'error_code',
message: 'this is an error message'
})
})
parser.on('footer', function (data) {
footerCalled ++
})
parser.on('data', function (data) {
called ++
parsed.push(data)
})
parser.on('end', function () {
ended = true
})
process.on('exit', function () {
it(called).equal(0)
it(headerCalled).equal(1)
it(footerCalled).equal(0)
console.error('PASSED')
})
File diff suppressed because it is too large Load Diff
+18
View File
@@ -0,0 +1,18 @@
{"total_rows":129,"offset":0,"rows":[
{ "id":"change1_0.6995461115147918"
, "key":"change1_0.6995461115147918"
, "value":{"rev":"1-e240bae28c7bb3667f02760f6398d508"}
, "doc":{
"_id": "change1_0.6995461115147918"
, "_rev": "1-e240bae28c7bb3667f02760f6398d508","hello":1}
},
{ "id":"change2_0.6995461115147918"
, "key":"change2_0.6995461115147918"
, "value":{"rev":"1-13677d36b98c0c075145bb8975105153"}
, "doc":{
"_id":"change2_0.6995461115147918"
, "_rev":"1-13677d36b98c0c075145bb8975105153"
, "hello":2
}
},
]}
+15
View File
@@ -0,0 +1,15 @@
{
"total": 5,
"docs": [
{
"key": {
"value": 0,
"some": "property"
}
},
{"value": 1},
{"value": 2},
{"blbl": [{}, {"a":0, "b":1, "value":3}, 10]},
{"value": 4}
]
}
+1
View File
@@ -0,0 +1 @@
{"error": "error_code", "message": "this is an error message"}
+19
View File
@@ -0,0 +1,19 @@
{"total_rows":129,"offset":0,"rows":[
{ "id":"change1_0.6995461115147918"
, "key":"change1_0.6995461115147918"
, "value":{"rev":"1-e240bae28c7bb3667f02760f6398d508"}
, "doc":{
"_id": "change1_0.6995461115147918"
, "_rev": "1-e240bae28c7bb3667f02760f6398d508","hello":1}
},
{ "id":"change2_0.6995461115147918"
, "key":"change2_0.6995461115147918"
, "value":{"rev":"1-13677d36b98c0c075145bb8975105153"}
, "doc":{
"_id":"change2_0.6995461115147918"
, "_rev":"1-13677d36b98c0c075145bb8975105153"
, "hello":2
}
}
],
"foo": {"bar": "baz"}}
+39
View File
@@ -0,0 +1,39 @@
var fs = require ('fs')
, join = require('path').join
, file = join(__dirname, 'fixtures','all_npm.json')
, JSONStream = require('../')
, it = require('it-is')
function fn (s) {
return !isNaN(parseInt(s, 10))
}
var expected = JSON.parse(fs.readFileSync(file))
, parser = JSONStream.parse(['rows', fn])
, called = 0
, ended = false
, parsed = []
fs.createReadStream(file).pipe(parser)
parser.on('data', function (data) {
called ++
it.has({
id: it.typeof('string'),
value: {rev: it.typeof('string')},
key:it.typeof('string')
})
parsed.push(data)
})
parser.on('end', function () {
ended = true
})
process.on('exit', function () {
it(called).equal(expected.rows.length)
it(parsed).deepEqual(expected.rows)
console.error('PASSED')
})
+135
View File
@@ -0,0 +1,135 @@
return // dont run this test for now since tape is weird and broken on 0.10
var fs = require('fs')
var JSONStream = require('../')
var file = process.argv[2] || '/tmp/JSONStream-test-large.json'
var size = Number(process.argv[3] || 100000)
var tape = require('tape')
// if (process.title !== 'browser') {
tape('out of mem', function (t) {
t.plan(1)
//////////////////////////////////////////////////////
// Produces a random number between arg1 and arg2
//////////////////////////////////////////////////////
var randomNumber = function (min, max) {
var number = Math.floor(Math.random() * (max - min + 1) + min);
return number;
};
//////////////////////////////////////////////////////
// Produces a random string of a length between arg1 and arg2
//////////////////////////////////////////////////////
var randomString = function (min, max) {
// add several spaces to increase chanses of creating 'words'
var chars = ' 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
var result = '';
var randomLength = randomNumber(min, max);
for (var i = randomLength; i > 0; --i) {
result += chars[Math.round(Math.random() * (chars.length - 1))];
}
return result;
};
//////////////////////////////////////////////////////
// Produces a random JSON document, as a string
//////////////////////////////////////////////////////
var randomJsonDoc = function () {
var doc = {
"CrashOccurenceID": randomNumber(10000, 50000),
"CrashID": randomNumber(1000, 10000),
"SiteName": randomString(10, 25),
"MachineName": randomString(10, 25),
"Date": randomString(26, 26),
"ProcessDuration": randomString(18, 18),
"ThreadIdentityName": null,
"WindowsIdentityName": randomString(15, 40),
"OperatingSystemName": randomString(35, 65),
"DetailedExceptionInformation": randomString(100, 800)
};
doc = JSON.stringify(doc);
doc = doc.replace(/\,/g, ',\n'); // add new lines after each attribute
return doc;
};
//////////////////////////////////////////////////////
// generates test data
//////////////////////////////////////////////////////
var generateTestData = function (cb) {
console.log('generating large data file...');
var stream = fs.createWriteStream(file, {
encoding: 'utf8'
});
var i = 0;
var max = size;
var writing = false
var split = ',\n';
var doc = randomJsonDoc();
stream.write('[');
function write () {
if(writing) return
writing = true
while(++i < max) {
if(Math.random() < 0.001)
console.log('generate..', i + ' / ' + size)
if(!stream.write(doc + split)) {
writing = false
return stream.once('drain', write)
}
}
stream.write(doc + ']')
stream.end();
console.log('END')
}
write()
stream.on('close', cb)
};
//////////////////////////////////////////////////////
// Shows that parsing 100000 instances using JSONStream fails
//
// After several seconds, you will get this crash
// FATAL ERROR: JS Allocation failed - process out of memory
//////////////////////////////////////////////////////
var testJSONStreamParse_causesOutOfMem = function (done) {
var items = 0
console.log('parsing data files using JSONStream...');
var parser = JSONStream.parse([true]);
var stream = fs.createReadStream(file);
stream.pipe(parser);
parser.on('data', function (data) {
items++
if(Math.random() < 0.01) console.log(items, '...')
});
parser.on('end', function () {
t.equal(items, size)
});
};
//////////////////////////////////////////////////////
// main
//////////////////////////////////////////////////////
fs.stat(file, function (err, stat) {
console.log(stat)
if(err)
generateTestData(testJSONStreamParse_causesOutOfMem);
else
testJSONStreamParse_causesOutOfMem()
})
})
// }
+54
View File
@@ -0,0 +1,54 @@
var fs = require ('fs')
, join = require('path').join
, file = join(__dirname, 'fixtures','header_footer.json')
, JSONStream = require('../')
, it = require('it-is')
var expected = JSON.parse(fs.readFileSync(file))
, parser = JSONStream.parse(['rows', /\d+/ /*, 'value'*/])
, called = 0
, headerCalled = 0
, footerCalled = 0
, ended = false
, parsed = []
fs.createReadStream(file).pipe(parser)
parser.on('header', function (data) {
headerCalled ++
it(data).deepEqual({
total_rows: 129,
offset: 0
})
})
parser.on('footer', function (data) {
footerCalled ++
it(data).deepEqual({
foo: { bar: 'baz' }
})
})
parser.on('data', function (data) {
called ++
it.has({
id: it.typeof('string'),
value: {rev: it.typeof('string')},
key:it.typeof('string')
})
parsed.push(data)
})
parser.on('end', function () {
ended = true
})
process.on('exit', function () {
it(called).equal(expected.rows.length)
it(headerCalled).equal(1)
it(footerCalled).equal(1)
it(parsed).deepEqual(expected.rows)
console.error('PASSED')
})
+34
View File
@@ -0,0 +1,34 @@
var JSONStream = require('../');
var test = require('tape')
test('#66', function (t) {
var error = 0;
var stream = JSONStream
.parse()
.on('error', function (err) {
t.ok(err);
error++;
})
.on('end', function () {
t.ok(error === 1);
t.end();
});
stream.write('["foo":bar[');
stream.end();
});
test('#81 - failure to parse nested objects', function (t) {
var stream = JSONStream
.parse('.bar.foo')
.on('error', function (err) {
t.error(err);
})
.on('end', function () {
t.end();
});
stream.write('{"bar":{"foo":"baz"}}');
stream.end();
});
+85
View File
@@ -0,0 +1,85 @@
var test = require('tape');
var fs = require ('fs');
var join = require('path').join;
var couch_sample_file = join(__dirname, 'fixtures','couch_sample.json');
var JSONStream = require('../');
var fixture = {
obj: {
one: 1,
two: 2,
three: 3
}
};
function assertFixtureKeys(stream, t) {
var keys = [];
var values = [];
stream.on('data', function(data) {
keys.push(data.key);
values.push(data.value);
});
stream.on('end', function() {
t.deepEqual(keys, ['one', 'two', 'three']);
t.deepEqual(values, [1,2,3]);
t.end();
});
stream.write(JSON.stringify(fixture));
stream.end();
}
test('keys via string', function(t) {
var stream = JSONStream.parse('obj.$*');
assertFixtureKeys(stream, t);
});
test('keys via array', function(t) {
var stream = JSONStream.parse(['obj',{emitKey: true}]);
assertFixtureKeys(stream, t);
});
test('advanced keys', function(t) {
var advanced = fs.readFileSync(couch_sample_file);
var stream = JSONStream.parse(['rows', true, 'doc', {emitKey: true}]);
var keys = [];
var values = [];
stream.on('data', function(data) {
keys.push(data.key);
values.push(data.value);
});
stream.on('end', function() {
t.deepEqual(keys, [
'_id', '_rev', 'hello',
'_id', '_rev', 'hello'
]);
t.deepEqual(values, [
"change1_0.6995461115147918", "1-e240bae28c7bb3667f02760f6398d508", 1,
"change2_0.6995461115147918", "1-13677d36b98c0c075145bb8975105153", 2
]);
t.end();
});
stream.write(advanced);
stream.end();
});
test('parent keys', function(t) {
var stream = JSONStream.parse('$*');
var d = null;
stream.on('data', function(data) {
if(d) t.fail('should only be called once');
d = data;
});
stream.on('end', function() {
t.deepEqual(d,{
key: 'obj',
value: fixture.obj
});
t.end();
});
stream.write(JSON.stringify(fixture));
stream.end();
})
+40
View File
@@ -0,0 +1,40 @@
var test = require('tape')
var JSONStream = require('../')
test('map function', function (t) {
var actual = []
stream = JSONStream.parse([true], function (e) { return e*10 })
stream.on('data', function (v) { actual.push(v)})
stream.on('end', function () {
t.deepEqual(actual, [10,20,30,40,50,60])
t.end()
})
stream.write(JSON.stringify([1,2,3,4,5,6], null, 2))
stream.end()
})
test('filter function', function (t) {
var actual = []
stream = JSONStream
.parse([true], function (e) { return e%2 ? e : null})
.on('data', function (v) { actual.push(v)})
.on('end', function () {
t.deepEqual(actual, [1,3,5])
t.end()
})
stream.write(JSON.stringify([1,2,3,4,5,6], null, 2))
stream.end()
})
+36
View File
@@ -0,0 +1,36 @@
var fs = require ('fs');
var net = require('net');
var join = require('path').join;
var file = join(__dirname, 'fixtures','all_npm.json');
var it = require('it-is');
var JSONStream = require('../');
var str = fs.readFileSync(file);
var datas = {}
var server = net.createServer(function(client) {
var data_calls = 0;
var parser = JSONStream.parse(['rows', true, 'key']);
parser.on('data', function(data) {
++ data_calls;
datas[data] = (datas[data] || 0) + 1
it(data).typeof('string')
});
parser.on('end', function() {
console.log('END')
var min = Infinity
for (var d in datas)
min = min > datas[d] ? datas[d] : min
it(min).equal(3);
server.close();
});
client.pipe(parser);
});
server.listen(9999);
var client = net.connect({ port : 9999 }, function() {
var msgs = str + ' ' + str + '\n\n' + str
client.end(msgs);
});
+29
View File
@@ -0,0 +1,29 @@
var fs = require ('fs');
var net = require('net');
var join = require('path').join;
var file = join(__dirname, 'fixtures','all_npm.json');
var it = require('it-is');
var JSONStream = require('../');
var str = fs.readFileSync(file);
var server = net.createServer(function(client) {
var data_calls = 0;
var parser = JSONStream.parse();
parser.on('error', function(err) {
console.log(err);
server.close();
});
parser.on('end', function() {
console.log('END');
server.close();
});
client.pipe(parser);
});
server.listen(9999);
var client = net.connect({ port : 9999 }, function() {
var msgs = str + '}';
client.end(msgs);
});
+28
View File
@@ -0,0 +1,28 @@
var JSONStream = require('../')
var data = [
{ID: 1, optional: null},
{ID: 2, optional: null},
{ID: 3, optional: 20},
{ID: 4, optional: null},
{ID: 5, optional: 'hello'},
{ID: 6, optional: null}
]
var test = require('tape')
test ('null properties', function (t) {
var actual = []
var stream =
JSONStream.parse('*.optional')
.on('data', function (v) { actual.push(v) })
.on('end', function () {
t.deepEqual(actual, [20, 'hello'])
t.end()
})
stream.write(JSON.stringify(data, null, 2))
stream.end()
})
+25
View File
@@ -0,0 +1,25 @@
/*
sometimes jsonparse changes numbers slightly.
*/
var r = Math.random()
, Parser = require('jsonparse')
, p = new Parser()
, assert = require('assert')
, times = 20
while (times --) {
assert.equal(JSON.parse(JSON.stringify(r)), r, 'core JSON')
p.onValue = function (v) {
console.error('parsed', v)
assert.equal(v,r)
}
console.error('correct', r)
p.write (new Buffer(JSON.stringify([r])))
}
+41
View File
@@ -0,0 +1,41 @@
var fs = require ('fs')
, join = require('path').join
, file = join(__dirname, 'fixtures','all_npm.json')
, JSONStream = require('../')
, it = require('it-is').style('colour')
function randomObj () {
return (
Math.random () < 0.4
? {hello: 'eonuhckmqjk',
whatever: 236515,
lies: true,
nothing: [null],
stuff: [Math.random(),Math.random(),Math.random()]
}
: ['AOREC', 'reoubaor', {ouec: 62642}, [[[], {}, 53]]]
)
}
var expected = []
, stringify = JSONStream.stringify()
, es = require('event-stream')
, stringified = ''
, called = 0
, count = 10
, ended = false
while (count --)
expected.push(randomObj())
es.connect(
es.readArray(expected),
stringify,
//JSONStream.parse([/./]),
es.writeArray(function (err, lines) {
it(JSON.parse(lines.join(''))).deepEqual(expected)
console.error('PASSED')
})
)
+47
View File
@@ -0,0 +1,47 @@
var fs = require ('fs')
, join = require('path').join
, file = join(__dirname, 'fixtures','all_npm.json')
, JSONStream = require('../')
, it = require('it-is').style('colour')
, es = require('event-stream')
, pending = 10
, passed = true
function randomObj () {
return (
Math.random () < 0.4
? {hello: 'eonuhckmqjk',
whatever: 236515,
lies: true,
nothing: [null],
stuff: [Math.random(),Math.random(),Math.random()]
}
: ['AOREC', 'reoubaor', {ouec: 62642}, [[[], {}, 53]]]
)
}
for (var ix = 0; ix < pending; ix++) (function (count) {
var expected = {}
, stringify = JSONStream.stringifyObject()
es.connect(
stringify,
es.writeArray(function (err, lines) {
it(JSON.parse(lines.join(''))).deepEqual(expected)
if (--pending === 0) {
console.error('PASSED')
}
})
)
while (count --) {
var key = Math.random().toString(16).slice(2)
expected[key] = randomObj()
stringify.write([ key, expected[key] ])
}
process.nextTick(function () {
stringify.end()
})
})(ix)
+35
View File
@@ -0,0 +1,35 @@
var fs = require ('fs')
, join = require('path').join
, file = join(__dirname, 'fixtures','all_npm.json')
, JSONStream = require('../')
, it = require('it-is')
var expected = JSON.parse(fs.readFileSync(file))
, parser = JSONStream.parse(['rows', /\d+/ /*, 'value'*/])
, called = 0
, ended = false
, parsed = []
fs.createReadStream(file).pipe(parser)
parser.on('data', function (data) {
called ++
it.has({
id: it.typeof('string'),
value: {rev: it.typeof('string')},
key:it.typeof('string')
})
parsed.push(data)
})
parser.on('end', function () {
ended = true
})
process.on('exit', function () {
it(called).equal(expected.rows.length)
it(parsed).deepEqual(expected.rows)
console.error('PASSED')
})
+29
View File
@@ -0,0 +1,29 @@
var fs = require ('fs')
, join = require('path').join
, file = join(__dirname, '..','package.json')
, JSONStream = require('../')
, it = require('it-is')
var expected = JSON.parse(fs.readFileSync(file))
, parser = JSONStream.parse([])
, called = 0
, ended = false
, parsed = []
fs.createReadStream(file).pipe(parser)
parser.on('data', function (data) {
called ++
it(data).deepEqual(expected)
})
parser.on('end', function () {
ended = true
})
process.on('exit', function () {
it(called).equal(1)
console.error('PASSED')
})
+41
View File
@@ -0,0 +1,41 @@
var fs = require ('fs')
, join = require('path').join
, file = join(__dirname, 'fixtures','all_npm.json')
, JSONStream = require('../')
, it = require('it-is').style('colour')
function randomObj () {
return (
Math.random () < 0.4
? {hello: 'eonuhckmqjk',
whatever: 236515,
lies: true,
nothing: [null],
// stuff: [Math.random(),Math.random(),Math.random()]
}
: ['AOREC', 'reoubaor', {ouec: 62642}, [[[], {}, 53]]]
)
}
var expected = []
, stringify = JSONStream.stringify()
, es = require('event-stream')
, stringified = ''
, called = 0
, count = 10
, ended = false
while (count --)
expected.push(randomObj())
es.connect(
es.readArray(expected),
stringify,
JSONStream.parse([/./]),
es.writeArray(function (err, lines) {
it(lines).has(expected)
console.error('PASSED')
})
)
+15
View File
@@ -0,0 +1,15 @@
The ISC License
Copyright (c) 2014 Elan Shanker
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+91
View File
@@ -0,0 +1,91 @@
anymatch [![Build Status](https://travis-ci.org/es128/anymatch.svg?branch=master)](https://travis-ci.org/es128/anymatch) [![Coverage Status](https://img.shields.io/coveralls/es128/anymatch.svg?branch=master)](https://coveralls.io/r/es128/anymatch?branch=master)
======
Javascript module to match a string against a regular expression, glob, string,
or function that takes the string as an argument and returns a truthy or falsy
value. The matcher can also be an array of any or all of these. Useful for
allowing a very flexible user-defined config to define things like file paths.
[![NPM](https://nodei.co/npm/anymatch.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/anymatch/)
[![NPM](https://nodei.co/npm-dl/anymatch.png?height=3&months=9)](https://nodei.co/npm-dl/anymatch/)
Usage
-----
```sh
npm install anymatch --save
```
#### anymatch (matchers, testString, [returnIndex], [startIndex], [endIndex])
* __matchers__: (_Array|String|RegExp|Function_)
String to be directly matched, string with glob patterns, regular expression
test, function that takes the testString as an argument and returns a truthy
value if it should be matched, or an array of any number and mix of these types.
* __testString__: (_String|Array_) The string to test against the matchers. If
passed as an array, the first element of the array will be used as the
`testString` for non-function matchers, while the entire array will be applied
as the arguments for function matchers.
* __returnIndex__: (_Boolean [optional]_) If true, return the array index of
the first matcher that that testString matched, or -1 if no match, instead of a
boolean result.
* __startIndex, endIndex__: (_Integer [optional]_) Can be used to define a
subset out of the array of provided matchers to test against. Can be useful
with bound matcher functions (see below). When used with `returnIndex = true`
preserves original indexing. Behaves the same as `Array.prototype.slice` (i.e.
includes array members up to, but not including endIndex).
```js
var anymatch = require('anymatch');
var matchers = [
'path/to/file.js',
'path/anyjs/**/*.js',
/foo.js$/,
function (string) {
return string.indexOf('bar') !== -1 && string.length > 10
}
];
anymatch(matchers, 'path/to/file.js'); // true
anymatch(matchers, 'path/anyjs/baz.js'); // true
anymatch(matchers, 'path/to/foo.js'); // true
anymatch(matchers, 'path/to/bar.js'); // true
anymatch(matchers, 'bar.js'); // false
// returnIndex = true
anymatch(matchers, 'foo.js', true); // 2
anymatch(matchers, 'path/anyjs/foo.js', true); // 1
// skip matchers
anymatch(matchers, 'path/to/file.js', false, 1); // false
anymatch(matchers, 'path/anyjs/foo.js', true, 2, 3); // 2
anymatch(matchers, 'path/to/bar.js', true, 0, 3); // -1
```
#### anymatch (matchers)
You can also pass in only your matcher(s) to get a curried function that has
already been bound to the provided matching criteria. This can be used as an
`Array.prototype.filter` callback.
```js
var matcher = anymatch(matchers);
matcher('path/to/file.js'); // true
matcher('path/anyjs/baz.js', true); // 1
matcher('path/anyjs/baz.js', true, 2); // -1
['foo.js', 'bar.js'].filter(matcher); // ['foo.js']
```
Change Log
----------
[See release notes page on GitHub](https://github.com/es128/anymatch/releases)
NOTE: As of v1.2.0, anymatch uses [micromatch](https://github.com/jonschlinkert/micromatch)
for glob pattern matching. The glob matching behavior should be functionally
equivalent to the commonly used [minimatch](https://github.com/isaacs/minimatch)
library (aside from some fixed bugs and greater performance), so a major
version bump wasn't merited. Issues with glob pattern matching should be
reported directly to the [micromatch issue tracker](https://github.com/jonschlinkert/micromatch/issues).
License
-------
[ISC](https://raw.github.com/es128/anymatch/master/LICENSE)
+64
View File
@@ -0,0 +1,64 @@
'use strict';
var arrify = require('arrify');
var micromatch = require('micromatch');
var path = require('path');
var anymatch = function(criteria, value, returnIndex, startIndex, endIndex) {
criteria = arrify(criteria);
value = arrify(value);
if (arguments.length === 1) {
return anymatch.bind(null, criteria.map(function(criterion) {
return typeof criterion === 'string' && criterion[0] !== '!' ?
micromatch.matcher(criterion) : criterion;
}));
}
startIndex = startIndex || 0;
var string = value[0];
var altString;
var matched = false;
var matchIndex = -1;
function testCriteria (criterion, index) {
var result;
switch (toString.call(criterion)) {
case '[object String]':
result = string === criterion || altString && altString === criterion;
result = result || micromatch.isMatch(string, criterion);
break;
case '[object RegExp]':
result = criterion.test(string) || altString && criterion.test(altString);
break;
case '[object Function]':
result = criterion.apply(null, value);
break;
default:
result = false;
}
if (result) {
matchIndex = index + startIndex;
}
return result;
}
var crit = criteria;
var negGlobs = crit.reduce(function(arr, criterion, index) {
if (typeof criterion === 'string' && criterion[0] === '!') {
if (crit === criteria) {
// make a copy before modifying
crit = crit.slice();
}
crit[index] = null;
arr.push(criterion.substr(1));
}
return arr;
}, []);
if (!negGlobs.length || !micromatch.any(string, negGlobs)) {
if (path.sep === '\\' && typeof string === 'string') {
altString = string.split('\\').join('/');
altString = altString === string ? null : altString;
}
matched = crit.slice(startIndex, endIndex).some(testCriteria);
}
return returnIndex === true ? matchIndex : matched;
};
module.exports = anymatch;
+96
View File
@@ -0,0 +1,96 @@
{
"_args": [
[
"anymatch@^1.3.0",
"C:\\Users\\Lukas Obermann\\Projekte\\Cha5App\\code\\git\\node_modules\\watchify"
]
],
"_from": "anymatch@>=1.3.0 <2.0.0",
"_id": "anymatch@1.3.0",
"_inCache": true,
"_installable": true,
"_location": "/anymatch",
"_nodeVersion": "1.6.2",
"_npmUser": {
"email": "elan.shanker+npm@gmail.com",
"name": "es128"
},
"_npmVersion": "2.7.3",
"_phantomChildren": {},
"_requested": {
"name": "anymatch",
"raw": "anymatch@^1.3.0",
"rawSpec": "^1.3.0",
"scope": null,
"spec": ">=1.3.0 <2.0.0",
"type": "range"
},
"_requiredBy": [
"/chokidar",
"/watchify"
],
"_resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.0.tgz",
"_shasum": "a3e52fa39168c825ff57b0248126ce5a8ff95507",
"_shrinkwrap": null,
"_spec": "anymatch@^1.3.0",
"_where": "C:\\Users\\Lukas Obermann\\Projekte\\Cha5App\\code\\git\\node_modules\\watchify",
"author": {
"name": "Elan Shanker",
"url": "http://github.com/es128"
},
"bugs": {
"url": "https://github.com/es128/anymatch/issues"
},
"dependencies": {
"arrify": "^1.0.0",
"micromatch": "^2.1.5"
},
"description": "Matches strings against configurable strings, globs, regular expressions, and/or functions",
"devDependencies": {
"coveralls": "^2.11.2",
"istanbul": "^0.3.13",
"mocha": "^2.2.4"
},
"directories": {},
"dist": {
"shasum": "a3e52fa39168c825ff57b0248126ce5a8ff95507",
"tarball": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.0.tgz"
},
"files": [
"index.js"
],
"gitHead": "253d2ad42f644ed18557f561312a7f8426daca84",
"homepage": "https://github.com/es128/anymatch",
"keywords": [
"match",
"any",
"string",
"file",
"fs",
"list",
"glob",
"regex",
"regexp",
"regular",
"expression",
"function"
],
"license": "ISC",
"maintainers": [
{
"email": "elan.shanker+npm@gmail.com",
"name": "es128"
}
],
"name": "anymatch",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git+https://github.com/es128/anymatch.git"
},
"scripts": {
"test": "istanbul cover _mocha && cat ./coverage/lcov.info | coveralls"
},
"version": "1.3.0"
}
+1
View File
@@ -0,0 +1 @@
node_modules
+4
View File
@@ -0,0 +1,4 @@
language: node_js
node_js:
- "0.8"
- "0.10"
+54
View File
@@ -0,0 +1,54 @@
# array-filter
`Array#filter` for older browsers.
[![testling badge](https://ci.testling.com/juliangruber/array-filter.png)](https://ci.testling.com/juliangruber/array-filter)
[![build status](https://secure.travis-ci.org/juliangruber/array-filter.png)](http://travis-ci.org/juliangruber/array-filter)
## Usage
```js
var filter = require('array-filter');
var array = [1, 2, 3];
console.log(filter(array, function (el, i, arr) {
return false; // I throw it on the ground!
}));
// => []
```
## Installation
With [npm](http://npmjs.org) do
```bash
$ npm install array-filter
```
Then bundle for the browser with [browserify](https://github.com/substack/browserify).
## License
(MIT)
Copyright (c) 2013 Julian Gruber &lt;julian@juliangruber.com&gt;
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.
+19
View File
@@ -0,0 +1,19 @@
/**
* Array#filter.
*
* @param {Array} arr
* @param {Function} fn
* @return {Array}
*/
module.exports = function (arr, fn) {
if (arr.filter) return arr.filter(fn);
var ret = [];
for (var i = 0; i < arr.length; i++) {
if (!hasOwn.call(arr, i)) continue;
if (fn(arr[i], i, arr)) ret.push(arr[i]);
}
return ret;
};
var hasOwn = Object.prototype.hasOwnProperty;
+96
View File
@@ -0,0 +1,96 @@
{
"_args": [
[
"array-filter@~0.0.0",
"C:\\Users\\Lukas Obermann\\Projekte\\Cha5App\\code\\git\\node_modules\\shell-quote"
]
],
"_from": "array-filter@>=0.0.0 <0.1.0",
"_id": "array-filter@0.0.1",
"_inCache": true,
"_installable": true,
"_location": "/array-filter",
"_npmUser": {
"email": "julian@juliangruber.com",
"name": "juliangruber"
},
"_npmVersion": "1.3.11",
"_phantomChildren": {},
"_requested": {
"name": "array-filter",
"raw": "array-filter@~0.0.0",
"rawSpec": "~0.0.0",
"scope": null,
"spec": ">=0.0.0 <0.1.0",
"type": "range"
},
"_requiredBy": [
"/shell-quote"
],
"_resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz",
"_shasum": "7da8cf2e26628ed732803581fd21f67cacd2eeec",
"_shrinkwrap": null,
"_spec": "array-filter@~0.0.0",
"_where": "C:\\Users\\Lukas Obermann\\Projekte\\Cha5App\\code\\git\\node_modules\\shell-quote",
"author": {
"email": "mail@juliangruber.com",
"name": "Julian Gruber",
"url": "http://juliangruber.com"
},
"bugs": {
"url": "https://github.com/juliangruber/array-filter/issues"
},
"dependencies": {},
"description": "Array#filter for older browsers.",
"devDependencies": {
"tape": "~2.3.2"
},
"directories": {},
"dist": {
"shasum": "7da8cf2e26628ed732803581fd21f67cacd2eeec",
"tarball": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz"
},
"homepage": "https://github.com/juliangruber/array-filter",
"keywords": [
"array",
"filter",
"browser",
"html",
"browserify"
],
"license": "MIT",
"main": "index.js",
"maintainers": [
{
"email": "julian@juliangruber.com",
"name": "juliangruber"
}
],
"name": "array-filter",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git://github.com/juliangruber/array-filter.git"
},
"scripts": {
"test": "tape test/*.js"
},
"testling": {
"browsers": [
"ie/8..latest",
"firefox/17..latest",
"firefox/nightly",
"chrome/22..latest",
"chrome/canary",
"opera/12..latest",
"opera/next",
"safari/5.1..latest",
"ipad/6.0..latest",
"iphone/6.0..latest",
"android-browser/4.2..latest"
],
"files": "test/*.js"
},
"version": "0.0.1"
}
+12
View File
@@ -0,0 +1,12 @@
var filter = require('..');
var test = require('tape');
test('filter', function(t) {
var arr = [1, 2, 3, 4, 5];
delete arr.filter;
var even = filter(arr, function(el) {
return el % 2 == 0;
});
t.deepEqual(even, [2, 4]);
t.end();
});
+12
View File
@@ -0,0 +1,12 @@
var filter = require('..');
var test = require('tape');
test('skip over holes', function(t) {
var arr = new Array(5);
delete arr.filter;
var res = filter(arr, function(el) {
return false;
});
t.deepEqual(res, []);
t.end();
});
+16 -13
View File
@@ -2,20 +2,24 @@
"_args": [
[
"array-find-index@^1.0.1",
"c:\\Users\\Lukas Obermann\\Projekte\\Cha5App\\code\\nodejs_web\\node_modules\\currently-unhandled"
"C:\\Users\\Lukas Obermann\\Projekte\\Cha5App\\code\\git\\node_modules\\currently-unhandled"
]
],
"_from": "array-find-index@>=1.0.1 <2.0.0",
"_id": "array-find-index@1.0.1",
"_id": "array-find-index@1.0.2",
"_inCache": true,
"_installable": true,
"_location": "/array-find-index",
"_nodeVersion": "4.2.4",
"_nodeVersion": "4.5.0",
"_npmOperationalInternal": {
"host": "packages-12-west.internal.npmjs.com",
"tmp": "tmp/array-find-index-1.0.2.tgz_1475224789159_0.7274378235451877"
},
"_npmUser": {
"email": "sindresorhus@gmail.com",
"name": "sindresorhus"
},
"_npmVersion": "2.14.12",
"_npmVersion": "2.15.9",
"_phantomChildren": {},
"_requested": {
"name": "array-find-index",
@@ -28,11 +32,11 @@
"_requiredBy": [
"/currently-unhandled"
],
"_resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.1.tgz",
"_shasum": "0bc25ddac941ec8a496ae258fd4ac188003ef3af",
"_resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
"_shasum": "df010aa1287e164bbda6f9723b0a96a1ec4187a1",
"_shrinkwrap": null,
"_spec": "array-find-index@^1.0.1",
"_where": "c:\\Users\\Lukas Obermann\\Projekte\\Cha5App\\code\\nodejs_web\\node_modules\\currently-unhandled",
"_where": "C:\\Users\\Lukas Obermann\\Projekte\\Cha5App\\code\\git\\node_modules\\currently-unhandled",
"author": {
"email": "sindresorhus@gmail.com",
"name": "Sindre Sorhus",
@@ -49,8 +53,8 @@
},
"directories": {},
"dist": {
"shasum": "0bc25ddac941ec8a496ae258fd4ac188003ef3af",
"tarball": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.1.tgz"
"shasum": "df010aa1287e164bbda6f9723b0a96a1ec4187a1",
"tarball": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz"
},
"engines": {
"node": ">=0.10.0"
@@ -58,10 +62,9 @@
"files": [
"index.js"
],
"gitHead": "0b2eea2c3e42aeb97be82b50f64a5672d2847036",
"homepage": "https://github.com/sindresorhus/array-find-index",
"gitHead": "983f4c827ad22fa0353182b1ddcbfaecd4412859",
"homepage": "https://github.com/sindresorhus/array-find-index#readme",
"keywords": [
"es6",
"es2015",
"ponyfill",
"polyfill",
@@ -88,5 +91,5 @@
"scripts": {
"test": "xo && ava"
},
"version": "1.0.1"
"version": "1.0.2"
}
+3 -5
View File
@@ -1,8 +1,6 @@
# array-find-index [![Build Status](https://travis-ci.org/sindresorhus/array-find-index.svg?branch=master)](https://travis-ci.org/sindresorhus/array-find-index)
> ES2015 [`Array#findIndex()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex) ponyfill
> Ponyfill: A polyfill that doesn't overwrite the native method
> ES2015 [`Array#findIndex()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex) [ponyfill](https://ponyfill.com)
## Install
@@ -15,7 +13,7 @@ $ npm install --save array-find-index
## Usage
```js
arrayFindIndex = require('array-find-index');
const arrayFindIndex = require('array-find-index');
arrayFindIndex(['rainbow', 'unicorn', 'pony'], x => x === 'unicorn');
//=> 1
@@ -29,4 +27,4 @@ Same as `Array#findIndex()`, but with the input array as the first argument.
## License
MIT © [Sindre Sorhus](http://sindresorhus.com)
MIT © [Sindre Sorhus](https://sindresorhus.com)
+4
View File
@@ -0,0 +1,4 @@
language: node_js
node_js:
- "0.8"
- "0.10"
+18
View File
@@ -0,0 +1,18 @@
This software is released under the MIT license:
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.
+5
View File
@@ -0,0 +1,5 @@
var map = require('../');
var letters = map([97,98,99], function (c) {
return String.fromCharCode(c);
});
console.log(letters.join(''));
+11
View File
@@ -0,0 +1,11 @@
module.exports = function (xs, f) {
if (xs.map) return xs.map(f);
var res = [];
for (var i = 0; i < xs.length; i++) {
var x = xs[i];
if (hasOwn.call(xs, i)) res.push(f(x, i, xs));
}
return res;
};
var hasOwn = Object.prototype.hasOwnProperty;
+100
View File
@@ -0,0 +1,100 @@
{
"_args": [
[
"array-map@~0.0.0",
"C:\\Users\\Lukas Obermann\\Projekte\\Cha5App\\code\\git\\node_modules\\shell-quote"
]
],
"_from": "array-map@>=0.0.0 <0.1.0",
"_id": "array-map@0.0.0",
"_inCache": true,
"_installable": true,
"_location": "/array-map",
"_npmUser": {
"email": "mail@substack.net",
"name": "substack"
},
"_npmVersion": "1.3.21",
"_phantomChildren": {},
"_requested": {
"name": "array-map",
"raw": "array-map@~0.0.0",
"rawSpec": "~0.0.0",
"scope": null,
"spec": ">=0.0.0 <0.1.0",
"type": "range"
},
"_requiredBy": [
"/shell-quote"
],
"_resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz",
"_shasum": "88a2bab73d1cf7bcd5c1b118a003f66f665fa662",
"_shrinkwrap": null,
"_spec": "array-map@~0.0.0",
"_where": "C:\\Users\\Lukas Obermann\\Projekte\\Cha5App\\code\\git\\node_modules\\shell-quote",
"author": {
"email": "mail@substack.net",
"name": "James Halliday",
"url": "http://substack.net"
},
"bugs": {
"url": "https://github.com/substack/array-map/issues"
},
"dependencies": {},
"description": "`[].map(f)` for older browsers",
"devDependencies": {
"tape": "~2.3.2"
},
"directories": {},
"dist": {
"shasum": "88a2bab73d1cf7bcd5c1b118a003f66f665fa662",
"tarball": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz"
},
"homepage": "https://github.com/substack/array-map",
"keywords": [
"array",
"map",
"browser",
"es5",
"shim",
"ie6",
"ie7",
"ie8"
],
"license": "MIT",
"main": "index.js",
"maintainers": [
{
"email": "mail@substack.net",
"name": "substack"
}
],
"name": "array-map",
"optionalDependencies": {},
"readme": "# array-map\n\n`[].map(f)` for older browsers\n\n[![testling badge](https://ci.testling.com/substack/array-map.png)](https://ci.testling.com/substack/array-map)\n\n[![build status](https://secure.travis-ci.org/substack/array-map.png)](http://travis-ci.org/substack/array-map)\n\n# example\n\n``` js\nvar map = require('array-map');\nvar letters = map([97,98,99], function (c) {\n return String.fromCharCode(c);\n});\nconsole.log(letters.join(''));\n```\n\noutput:\n\n```\nabc\n```\n\n# methods\n\n``` js\nvar map = require('array-map')\n```\n\n## var ys = map(xs, f)\n\nCreate a new array `ys` by applying `f(xs[i], i, xs)` to each element in `xs` at\nindex `i`.\n\n# install\n\nWith [npm](https://npmjs.org) do:\n\n```\nnpm install array-map\n```\n\n# license\n\nMIT\n",
"readmeFilename": "readme.markdown",
"repository": {
"type": "git",
"url": "git://github.com/substack/array-map.git"
},
"scripts": {
"test": "tape test/*.js"
},
"testling": {
"browsers": [
"ie/6..latest",
"firefox/3.5",
"firefox/latest",
"chrome/5",
"chrome/latest",
"opera/12..latest",
"opera/next",
"safari/5.1..latest",
"ipad/6.0..latest",
"iphone/6.0..latest",
"android-browser/4.2..latest"
],
"files": "test/*.js"
},
"version": "0.0.0"
}
+46
View File
@@ -0,0 +1,46 @@
# array-map
`[].map(f)` for older browsers
[![testling badge](https://ci.testling.com/substack/array-map.png)](https://ci.testling.com/substack/array-map)
[![build status](https://secure.travis-ci.org/substack/array-map.png)](http://travis-ci.org/substack/array-map)
# example
``` js
var map = require('array-map');
var letters = map([97,98,99], function (c) {
return String.fromCharCode(c);
});
console.log(letters.join(''));
```
output:
```
abc
```
# methods
``` js
var map = require('array-map')
```
## var ys = map(xs, f)
Create a new array `ys` by applying `f(xs[i], i, xs)` to each element in `xs` at
index `i`.
# install
With [npm](https://npmjs.org) do:
```
npm install array-map
```
# license
MIT
+77
View File
@@ -0,0 +1,77 @@
var map = require('../');
var test = require('tape');
test('numbers -> letters', function (t) {
t.plan(2);
var a = map([97,98,99], function (c) {
return String.fromCharCode(c);
});
t.equal(a.join(''), 'abc');
var b = map(cripple([97,98,99]), function (c) {
return String.fromCharCode(c);
});
t.equal(b.join(''), 'abc');
});
test('elements and indexes', function (t) {
t.plan(8);
var x = { q: 5 }, y = 3, z = null;
t.deepEqual(
map([x,y,z], function (c, i) { return i }),
[ 0, 1, 2 ],
'index check'
);
t.deepEqual(
map([x,y,z], function (c, i) { return i }),
[ 0, 1, 2 ],
'crippled index check'
);
var xs0 = [ x, y, z ];
map(xs0, function (c, i, xs) {
t.strictEqual(xs, xs0, 'argument[2]');
});
var xs1 = [ x, y, z ];
map(xs1, function (c, i, xs) {
t.strictEqual(xs, xs1, 'crippled argument[2]');
});
});
test('ignore holes', function (t) {
t.plan(2);
t.deepEqual(
map(new Array(5), function (x) { return x }),
[]
);
t.deepEqual(
map(cripple(new Array(5)), function (x) { return x }),
[]
);
});
test('sparse map', function (t) {
t.plan(2);
var xs = new Array(5);
xs[2] = 'a';
xs[4] = 'b';
t.equal(
map(xs, function (x, i) { return x + i }).join(''),
'a2b4'
);
var ys = new Array(5);
ys[2] = 'a';
ys[4] = 'b';
t.equal(
map(cripple(xs), function (x, i) { return x + i }).join(''),
'a2b4'
);
t.end();
});
function cripple (xs) {
xs.map = undefined;
return xs;
}
+4
View File
@@ -0,0 +1,4 @@
language: node_js
node_js:
- "0.8"
- "0.10"
+18
View File
@@ -0,0 +1,18 @@
This software is released under the MIT license:
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.
+4
View File
@@ -0,0 +1,4 @@
var reduce = require('../');
var xs = [ 1, 2, 3, 4 ];
var sum = reduce(xs, function (acc, x) { return acc + x }, 0);
console.log(sum);
+18
View File
@@ -0,0 +1,18 @@
var hasOwn = Object.prototype.hasOwnProperty;
module.exports = function (xs, f, acc) {
var hasAcc = arguments.length >= 3;
if (hasAcc && xs.reduce) return xs.reduce(f, acc);
if (xs.reduce) return xs.reduce(f);
for (var i = 0; i < xs.length; i++) {
if (!hasOwn.call(xs, i)) continue;
if (!hasAcc) {
acc = xs[i];
hasAcc = true;
continue;
}
acc = f(acc, xs[i], i);
}
return acc;
};
+99
View File
@@ -0,0 +1,99 @@
{
"_args": [
[
"array-reduce@~0.0.0",
"C:\\Users\\Lukas Obermann\\Projekte\\Cha5App\\code\\git\\node_modules\\shell-quote"
]
],
"_from": "array-reduce@>=0.0.0 <0.1.0",
"_id": "array-reduce@0.0.0",
"_inCache": true,
"_installable": true,
"_location": "/array-reduce",
"_npmUser": {
"email": "mail@substack.net",
"name": "substack"
},
"_npmVersion": "1.3.21",
"_phantomChildren": {},
"_requested": {
"name": "array-reduce",
"raw": "array-reduce@~0.0.0",
"rawSpec": "~0.0.0",
"scope": null,
"spec": ">=0.0.0 <0.1.0",
"type": "range"
},
"_requiredBy": [
"/shell-quote"
],
"_resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz",
"_shasum": "173899d3ffd1c7d9383e4479525dbe278cab5f2b",
"_shrinkwrap": null,
"_spec": "array-reduce@~0.0.0",
"_where": "C:\\Users\\Lukas Obermann\\Projekte\\Cha5App\\code\\git\\node_modules\\shell-quote",
"author": {
"email": "mail@substack.net",
"name": "James Halliday",
"url": "http://substack.net"
},
"bugs": {
"url": "https://github.com/substack/array-reduce/issues"
},
"dependencies": {},
"description": "`[].reduce()` for old browsers",
"devDependencies": {
"tape": "~2.3.2"
},
"directories": {},
"dist": {
"shasum": "173899d3ffd1c7d9383e4479525dbe278cab5f2b",
"tarball": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz"
},
"homepage": "https://github.com/substack/array-reduce",
"keywords": [
"array",
"reduce",
"es5",
"ie6",
"ie7",
"ie8",
"fold"
],
"license": "MIT",
"main": "index.js",
"maintainers": [
{
"email": "mail@substack.net",
"name": "substack"
}
],
"name": "array-reduce",
"optionalDependencies": {},
"readme": "# array-reduce\n\n`[].reduce()` for old browsers\n\n[![testling badge](https://ci.testling.com/substack/array-reduce.png)](https://ci.testling.com/substack/array-reduce)\n\n[![build status](https://secure.travis-ci.org/substack/array-reduce.png)](http://travis-ci.org/substack/array-reduce)\n\n# example\n\n```\nvar reduce = require('array-reduce');\nvar xs = [ 1, 2, 3, 4 ];\nvar sum = reduce(xs, function (acc, x) { return acc + x }, 0);\nconsole.log(sum);\n```\n\noutput:\n\n```\n10\n```\n\n# methods\n\n``` js\nvar reduce = require('array-reduce')\n```\n\n## var res = reduce(xs, f, init)\n\nCreate a result `res` by folding `acc = f(acc, xs[i], i)` over each element in\nthe array `xs` at element `i`. If `init` is given, the first `acc` value is\n`init`, otherwise `xs[0]` is used.\n\n# install\n\nWith [npm](https://npmjs.org) do:\n\n```\nnpm install array-reduce\n```\n\n# license\n\nMIT\n",
"readmeFilename": "readme.markdown",
"repository": {
"type": "git",
"url": "git://github.com/substack/array-reduce.git"
},
"scripts": {
"test": "tape test/*.js"
},
"testling": {
"browsers": [
"ie/8..latest",
"firefox/16..latest",
"firefox/nightly",
"chrome/22..latest",
"chrome/canary",
"opera/12..latest",
"opera/next",
"safari/5.1..latest",
"ipad/6.0..latest",
"iphone/6.0..latest",
"android-browser/4.2..latest"
],
"files": "test/*.js"
},
"version": "0.0.0"
}
+46
View File
@@ -0,0 +1,46 @@
# array-reduce
`[].reduce()` for old browsers
[![testling badge](https://ci.testling.com/substack/array-reduce.png)](https://ci.testling.com/substack/array-reduce)
[![build status](https://secure.travis-ci.org/substack/array-reduce.png)](http://travis-ci.org/substack/array-reduce)
# example
```
var reduce = require('array-reduce');
var xs = [ 1, 2, 3, 4 ];
var sum = reduce(xs, function (acc, x) { return acc + x }, 0);
console.log(sum);
```
output:
```
10
```
# methods
``` js
var reduce = require('array-reduce')
```
## var res = reduce(xs, f, init)
Create a result `res` by folding `acc = f(acc, xs[i], i)` over each element in
the array `xs` at element `i`. If `init` is given, the first `acc` value is
`init`, otherwise `xs[0]` is used.
# install
With [npm](https://npmjs.org) do:
```
npm install array-reduce
```
# license
MIT
+85
View File
@@ -0,0 +1,85 @@
var reduce = require('../');
var test = require('tape');
test('numeric reduces', function (t) {
t.plan(6);
var xs = [ 1, 2, 3, 4 ];
t.equal(
reduce(xs, function (acc, x) { return acc + x }, 0),
10
);
t.equal(
reduce(xs, function (acc, x) { return acc + x }, 100),
110
);
t.equal(
reduce(xs, function (acc, x) { return acc + x }),
10
);
var ys = cripple([ 1, 2, 3, 4 ]);
t.equal(
reduce(ys, function (acc, x) { return acc + x }, 0),
10
);
t.equal(
reduce(ys, function (acc, x) { return acc + x }, 100),
110
);
t.equal(
reduce(ys, function (acc, x) { return acc + x }),
10
);
});
test('holes', function (t) {
t.plan(4);
var xs = Array(10);
xs[2] = 5; xs[4] = 6; xs[8] = 4;
t.equal(
reduce(xs, function (acc, x) { return acc + x }),
15
);
t.equal(
reduce(xs, function (acc, x) { return acc + x }, 100),
115
);
var ys = cripple(Array(10));
ys[2] = 5; ys[4] = 6; ys[8] = 4;
t.equal(
reduce(ys, function (acc, x) { return acc + x }),
15
);
t.equal(
reduce(ys, function (acc, x) { return acc + x }, 100),
115
);
});
test('object', function (t) {
t.plan(1);
var obj = { a: 3, b: 4, c: 5 };
var res = reduce(objectKeys(obj), function (acc, key) {
acc[key.toUpperCase()] = obj[key] * 111;
return acc;
}, {});
t.deepEqual(res, { A: 333, B: 444, C: 555 });
});
function cripple (xs) {
xs.reduce = undefined;
return xs;
}
var objectKeys = function (obj) {
var keys = [];
for (var key in obj) {
if (hasOwn.call(obj, key)) keys.push(key);
}
return keys;
};
var hasOwn = Object.prototype.hasOwnProperty;
+2
View File
@@ -0,0 +1,2 @@
test
rfc
+100
View File
@@ -0,0 +1,100 @@
# ASN1.js
ASN.1 DER Encoder/Decoder and DSL.
## Example
Define model:
```javascript
var asn = require('asn1.js');
var Human = asn.define('Human', function() {
this.seq().obj(
this.key('firstName').octstr(),
this.key('lastName').octstr(),
this.key('age').int(),
this.key('gender').enum({ 0: 'male', 1: 'female' }),
this.key('bio').seqof(Bio)
);
});
var Bio = asn.define('Bio', function() {
this.seq().obj(
this.key('time').gentime(),
this.key('description').octstr()
);
});
```
Encode data:
```javascript
var output = Human.encode({
firstName: 'Thomas',
lastName: 'Anderson',
age: 28,
gender: 'male',
bio: [
{
time: +new Date('31 March 1999'),
description: 'freedom of mind'
}
]
}, 'der');
```
Decode data:
```javascript
var human = Human.decode(output, 'der');
console.log(human);
/*
{ firstName: <Buffer 54 68 6f 6d 61 73>,
lastName: <Buffer 41 6e 64 65 72 73 6f 6e>,
age: 28,
gender: 'male',
bio:
[ { time: 922820400000,
description: <Buffer 66 72 65 65 64 6f 6d 20 6f 66 20 6d 69 6e 64> } ] }
*/
```
### Partial decode
Its possible to parse data without stopping on first error. In order to do it,
you should call:
```javascript
var human = Human.decode(output, 'der', { partial: true });
console.log(human);
/*
{ result: { ... },
errors: [ ... ] }
*/
```
#### LICENSE
This software is licensed under the MIT License.
Copyright Fedor Indutny, 2013.
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.
+9
View File
@@ -0,0 +1,9 @@
var asn1 = exports;
asn1.bignum = require('bn.js');
asn1.define = require('./asn1/api').define;
asn1.base = require('./asn1/base');
asn1.constants = require('./asn1/constants');
asn1.decoders = require('./asn1/decoders');
asn1.encoders = require('./asn1/encoders');
+61
View File
@@ -0,0 +1,61 @@
var asn1 = require('../asn1');
var inherits = require('inherits');
var api = exports;
api.define = function define(name, body) {
return new Entity(name, body);
};
function Entity(name, body) {
this.name = name;
this.body = body;
this.decoders = {};
this.encoders = {};
};
Entity.prototype._createNamed = function createNamed(base) {
var named;
try {
named = require('vm').runInThisContext(
'(function ' + this.name + '(entity) {\n' +
' this._initNamed(entity);\n' +
'})'
);
} catch (e) {
named = function (entity) {
this._initNamed(entity);
};
}
inherits(named, base);
named.prototype._initNamed = function initnamed(entity) {
base.call(this, entity);
};
return new named(this);
};
Entity.prototype._getDecoder = function _getDecoder(enc) {
enc = enc || 'der';
// Lazily create decoder
if (!this.decoders.hasOwnProperty(enc))
this.decoders[enc] = this._createNamed(asn1.decoders[enc]);
return this.decoders[enc];
};
Entity.prototype.decode = function decode(data, enc, options) {
return this._getDecoder(enc).decode(data, options);
};
Entity.prototype._getEncoder = function _getEncoder(enc) {
enc = enc || 'der';
// Lazily create encoder
if (!this.encoders.hasOwnProperty(enc))
this.encoders[enc] = this._createNamed(asn1.encoders[enc]);
return this.encoders[enc];
};
Entity.prototype.encode = function encode(data, enc, /* internal */ reporter) {
return this._getEncoder(enc).encode(data, reporter);
};
+116
View File
@@ -0,0 +1,116 @@
var inherits = require('inherits');
var Reporter = require('../base').Reporter;
var Buffer = require('buffer').Buffer;
function DecoderBuffer(base, options) {
Reporter.call(this, options);
if (!Buffer.isBuffer(base)) {
this.error('Input not Buffer');
return;
}
this.base = base;
this.offset = 0;
this.length = base.length;
}
inherits(DecoderBuffer, Reporter);
exports.DecoderBuffer = DecoderBuffer;
DecoderBuffer.prototype.save = function save() {
return { offset: this.offset, reporter: Reporter.prototype.save.call(this) };
};
DecoderBuffer.prototype.restore = function restore(save) {
// Return skipped data
var res = new DecoderBuffer(this.base);
res.offset = save.offset;
res.length = this.offset;
this.offset = save.offset;
Reporter.prototype.restore.call(this, save.reporter);
return res;
};
DecoderBuffer.prototype.isEmpty = function isEmpty() {
return this.offset === this.length;
};
DecoderBuffer.prototype.readUInt8 = function readUInt8(fail) {
if (this.offset + 1 <= this.length)
return this.base.readUInt8(this.offset++, true);
else
return this.error(fail || 'DecoderBuffer overrun');
}
DecoderBuffer.prototype.skip = function skip(bytes, fail) {
if (!(this.offset + bytes <= this.length))
return this.error(fail || 'DecoderBuffer overrun');
var res = new DecoderBuffer(this.base);
// Share reporter state
res._reporterState = this._reporterState;
res.offset = this.offset;
res.length = this.offset + bytes;
this.offset += bytes;
return res;
}
DecoderBuffer.prototype.raw = function raw(save) {
return this.base.slice(save ? save.offset : this.offset, this.length);
}
function EncoderBuffer(value, reporter) {
if (Array.isArray(value)) {
this.length = 0;
this.value = value.map(function(item) {
if (!(item instanceof EncoderBuffer))
item = new EncoderBuffer(item, reporter);
this.length += item.length;
return item;
}, this);
} else if (typeof value === 'number') {
if (!(0 <= value && value <= 0xff))
return reporter.error('non-byte EncoderBuffer value');
this.value = value;
this.length = 1;
} else if (typeof value === 'string') {
this.value = value;
this.length = Buffer.byteLength(value);
} else if (Buffer.isBuffer(value)) {
this.value = value;
this.length = value.length;
} else {
return reporter.error('Unsupported type: ' + typeof value);
}
}
exports.EncoderBuffer = EncoderBuffer;
EncoderBuffer.prototype.join = function join(out, offset) {
if (!out)
out = new Buffer(this.length);
if (!offset)
offset = 0;
if (this.length === 0)
return out;
if (Array.isArray(this.value)) {
this.value.forEach(function(item) {
item.join(out, offset);
offset += item.length;
});
} else {
if (typeof this.value === 'number')
out[offset] = this.value;
else if (typeof this.value === 'string')
out.write(this.value, offset);
else if (Buffer.isBuffer(this.value))
this.value.copy(out, offset);
offset += this.length;
}
return out;
};
+6
View File
@@ -0,0 +1,6 @@
var base = exports;
base.Reporter = require('./reporter').Reporter;
base.DecoderBuffer = require('./buffer').DecoderBuffer;
base.EncoderBuffer = require('./buffer').EncoderBuffer;
base.Node = require('./node');
+629
View File
@@ -0,0 +1,629 @@
var Reporter = require('../base').Reporter;
var EncoderBuffer = require('../base').EncoderBuffer;
var DecoderBuffer = require('../base').DecoderBuffer;
var assert = require('minimalistic-assert');
// Supported tags
var tags = [
'seq', 'seqof', 'set', 'setof', 'objid', 'bool',
'gentime', 'utctime', 'null_', 'enum', 'int',
'bitstr', 'bmpstr', 'charstr', 'genstr', 'graphstr', 'ia5str', 'iso646str',
'numstr', 'octstr', 'printstr', 't61str', 'unistr', 'utf8str', 'videostr'
];
// Public methods list
var methods = [
'key', 'obj', 'use', 'optional', 'explicit', 'implicit', 'def', 'choice',
'any', 'contains'
].concat(tags);
// Overrided methods list
var overrided = [
'_peekTag', '_decodeTag', '_use',
'_decodeStr', '_decodeObjid', '_decodeTime',
'_decodeNull', '_decodeInt', '_decodeBool', '_decodeList',
'_encodeComposite', '_encodeStr', '_encodeObjid', '_encodeTime',
'_encodeNull', '_encodeInt', '_encodeBool'
];
function Node(enc, parent) {
var state = {};
this._baseState = state;
state.enc = enc;
state.parent = parent || null;
state.children = null;
// State
state.tag = null;
state.args = null;
state.reverseArgs = null;
state.choice = null;
state.optional = false;
state.any = false;
state.obj = false;
state.use = null;
state.useDecoder = null;
state.key = null;
state['default'] = null;
state.explicit = null;
state.implicit = null;
state.contains = null;
// Should create new instance on each method
if (!state.parent) {
state.children = [];
this._wrap();
}
}
module.exports = Node;
var stateProps = [
'enc', 'parent', 'children', 'tag', 'args', 'reverseArgs', 'choice',
'optional', 'any', 'obj', 'use', 'alteredUse', 'key', 'default', 'explicit',
'implicit', 'contains'
];
Node.prototype.clone = function clone() {
var state = this._baseState;
var cstate = {};
stateProps.forEach(function(prop) {
cstate[prop] = state[prop];
});
var res = new this.constructor(cstate.parent);
res._baseState = cstate;
return res;
};
Node.prototype._wrap = function wrap() {
var state = this._baseState;
methods.forEach(function(method) {
this[method] = function _wrappedMethod() {
var clone = new this.constructor(this);
state.children.push(clone);
return clone[method].apply(clone, arguments);
};
}, this);
};
Node.prototype._init = function init(body) {
var state = this._baseState;
assert(state.parent === null);
body.call(this);
// Filter children
state.children = state.children.filter(function(child) {
return child._baseState.parent === this;
}, this);
assert.equal(state.children.length, 1, 'Root node can have only one child');
};
Node.prototype._useArgs = function useArgs(args) {
var state = this._baseState;
// Filter children and args
var children = args.filter(function(arg) {
return arg instanceof this.constructor;
}, this);
args = args.filter(function(arg) {
return !(arg instanceof this.constructor);
}, this);
if (children.length !== 0) {
assert(state.children === null);
state.children = children;
// Replace parent to maintain backward link
children.forEach(function(child) {
child._baseState.parent = this;
}, this);
}
if (args.length !== 0) {
assert(state.args === null);
state.args = args;
state.reverseArgs = args.map(function(arg) {
if (typeof arg !== 'object' || arg.constructor !== Object)
return arg;
var res = {};
Object.keys(arg).forEach(function(key) {
if (key == (key | 0))
key |= 0;
var value = arg[key];
res[value] = key;
});
return res;
});
}
};
//
// Overrided methods
//
overrided.forEach(function(method) {
Node.prototype[method] = function _overrided() {
var state = this._baseState;
throw new Error(method + ' not implemented for encoding: ' + state.enc);
};
});
//
// Public methods
//
tags.forEach(function(tag) {
Node.prototype[tag] = function _tagMethod() {
var state = this._baseState;
var args = Array.prototype.slice.call(arguments);
assert(state.tag === null);
state.tag = tag;
this._useArgs(args);
return this;
};
});
Node.prototype.use = function use(item) {
var state = this._baseState;
assert(state.use === null);
state.use = item;
return this;
};
Node.prototype.optional = function optional() {
var state = this._baseState;
state.optional = true;
return this;
};
Node.prototype.def = function def(val) {
var state = this._baseState;
assert(state['default'] === null);
state['default'] = val;
state.optional = true;
return this;
};
Node.prototype.explicit = function explicit(num) {
var state = this._baseState;
assert(state.explicit === null && state.implicit === null);
state.explicit = num;
return this;
};
Node.prototype.implicit = function implicit(num) {
var state = this._baseState;
assert(state.explicit === null && state.implicit === null);
state.implicit = num;
return this;
};
Node.prototype.obj = function obj() {
var state = this._baseState;
var args = Array.prototype.slice.call(arguments);
state.obj = true;
if (args.length !== 0)
this._useArgs(args);
return this;
};
Node.prototype.key = function key(newKey) {
var state = this._baseState;
assert(state.key === null);
state.key = newKey;
return this;
};
Node.prototype.any = function any() {
var state = this._baseState;
state.any = true;
return this;
};
Node.prototype.choice = function choice(obj) {
var state = this._baseState;
assert(state.choice === null);
state.choice = obj;
this._useArgs(Object.keys(obj).map(function(key) {
return obj[key];
}));
return this;
};
Node.prototype.contains = function contains(item) {
var state = this._baseState;
assert(state.use === null);
state.contains = item;
return this;
};
//
// Decoding
//
Node.prototype._decode = function decode(input, options) {
var state = this._baseState;
// Decode root node
if (state.parent === null)
return input.wrapResult(state.children[0]._decode(input, options));
var result = state['default'];
var present = true;
var prevKey = null;
if (state.key !== null)
prevKey = input.enterKey(state.key);
// Check if tag is there
if (state.optional) {
var tag = null;
if (state.explicit !== null)
tag = state.explicit;
else if (state.implicit !== null)
tag = state.implicit;
else if (state.tag !== null)
tag = state.tag;
if (tag === null && !state.any) {
// Trial and Error
var save = input.save();
try {
if (state.choice === null)
this._decodeGeneric(state.tag, input, options);
else
this._decodeChoice(input, options);
present = true;
} catch (e) {
present = false;
}
input.restore(save);
} else {
present = this._peekTag(input, tag, state.any);
if (input.isError(present))
return present;
}
}
// Push object on stack
var prevObj;
if (state.obj && present)
prevObj = input.enterObject();
if (present) {
// Unwrap explicit values
if (state.explicit !== null) {
var explicit = this._decodeTag(input, state.explicit);
if (input.isError(explicit))
return explicit;
input = explicit;
}
var start = input.offset;
// Unwrap implicit and normal values
if (state.use === null && state.choice === null) {
if (state.any)
var save = input.save();
var body = this._decodeTag(
input,
state.implicit !== null ? state.implicit : state.tag,
state.any
);
if (input.isError(body))
return body;
if (state.any)
result = input.raw(save);
else
input = body;
}
if (options && options.track && state.tag !== null)
options.track(input.path(), start, input.length, 'tagged');
if (options && options.track && state.tag !== null)
options.track(input.path(), input.offset, input.length, 'content');
// Select proper method for tag
if (state.any)
result = result;
else if (state.choice === null)
result = this._decodeGeneric(state.tag, input, options);
else
result = this._decodeChoice(input, options);
if (input.isError(result))
return result;
// Decode children
if (!state.any && state.choice === null && state.children !== null) {
state.children.forEach(function decodeChildren(child) {
// NOTE: We are ignoring errors here, to let parser continue with other
// parts of encoded data
child._decode(input, options);
});
}
// Decode contained/encoded by schema, only in bit or octet strings
if (state.contains && (state.tag === 'octstr' || state.tag === 'bitstr')) {
var data = new DecoderBuffer(result);
result = this._getUse(state.contains, input._reporterState.obj)
._decode(data, options);
}
}
// Pop object
if (state.obj && present)
result = input.leaveObject(prevObj);
// Set key
if (state.key !== null && (result !== null || present === true))
input.leaveKey(prevKey, state.key, result);
else if (prevKey !== null)
input.exitKey(prevKey);
return result;
};
Node.prototype._decodeGeneric = function decodeGeneric(tag, input, options) {
var state = this._baseState;
if (tag === 'seq' || tag === 'set')
return null;
if (tag === 'seqof' || tag === 'setof')
return this._decodeList(input, tag, state.args[0], options);
else if (/str$/.test(tag))
return this._decodeStr(input, tag, options);
else if (tag === 'objid' && state.args)
return this._decodeObjid(input, state.args[0], state.args[1], options);
else if (tag === 'objid')
return this._decodeObjid(input, null, null, options);
else if (tag === 'gentime' || tag === 'utctime')
return this._decodeTime(input, tag, options);
else if (tag === 'null_')
return this._decodeNull(input, options);
else if (tag === 'bool')
return this._decodeBool(input, options);
else if (tag === 'int' || tag === 'enum')
return this._decodeInt(input, state.args && state.args[0], options);
if (state.use !== null) {
return this._getUse(state.use, input._reporterState.obj)
._decode(input, options);
} else {
return input.error('unknown tag: ' + tag);
}
};
Node.prototype._getUse = function _getUse(entity, obj) {
var state = this._baseState;
// Create altered use decoder if implicit is set
state.useDecoder = this._use(entity, obj);
assert(state.useDecoder._baseState.parent === null);
state.useDecoder = state.useDecoder._baseState.children[0];
if (state.implicit !== state.useDecoder._baseState.implicit) {
state.useDecoder = state.useDecoder.clone();
state.useDecoder._baseState.implicit = state.implicit;
}
return state.useDecoder;
};
Node.prototype._decodeChoice = function decodeChoice(input, options) {
var state = this._baseState;
var result = null;
var match = false;
Object.keys(state.choice).some(function(key) {
var save = input.save();
var node = state.choice[key];
try {
var value = node._decode(input, options);
if (input.isError(value))
return false;
result = { type: key, value: value };
match = true;
} catch (e) {
input.restore(save);
return false;
}
return true;
}, this);
if (!match)
return input.error('Choice not matched');
return result;
};
//
// Encoding
//
Node.prototype._createEncoderBuffer = function createEncoderBuffer(data) {
return new EncoderBuffer(data, this.reporter);
};
Node.prototype._encode = function encode(data, reporter, parent) {
var state = this._baseState;
if (state['default'] !== null && state['default'] === data)
return;
var result = this._encodeValue(data, reporter, parent);
if (result === undefined)
return;
if (this._skipDefault(result, reporter, parent))
return;
return result;
};
Node.prototype._encodeValue = function encode(data, reporter, parent) {
var state = this._baseState;
// Decode root node
if (state.parent === null)
return state.children[0]._encode(data, reporter || new Reporter());
var result = null;
// Set reporter to share it with a child class
this.reporter = reporter;
// Check if data is there
if (state.optional && data === undefined) {
if (state['default'] !== null)
data = state['default']
else
return;
}
// Encode children first
var content = null;
var primitive = false;
if (state.any) {
// Anything that was given is translated to buffer
result = this._createEncoderBuffer(data);
} else if (state.choice) {
result = this._encodeChoice(data, reporter);
} else if (state.contains) {
content = this._getUse(state.contains, parent)._encode(data, reporter);
primitive = true;
} else if (state.children) {
content = state.children.map(function(child) {
if (child._baseState.tag === 'null_')
return child._encode(null, reporter, data);
if (child._baseState.key === null)
return reporter.error('Child should have a key');
var prevKey = reporter.enterKey(child._baseState.key);
if (typeof data !== 'object')
return reporter.error('Child expected, but input is not object');
var res = child._encode(data[child._baseState.key], reporter, data);
reporter.leaveKey(prevKey);
return res;
}, this).filter(function(child) {
return child;
});
content = this._createEncoderBuffer(content);
} else {
if (state.tag === 'seqof' || state.tag === 'setof') {
// TODO(indutny): this should be thrown on DSL level
if (!(state.args && state.args.length === 1))
return reporter.error('Too many args for : ' + state.tag);
if (!Array.isArray(data))
return reporter.error('seqof/setof, but data is not Array');
var child = this.clone();
child._baseState.implicit = null;
content = this._createEncoderBuffer(data.map(function(item) {
var state = this._baseState;
return this._getUse(state.args[0], data)._encode(item, reporter);
}, child));
} else if (state.use !== null) {
result = this._getUse(state.use, parent)._encode(data, reporter);
} else {
content = this._encodePrimitive(state.tag, data);
primitive = true;
}
}
// Encode data itself
var result;
if (!state.any && state.choice === null) {
var tag = state.implicit !== null ? state.implicit : state.tag;
var cls = state.implicit === null ? 'universal' : 'context';
if (tag === null) {
if (state.use === null)
reporter.error('Tag could be ommited only for .use()');
} else {
if (state.use === null)
result = this._encodeComposite(tag, primitive, cls, content);
}
}
// Wrap in explicit
if (state.explicit !== null)
result = this._encodeComposite(state.explicit, false, 'context', result);
return result;
};
Node.prototype._encodeChoice = function encodeChoice(data, reporter) {
var state = this._baseState;
var node = state.choice[data.type];
if (!node) {
assert(
false,
data.type + ' not found in ' +
JSON.stringify(Object.keys(state.choice)));
}
return node._encode(data.value, reporter);
};
Node.prototype._encodePrimitive = function encodePrimitive(tag, data) {
var state = this._baseState;
if (/str$/.test(tag))
return this._encodeStr(data, tag);
else if (tag === 'objid' && state.args)
return this._encodeObjid(data, state.reverseArgs[0], state.args[1]);
else if (tag === 'objid')
return this._encodeObjid(data, null, null);
else if (tag === 'gentime' || tag === 'utctime')
return this._encodeTime(data, tag);
else if (tag === 'null_')
return this._encodeNull();
else if (tag === 'int' || tag === 'enum')
return this._encodeInt(data, state.args && state.reverseArgs[0]);
else if (tag === 'bool')
return this._encodeBool(data);
else
throw new Error('Unsupported tag: ' + tag);
};
Node.prototype._isNumstr = function isNumstr(str) {
return /^[0-9 ]*$/.test(str);
};
Node.prototype._isPrintstr = function isPrintstr(str) {
return /^[A-Za-z0-9 '\(\)\+,\-\.\/:=\?]*$/.test(str);
};
+121
View File
@@ -0,0 +1,121 @@
var inherits = require('inherits');
function Reporter(options) {
this._reporterState = {
obj: null,
path: [],
options: options || {},
errors: []
};
}
exports.Reporter = Reporter;
Reporter.prototype.isError = function isError(obj) {
return obj instanceof ReporterError;
};
Reporter.prototype.save = function save() {
var state = this._reporterState;
return { obj: state.obj, pathLen: state.path.length };
};
Reporter.prototype.restore = function restore(data) {
var state = this._reporterState;
state.obj = data.obj;
state.path = state.path.slice(0, data.pathLen);
};
Reporter.prototype.enterKey = function enterKey(key) {
return this._reporterState.path.push(key);
};
Reporter.prototype.exitKey = function exitKey(index) {
var state = this._reporterState;
state.path = state.path.slice(0, index - 1);
};
Reporter.prototype.leaveKey = function leaveKey(index, key, value) {
var state = this._reporterState;
this.exitKey(index);
if (state.obj !== null)
state.obj[key] = value;
};
Reporter.prototype.path = function path() {
return this._reporterState.path.join('/');
};
Reporter.prototype.enterObject = function enterObject() {
var state = this._reporterState;
var prev = state.obj;
state.obj = {};
return prev;
};
Reporter.prototype.leaveObject = function leaveObject(prev) {
var state = this._reporterState;
var now = state.obj;
state.obj = prev;
return now;
};
Reporter.prototype.error = function error(msg) {
var err;
var state = this._reporterState;
var inherited = msg instanceof ReporterError;
if (inherited) {
err = msg;
} else {
err = new ReporterError(state.path.map(function(elem) {
return '[' + JSON.stringify(elem) + ']';
}).join(''), msg.message || msg, msg.stack);
}
if (!state.options.partial)
throw err;
if (!inherited)
state.errors.push(err);
return err;
};
Reporter.prototype.wrapResult = function wrapResult(result) {
var state = this._reporterState;
if (!state.options.partial)
return result;
return {
result: this.isError(result) ? null : result,
errors: state.errors
};
};
function ReporterError(path, msg) {
this.path = path;
this.rethrow(msg);
};
inherits(ReporterError, Error);
ReporterError.prototype.rethrow = function rethrow(msg) {
this.message = msg + ' at: ' + (this.path || '(shallow)');
if (Error.captureStackTrace)
Error.captureStackTrace(this, ReporterError);
if (!this.stack) {
try {
// IE only adds stack when thrown
throw new Error(this.message);
} catch (e) {
this.stack = e.stack;
}
}
return this;
};
+42
View File
@@ -0,0 +1,42 @@
var constants = require('../constants');
exports.tagClass = {
0: 'universal',
1: 'application',
2: 'context',
3: 'private'
};
exports.tagClassByName = constants._reverse(exports.tagClass);
exports.tag = {
0x00: 'end',
0x01: 'bool',
0x02: 'int',
0x03: 'bitstr',
0x04: 'octstr',
0x05: 'null_',
0x06: 'objid',
0x07: 'objDesc',
0x08: 'external',
0x09: 'real',
0x0a: 'enum',
0x0b: 'embed',
0x0c: 'utf8str',
0x0d: 'relativeOid',
0x10: 'seq',
0x11: 'set',
0x12: 'numstr',
0x13: 'printstr',
0x14: 't61str',
0x15: 'videostr',
0x16: 'ia5str',
0x17: 'utctime',
0x18: 'gentime',
0x19: 'graphstr',
0x1a: 'iso646str',
0x1b: 'genstr',
0x1c: 'unistr',
0x1d: 'charstr',
0x1e: 'bmpstr'
};
exports.tagByName = constants._reverse(exports.tag);
+19
View File
@@ -0,0 +1,19 @@
var constants = exports;
// Helper
constants._reverse = function reverse(map) {
var res = {};
Object.keys(map).forEach(function(key) {
// Convert key to integer if it is stringified
if ((key | 0) == key)
key = key | 0;
var value = map[key];
res[value] = key;
});
return res;
};
constants.der = require('./der');

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