choi

fix dependencies

Showing 152 changed files with 4700 additions and 0 deletions
1 +#### 9.0.0
2 +* 27/05/2019
3 +* For compatibility with legacy browsers, remove `Symbol` references.
4 +
5 +#### 8.1.1
6 +* 24/02/2019
7 +* [BUGFIX] #222 Restore missing `var` to `export BigNumber`.
8 +* Allow any key in BigNumber.Instance in *bignumber.d.ts*.
9 +
10 +#### 8.1.0
11 +* 23/02/2019
12 +* [NEW FEATURE] #220 Create a BigNumber using `{s, e, c}`.
13 +* [NEW FEATURE] `isBigNumber`: if `BigNumber.DEBUG` is `true`, also check that the BigNumber instance is well-formed.
14 +* Remove `instanceof` checks; just use `_isBigNumber` to identify a BigNumber instance.
15 +* Add `_isBigNumber` to prototype in *bignumber.mjs*.
16 +* Add tests for BigNumber creation from object.
17 +* Update *API.html*.
18 +
19 +#### 8.0.2
20 +* 13/01/2019
21 +* #209 `toPrecision` without argument should follow `toString`.
22 +* Improve *Use* section of *README*.
23 +* Optimise `toString(10)`.
24 +* Add verson number to API doc.
25 +
26 +#### 8.0.1
27 +* 01/11/2018
28 +* Rest parameter must be array type in *bignumber.d.ts*.
29 +
30 +#### 8.0.0
31 +* 01/11/2018
32 +* [NEW FEATURE] Add `BigNumber.sum` method.
33 +* [NEW FEATURE]`toFormat`: add `prefix` and `suffix` options.
34 +* [NEW FEATURE] #178 Pass custom formatting to `toFormat`.
35 +* [BREAKING CHANGE] #184 `toFraction`: return array of BigNumbers not strings.
36 +* [NEW FEATURE] #185 Enable overwrite of `valueOf` to prevent accidental addition to string.
37 +* #183 Add Node.js `crypto` requirement to documentation.
38 +* [BREAKING CHANGE] #198 Disallow signs and whitespace in custom alphabet.
39 +* [NEW FEATURE] #188 Implement `util.inspect.custom` for Node.js REPL.
40 +* #170 Make `isBigNumber` a type guard in *bignumber.d.ts*.
41 +* [BREAKING CHANGE] `BigNumber.min` and `BigNumber.max`: don't accept an array.
42 +* Update *.travis.yml*.
43 +* Remove *bower.json*.
44 +
45 +#### 7.2.1
46 +* 24/05/2018
47 +* Add `browser` field to *package.json*.
48 +
49 +#### 7.2.0
50 +* 22/05/2018
51 +* #166 Correct *.mjs* file. Remove extension from `main` field in *package.json*.
52 +
53 +#### 7.1.0
54 +* 18/05/2018
55 +* Add `module` field to *package.json* for *bignumber.mjs*.
56 +
57 +#### 7.0.2
58 +* 17/05/2018
59 +* #165 Bugfix: upper-case letters for bases 11-36 in a custom alphabet.
60 +* Add note to *README* regarding creating BigNumbers from Number values.
61 +
62 +#### 7.0.1
63 +* 26/04/2018
64 +* #158 Fix global object variable name typo.
65 +
66 +#### 7.0.0
67 +* 26/04/2018
68 +* #143 Remove global BigNumber from typings.
69 +* #144 Enable compatibility with `Object.freeze(Object.prototype)`.
70 +* #148 #123 #11 Only throw on a number primitive with more than 15 significant digits if `BigNumber.DEBUG` is `true`.
71 +* Only throw on an invalid BigNumber value if `BigNumber.DEBUG` is `true`. Return BigNumber `NaN` instead.
72 +* #154 `exponentiatedBy`: allow BigNumber exponent.
73 +* #156 Prevent Content Security Policy *unsafe-eval* issue.
74 +* `toFraction`: allow `Infinity` maximum denominator.
75 +* Comment-out some excess tests to reduce test time.
76 +* Amend indentation and other spacing.
77 +
78 +#### 6.0.0
79 +* 26/01/2018
80 +* #137 Implement `APLHABET` configuration option.
81 +* Remove `ERRORS` configuration option.
82 +* Remove `toDigits` method; extend `precision` method accordingly.
83 +* Remove s`round` method; extend `decimalPlaces` method accordingly.
84 +* Remove methods: `ceil`, `floor`, and `truncated`.
85 +* Remove method aliases: `add`, `cmp`, `isInt`, `isNeg`, `trunc`, `mul`, `neg` and `sub`.
86 +* Rename methods: `shift` to `shiftedBy`, `another` to `clone`, `toPower` to `exponentiatedBy`, and `equals` to `isEqualTo`.
87 +* Rename methods: add `is` prefix to `greaterThan`, `greaterThanOrEqualTo`, `lessThan` and `lessThanOrEqualTo`.
88 +* Add methods: `multipliedBy`, `isBigNumber`, `isPositive`, `integerValue`, `maximum` and `minimum`.
89 +* Refactor test suite.
90 +* Add *CHANGELOG.md*.
91 +* Rewrite *bignumber.d.ts*.
92 +* Redo API image.
93 +
94 +#### 5.0.0
95 +* 27/11/2017
96 +* #81 Don't throw on constructor call without `new`.
97 +
98 +#### 4.1.0
99 +* 26/09/2017
100 +* Remove node 0.6 from *.travis.yml*.
101 +* Add *bignumber.mjs*.
102 +
103 +#### 4.0.4
104 +* 03/09/2017
105 +* Add missing aliases to *bignumber.d.ts*.
106 +
107 +#### 4.0.3
108 +* 30/08/2017
109 +* Add types: *bignumber.d.ts*.
110 +
111 +#### 4.0.2
112 +* 03/05/2017
113 +* #120 Workaround Safari/Webkit bug.
114 +
115 +#### 4.0.1
116 +* 05/04/2017
117 +* #121 BigNumber.default to BigNumber['default'].
118 +
119 +#### 4.0.0
120 +* 09/01/2017
121 +* Replace BigNumber.isBigNumber method with isBigNumber prototype property.
122 +
123 +#### 3.1.2
124 +* 08/01/2017
125 +* Minor documentation edit.
126 +
127 +#### 3.1.1
128 +* 08/01/2017
129 +* Uncomment `isBigNumber` tests.
130 +* Ignore dot files.
131 +
132 +#### 3.1.0
133 +* 08/01/2017
134 +* Add `isBigNumber` method.
135 +
136 +#### 3.0.2
137 +* 08/01/2017
138 +* Bugfix: Possible incorrect value of `ERRORS` after a `BigNumber.another` call (due to `parseNumeric` declaration in outer scope).
139 +
140 +#### 3.0.1
141 +* 23/11/2016
142 +* Apply fix for old ipads with `%` issue, see #57 and #102.
143 +* Correct error message.
144 +
145 +#### 3.0.0
146 +* 09/11/2016
147 +* Remove `require('crypto')` - leave it to the user.
148 +* Add `BigNumber.set` as `BigNumber.config` alias.
149 +* Default `POW_PRECISION` to `0`.
150 +
151 +#### 2.4.0
152 +* 14/07/2016
153 +* #97 Add exports to support ES6 imports.
154 +
155 +#### 2.3.0
156 +* 07/03/2016
157 +* #86 Add modulus parameter to `toPower`.
158 +
159 +#### 2.2.0
160 +* 03/03/2016
161 +* #91 Permit larger JS integers.
162 +
163 +#### 2.1.4
164 +* 15/12/2015
165 +* Correct UMD.
166 +
167 +#### 2.1.3
168 +* 13/12/2015
169 +* Refactor re global object and crypto availability when bundling.
170 +
171 +#### 2.1.2
172 +* 10/12/2015
173 +* Bugfix: `window.crypto` not assigned to `crypto`.
174 +
175 +#### 2.1.1
176 +* 09/12/2015
177 +* Prevent code bundler from adding `crypto` shim.
178 +
179 +#### 2.1.0
180 +* 26/10/2015
181 +* For `valueOf` and `toJSON`, include the minus sign with negative zero.
182 +
183 +#### 2.0.8
184 +* 2/10/2015
185 +* Internal round function bugfix.
186 +
187 +#### 2.0.6
188 +* 31/03/2015
189 +* Add bower.json. Tweak division after in-depth review.
190 +
191 +#### 2.0.5
192 +* 25/03/2015
193 +* Amend README. Remove bitcoin address.
194 +
195 +#### 2.0.4
196 +* 25/03/2015
197 +* Critical bugfix #58: division.
198 +
199 +#### 2.0.3
200 +* 18/02/2015
201 +* Amend README. Add source map.
202 +
203 +#### 2.0.2
204 +* 18/02/2015
205 +* Correct links.
206 +
207 +#### 2.0.1
208 +* 18/02/2015
209 +* Add `max`, `min`, `precision`, `random`, `shiftedBy`, `toDigits` and `truncated` methods.
210 +* Add the short-forms: `add`, `mul`, `sd`, `sub` and `trunc`.
211 +* Add an `another` method to enable multiple independent constructors to be created.
212 +* Add support for the base 2, 8 and 16 prefixes `0b`, `0o` and `0x`.
213 +* Enable a rounding mode to be specified as a second parameter to `toExponential`, `toFixed`, `toFormat` and `toPrecision`.
214 +* Add a `CRYPTO` configuration property so cryptographically-secure pseudo-random number generation can be specified.
215 +* Add a `MODULO_MODE` configuration property to enable the rounding mode used by the `modulo` operation to be specified.
216 +* Add a `POW_PRECISION` configuration property to enable the number of significant digits calculated by the power operation to be limited.
217 +* Improve code quality.
218 +* Improve documentation.
219 +
220 +#### 2.0.0
221 +* 29/12/2014
222 +* Add `dividedToIntegerBy`, `isInteger` and `toFormat` methods.
223 +* Remove the following short-forms: `isF`, `isZ`, `toE`, `toF`, `toFr`, `toN`, `toP`, `toS`.
224 +* Store a BigNumber's coefficient in base 1e14, rather than base 10.
225 +* Add fast path for integers to BigNumber constructor.
226 +* Incorporate the library into the online documentation.
227 +
228 +#### 1.5.0
229 +* 13/11/2014
230 +* Add `toJSON` and `decimalPlaces` methods.
231 +
232 +#### 1.4.1
233 +* 08/06/2014
234 +* Amend README.
235 +
236 +#### 1.4.0
237 +* 08/05/2014
238 +* Add `toNumber`.
239 +
240 +#### 1.3.0
241 +* 08/11/2013
242 +* Ensure correct rounding of `sqrt` in all, rather than almost all, cases.
243 +* Maximum radix to 64.
244 +
245 +#### 1.2.1
246 +* 17/10/2013
247 +* Sign of zero when x < 0 and x + (-x) = 0.
248 +
249 +#### 1.2.0
250 +* 19/9/2013
251 +* Throw Error objects for stack.
252 +
253 +#### 1.1.1
254 +* 22/8/2013
255 +* Show original value in constructor error message.
256 +
257 +#### 1.1.0
258 +* 1/8/2013
259 +* Allow numbers with trailing radix point.
260 +
261 +#### 1.0.1
262 +* Bugfix: error messages with incorrect method name
263 +
264 +#### 1.0.0
265 +* 8/11/2012
266 +* Initial release
1 +The MIT Licence.
2 +
3 +Copyright (c) 2019 Michael Mclaughlin
4 +
5 +Permission is hereby granted, free of charge, to any person obtaining
6 +a copy of this software and associated documentation files (the
7 +'Software'), to deal in the Software without restriction, including
8 +without limitation the rights to use, copy, modify, merge, publish,
9 +distribute, sublicense, and/or sell copies of the Software, and to
10 +permit persons to whom the Software is furnished to do so, subject to
11 +the following conditions:
12 +
13 +The above copyright notice and this permission notice shall be
14 +included in all copies or substantial portions of the Software.
15 +
16 +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
17 +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20 +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21 +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22 +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 +
1 +![bignumber.js](https://raw.githubusercontent.com/MikeMcl/bignumber.js/gh-pages/bignumberjs.png)
2 +
3 +A JavaScript library for arbitrary-precision decimal and non-decimal arithmetic.
4 +
5 +[![Build Status](https://travis-ci.org/MikeMcl/bignumber.js.svg)](https://travis-ci.org/MikeMcl/bignumber.js)
6 +
7 +<br />
8 +
9 +## Features
10 +
11 + - Integers and decimals
12 + - Simple API but full-featured
13 + - Faster, smaller, and perhaps easier to use than JavaScript versions of Java's BigDecimal
14 + - 8 KB minified and gzipped
15 + - Replicates the `toExponential`, `toFixed`, `toPrecision` and `toString` methods of JavaScript's Number type
16 + - Includes a `toFraction` and a correctly-rounded `squareRoot` method
17 + - Supports cryptographically-secure pseudo-random number generation
18 + - No dependencies
19 + - Wide platform compatibility: uses JavaScript 1.5 (ECMAScript 3) features only
20 + - Comprehensive [documentation](http://mikemcl.github.io/bignumber.js/) and test set
21 +
22 +![API](https://raw.githubusercontent.com/MikeMcl/bignumber.js/gh-pages/API.png)
23 +
24 +If a smaller and simpler library is required see [big.js](https://github.com/MikeMcl/big.js/).
25 +It's less than half the size but only works with decimal numbers and only has half the methods.
26 +It also does not allow `NaN` or `Infinity`, or have the configuration options of this library.
27 +
28 +See also [decimal.js](https://github.com/MikeMcl/decimal.js/), which among other things adds support for non-integer powers, and performs all operations to a specified number of significant digits.
29 +
30 +## Load
31 +
32 +The library is the single JavaScript file *bignumber.js* (or minified, *bignumber.min.js*).
33 +
34 +Browser:
35 +
36 +```html
37 +<script src='path/to/bignumber.js'></script>
38 +```
39 +
40 +[Node.js](http://nodejs.org):
41 +
42 +```bash
43 +$ npm install bignumber.js
44 +```
45 +
46 +```javascript
47 +const BigNumber = require('bignumber.js');
48 +```
49 +
50 +ES6 module:
51 +
52 +```javascript
53 +import BigNumber from "./bignumber.mjs"
54 +```
55 +
56 +AMD loader libraries such as [requireJS](http://requirejs.org/):
57 +
58 +```javascript
59 +require(['bignumber'], function(BigNumber) {
60 + // Use BigNumber here in local scope. No global BigNumber.
61 +});
62 +```
63 +
64 +## Use
65 +
66 +The library exports a single constructor function, [`BigNumber`](http://mikemcl.github.io/bignumber.js/#bignumber), which accepts a value of type Number, String or BigNumber,
67 +
68 +```javascript
69 +let x = new BigNumber(123.4567);
70 +let y = BigNumber('123456.7e-3');
71 +let z = new BigNumber(x);
72 +x.isEqualTo(y) && y.isEqualTo(z) && x.isEqualTo(z); // true
73 +```
74 +
75 +To get the string value of a BigNumber use [`toString()`](http://mikemcl.github.io/bignumber.js/#toS) or [`toFixed()`](http://mikemcl.github.io/bignumber.js/#toFix). Using `toFixed()` prevents exponential notation being returned, no matter how large or small the value.
76 +
77 +```javascript
78 +let x = new BigNumber('1111222233334444555566');
79 +x.toString(); // "1.111222233334444555566e+21"
80 +x.toFixed(); // "1111222233334444555566"
81 +```
82 +
83 +If the limited precision of Number values is not well understood, it is recommended to create BigNumbers from String values rather than Number values to avoid a potential loss of precision.
84 +
85 +*In all further examples below, `let`, semicolons and `toString` calls are not shown. If a commented-out value is in quotes it means `toString` has been called on the preceding expression.*
86 +
87 +```javascript
88 +// Precision loss from using numeric literals with more than 15 significant digits.
89 +new BigNumber(1.0000000000000001) // '1'
90 +new BigNumber(88259496234518.57) // '88259496234518.56'
91 +new BigNumber(99999999999999999999) // '100000000000000000000'
92 +
93 +// Precision loss from using numeric literals outside the range of Number values.
94 +new BigNumber(2e+308) // 'Infinity'
95 +new BigNumber(1e-324) // '0'
96 +
97 +// Precision loss from the unexpected result of arithmetic with Number values.
98 +new BigNumber(0.7 + 0.1) // '0.7999999999999999'
99 +```
100 +
101 +When creating a BigNumber from a Number, note that a BigNumber is created from a Number's decimal `toString()` value not from its underlying binary value. If the latter is required, then pass the Number's `toString(2)` value and specify base 2.
102 +
103 +```javascript
104 +new BigNumber(Number.MAX_VALUE.toString(2), 2)
105 +```
106 +
107 +BigNumbers can be created from values in bases from 2 to 36. See [`ALPHABET`](http://mikemcl.github.io/bignumber.js/#alphabet) to extend this range.
108 +
109 +```javascript
110 +a = new BigNumber(1011, 2) // "11"
111 +b = new BigNumber('zz.9', 36) // "1295.25"
112 +c = a.plus(b) // "1306.25"
113 +```
114 +
115 +Performance is better if base 10 is NOT specified for decimal values. Only specify base 10 when it is desired that the number of decimal places of the input value be limited to the current [`DECIMAL_PLACES`](http://mikemcl.github.io/bignumber.js/#decimal-places) setting.
116 +
117 +A BigNumber is immutable in the sense that it is not changed by its methods.
118 +
119 +```javascript
120 +0.3 - 0.1 // 0.19999999999999998
121 +x = new BigNumber(0.3)
122 +x.minus(0.1) // "0.2"
123 +x // "0.3"
124 +```
125 +
126 +The methods that return a BigNumber can be chained.
127 +
128 +```javascript
129 +x.dividedBy(y).plus(z).times(9)
130 +x.times('1.23456780123456789e+9').plus(9876.5432321).dividedBy('4444562598.111772').integerValue()
131 +```
132 +
133 +Some of the longer method names have a shorter alias.
134 +
135 +```javascript
136 +x.squareRoot().dividedBy(y).exponentiatedBy(3).isEqualTo(x.sqrt().div(y).pow(3)) // true
137 +x.modulo(y).multipliedBy(z).eq(x.mod(y).times(z)) // true
138 +```
139 +
140 +As with JavaScript's Number type, there are [`toExponential`](http://mikemcl.github.io/bignumber.js/#toE), [`toFixed`](http://mikemcl.github.io/bignumber.js/#toFix) and [`toPrecision`](http://mikemcl.github.io/bignumber.js/#toP) methods.
141 +
142 +```javascript
143 +x = new BigNumber(255.5)
144 +x.toExponential(5) // "2.55500e+2"
145 +x.toFixed(5) // "255.50000"
146 +x.toPrecision(5) // "255.50"
147 +x.toNumber() // 255.5
148 +```
149 +
150 + A base can be specified for [`toString`](http://mikemcl.github.io/bignumber.js/#toS). Performance is better if base 10 is NOT specified, i.e. use `toString()` not `toString(10)`. Only specify base 10 when it is desired that the number of decimal places be limited to the current [`DECIMAL_PLACES`](http://mikemcl.github.io/bignumber.js/#decimal-places) setting.
151 +
152 + ```javascript
153 + x.toString(16) // "ff.8"
154 + ```
155 +
156 +There is a [`toFormat`](http://mikemcl.github.io/bignumber.js/#toFor) method which may be useful for internationalisation.
157 +
158 +```javascript
159 +y = new BigNumber('1234567.898765')
160 +y.toFormat(2) // "1,234,567.90"
161 +```
162 +
163 +The maximum number of decimal places of the result of an operation involving division (i.e. a division, square root, base conversion or negative power operation) is set using the `set` or `config` method of the `BigNumber` constructor.
164 +
165 +The other arithmetic operations always give the exact result.
166 +
167 +```javascript
168 +BigNumber.set({ DECIMAL_PLACES: 10, ROUNDING_MODE: 4 })
169 +
170 +x = new BigNumber(2)
171 +y = new BigNumber(3)
172 +z = x.dividedBy(y) // "0.6666666667"
173 +z.squareRoot() // "0.8164965809"
174 +z.exponentiatedBy(-3) // "3.3749999995"
175 +z.toString(2) // "0.1010101011"
176 +z.multipliedBy(z) // "0.44444444448888888889"
177 +z.multipliedBy(z).decimalPlaces(10) // "0.4444444445"
178 +```
179 +
180 +There is a [`toFraction`](http://mikemcl.github.io/bignumber.js/#toFr) method with an optional *maximum denominator* argument
181 +
182 +```javascript
183 +y = new BigNumber(355)
184 +pi = y.dividedBy(113) // "3.1415929204"
185 +pi.toFraction() // [ "7853982301", "2500000000" ]
186 +pi.toFraction(1000) // [ "355", "113" ]
187 +```
188 +
189 +and [`isNaN`](http://mikemcl.github.io/bignumber.js/#isNaN) and [`isFinite`](http://mikemcl.github.io/bignumber.js/#isF) methods, as `NaN` and `Infinity` are valid `BigNumber` values.
190 +
191 +```javascript
192 +x = new BigNumber(NaN) // "NaN"
193 +y = new BigNumber(Infinity) // "Infinity"
194 +x.isNaN() && !y.isNaN() && !x.isFinite() && !y.isFinite() // true
195 +```
196 +
197 +The value of a BigNumber is stored in a decimal floating point format in terms of a coefficient, exponent and sign.
198 +
199 +```javascript
200 +x = new BigNumber(-123.456);
201 +x.c // [ 123, 45600000000000 ] coefficient (i.e. significand)
202 +x.e // 2 exponent
203 +x.s // -1 sign
204 +```
205 +
206 +For advanced usage, multiple BigNumber constructors can be created, each with their own independent configuration.
207 +
208 +```javascript
209 +// Set DECIMAL_PLACES for the original BigNumber constructor
210 +BigNumber.set({ DECIMAL_PLACES: 10 })
211 +
212 +// Create another BigNumber constructor, optionally passing in a configuration object
213 +BN = BigNumber.clone({ DECIMAL_PLACES: 5 })
214 +
215 +x = new BigNumber(1)
216 +y = new BN(1)
217 +
218 +x.div(3) // '0.3333333333'
219 +y.div(3) // '0.33333'
220 +```
221 +
222 +For further information see the [API](http://mikemcl.github.io/bignumber.js/) reference in the *doc* directory.
223 +
224 +## Test
225 +
226 +The *test/modules* directory contains the test scripts for each method.
227 +
228 +The tests can be run with Node.js or a browser. For Node.js use
229 +
230 + $ npm test
231 +
232 +or
233 +
234 + $ node test/test
235 +
236 +To test a single method, use, for example
237 +
238 + $ node test/methods/toFraction
239 +
240 +For the browser, open *test/test.html*.
241 +
242 +## Build
243 +
244 +For Node, if [uglify-js](https://github.com/mishoo/UglifyJS2) is installed
245 +
246 + npm install uglify-js -g
247 +
248 +then
249 +
250 + npm run build
251 +
252 +will create *bignumber.min.js*.
253 +
254 +A source map will also be created in the root directory.
255 +
256 +## Feedback
257 +
258 +Open an issue, or email
259 +
260 +Michael
261 +
262 +<a href="mailto:M8ch88l@gmail.com">M8ch88l@gmail.com</a>
263 +
264 +## Licence
265 +
266 +The MIT Licence.
267 +
268 +See [LICENCE](https://github.com/MikeMcl/bignumber.js/blob/master/LICENCE).
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
1 +{
2 + "_from": "bignumber.js@9.0.0",
3 + "_id": "bignumber.js@9.0.0",
4 + "_inBundle": false,
5 + "_integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==",
6 + "_location": "/bignumber.js",
7 + "_phantomChildren": {},
8 + "_requested": {
9 + "type": "version",
10 + "registry": true,
11 + "raw": "bignumber.js@9.0.0",
12 + "name": "bignumber.js",
13 + "escapedName": "bignumber.js",
14 + "rawSpec": "9.0.0",
15 + "saveSpec": null,
16 + "fetchSpec": "9.0.0"
17 + },
18 + "_requiredBy": [
19 + "/mysql"
20 + ],
21 + "_resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz",
22 + "_shasum": "805880f84a329b5eac6e7cb6f8274b6d82bdf075",
23 + "_spec": "bignumber.js@9.0.0",
24 + "_where": "C:\\Users\\user\\Desktop\\Singer-Composer\\node_modules\\mysql",
25 + "author": {
26 + "name": "Michael Mclaughlin",
27 + "email": "M8ch88l@gmail.com"
28 + },
29 + "browser": "bignumber.js",
30 + "bugs": {
31 + "url": "https://github.com/MikeMcl/bignumber.js/issues"
32 + },
33 + "bundleDependencies": false,
34 + "dependencies": {},
35 + "deprecated": false,
36 + "description": "A library for arbitrary-precision decimal and non-decimal arithmetic",
37 + "engines": {
38 + "node": "*"
39 + },
40 + "homepage": "https://github.com/MikeMcl/bignumber.js#readme",
41 + "keywords": [
42 + "arbitrary",
43 + "precision",
44 + "arithmetic",
45 + "big",
46 + "number",
47 + "decimal",
48 + "float",
49 + "biginteger",
50 + "bigdecimal",
51 + "bignumber",
52 + "bigint",
53 + "bignum"
54 + ],
55 + "license": "MIT",
56 + "main": "bignumber",
57 + "module": "bignumber.mjs",
58 + "name": "bignumber.js",
59 + "repository": {
60 + "type": "git",
61 + "url": "git+https://github.com/MikeMcl/bignumber.js.git"
62 + },
63 + "scripts": {
64 + "build": "uglifyjs bignumber.js --source-map -c -m -o bignumber.min.js",
65 + "test": "node test/test"
66 + },
67 + "types": "bignumber.d.ts",
68 + "version": "9.0.0"
69 +}
1 +language: node_js
2 +node_js:
3 + - "0.8"
4 + - "0.10"
1 +
2 +test:
3 + @node_modules/.bin/tape test.js
4 +
5 +.PHONY: test
6 +
1 +
2 +# isarray
3 +
4 +`Array#isArray` for older browsers.
5 +
6 +[![build status](https://secure.travis-ci.org/juliangruber/isarray.svg)](http://travis-ci.org/juliangruber/isarray)
7 +[![downloads](https://img.shields.io/npm/dm/isarray.svg)](https://www.npmjs.org/package/isarray)
8 +
9 +[![browser support](https://ci.testling.com/juliangruber/isarray.png)
10 +](https://ci.testling.com/juliangruber/isarray)
11 +
12 +## Usage
13 +
14 +```js
15 +var isArray = require('isarray');
16 +
17 +console.log(isArray([])); // => true
18 +console.log(isArray({})); // => false
19 +```
20 +
21 +## Installation
22 +
23 +With [npm](http://npmjs.org) do
24 +
25 +```bash
26 +$ npm install isarray
27 +```
28 +
29 +Then bundle for the browser with
30 +[browserify](https://github.com/substack/browserify).
31 +
32 +With [component](http://component.io) do
33 +
34 +```bash
35 +$ component install juliangruber/isarray
36 +```
37 +
38 +## License
39 +
40 +(MIT)
41 +
42 +Copyright (c) 2013 Julian Gruber &lt;julian@juliangruber.com&gt;
43 +
44 +Permission is hereby granted, free of charge, to any person obtaining a copy of
45 +this software and associated documentation files (the "Software"), to deal in
46 +the Software without restriction, including without limitation the rights to
47 +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
48 +of the Software, and to permit persons to whom the Software is furnished to do
49 +so, subject to the following conditions:
50 +
51 +The above copyright notice and this permission notice shall be included in all
52 +copies or substantial portions of the Software.
53 +
54 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
55 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
56 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
57 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
58 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
59 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
60 +SOFTWARE.
1 +{
2 + "name" : "isarray",
3 + "description" : "Array#isArray for older browsers",
4 + "version" : "0.0.1",
5 + "repository" : "juliangruber/isarray",
6 + "homepage": "https://github.com/juliangruber/isarray",
7 + "main" : "index.js",
8 + "scripts" : [
9 + "index.js"
10 + ],
11 + "dependencies" : {},
12 + "keywords": ["browser","isarray","array"],
13 + "author": {
14 + "name": "Julian Gruber",
15 + "email": "mail@juliangruber.com",
16 + "url": "http://juliangruber.com"
17 + },
18 + "license": "MIT"
19 +}
1 +var toString = {}.toString;
2 +
3 +module.exports = Array.isArray || function (arr) {
4 + return toString.call(arr) == '[object Array]';
5 +};
1 +{
2 + "_from": "isarray@~1.0.0",
3 + "_id": "isarray@1.0.0",
4 + "_inBundle": false,
5 + "_integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
6 + "_location": "/isarray",
7 + "_phantomChildren": {},
8 + "_requested": {
9 + "type": "range",
10 + "registry": true,
11 + "raw": "isarray@~1.0.0",
12 + "name": "isarray",
13 + "escapedName": "isarray",
14 + "rawSpec": "~1.0.0",
15 + "saveSpec": null,
16 + "fetchSpec": "~1.0.0"
17 + },
18 + "_requiredBy": [
19 + "/readable-stream"
20 + ],
21 + "_resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
22 + "_shasum": "bb935d48582cba168c06834957a54a3e07124f11",
23 + "_spec": "isarray@~1.0.0",
24 + "_where": "C:\\Users\\user\\Desktop\\Singer-Composer\\node_modules\\readable-stream",
25 + "author": {
26 + "name": "Julian Gruber",
27 + "email": "mail@juliangruber.com",
28 + "url": "http://juliangruber.com"
29 + },
30 + "bugs": {
31 + "url": "https://github.com/juliangruber/isarray/issues"
32 + },
33 + "bundleDependencies": false,
34 + "dependencies": {},
35 + "deprecated": false,
36 + "description": "Array#isArray for older browsers",
37 + "devDependencies": {
38 + "tape": "~2.13.4"
39 + },
40 + "homepage": "https://github.com/juliangruber/isarray",
41 + "keywords": [
42 + "browser",
43 + "isarray",
44 + "array"
45 + ],
46 + "license": "MIT",
47 + "main": "index.js",
48 + "name": "isarray",
49 + "repository": {
50 + "type": "git",
51 + "url": "git://github.com/juliangruber/isarray.git"
52 + },
53 + "scripts": {
54 + "test": "tape test.js"
55 + },
56 + "testling": {
57 + "files": "test.js",
58 + "browsers": [
59 + "ie/8..latest",
60 + "firefox/17..latest",
61 + "firefox/nightly",
62 + "chrome/22..latest",
63 + "chrome/canary",
64 + "opera/12..latest",
65 + "opera/next",
66 + "safari/5.1..latest",
67 + "ipad/6.0..latest",
68 + "iphone/6.0..latest",
69 + "android-browser/4.2..latest"
70 + ]
71 + },
72 + "version": "1.0.0"
73 +}
1 +var isArray = require('./');
2 +var test = require('tape');
3 +
4 +test('is array', function(t){
5 + t.ok(isArray([]));
6 + t.notOk(isArray({}));
7 + t.notOk(isArray(null));
8 + t.notOk(isArray(false));
9 +
10 + var obj = {};
11 + obj[0] = true;
12 + t.notOk(isArray(obj));
13 +
14 + var arr = [];
15 + arr.foo = 'bar';
16 + t.ok(isArray(arr));
17 +
18 + t.end();
19 +});
20 +
1 +language: node_js
2 +sudo: false
3 +script: npm run coverage
4 +node_js:
5 +- '6'
6 +- '7'
7 +cache:
8 + directories:
9 + - node_modules
1 +## [v2.0.0]
2 +> Jun 5, 2018
3 +
4 +See [Upgrading to v2.0.0](https://github.com/rstacruz/mocha-jsdom#upgrading-to-v200) for notes on how to update from an older version.
5 +
6 +* [#32] - `jsdom` is now a direct dependency of `mocha-jsdom` :tada:
7 +
8 +[#32]: https://github.com/rstacruz/mocha-jsdom/issues/32
9 +[v2.0.0]: https://github.com/rstacruz/mocha-jsdom/compare/v1.2.0...v2.0.0
10 +
11 +## [v1.2.0]
12 +> Jun 5, 2018
13 +
14 +* [#29] - Update Jsdom compatibility ([@RobLoach])
15 +* [#31] - Update all npm dependencies
16 +
17 +[#29]: https://github.com/rstacruz/mocha-jsdom/issues/29
18 +[#31]: https://github.com/rstacruz/mocha-jsdom/issues/31
19 +[@RobLoach]: https://github.com/robloach
20 +[v1.2.0]: https://github.com/rstacruz/mocha-jsdom/compare/v1.1.0...v1.2.0
21 +
22 +## [v1.1.0]
23 +> Feb 22, 2016
24 +
25 +* [#18] - Initialize global.window when it is undefined; fixes compatibility with [airbnb/enzyme][]. ([@moonboots])
26 +
27 +[v1.1.0]: https://github.com/rstacruz/mocha-jsdom/compare/v1.0.0...v1.1.0
28 +
29 +## [v1.0.0] - Jul 4, 2015
30 +
31 +* Add testling/browserify support.
32 +* Add more examples.
33 +
34 +[v1.0.0]: https://github.com/rstacruz/mocha-jsdom/compare/v0.5.0...v1.0.0
35 +
36 +## [v0.5.0] - Jun 26, 2015
37 +
38 +* Add `rerequire()` to help with using mocha-jsdom with `mocha --watch`.
39 +* Internal: change coding standard to feross/standard.
40 +
41 +## [v0.4.0] - May 25, 2015
42 +
43 +* [#5] - Add `useEach` option. ([@jasco], [#6])
44 +* [#7] - Add a `skipWindowCheck` option.
45 +
46 +## [v0.3.0] - Apr 3, 2015
47 +
48 +* [#3] - Bump `jsdom` dependency version. This fixes the "needs a context" error ([@nacyot], [#3])
49 +
50 +[#3]: https://github.com/rstacruz/mocha-jsdom/issues/3
51 +[#4]: https://github.com/rstacruz/mocha-jsdom/issues/4
52 +[@nacyot]: https://github.com/nacyot
53 +
54 +## [v0.2.1] - Feb 19, 2014
55 +
56 +* Add `LICENSE` file
57 +* Update documentation
58 +* No functionality changes
59 +
60 +## [v0.2.0] - November 5, 2014
61 +
62 +* Skip warnings. Add `JSDOM_VERBOSE=1` to your env to reenable them.
63 +
64 +## [v0.1.2] - September 27, 2014
65 +
66 +* Throw a useful error when invoked twice.
67 +
68 +## [v0.1.1] - September 27, 2014
69 +
70 +* Re-release with updated Readme.
71 +
72 +[airbnb/enzyme]: https://github.com/airbnb/enzyme
73 +
74 +## v0.1.0 - September 25, 2014
75 +
76 +* Initial version.
77 +
78 +[#5]: https://github.com/rstacruz/mocha-jsdom/issues/5
79 +[#6]: https://github.com/rstacruz/mocha-jsdom/issues/6
80 +[#7]: https://github.com/rstacruz/mocha-jsdom/issues/7
81 +[@jasco]: https://github.com/jasco
82 +[v0.5.0]: https://github.com/rstacruz/mocha-jsdom/compare/v0.4.0...v0.5.0
83 +[v0.4.0]: https://github.com/rstacruz/mocha-jsdom/compare/v0.3.0...v0.4.0
84 +[v0.3.0]: https://github.com/rstacruz/mocha-jsdom/compare/v0.2.1...v0.3.0
85 +[v0.2.1]: https://github.com/rstacruz/mocha-jsdom/compare/v0.2.0...v0.2.1
86 +[v0.2.0]: https://github.com/rstacruz/mocha-jsdom/compare/v0.1.2...v0.2.0
87 +[v0.1.2]: https://github.com/rstacruz/mocha-jsdom/compare/v0.1.1...v0.1.2
88 +[v0.1.1]: https://github.com/rstacruz/mocha-jsdom/compare/v0.1.0...v0.1.1
89 +[#18]: https://github.com/rstacruz/mocha-jsdom/issues/18
90 +[@moonboots]: https://github.com/moonboots
1 +Copyright © 2015 Rico Sta. Cruz
2 +
3 +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:
4 +
5 +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 +
7 +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.
1 +> _Deprecation notice:_
2 +> Consider [jsdom-global](https://github.com/rstacruz/jsdom-global) instead, a simpler alternative that also works outside of Mocha. `mocha-jsdom` still works, but `jsdom-global` is better supported.
3 +
4 +---
5 +
6 +# mocha-jsdom
7 +
8 +> Test frontend libraries in the console using Node.js, [mocha] and [jsdom].
9 +
10 +[![Status](https://travis-ci.org/rstacruz/mocha-jsdom.svg?branch=master)](https://travis-ci.org/rstacruz/mocha-jsdom "See test builds")
11 +
12 +<br>
13 +
14 +## Usage
15 +
16 +```sh
17 +$ npm i --save-dev mocha-jsdom
18 +```
19 +
20 +[![npm version](http://img.shields.io/npm/v/mocha-jsdom.svg?style=flat)](https://npmjs.org/package/mocha-jsdom "View this project on npm")
21 +
22 +Use `jsdom()` inside your `describe(...)` block (or the global context). It will
23 +turn your Node.js environment into a mock browser environment supporting the
24 +full DOM and browser API. The variables `window`, `document`, `history` (and so
25 +on) will then be available for use.
26 +
27 +```js
28 +var jsdom = require('mocha-jsdom')
29 +var expect = require('chai').expect
30 +
31 +describe('mocha tests', function () {
32 +
33 + jsdom()
34 +
35 + it('has document', function () {
36 + var div = document.createElement('div')
37 + expect(div.nodeName).eql('DIV')
38 + })
39 +
40 +})
41 +```
42 +
43 +See [examples/basic](examples/basic) for an example of a basic setup.
44 +
45 +<br>
46 +
47 +## Upgrading to v2.0.0
48 +
49 +If you are coming from mocha-jsdom v1.x, remove `jsdom` if you're not using it before upgrading. `jsdom` is now a direct dependency of `mocha-jsdom`.
50 +
51 +```bash
52 +# using Yarn
53 +yarn remove jsdom
54 +yarn upgrade mocha-jsdom
55 +```
56 +
57 +```bash
58 +# using npm
59 +npm uninstall -S -D jsdom
60 +npm upgrade mocha-jsdom
61 +```
62 +
63 +<br>
64 +
65 +## Node and io.js information
66 +
67 +As of jsdom 4.0.0, [jsdom now requires io.js](https://github.com/tmpvar/jsdom/blob/master/Changelog.md#400) and will not work with Node.js 0.12 or below.
68 +
69 +<br>
70 +
71 +## How it works
72 +
73 +mocha-jsdom is a simple glue to integrate [jsdom] to mocha.
74 +
75 +Invoking `jsdom()` will inject `before` and `after` handlers to the current
76 +mocha suite which will setup and teardown jsdom. Here's what it does:
77 +
78 +* __Window__: `global.window` will be available as the jsdom.
79 +
80 +* __Globals__: global variables like `document` and `history` are propagated,
81 + and they're cleaned up after tests run.
82 +
83 +* __Error handling__: jsdom errors are sanitized so that their stack traces are
84 +shortened.
85 +
86 +__NB:__ Before you try this library, learn about jsdom first. In fact, you may be
87 +able to integrate jsdom into your tests *without* this library; this is mostly
88 +syntactic sugar and reasonable defaults.
89 +
90 +<br>
91 +
92 +## Using with a library
93 +
94 +Perfect for testing small DOM-consuming utilities in the console. See
95 +[test/jquery.js](test/jquery.js) for an example.
96 +
97 +```js
98 +describe('mocha tests', function () {
99 +
100 + var $
101 + jsdom()
102 +
103 + before(function () {
104 + $ = require('jquery')
105 + })
106 +
107 + it('works', function () {
108 + document.body.innerHTML = '<div>hola</div>'
109 + expect($("div").html()).eql('hola')
110 + })
111 +
112 +})
113 +```
114 +
115 +See [examples/basic](examples/basic) for an example of a basic setup.
116 +
117 +<br>
118 +
119 +## Using with a library, alternate
120 +
121 +You can also pass the source code via `src`:
122 +
123 +```js
124 +describe('mocha tests', function () {
125 + jsdom({
126 + src: fs.readFileSync('jquery.js', 'utf-8')
127 + })
128 +
129 + ...
130 +})
131 +```
132 +
133 +<br>
134 +
135 +## Configuration
136 +
137 +You can pass jsdom options:
138 +
139 +```js
140 +describe('mocha tests', function () {
141 + jsdom({
142 + parsingMode: 'xml'
143 + })
144 +
145 + ...
146 +})
147 +```
148 +
149 +<br>
150 +
151 +## Working with mocha --watch
152 +
153 +When using with `--watch`, you my encounter strange errors from 3rd-party
154 +libraries like jQuery not working properly.
155 +
156 +In these cases, use `require('mocha-jsdom').rerequire` instead of `require()`.
157 +This will ensure that the `require()` call will always happen.
158 +
159 +```js
160 +var $
161 +var jsdom = require('mocha-jsdom')
162 +var rerequire = jsdom.rerequire
163 +
164 +jsdom()
165 +
166 +before(function () {
167 + $ = rerequire('jquery')
168 +})
169 +```
170 +
171 +<br>
172 +
173 +## Special config
174 +
175 +Other mocha-jsdom specific options:
176 +
177 + * `globalize` - propagates to values in `window` to `global`. defaults to true.
178 +
179 + * `console` - allows you to use `console.log` inside a jsdom script. defaults
180 + to true.
181 +
182 + * `useEach` - bind to Mocha's `beforeEach`/`afterEach` rather than `before`/`after`.
183 + defaults to false.
184 +
185 + * `skipWindowCheck` - skips checking of `window` at startup. When false,
186 + mocha-jsdom will throw an error if `window` already exists. Defaults to false.
187 +
188 +[jsdom]: https://www.npmjs.org/package/jsdom
189 +[mocha]: https://www.npmjs.com/package/mocha
190 +
191 +<br>
192 +
193 +## Testling support
194 +
195 +Yes, fully compatible with testling. A test suite using jsdom should be able to use testling.
196 +
197 +See [examples/basic](examples/basic/) for a setup that allows for testing via iojs (jsdom), testling, and mocha via the browser.
198 +
199 +<br>
200 +
201 +## Thanks
202 +
203 +> **mocha-jsdom** © 2014-2018 Rico Sta. Cruz. Released under the [MIT] License.<br>
204 +> Authored and maintained by Rico Sta. Cruz with help from contributors ([list][contributors]).
205 +
206 +[![](https://img.shields.io/github/followers/rstacruz.svg?style=social&label=@rstacruz)](https://github.com/rstacruz)
207 +&nbsp;&nbsp;
208 +[![](https://img.shields.io/twitter/follow/rstacruz.svg?style=social&label=@rstacruz)](https://twitter.com/rstacruz)
209 +&nbsp;&nbsp;
210 +**[ricostacruz.com](http://ricostacruz.com)**
211 +
212 +[mit]: http://mit-license.org/
213 +[contributors]: http://github.com/rstacruz/mocha-jsdom/contributors
1 +/*
2 + * A noop version in case your tests are browserified (eg, when using
3 + * testling).
4 + */
5 +
6 +module.exports = function () {}
1 +This is a basic example of what you can put in your project's `test/` folder.
2 +It will allow you to run tests in both jsdom (iojs/node) and the browser.
1 +<!doctype html>
2 +<html>
3 +<head>
4 + <title>Mocha</title>
5 + <meta charset="utf-8">
6 + <meta name="viewport" content="width=device-width, initial-scale=1.0">
7 + <link href="https://cdn.rawgit.com/mochajs/mocha/2.2.5/mocha.css" rel="stylesheet" />
8 +</head>
9 +<body>
10 + <div id="mocha"></div>
11 + <script src="https://cdn.rawgit.com/mochajs/mocha/2.2.5/mocha.js"></script>
12 + <script src="https://cdn.rawgit.com/chaijs/chai/2.3.0/chai.js"></script>
13 + <script>mocha.setup('bdd')</script>
14 + <!-- thing to test -->
15 + <script src="../index.js"></script>
16 + <!-- your test files -->
17 + <script src="setup.js"></script>
18 + <script src="test.js"></script>
19 + <script>mocha.run()</script>
20 +</body>
21 +</html>
1 +if (typeof process === 'object') {
2 + // Initialize node environment
3 + global.expect = require('chai').expect
4 + require('mocha-jsdom')()
5 +} else {
6 + window.expect = window.chai.expect
7 + window.require = function () { /* noop */ }
8 +}
1 +/* global describe, it, before, expect */
2 +require('./setup')
3 +
4 +describe('my library', function () {
5 + var mylib
6 +
7 + before(function () {
8 + mylib = require('mylib') || window.mylib
9 + })
10 +
11 + it('works', function () {
12 + expect(mylib.greet()).to.eql('hola')
13 + })
14 +})
1 +These examples are here so you can see what failures look like.
2 +
3 +Run `mocha one.js` or `mocha two.js` to see.
1 +/* global it, expect, describe */
2 +/* jshint expr: true */
3 +
4 +var jsdom = require('../../index')
5 +
6 +describe('error', function () {
7 + jsdom({
8 + src: "(function () { throw new Error('ffff'); })()"
9 + })
10 +
11 + it('fails', function () {
12 + expect(global.document).be.undefined // eslint-disable-line no-unused-expressions
13 + })
14 +})
1 +/* global describe, it, expect */
2 +
3 +describe('src', function () {
4 + require('../../index')({
5 + src: '}}'
6 + })
7 +
8 + it('works', function () {
9 + expect(window.lol()).eql('DIV')
10 + })
11 +})
1 +var extend = Object.assign || require('util')._extend // eslint-disable-line node/no-deprecated-api
2 +var Path = require('path')
3 +
4 +/*
5 + * store original global keys
6 + */
7 +
8 +var blacklist = Object.keys(global)
9 +blacklist.push('constructor')
10 +
11 +/*
12 + * default config
13 + */
14 +
15 +var defaults = {
16 + globalize: true,
17 + console: true,
18 + useEach: false,
19 + skipWindowCheck: false,
20 + html:
21 + "<!doctype html><html><head><meta charset='utf-8'></head>" +
22 + '<body></body></html>'
23 +}
24 +
25 +/*
26 + * simple jsdom integration.
27 + * You can pass jsdom options in, too:
28 + *
29 + * require('./support/jsdom')({
30 + * src: [ jquery ]
31 + * })
32 + */
33 +
34 +module.exports = function (_options) {
35 + var options = extend(extend({}, defaults), _options)
36 +
37 + var keys = []
38 +
39 + var before = options.useEach ? global.beforeEach : global.before
40 + var after = options.useEach ? global.afterEach : global.after
41 +
42 + /*
43 + * register jsdom before the entire test suite
44 + */
45 +
46 + before(function (next) {
47 + if (global.window && !options.skipWindowCheck) {
48 + throw new Error(
49 + 'mocha-jsdom: already a browser environment, or mocha-jsdom invoked ' +
50 + "twice. use 'skipWindowCheck' to disable this check."
51 + )
52 + }
53 + require('jsdom/lib/old-api').env(
54 + extend(extend({}, options), { done: done })
55 + )
56 +
57 + function done (errors, window) {
58 + if (options.globalize) {
59 + propagateToGlobal(window)
60 + } else {
61 + global.window = window
62 + }
63 +
64 + if (options.console) {
65 + window.console = global.console
66 + }
67 +
68 + if (errors) {
69 + return next(getError(errors))
70 + }
71 +
72 + next(null)
73 + }
74 + })
75 +
76 + /*
77 + * undo keys from being propagated to global after the test suite
78 + */
79 +
80 + after(function () {
81 + if (options.globalize) {
82 + keys.forEach(function (key) {
83 + delete global[key]
84 + })
85 + } else {
86 + delete global.window
87 + }
88 + })
89 +
90 + /*
91 + * propagate keys from `window` to `global`
92 + */
93 +
94 + function propagateToGlobal (window) {
95 + for (var key in window) {
96 + if (!window.hasOwnProperty(key)) continue
97 + if (~blacklist.indexOf(key)) continue
98 + if (global[key]) {
99 + if (process.env.JSDOM_VERBOSE) {
100 + console.warn(
101 + "[jsdom] Warning: skipping cleanup of global['" + key + "']"
102 + )
103 + }
104 + continue
105 + }
106 +
107 + keys.push(key)
108 + global[key] = window[key]
109 + }
110 + }
111 +
112 + /*
113 + * re-throws jsdom errors
114 + */
115 +
116 + function getError (errors) {
117 + var data = errors[0].data
118 + var err = data.error
119 + err.message = err.message + ' [jsdom]'
120 +
121 + // clean up stack trace
122 + if (err.stack) {
123 + err.stack = err.stack
124 + .split('\n')
125 + .reduce(function (list, line) {
126 + if (line.match(/node_modules.+(jsdom|mocha)/)) {
127 + return list
128 + }
129 +
130 + line = line
131 + .replace(/file:\/\/.*<script>/g, '<script>')
132 + .replace(/:undefined:undefined/g, '')
133 + list.push(line)
134 + return list
135 + }, [])
136 + .join('\n')
137 + }
138 +
139 + return err
140 + }
141 +}
142 +
143 +module.exports.rerequire = rerequire
144 +
145 +/**
146 + * Requires a module via `require()`, but invalidates the cache so it may be
147 + * called again in the future. Useful for `mocha --watch`.
148 + *
149 + * var rerequire = require('mocha-jsdom').rerequire
150 + * var $ = rerequire('jquery')
151 + */
152 +
153 +function rerequire (module) {
154 + if (module[0] === '.') {
155 + module = Path.join(Path.dirname(getCaller()), module)
156 + }
157 +
158 + var oldkeys = Object.keys(require.cache)
159 + var result = require(module)
160 + var newkeys = Object.keys(require.cache)
161 + newkeys.forEach(function (newkey) {
162 + if (!~oldkeys.indexOf(newkey)) {
163 + delete require.cache[newkey]
164 + }
165 + })
166 + return result
167 +}
168 +
169 +/**
170 + * Internal: gets the filename of the caller function. The `offset` defines how
171 + * many hops away it's expected to be from in the stack trace.
172 + *
173 + * See: http://stackoverflow.com/questions/16697791/nodejs-get-filename-of-caller-function
174 + */
175 +
176 +function getCaller (offset) {
177 + /* eslint-disable handle-callback-err */
178 + if (typeof offset !== 'number') offset = 1
179 + var old = Error.prepareStackTrace
180 + var err = new Error()
181 + Error.prepareStackTrace = function (err, stack) {
182 + return stack
183 + }
184 + var fname = err.stack[1 + offset].getFileName()
185 + Error.prepareStackTrace = old
186 + return fname
187 +}
1 +{
2 + "_args": [
3 + [
4 + "mocha-jsdom@2.0.0",
5 + "C:\\Users\\user\\Desktop\\Singer-Composer"
6 + ]
7 + ],
8 + "_development": true,
9 + "_from": "mocha-jsdom@2.0.0",
10 + "_id": "mocha-jsdom@2.0.0",
11 + "_inBundle": false,
12 + "_integrity": "sha512-+3D++FPXHXEesbBD7Q/r4dkc3XzVFMPLJVIECaQ685dj9qKQYzliqX8IXyIUbUL4x1QfgD9h8Zao8cn03NKKEA==",
13 + "_location": "/mocha-jsdom",
14 + "_phantomChildren": {},
15 + "_requested": {
16 + "type": "version",
17 + "registry": true,
18 + "raw": "mocha-jsdom@2.0.0",
19 + "name": "mocha-jsdom",
20 + "escapedName": "mocha-jsdom",
21 + "rawSpec": "2.0.0",
22 + "saveSpec": null,
23 + "fetchSpec": "2.0.0"
24 + },
25 + "_requiredBy": [
26 + "#DEV:/"
27 + ],
28 + "_resolved": "https://registry.npmjs.org/mocha-jsdom/-/mocha-jsdom-2.0.0.tgz",
29 + "_spec": "2.0.0",
30 + "_where": "C:\\Users\\user\\Desktop\\Singer-Composer",
31 + "author": {
32 + "name": "Rico Sta. Cruz",
33 + "email": "rico@ricostacruz.com"
34 + },
35 + "browser": "browser.js",
36 + "bugs": {
37 + "url": "https://github.com/rstacruz/mocha-jsdom/issues"
38 + },
39 + "dependencies": {
40 + "jsdom": "^11.11.0"
41 + },
42 + "description": "Simple integration of jsdom into mocha tests",
43 + "devDependencies": {
44 + "chai": "4.1.2",
45 + "istanbul": "0.4.5",
46 + "jquery": "3.3.1",
47 + "mocha": "5.2.0",
48 + "mocha-standard": "1.0.0",
49 + "standard": "11.0.1"
50 + },
51 + "directories": {
52 + "test": "test"
53 + },
54 + "homepage": "https://github.com/rstacruz/mocha-jsdom#readme",
55 + "keywords": [
56 + "jsdom",
57 + "mocha"
58 + ],
59 + "license": "MIT",
60 + "main": "index.js",
61 + "name": "mocha-jsdom",
62 + "peerDependencies": {
63 + "mocha": "*"
64 + },
65 + "repository": {
66 + "type": "git",
67 + "url": "git+https://github.com/rstacruz/mocha-jsdom.git"
68 + },
69 + "scripts": {
70 + "coverage": "istanbul cover _mocha -- -R spec",
71 + "test": "mocha"
72 + },
73 + "version": "2.0.0"
74 +}
1 +/* this module will have side effects if it's ran more than once.
2 + * we're gonna test for that. */
3 +
4 +global._rerequirable_count++
1 +/* global describe, it, expect */
2 +/* jshint expr: true */
3 +
4 +var jsdom = require('../index')
5 +
6 +describe('globalize', function () {
7 + jsdom({ globalize: false })
8 +
9 + it('does not globalize', function () {
10 + expect(global.document).be.undefined // eslint-disable-line no-unused-expressions
11 + })
12 +})
1 +/* global describe, before, it, document, expect */
2 +
3 +var jsdom = require('../index')
4 +
5 +describe('jquery', function () {
6 + var $
7 + jsdom()
8 +
9 + before(function () {
10 + $ = require('jquery')
11 + })
12 +
13 + it('creating elements works', function () {
14 + var div = $('<div>hello <b>world</b></div>')
15 + expect(div.html()).to.eql('hello <b>world</b>')
16 + })
17 +
18 + it('lookup works', function () {
19 + document.body.innerHTML = '<div>hola</div>'
20 + expect($('div').html()).eql('hola')
21 + })
22 +})
1 +--require test/setup
2 +--timeout 5000
1 +/* global describe, it, beforeEach, expect */
2 +
3 +var rerequire = require('../index').rerequire
4 +
5 +describe('rerequire', function () {
6 + beforeEach(function () {
7 + global._rerequirable_count = 0
8 + })
9 +
10 + it('has a fixture that works', function () {
11 + rerequire('./fixtures/rerequirable')
12 + expect(global._rerequirable_count).eql(1)
13 + })
14 +
15 + // ensure that subsequent runs don't bother
16 + it('has a fixture that really works', function () {
17 + rerequire('./fixtures/rerequirable')
18 + expect(global._rerequirable_count).eql(1)
19 + })
20 +
21 + it('works 5x', function () {
22 + rerequire('./fixtures/rerequirable')
23 + rerequire('./fixtures/rerequirable')
24 + rerequire('./fixtures/rerequirable')
25 + rerequire('./fixtures/rerequirable')
26 + rerequire('./fixtures/rerequirable')
27 + expect(global._rerequirable_count).eql(5)
28 + })
29 +})
1 +/* global it, before, window, describe, expect */
2 +
3 +var jsdom = require('../index')
4 +
5 +describe('robust', function () {
6 + before(function () {
7 + // User or another test framework redefines global.window
8 + global.window = undefined
9 + })
10 +
11 + jsdom()
12 +
13 + it('has window', function () {
14 + expect(global.window).to.not.be.undefined // eslint-disable-line no-unused-expressions
15 + })
16 +})
1 +global.expect = require('chai').expect
1 +/* global it, history, describe, location, expect */
2 +
3 +var jsdom = require('../index')
4 +
5 +describe('simple', function () {
6 + jsdom()
7 +
8 + it('has document', function () {
9 + var div = document.createElement('div')
10 + expect(div.nodeName).eql('DIV')
11 + })
12 +
13 + it('has history', function () {
14 + history.pushState({}, 'abc', '#/a/b/c')
15 + expect(location.href).match(/\/a\/b\/c$/)
16 + })
17 +})
1 +/* global describe, it, before, after, expect */
2 +/* jshint expr: true */
3 +
4 +var jsdom = require('../index')
5 +
6 +describe('skipWindowCheck: true', function () {
7 + before(function () {
8 + global.window = {}
9 + })
10 +
11 + after(function () {
12 + delete global.window
13 + })
14 +
15 + jsdom({ skipWindowCheck: true })
16 +
17 + it('does not throw errors', function () {
18 + var div = document.createElement('div')
19 + expect(div.nodeName).eql('DIV')
20 + })
21 +})
1 +/* global describe, it */
2 +
3 +describe('standard', function () {
4 + it('is conformed to', require('mocha-standard'))
5 +})
1 +/* global describe, it, expect */
2 +/* jshint expr: true */
3 +
4 +var jsdom = require('../index')
5 +
6 +describe('check useEach false (default)', function () {
7 + var someContent = '<div>hola</div>'
8 + jsdom()
9 +
10 + it('check that html body is empty', function () {
11 + expect(document.body.innerHTML).to.be.empty // eslint-disable-line no-unused-expressions
12 + })
13 +
14 + it('accepts an html body', function () {
15 + document.body.innerHTML = someContent
16 + expect(document.body.innerHTML).eql(someContent)
17 + })
18 +
19 + it('has document persisting across tests', function () {
20 + expect(document.body.innerHTML).eql(someContent)
21 + })
22 +})
23 +
24 +describe('check useEach true', function () {
25 + var someContent = '<div>hola</div>'
26 + jsdom({ useEach: true })
27 +
28 + it('check that html body is empty', function () {
29 + expect(document.body.innerHTML).to.be.empty // eslint-disable-line no-unused-expressions
30 + })
31 +
32 + it('accepts an html body', function () {
33 + document.body.innerHTML = someContent
34 + expect(document.body.innerHTML).eql(someContent)
35 + })
36 +
37 + it('changes to the dom do not persist between tests', function () {
38 + expect(document.body.innerHTML).to.be.empty // eslint-disable-line no-unused-expressions
39 + })
40 +})
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
1 +Copyright (c) 2012 Felix Geisendörfer (felix@debuggable.com) and contributors
2 +
3 + Permission is hereby granted, free of charge, to any person obtaining a copy
4 + of this software and associated documentation files (the "Software"), to deal
5 + in the Software without restriction, including without limitation the rights
6 + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 + copies of the Software, and to permit persons to whom the Software is
8 + furnished to do so, subject to the following conditions:
9 +
10 + The above copyright notice and this permission notice shall be included in
11 + all copies or substantial portions of the Software.
12 +
13 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 + THE SOFTWARE.
This diff is collapsed. Click to expand it.
1 +var Classes = Object.create(null);
2 +
3 +/**
4 + * Create a new Connection instance.
5 + * @param {object|string} config Configuration or connection string for new MySQL connection
6 + * @return {Connection} A new MySQL connection
7 + * @public
8 + */
9 +exports.createConnection = function createConnection(config) {
10 + var Connection = loadClass('Connection');
11 + var ConnectionConfig = loadClass('ConnectionConfig');
12 +
13 + return new Connection({config: new ConnectionConfig(config)});
14 +};
15 +
16 +/**
17 + * Create a new Pool instance.
18 + * @param {object|string} config Configuration or connection string for new MySQL connections
19 + * @return {Pool} A new MySQL pool
20 + * @public
21 + */
22 +exports.createPool = function createPool(config) {
23 + var Pool = loadClass('Pool');
24 + var PoolConfig = loadClass('PoolConfig');
25 +
26 + return new Pool({config: new PoolConfig(config)});
27 +};
28 +
29 +/**
30 + * Create a new PoolCluster instance.
31 + * @param {object} [config] Configuration for pool cluster
32 + * @return {PoolCluster} New MySQL pool cluster
33 + * @public
34 + */
35 +exports.createPoolCluster = function createPoolCluster(config) {
36 + var PoolCluster = loadClass('PoolCluster');
37 +
38 + return new PoolCluster(config);
39 +};
40 +
41 +/**
42 + * Create a new Query instance.
43 + * @param {string} sql The SQL for the query
44 + * @param {array} [values] Any values to insert into placeholders in sql
45 + * @param {function} [callback] The callback to use when query is complete
46 + * @return {Query} New query object
47 + * @public
48 + */
49 +exports.createQuery = function createQuery(sql, values, callback) {
50 + var Connection = loadClass('Connection');
51 +
52 + return Connection.createQuery(sql, values, callback);
53 +};
54 +
55 +/**
56 + * Escape a value for SQL.
57 + * @param {*} value The value to escape
58 + * @param {boolean} [stringifyObjects=false] Setting if objects should be stringified
59 + * @param {string} [timeZone=local] Setting for time zone to use for Date conversion
60 + * @return {string} Escaped string value
61 + * @public
62 + */
63 +exports.escape = function escape(value, stringifyObjects, timeZone) {
64 + var SqlString = loadClass('SqlString');
65 +
66 + return SqlString.escape(value, stringifyObjects, timeZone);
67 +};
68 +
69 +/**
70 + * Escape an identifier for SQL.
71 + * @param {*} value The value to escape
72 + * @param {boolean} [forbidQualified=false] Setting to treat '.' as part of identifier
73 + * @return {string} Escaped string value
74 + * @public
75 + */
76 +exports.escapeId = function escapeId(value, forbidQualified) {
77 + var SqlString = loadClass('SqlString');
78 +
79 + return SqlString.escapeId(value, forbidQualified);
80 +};
81 +
82 +/**
83 + * Format SQL and replacement values into a SQL string.
84 + * @param {string} sql The SQL for the query
85 + * @param {array} [values] Any values to insert into placeholders in sql
86 + * @param {boolean} [stringifyObjects=false] Setting if objects should be stringified
87 + * @param {string} [timeZone=local] Setting for time zone to use for Date conversion
88 + * @return {string} Formatted SQL string
89 + * @public
90 + */
91 +exports.format = function format(sql, values, stringifyObjects, timeZone) {
92 + var SqlString = loadClass('SqlString');
93 +
94 + return SqlString.format(sql, values, stringifyObjects, timeZone);
95 +};
96 +
97 +/**
98 + * Wrap raw SQL strings from escape overriding.
99 + * @param {string} sql The raw SQL
100 + * @return {object} Wrapped object
101 + * @public
102 + */
103 +exports.raw = function raw(sql) {
104 + var SqlString = loadClass('SqlString');
105 +
106 + return SqlString.raw(sql);
107 +};
108 +
109 +/**
110 + * The type constants.
111 + * @public
112 + */
113 +Object.defineProperty(exports, 'Types', {
114 + get: loadClass.bind(null, 'Types')
115 +});
116 +
117 +/**
118 + * Load the given class.
119 + * @param {string} className Name of class to default
120 + * @return {function|object} Class constructor or exports
121 + * @private
122 + */
123 +function loadClass(className) {
124 + var Class = Classes[className];
125 +
126 + if (Class !== undefined) {
127 + return Class;
128 + }
129 +
130 + // This uses a switch for static require analysis
131 + switch (className) {
132 + case 'Connection':
133 + Class = require('./lib/Connection');
134 + break;
135 + case 'ConnectionConfig':
136 + Class = require('./lib/ConnectionConfig');
137 + break;
138 + case 'Pool':
139 + Class = require('./lib/Pool');
140 + break;
141 + case 'PoolCluster':
142 + Class = require('./lib/PoolCluster');
143 + break;
144 + case 'PoolConfig':
145 + Class = require('./lib/PoolConfig');
146 + break;
147 + case 'SqlString':
148 + Class = require('./lib/protocol/SqlString');
149 + break;
150 + case 'Types':
151 + Class = require('./lib/protocol/constants/types');
152 + break;
153 + default:
154 + throw new Error('Cannot find class \'' + className + '\'');
155 + }
156 +
157 + // Store to prevent invoking require()
158 + Classes[className] = Class;
159 +
160 + return Class;
161 +}
This diff is collapsed. Click to expand it.
1 +var urlParse = require('url').parse;
2 +var ClientConstants = require('./protocol/constants/client');
3 +var Charsets = require('./protocol/constants/charsets');
4 +var SSLProfiles = null;
5 +
6 +module.exports = ConnectionConfig;
7 +function ConnectionConfig(options) {
8 + if (typeof options === 'string') {
9 + options = ConnectionConfig.parseUrl(options);
10 + }
11 +
12 + this.host = options.host || 'localhost';
13 + this.port = options.port || 3306;
14 + this.localAddress = options.localAddress;
15 + this.socketPath = options.socketPath;
16 + this.user = options.user || undefined;
17 + this.password = options.password || undefined;
18 + this.database = options.database;
19 + this.connectTimeout = (options.connectTimeout === undefined)
20 + ? (10 * 1000)
21 + : options.connectTimeout;
22 + this.insecureAuth = options.insecureAuth || false;
23 + this.supportBigNumbers = options.supportBigNumbers || false;
24 + this.bigNumberStrings = options.bigNumberStrings || false;
25 + this.dateStrings = options.dateStrings || false;
26 + this.debug = options.debug;
27 + this.trace = options.trace !== false;
28 + this.stringifyObjects = options.stringifyObjects || false;
29 + this.timezone = options.timezone || 'local';
30 + this.flags = options.flags || '';
31 + this.queryFormat = options.queryFormat;
32 + this.pool = options.pool || undefined;
33 + this.ssl = (typeof options.ssl === 'string')
34 + ? ConnectionConfig.getSSLProfile(options.ssl)
35 + : (options.ssl || false);
36 + this.localInfile = (options.localInfile === undefined)
37 + ? true
38 + : options.localInfile;
39 + this.multipleStatements = options.multipleStatements || false;
40 + this.typeCast = (options.typeCast === undefined)
41 + ? true
42 + : options.typeCast;
43 +
44 + if (this.timezone[0] === ' ') {
45 + // "+" is a url encoded char for space so it
46 + // gets translated to space when giving a
47 + // connection string..
48 + this.timezone = '+' + this.timezone.substr(1);
49 + }
50 +
51 + if (this.ssl) {
52 + // Default rejectUnauthorized to true
53 + this.ssl.rejectUnauthorized = this.ssl.rejectUnauthorized !== false;
54 + }
55 +
56 + this.maxPacketSize = 0;
57 + this.charsetNumber = (options.charset)
58 + ? ConnectionConfig.getCharsetNumber(options.charset)
59 + : options.charsetNumber || Charsets.UTF8_GENERAL_CI;
60 +
61 + // Set the client flags
62 + var defaultFlags = ConnectionConfig.getDefaultFlags(options);
63 + this.clientFlags = ConnectionConfig.mergeFlags(defaultFlags, options.flags);
64 +}
65 +
66 +ConnectionConfig.mergeFlags = function mergeFlags(defaultFlags, userFlags) {
67 + var allFlags = ConnectionConfig.parseFlagList(defaultFlags);
68 + var newFlags = ConnectionConfig.parseFlagList(userFlags);
69 +
70 + // Merge the new flags
71 + for (var flag in newFlags) {
72 + if (allFlags[flag] !== false) {
73 + allFlags[flag] = newFlags[flag];
74 + }
75 + }
76 +
77 + // Build flags
78 + var flags = 0x0;
79 + for (var flag in allFlags) {
80 + if (allFlags[flag]) {
81 + // TODO: Throw here on some future release
82 + flags |= ClientConstants['CLIENT_' + flag] || 0x0;
83 + }
84 + }
85 +
86 + return flags;
87 +};
88 +
89 +ConnectionConfig.getCharsetNumber = function getCharsetNumber(charset) {
90 + var num = Charsets[charset.toUpperCase()];
91 +
92 + if (num === undefined) {
93 + throw new TypeError('Unknown charset \'' + charset + '\'');
94 + }
95 +
96 + return num;
97 +};
98 +
99 +ConnectionConfig.getDefaultFlags = function getDefaultFlags(options) {
100 + var defaultFlags = [
101 + '-COMPRESS', // Compression protocol *NOT* supported
102 + '-CONNECT_ATTRS', // Does *NOT* send connection attributes in Protocol::HandshakeResponse41
103 + '+CONNECT_WITH_DB', // One can specify db on connect in Handshake Response Packet
104 + '+FOUND_ROWS', // Send found rows instead of affected rows
105 + '+IGNORE_SIGPIPE', // Don't issue SIGPIPE if network failures
106 + '+IGNORE_SPACE', // Let the parser ignore spaces before '('
107 + '+LOCAL_FILES', // Can use LOAD DATA LOCAL
108 + '+LONG_FLAG', // Longer flags in Protocol::ColumnDefinition320
109 + '+LONG_PASSWORD', // Use the improved version of Old Password Authentication
110 + '+MULTI_RESULTS', // Can handle multiple resultsets for COM_QUERY
111 + '+ODBC', // Special handling of ODBC behaviour
112 + '-PLUGIN_AUTH', // Does *NOT* support auth plugins
113 + '+PROTOCOL_41', // Uses the 4.1 protocol
114 + '+PS_MULTI_RESULTS', // Can handle multiple resultsets for COM_STMT_EXECUTE
115 + '+RESERVED', // Unused
116 + '+SECURE_CONNECTION', // Supports Authentication::Native41
117 + '+TRANSACTIONS' // Expects status flags
118 + ];
119 +
120 + if (options && options.localInfile !== undefined && !options.localInfile) {
121 + // Disable LOCAL modifier for LOAD DATA INFILE
122 + defaultFlags.push('-LOCAL_FILES');
123 + }
124 +
125 + if (options && options.multipleStatements) {
126 + // May send multiple statements per COM_QUERY and COM_STMT_PREPARE
127 + defaultFlags.push('+MULTI_STATEMENTS');
128 + }
129 +
130 + return defaultFlags;
131 +};
132 +
133 +ConnectionConfig.getSSLProfile = function getSSLProfile(name) {
134 + if (!SSLProfiles) {
135 + SSLProfiles = require('./protocol/constants/ssl_profiles');
136 + }
137 +
138 + var ssl = SSLProfiles[name];
139 +
140 + if (ssl === undefined) {
141 + throw new TypeError('Unknown SSL profile \'' + name + '\'');
142 + }
143 +
144 + return ssl;
145 +};
146 +
147 +ConnectionConfig.parseFlagList = function parseFlagList(flagList) {
148 + var allFlags = Object.create(null);
149 +
150 + if (!flagList) {
151 + return allFlags;
152 + }
153 +
154 + var flags = !Array.isArray(flagList)
155 + ? String(flagList || '').toUpperCase().split(/\s*,+\s*/)
156 + : flagList;
157 +
158 + for (var i = 0; i < flags.length; i++) {
159 + var flag = flags[i];
160 + var offset = 1;
161 + var state = flag[0];
162 +
163 + if (state === undefined) {
164 + // TODO: throw here on some future release
165 + continue;
166 + }
167 +
168 + if (state !== '-' && state !== '+') {
169 + offset = 0;
170 + state = '+';
171 + }
172 +
173 + allFlags[flag.substr(offset)] = state === '+';
174 + }
175 +
176 + return allFlags;
177 +};
178 +
179 +ConnectionConfig.parseUrl = function(url) {
180 + url = urlParse(url, true);
181 +
182 + var options = {
183 + host : url.hostname,
184 + port : url.port,
185 + database : url.pathname.substr(1)
186 + };
187 +
188 + if (url.auth) {
189 + var auth = url.auth.split(':');
190 + options.user = auth.shift();
191 + options.password = auth.join(':');
192 + }
193 +
194 + if (url.query) {
195 + for (var key in url.query) {
196 + var value = url.query[key];
197 +
198 + try {
199 + // Try to parse this as a JSON expression first
200 + options[key] = JSON.parse(value);
201 + } catch (err) {
202 + // Otherwise assume it is a plain string
203 + options[key] = value;
204 + }
205 + }
206 + }
207 +
208 + return options;
209 +};
1 +var mysql = require('../');
2 +var Connection = require('./Connection');
3 +var EventEmitter = require('events').EventEmitter;
4 +var Util = require('util');
5 +var PoolConnection = require('./PoolConnection');
6 +
7 +module.exports = Pool;
8 +
9 +Util.inherits(Pool, EventEmitter);
10 +function Pool(options) {
11 + EventEmitter.call(this);
12 + this.config = options.config;
13 + this.config.connectionConfig.pool = this;
14 +
15 + this._acquiringConnections = [];
16 + this._allConnections = [];
17 + this._freeConnections = [];
18 + this._connectionQueue = [];
19 + this._closed = false;
20 +}
21 +
22 +Pool.prototype.getConnection = function (cb) {
23 +
24 + if (this._closed) {
25 + var err = new Error('Pool is closed.');
26 + err.code = 'POOL_CLOSED';
27 + process.nextTick(function () {
28 + cb(err);
29 + });
30 + return;
31 + }
32 +
33 + var connection;
34 + var pool = this;
35 +
36 + if (this._freeConnections.length > 0) {
37 + connection = this._freeConnections.shift();
38 + this.acquireConnection(connection, cb);
39 + return;
40 + }
41 +
42 + if (this.config.connectionLimit === 0 || this._allConnections.length < this.config.connectionLimit) {
43 + connection = new PoolConnection(this, { config: this.config.newConnectionConfig() });
44 +
45 + this._acquiringConnections.push(connection);
46 + this._allConnections.push(connection);
47 +
48 + connection.connect({timeout: this.config.acquireTimeout}, function onConnect(err) {
49 + spliceConnection(pool._acquiringConnections, connection);
50 +
51 + if (pool._closed) {
52 + err = new Error('Pool is closed.');
53 + err.code = 'POOL_CLOSED';
54 + }
55 +
56 + if (err) {
57 + pool._purgeConnection(connection);
58 + cb(err);
59 + return;
60 + }
61 +
62 + pool.emit('connection', connection);
63 + pool.emit('acquire', connection);
64 + cb(null, connection);
65 + });
66 + return;
67 + }
68 +
69 + if (!this.config.waitForConnections) {
70 + process.nextTick(function(){
71 + var err = new Error('No connections available.');
72 + err.code = 'POOL_CONNLIMIT';
73 + cb(err);
74 + });
75 + return;
76 + }
77 +
78 + this._enqueueCallback(cb);
79 +};
80 +
81 +Pool.prototype.acquireConnection = function acquireConnection(connection, cb) {
82 + if (connection._pool !== this) {
83 + throw new Error('Connection acquired from wrong pool.');
84 + }
85 +
86 + var changeUser = this._needsChangeUser(connection);
87 + var pool = this;
88 +
89 + this._acquiringConnections.push(connection);
90 +
91 + function onOperationComplete(err) {
92 + spliceConnection(pool._acquiringConnections, connection);
93 +
94 + if (pool._closed) {
95 + err = new Error('Pool is closed.');
96 + err.code = 'POOL_CLOSED';
97 + }
98 +
99 + if (err) {
100 + pool._connectionQueue.unshift(cb);
101 + pool._purgeConnection(connection);
102 + return;
103 + }
104 +
105 + if (changeUser) {
106 + pool.emit('connection', connection);
107 + }
108 +
109 + pool.emit('acquire', connection);
110 + cb(null, connection);
111 + }
112 +
113 + if (changeUser) {
114 + // restore user back to pool configuration
115 + connection.config = this.config.newConnectionConfig();
116 + connection.changeUser({timeout: this.config.acquireTimeout}, onOperationComplete);
117 + } else {
118 + // ping connection
119 + connection.ping({timeout: this.config.acquireTimeout}, onOperationComplete);
120 + }
121 +};
122 +
123 +Pool.prototype.releaseConnection = function releaseConnection(connection) {
124 +
125 + if (this._acquiringConnections.indexOf(connection) !== -1) {
126 + // connection is being acquired
127 + return;
128 + }
129 +
130 + if (connection._pool) {
131 + if (connection._pool !== this) {
132 + throw new Error('Connection released to wrong pool');
133 + }
134 +
135 + if (this._freeConnections.indexOf(connection) !== -1) {
136 + // connection already in free connection pool
137 + // this won't catch all double-release cases
138 + throw new Error('Connection already released');
139 + } else {
140 + // add connection to end of free queue
141 + this._freeConnections.push(connection);
142 + this.emit('release', connection);
143 + }
144 + }
145 +
146 + if (this._closed) {
147 + // empty the connection queue
148 + this._connectionQueue.splice(0).forEach(function (cb) {
149 + var err = new Error('Pool is closed.');
150 + err.code = 'POOL_CLOSED';
151 + process.nextTick(function () {
152 + cb(err);
153 + });
154 + });
155 + } else if (this._connectionQueue.length) {
156 + // get connection with next waiting callback
157 + this.getConnection(this._connectionQueue.shift());
158 + }
159 +};
160 +
161 +Pool.prototype.end = function (cb) {
162 + this._closed = true;
163 +
164 + if (typeof cb !== 'function') {
165 + cb = function (err) {
166 + if (err) throw err;
167 + };
168 + }
169 +
170 + var calledBack = false;
171 + var waitingClose = 0;
172 +
173 + function onEnd(err) {
174 + if (!calledBack && (err || --waitingClose <= 0)) {
175 + calledBack = true;
176 + cb(err);
177 + }
178 + }
179 +
180 + while (this._allConnections.length !== 0) {
181 + waitingClose++;
182 + this._purgeConnection(this._allConnections[0], onEnd);
183 + }
184 +
185 + if (waitingClose === 0) {
186 + process.nextTick(onEnd);
187 + }
188 +};
189 +
190 +Pool.prototype.query = function (sql, values, cb) {
191 + var query = Connection.createQuery(sql, values, cb);
192 +
193 + if (!(typeof sql === 'object' && 'typeCast' in sql)) {
194 + query.typeCast = this.config.connectionConfig.typeCast;
195 + }
196 +
197 + if (this.config.connectionConfig.trace) {
198 + // Long stack trace support
199 + query._callSite = new Error();
200 + }
201 +
202 + this.getConnection(function (err, conn) {
203 + if (err) {
204 + query.on('error', function () {});
205 + query.end(err);
206 + return;
207 + }
208 +
209 + // Release connection based off event
210 + query.once('end', function() {
211 + conn.release();
212 + });
213 +
214 + conn.query(query);
215 + });
216 +
217 + return query;
218 +};
219 +
220 +Pool.prototype._enqueueCallback = function _enqueueCallback(callback) {
221 +
222 + if (this.config.queueLimit && this._connectionQueue.length >= this.config.queueLimit) {
223 + process.nextTick(function () {
224 + var err = new Error('Queue limit reached.');
225 + err.code = 'POOL_ENQUEUELIMIT';
226 + callback(err);
227 + });
228 + return;
229 + }
230 +
231 + // Bind to domain, as dequeue will likely occur in a different domain
232 + var cb = process.domain
233 + ? process.domain.bind(callback)
234 + : callback;
235 +
236 + this._connectionQueue.push(cb);
237 + this.emit('enqueue');
238 +};
239 +
240 +Pool.prototype._needsChangeUser = function _needsChangeUser(connection) {
241 + var connConfig = connection.config;
242 + var poolConfig = this.config.connectionConfig;
243 +
244 + // check if changeUser values are different
245 + return connConfig.user !== poolConfig.user
246 + || connConfig.database !== poolConfig.database
247 + || connConfig.password !== poolConfig.password
248 + || connConfig.charsetNumber !== poolConfig.charsetNumber;
249 +};
250 +
251 +Pool.prototype._purgeConnection = function _purgeConnection(connection, callback) {
252 + var cb = callback || function () {};
253 +
254 + if (connection.state === 'disconnected') {
255 + connection.destroy();
256 + }
257 +
258 + this._removeConnection(connection);
259 +
260 + if (connection.state !== 'disconnected' && !connection._protocol._quitSequence) {
261 + connection._realEnd(cb);
262 + return;
263 + }
264 +
265 + process.nextTick(cb);
266 +};
267 +
268 +Pool.prototype._removeConnection = function(connection) {
269 + connection._pool = null;
270 +
271 + // Remove connection from all connections
272 + spliceConnection(this._allConnections, connection);
273 +
274 + // Remove connection from free connections
275 + spliceConnection(this._freeConnections, connection);
276 +
277 + this.releaseConnection(connection);
278 +};
279 +
280 +Pool.prototype.escape = function(value) {
281 + return mysql.escape(value, this.config.connectionConfig.stringifyObjects, this.config.connectionConfig.timezone);
282 +};
283 +
284 +Pool.prototype.escapeId = function escapeId(value) {
285 + return mysql.escapeId(value, false);
286 +};
287 +
288 +function spliceConnection(array, connection) {
289 + var index;
290 + if ((index = array.indexOf(connection)) !== -1) {
291 + // Remove connection from all connections
292 + array.splice(index, 1);
293 + }
294 +}
1 +var Pool = require('./Pool');
2 +var PoolConfig = require('./PoolConfig');
3 +var PoolNamespace = require('./PoolNamespace');
4 +var PoolSelector = require('./PoolSelector');
5 +var Util = require('util');
6 +var EventEmitter = require('events').EventEmitter;
7 +
8 +module.exports = PoolCluster;
9 +
10 +/**
11 + * PoolCluster
12 + * @constructor
13 + * @param {object} [config] The pool cluster configuration
14 + * @public
15 + */
16 +function PoolCluster(config) {
17 + EventEmitter.call(this);
18 +
19 + config = config || {};
20 + this._canRetry = typeof config.canRetry === 'undefined' ? true : config.canRetry;
21 + this._defaultSelector = config.defaultSelector || 'RR';
22 + this._removeNodeErrorCount = config.removeNodeErrorCount || 5;
23 + this._restoreNodeTimeout = config.restoreNodeTimeout || 0;
24 +
25 + this._closed = false;
26 + this._findCaches = Object.create(null);
27 + this._lastId = 0;
28 + this._namespaces = Object.create(null);
29 + this._nodes = Object.create(null);
30 +}
31 +
32 +Util.inherits(PoolCluster, EventEmitter);
33 +
34 +PoolCluster.prototype.add = function add(id, config) {
35 + if (this._closed) {
36 + throw new Error('PoolCluster is closed.');
37 + }
38 +
39 + var nodeId = typeof id === 'object'
40 + ? 'CLUSTER::' + (++this._lastId)
41 + : String(id);
42 +
43 + if (this._nodes[nodeId] !== undefined) {
44 + throw new Error('Node ID "' + nodeId + '" is already defined in PoolCluster.');
45 + }
46 +
47 + var poolConfig = typeof id !== 'object'
48 + ? new PoolConfig(config)
49 + : new PoolConfig(id);
50 +
51 + this._nodes[nodeId] = {
52 + id : nodeId,
53 + errorCount : 0,
54 + pool : new Pool({config: poolConfig}),
55 + _offlineUntil : 0
56 + };
57 +
58 + this._clearFindCaches();
59 +};
60 +
61 +PoolCluster.prototype.end = function end(callback) {
62 + var cb = callback !== undefined
63 + ? callback
64 + : _cb;
65 +
66 + if (typeof cb !== 'function') {
67 + throw TypeError('callback argument must be a function');
68 + }
69 +
70 + if (this._closed) {
71 + process.nextTick(cb);
72 + return;
73 + }
74 +
75 + this._closed = true;
76 +
77 + var calledBack = false;
78 + var nodeIds = Object.keys(this._nodes);
79 + var waitingClose = 0;
80 +
81 + function onEnd(err) {
82 + if (!calledBack && (err || --waitingClose <= 0)) {
83 + calledBack = true;
84 + cb(err);
85 + }
86 + }
87 +
88 + for (var i = 0; i < nodeIds.length; i++) {
89 + var nodeId = nodeIds[i];
90 + var node = this._nodes[nodeId];
91 +
92 + waitingClose++;
93 + node.pool.end(onEnd);
94 + }
95 +
96 + if (waitingClose === 0) {
97 + process.nextTick(onEnd);
98 + }
99 +};
100 +
101 +PoolCluster.prototype.of = function(pattern, selector) {
102 + pattern = pattern || '*';
103 +
104 + selector = selector || this._defaultSelector;
105 + selector = selector.toUpperCase();
106 + if (typeof PoolSelector[selector] === 'undefined') {
107 + selector = this._defaultSelector;
108 + }
109 +
110 + var key = pattern + selector;
111 +
112 + if (typeof this._namespaces[key] === 'undefined') {
113 + this._namespaces[key] = new PoolNamespace(this, pattern, selector);
114 + }
115 +
116 + return this._namespaces[key];
117 +};
118 +
119 +PoolCluster.prototype.remove = function remove(pattern) {
120 + var foundNodeIds = this._findNodeIds(pattern, true);
121 +
122 + for (var i = 0; i < foundNodeIds.length; i++) {
123 + var node = this._getNode(foundNodeIds[i]);
124 +
125 + if (node) {
126 + this._removeNode(node);
127 + }
128 + }
129 +};
130 +
131 +PoolCluster.prototype.getConnection = function(pattern, selector, cb) {
132 + var namespace;
133 + if (typeof pattern === 'function') {
134 + cb = pattern;
135 + namespace = this.of();
136 + } else {
137 + if (typeof selector === 'function') {
138 + cb = selector;
139 + selector = this._defaultSelector;
140 + }
141 +
142 + namespace = this.of(pattern, selector);
143 + }
144 +
145 + namespace.getConnection(cb);
146 +};
147 +
148 +PoolCluster.prototype._clearFindCaches = function _clearFindCaches() {
149 + this._findCaches = Object.create(null);
150 +};
151 +
152 +PoolCluster.prototype._decreaseErrorCount = function _decreaseErrorCount(node) {
153 + var errorCount = node.errorCount;
154 +
155 + if (errorCount > this._removeNodeErrorCount) {
156 + errorCount = this._removeNodeErrorCount;
157 + }
158 +
159 + if (errorCount < 1) {
160 + errorCount = 1;
161 + }
162 +
163 + node.errorCount = errorCount - 1;
164 +
165 + if (node._offlineUntil) {
166 + node._offlineUntil = 0;
167 + this.emit('online', node.id);
168 + }
169 +};
170 +
171 +PoolCluster.prototype._findNodeIds = function _findNodeIds(pattern, includeOffline) {
172 + var currentTime = 0;
173 + var foundNodeIds = this._findCaches[pattern];
174 +
175 + if (foundNodeIds === undefined) {
176 + var expression = patternRegExp(pattern);
177 + var nodeIds = Object.keys(this._nodes);
178 +
179 + foundNodeIds = nodeIds.filter(function (id) {
180 + return id.match(expression);
181 + });
182 +
183 + this._findCaches[pattern] = foundNodeIds;
184 + }
185 +
186 + if (includeOffline) {
187 + return foundNodeIds;
188 + }
189 +
190 + return foundNodeIds.filter(function (nodeId) {
191 + var node = this._getNode(nodeId);
192 +
193 + if (!node._offlineUntil) {
194 + return true;
195 + }
196 +
197 + if (!currentTime) {
198 + currentTime = getMonotonicMilliseconds();
199 + }
200 +
201 + return node._offlineUntil <= currentTime;
202 + }, this);
203 +};
204 +
205 +PoolCluster.prototype._getNode = function _getNode(id) {
206 + return this._nodes[id] || null;
207 +};
208 +
209 +PoolCluster.prototype._increaseErrorCount = function _increaseErrorCount(node) {
210 + var errorCount = ++node.errorCount;
211 +
212 + if (this._removeNodeErrorCount > errorCount) {
213 + return;
214 + }
215 +
216 + if (this._restoreNodeTimeout > 0) {
217 + node._offlineUntil = getMonotonicMilliseconds() + this._restoreNodeTimeout;
218 + this.emit('offline', node.id);
219 + return;
220 + }
221 +
222 + this._removeNode(node);
223 + this.emit('remove', node.id);
224 +};
225 +
226 +PoolCluster.prototype._getConnection = function(node, cb) {
227 + var self = this;
228 +
229 + node.pool.getConnection(function (err, connection) {
230 + if (err) {
231 + self._increaseErrorCount(node);
232 + cb(err);
233 + return;
234 + } else {
235 + self._decreaseErrorCount(node);
236 + }
237 +
238 + connection._clusterId = node.id;
239 +
240 + cb(null, connection);
241 + });
242 +};
243 +
244 +PoolCluster.prototype._removeNode = function _removeNode(node) {
245 + delete this._nodes[node.id];
246 +
247 + this._clearFindCaches();
248 +
249 + node.pool.end(_noop);
250 +};
251 +
252 +function getMonotonicMilliseconds() {
253 + var ms;
254 +
255 + if (typeof process.hrtime === 'function') {
256 + ms = process.hrtime();
257 + ms = ms[0] * 1e3 + ms[1] * 1e-6;
258 + } else {
259 + ms = process.uptime() * 1000;
260 + }
261 +
262 + return Math.floor(ms);
263 +}
264 +
265 +function isRegExp(val) {
266 + return typeof val === 'object'
267 + && Object.prototype.toString.call(val) === '[object RegExp]';
268 +}
269 +
270 +function patternRegExp(pattern) {
271 + if (isRegExp(pattern)) {
272 + return pattern;
273 + }
274 +
275 + var source = pattern
276 + .replace(/([.+?^=!:${}()|\[\]\/\\])/g, '\\$1')
277 + .replace(/\*/g, '.*');
278 +
279 + return new RegExp('^' + source + '$');
280 +}
281 +
282 +function _cb(err) {
283 + if (err) {
284 + throw err;
285 + }
286 +}
287 +
288 +function _noop() {}
1 +
2 +var ConnectionConfig = require('./ConnectionConfig');
3 +
4 +module.exports = PoolConfig;
5 +function PoolConfig(options) {
6 + if (typeof options === 'string') {
7 + options = ConnectionConfig.parseUrl(options);
8 + }
9 +
10 + this.acquireTimeout = (options.acquireTimeout === undefined)
11 + ? 10 * 1000
12 + : Number(options.acquireTimeout);
13 + this.connectionConfig = new ConnectionConfig(options);
14 + this.waitForConnections = (options.waitForConnections === undefined)
15 + ? true
16 + : Boolean(options.waitForConnections);
17 + this.connectionLimit = (options.connectionLimit === undefined)
18 + ? 10
19 + : Number(options.connectionLimit);
20 + this.queueLimit = (options.queueLimit === undefined)
21 + ? 0
22 + : Number(options.queueLimit);
23 +}
24 +
25 +PoolConfig.prototype.newConnectionConfig = function newConnectionConfig() {
26 + var connectionConfig = new ConnectionConfig(this.connectionConfig);
27 +
28 + connectionConfig.clientFlags = this.connectionConfig.clientFlags;
29 + connectionConfig.maxPacketSize = this.connectionConfig.maxPacketSize;
30 +
31 + return connectionConfig;
32 +};
1 +var inherits = require('util').inherits;
2 +var Connection = require('./Connection');
3 +var Events = require('events');
4 +
5 +module.exports = PoolConnection;
6 +inherits(PoolConnection, Connection);
7 +
8 +function PoolConnection(pool, options) {
9 + Connection.call(this, options);
10 + this._pool = pool;
11 +
12 + // Bind connection to pool domain
13 + if (Events.usingDomains) {
14 + this.domain = pool.domain;
15 + }
16 +
17 + // When a fatal error occurs the connection's protocol ends, which will cause
18 + // the connection to end as well, thus we only need to watch for the end event
19 + // and we will be notified of disconnects.
20 + this.on('end', this._removeFromPool);
21 + this.on('error', function (err) {
22 + if (err.fatal) {
23 + this._removeFromPool();
24 + }
25 + });
26 +}
27 +
28 +PoolConnection.prototype.release = function release() {
29 + var pool = this._pool;
30 +
31 + if (!pool || pool._closed) {
32 + return undefined;
33 + }
34 +
35 + return pool.releaseConnection(this);
36 +};
37 +
38 +// TODO: Remove this when we are removing PoolConnection#end
39 +PoolConnection.prototype._realEnd = Connection.prototype.end;
40 +
41 +PoolConnection.prototype.end = function () {
42 + console.warn(
43 + 'Calling conn.end() to release a pooled connection is ' +
44 + 'deprecated. In next version calling conn.end() will be ' +
45 + 'restored to default conn.end() behavior. Use ' +
46 + 'conn.release() instead.'
47 + );
48 + this.release();
49 +};
50 +
51 +PoolConnection.prototype.destroy = function () {
52 + Connection.prototype.destroy.apply(this, arguments);
53 + this._removeFromPool(this);
54 +};
55 +
56 +PoolConnection.prototype._removeFromPool = function _removeFromPool() {
57 + if (!this._pool || this._pool._closed) {
58 + return;
59 + }
60 +
61 + var pool = this._pool;
62 + this._pool = null;
63 +
64 + pool._purgeConnection(this);
65 +};
1 +var Connection = require('./Connection');
2 +var PoolSelector = require('./PoolSelector');
3 +
4 +module.exports = PoolNamespace;
5 +
6 +/**
7 + * PoolNamespace
8 + * @constructor
9 + * @param {PoolCluster} cluster The parent cluster for the namespace
10 + * @param {string} pattern The selection pattern to use
11 + * @param {string} selector The selector name to use
12 + * @public
13 + */
14 +function PoolNamespace(cluster, pattern, selector) {
15 + this._cluster = cluster;
16 + this._pattern = pattern;
17 + this._selector = new PoolSelector[selector]();
18 +}
19 +
20 +PoolNamespace.prototype.getConnection = function(cb) {
21 + var clusterNode = this._getClusterNode();
22 + var cluster = this._cluster;
23 + var namespace = this;
24 +
25 + if (clusterNode === null) {
26 + var err = null;
27 +
28 + if (this._cluster._findNodeIds(this._pattern, true).length !== 0) {
29 + err = new Error('Pool does not have online node.');
30 + err.code = 'POOL_NONEONLINE';
31 + } else {
32 + err = new Error('Pool does not exist.');
33 + err.code = 'POOL_NOEXIST';
34 + }
35 +
36 + cb(err);
37 + return;
38 + }
39 +
40 + cluster._getConnection(clusterNode, function(err, connection) {
41 + var retry = err && cluster._canRetry
42 + && cluster._findNodeIds(namespace._pattern).length !== 0;
43 +
44 + if (retry) {
45 + namespace.getConnection(cb);
46 + return;
47 + }
48 +
49 + if (err) {
50 + cb(err);
51 + return;
52 + }
53 +
54 + cb(null, connection);
55 + });
56 +};
57 +
58 +PoolNamespace.prototype.query = function (sql, values, cb) {
59 + var cluster = this._cluster;
60 + var clusterNode = this._getClusterNode();
61 + var query = Connection.createQuery(sql, values, cb);
62 + var namespace = this;
63 +
64 + if (clusterNode === null) {
65 + var err = null;
66 +
67 + if (this._cluster._findNodeIds(this._pattern, true).length !== 0) {
68 + err = new Error('Pool does not have online node.');
69 + err.code = 'POOL_NONEONLINE';
70 + } else {
71 + err = new Error('Pool does not exist.');
72 + err.code = 'POOL_NOEXIST';
73 + }
74 +
75 + process.nextTick(function () {
76 + query.on('error', function () {});
77 + query.end(err);
78 + });
79 + return query;
80 + }
81 +
82 + if (!(typeof sql === 'object' && 'typeCast' in sql)) {
83 + query.typeCast = clusterNode.pool.config.connectionConfig.typeCast;
84 + }
85 +
86 + if (clusterNode.pool.config.connectionConfig.trace) {
87 + // Long stack trace support
88 + query._callSite = new Error();
89 + }
90 +
91 + cluster._getConnection(clusterNode, function (err, conn) {
92 + var retry = err && cluster._canRetry
93 + && cluster._findNodeIds(namespace._pattern).length !== 0;
94 +
95 + if (retry) {
96 + namespace.query(query);
97 + return;
98 + }
99 +
100 + if (err) {
101 + query.on('error', function () {});
102 + query.end(err);
103 + return;
104 + }
105 +
106 + // Release connection based off event
107 + query.once('end', function() {
108 + conn.release();
109 + });
110 +
111 + conn.query(query);
112 + });
113 +
114 + return query;
115 +};
116 +
117 +PoolNamespace.prototype._getClusterNode = function _getClusterNode() {
118 + var foundNodeIds = this._cluster._findNodeIds(this._pattern);
119 + var nodeId;
120 +
121 + switch (foundNodeIds.length) {
122 + case 0:
123 + nodeId = null;
124 + break;
125 + case 1:
126 + nodeId = foundNodeIds[0];
127 + break;
128 + default:
129 + nodeId = this._selector(foundNodeIds);
130 + break;
131 + }
132 +
133 + return nodeId !== null
134 + ? this._cluster._getNode(nodeId)
135 + : null;
136 +};
1 +
2 +/**
3 + * PoolSelector
4 + */
5 +var PoolSelector = module.exports = {};
6 +
7 +PoolSelector.RR = function PoolSelectorRoundRobin() {
8 + var index = 0;
9 +
10 + return function(clusterIds) {
11 + if (index >= clusterIds.length) {
12 + index = 0;
13 + }
14 +
15 + var clusterId = clusterIds[index++];
16 +
17 + return clusterId;
18 + };
19 +};
20 +
21 +PoolSelector.RANDOM = function PoolSelectorRandom() {
22 + return function(clusterIds) {
23 + return clusterIds[Math.floor(Math.random() * clusterIds.length)];
24 + };
25 +};
26 +
27 +PoolSelector.ORDER = function PoolSelectorOrder() {
28 + return function(clusterIds) {
29 + return clusterIds[0];
30 + };
31 +};
1 +var Buffer = require('safe-buffer').Buffer;
2 +var Crypto = require('crypto');
3 +var Auth = exports;
4 +
5 +function auth(name, data, options) {
6 + options = options || {};
7 +
8 + switch (name) {
9 + case 'mysql_native_password':
10 + return Auth.token(options.password, data.slice(0, 20));
11 + default:
12 + return undefined;
13 + }
14 +}
15 +Auth.auth = auth;
16 +
17 +function sha1(msg) {
18 + var hash = Crypto.createHash('sha1');
19 + hash.update(msg, 'binary');
20 + return hash.digest('binary');
21 +}
22 +Auth.sha1 = sha1;
23 +
24 +function xor(a, b) {
25 + a = Buffer.from(a, 'binary');
26 + b = Buffer.from(b, 'binary');
27 + var result = Buffer.allocUnsafe(a.length);
28 + for (var i = 0; i < a.length; i++) {
29 + result[i] = (a[i] ^ b[i]);
30 + }
31 + return result;
32 +}
33 +Auth.xor = xor;
34 +
35 +Auth.token = function(password, scramble) {
36 + if (!password) {
37 + return Buffer.alloc(0);
38 + }
39 +
40 + // password must be in binary format, not utf8
41 + var stage1 = sha1((Buffer.from(password, 'utf8')).toString('binary'));
42 + var stage2 = sha1(stage1);
43 + var stage3 = sha1(scramble.toString('binary') + stage2);
44 + return xor(stage3, stage1);
45 +};
46 +
47 +// This is a port of sql/password.c:hash_password which needs to be used for
48 +// pre-4.1 passwords.
49 +Auth.hashPassword = function(password) {
50 + var nr = [0x5030, 0x5735];
51 + var add = 7;
52 + var nr2 = [0x1234, 0x5671];
53 + var result = Buffer.alloc(8);
54 +
55 + if (typeof password === 'string'){
56 + password = Buffer.from(password);
57 + }
58 +
59 + for (var i = 0; i < password.length; i++) {
60 + var c = password[i];
61 + if (c === 32 || c === 9) {
62 + // skip space in password
63 + continue;
64 + }
65 +
66 + // nr^= (((nr & 63)+add)*c)+ (nr << 8);
67 + // nr = xor(nr, add(mul(add(and(nr, 63), add), c), shl(nr, 8)))
68 + nr = this.xor32(nr, this.add32(this.mul32(this.add32(this.and32(nr, [0, 63]), [0, add]), [0, c]), this.shl32(nr, 8)));
69 +
70 + // nr2+=(nr2 << 8) ^ nr;
71 + // nr2 = add(nr2, xor(shl(nr2, 8), nr))
72 + nr2 = this.add32(nr2, this.xor32(this.shl32(nr2, 8), nr));
73 +
74 + // add+=tmp;
75 + add += c;
76 + }
77 +
78 + this.int31Write(result, nr, 0);
79 + this.int31Write(result, nr2, 4);
80 +
81 + return result;
82 +};
83 +
84 +Auth.randomInit = function(seed1, seed2) {
85 + return {
86 + max_value : 0x3FFFFFFF,
87 + max_value_dbl : 0x3FFFFFFF,
88 + seed1 : seed1 % 0x3FFFFFFF,
89 + seed2 : seed2 % 0x3FFFFFFF
90 + };
91 +};
92 +
93 +Auth.myRnd = function(r){
94 + r.seed1 = (r.seed1 * 3 + r.seed2) % r.max_value;
95 + r.seed2 = (r.seed1 + r.seed2 + 33) % r.max_value;
96 +
97 + return r.seed1 / r.max_value_dbl;
98 +};
99 +
100 +Auth.scramble323 = function(message, password) {
101 + if (!password) {
102 + return Buffer.alloc(0);
103 + }
104 +
105 + var to = Buffer.allocUnsafe(8);
106 + var hashPass = this.hashPassword(password);
107 + var hashMessage = this.hashPassword(message.slice(0, 8));
108 + var seed1 = this.int32Read(hashPass, 0) ^ this.int32Read(hashMessage, 0);
109 + var seed2 = this.int32Read(hashPass, 4) ^ this.int32Read(hashMessage, 4);
110 + var r = this.randomInit(seed1, seed2);
111 +
112 + for (var i = 0; i < 8; i++){
113 + to[i] = Math.floor(this.myRnd(r) * 31) + 64;
114 + }
115 + var extra = (Math.floor(this.myRnd(r) * 31));
116 +
117 + for (var i = 0; i < 8; i++){
118 + to[i] ^= extra;
119 + }
120 +
121 + return to;
122 +};
123 +
124 +Auth.xor32 = function(a, b){
125 + return [a[0] ^ b[0], a[1] ^ b[1]];
126 +};
127 +
128 +Auth.add32 = function(a, b){
129 + var w1 = a[1] + b[1];
130 + var w2 = a[0] + b[0] + ((w1 & 0xFFFF0000) >> 16);
131 +
132 + return [w2 & 0xFFFF, w1 & 0xFFFF];
133 +};
134 +
135 +Auth.mul32 = function(a, b){
136 + // based on this example of multiplying 32b ints using 16b
137 + // http://www.dsprelated.com/showmessage/89790/1.php
138 + var w1 = a[1] * b[1];
139 + var w2 = (((a[1] * b[1]) >> 16) & 0xFFFF) + ((a[0] * b[1]) & 0xFFFF) + (a[1] * b[0] & 0xFFFF);
140 +
141 + return [w2 & 0xFFFF, w1 & 0xFFFF];
142 +};
143 +
144 +Auth.and32 = function(a, b){
145 + return [a[0] & b[0], a[1] & b[1]];
146 +};
147 +
148 +Auth.shl32 = function(a, b){
149 + // assume b is 16 or less
150 + var w1 = a[1] << b;
151 + var w2 = (a[0] << b) | ((w1 & 0xFFFF0000) >> 16);
152 +
153 + return [w2 & 0xFFFF, w1 & 0xFFFF];
154 +};
155 +
156 +Auth.int31Write = function(buffer, number, offset) {
157 + buffer[offset] = (number[0] >> 8) & 0x7F;
158 + buffer[offset + 1] = (number[0]) & 0xFF;
159 + buffer[offset + 2] = (number[1] >> 8) & 0xFF;
160 + buffer[offset + 3] = (number[1]) & 0xFF;
161 +};
162 +
163 +Auth.int32Read = function(buffer, offset){
164 + return (buffer[offset] << 24)
165 + + (buffer[offset + 1] << 16)
166 + + (buffer[offset + 2] << 8)
167 + + (buffer[offset + 3]);
168 +};
1 +
2 +module.exports = BufferList;
3 +function BufferList() {
4 + this.bufs = [];
5 + this.size = 0;
6 +}
7 +
8 +BufferList.prototype.shift = function shift() {
9 + var buf = this.bufs.shift();
10 +
11 + if (buf) {
12 + this.size -= buf.length;
13 + }
14 +
15 + return buf;
16 +};
17 +
18 +BufferList.prototype.push = function push(buf) {
19 + if (!buf || !buf.length) {
20 + return;
21 + }
22 +
23 + this.bufs.push(buf);
24 + this.size += buf.length;
25 +};
1 +module.exports = PacketHeader;
2 +function PacketHeader(length, number) {
3 + this.length = length;
4 + this.number = number;
5 +}
1 +var BIT_16 = Math.pow(2, 16);
2 +var BIT_24 = Math.pow(2, 24);
3 +var BUFFER_ALLOC_SIZE = Math.pow(2, 8);
4 +// The maximum precision JS Numbers can hold precisely
5 +// Don't panic: Good enough to represent byte values up to 8192 TB
6 +var IEEE_754_BINARY_64_PRECISION = Math.pow(2, 53);
7 +var MAX_PACKET_LENGTH = Math.pow(2, 24) - 1;
8 +var Buffer = require('safe-buffer').Buffer;
9 +
10 +module.exports = PacketWriter;
11 +function PacketWriter() {
12 + this._buffer = null;
13 + this._offset = 0;
14 +}
15 +
16 +PacketWriter.prototype.toBuffer = function toBuffer(parser) {
17 + if (!this._buffer) {
18 + this._buffer = Buffer.alloc(0);
19 + this._offset = 0;
20 + }
21 +
22 + var buffer = this._buffer;
23 + var length = this._offset;
24 + var packets = Math.floor(length / MAX_PACKET_LENGTH) + 1;
25 +
26 + this._buffer = Buffer.allocUnsafe(length + packets * 4);
27 + this._offset = 0;
28 +
29 + for (var packet = 0; packet < packets; packet++) {
30 + var isLast = (packet + 1 === packets);
31 + var packetLength = (isLast)
32 + ? length % MAX_PACKET_LENGTH
33 + : MAX_PACKET_LENGTH;
34 +
35 + var packetNumber = parser.incrementPacketNumber();
36 +
37 + this.writeUnsignedNumber(3, packetLength);
38 + this.writeUnsignedNumber(1, packetNumber);
39 +
40 + var start = packet * MAX_PACKET_LENGTH;
41 + var end = start + packetLength;
42 +
43 + this.writeBuffer(buffer.slice(start, end));
44 + }
45 +
46 + return this._buffer;
47 +};
48 +
49 +PacketWriter.prototype.writeUnsignedNumber = function(bytes, value) {
50 + this._allocate(bytes);
51 +
52 + for (var i = 0; i < bytes; i++) {
53 + this._buffer[this._offset++] = (value >> (i * 8)) & 0xff;
54 + }
55 +};
56 +
57 +PacketWriter.prototype.writeFiller = function(bytes) {
58 + this._allocate(bytes);
59 +
60 + for (var i = 0; i < bytes; i++) {
61 + this._buffer[this._offset++] = 0x00;
62 + }
63 +};
64 +
65 +PacketWriter.prototype.writeNullTerminatedString = function(value, encoding) {
66 + // Typecast undefined into '' and numbers into strings
67 + value = value || '';
68 + value = value + '';
69 +
70 + var bytes = Buffer.byteLength(value, encoding || 'utf-8') + 1;
71 + this._allocate(bytes);
72 +
73 + this._buffer.write(value, this._offset, encoding);
74 + this._buffer[this._offset + bytes - 1] = 0x00;
75 +
76 + this._offset += bytes;
77 +};
78 +
79 +PacketWriter.prototype.writeString = function(value) {
80 + // Typecast undefined into '' and numbers into strings
81 + value = value || '';
82 + value = value + '';
83 +
84 + var bytes = Buffer.byteLength(value, 'utf-8');
85 + this._allocate(bytes);
86 +
87 + this._buffer.write(value, this._offset, 'utf-8');
88 +
89 + this._offset += bytes;
90 +};
91 +
92 +PacketWriter.prototype.writeBuffer = function(value) {
93 + var bytes = value.length;
94 +
95 + this._allocate(bytes);
96 + value.copy(this._buffer, this._offset);
97 + this._offset += bytes;
98 +};
99 +
100 +PacketWriter.prototype.writeLengthCodedNumber = function(value) {
101 + if (value === null) {
102 + this._allocate(1);
103 + this._buffer[this._offset++] = 251;
104 + return;
105 + }
106 +
107 + if (value <= 250) {
108 + this._allocate(1);
109 + this._buffer[this._offset++] = value;
110 + return;
111 + }
112 +
113 + if (value > IEEE_754_BINARY_64_PRECISION) {
114 + throw new Error(
115 + 'writeLengthCodedNumber: JS precision range exceeded, your ' +
116 + 'number is > 53 bit: "' + value + '"'
117 + );
118 + }
119 +
120 + if (value < BIT_16) {
121 + this._allocate(3);
122 + this._buffer[this._offset++] = 252;
123 + } else if (value < BIT_24) {
124 + this._allocate(4);
125 + this._buffer[this._offset++] = 253;
126 + } else {
127 + this._allocate(9);
128 + this._buffer[this._offset++] = 254;
129 + }
130 +
131 + // 16 Bit
132 + this._buffer[this._offset++] = value & 0xff;
133 + this._buffer[this._offset++] = (value >> 8) & 0xff;
134 +
135 + if (value < BIT_16) {
136 + return;
137 + }
138 +
139 + // 24 Bit
140 + this._buffer[this._offset++] = (value >> 16) & 0xff;
141 +
142 + if (value < BIT_24) {
143 + return;
144 + }
145 +
146 + this._buffer[this._offset++] = (value >> 24) & 0xff;
147 +
148 + // Hack: Get the most significant 32 bit (JS bitwise operators are 32 bit)
149 + value = value.toString(2);
150 + value = value.substr(0, value.length - 32);
151 + value = parseInt(value, 2);
152 +
153 + this._buffer[this._offset++] = value & 0xff;
154 + this._buffer[this._offset++] = (value >> 8) & 0xff;
155 + this._buffer[this._offset++] = (value >> 16) & 0xff;
156 +
157 + // Set last byte to 0, as we can only support 53 bits in JS (see above)
158 + this._buffer[this._offset++] = 0;
159 +};
160 +
161 +PacketWriter.prototype.writeLengthCodedBuffer = function(value) {
162 + var bytes = value.length;
163 + this.writeLengthCodedNumber(bytes);
164 + this.writeBuffer(value);
165 +};
166 +
167 +PacketWriter.prototype.writeNullTerminatedBuffer = function(value) {
168 + this.writeBuffer(value);
169 + this.writeFiller(1); // 0x00 terminator
170 +};
171 +
172 +PacketWriter.prototype.writeLengthCodedString = function(value) {
173 + if (value === null) {
174 + this.writeLengthCodedNumber(null);
175 + return;
176 + }
177 +
178 + value = (value === undefined)
179 + ? ''
180 + : String(value);
181 +
182 + var bytes = Buffer.byteLength(value, 'utf-8');
183 + this.writeLengthCodedNumber(bytes);
184 +
185 + if (!bytes) {
186 + return;
187 + }
188 +
189 + this._allocate(bytes);
190 + this._buffer.write(value, this._offset, 'utf-8');
191 + this._offset += bytes;
192 +};
193 +
194 +PacketWriter.prototype._allocate = function _allocate(bytes) {
195 + if (!this._buffer) {
196 + this._buffer = Buffer.alloc(Math.max(BUFFER_ALLOC_SIZE, bytes));
197 + this._offset = 0;
198 + return;
199 + }
200 +
201 + var bytesRemaining = this._buffer.length - this._offset;
202 + if (bytesRemaining >= bytes) {
203 + return;
204 + }
205 +
206 + var newSize = this._buffer.length + Math.max(BUFFER_ALLOC_SIZE, bytes);
207 + var oldBuffer = this._buffer;
208 +
209 + this._buffer = Buffer.alloc(newSize);
210 + oldBuffer.copy(this._buffer);
211 +};
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
1 +module.exports = ResultSet;
2 +function ResultSet(resultSetHeaderPacket) {
3 + this.resultSetHeaderPacket = resultSetHeaderPacket;
4 + this.fieldPackets = [];
5 + this.eofPackets = [];
6 + this.rows = [];
7 +}
1 +module.exports = require('sqlstring');
1 +var Timers = require('timers');
2 +
3 +module.exports = Timer;
4 +function Timer(object) {
5 + this._object = object;
6 + this._timeout = null;
7 +}
8 +
9 +Timer.prototype.active = function active() {
10 + if (this._timeout) {
11 + if (this._timeout.refresh) {
12 + this._timeout.refresh();
13 + } else {
14 + Timers.active(this._timeout);
15 + }
16 + }
17 +};
18 +
19 +Timer.prototype.start = function start(msecs) {
20 + this.stop();
21 + this._timeout = Timers.setTimeout(this._onTimeout.bind(this), msecs);
22 +};
23 +
24 +Timer.prototype.stop = function stop() {
25 + if (this._timeout) {
26 + Timers.clearTimeout(this._timeout);
27 + this._timeout = null;
28 + }
29 +};
30 +
31 +Timer.prototype._onTimeout = function _onTimeout() {
32 + return this._object._onTimeout();
33 +};
This diff is collapsed. Click to expand it.
1 +// Manually extracted from mysql-5.5.23/include/mysql_com.h
2 +exports.CLIENT_LONG_PASSWORD = 1; /* new more secure passwords */
3 +exports.CLIENT_FOUND_ROWS = 2; /* Found instead of affected rows */
4 +exports.CLIENT_LONG_FLAG = 4; /* Get all column flags */
5 +exports.CLIENT_CONNECT_WITH_DB = 8; /* One can specify db on connect */
6 +exports.CLIENT_NO_SCHEMA = 16; /* Don't allow database.table.column */
7 +exports.CLIENT_COMPRESS = 32; /* Can use compression protocol */
8 +exports.CLIENT_ODBC = 64; /* Odbc client */
9 +exports.CLIENT_LOCAL_FILES = 128; /* Can use LOAD DATA LOCAL */
10 +exports.CLIENT_IGNORE_SPACE = 256; /* Ignore spaces before '(' */
11 +exports.CLIENT_PROTOCOL_41 = 512; /* New 4.1 protocol */
12 +exports.CLIENT_INTERACTIVE = 1024; /* This is an interactive client */
13 +exports.CLIENT_SSL = 2048; /* Switch to SSL after handshake */
14 +exports.CLIENT_IGNORE_SIGPIPE = 4096; /* IGNORE sigpipes */
15 +exports.CLIENT_TRANSACTIONS = 8192; /* Client knows about transactions */
16 +exports.CLIENT_RESERVED = 16384; /* Old flag for 4.1 protocol */
17 +exports.CLIENT_SECURE_CONNECTION = 32768; /* New 4.1 authentication */
18 +
19 +exports.CLIENT_MULTI_STATEMENTS = 65536; /* Enable/disable multi-stmt support */
20 +exports.CLIENT_MULTI_RESULTS = 131072; /* Enable/disable multi-results */
21 +exports.CLIENT_PS_MULTI_RESULTS = 262144; /* Multi-results in PS-protocol */
22 +
23 +exports.CLIENT_PLUGIN_AUTH = 524288; /* Client supports plugin authentication */
24 +
25 +exports.CLIENT_SSL_VERIFY_SERVER_CERT = 1073741824;
26 +exports.CLIENT_REMEMBER_OPTIONS = 2147483648;
This diff could not be displayed because it is too large.
1 +// Manually extracted from mysql-5.5.23/include/mysql_com.h
2 +exports.NOT_NULL_FLAG = 1; /* Field can't be NULL */
3 +exports.PRI_KEY_FLAG = 2; /* Field is part of a primary key */
4 +exports.UNIQUE_KEY_FLAG = 4; /* Field is part of a unique key */
5 +exports.MULTIPLE_KEY_FLAG = 8; /* Field is part of a key */
6 +exports.BLOB_FLAG = 16; /* Field is a blob */
7 +exports.UNSIGNED_FLAG = 32; /* Field is unsigned */
8 +exports.ZEROFILL_FLAG = 64; /* Field is zerofill */
9 +exports.BINARY_FLAG = 128; /* Field is binary */
10 +
11 +/* The following are only sent to new clients */
12 +exports.ENUM_FLAG = 256; /* field is an enum */
13 +exports.AUTO_INCREMENT_FLAG = 512; /* field is a autoincrement field */
14 +exports.TIMESTAMP_FLAG = 1024; /* Field is a timestamp */
15 +exports.SET_FLAG = 2048; /* field is a set */
16 +exports.NO_DEFAULT_VALUE_FLAG = 4096; /* Field doesn't have default value */
17 +exports.ON_UPDATE_NOW_FLAG = 8192; /* Field is set to NOW on UPDATE */
18 +exports.NUM_FLAG = 32768; /* Field is num (for clients) */
1 +// Manually extracted from mysql-5.5.23/include/mysql_com.h
2 +
3 +/**
4 + Is raised when a multi-statement transaction
5 + has been started, either explicitly, by means
6 + of BEGIN or COMMIT AND CHAIN, or
7 + implicitly, by the first transactional
8 + statement, when autocommit=off.
9 +*/
10 +exports.SERVER_STATUS_IN_TRANS = 1;
11 +exports.SERVER_STATUS_AUTOCOMMIT = 2; /* Server in auto_commit mode */
12 +exports.SERVER_MORE_RESULTS_EXISTS = 8; /* Multi query - next query exists */
13 +exports.SERVER_QUERY_NO_GOOD_INDEX_USED = 16;
14 +exports.SERVER_QUERY_NO_INDEX_USED = 32;
15 +/**
16 + The server was able to fulfill the clients request and opened a
17 + read-only non-scrollable cursor for a query. This flag comes
18 + in reply to COM_STMT_EXECUTE and COM_STMT_FETCH commands.
19 +*/
20 +exports.SERVER_STATUS_CURSOR_EXISTS = 64;
21 +/**
22 + This flag is sent when a read-only cursor is exhausted, in reply to
23 + COM_STMT_FETCH command.
24 +*/
25 +exports.SERVER_STATUS_LAST_ROW_SENT = 128;
26 +exports.SERVER_STATUS_DB_DROPPED = 256; /* A database was dropped */
27 +exports.SERVER_STATUS_NO_BACKSLASH_ESCAPES = 512;
28 +/**
29 + Sent to the client if after a prepared statement reprepare
30 + we discovered that the new statement returns a different
31 + number of result set columns.
32 +*/
33 +exports.SERVER_STATUS_METADATA_CHANGED = 1024;
34 +exports.SERVER_QUERY_WAS_SLOW = 2048;
35 +
36 +/**
37 + To mark ResultSet containing output parameter values.
38 +*/
39 +exports.SERVER_PS_OUT_PARAMS = 4096;
This diff is collapsed. Click to expand it.
1 +/**
2 + * MySQL type constants
3 + *
4 + * Extracted from version 5.7.29
5 + *
6 + * !! Generated by generate-type-constants.js, do not modify by hand !!
7 + */
8 +
9 +exports.DECIMAL = 0;
10 +exports.TINY = 1;
11 +exports.SHORT = 2;
12 +exports.LONG = 3;
13 +exports.FLOAT = 4;
14 +exports.DOUBLE = 5;
15 +exports.NULL = 6;
16 +exports.TIMESTAMP = 7;
17 +exports.LONGLONG = 8;
18 +exports.INT24 = 9;
19 +exports.DATE = 10;
20 +exports.TIME = 11;
21 +exports.DATETIME = 12;
22 +exports.YEAR = 13;
23 +exports.NEWDATE = 14;
24 +exports.VARCHAR = 15;
25 +exports.BIT = 16;
26 +exports.TIMESTAMP2 = 17;
27 +exports.DATETIME2 = 18;
28 +exports.TIME2 = 19;
29 +exports.JSON = 245;
30 +exports.NEWDECIMAL = 246;
31 +exports.ENUM = 247;
32 +exports.SET = 248;
33 +exports.TINY_BLOB = 249;
34 +exports.MEDIUM_BLOB = 250;
35 +exports.LONG_BLOB = 251;
36 +exports.BLOB = 252;
37 +exports.VAR_STRING = 253;
38 +exports.STRING = 254;
39 +exports.GEOMETRY = 255;
40 +
41 +// Lookup-by-number table
42 +exports[0] = 'DECIMAL';
43 +exports[1] = 'TINY';
44 +exports[2] = 'SHORT';
45 +exports[3] = 'LONG';
46 +exports[4] = 'FLOAT';
47 +exports[5] = 'DOUBLE';
48 +exports[6] = 'NULL';
49 +exports[7] = 'TIMESTAMP';
50 +exports[8] = 'LONGLONG';
51 +exports[9] = 'INT24';
52 +exports[10] = 'DATE';
53 +exports[11] = 'TIME';
54 +exports[12] = 'DATETIME';
55 +exports[13] = 'YEAR';
56 +exports[14] = 'NEWDATE';
57 +exports[15] = 'VARCHAR';
58 +exports[16] = 'BIT';
59 +exports[17] = 'TIMESTAMP2';
60 +exports[18] = 'DATETIME2';
61 +exports[19] = 'TIME2';
62 +exports[245] = 'JSON';
63 +exports[246] = 'NEWDECIMAL';
64 +exports[247] = 'ENUM';
65 +exports[248] = 'SET';
66 +exports[249] = 'TINY_BLOB';
67 +exports[250] = 'MEDIUM_BLOB';
68 +exports[251] = 'LONG_BLOB';
69 +exports[252] = 'BLOB';
70 +exports[253] = 'VAR_STRING';
71 +exports[254] = 'STRING';
72 +exports[255] = 'GEOMETRY';
1 +module.exports = AuthSwitchRequestPacket;
2 +function AuthSwitchRequestPacket(options) {
3 + options = options || {};
4 +
5 + this.status = 0xfe;
6 + this.authMethodName = options.authMethodName;
7 + this.authMethodData = options.authMethodData;
8 +}
9 +
10 +AuthSwitchRequestPacket.prototype.parse = function parse(parser) {
11 + this.status = parser.parseUnsignedNumber(1);
12 + this.authMethodName = parser.parseNullTerminatedString();
13 + this.authMethodData = parser.parsePacketTerminatedBuffer();
14 +};
15 +
16 +AuthSwitchRequestPacket.prototype.write = function write(writer) {
17 + writer.writeUnsignedNumber(1, this.status);
18 + writer.writeNullTerminatedString(this.authMethodName);
19 + writer.writeBuffer(this.authMethodData);
20 +};
1 +module.exports = AuthSwitchResponsePacket;
2 +function AuthSwitchResponsePacket(options) {
3 + options = options || {};
4 +
5 + this.data = options.data;
6 +}
7 +
8 +AuthSwitchResponsePacket.prototype.parse = function parse(parser) {
9 + this.data = parser.parsePacketTerminatedBuffer();
10 +};
11 +
12 +AuthSwitchResponsePacket.prototype.write = function write(writer) {
13 + writer.writeBuffer(this.data);
14 +};
1 +var Buffer = require('safe-buffer').Buffer;
2 +
3 +module.exports = ClientAuthenticationPacket;
4 +function ClientAuthenticationPacket(options) {
5 + options = options || {};
6 +
7 + this.clientFlags = options.clientFlags;
8 + this.maxPacketSize = options.maxPacketSize;
9 + this.charsetNumber = options.charsetNumber;
10 + this.filler = undefined;
11 + this.user = options.user;
12 + this.scrambleBuff = options.scrambleBuff;
13 + this.database = options.database;
14 + this.protocol41 = options.protocol41;
15 +}
16 +
17 +ClientAuthenticationPacket.prototype.parse = function(parser) {
18 + if (this.protocol41) {
19 + this.clientFlags = parser.parseUnsignedNumber(4);
20 + this.maxPacketSize = parser.parseUnsignedNumber(4);
21 + this.charsetNumber = parser.parseUnsignedNumber(1);
22 + this.filler = parser.parseFiller(23);
23 + this.user = parser.parseNullTerminatedString();
24 + this.scrambleBuff = parser.parseLengthCodedBuffer();
25 + this.database = parser.parseNullTerminatedString();
26 + } else {
27 + this.clientFlags = parser.parseUnsignedNumber(2);
28 + this.maxPacketSize = parser.parseUnsignedNumber(3);
29 + this.user = parser.parseNullTerminatedString();
30 + this.scrambleBuff = parser.parseBuffer(8);
31 + this.database = parser.parseLengthCodedBuffer();
32 + }
33 +};
34 +
35 +ClientAuthenticationPacket.prototype.write = function(writer) {
36 + if (this.protocol41) {
37 + writer.writeUnsignedNumber(4, this.clientFlags);
38 + writer.writeUnsignedNumber(4, this.maxPacketSize);
39 + writer.writeUnsignedNumber(1, this.charsetNumber);
40 + writer.writeFiller(23);
41 + writer.writeNullTerminatedString(this.user);
42 + writer.writeLengthCodedBuffer(this.scrambleBuff);
43 + writer.writeNullTerminatedString(this.database);
44 + } else {
45 + writer.writeUnsignedNumber(2, this.clientFlags);
46 + writer.writeUnsignedNumber(3, this.maxPacketSize);
47 + writer.writeNullTerminatedString(this.user);
48 + writer.writeBuffer(this.scrambleBuff);
49 + if (this.database && this.database.length) {
50 + writer.writeFiller(1);
51 + writer.writeBuffer(Buffer.from(this.database));
52 + }
53 + }
54 +};
1 +module.exports = ComChangeUserPacket;
2 +function ComChangeUserPacket(options) {
3 + options = options || {};
4 +
5 + this.command = 0x11;
6 + this.user = options.user;
7 + this.scrambleBuff = options.scrambleBuff;
8 + this.database = options.database;
9 + this.charsetNumber = options.charsetNumber;
10 +}
11 +
12 +ComChangeUserPacket.prototype.parse = function(parser) {
13 + this.command = parser.parseUnsignedNumber(1);
14 + this.user = parser.parseNullTerminatedString();
15 + this.scrambleBuff = parser.parseLengthCodedBuffer();
16 + this.database = parser.parseNullTerminatedString();
17 + this.charsetNumber = parser.parseUnsignedNumber(1);
18 +};
19 +
20 +ComChangeUserPacket.prototype.write = function(writer) {
21 + writer.writeUnsignedNumber(1, this.command);
22 + writer.writeNullTerminatedString(this.user);
23 + writer.writeLengthCodedBuffer(this.scrambleBuff);
24 + writer.writeNullTerminatedString(this.database);
25 + writer.writeUnsignedNumber(2, this.charsetNumber);
26 +};
1 +module.exports = ComPingPacket;
2 +function ComPingPacket() {
3 + this.command = 0x0e;
4 +}
5 +
6 +ComPingPacket.prototype.write = function(writer) {
7 + writer.writeUnsignedNumber(1, this.command);
8 +};
9 +
10 +ComPingPacket.prototype.parse = function(parser) {
11 + this.command = parser.parseUnsignedNumber(1);
12 +};
1 +module.exports = ComQueryPacket;
2 +function ComQueryPacket(sql) {
3 + this.command = 0x03;
4 + this.sql = sql;
5 +}
6 +
7 +ComQueryPacket.prototype.write = function(writer) {
8 + writer.writeUnsignedNumber(1, this.command);
9 + writer.writeString(this.sql);
10 +};
11 +
12 +ComQueryPacket.prototype.parse = function(parser) {
13 + this.command = parser.parseUnsignedNumber(1);
14 + this.sql = parser.parsePacketTerminatedString();
15 +};
1 +module.exports = ComQuitPacket;
2 +function ComQuitPacket() {
3 + this.command = 0x01;
4 +}
5 +
6 +ComQuitPacket.prototype.parse = function parse(parser) {
7 + this.command = parser.parseUnsignedNumber(1);
8 +};
9 +
10 +ComQuitPacket.prototype.write = function write(writer) {
11 + writer.writeUnsignedNumber(1, this.command);
12 +};
1 +module.exports = ComStatisticsPacket;
2 +function ComStatisticsPacket() {
3 + this.command = 0x09;
4 +}
5 +
6 +ComStatisticsPacket.prototype.write = function(writer) {
7 + writer.writeUnsignedNumber(1, this.command);
8 +};
9 +
10 +ComStatisticsPacket.prototype.parse = function(parser) {
11 + this.command = parser.parseUnsignedNumber(1);
12 +};
1 +module.exports = EmptyPacket;
2 +function EmptyPacket() {
3 +}
4 +
5 +EmptyPacket.prototype.parse = function parse() {
6 +};
7 +
8 +EmptyPacket.prototype.write = function write() {
9 +};
1 +module.exports = EofPacket;
2 +function EofPacket(options) {
3 + options = options || {};
4 +
5 + this.fieldCount = undefined;
6 + this.warningCount = options.warningCount;
7 + this.serverStatus = options.serverStatus;
8 + this.protocol41 = options.protocol41;
9 +}
10 +
11 +EofPacket.prototype.parse = function(parser) {
12 + this.fieldCount = parser.parseUnsignedNumber(1);
13 + if (this.protocol41) {
14 + this.warningCount = parser.parseUnsignedNumber(2);
15 + this.serverStatus = parser.parseUnsignedNumber(2);
16 + }
17 +};
18 +
19 +EofPacket.prototype.write = function(writer) {
20 + writer.writeUnsignedNumber(1, 0xfe);
21 + if (this.protocol41) {
22 + writer.writeUnsignedNumber(2, this.warningCount);
23 + writer.writeUnsignedNumber(2, this.serverStatus);
24 + }
25 +};
1 +module.exports = ErrorPacket;
2 +function ErrorPacket(options) {
3 + options = options || {};
4 +
5 + this.fieldCount = options.fieldCount;
6 + this.errno = options.errno;
7 + this.sqlStateMarker = options.sqlStateMarker;
8 + this.sqlState = options.sqlState;
9 + this.message = options.message;
10 +}
11 +
12 +ErrorPacket.prototype.parse = function(parser) {
13 + this.fieldCount = parser.parseUnsignedNumber(1);
14 + this.errno = parser.parseUnsignedNumber(2);
15 +
16 + // sqlStateMarker ('#' = 0x23) indicates error packet format
17 + if (parser.peak() === 0x23) {
18 + this.sqlStateMarker = parser.parseString(1);
19 + this.sqlState = parser.parseString(5);
20 + }
21 +
22 + this.message = parser.parsePacketTerminatedString();
23 +};
24 +
25 +ErrorPacket.prototype.write = function(writer) {
26 + writer.writeUnsignedNumber(1, 0xff);
27 + writer.writeUnsignedNumber(2, this.errno);
28 +
29 + if (this.sqlStateMarker) {
30 + writer.writeString(this.sqlStateMarker);
31 + writer.writeString(this.sqlState);
32 + }
33 +
34 + writer.writeString(this.message);
35 +};
1 +var Types = require('../constants/types');
2 +
3 +module.exports = Field;
4 +function Field(options) {
5 + options = options || {};
6 +
7 + this.parser = options.parser;
8 + this.packet = options.packet;
9 + this.db = options.packet.db;
10 + this.table = options.packet.table;
11 + this.name = options.packet.name;
12 + this.type = Types[options.packet.type];
13 + this.length = options.packet.length;
14 +}
15 +
16 +Field.prototype.string = function () {
17 + return this.parser.parseLengthCodedString();
18 +};
19 +
20 +Field.prototype.buffer = function () {
21 + return this.parser.parseLengthCodedBuffer();
22 +};
23 +
24 +Field.prototype.geometry = function () {
25 + return this.parser.parseGeometryValue();
26 +};
1 +module.exports = FieldPacket;
2 +function FieldPacket(options) {
3 + options = options || {};
4 +
5 + this.catalog = options.catalog;
6 + this.db = options.db;
7 + this.table = options.table;
8 + this.orgTable = options.orgTable;
9 + this.name = options.name;
10 + this.orgName = options.orgName;
11 + this.charsetNr = options.charsetNr;
12 + this.length = options.length;
13 + this.type = options.type;
14 + this.flags = options.flags;
15 + this.decimals = options.decimals;
16 + this.default = options.default;
17 + this.zeroFill = options.zeroFill;
18 + this.protocol41 = options.protocol41;
19 +}
20 +
21 +FieldPacket.prototype.parse = function(parser) {
22 + if (this.protocol41) {
23 + this.catalog = parser.parseLengthCodedString();
24 + this.db = parser.parseLengthCodedString();
25 + this.table = parser.parseLengthCodedString();
26 + this.orgTable = parser.parseLengthCodedString();
27 + this.name = parser.parseLengthCodedString();
28 + this.orgName = parser.parseLengthCodedString();
29 +
30 + if (parser.parseLengthCodedNumber() !== 0x0c) {
31 + var err = new TypeError('Received invalid field length');
32 + err.code = 'PARSER_INVALID_FIELD_LENGTH';
33 + throw err;
34 + }
35 +
36 + this.charsetNr = parser.parseUnsignedNumber(2);
37 + this.length = parser.parseUnsignedNumber(4);
38 + this.type = parser.parseUnsignedNumber(1);
39 + this.flags = parser.parseUnsignedNumber(2);
40 + this.decimals = parser.parseUnsignedNumber(1);
41 +
42 + var filler = parser.parseBuffer(2);
43 + if (filler[0] !== 0x0 || filler[1] !== 0x0) {
44 + var err = new TypeError('Received invalid filler');
45 + err.code = 'PARSER_INVALID_FILLER';
46 + throw err;
47 + }
48 +
49 + // parsed flags
50 + this.zeroFill = (this.flags & 0x0040 ? true : false);
51 +
52 + if (parser.reachedPacketEnd()) {
53 + return;
54 + }
55 +
56 + this.default = parser.parseLengthCodedString();
57 + } else {
58 + this.table = parser.parseLengthCodedString();
59 + this.name = parser.parseLengthCodedString();
60 + this.length = parser.parseUnsignedNumber(parser.parseUnsignedNumber(1));
61 + this.type = parser.parseUnsignedNumber(parser.parseUnsignedNumber(1));
62 + }
63 +};
64 +
65 +FieldPacket.prototype.write = function(writer) {
66 + if (this.protocol41) {
67 + writer.writeLengthCodedString(this.catalog);
68 + writer.writeLengthCodedString(this.db);
69 + writer.writeLengthCodedString(this.table);
70 + writer.writeLengthCodedString(this.orgTable);
71 + writer.writeLengthCodedString(this.name);
72 + writer.writeLengthCodedString(this.orgName);
73 +
74 + writer.writeLengthCodedNumber(0x0c);
75 + writer.writeUnsignedNumber(2, this.charsetNr || 0);
76 + writer.writeUnsignedNumber(4, this.length || 0);
77 + writer.writeUnsignedNumber(1, this.type || 0);
78 + writer.writeUnsignedNumber(2, this.flags || 0);
79 + writer.writeUnsignedNumber(1, this.decimals || 0);
80 + writer.writeFiller(2);
81 +
82 + if (this.default !== undefined) {
83 + writer.writeLengthCodedString(this.default);
84 + }
85 + } else {
86 + writer.writeLengthCodedString(this.table);
87 + writer.writeLengthCodedString(this.name);
88 + writer.writeUnsignedNumber(1, 0x01);
89 + writer.writeUnsignedNumber(1, this.length);
90 + writer.writeUnsignedNumber(1, 0x01);
91 + writer.writeUnsignedNumber(1, this.type);
92 + }
93 +};
1 +var Buffer = require('safe-buffer').Buffer;
2 +var Client = require('../constants/client');
3 +
4 +module.exports = HandshakeInitializationPacket;
5 +function HandshakeInitializationPacket(options) {
6 + options = options || {};
7 +
8 + this.protocolVersion = options.protocolVersion;
9 + this.serverVersion = options.serverVersion;
10 + this.threadId = options.threadId;
11 + this.scrambleBuff1 = options.scrambleBuff1;
12 + this.filler1 = options.filler1;
13 + this.serverCapabilities1 = options.serverCapabilities1;
14 + this.serverLanguage = options.serverLanguage;
15 + this.serverStatus = options.serverStatus;
16 + this.serverCapabilities2 = options.serverCapabilities2;
17 + this.scrambleLength = options.scrambleLength;
18 + this.filler2 = options.filler2;
19 + this.scrambleBuff2 = options.scrambleBuff2;
20 + this.filler3 = options.filler3;
21 + this.pluginData = options.pluginData;
22 + this.protocol41 = options.protocol41;
23 +
24 + if (this.protocol41) {
25 + // force set the bit in serverCapabilities1
26 + this.serverCapabilities1 |= Client.CLIENT_PROTOCOL_41;
27 + }
28 +}
29 +
30 +HandshakeInitializationPacket.prototype.parse = function(parser) {
31 + this.protocolVersion = parser.parseUnsignedNumber(1);
32 + this.serverVersion = parser.parseNullTerminatedString();
33 + this.threadId = parser.parseUnsignedNumber(4);
34 + this.scrambleBuff1 = parser.parseBuffer(8);
35 + this.filler1 = parser.parseFiller(1);
36 + this.serverCapabilities1 = parser.parseUnsignedNumber(2);
37 + this.serverLanguage = parser.parseUnsignedNumber(1);
38 + this.serverStatus = parser.parseUnsignedNumber(2);
39 +
40 + this.protocol41 = (this.serverCapabilities1 & (1 << 9)) > 0;
41 +
42 + if (this.protocol41) {
43 + this.serverCapabilities2 = parser.parseUnsignedNumber(2);
44 + this.scrambleLength = parser.parseUnsignedNumber(1);
45 + this.filler2 = parser.parseFiller(10);
46 + // scrambleBuff2 should be 0x00 terminated, but sphinx does not do this
47 + // so we assume scrambleBuff2 to be 12 byte and treat the next byte as a
48 + // filler byte.
49 + this.scrambleBuff2 = parser.parseBuffer(12);
50 + this.filler3 = parser.parseFiller(1);
51 + } else {
52 + this.filler2 = parser.parseFiller(13);
53 + }
54 +
55 + if (parser.reachedPacketEnd()) {
56 + return;
57 + }
58 +
59 + // According to the docs this should be 0x00 terminated, but MariaDB does
60 + // not do this, so we assume this string to be packet terminated.
61 + this.pluginData = parser.parsePacketTerminatedString();
62 +
63 + // However, if there is a trailing '\0', strip it
64 + var lastChar = this.pluginData.length - 1;
65 + if (this.pluginData[lastChar] === '\0') {
66 + this.pluginData = this.pluginData.substr(0, lastChar);
67 + }
68 +};
69 +
70 +HandshakeInitializationPacket.prototype.write = function(writer) {
71 + writer.writeUnsignedNumber(1, this.protocolVersion);
72 + writer.writeNullTerminatedString(this.serverVersion);
73 + writer.writeUnsignedNumber(4, this.threadId);
74 + writer.writeBuffer(this.scrambleBuff1);
75 + writer.writeFiller(1);
76 + writer.writeUnsignedNumber(2, this.serverCapabilities1);
77 + writer.writeUnsignedNumber(1, this.serverLanguage);
78 + writer.writeUnsignedNumber(2, this.serverStatus);
79 + if (this.protocol41) {
80 + writer.writeUnsignedNumber(2, this.serverCapabilities2);
81 + writer.writeUnsignedNumber(1, this.scrambleLength);
82 + writer.writeFiller(10);
83 + }
84 + writer.writeNullTerminatedBuffer(this.scrambleBuff2);
85 +
86 + if (this.pluginData !== undefined) {
87 + writer.writeNullTerminatedString(this.pluginData);
88 + }
89 +};
90 +
91 +HandshakeInitializationPacket.prototype.scrambleBuff = function() {
92 + var buffer = null;
93 +
94 + if (typeof this.scrambleBuff2 === 'undefined') {
95 + buffer = Buffer.from(this.scrambleBuff1);
96 + } else {
97 + buffer = Buffer.allocUnsafe(this.scrambleBuff1.length + this.scrambleBuff2.length);
98 + this.scrambleBuff1.copy(buffer, 0);
99 + this.scrambleBuff2.copy(buffer, this.scrambleBuff1.length);
100 + }
101 +
102 + return buffer;
103 +};
1 +module.exports = LocalDataFilePacket;
2 +
3 +/**
4 + * Create a new LocalDataFilePacket
5 + * @constructor
6 + * @param {Buffer} data The data contents of the packet
7 + * @public
8 + */
9 +function LocalDataFilePacket(data) {
10 + this.data = data;
11 +}
12 +
13 +LocalDataFilePacket.prototype.write = function(writer) {
14 + writer.writeBuffer(this.data);
15 +};
1 +module.exports = LocalInfileRequestPacket;
2 +function LocalInfileRequestPacket(options) {
3 + options = options || {};
4 +
5 + this.filename = options.filename;
6 +}
7 +
8 +LocalInfileRequestPacket.prototype.parse = function parse(parser) {
9 + if (parser.parseLengthCodedNumber() !== null) {
10 + var err = new TypeError('Received invalid field length');
11 + err.code = 'PARSER_INVALID_FIELD_LENGTH';
12 + throw err;
13 + }
14 +
15 + this.filename = parser.parsePacketTerminatedString();
16 +};
17 +
18 +LocalInfileRequestPacket.prototype.write = function write(writer) {
19 + writer.writeLengthCodedNumber(null);
20 + writer.writeString(this.filename);
21 +};
1 +
2 +// Language-neutral expression to match ER_UPDATE_INFO
3 +var ER_UPDATE_INFO_REGEXP = /^[^:0-9]+: [0-9]+[^:0-9]+: ([0-9]+)[^:0-9]+: [0-9]+[^:0-9]*$/;
4 +
5 +module.exports = OkPacket;
6 +function OkPacket(options) {
7 + options = options || {};
8 +
9 + this.fieldCount = undefined;
10 + this.affectedRows = undefined;
11 + this.insertId = undefined;
12 + this.serverStatus = undefined;
13 + this.warningCount = undefined;
14 + this.message = undefined;
15 + this.protocol41 = options.protocol41;
16 +}
17 +
18 +OkPacket.prototype.parse = function(parser) {
19 + this.fieldCount = parser.parseUnsignedNumber(1);
20 + this.affectedRows = parser.parseLengthCodedNumber();
21 + this.insertId = parser.parseLengthCodedNumber();
22 + if (this.protocol41) {
23 + this.serverStatus = parser.parseUnsignedNumber(2);
24 + this.warningCount = parser.parseUnsignedNumber(2);
25 + }
26 + this.message = parser.parsePacketTerminatedString();
27 + this.changedRows = 0;
28 +
29 + var m = ER_UPDATE_INFO_REGEXP.exec(this.message);
30 + if (m !== null) {
31 + this.changedRows = parseInt(m[1], 10);
32 + }
33 +};
34 +
35 +OkPacket.prototype.write = function(writer) {
36 + writer.writeUnsignedNumber(1, 0x00);
37 + writer.writeLengthCodedNumber(this.affectedRows || 0);
38 + writer.writeLengthCodedNumber(this.insertId || 0);
39 + if (this.protocol41) {
40 + writer.writeUnsignedNumber(2, this.serverStatus || 0);
41 + writer.writeUnsignedNumber(2, this.warningCount || 0);
42 + }
43 + writer.writeString(this.message);
44 +};
1 +module.exports = OldPasswordPacket;
2 +function OldPasswordPacket(options) {
3 + options = options || {};
4 +
5 + this.scrambleBuff = options.scrambleBuff;
6 +}
7 +
8 +OldPasswordPacket.prototype.parse = function(parser) {
9 + this.scrambleBuff = parser.parsePacketTerminatedBuffer();
10 +};
11 +
12 +OldPasswordPacket.prototype.write = function(writer) {
13 + writer.writeBuffer(this.scrambleBuff);
14 +};
1 +module.exports = ResultSetHeaderPacket;
2 +function ResultSetHeaderPacket(options) {
3 + options = options || {};
4 +
5 + this.fieldCount = options.fieldCount;
6 +}
7 +
8 +ResultSetHeaderPacket.prototype.parse = function(parser) {
9 + this.fieldCount = parser.parseLengthCodedNumber();
10 +};
11 +
12 +ResultSetHeaderPacket.prototype.write = function(writer) {
13 + writer.writeLengthCodedNumber(this.fieldCount);
14 +};
1 +var Types = require('../constants/types');
2 +var Charsets = require('../constants/charsets');
3 +var Field = require('./Field');
4 +var IEEE_754_BINARY_64_PRECISION = Math.pow(2, 53);
5 +
6 +module.exports = RowDataPacket;
7 +function RowDataPacket() {
8 +}
9 +
10 +Object.defineProperty(RowDataPacket.prototype, 'parse', {
11 + configurable : true,
12 + enumerable : false,
13 + value : parse
14 +});
15 +
16 +Object.defineProperty(RowDataPacket.prototype, '_typeCast', {
17 + configurable : true,
18 + enumerable : false,
19 + value : typeCast
20 +});
21 +
22 +function parse(parser, fieldPackets, typeCast, nestTables, connection) {
23 + var self = this;
24 + var next = function () {
25 + return self._typeCast(fieldPacket, parser, connection.config.timezone, connection.config.supportBigNumbers, connection.config.bigNumberStrings, connection.config.dateStrings);
26 + };
27 +
28 + for (var i = 0; i < fieldPackets.length; i++) {
29 + var fieldPacket = fieldPackets[i];
30 + var value;
31 +
32 + if (typeof typeCast === 'function') {
33 + value = typeCast.apply(connection, [ new Field({ packet: fieldPacket, parser: parser }), next ]);
34 + } else {
35 + value = (typeCast)
36 + ? this._typeCast(fieldPacket, parser, connection.config.timezone, connection.config.supportBigNumbers, connection.config.bigNumberStrings, connection.config.dateStrings)
37 + : ( (fieldPacket.charsetNr === Charsets.BINARY)
38 + ? parser.parseLengthCodedBuffer()
39 + : parser.parseLengthCodedString() );
40 + }
41 +
42 + if (typeof nestTables === 'string' && nestTables.length) {
43 + this[fieldPacket.table + nestTables + fieldPacket.name] = value;
44 + } else if (nestTables) {
45 + this[fieldPacket.table] = this[fieldPacket.table] || {};
46 + this[fieldPacket.table][fieldPacket.name] = value;
47 + } else {
48 + this[fieldPacket.name] = value;
49 + }
50 + }
51 +}
52 +
53 +function typeCast(field, parser, timeZone, supportBigNumbers, bigNumberStrings, dateStrings) {
54 + var numberString;
55 +
56 + switch (field.type) {
57 + case Types.TIMESTAMP:
58 + case Types.TIMESTAMP2:
59 + case Types.DATE:
60 + case Types.DATETIME:
61 + case Types.DATETIME2:
62 + case Types.NEWDATE:
63 + var dateString = parser.parseLengthCodedString();
64 +
65 + if (typeMatch(field.type, dateStrings)) {
66 + return dateString;
67 + }
68 +
69 + if (dateString === null) {
70 + return null;
71 + }
72 +
73 + var originalString = dateString;
74 + if (field.type === Types.DATE) {
75 + dateString += ' 00:00:00';
76 + }
77 +
78 + if (timeZone !== 'local') {
79 + dateString += ' ' + timeZone;
80 + }
81 +
82 + var dt = new Date(dateString);
83 + if (isNaN(dt.getTime())) {
84 + return originalString;
85 + }
86 +
87 + return dt;
88 + case Types.TINY:
89 + case Types.SHORT:
90 + case Types.LONG:
91 + case Types.INT24:
92 + case Types.YEAR:
93 + case Types.FLOAT:
94 + case Types.DOUBLE:
95 + numberString = parser.parseLengthCodedString();
96 + return (numberString === null || (field.zeroFill && numberString[0] === '0'))
97 + ? numberString : Number(numberString);
98 + case Types.NEWDECIMAL:
99 + case Types.LONGLONG:
100 + numberString = parser.parseLengthCodedString();
101 + return (numberString === null || (field.zeroFill && numberString[0] === '0'))
102 + ? numberString
103 + : ((supportBigNumbers && (bigNumberStrings || (Number(numberString) >= IEEE_754_BINARY_64_PRECISION) || Number(numberString) <= -IEEE_754_BINARY_64_PRECISION))
104 + ? numberString
105 + : Number(numberString));
106 + case Types.BIT:
107 + return parser.parseLengthCodedBuffer();
108 + case Types.STRING:
109 + case Types.VAR_STRING:
110 + case Types.TINY_BLOB:
111 + case Types.MEDIUM_BLOB:
112 + case Types.LONG_BLOB:
113 + case Types.BLOB:
114 + return (field.charsetNr === Charsets.BINARY)
115 + ? parser.parseLengthCodedBuffer()
116 + : parser.parseLengthCodedString();
117 + case Types.GEOMETRY:
118 + return parser.parseGeometryValue();
119 + default:
120 + return parser.parseLengthCodedString();
121 + }
122 +}
123 +
124 +function typeMatch(type, list) {
125 + if (Array.isArray(list)) {
126 + return list.indexOf(Types[type]) !== -1;
127 + } else {
128 + return Boolean(list);
129 + }
130 +}
1 +// http://dev.mysql.com/doc/internals/en/ssl.html
2 +// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::SSLRequest
3 +
4 +var ClientConstants = require('../constants/client');
5 +
6 +module.exports = SSLRequestPacket;
7 +
8 +function SSLRequestPacket(options) {
9 + options = options || {};
10 + this.clientFlags = options.clientFlags | ClientConstants.CLIENT_SSL;
11 + this.maxPacketSize = options.maxPacketSize;
12 + this.charsetNumber = options.charsetNumber;
13 +}
14 +
15 +SSLRequestPacket.prototype.parse = function(parser) {
16 + // TODO: check SSLRequest packet v41 vs pre v41
17 + this.clientFlags = parser.parseUnsignedNumber(4);
18 + this.maxPacketSize = parser.parseUnsignedNumber(4);
19 + this.charsetNumber = parser.parseUnsignedNumber(1);
20 +};
21 +
22 +SSLRequestPacket.prototype.write = function(writer) {
23 + writer.writeUnsignedNumber(4, this.clientFlags);
24 + writer.writeUnsignedNumber(4, this.maxPacketSize);
25 + writer.writeUnsignedNumber(1, this.charsetNumber);
26 + writer.writeFiller(23);
27 +};
1 +module.exports = StatisticsPacket;
2 +function StatisticsPacket() {
3 + this.message = undefined;
4 +}
5 +
6 +StatisticsPacket.prototype.parse = function(parser) {
7 + this.message = parser.parsePacketTerminatedString();
8 +
9 + var items = this.message.split(/\s\s/);
10 + for (var i = 0; i < items.length; i++) {
11 + var m = items[i].match(/^(.+)\:\s+(.+)$/);
12 + if (m !== null) {
13 + this[m[1].toLowerCase().replace(/\s/g, '_')] = Number(m[2]);
14 + }
15 + }
16 +};
17 +
18 +StatisticsPacket.prototype.write = function(writer) {
19 + writer.writeString(this.message);
20 +};
1 +module.exports = UseOldPasswordPacket;
2 +function UseOldPasswordPacket(options) {
3 + options = options || {};
4 +
5 + this.firstByte = options.firstByte || 0xfe;
6 +}
7 +
8 +UseOldPasswordPacket.prototype.parse = function(parser) {
9 + this.firstByte = parser.parseUnsignedNumber(1);
10 +};
11 +
12 +UseOldPasswordPacket.prototype.write = function(writer) {
13 + writer.writeUnsignedNumber(1, this.firstByte);
14 +};
1 +exports.AuthSwitchRequestPacket = require('./AuthSwitchRequestPacket');
2 +exports.AuthSwitchResponsePacket = require('./AuthSwitchResponsePacket');
3 +exports.ClientAuthenticationPacket = require('./ClientAuthenticationPacket');
4 +exports.ComChangeUserPacket = require('./ComChangeUserPacket');
5 +exports.ComPingPacket = require('./ComPingPacket');
6 +exports.ComQueryPacket = require('./ComQueryPacket');
7 +exports.ComQuitPacket = require('./ComQuitPacket');
8 +exports.ComStatisticsPacket = require('./ComStatisticsPacket');
9 +exports.EmptyPacket = require('./EmptyPacket');
10 +exports.EofPacket = require('./EofPacket');
11 +exports.ErrorPacket = require('./ErrorPacket');
12 +exports.Field = require('./Field');
13 +exports.FieldPacket = require('./FieldPacket');
14 +exports.HandshakeInitializationPacket = require('./HandshakeInitializationPacket');
15 +exports.LocalDataFilePacket = require('./LocalDataFilePacket');
16 +exports.LocalInfileRequestPacket = require('./LocalInfileRequestPacket');
17 +exports.OkPacket = require('./OkPacket');
18 +exports.OldPasswordPacket = require('./OldPasswordPacket');
19 +exports.ResultSetHeaderPacket = require('./ResultSetHeaderPacket');
20 +exports.RowDataPacket = require('./RowDataPacket');
21 +exports.SSLRequestPacket = require('./SSLRequestPacket');
22 +exports.StatisticsPacket = require('./StatisticsPacket');
23 +exports.UseOldPasswordPacket = require('./UseOldPasswordPacket');
1 +var Sequence = require('./Sequence');
2 +var Util = require('util');
3 +var Packets = require('../packets');
4 +var Auth = require('../Auth');
5 +
6 +module.exports = ChangeUser;
7 +Util.inherits(ChangeUser, Sequence);
8 +function ChangeUser(options, callback) {
9 + Sequence.call(this, options, callback);
10 +
11 + this._user = options.user;
12 + this._password = options.password;
13 + this._database = options.database;
14 + this._charsetNumber = options.charsetNumber;
15 + this._currentConfig = options.currentConfig;
16 +}
17 +
18 +ChangeUser.prototype.determinePacket = function determinePacket(firstByte) {
19 + switch (firstByte) {
20 + case 0xfe: return Packets.AuthSwitchRequestPacket;
21 + case 0xff: return Packets.ErrorPacket;
22 + default: return undefined;
23 + }
24 +};
25 +
26 +ChangeUser.prototype.start = function(handshakeInitializationPacket) {
27 + var scrambleBuff = handshakeInitializationPacket.scrambleBuff();
28 + scrambleBuff = Auth.token(this._password, scrambleBuff);
29 +
30 + var packet = new Packets.ComChangeUserPacket({
31 + user : this._user,
32 + scrambleBuff : scrambleBuff,
33 + database : this._database,
34 + charsetNumber : this._charsetNumber
35 + });
36 +
37 + this._currentConfig.user = this._user;
38 + this._currentConfig.password = this._password;
39 + this._currentConfig.database = this._database;
40 + this._currentConfig.charsetNumber = this._charsetNumber;
41 +
42 + this.emit('packet', packet);
43 +};
44 +
45 +ChangeUser.prototype['AuthSwitchRequestPacket'] = function (packet) {
46 + var name = packet.authMethodName;
47 + var data = Auth.auth(name, packet.authMethodData, {
48 + password: this._password
49 + });
50 +
51 + if (data !== undefined) {
52 + this.emit('packet', new Packets.AuthSwitchResponsePacket({
53 + data: data
54 + }));
55 + } else {
56 + var err = new Error('MySQL is requesting the ' + name + ' authentication method, which is not supported.');
57 + err.code = 'UNSUPPORTED_AUTH_METHOD';
58 + err.fatal = true;
59 + this.end(err);
60 + }
61 +};
62 +
63 +ChangeUser.prototype['ErrorPacket'] = function(packet) {
64 + var err = this._packetToError(packet);
65 + err.fatal = true;
66 + this.end(err);
67 +};
1 +var Sequence = require('./Sequence');
2 +var Util = require('util');
3 +var Packets = require('../packets');
4 +var Auth = require('../Auth');
5 +var ClientConstants = require('../constants/client');
6 +
7 +module.exports = Handshake;
8 +Util.inherits(Handshake, Sequence);
9 +function Handshake(options, callback) {
10 + Sequence.call(this, options, callback);
11 +
12 + options = options || {};
13 +
14 + this._config = options.config;
15 + this._handshakeInitializationPacket = null;
16 +}
17 +
18 +Handshake.prototype.determinePacket = function determinePacket(firstByte, parser) {
19 + if (firstByte === 0xff) {
20 + return Packets.ErrorPacket;
21 + }
22 +
23 + if (!this._handshakeInitializationPacket) {
24 + return Packets.HandshakeInitializationPacket;
25 + }
26 +
27 + if (firstByte === 0xfe) {
28 + return (parser.packetLength() === 1)
29 + ? Packets.UseOldPasswordPacket
30 + : Packets.AuthSwitchRequestPacket;
31 + }
32 +
33 + return undefined;
34 +};
35 +
36 +Handshake.prototype['AuthSwitchRequestPacket'] = function (packet) {
37 + var name = packet.authMethodName;
38 + var data = Auth.auth(name, packet.authMethodData, {
39 + password: this._config.password
40 + });
41 +
42 + if (data !== undefined) {
43 + this.emit('packet', new Packets.AuthSwitchResponsePacket({
44 + data: data
45 + }));
46 + } else {
47 + var err = new Error('MySQL is requesting the ' + name + ' authentication method, which is not supported.');
48 + err.code = 'UNSUPPORTED_AUTH_METHOD';
49 + err.fatal = true;
50 + this.end(err);
51 + }
52 +};
53 +
54 +Handshake.prototype['HandshakeInitializationPacket'] = function(packet) {
55 + this._handshakeInitializationPacket = packet;
56 +
57 + this._config.protocol41 = packet.protocol41;
58 +
59 + var serverSSLSupport = packet.serverCapabilities1 & ClientConstants.CLIENT_SSL;
60 +
61 + if (this._config.ssl) {
62 + if (!serverSSLSupport) {
63 + var err = new Error('Server does not support secure connection');
64 +
65 + err.code = 'HANDSHAKE_NO_SSL_SUPPORT';
66 + err.fatal = true;
67 +
68 + this.end(err);
69 + return;
70 + }
71 +
72 + this._config.clientFlags |= ClientConstants.CLIENT_SSL;
73 + this.emit('packet', new Packets.SSLRequestPacket({
74 + clientFlags : this._config.clientFlags,
75 + maxPacketSize : this._config.maxPacketSize,
76 + charsetNumber : this._config.charsetNumber
77 + }));
78 + this.emit('start-tls');
79 + } else {
80 + this._sendCredentials();
81 + }
82 +};
83 +
84 +Handshake.prototype._tlsUpgradeCompleteHandler = function() {
85 + this._sendCredentials();
86 +};
87 +
88 +Handshake.prototype._sendCredentials = function() {
89 + var packet = this._handshakeInitializationPacket;
90 + this.emit('packet', new Packets.ClientAuthenticationPacket({
91 + clientFlags : this._config.clientFlags,
92 + maxPacketSize : this._config.maxPacketSize,
93 + charsetNumber : this._config.charsetNumber,
94 + user : this._config.user,
95 + database : this._config.database,
96 + protocol41 : packet.protocol41,
97 + scrambleBuff : (packet.protocol41)
98 + ? Auth.token(this._config.password, packet.scrambleBuff())
99 + : Auth.scramble323(packet.scrambleBuff(), this._config.password)
100 + }));
101 +};
102 +
103 +Handshake.prototype['UseOldPasswordPacket'] = function() {
104 + if (!this._config.insecureAuth) {
105 + var err = new Error(
106 + 'MySQL server is requesting the old and insecure pre-4.1 auth mechanism. ' +
107 + 'Upgrade the user password or use the {insecureAuth: true} option.'
108 + );
109 +
110 + err.code = 'HANDSHAKE_INSECURE_AUTH';
111 + err.fatal = true;
112 +
113 + this.end(err);
114 + return;
115 + }
116 +
117 + this.emit('packet', new Packets.OldPasswordPacket({
118 + scrambleBuff: Auth.scramble323(this._handshakeInitializationPacket.scrambleBuff(), this._config.password)
119 + }));
120 +};
121 +
122 +Handshake.prototype['ErrorPacket'] = function(packet) {
123 + var err = this._packetToError(packet, true);
124 + err.fatal = true;
125 + this.end(err);
126 +};
1 +var Sequence = require('./Sequence');
2 +var Util = require('util');
3 +var Packets = require('../packets');
4 +
5 +module.exports = Ping;
6 +Util.inherits(Ping, Sequence);
7 +
8 +function Ping(options, callback) {
9 + if (!callback && typeof options === 'function') {
10 + callback = options;
11 + options = {};
12 + }
13 +
14 + Sequence.call(this, options, callback);
15 +}
16 +
17 +Ping.prototype.start = function() {
18 + this.emit('packet', new Packets.ComPingPacket());
19 +};
1 +var ClientConstants = require('../constants/client');
2 +var fs = require('fs');
3 +var Packets = require('../packets');
4 +var ResultSet = require('../ResultSet');
5 +var Sequence = require('./Sequence');
6 +var ServerStatus = require('../constants/server_status');
7 +var Readable = require('readable-stream');
8 +var Util = require('util');
9 +
10 +module.exports = Query;
11 +Util.inherits(Query, Sequence);
12 +function Query(options, callback) {
13 + Sequence.call(this, options, callback);
14 +
15 + this.sql = options.sql;
16 + this.values = options.values;
17 + this.typeCast = (options.typeCast === undefined)
18 + ? true
19 + : options.typeCast;
20 + this.nestTables = options.nestTables || false;
21 +
22 + this._resultSet = null;
23 + this._results = [];
24 + this._fields = [];
25 + this._index = 0;
26 + this._loadError = null;
27 +}
28 +
29 +Query.prototype.start = function() {
30 + this.emit('packet', new Packets.ComQueryPacket(this.sql));
31 +};
32 +
33 +Query.prototype.determinePacket = function determinePacket(byte, parser) {
34 + var resultSet = this._resultSet;
35 +
36 + if (!resultSet) {
37 + switch (byte) {
38 + case 0x00: return Packets.OkPacket;
39 + case 0xfb: return Packets.LocalInfileRequestPacket;
40 + case 0xff: return Packets.ErrorPacket;
41 + default: return Packets.ResultSetHeaderPacket;
42 + }
43 + }
44 +
45 + if (resultSet.eofPackets.length === 0) {
46 + return (resultSet.fieldPackets.length < resultSet.resultSetHeaderPacket.fieldCount)
47 + ? Packets.FieldPacket
48 + : Packets.EofPacket;
49 + }
50 +
51 + if (byte === 0xff) {
52 + return Packets.ErrorPacket;
53 + }
54 +
55 + if (byte === 0xfe && parser.packetLength() < 9) {
56 + return Packets.EofPacket;
57 + }
58 +
59 + return Packets.RowDataPacket;
60 +};
61 +
62 +Query.prototype['OkPacket'] = function(packet) {
63 + // try...finally for exception safety
64 + try {
65 + if (!this._callback) {
66 + this.emit('result', packet, this._index);
67 + } else {
68 + this._results.push(packet);
69 + this._fields.push(undefined);
70 + }
71 + } finally {
72 + this._index++;
73 + this._resultSet = null;
74 + this._handleFinalResultPacket(packet);
75 + }
76 +};
77 +
78 +Query.prototype['ErrorPacket'] = function(packet) {
79 + var err = this._packetToError(packet);
80 +
81 + var results = (this._results.length > 0)
82 + ? this._results
83 + : undefined;
84 +
85 + var fields = (this._fields.length > 0)
86 + ? this._fields
87 + : undefined;
88 +
89 + err.index = this._index;
90 + err.sql = this.sql;
91 +
92 + this.end(err, results, fields);
93 +};
94 +
95 +Query.prototype['LocalInfileRequestPacket'] = function(packet) {
96 + if (this._connection.config.clientFlags & ClientConstants.CLIENT_LOCAL_FILES) {
97 + this._sendLocalDataFile(packet.filename);
98 + } else {
99 + this._loadError = new Error('Load local files command is disabled');
100 + this._loadError.code = 'LOCAL_FILES_DISABLED';
101 + this._loadError.fatal = false;
102 +
103 + this.emit('packet', new Packets.EmptyPacket());
104 + }
105 +};
106 +
107 +Query.prototype['ResultSetHeaderPacket'] = function(packet) {
108 + this._resultSet = new ResultSet(packet);
109 +};
110 +
111 +Query.prototype['FieldPacket'] = function(packet) {
112 + this._resultSet.fieldPackets.push(packet);
113 +};
114 +
115 +Query.prototype['EofPacket'] = function(packet) {
116 + this._resultSet.eofPackets.push(packet);
117 +
118 + if (this._resultSet.eofPackets.length === 1 && !this._callback) {
119 + this.emit('fields', this._resultSet.fieldPackets, this._index);
120 + }
121 +
122 + if (this._resultSet.eofPackets.length !== 2) {
123 + return;
124 + }
125 +
126 + if (this._callback) {
127 + this._results.push(this._resultSet.rows);
128 + this._fields.push(this._resultSet.fieldPackets);
129 + }
130 +
131 + this._index++;
132 + this._resultSet = null;
133 + this._handleFinalResultPacket(packet);
134 +};
135 +
136 +Query.prototype._handleFinalResultPacket = function(packet) {
137 + if (packet.serverStatus & ServerStatus.SERVER_MORE_RESULTS_EXISTS) {
138 + return;
139 + }
140 +
141 + var results = (this._results.length > 1)
142 + ? this._results
143 + : this._results[0];
144 +
145 + var fields = (this._fields.length > 1)
146 + ? this._fields
147 + : this._fields[0];
148 +
149 + this.end(this._loadError, results, fields);
150 +};
151 +
152 +Query.prototype['RowDataPacket'] = function(packet, parser, connection) {
153 + packet.parse(parser, this._resultSet.fieldPackets, this.typeCast, this.nestTables, connection);
154 +
155 + if (this._callback) {
156 + this._resultSet.rows.push(packet);
157 + } else {
158 + this.emit('result', packet, this._index);
159 + }
160 +};
161 +
162 +Query.prototype._sendLocalDataFile = function(path) {
163 + var self = this;
164 + var localStream = fs.createReadStream(path, {
165 + flag : 'r',
166 + encoding : null,
167 + autoClose : true
168 + });
169 +
170 + this.on('pause', function () {
171 + localStream.pause();
172 + });
173 +
174 + this.on('resume', function () {
175 + localStream.resume();
176 + });
177 +
178 + localStream.on('data', function (data) {
179 + self.emit('packet', new Packets.LocalDataFilePacket(data));
180 + });
181 +
182 + localStream.on('error', function (err) {
183 + self._loadError = err;
184 + localStream.emit('end');
185 + });
186 +
187 + localStream.on('end', function () {
188 + self.emit('packet', new Packets.EmptyPacket());
189 + });
190 +};
191 +
192 +Query.prototype.stream = function(options) {
193 + var self = this;
194 +
195 + options = options || {};
196 + options.objectMode = true;
197 +
198 + var stream = new Readable(options);
199 +
200 + stream._read = function() {
201 + self._connection && self._connection.resume();
202 + };
203 +
204 + stream.once('end', function() {
205 + process.nextTick(function () {
206 + stream.emit('close');
207 + });
208 + });
209 +
210 + this.on('result', function(row, i) {
211 + if (!stream.push(row)) self._connection.pause();
212 + stream.emit('result', row, i); // replicate old emitter
213 + });
214 +
215 + this.on('error', function(err) {
216 + stream.emit('error', err); // Pass on any errors
217 + });
218 +
219 + this.on('end', function() {
220 + stream.push(null); // pushing null, indicating EOF
221 + });
222 +
223 + this.on('fields', function(fields, i) {
224 + stream.emit('fields', fields, i); // replicate old emitter
225 + });
226 +
227 + return stream;
228 +};
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.