This commit is contained in:
2025-10-21 08:10:15 +00:00
commit 8eaf13f445
1983 changed files with 292430 additions and 0 deletions

19
node_modules/mysql2/License generated vendored Normal file
View File

@@ -0,0 +1,19 @@
Copyright (c) 2016 Andrey Sidorov (sidorares@yandex.ru) and contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

114
node_modules/mysql2/README.md generated vendored Normal file
View File

@@ -0,0 +1,114 @@
[npm-image]: https://img.shields.io/npm/v/mysql2.svg
[npm-url]: https://npmjs.com/package/mysql2
[node-version-image]: https://img.shields.io/node/v/mysql2.svg
[node-version-url]: https://nodejs.org/en/download
[downloads-image]: https://img.shields.io/npm/dm/mysql2.svg
[downloads-url]: https://npmjs.com/package/mysql2
[license-url]: https://github.com/sidorares/node-mysql2/blob/master/License
[license-image]: https://img.shields.io/npm/l/mysql2.svg?maxAge=2592000
[node-mysql]: https://github.com/mysqljs/mysql
[mysqljs]: https://github.com/mysqljs
[mysql-native]: https://github.com/sidorares/nodejs-mysql-native
[sidorares]: https://github.com/sidorares
[TooTallNate]: https://gist.github.com/TooTallNate
[starttls.js]: https://gist.github.com/TooTallNate/848444
[node-mariasql]: https://github.com/mscdex/node-mariasql
[contributors]: https://github.com/sidorares/node-mysql2/graphs/contributors
[contributing]: https://github.com/sidorares/node-mysql2/blob/master/Contributing.md
[docs-base]: https://sidorares.github.io/node-mysql2/docs
[docs-base-zh-CN]: https://sidorares.github.io/node-mysql2/zh-CN/docs
[docs-base-pt-BR]: https://sidorares.github.io/node-mysql2/pt-BR/docs
[docs-prepared-statements]: https://sidorares.github.io/node-mysql2/docs/documentation/prepared-statements
[docs-mysql-server]: https://sidorares.github.io/node-mysql2/docs/documentation/mysql-server
[docs-promise-wrapper]: https://sidorares.github.io/node-mysql2/docs/documentation/promise-wrapper
[docs-authentication-switch]: https://sidorares.github.io/node-mysql2/docs/documentation/authentication-switch
[docs-streams]: https://sidorares.github.io/node-mysql2/docs/documentation/extras
[docs-typescript-docs]: https://sidorares.github.io/node-mysql2/docs/documentation/typescript-examples
[docs-qs-pooling]: https://sidorares.github.io/node-mysql2/docs#using-connection-pools
[docs-qs-first-query]: https://sidorares.github.io/node-mysql2/docs#first-query
[docs-qs-using-prepared-statements]: https://sidorares.github.io/node-mysql2/docs#using-prepared-statements
[docs-examples]: https://sidorares.github.io/node-mysql2/docs/examples
[docs-faq]: https://sidorares.github.io/node-mysql2/docs/faq
[docs-documentation]: https://sidorares.github.io/node-mysql2/docs/documentation
[docs-contributing]: https://sidorares.github.io/node-mysql2/docs/contributing/website
[coverage]: https://img.shields.io/codecov/c/github/sidorares/node-mysql2
[coverage-url]: https://app.codecov.io/github/sidorares/node-mysql2
[ci-url]: https://github.com/sidorares/node-mysql2/actions/workflows/ci-coverage.yml?query=branch%3Amaster
[ci-image]: https://img.shields.io/github/actions/workflow/status/sidorares/node-mysql2/ci-coverage.yml?event=push&style=flat&label=CI&branch=master
# MySQL2
[![NPM Version][npm-image]][npm-url]
[![NPM Downloads][downloads-image]][downloads-url]
[![Node.js Version][node-version-image]][node-version-url]
[![GitHub Workflow Status (with event)][ci-image]][ci-url]
[![Codecov][coverage]][coverage-url]
[![License][license-image]][license-url]
[English][docs-base] | [简体中文][docs-base-zh-CN] | [Português (BR)][docs-base-pt-BR]
> MySQL client for Node.js with focus on performance. Supports prepared statements, non-utf8 encodings, binary log protocol, compression, ssl [much more][docs-documentation].
**Table of Contents**
- [History and Why MySQL2](#history-and-why-mysql2)
- [Installation](#installation)
- [Documentation](#documentation)
- [Acknowledgements](#acknowledgements)
- [Contributing](#contributing)
## History and Why MySQL2
MySQL2 project is a continuation of [MySQL-Native][mysql-native]. Protocol parser code was rewritten from scratch and api changed to match popular [Node MySQL][node-mysql]. MySQL2 team is working together with [Node MySQL][node-mysql] team to factor out shared code and move it under [mysqljs][mysqljs] organization.
MySQL2 is mostly API compatible with [Node MySQL][node-mysql] and supports majority of features. MySQL2 also offers these additional features:
- Faster / Better Performance
- [Prepared Statements][docs-prepared-statements]
- MySQL Binary Log Protocol
- [MySQL Server][docs-mysql-server]
- Extended support for Encoding and Collation
- [Promise Wrapper][docs-promise-wrapper]
- Compression
- SSL and [Authentication Switch][docs-authentication-switch]
- [Custom Streams][docs-streams]
- [Pooling][docs-qs-pooling]
## Installation
MySQL2 is free from native bindings and can be installed on Linux, Mac OS or Windows without any issues.
```bash
npm install --save mysql2
```
If you are using TypeScript, you will need to install `@types/node`.
```bash
npm install --save-dev @types/node
```
> For TypeScript documentation and examples, see [here][docs-typescript-docs].
## Documentation
- [Quickstart][docs-base]
- [First Query][docs-qs-first-query], [Using Prepared Statements][docs-qs-using-prepared-statements], [Using Connection Pools][docs-qs-pooling] and more.
- [Documentation][docs-documentation]
- [Examples][docs-examples]
- [FAQ][docs-faq]
## Acknowledgements
- Internal protocol is written by [@sidorares][sidorares] [MySQL-Native][mysql-native].
- Constants, SQL parameters interpolation, Pooling, `ConnectionConfig` class taken from [Node MySQL][node-mysql].
- SSL upgrade code based on [@TooTallNate][TooTallNate] [code][starttls.js].
- Secure connection / compressed connection api flags compatible to [MariaSQL][node-mariasql] client.
- [Contributors][contributors].
## Contributing
Want to improve something in **MySQL2**?
Please check [Contributing.md][contributing] for detailed instruction on how to get started.
To contribute in **MySQL2 Documentation**, please visit the [Website Contributing Guidelines][docs-contributing] for detailed instruction on how to get started.

1
node_modules/mysql2/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1 @@
export * from './typings/mysql/index.js';

77
node_modules/mysql2/index.js generated vendored Normal file
View File

@@ -0,0 +1,77 @@
'use strict';
const SqlString = require('sqlstring');
const ConnectionConfig = require('./lib/connection_config.js');
const parserCache = require('./lib/parsers/parser_cache.js');
const Connection = require('./lib/connection.js');
exports.createConnection = require('./lib/create_connection.js');
exports.connect = exports.createConnection;
exports.Connection = Connection;
exports.ConnectionConfig = ConnectionConfig;
const Pool = require('./lib/pool.js');
const PoolCluster = require('./lib/pool_cluster.js');
const createPool = require('./lib/create_pool.js');
const createPoolCluster = require('./lib/create_pool_cluster.js');
exports.createPool = createPool;
exports.createPoolCluster = createPoolCluster;
exports.createQuery = Connection.createQuery;
exports.Pool = Pool;
exports.PoolCluster = PoolCluster;
exports.createServer = function (handler) {
const Server = require('./lib/server.js');
const s = new Server();
if (handler) {
s.on('connection', handler);
}
return s;
};
exports.PoolConnection = require('./lib/pool_connection.js');
exports.authPlugins = require('./lib/auth_plugins');
exports.escape = SqlString.escape;
exports.escapeId = SqlString.escapeId;
exports.format = SqlString.format;
exports.raw = SqlString.raw;
exports.__defineGetter__(
'createConnectionPromise',
() => require('./promise.js').createConnection
);
exports.__defineGetter__(
'createPoolPromise',
() => require('./promise.js').createPool
);
exports.__defineGetter__(
'createPoolClusterPromise',
() => require('./promise.js').createPoolCluster
);
exports.__defineGetter__('Types', () => require('./lib/constants/types.js'));
exports.__defineGetter__('Charsets', () =>
require('./lib/constants/charsets.js')
);
exports.__defineGetter__('CharsetToEncoding', () =>
require('./lib/constants/charset_encodings.js')
);
exports.setMaxParserCache = function (max) {
parserCache.setMaxCache(max);
};
exports.clearParserCache = function () {
parserCache.clearCache();
};

95
node_modules/mysql2/lib/auth_41.js generated vendored Normal file
View File

@@ -0,0 +1,95 @@
'use strict';
/*
4.1 authentication: (http://bazaar.launchpad.net/~mysql/mysql-server/5.5/view/head:/sql/password.c)
SERVER: public_seed=create_random_string()
send(public_seed)
CLIENT: recv(public_seed)
hash_stage1=sha1("password")
hash_stage2=sha1(hash_stage1)
reply=xor(hash_stage1, sha1(public_seed,hash_stage2)
// this three steps are done in scramble()
send(reply)
SERVER: recv(reply)
hash_stage1=xor(reply, sha1(public_seed,hash_stage2))
candidate_hash2=sha1(hash_stage1)
check(candidate_hash2==hash_stage2)
server stores sha1(sha1(password)) ( hash_stag2)
*/
const crypto = require('crypto');
function sha1(msg, msg1, msg2) {
const hash = crypto.createHash('sha1');
hash.update(msg);
if (msg1) {
hash.update(msg1);
}
if (msg2) {
hash.update(msg2);
}
return hash.digest();
}
function xor(a, b) {
const result = Buffer.allocUnsafe(a.length);
for (let i = 0; i < a.length; i++) {
result[i] = a[i] ^ b[i];
}
return result;
}
exports.xor = xor;
function token(password, scramble1, scramble2) {
if (!password) {
return Buffer.alloc(0);
}
const stage1 = sha1(password);
return exports.calculateTokenFromPasswordSha(stage1, scramble1, scramble2);
}
exports.calculateTokenFromPasswordSha = function (
passwordSha,
scramble1,
scramble2
) {
// we use AUTH 41 here, and we need only the bytes we just need.
const authPluginData1 = scramble1.slice(0, 8);
const authPluginData2 = scramble2.slice(0, 12);
const stage2 = sha1(passwordSha);
const stage3 = sha1(authPluginData1, authPluginData2, stage2);
return xor(stage3, passwordSha);
};
exports.calculateToken = token;
exports.verifyToken = function (publicSeed1, publicSeed2, token, doubleSha) {
const hashStage1 = xor(token, sha1(publicSeed1, publicSeed2, doubleSha));
const candidateHash2 = sha1(hashStage1);
return candidateHash2.compare(doubleSha) === 0;
};
exports.doubleSha1 = function (password) {
return sha1(sha1(password));
};
function xorRotating(a, seed) {
const result = Buffer.allocUnsafe(a.length);
const seedLen = seed.length;
for (let i = 0; i < a.length; i++) {
result[i] = a[i] ^ seed[i % seedLen];
}
return result;
}
exports.xorRotating = xorRotating;

View File

@@ -0,0 +1,108 @@
'use strict';
// https://mysqlserverteam.com/mysql-8-0-4-new-default-authentication-plugin-caching_sha2_password/
const PLUGIN_NAME = 'caching_sha2_password';
const crypto = require('crypto');
const { xor, xorRotating } = require('../auth_41');
const REQUEST_SERVER_KEY_PACKET = Buffer.from([2]);
const FAST_AUTH_SUCCESS_PACKET = Buffer.from([3]);
const PERFORM_FULL_AUTHENTICATION_PACKET = Buffer.from([4]);
const STATE_INITIAL = 0;
const STATE_TOKEN_SENT = 1;
const STATE_WAIT_SERVER_KEY = 2;
const STATE_FINAL = -1;
function sha256(msg) {
const hash = crypto.createHash('sha256');
hash.update(msg);
return hash.digest();
}
function calculateToken(password, scramble) {
if (!password) {
return Buffer.alloc(0);
}
const stage1 = sha256(Buffer.from(password));
const stage2 = sha256(stage1);
const stage3 = sha256(Buffer.concat([stage2, scramble]));
return xor(stage1, stage3);
}
function encrypt(password, scramble, key) {
const stage1 = xorRotating(Buffer.from(`${password}\0`, 'utf8'), scramble);
return crypto.publicEncrypt(
{
key,
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
},
stage1
);
}
module.exports =
(pluginOptions = {}) =>
({ connection }) => {
let state = 0;
let scramble = null;
const password = connection.config.password;
const authWithKey = (serverKey) => {
const _password = encrypt(password, scramble, serverKey);
state = STATE_FINAL;
return _password;
};
return (data) => {
switch (state) {
case STATE_INITIAL:
scramble = data.slice(0, 20);
state = STATE_TOKEN_SENT;
return calculateToken(password, scramble);
case STATE_TOKEN_SENT:
if (FAST_AUTH_SUCCESS_PACKET.equals(data)) {
state = STATE_FINAL;
return null;
}
if (PERFORM_FULL_AUTHENTICATION_PACKET.equals(data)) {
const isSecureConnection =
typeof pluginOptions.overrideIsSecure === 'undefined'
? connection.config.ssl || connection.config.socketPath
: pluginOptions.overrideIsSecure;
if (isSecureConnection) {
state = STATE_FINAL;
return Buffer.from(`${password}\0`, 'utf8');
}
// if client provides key we can save one extra roundrip on first connection
if (pluginOptions.serverPublicKey) {
return authWithKey(pluginOptions.serverPublicKey);
}
state = STATE_WAIT_SERVER_KEY;
return REQUEST_SERVER_KEY_PACKET;
}
throw new Error(
`Invalid AuthMoreData packet received by ${PLUGIN_NAME} plugin in STATE_TOKEN_SENT state.`
);
case STATE_WAIT_SERVER_KEY:
if (pluginOptions.onServerPublicKey) {
pluginOptions.onServerPublicKey(data);
}
return authWithKey(data);
case STATE_FINAL:
throw new Error(
`Unexpected data in AuthMoreData packet received by ${PLUGIN_NAME} plugin in STATE_FINAL state.`
);
}
throw new Error(
`Unexpected data in AuthMoreData packet received by ${PLUGIN_NAME} plugin in state ${state}`
);
};
};

View File

@@ -0,0 +1,18 @@
##
https://dev.mysql.com/doc/refman/8.0/en/caching-sha2-pluggable-authentication.html
```js
const mysql = require('mysql');
mysql.createConnection({
authPlugins: {
caching_sha2_password: mysql.authPlugins.caching_sha2_password({
onServerPublikKey: function (key) {
console.log(key);
},
serverPublicKey: 'xxxyyy',
overrideIsSecure: true, //
}),
},
});
```

8
node_modules/mysql2/lib/auth_plugins/index.js generated vendored Normal file
View File

@@ -0,0 +1,8 @@
'use strict';
module.exports = {
caching_sha2_password: require('./caching_sha2_password'),
mysql_clear_password: require('./mysql_clear_password'),
mysql_native_password: require('./mysql_native_password'),
sha256_password: require('./sha256_password'),
};

View File

@@ -0,0 +1,17 @@
'use strict';
function bufferFromStr(str) {
return Buffer.from(`${str}\0`);
}
const create_mysql_clear_password_plugin = (pluginOptions) =>
function mysql_clear_password_plugin({ connection, command }) {
const password =
command.password || pluginOptions.password || connection.config.password;
return function (/* pluginData */) {
return bufferFromStr(password);
};
};
module.exports = create_mysql_clear_password_plugin;

View File

@@ -0,0 +1,34 @@
'use strict';
//const PLUGIN_NAME = 'mysql_native_password';
const auth41 = require('../auth_41.js');
module.exports =
(pluginOptions) =>
({ connection, command }) => {
const password =
command.password || pluginOptions.password || connection.config.password;
const passwordSha1 =
command.passwordSha1 ||
pluginOptions.passwordSha1 ||
connection.config.passwordSha1;
return (data) => {
const authPluginData1 = data.slice(0, 8);
const authPluginData2 = data.slice(8, 20);
let authToken;
if (passwordSha1) {
authToken = auth41.calculateTokenFromPasswordSha(
passwordSha1,
authPluginData1,
authPluginData2
);
} else {
authToken = auth41.calculateToken(
password,
authPluginData1,
authPluginData2
);
}
return authToken;
};
};

View File

@@ -0,0 +1,68 @@
'use strict';
const PLUGIN_NAME = 'sha256_password';
const crypto = require('crypto');
const { xorRotating } = require('../auth_41');
const Tls = require('tls');
const REQUEST_SERVER_KEY_PACKET = Buffer.from([1]);
const STATE_INITIAL = 0;
const STATE_WAIT_SERVER_KEY = 1;
const STATE_FINAL = -1;
function encrypt(password, scramble, key) {
const stage1 = xorRotating(Buffer.from(`${password}\0`, 'utf8'), scramble);
return crypto.publicEncrypt(key, stage1);
}
module.exports =
(pluginOptions = {}) =>
({ connection }) => {
let state = 0;
let scramble = null;
const password = connection.config.password;
const authWithKey = (serverKey) => {
const _password = encrypt(password, scramble, serverKey);
state = STATE_FINAL;
return _password;
};
return (data) => {
switch (state) {
case STATE_INITIAL:
if (
connection.stream instanceof Tls.TLSSocket &&
connection.stream.encrypted === true
) {
// We don't need to encrypt passwords over TLS connection
return Buffer.from(`${password}\0`, 'utf8');
}
scramble = data.slice(0, 20);
// if client provides key we can save one extra roundrip on first connection
if (pluginOptions.serverPublicKey) {
return authWithKey(pluginOptions.serverPublicKey);
}
state = STATE_WAIT_SERVER_KEY;
return REQUEST_SERVER_KEY_PACKET;
case STATE_WAIT_SERVER_KEY:
if (pluginOptions.onServerPublicKey) {
pluginOptions.onServerPublicKey(data);
}
return authWithKey(data);
case STATE_FINAL:
throw new Error(
`Unexpected data in AuthMoreData packet received by ${PLUGIN_NAME} plugin in STATE_FINAL state.`
);
}
throw new Error(
`Unexpected data in AuthMoreData packet received by ${PLUGIN_NAME} plugin in state ${state}`
);
};
};

945
node_modules/mysql2/lib/base/connection.js generated vendored Normal file
View File

@@ -0,0 +1,945 @@
// This file was modified by Oracle on June 1, 2021.
// The changes involve new logic to handle an additional ERR Packet sent by
// the MySQL server when the connection is closed unexpectedly.
// Modifications copyright (c) 2021, Oracle and/or its affiliates.
// This file was modified by Oracle on June 17, 2021.
// The changes involve logic to ensure the socket connection is closed when
// there is a fatal error.
// Modifications copyright (c) 2021, Oracle and/or its affiliates.
// This file was modified by Oracle on September 21, 2021.
// The changes involve passing additional authentication factor passwords
// to the ChangeUser Command instance.
// Modifications copyright (c) 2021, Oracle and/or its affiliates.
'use strict';
const Net = require('net');
const Tls = require('tls');
const Timers = require('timers');
const EventEmitter = require('events').EventEmitter;
const Readable = require('stream').Readable;
const Queue = require('denque');
const SqlString = require('sqlstring');
const { createLRU } = require('lru.min');
const PacketParser = require('../packet_parser.js');
const Packets = require('../packets/index.js');
const Commands = require('../commands/index.js');
const ConnectionConfig = require('../connection_config.js');
const CharsetToEncoding = require('../constants/charset_encodings.js');
let _connectionId = 0;
let convertNamedPlaceholders = null;
class BaseConnection extends EventEmitter {
constructor(opts) {
super();
this.config = opts.config;
// TODO: fill defaults
// if no params, connect to /var/lib/mysql/mysql.sock ( /tmp/mysql.sock on OSX )
// if host is given, connect to host:3306
// TODO: use `/usr/local/mysql/bin/mysql_config --socket` output? as default socketPath
// if there is no host/port and no socketPath parameters?
if (!opts.config.stream) {
if (opts.config.socketPath) {
this.stream = Net.connect(opts.config.socketPath);
} else {
this.stream = Net.connect(opts.config.port, opts.config.host);
// Optionally enable keep-alive on the socket.
if (this.config.enableKeepAlive) {
this.stream.on('connect', () => {
this.stream.setKeepAlive(true, this.config.keepAliveInitialDelay);
});
}
// Enable TCP_NODELAY flag. This is needed so that the network packets
// are sent immediately to the server
this.stream.setNoDelay(true);
}
// if stream is a function, treat it as "stream agent / factory"
} else if (typeof opts.config.stream === 'function') {
this.stream = opts.config.stream(opts);
} else {
this.stream = opts.config.stream;
}
this._internalId = _connectionId++;
this._commands = new Queue();
this._command = null;
this._paused = false;
this._paused_packets = new Queue();
this._statements = createLRU({
max: this.config.maxPreparedStatements,
onEviction: function (_, statement) {
statement.close();
},
});
this.serverCapabilityFlags = 0;
this.authorized = false;
this.sequenceId = 0;
this.compressedSequenceId = 0;
this.threadId = null;
this._handshakePacket = null;
this._fatalError = null;
this._protocolError = null;
this._outOfOrderPackets = [];
this.clientEncoding = CharsetToEncoding[this.config.charsetNumber];
this.stream.on('error', this._handleNetworkError.bind(this));
// see https://gist.github.com/khoomeister/4985691#use-that-instead-of-bind
this.packetParser = new PacketParser((p) => {
this.handlePacket(p);
});
this.stream.on('data', (data) => {
if (this.connectTimeout) {
Timers.clearTimeout(this.connectTimeout);
this.connectTimeout = null;
}
this.packetParser.execute(data);
});
this.stream.on('end', () => {
// emit the end event so that the pooled connection can close the connection
this.emit('end');
});
this.stream.on('close', () => {
// we need to set this flag everywhere where we want connection to close
if (this._closing) {
return;
}
if (!this._protocolError) {
// no particular error message before disconnect
this._protocolError = new Error(
'Connection lost: The server closed the connection.'
);
this._protocolError.fatal = true;
this._protocolError.code = 'PROTOCOL_CONNECTION_LOST';
}
this._notifyError(this._protocolError);
});
let handshakeCommand;
if (!this.config.isServer) {
handshakeCommand = new Commands.ClientHandshake(this.config.clientFlags);
handshakeCommand.on('end', () => {
// this happens when handshake finishes early either because there was
// some fatal error or the server sent an error packet instead of
// an hello packet (for example, 'Too many connections' error)
if (
!handshakeCommand.handshake ||
this._fatalError ||
this._protocolError
) {
return;
}
this._handshakePacket = handshakeCommand.handshake;
this.threadId = handshakeCommand.handshake.connectionId;
this.emit('connect', handshakeCommand.handshake);
});
handshakeCommand.on('error', (err) => {
this._closing = true;
this._notifyError(err);
});
this.addCommand(handshakeCommand);
}
// in case there was no initial handshake but we need to read sting, assume it utf-8
// most common example: "Too many connections" error ( packet is sent immediately on connection attempt, we don't know server encoding yet)
// will be overwritten with actual encoding value as soon as server handshake packet is received
this.serverEncoding = 'utf8';
if (this.config.connectTimeout) {
const timeoutHandler = this._handleTimeoutError.bind(this);
this.connectTimeout = Timers.setTimeout(
timeoutHandler,
this.config.connectTimeout
);
}
}
_addCommandClosedState(cmd) {
const err = new Error(
"Can't add new command when connection is in closed state"
);
err.fatal = true;
if (cmd.onResult) {
cmd.onResult(err);
} else {
this.emit('error', err);
}
}
_handleFatalError(err) {
err.fatal = true;
// stop receiving packets
this.stream.removeAllListeners('data');
this.addCommand = this._addCommandClosedState;
this.write = () => {
this.emit('error', new Error("Can't write in closed state"));
};
this._notifyError(err);
this._fatalError = err;
}
_handleNetworkError(err) {
if (this.connectTimeout) {
Timers.clearTimeout(this.connectTimeout);
this.connectTimeout = null;
}
// Do not throw an error when a connection ends with a RST,ACK packet
if (err.code === 'ECONNRESET' && this._closing) {
return;
}
this._handleFatalError(err);
}
_handleTimeoutError() {
if (this.connectTimeout) {
Timers.clearTimeout(this.connectTimeout);
this.connectTimeout = null;
}
this.stream.destroy && this.stream.destroy();
const err = new Error('connect ETIMEDOUT');
err.errorno = 'ETIMEDOUT';
err.code = 'ETIMEDOUT';
err.syscall = 'connect';
this._handleNetworkError(err);
}
// notify all commands in the queue and bubble error as connection "error"
// called on stream error or unexpected termination
_notifyError(err) {
if (this.connectTimeout) {
Timers.clearTimeout(this.connectTimeout);
this.connectTimeout = null;
}
// prevent from emitting 'PROTOCOL_CONNECTION_LOST' after EPIPE or ECONNRESET
if (this._fatalError) {
return;
}
let command;
// if there is no active command, notify connection
// if there are commands and all of them have callbacks, pass error via callback
let bubbleErrorToConnection = !this._command;
if (this._command && this._command.onResult) {
this._command.onResult(err);
this._command = null;
// connection handshake is special because we allow it to be implicit
// if error happened during handshake, but there are others commands in queue
// then bubble error to other commands and not to connection
} else if (
!(
this._command &&
this._command.constructor === Commands.ClientHandshake &&
this._commands.length > 0
)
) {
bubbleErrorToConnection = true;
}
while ((command = this._commands.shift())) {
if (command.onResult) {
command.onResult(err);
} else {
bubbleErrorToConnection = true;
}
}
// notify connection if some comands in the queue did not have callbacks
// or if this is pool connection ( so it can be removed from pool )
if (bubbleErrorToConnection || this._pool) {
this.emit('error', err);
}
// close connection after emitting the event in case of a fatal error
if (err.fatal) {
this.close();
}
}
write(buffer) {
const result = this.stream.write(buffer, (err) => {
if (err) {
this._handleNetworkError(err);
}
});
if (!result) {
this.stream.emit('pause');
}
}
// http://dev.mysql.com/doc/internals/en/sequence-id.html
//
// The sequence-id is incremented with each packet and may wrap around.
// It starts at 0 and is reset to 0 when a new command
// begins in the Command Phase.
// http://dev.mysql.com/doc/internals/en/example-several-mysql-packets.html
_resetSequenceId() {
this.sequenceId = 0;
this.compressedSequenceId = 0;
}
_bumpCompressedSequenceId(numPackets) {
this.compressedSequenceId += numPackets;
this.compressedSequenceId %= 256;
}
_bumpSequenceId(numPackets) {
this.sequenceId += numPackets;
this.sequenceId %= 256;
}
writePacket(packet) {
const MAX_PACKET_LENGTH = 16777215;
const length = packet.length();
let chunk, offset, header;
if (length < MAX_PACKET_LENGTH) {
packet.writeHeader(this.sequenceId);
if (this.config.debug) {
console.log(
`${this._internalId} ${this.connectionId} <== ${this._command._commandName}#${this._command.stateName()}(${[this.sequenceId, packet._name, packet.length()].join(',')})`
);
console.log(
`${this._internalId} ${this.connectionId} <== ${packet.buffer.toString('hex')}`
);
}
this._bumpSequenceId(1);
this.write(packet.buffer);
} else {
if (this.config.debug) {
console.log(
`${this._internalId} ${this.connectionId} <== Writing large packet, raw content not written:`
);
console.log(
`${this._internalId} ${this.connectionId} <== ${this._command._commandName}#${this._command.stateName()}(${[this.sequenceId, packet._name, packet.length()].join(',')})`
);
}
for (offset = 4; offset < 4 + length; offset += MAX_PACKET_LENGTH) {
chunk = packet.buffer.slice(offset, offset + MAX_PACKET_LENGTH);
if (chunk.length === MAX_PACKET_LENGTH) {
header = Buffer.from([0xff, 0xff, 0xff, this.sequenceId]);
} else {
header = Buffer.from([
chunk.length & 0xff,
(chunk.length >> 8) & 0xff,
(chunk.length >> 16) & 0xff,
this.sequenceId,
]);
}
this._bumpSequenceId(1);
this.write(header);
this.write(chunk);
}
}
}
// 0.11+ environment
startTLS(onSecure) {
if (this.config.debug) {
console.log('Upgrading connection to TLS');
}
const secureContext = Tls.createSecureContext({
ca: this.config.ssl.ca,
cert: this.config.ssl.cert,
ciphers: this.config.ssl.ciphers,
key: this.config.ssl.key,
passphrase: this.config.ssl.passphrase,
minVersion: this.config.ssl.minVersion,
maxVersion: this.config.ssl.maxVersion,
});
const rejectUnauthorized = this.config.ssl.rejectUnauthorized;
const verifyIdentity = this.config.ssl.verifyIdentity;
const servername = this.config.host;
let secureEstablished = false;
this.stream.removeAllListeners('data');
const secureSocket = Tls.connect(
{
rejectUnauthorized,
requestCert: rejectUnauthorized,
checkServerIdentity: verifyIdentity
? Tls.checkServerIdentity
: function () {
return undefined;
},
secureContext,
isServer: false,
socket: this.stream,
servername,
},
() => {
secureEstablished = true;
if (rejectUnauthorized) {
if (typeof servername === 'string' && verifyIdentity) {
const cert = secureSocket.getPeerCertificate(true);
const serverIdentityCheckError = Tls.checkServerIdentity(
servername,
cert
);
if (serverIdentityCheckError) {
onSecure(serverIdentityCheckError);
return;
}
}
}
onSecure();
}
);
// error handler for secure socket
secureSocket.on('error', (err) => {
if (secureEstablished) {
this._handleNetworkError(err);
} else {
onSecure(err);
}
});
secureSocket.on('data', (data) => {
this.packetParser.execute(data);
});
this.stream = secureSocket;
}
protocolError(message, code) {
// Starting with MySQL 8.0.24, if the client closes the connection
// unexpectedly, the server will send a last ERR Packet, which we can
// safely ignore.
// https://dev.mysql.com/worklog/task/?id=12999
if (this._closing) {
return;
}
const err = new Error(message);
err.fatal = true;
err.code = code || 'PROTOCOL_ERROR';
this.emit('error', err);
}
get fatalError() {
return this._fatalError;
}
handlePacket(packet) {
if (this._paused) {
this._paused_packets.push(packet);
return;
}
if (this.config.debug) {
if (packet) {
console.log(
` raw: ${packet.buffer
.slice(packet.offset, packet.offset + packet.length())
.toString('hex')}`
);
console.trace();
const commandName = this._command
? this._command._commandName
: '(no command)';
const stateName = this._command
? this._command.stateName()
: '(no command)';
console.log(
`${this._internalId} ${this.connectionId} ==> ${commandName}#${stateName}(${[packet.sequenceId, packet.type(), packet.length()].join(',')})`
);
}
}
if (!this._command) {
const marker = packet.peekByte();
// If it's an Err Packet, we should use it.
if (marker === 0xff) {
const error = Packets.Error.fromPacket(packet);
this.protocolError(error.message, error.code);
} else {
// Otherwise, it means it's some other unexpected packet.
this.protocolError(
'Unexpected packet while no commands in the queue',
'PROTOCOL_UNEXPECTED_PACKET'
);
}
this.close();
return;
}
if (packet) {
// Note: when server closes connection due to inactivity, Err packet ER_CLIENT_INTERACTION_TIMEOUT from MySQL 8.0.24, sequenceId will be 0
if (this.sequenceId !== packet.sequenceId) {
const err = new Error(
`Warning: got packets out of order. Expected ${this.sequenceId} but received ${packet.sequenceId}`
);
err.expected = this.sequenceId;
err.received = packet.sequenceId;
this.emit('warn', err); // REVIEW
console.error(err.message);
}
this._bumpSequenceId(packet.numPackets);
}
try {
if (this._fatalError) {
// skip remaining packets after client is in the error state
return;
}
const done = this._command.execute(packet, this);
if (done) {
this._command = this._commands.shift();
if (this._command) {
this.sequenceId = 0;
this.compressedSequenceId = 0;
this.handlePacket();
}
}
} catch (err) {
this._handleFatalError(err);
this.stream.destroy();
}
}
addCommand(cmd) {
// this.compressedSequenceId = 0;
// this.sequenceId = 0;
if (this.config.debug) {
const commandName = cmd.constructor.name;
console.log(`Add command: ${commandName}`);
cmd._commandName = commandName;
}
if (!this._command) {
this._command = cmd;
this.handlePacket();
} else {
this._commands.push(cmd);
}
return cmd;
}
format(sql, values) {
if (typeof this.config.queryFormat === 'function') {
return this.config.queryFormat.call(
this,
sql,
values,
this.config.timezone
);
}
const opts = {
sql: sql,
values: values,
};
this._resolveNamedPlaceholders(opts);
return SqlString.format(
opts.sql,
opts.values,
this.config.stringifyObjects,
this.config.timezone
);
}
escape(value) {
return SqlString.escape(value, false, this.config.timezone);
}
escapeId(value) {
return SqlString.escapeId(value, false);
}
raw(sql) {
return SqlString.raw(sql);
}
_resolveNamedPlaceholders(options) {
let unnamed;
if (this.config.namedPlaceholders || options.namedPlaceholders) {
if (Array.isArray(options.values)) {
// if an array is provided as the values, assume the conversion is not necessary.
// this allows the usage of unnamed placeholders even if the namedPlaceholders flag is enabled.
return;
}
if (convertNamedPlaceholders === null) {
convertNamedPlaceholders = require('named-placeholders')();
}
unnamed = convertNamedPlaceholders(options.sql, options.values);
options.sql = unnamed[0];
options.values = unnamed[1];
}
}
query(sql, values, cb) {
let cmdQuery;
if (sql.constructor === Commands.Query) {
cmdQuery = sql;
} else {
cmdQuery = BaseConnection.createQuery(sql, values, cb, this.config);
}
this._resolveNamedPlaceholders(cmdQuery);
const rawSql = this.format(
cmdQuery.sql,
cmdQuery.values !== undefined ? cmdQuery.values : []
);
cmdQuery.sql = rawSql;
return this.addCommand(cmdQuery);
}
pause() {
this._paused = true;
this.stream.pause();
}
resume() {
let packet;
this._paused = false;
while ((packet = this._paused_packets.shift())) {
this.handlePacket(packet);
// don't resume if packet handler paused connection
if (this._paused) {
return;
}
}
this.stream.resume();
}
// TODO: named placeholders support
prepare(options, cb) {
if (typeof options === 'string') {
options = { sql: options };
}
return this.addCommand(new Commands.Prepare(options, cb));
}
unprepare(sql) {
let options = {};
if (typeof sql === 'object') {
options = sql;
} else {
options.sql = sql;
}
const key = BaseConnection.statementKey(options);
const stmt = this._statements.get(key);
if (stmt) {
this._statements.delete(key);
stmt.close();
}
return stmt;
}
execute(sql, values, cb) {
let options = {
infileStreamFactory: this.config.infileStreamFactory,
};
if (typeof sql === 'object') {
// execute(options, cb)
options = {
...options,
...sql,
sql: sql.sql,
values: sql.values,
};
if (typeof values === 'function') {
cb = values;
} else {
options.values = options.values || values;
}
} else if (typeof values === 'function') {
// execute(sql, cb)
cb = values;
options.sql = sql;
options.values = undefined;
} else {
// execute(sql, values, cb)
options.sql = sql;
options.values = values;
}
this._resolveNamedPlaceholders(options);
// check for values containing undefined
if (options.values) {
//If namedPlaceholder is not enabled and object is passed as bind parameters
if (!Array.isArray(options.values)) {
throw new TypeError(
'Bind parameters must be array if namedPlaceholders parameter is not enabled'
);
}
options.values.forEach((val) => {
//If namedPlaceholder is not enabled and object is passed as bind parameters
if (!Array.isArray(options.values)) {
throw new TypeError(
'Bind parameters must be array if namedPlaceholders parameter is not enabled'
);
}
if (val === undefined) {
throw new TypeError(
'Bind parameters must not contain undefined. To pass SQL NULL specify JS null'
);
}
if (typeof val === 'function') {
throw new TypeError(
'Bind parameters must not contain function(s). To pass the body of a function as a string call .toString() first'
);
}
});
}
const executeCommand = new Commands.Execute(options, cb);
const prepareCommand = new Commands.Prepare(options, (err, stmt) => {
if (err) {
// skip execute command if prepare failed, we have main
// combined callback here
executeCommand.start = function () {
return null;
};
if (cb) {
cb(err);
} else {
executeCommand.emit('error', err);
}
executeCommand.emit('end');
return;
}
executeCommand.statement = stmt;
});
this.addCommand(prepareCommand);
this.addCommand(executeCommand);
return executeCommand;
}
changeUser(options, callback) {
if (!callback && typeof options === 'function') {
callback = options;
options = {};
}
const charsetNumber = options.charset
? ConnectionConfig.getCharsetNumber(options.charset)
: this.config.charsetNumber;
return this.addCommand(
new Commands.ChangeUser(
{
user: options.user || this.config.user,
// for the purpose of multi-factor authentication, or not, the main
// password (used for the 1st authentication factor) can also be
// provided via the "password1" option
password:
options.password ||
options.password1 ||
this.config.password ||
this.config.password1,
password2: options.password2 || this.config.password2,
password3: options.password3 || this.config.password3,
passwordSha1: options.passwordSha1 || this.config.passwordSha1,
database: options.database || this.config.database,
timeout: options.timeout,
charsetNumber: charsetNumber,
currentConfig: this.config,
},
(err) => {
if (err) {
err.fatal = true;
}
if (callback) {
callback(err);
}
}
)
);
}
// transaction helpers
beginTransaction(cb) {
return this.query('START TRANSACTION', cb);
}
commit(cb) {
return this.query('COMMIT', cb);
}
rollback(cb) {
return this.query('ROLLBACK', cb);
}
ping(cb) {
return this.addCommand(new Commands.Ping(cb));
}
_registerSlave(opts, cb) {
return this.addCommand(new Commands.RegisterSlave(opts, cb));
}
_binlogDump(opts, cb) {
return this.addCommand(new Commands.BinlogDump(opts, cb));
}
// currently just alias to close
destroy() {
this.close();
}
close() {
if (this.connectTimeout) {
Timers.clearTimeout(this.connectTimeout);
this.connectTimeout = null;
}
this._closing = true;
this.stream.end();
this.addCommand = this._addCommandClosedState;
}
createBinlogStream(opts) {
// TODO: create proper stream class
// TODO: use through2
let test = 1;
const stream = new Readable({ objectMode: true });
stream._read = function () {
return {
data: test++,
};
};
this._registerSlave(opts, () => {
const dumpCmd = this._binlogDump(opts);
dumpCmd.on('event', (ev) => {
stream.push(ev);
});
dumpCmd.on('eof', () => {
stream.push(null);
// if non-blocking, then close stream to prevent errors
if (opts.flags && opts.flags & 0x01) {
this.close();
}
});
// TODO: pipe errors as well
});
return stream;
}
connect(cb) {
if (!cb) {
return;
}
if (this._fatalError || this._protocolError) {
return cb(this._fatalError || this._protocolError);
}
if (this._handshakePacket) {
return cb(null, this);
}
let connectCalled = 0;
function callbackOnce(isErrorHandler) {
return function (param) {
if (!connectCalled) {
if (isErrorHandler) {
cb(param);
} else {
cb(null, param);
}
}
connectCalled = 1;
};
}
this.once('error', callbackOnce(true));
this.once('connect', callbackOnce(false));
}
// ===================================
// outgoing server connection methods
// ===================================
writeColumns(columns) {
this.writePacket(Packets.ResultSetHeader.toPacket(columns.length));
columns.forEach((column) => {
this.writePacket(
Packets.ColumnDefinition.toPacket(column, this.serverConfig.encoding)
);
});
this.writeEof();
}
// row is array of columns, not hash
writeTextRow(column) {
this.writePacket(
Packets.TextRow.toPacket(column, this.serverConfig.encoding)
);
}
writeBinaryRow(column) {
this.writePacket(
Packets.BinaryRow.toPacket(column, this.serverConfig.encoding)
);
}
writeTextResult(rows, columns, binary = false) {
this.writeColumns(columns);
rows.forEach((row) => {
const arrayRow = new Array(columns.length);
columns.forEach((column) => {
arrayRow.push(row[column.name]);
});
if (binary) {
this.writeBinaryRow(arrayRow);
} else this.writeTextRow(arrayRow);
});
this.writeEof();
}
writeEof(warnings, statusFlags) {
this.writePacket(Packets.EOF.toPacket(warnings, statusFlags));
}
writeOk(args) {
if (!args) {
args = { affectedRows: 0 };
}
this.writePacket(Packets.OK.toPacket(args, this.serverConfig.encoding));
}
writeError(args) {
// if we want to send error before initial hello was sent, use default encoding
const encoding = this.serverConfig ? this.serverConfig.encoding : 'cesu8';
this.writePacket(Packets.Error.toPacket(args, encoding));
}
serverHandshake(args) {
this.serverConfig = args;
this.serverConfig.encoding =
CharsetToEncoding[this.serverConfig.characterSet];
return this.addCommand(new Commands.ServerHandshake(args));
}
// ===============================================================
end(callback) {
if (this.config.isServer) {
this._closing = true;
const quitCmd = new EventEmitter();
setImmediate(() => {
this.stream.end();
quitCmd.emit('end');
});
return quitCmd;
}
// trigger error if more commands enqueued after end command
const quitCmd = this.addCommand(new Commands.Quit(callback));
this.addCommand = this._addCommandClosedState;
return quitCmd;
}
static createQuery(sql, values, cb, config) {
let options = {
rowsAsArray: config.rowsAsArray,
infileStreamFactory: config.infileStreamFactory,
};
if (typeof sql === 'object') {
// query(options, cb)
options = {
...options,
...sql,
sql: sql.sql,
values: sql.values,
};
if (typeof values === 'function') {
cb = values;
} else if (values !== undefined) {
options.values = values;
}
} else if (typeof values === 'function') {
// query(sql, cb)
cb = values;
options.sql = sql;
options.values = undefined;
} else {
// query(sql, values, cb)
options.sql = sql;
options.values = values;
}
return new Commands.Query(options, cb);
}
static statementKey(options) {
return `${typeof options.nestTables}/${options.nestTables}/${options.rowsAsArray}${options.sql}`;
}
}
module.exports = BaseConnection;

237
node_modules/mysql2/lib/base/pool.js generated vendored Normal file
View File

@@ -0,0 +1,237 @@
'use strict';
const process = require('process');
const SqlString = require('sqlstring');
const EventEmitter = require('events').EventEmitter;
const PoolConnection = require('../pool_connection.js');
const Queue = require('denque');
const BaseConnection = require('./connection.js');
function spliceConnection(queue, connection) {
const len = queue.length;
for (let i = 0; i < len; i++) {
if (queue.get(i) === connection) {
queue.removeOne(i);
break;
}
}
}
class BasePool extends EventEmitter {
constructor(options) {
super();
this.config = options.config;
this.config.connectionConfig.pool = this;
this._allConnections = new Queue();
this._freeConnections = new Queue();
this._connectionQueue = new Queue();
this._closed = false;
if (this.config.maxIdle < this.config.connectionLimit) {
// create idle connection timeout automatically release job
this._removeIdleTimeoutConnections();
}
}
getConnection(cb) {
if (this._closed) {
return process.nextTick(() => cb(new Error('Pool is closed.')));
}
let connection;
if (this._freeConnections.length > 0) {
connection = this._freeConnections.pop();
this.emit('acquire', connection);
return process.nextTick(() => cb(null, connection));
}
if (
this.config.connectionLimit === 0 ||
this._allConnections.length < this.config.connectionLimit
) {
connection = new PoolConnection(this, {
config: this.config.connectionConfig,
});
this._allConnections.push(connection);
return connection.connect((err) => {
if (this._closed) {
return cb(new Error('Pool is closed.'));
}
if (err) {
return cb(err);
}
this.emit('connection', connection);
this.emit('acquire', connection);
return cb(null, connection);
});
}
if (!this.config.waitForConnections) {
return process.nextTick(() => cb(new Error('No connections available.')));
}
if (
this.config.queueLimit &&
this._connectionQueue.length >= this.config.queueLimit
) {
return cb(new Error('Queue limit reached.'));
}
this.emit('enqueue');
return this._connectionQueue.push(cb);
}
releaseConnection(connection) {
let cb;
if (!connection._pool) {
// The connection has been removed from the pool and is no longer good.
if (this._connectionQueue.length) {
cb = this._connectionQueue.shift();
process.nextTick(this.getConnection.bind(this, cb));
}
} else if (this._connectionQueue.length) {
cb = this._connectionQueue.shift();
process.nextTick(cb.bind(null, null, connection));
} else {
this._freeConnections.push(connection);
this.emit('release', connection);
}
}
end(cb) {
this._closed = true;
clearTimeout(this._removeIdleTimeoutConnectionsTimer);
if (typeof cb !== 'function') {
cb = function (err) {
if (err) {
throw err;
}
};
}
let calledBack = false;
let closedConnections = 0;
let connection;
const endCB = function (err) {
if (calledBack) {
return;
}
if (err || ++closedConnections >= this._allConnections.length) {
calledBack = true;
cb(err);
return;
}
}.bind(this);
if (this._allConnections.length === 0) {
endCB();
return;
}
for (let i = 0; i < this._allConnections.length; i++) {
connection = this._allConnections.get(i);
connection._realEnd(endCB);
}
}
query(sql, values, cb) {
const cmdQuery = BaseConnection.createQuery(
sql,
values,
cb,
this.config.connectionConfig
);
if (typeof cmdQuery.namedPlaceholders === 'undefined') {
cmdQuery.namedPlaceholders =
this.config.connectionConfig.namedPlaceholders;
}
this.getConnection((err, conn) => {
if (err) {
if (typeof cmdQuery.onResult === 'function') {
cmdQuery.onResult(err);
} else {
cmdQuery.emit('error', err);
}
return;
}
try {
conn.query(cmdQuery).once('end', () => {
conn.release();
});
} catch (e) {
conn.release();
throw e;
}
});
return cmdQuery;
}
execute(sql, values, cb) {
// TODO construct execute command first here and pass it to connection.execute
// so that polymorphic arguments logic is there in one place
if (typeof values === 'function') {
cb = values;
values = [];
}
this.getConnection((err, conn) => {
if (err) {
return cb(err);
}
try {
conn.execute(sql, values, cb).once('end', () => {
conn.release();
});
} catch (e) {
conn.release();
return cb(e);
}
});
}
_removeConnection(connection) {
// Remove connection from all connections
spliceConnection(this._allConnections, connection);
// Remove connection from free connections
spliceConnection(this._freeConnections, connection);
this.releaseConnection(connection);
}
_removeIdleTimeoutConnections() {
if (this._removeIdleTimeoutConnectionsTimer) {
clearTimeout(this._removeIdleTimeoutConnectionsTimer);
}
this._removeIdleTimeoutConnectionsTimer = setTimeout(() => {
try {
while (
this._freeConnections.length > this.config.maxIdle ||
(this._freeConnections.length > 0 &&
Date.now() - this._freeConnections.get(0).lastActiveTime >
this.config.idleTimeout)
) {
if (this.config.connectionConfig.gracefulEnd) {
this._freeConnections.get(0).end();
} else {
this._freeConnections.get(0).destroy();
}
}
} finally {
this._removeIdleTimeoutConnections();
}
}, 1000);
}
format(sql, values) {
return SqlString.format(
sql,
values,
this.config.connectionConfig.stringifyObjects,
this.config.connectionConfig.timezone
);
}
escape(value) {
return SqlString.escape(
value,
this.config.connectionConfig.stringifyObjects,
this.config.connectionConfig.timezone
);
}
escapeId(value) {
return SqlString.escapeId(value, false);
}
}
module.exports = BasePool;

70
node_modules/mysql2/lib/base/pool_connection.js generated vendored Normal file
View File

@@ -0,0 +1,70 @@
'use strict';
const BaseConnection = require('./connection.js');
class BasePoolConnection extends BaseConnection {
constructor(pool, options) {
super(options);
this._pool = pool;
// The last active time of this connection
this.lastActiveTime = Date.now();
// When a fatal error occurs the connection's protocol ends, which will cause
// the connection to end as well, thus we only need to watch for the end event
// and we will be notified of disconnects.
// REVIEW: Moved to `once`
this.once('end', () => {
this._removeFromPool();
});
this.once('error', () => {
this._removeFromPool();
});
}
release() {
if (!this._pool || this._pool._closed) {
return;
}
// update last active time
this.lastActiveTime = Date.now();
this._pool.releaseConnection(this);
}
end() {
if (this.config.gracefulEnd) {
this._removeFromPool();
super.end();
return;
}
const err = new Error(
'Calling conn.end() to release a pooled connection is ' +
'deprecated. In next version calling conn.end() will be ' +
'restored to default conn.end() behavior. Use ' +
'conn.release() instead.'
);
this.emit('warn', err);
console.warn(err.message);
this.release();
}
destroy() {
this._removeFromPool();
super.destroy();
}
_removeFromPool() {
if (!this._pool || this._pool._closed) {
return;
}
const pool = this._pool;
this._pool = null;
pool._removeConnection(this);
}
}
BasePoolConnection.statementKey = BaseConnection.statementKey;
module.exports = BasePoolConnection;
// TODO: Remove this when we are removing PoolConnection#end
BasePoolConnection.prototype._realEnd = BaseConnection.prototype.end;

111
node_modules/mysql2/lib/commands/auth_switch.js generated vendored Normal file
View File

@@ -0,0 +1,111 @@
// This file was modified by Oracle on July 5, 2021.
// Errors generated by asynchronous authentication plugins are now being
// handled and subsequently emitted at the command level.
// Modifications copyright (c) 2021, Oracle and/or its affiliates.
'use strict';
const Packets = require('../packets/index.js');
const sha256_password = require('../auth_plugins/sha256_password');
const caching_sha2_password = require('../auth_plugins/caching_sha2_password.js');
const mysql_native_password = require('../auth_plugins/mysql_native_password.js');
const mysql_clear_password = require('../auth_plugins/mysql_clear_password.js');
const standardAuthPlugins = {
sha256_password: sha256_password({}),
caching_sha2_password: caching_sha2_password({}),
mysql_native_password: mysql_native_password({}),
mysql_clear_password: mysql_clear_password({}),
};
function warnLegacyAuthSwitch() {
console.warn(
'WARNING! authSwitchHandler api is deprecated, please use new authPlugins api'
);
}
function authSwitchPluginError(error, command) {
// Authentication errors are fatal
error.code = 'AUTH_SWITCH_PLUGIN_ERROR';
error.fatal = true;
command.emit('error', error);
}
function authSwitchRequest(packet, connection, command) {
const { pluginName, pluginData } =
Packets.AuthSwitchRequest.fromPacket(packet);
let authPlugin =
connection.config.authPlugins && connection.config.authPlugins[pluginName];
// legacy plugin api don't allow to override mysql_native_password
// if pluginName is mysql_native_password it's using standard auth4.1 auth
if (
connection.config.authSwitchHandler &&
pluginName !== 'mysql_native_password'
) {
const legacySwitchHandler = connection.config.authSwitchHandler;
warnLegacyAuthSwitch();
legacySwitchHandler({ pluginName, pluginData }, (err, data) => {
if (err) {
return authSwitchPluginError(err, command);
}
connection.writePacket(new Packets.AuthSwitchResponse(data).toPacket());
});
return;
}
if (!authPlugin) {
authPlugin = standardAuthPlugins[pluginName];
}
if (!authPlugin) {
throw new Error(
`Server requests authentication using unknown plugin ${pluginName}. See ${'TODO: add plugins doco here'} on how to configure or author authentication plugins.`
);
}
connection._authPlugin = authPlugin({ connection, command });
Promise.resolve(connection._authPlugin(pluginData))
.then((data) => {
if (data) {
connection.writePacket(new Packets.AuthSwitchResponse(data).toPacket());
}
})
.catch((err) => {
authSwitchPluginError(err, command);
});
}
function authSwitchRequestMoreData(packet, connection, command) {
const { data } = Packets.AuthSwitchRequestMoreData.fromPacket(packet);
if (connection.config.authSwitchHandler) {
const legacySwitchHandler = connection.config.authSwitchHandler;
warnLegacyAuthSwitch();
legacySwitchHandler({ pluginData: data }, (err, data) => {
if (err) {
return authSwitchPluginError(err, command);
}
connection.writePacket(new Packets.AuthSwitchResponse(data).toPacket());
});
return;
}
if (!connection._authPlugin) {
throw new Error(
'AuthPluginMoreData received but no auth plugin instance found'
);
}
Promise.resolve(connection._authPlugin(data))
.then((data) => {
if (data) {
connection.writePacket(new Packets.AuthSwitchResponse(data).toPacket());
}
})
.catch((err) => {
authSwitchPluginError(err, command);
});
}
module.exports = {
authSwitchRequest,
authSwitchRequestMoreData,
};

109
node_modules/mysql2/lib/commands/binlog_dump.js generated vendored Normal file
View File

@@ -0,0 +1,109 @@
'use strict';
const Command = require('./command');
const Packets = require('../packets');
const eventParsers = [];
class BinlogEventHeader {
constructor(packet) {
this.timestamp = packet.readInt32();
this.eventType = packet.readInt8();
this.serverId = packet.readInt32();
this.eventSize = packet.readInt32();
this.logPos = packet.readInt32();
this.flags = packet.readInt16();
}
}
class BinlogDump extends Command {
constructor(opts) {
super();
// this.onResult = callback;
this.opts = opts;
}
start(packet, connection) {
const newPacket = new Packets.BinlogDump(this.opts);
connection.writePacket(newPacket.toPacket(1));
return BinlogDump.prototype.binlogData;
}
binlogData(packet) {
// ok - continue consuming events
// error - error
// eof - end of binlog
if (packet.isEOF()) {
this.emit('eof');
return null;
}
// binlog event header
packet.readInt8();
const header = new BinlogEventHeader(packet);
const EventParser = eventParsers[header.eventType];
let event;
if (EventParser) {
event = new EventParser(packet);
} else {
event = {
name: 'UNKNOWN',
};
}
event.header = header;
this.emit('event', event);
return BinlogDump.prototype.binlogData;
}
}
class RotateEvent {
constructor(packet) {
this.pposition = packet.readInt32();
// TODO: read uint64 here
packet.readInt32(); // positionDword2
this.nextBinlog = packet.readString();
this.name = 'RotateEvent';
}
}
class FormatDescriptionEvent {
constructor(packet) {
this.binlogVersion = packet.readInt16();
this.serverVersion = packet.readString(50).replace(/\u0000.*/, ''); // eslint-disable-line no-control-regex
this.createTimestamp = packet.readInt32();
this.eventHeaderLength = packet.readInt8(); // should be 19
this.eventsLength = packet.readBuffer();
this.name = 'FormatDescriptionEvent';
}
}
class QueryEvent {
constructor(packet) {
const parseStatusVars = require('../packets/binlog_query_statusvars.js');
this.slaveProxyId = packet.readInt32();
this.executionTime = packet.readInt32();
const schemaLength = packet.readInt8();
this.errorCode = packet.readInt16();
const statusVarsLength = packet.readInt16();
const statusVars = packet.readBuffer(statusVarsLength);
this.schema = packet.readString(schemaLength);
packet.readInt8(); // should be zero
this.statusVars = parseStatusVars(statusVars);
this.query = packet.readString();
this.name = 'QueryEvent';
}
}
class XidEvent {
constructor(packet) {
this.binlogVersion = packet.readInt16();
this.xid = packet.readInt64();
this.name = 'XidEvent';
}
}
eventParsers[2] = QueryEvent;
eventParsers[4] = RotateEvent;
eventParsers[15] = FormatDescriptionEvent;
eventParsers[16] = XidEvent;
module.exports = BinlogDump;

68
node_modules/mysql2/lib/commands/change_user.js generated vendored Normal file
View File

@@ -0,0 +1,68 @@
// This file was modified by Oracle on September 21, 2021.
// The changes involve saving additional authentication factor passwords
// in the command scope and enabling multi-factor authentication in the
// client-side when the server supports it.
// Modifications copyright (c) 2021, Oracle and/or its affiliates.
'use strict';
const Command = require('./command.js');
const Packets = require('../packets/index.js');
const ClientConstants = require('../constants/client');
const ClientHandshake = require('./client_handshake.js');
const CharsetToEncoding = require('../constants/charset_encodings.js');
class ChangeUser extends Command {
constructor(options, callback) {
super();
this.onResult = callback;
this.user = options.user;
this.password = options.password;
// "password1" is an alias of "password"
this.password1 = options.password;
this.password2 = options.password2;
this.password3 = options.password3;
this.database = options.database;
this.passwordSha1 = options.passwordSha1;
this.charsetNumber = options.charsetNumber;
this.currentConfig = options.currentConfig;
this.authenticationFactor = 0;
}
start(packet, connection) {
const newPacket = new Packets.ChangeUser({
flags: connection.config.clientFlags,
user: this.user,
database: this.database,
charsetNumber: this.charsetNumber,
password: this.password,
passwordSha1: this.passwordSha1,
authPluginData1: connection._handshakePacket.authPluginData1,
authPluginData2: connection._handshakePacket.authPluginData2,
});
this.currentConfig.user = this.user;
this.currentConfig.password = this.password;
this.currentConfig.database = this.database;
this.currentConfig.charsetNumber = this.charsetNumber;
connection.clientEncoding = CharsetToEncoding[this.charsetNumber];
// clear prepared statements cache as all statements become invalid after changeUser
connection._statements.clear();
connection.writePacket(newPacket.toPacket());
// check if the server supports multi-factor authentication
const multiFactorAuthentication =
connection.serverCapabilityFlags &
ClientConstants.MULTI_FACTOR_AUTHENTICATION;
if (multiFactorAuthentication) {
// if the server supports multi-factor authentication, we enable it in
// the client
this.authenticationFactor = 1;
}
return ChangeUser.prototype.handshakeResult;
}
}
ChangeUser.prototype.handshakeResult =
ClientHandshake.prototype.handshakeResult;
ChangeUser.prototype.calculateNativePasswordAuthToken =
ClientHandshake.prototype.calculateNativePasswordAuthToken;
module.exports = ChangeUser;

241
node_modules/mysql2/lib/commands/client_handshake.js generated vendored Normal file
View File

@@ -0,0 +1,241 @@
// This file was modified by Oracle on June 17, 2021.
// Handshake errors are now maked as fatal and the corresponding events are
// emitted in the command instance itself.
// Modifications copyright (c) 2021, Oracle and/or its affiliates.
// This file was modified by Oracle on September 21, 2021.
// Handshake workflow now supports additional authentication factors requested
// by the server.
// Modifications copyright (c) 2021, Oracle and/or its affiliates.
'use strict';
const Command = require('./command.js');
const Packets = require('../packets/index.js');
const ClientConstants = require('../constants/client.js');
const CharsetToEncoding = require('../constants/charset_encodings.js');
const auth41 = require('../auth_41.js');
function flagNames(flags) {
const res = [];
for (const c in ClientConstants) {
if (flags & ClientConstants[c]) {
res.push(c.replace(/_/g, ' ').toLowerCase());
}
}
return res;
}
class ClientHandshake extends Command {
constructor(clientFlags) {
super();
this.handshake = null;
this.clientFlags = clientFlags;
this.authenticationFactor = 0;
}
start() {
return ClientHandshake.prototype.handshakeInit;
}
sendSSLRequest(connection) {
const sslRequest = new Packets.SSLRequest(
this.clientFlags,
connection.config.charsetNumber
);
connection.writePacket(sslRequest.toPacket());
}
sendCredentials(connection) {
if (connection.config.debug) {
// eslint-disable-next-line
console.log(
'Sending handshake packet: flags:%d=(%s)',
this.clientFlags,
flagNames(this.clientFlags).join(', ')
);
}
this.user = connection.config.user;
this.password = connection.config.password;
// "password1" is an alias to the original "password" value
// to make it easier to integrate multi-factor authentication
this.password1 = connection.config.password;
// "password2" and "password3" are the 2nd and 3rd factor authentication
// passwords, which can be undefined depending on the authentication
// plugin being used
this.password2 = connection.config.password2;
this.password3 = connection.config.password3;
this.passwordSha1 = connection.config.passwordSha1;
this.database = connection.config.database;
this.authPluginName = this.handshake.authPluginName;
const handshakeResponse = new Packets.HandshakeResponse({
flags: this.clientFlags,
user: this.user,
database: this.database,
password: this.password,
passwordSha1: this.passwordSha1,
charsetNumber: connection.config.charsetNumber,
authPluginData1: this.handshake.authPluginData1,
authPluginData2: this.handshake.authPluginData2,
compress: connection.config.compress,
connectAttributes: connection.config.connectAttributes,
});
connection.writePacket(handshakeResponse.toPacket());
}
calculateNativePasswordAuthToken(authPluginData) {
// TODO: dont split into authPluginData1 and authPluginData2, instead join when 1 & 2 received
const authPluginData1 = authPluginData.slice(0, 8);
const authPluginData2 = authPluginData.slice(8, 20);
let authToken;
if (this.passwordSha1) {
authToken = auth41.calculateTokenFromPasswordSha(
this.passwordSha1,
authPluginData1,
authPluginData2
);
} else {
authToken = auth41.calculateToken(
this.password,
authPluginData1,
authPluginData2
);
}
return authToken;
}
handshakeInit(helloPacket, connection) {
this.on('error', (e) => {
connection._fatalError = e;
connection._protocolError = e;
});
this.handshake = Packets.Handshake.fromPacket(helloPacket);
if (connection.config.debug) {
// eslint-disable-next-line
console.log(
'Server hello packet: capability flags:%d=(%s)',
this.handshake.capabilityFlags,
flagNames(this.handshake.capabilityFlags).join(', ')
);
}
connection.serverCapabilityFlags = this.handshake.capabilityFlags;
connection.serverEncoding = CharsetToEncoding[this.handshake.characterSet];
connection.connectionId = this.handshake.connectionId;
const serverSSLSupport =
this.handshake.capabilityFlags & ClientConstants.SSL;
// multi factor authentication is enabled with the
// "MULTI_FACTOR_AUTHENTICATION" capability and should only be used if it
// is supported by the server
const multiFactorAuthentication =
this.handshake.capabilityFlags &
ClientConstants.MULTI_FACTOR_AUTHENTICATION;
this.clientFlags = this.clientFlags | multiFactorAuthentication;
// use compression only if requested by client and supported by server
connection.config.compress =
connection.config.compress &&
this.handshake.capabilityFlags & ClientConstants.COMPRESS;
this.clientFlags = this.clientFlags | connection.config.compress;
if (connection.config.ssl) {
// client requires SSL but server does not support it
if (!serverSSLSupport) {
const err = new Error('Server does not support secure connection');
err.code = 'HANDSHAKE_NO_SSL_SUPPORT';
err.fatal = true;
this.emit('error', err);
return false;
}
// send ssl upgrade request and immediately upgrade connection to secure
this.clientFlags |= ClientConstants.SSL;
this.sendSSLRequest(connection);
connection.startTLS((err) => {
// after connection is secure
if (err) {
// SSL negotiation error are fatal
err.code = 'HANDSHAKE_SSL_ERROR';
err.fatal = true;
this.emit('error', err);
return;
}
// rest of communication is encrypted
this.sendCredentials(connection);
});
} else {
this.sendCredentials(connection);
}
if (multiFactorAuthentication) {
// if the server supports multi-factor authentication, we enable it in
// the client
this.authenticationFactor = 1;
}
return ClientHandshake.prototype.handshakeResult;
}
handshakeResult(packet, connection) {
const marker = packet.peekByte();
// packet can be OK_Packet, ERR_Packet, AuthSwitchRequest, AuthNextFactor
// or AuthMoreData
if (marker === 0xfe || marker === 1 || marker === 0x02) {
const authSwitch = require('./auth_switch');
try {
if (marker === 1) {
authSwitch.authSwitchRequestMoreData(packet, connection, this);
} else {
// if authenticationFactor === 0, it means the server does not support
// the multi-factor authentication capability
if (this.authenticationFactor !== 0) {
// if we are past the first authentication factor, we should use the
// corresponding password (if there is one)
connection.config.password =
this[`password${this.authenticationFactor}`];
// update the current authentication factor
this.authenticationFactor += 1;
}
// if marker === 0x02, it means it is an AuthNextFactor packet,
// which is similar in structure to an AuthSwitchRequest packet,
// so, we can use it directly
authSwitch.authSwitchRequest(packet, connection, this);
}
return ClientHandshake.prototype.handshakeResult;
} catch (err) {
// Authentication errors are fatal
err.code = 'AUTH_SWITCH_PLUGIN_ERROR';
err.fatal = true;
if (this.onResult) {
this.onResult(err);
} else {
this.emit('error', err);
}
return null;
}
}
if (marker !== 0) {
const err = new Error('Unexpected packet during handshake phase');
// Unknown handshake errors are fatal
err.code = 'HANDSHAKE_UNKNOWN_ERROR';
err.fatal = true;
if (this.onResult) {
this.onResult(err);
} else {
this.emit('error', err);
}
return null;
}
// this should be called from ClientHandshake command only
// and skipped when called from ChangeUser command
if (!connection.authorized) {
connection.authorized = true;
if (connection.config.compress) {
const enableCompression =
require('../compressed_protocol.js').enableCompression;
enableCompression(connection);
}
}
if (this.onResult) {
this.onResult(null);
}
return null;
}
}
module.exports = ClientHandshake;

18
node_modules/mysql2/lib/commands/close_statement.js generated vendored Normal file
View File

@@ -0,0 +1,18 @@
'use strict';
const Command = require('./command');
const Packets = require('../packets/index.js');
class CloseStatement extends Command {
constructor(id) {
super();
this.id = id;
}
start(packet, connection) {
connection.writePacket(new Packets.CloseStatement(this.id).toPacket(1));
return null;
}
}
module.exports = CloseStatement;

54
node_modules/mysql2/lib/commands/command.js generated vendored Normal file
View File

@@ -0,0 +1,54 @@
'use strict';
const EventEmitter = require('events').EventEmitter;
const Timers = require('timers');
class Command extends EventEmitter {
constructor() {
super();
this.next = null;
}
// slow. debug only
stateName() {
const state = this.next;
for (const i in this) {
if (this[i] === state && i !== 'next') {
return i;
}
}
return 'unknown name';
}
execute(packet, connection) {
if (!this.next) {
this.next = this.start;
connection._resetSequenceId();
}
if (packet && packet.isError()) {
const err = packet.asError(connection.clientEncoding);
err.sql = this.sql || this.query;
if (this.queryTimeout) {
Timers.clearTimeout(this.queryTimeout);
this.queryTimeout = null;
}
if (this.onResult) {
this.onResult(err);
this.emit('end');
} else {
this.emit('error', err);
this.emit('end');
}
return true;
}
// TODO: don't return anything from execute, it's ugly and error-prone. Listen for 'end' event in connection
this.next = this.next(packet, connection);
if (this.next) {
return false;
}
this.emit('end');
return true;
}
}
module.exports = Command;

112
node_modules/mysql2/lib/commands/execute.js generated vendored Normal file
View File

@@ -0,0 +1,112 @@
'use strict';
const Command = require('./command.js');
const Query = require('./query.js');
const Packets = require('../packets/index.js');
const getBinaryParser = require('../parsers/binary_parser.js');
const getStaticBinaryParser = require('../parsers/static_binary_parser.js');
class Execute extends Command {
constructor(options, callback) {
super();
this.statement = options.statement;
this.sql = options.sql;
this.values = options.values;
this.onResult = callback;
this.parameters = options.values;
this.insertId = 0;
this.timeout = options.timeout;
this.queryTimeout = null;
this._rows = [];
this._fields = [];
this._result = [];
this._fieldCount = 0;
this._rowParser = null;
this._executeOptions = options;
this._resultIndex = 0;
this._localStream = null;
this._unpipeStream = function () {};
this._streamFactory = options.infileStreamFactory;
this._connection = null;
}
buildParserFromFields(fields, connection) {
if (this.options.disableEval) {
return getStaticBinaryParser(fields, this.options, connection.config);
}
return getBinaryParser(fields, this.options, connection.config);
}
start(packet, connection) {
this._connection = connection;
this.options = Object.assign({}, connection.config, this._executeOptions);
this._setTimeout();
const executePacket = new Packets.Execute(
this.statement.id,
this.parameters,
connection.config.charsetNumber,
connection.config.timezone
);
//For reasons why this try-catch is here, please see
// https://github.com/sidorares/node-mysql2/pull/689
//For additional discussion, see
// 1. https://github.com/sidorares/node-mysql2/issues/493
// 2. https://github.com/sidorares/node-mysql2/issues/187
// 3. https://github.com/sidorares/node-mysql2/issues/480
try {
connection.writePacket(executePacket.toPacket(1));
} catch (error) {
this.onResult(error);
}
return Execute.prototype.resultsetHeader;
}
readField(packet, connection) {
let fields;
// disabling for now, but would be great to find reliable way to parse fields only once
// fields reported by prepare can be empty at all or just incorrect - see #169
//
// perfomance optimisation: if we already have this field parsed in statement header, use one from header
// const field = this.statement.columns.length == this._fieldCount ?
// this.statement.columns[this._receivedFieldsCount] : new Packets.ColumnDefinition(packet);
const field = new Packets.ColumnDefinition(
packet,
connection.clientEncoding
);
this._receivedFieldsCount++;
this._fields[this._resultIndex].push(field);
if (this._receivedFieldsCount === this._fieldCount) {
fields = this._fields[this._resultIndex];
this.emit('fields', fields, this._resultIndex);
return Execute.prototype.fieldsEOF;
}
return Execute.prototype.readField;
}
fieldsEOF(packet, connection) {
// check EOF
if (!packet.isEOF()) {
return connection.protocolError('Expected EOF packet');
}
this._rowParser = new (this.buildParserFromFields(
this._fields[this._resultIndex],
connection
))();
return Execute.prototype.row;
}
}
Execute.prototype.done = Query.prototype.done;
Execute.prototype.doneInsert = Query.prototype.doneInsert;
Execute.prototype.resultsetHeader = Query.prototype.resultsetHeader;
Execute.prototype._findOrCreateReadStream =
Query.prototype._findOrCreateReadStream;
Execute.prototype._streamLocalInfile = Query.prototype._streamLocalInfile;
Execute.prototype._setTimeout = Query.prototype._setTimeout;
Execute.prototype._handleTimeoutError = Query.prototype._handleTimeoutError;
Execute.prototype.row = Query.prototype.row;
Execute.prototype.stream = Query.prototype.stream;
module.exports = Execute;

27
node_modules/mysql2/lib/commands/index.js generated vendored Normal file
View File

@@ -0,0 +1,27 @@
'use strict';
const ClientHandshake = require('./client_handshake.js');
const ServerHandshake = require('./server_handshake.js');
const Query = require('./query.js');
const Prepare = require('./prepare.js');
const CloseStatement = require('./close_statement.js');
const Execute = require('./execute.js');
const Ping = require('./ping.js');
const RegisterSlave = require('./register_slave.js');
const BinlogDump = require('./binlog_dump.js');
const ChangeUser = require('./change_user.js');
const Quit = require('./quit.js');
module.exports = {
ClientHandshake,
ServerHandshake,
Query,
Prepare,
CloseStatement,
Execute,
Ping,
RegisterSlave,
BinlogDump,
ChangeUser,
Quit,
};

36
node_modules/mysql2/lib/commands/ping.js generated vendored Normal file
View File

@@ -0,0 +1,36 @@
'use strict';
const Command = require('./command');
const CommandCode = require('../constants/commands');
const Packet = require('../packets/packet');
// TODO: time statistics?
// usefull for queue size and network latency monitoring
// store created,sent,reply timestamps
class Ping extends Command {
constructor(callback) {
super();
this.onResult = callback;
}
start(packet, connection) {
const ping = new Packet(
0,
Buffer.from([1, 0, 0, 0, CommandCode.PING]),
0,
5
);
connection.writePacket(ping);
return Ping.prototype.pingResponse;
}
pingResponse() {
// TODO: check it's OK packet. error check already done in caller
if (this.onResult) {
process.nextTick(this.onResult.bind(this));
}
return null;
}
}
module.exports = Ping;

143
node_modules/mysql2/lib/commands/prepare.js generated vendored Normal file
View File

@@ -0,0 +1,143 @@
'use strict';
const Packets = require('../packets/index.js');
const Command = require('./command.js');
const CloseStatement = require('./close_statement.js');
const Execute = require('./execute.js');
class PreparedStatementInfo {
constructor(query, id, columns, parameters, connection) {
this.query = query;
this.id = id;
this.columns = columns;
this.parameters = parameters;
this.rowParser = null;
this._connection = connection;
}
close() {
return this._connection.addCommand(new CloseStatement(this.id));
}
execute(parameters, callback) {
if (typeof parameters === 'function') {
callback = parameters;
parameters = [];
}
return this._connection.addCommand(
new Execute({ statement: this, values: parameters }, callback)
);
}
}
class Prepare extends Command {
constructor(options, callback) {
super();
this.query = options.sql;
this.onResult = callback;
this.id = 0;
this.fieldCount = 0;
this.parameterCount = 0;
this.fields = [];
this.parameterDefinitions = [];
this.options = options;
}
start(packet, connection) {
const Connection = connection.constructor;
this.key = Connection.statementKey(this.options);
const statement = connection._statements.get(this.key);
if (statement) {
if (this.onResult) {
this.onResult(null, statement);
}
return null;
}
const cmdPacket = new Packets.PrepareStatement(
this.query,
connection.config.charsetNumber,
this.options.values
);
connection.writePacket(cmdPacket.toPacket(1));
return Prepare.prototype.prepareHeader;
}
prepareHeader(packet, connection) {
const header = new Packets.PreparedStatementHeader(packet);
this.id = header.id;
this.fieldCount = header.fieldCount;
this.parameterCount = header.parameterCount;
if (this.parameterCount > 0) {
return Prepare.prototype.readParameter;
}
if (this.fieldCount > 0) {
return Prepare.prototype.readField;
}
return this.prepareDone(connection);
}
readParameter(packet, connection) {
// there might be scenarios when mysql server reports more parameters than
// are actually present in the array of parameter definitions.
// if EOF packet is received we switch to "read fields" state if there are
// any fields reported by the server, otherwise we finish the command.
if (packet.isEOF()) {
if (this.fieldCount > 0) {
return Prepare.prototype.readField;
}
return this.prepareDone(connection);
}
const def = new Packets.ColumnDefinition(packet, connection.clientEncoding);
this.parameterDefinitions.push(def);
if (this.parameterDefinitions.length === this.parameterCount) {
return Prepare.prototype.parametersEOF;
}
return this.readParameter;
}
readField(packet, connection) {
if (packet.isEOF()) {
return this.prepareDone(connection);
}
const def = new Packets.ColumnDefinition(packet, connection.clientEncoding);
this.fields.push(def);
if (this.fields.length === this.fieldCount) {
return Prepare.prototype.fieldsEOF;
}
return Prepare.prototype.readField;
}
parametersEOF(packet, connection) {
if (!packet.isEOF()) {
return connection.protocolError('Expected EOF packet after parameters');
}
if (this.fieldCount > 0) {
return Prepare.prototype.readField;
}
return this.prepareDone(connection);
}
fieldsEOF(packet, connection) {
if (!packet.isEOF()) {
return connection.protocolError('Expected EOF packet after fields');
}
return this.prepareDone(connection);
}
prepareDone(connection) {
const statement = new PreparedStatementInfo(
this.query,
this.id,
this.fields,
this.parameterDefinitions,
connection
);
connection._statements.set(this.key, statement);
if (this.onResult) {
this.onResult(null, statement);
}
return null;
}
}
module.exports = Prepare;

366
node_modules/mysql2/lib/commands/query.js generated vendored Normal file
View File

@@ -0,0 +1,366 @@
'use strict';
const process = require('process');
const Timers = require('timers');
const Readable = require('stream').Readable;
const Command = require('./command.js');
const Packets = require('../packets/index.js');
const getTextParser = require('../parsers/text_parser.js');
const staticParser = require('../parsers/static_text_parser.js');
const ServerStatus = require('../constants/server_status.js');
const EmptyPacket = new Packets.Packet(0, Buffer.allocUnsafe(4), 0, 4);
// http://dev.mysql.com/doc/internals/en/com-query.html
class Query extends Command {
constructor(options, callback) {
super();
this.sql = options.sql;
this.values = options.values;
this._queryOptions = options;
this.namedPlaceholders = options.namedPlaceholders || false;
this.onResult = callback;
this.timeout = options.timeout;
this.queryTimeout = null;
this._fieldCount = 0;
this._rowParser = null;
this._fields = [];
this._rows = [];
this._receivedFieldsCount = 0;
this._resultIndex = 0;
this._localStream = null;
this._unpipeStream = function () {};
this._streamFactory = options.infileStreamFactory;
this._connection = null;
}
then() {
const err =
"You have tried to call .then(), .catch(), or invoked await on the result of query that is not a promise, which is a programming error. Try calling con.promise().query(), or require('mysql2/promise') instead of 'mysql2' for a promise-compatible version of the query interface. To learn how to use async/await or Promises check out documentation at https://sidorares.github.io/node-mysql2/docs#using-promise-wrapper, or the mysql2 documentation at https://sidorares.github.io/node-mysql2/docs/documentation/promise-wrapper";
// eslint-disable-next-line
console.log(err);
throw new Error(err);
}
/* eslint no-unused-vars: ["error", { "argsIgnorePattern": "^_" }] */
start(_packet, connection) {
if (connection.config.debug) {
// eslint-disable-next-line
console.log(' Sending query command: %s', this.sql);
}
this._connection = connection;
this.options = Object.assign({}, connection.config, this._queryOptions);
this._setTimeout();
const cmdPacket = new Packets.Query(
this.sql,
connection.config.charsetNumber
);
connection.writePacket(cmdPacket.toPacket(1));
return Query.prototype.resultsetHeader;
}
done() {
this._unpipeStream();
// if all ready timeout, return null directly
if (this.timeout && !this.queryTimeout) {
return null;
}
// else clear timer
if (this.queryTimeout) {
Timers.clearTimeout(this.queryTimeout);
this.queryTimeout = null;
}
if (this.onResult) {
let rows, fields;
if (this._resultIndex === 0) {
rows = this._rows[0];
fields = this._fields[0];
} else {
rows = this._rows;
fields = this._fields;
}
if (fields) {
process.nextTick(() => {
this.onResult(null, rows, fields);
});
} else {
process.nextTick(() => {
this.onResult(null, rows);
});
}
}
return null;
}
doneInsert(rs) {
if (this._localStreamError) {
if (this.onResult) {
this.onResult(this._localStreamError, rs);
} else {
this.emit('error', this._localStreamError);
}
return null;
}
this._rows.push(rs);
this._fields.push(void 0);
this.emit('fields', void 0);
this.emit('result', rs);
if (rs.serverStatus & ServerStatus.SERVER_MORE_RESULTS_EXISTS) {
this._resultIndex++;
return this.resultsetHeader;
}
return this.done();
}
resultsetHeader(packet, connection) {
const rs = new Packets.ResultSetHeader(packet, connection);
this._fieldCount = rs.fieldCount;
if (connection.config.debug) {
// eslint-disable-next-line
console.log(
` Resultset header received, expecting ${rs.fieldCount} column definition packets`
);
}
if (this._fieldCount === 0) {
return this.doneInsert(rs);
}
if (this._fieldCount === null) {
return this._streamLocalInfile(connection, rs.infileName);
}
this._receivedFieldsCount = 0;
this._rows.push([]);
this._fields.push([]);
return this.readField;
}
_streamLocalInfile(connection, path) {
if (this._streamFactory) {
this._localStream = this._streamFactory(path);
} else {
this._localStreamError = new Error(
`As a result of LOCAL INFILE command server wants to read ${path} file, but as of v2.0 you must provide streamFactory option returning ReadStream.`
);
connection.writePacket(EmptyPacket);
return this.infileOk;
}
const onConnectionError = () => {
this._unpipeStream();
};
const onDrain = () => {
this._localStream.resume();
};
const onPause = () => {
this._localStream.pause();
};
const onData = function (data) {
const dataWithHeader = Buffer.allocUnsafe(data.length + 4);
data.copy(dataWithHeader, 4);
connection.writePacket(
new Packets.Packet(0, dataWithHeader, 0, dataWithHeader.length)
);
};
const onEnd = () => {
connection.removeListener('error', onConnectionError);
connection.writePacket(EmptyPacket);
};
const onError = (err) => {
this._localStreamError = err;
connection.removeListener('error', onConnectionError);
connection.writePacket(EmptyPacket);
};
this._unpipeStream = () => {
connection.stream.removeListener('pause', onPause);
connection.stream.removeListener('drain', onDrain);
this._localStream.removeListener('data', onData);
this._localStream.removeListener('end', onEnd);
this._localStream.removeListener('error', onError);
};
connection.stream.on('pause', onPause);
connection.stream.on('drain', onDrain);
this._localStream.on('data', onData);
this._localStream.on('end', onEnd);
this._localStream.on('error', onError);
connection.once('error', onConnectionError);
return this.infileOk;
}
readField(packet, connection) {
this._receivedFieldsCount++;
// Often there is much more data in the column definition than in the row itself
// If you set manually _fields[0] to array of ColumnDefinition's (from previous call)
// you can 'cache' result of parsing. Field packets still received, but ignored in that case
// this is the reason _receivedFieldsCount exist (otherwise we could just use current length of fields array)
if (this._fields[this._resultIndex].length !== this._fieldCount) {
const field = new Packets.ColumnDefinition(
packet,
connection.clientEncoding
);
this._fields[this._resultIndex].push(field);
if (connection.config.debug) {
/* eslint-disable no-console */
console.log(' Column definition:');
console.log(` name: ${field.name}`);
console.log(` type: ${field.columnType}`);
console.log(` flags: ${field.flags}`);
/* eslint-enable no-console */
}
}
// last field received
if (this._receivedFieldsCount === this._fieldCount) {
const fields = this._fields[this._resultIndex];
this.emit('fields', fields);
if (this.options.disableEval) {
this._rowParser = staticParser(fields, this.options, connection.config);
} else {
this._rowParser = new (getTextParser(
fields,
this.options,
connection.config
))(fields);
}
return Query.prototype.fieldsEOF;
}
return Query.prototype.readField;
}
fieldsEOF(packet, connection) {
// check EOF
if (!packet.isEOF()) {
return connection.protocolError('Expected EOF packet');
}
return this.row;
}
/* eslint no-unused-vars: ["error", { "argsIgnorePattern": "^_" }] */
row(packet, _connection) {
if (packet.isEOF()) {
const status = packet.eofStatusFlags();
const moreResults = status & ServerStatus.SERVER_MORE_RESULTS_EXISTS;
if (moreResults) {
this._resultIndex++;
return Query.prototype.resultsetHeader;
}
return this.done();
}
let row;
try {
row = this._rowParser.next(
packet,
this._fields[this._resultIndex],
this.options
);
} catch (err) {
this._localStreamError = err;
return this.doneInsert(null);
}
if (this.onResult) {
this._rows[this._resultIndex].push(row);
} else {
this.emit('result', row, this._resultIndex);
}
return Query.prototype.row;
}
infileOk(packet, connection) {
const rs = new Packets.ResultSetHeader(packet, connection);
return this.doneInsert(rs);
}
stream(options) {
options = options || Object.create(null);
options.objectMode = true;
const stream = new Readable({
...options,
emitClose: true,
autoDestroy: true,
read: () => {
this._connection && this._connection.resume();
},
});
// Prevent a breaking change for users that rely on `end` event
stream.once('close', () => {
if (!stream.readableEnded) {
stream.emit('end');
}
});
const onResult = (row, index) => {
if (stream.destroyed) return;
if (!stream.push(row)) {
this._connection && this._connection.pause();
}
stream.emit('result', row, index); // replicate old emitter
};
const onFields = (fields) => {
if (stream.destroyed) return;
stream.emit('fields', fields); // replicate old emitter
};
const onEnd = () => {
if (stream.destroyed) return;
stream.push(null); // pushing null, indicating EOF
};
const onError = (err) => {
stream.destroy(err);
};
stream._destroy = (err, cb) => {
this._connection && this._connection.resume();
this.removeListener('result', onResult);
this.removeListener('fields', onFields);
this.removeListener('end', onEnd);
this.removeListener('error', onError);
cb(err); // Pass on any errors
};
this.on('result', onResult);
this.on('fields', onFields);
this.on('end', onEnd);
this.on('error', onError);
return stream;
}
_setTimeout() {
if (this.timeout) {
const timeoutHandler = this._handleTimeoutError.bind(this);
this.queryTimeout = Timers.setTimeout(timeoutHandler, this.timeout);
}
}
_handleTimeoutError() {
if (this.queryTimeout) {
Timers.clearTimeout(this.queryTimeout);
this.queryTimeout = null;
}
const err = new Error('Query inactivity timeout');
err.errorno = 'PROTOCOL_SEQUENCE_TIMEOUT';
err.code = 'PROTOCOL_SEQUENCE_TIMEOUT';
err.syscall = 'query';
if (this.onResult) {
this.onResult(err);
} else {
this.emit('error', err);
}
}
}
Query.prototype.catch = Query.prototype.then;
module.exports = Query;

29
node_modules/mysql2/lib/commands/quit.js generated vendored Normal file
View File

@@ -0,0 +1,29 @@
'use strict';
const Command = require('./command.js');
const CommandCode = require('../constants/commands.js');
const Packet = require('../packets/packet.js');
class Quit extends Command {
constructor(callback) {
super();
this.onResult = callback;
}
start(packet, connection) {
connection._closing = true;
const quit = new Packet(
0,
Buffer.from([1, 0, 0, 0, CommandCode.QUIT]),
0,
5
);
if (this.onResult) {
this.onResult();
}
connection.writePacket(quit);
return null;
}
}
module.exports = Quit;

27
node_modules/mysql2/lib/commands/register_slave.js generated vendored Normal file
View File

@@ -0,0 +1,27 @@
'use strict';
const Command = require('./command');
const Packets = require('../packets');
class RegisterSlave extends Command {
constructor(opts, callback) {
super();
this.onResult = callback;
this.opts = opts;
}
start(packet, connection) {
const newPacket = new Packets.RegisterSlave(this.opts);
connection.writePacket(newPacket.toPacket(1));
return RegisterSlave.prototype.registerResponse;
}
registerResponse() {
if (this.onResult) {
process.nextTick(this.onResult.bind(this));
}
return null;
}
}
module.exports = RegisterSlave;

203
node_modules/mysql2/lib/commands/server_handshake.js generated vendored Normal file
View File

@@ -0,0 +1,203 @@
'use strict';
const CommandCode = require('../constants/commands.js');
const Errors = require('../constants/errors.js');
const Command = require('./command.js');
const Packets = require('../packets/index.js');
class ServerHandshake extends Command {
constructor(args) {
super();
this.args = args;
/*
this.protocolVersion = args.protocolVersion || 10;
this.serverVersion = args.serverVersion;
this.connectionId = args.connectionId,
this.statusFlags = args.statusFlags,
this.characterSet = args.characterSet,
this.capabilityFlags = args.capabilityFlags || 512;
*/
}
start(packet, connection) {
const serverHelloPacket = new Packets.Handshake(this.args);
this.serverHello = serverHelloPacket;
serverHelloPacket.setScrambleData((err) => {
if (err) {
connection.emit('error', new Error('Error generating random bytes'));
return;
}
connection.writePacket(serverHelloPacket.toPacket(0));
});
return ServerHandshake.prototype.readClientReply;
}
readClientReply(packet, connection) {
// check auth here
const clientHelloReply = Packets.HandshakeResponse.fromPacket(packet);
// TODO check we don't have something similar already
connection.clientHelloReply = clientHelloReply;
if (this.args.authCallback) {
this.args.authCallback(
{
user: clientHelloReply.user,
database: clientHelloReply.database,
address: connection.stream.remoteAddress,
authPluginData1: this.serverHello.authPluginData1,
authPluginData2: this.serverHello.authPluginData2,
authToken: clientHelloReply.authToken,
},
(err, mysqlError) => {
// if (err)
if (!mysqlError) {
connection.writeOk();
} else {
// TODO create constants / errorToCode
// 1045 = ER_ACCESS_DENIED_ERROR
connection.writeError({
message: mysqlError.message || '',
code: mysqlError.code || 1045,
});
connection.close();
}
}
);
} else {
connection.writeOk();
}
return ServerHandshake.prototype.dispatchCommands;
}
_isStatement(query, name) {
const firstWord = query.split(' ')[0].toUpperCase();
return firstWord === name;
}
dispatchCommands(packet, connection) {
// command from client to server
let knownCommand = true;
const encoding = connection.clientHelloReply.encoding;
const commandCode = packet.readInt8();
switch (commandCode) {
case CommandCode.STMT_PREPARE:
if (connection.listeners('stmt_prepare').length) {
const query = packet.readString(undefined, encoding);
connection.emit('stmt_prepare', query);
} else {
connection.writeError({
code: Errors.HA_ERR_INTERNAL_ERROR,
message: 'No query handler for prepared statements.',
});
}
break;
case CommandCode.STMT_EXECUTE:
if (connection.listeners('stmt_execute').length) {
const { stmtId, flags, iterationCount, values } =
Packets.Execute.fromPacket(packet, encoding);
connection.emit(
'stmt_execute',
stmtId,
flags,
iterationCount,
values
);
} else {
connection.writeError({
code: Errors.HA_ERR_INTERNAL_ERROR,
message: 'No query handler for execute statements.',
});
}
break;
case CommandCode.QUIT:
if (connection.listeners('quit').length) {
connection.emit('quit');
} else {
connection.stream.end();
}
break;
case CommandCode.INIT_DB:
if (connection.listeners('init_db').length) {
const schemaName = packet.readString(undefined, encoding);
connection.emit('init_db', schemaName);
} else {
connection.writeOk();
}
break;
case CommandCode.QUERY:
if (connection.listeners('query').length) {
const query = packet.readString(undefined, encoding);
if (
this._isStatement(query, 'PREPARE') ||
this._isStatement(query, 'SET')
) {
connection.emit('stmt_prepare', query);
} else if (this._isStatement(query, 'EXECUTE')) {
connection.emit('stmt_execute', null, null, null, null, query);
} else connection.emit('query', query);
} else {
connection.writeError({
code: Errors.HA_ERR_INTERNAL_ERROR,
message: 'No query handler',
});
}
break;
case CommandCode.FIELD_LIST:
if (connection.listeners('field_list').length) {
const table = packet.readNullTerminatedString(encoding);
const fields = packet.readString(undefined, encoding);
connection.emit('field_list', table, fields);
} else {
connection.writeError({
code: Errors.ER_WARN_DEPRECATED_SYNTAX,
message:
'As of MySQL 5.7.11, COM_FIELD_LIST is deprecated and will be removed in a future version of MySQL.',
});
}
break;
case CommandCode.PING:
if (connection.listeners('ping').length) {
connection.emit('ping');
} else {
connection.writeOk();
}
break;
default:
knownCommand = false;
}
if (connection.listeners('packet').length) {
connection.emit('packet', packet.clone(), knownCommand, commandCode);
} else if (!knownCommand) {
// eslint-disable-next-line no-console
console.log('Unknown command:', commandCode);
}
return ServerHandshake.prototype.dispatchCommands;
}
}
module.exports = ServerHandshake;
// TODO: implement server-side 4.1 authentication
/*
4.1 authentication: (http://bazaar.launchpad.net/~mysql/mysql-server/5.5/view/head:/sql/password.c)
SERVER: public_seed=create_random_string()
send(public_seed)
CLIENT: recv(public_seed)
hash_stage1=sha1("password")
hash_stage2=sha1(hash_stage1)
reply=xor(hash_stage1, sha1(public_seed,hash_stage2)
// this three steps are done in scramble()
send(reply)
SERVER: recv(reply)
hash_stage1=xor(reply, sha1(public_seed,hash_stage2))
candidate_hash2=sha1(hash_stage1)
check(candidate_hash2==hash_stage2)
server stores sha1(sha1(password)) ( hash_stag2)
*/

127
node_modules/mysql2/lib/compressed_protocol.js generated vendored Normal file
View File

@@ -0,0 +1,127 @@
'use strict';
// connection mixins
// implementation of http://dev.mysql.com/doc/internals/en/compression.html
const zlib = require('zlib');
const PacketParser = require('./packet_parser.js');
function handleCompressedPacket(packet) {
// eslint-disable-next-line consistent-this, no-invalid-this
const connection = this;
const deflatedLength = packet.readInt24();
const body = packet.readBuffer();
if (deflatedLength !== 0) {
connection.inflateQueue.push((task) => {
zlib.inflate(body, (err, data) => {
if (err) {
connection._handleNetworkError(err);
return;
}
connection._bumpCompressedSequenceId(packet.numPackets);
connection._inflatedPacketsParser.execute(data);
task.done();
});
});
} else {
connection.inflateQueue.push((task) => {
connection._bumpCompressedSequenceId(packet.numPackets);
connection._inflatedPacketsParser.execute(body);
task.done();
});
}
}
function writeCompressed(buffer) {
// http://dev.mysql.com/doc/internals/en/example-several-mysql-packets.html
// note: sending a MySQL Packet of the size 2^245 to 2^241 via compression
// leads to at least one extra compressed packet.
// (this is because "length of the packet before compression" need to fit
// into 3 byte unsigned int. "length of the packet before compression" includes
// 4 byte packet header, hence 2^245)
const MAX_COMPRESSED_LENGTH = 16777210;
let start;
if (buffer.length > MAX_COMPRESSED_LENGTH) {
for (start = 0; start < buffer.length; start += MAX_COMPRESSED_LENGTH) {
writeCompressed.call(
// eslint-disable-next-line no-invalid-this
this,
buffer.slice(start, start + MAX_COMPRESSED_LENGTH)
);
}
return;
}
// eslint-disable-next-line no-invalid-this, consistent-this
const connection = this;
let packetLen = buffer.length;
const compressHeader = Buffer.allocUnsafe(7);
// seqqueue is used here because zlib async execution is routed via thread pool
// internally and when we have multiple compressed packets arriving we need
// to assemble uncompressed result sequentially
(function (seqId) {
connection.deflateQueue.push((task) => {
zlib.deflate(buffer, (err, compressed) => {
if (err) {
connection._handleFatalError(err);
return;
}
let compressedLength = compressed.length;
if (compressedLength < packetLen) {
compressHeader.writeUInt8(compressedLength & 0xff, 0);
compressHeader.writeUInt16LE(compressedLength >> 8, 1);
compressHeader.writeUInt8(seqId, 3);
compressHeader.writeUInt8(packetLen & 0xff, 4);
compressHeader.writeUInt16LE(packetLen >> 8, 5);
connection.writeUncompressed(compressHeader);
connection.writeUncompressed(compressed);
} else {
// http://dev.mysql.com/doc/internals/en/uncompressed-payload.html
// To send an uncompressed payload:
// - set length of payload before compression to 0
// - the compressed payload contains the uncompressed payload instead.
compressedLength = packetLen;
packetLen = 0;
compressHeader.writeUInt8(compressedLength & 0xff, 0);
compressHeader.writeUInt16LE(compressedLength >> 8, 1);
compressHeader.writeUInt8(seqId, 3);
compressHeader.writeUInt8(packetLen & 0xff, 4);
compressHeader.writeUInt16LE(packetLen >> 8, 5);
connection.writeUncompressed(compressHeader);
connection.writeUncompressed(buffer);
}
task.done();
});
});
})(connection.compressedSequenceId);
connection._bumpCompressedSequenceId(1);
}
function enableCompression(connection) {
connection._lastWrittenPacketId = 0;
connection._lastReceivedPacketId = 0;
connection._handleCompressedPacket = handleCompressedPacket;
connection._inflatedPacketsParser = new PacketParser((p) => {
connection.handlePacket(p);
}, 4);
connection._inflatedPacketsParser._lastPacket = 0;
connection.packetParser = new PacketParser((packet) => {
connection._handleCompressedPacket(packet);
}, 7);
connection.writeUncompressed = connection.write;
connection.write = writeCompressed;
const seqqueue = require('seq-queue');
connection.inflateQueue = seqqueue.createQueue();
connection.deflateQueue = seqqueue.createQueue();
}
module.exports = {
enableCompression: enableCompression,
};

12
node_modules/mysql2/lib/connection.js generated vendored Normal file
View File

@@ -0,0 +1,12 @@
'use strict';
const BaseConnection = require('./base/connection.js');
class Connection extends BaseConnection {
promise(promiseImpl) {
const PromiseConnection = require('./promise/connection.js');
return new PromiseConnection(this, promiseImpl);
}
}
module.exports = Connection;

294
node_modules/mysql2/lib/connection_config.js generated vendored Normal file
View File

@@ -0,0 +1,294 @@
// This file was modified by Oracle on September 21, 2021.
// New connection options for additional authentication factors were
// introduced.
// Multi-factor authentication capability is now enabled if one of these
// options is used.
// Modifications copyright (c) 2021, Oracle and/or its affiliates.
'use strict';
const { URL } = require('url');
const ClientConstants = require('./constants/client');
const Charsets = require('./constants/charsets');
const { version } = require('../package.json');
let SSLProfiles = null;
const validOptions = {
authPlugins: 1,
authSwitchHandler: 1,
bigNumberStrings: 1,
charset: 1,
charsetNumber: 1,
compress: 1,
connectAttributes: 1,
connectTimeout: 1,
database: 1,
dateStrings: 1,
debug: 1,
decimalNumbers: 1,
enableKeepAlive: 1,
flags: 1,
host: 1,
insecureAuth: 1,
infileStreamFactory: 1,
isServer: 1,
keepAliveInitialDelay: 1,
localAddress: 1,
maxPreparedStatements: 1,
multipleStatements: 1,
namedPlaceholders: 1,
nestTables: 1,
password: 1,
// with multi-factor authentication, the main password (used for the first
// authentication factor) can be provided via password1
password1: 1,
password2: 1,
password3: 1,
passwordSha1: 1,
pool: 1,
port: 1,
queryFormat: 1,
rowsAsArray: 1,
socketPath: 1,
ssl: 1,
stream: 1,
stringifyObjects: 1,
supportBigNumbers: 1,
timezone: 1,
trace: 1,
typeCast: 1,
uri: 1,
user: 1,
disableEval: 1,
// These options are used for Pool
connectionLimit: 1,
maxIdle: 1,
idleTimeout: 1,
Promise: 1,
queueLimit: 1,
waitForConnections: 1,
jsonStrings: 1,
gracefulEnd: 1,
};
class ConnectionConfig {
constructor(options) {
if (typeof options === 'string') {
options = ConnectionConfig.parseUrl(options);
} else if (options && options.uri) {
const uriOptions = ConnectionConfig.parseUrl(options.uri);
for (const key in uriOptions) {
if (!Object.prototype.hasOwnProperty.call(uriOptions, key)) continue;
if (options[key]) continue;
options[key] = uriOptions[key];
}
}
for (const key in options) {
if (!Object.prototype.hasOwnProperty.call(options, key)) continue;
if (validOptions[key] !== 1) {
// REVIEW: Should this be emitted somehow?
// eslint-disable-next-line no-console
console.error(
`Ignoring invalid configuration option passed to Connection: ${key}. This is currently a warning, but in future versions of MySQL2, an error will be thrown if you pass an invalid configuration option to a Connection`
);
}
}
this.isServer = options.isServer;
this.stream = options.stream;
this.host = options.host || 'localhost';
this.port =
(typeof options.port === 'string'
? parseInt(options.port, 10)
: options.port) || 3306;
this.localAddress = options.localAddress;
this.socketPath = options.socketPath;
this.user = options.user || undefined;
// for the purpose of multi-factor authentication, or not, the main
// password (used for the 1st authentication factor) can also be
// provided via the "password1" option
this.password = options.password || options.password1 || undefined;
this.password2 = options.password2 || undefined;
this.password3 = options.password3 || undefined;
this.passwordSha1 = options.passwordSha1 || undefined;
this.database = options.database;
this.connectTimeout = isNaN(options.connectTimeout)
? 10 * 1000
: options.connectTimeout;
this.insecureAuth = options.insecureAuth || false;
this.infileStreamFactory = options.infileStreamFactory || undefined;
this.supportBigNumbers = options.supportBigNumbers || false;
this.bigNumberStrings = options.bigNumberStrings || false;
this.decimalNumbers = options.decimalNumbers || false;
this.dateStrings = options.dateStrings || false;
this.debug = options.debug;
this.trace = options.trace !== false;
this.stringifyObjects = options.stringifyObjects || false;
this.enableKeepAlive = options.enableKeepAlive !== false;
this.keepAliveInitialDelay = options.keepAliveInitialDelay;
if (
options.timezone &&
!/^(?:local|Z|[ +-]\d\d:\d\d)$/.test(options.timezone)
) {
// strictly supports timezones specified by mysqljs/mysql:
// https://github.com/mysqljs/mysql#user-content-connection-options
// eslint-disable-next-line no-console
console.error(
`Ignoring invalid timezone passed to Connection: ${options.timezone}. This is currently a warning, but in future versions of MySQL2, an error will be thrown if you pass an invalid configuration option to a Connection`
);
// SqlStrings falls back to UTC on invalid timezone
this.timezone = 'Z';
} else {
this.timezone = options.timezone || 'local';
}
this.queryFormat = options.queryFormat;
this.pool = options.pool || undefined;
this.ssl =
typeof options.ssl === 'string'
? ConnectionConfig.getSSLProfile(options.ssl)
: options.ssl || false;
this.multipleStatements = options.multipleStatements || false;
this.rowsAsArray = options.rowsAsArray || false;
this.namedPlaceholders = options.namedPlaceholders || false;
this.nestTables =
options.nestTables === undefined ? undefined : options.nestTables;
this.typeCast = options.typeCast === undefined ? true : options.typeCast;
this.disableEval = Boolean(options.disableEval);
if (this.timezone[0] === ' ') {
// "+" is a url encoded char for space so it
// gets translated to space when giving a
// connection string..
this.timezone = `+${this.timezone.slice(1)}`;
}
if (this.ssl) {
if (typeof this.ssl !== 'object') {
throw new TypeError(
`SSL profile must be an object, instead it's a ${typeof this.ssl}`
);
}
// Default rejectUnauthorized to true
this.ssl.rejectUnauthorized = this.ssl.rejectUnauthorized !== false;
}
this.maxPacketSize = 0;
this.charsetNumber = options.charset
? ConnectionConfig.getCharsetNumber(options.charset)
: options.charsetNumber || Charsets.UTF8MB4_UNICODE_CI;
this.compress = options.compress || false;
this.authPlugins = options.authPlugins;
this.authSwitchHandler = options.authSwitchHandler;
this.clientFlags = ConnectionConfig.mergeFlags(
ConnectionConfig.getDefaultFlags(options),
options.flags || ''
);
// Default connection attributes
// https://dev.mysql.com/doc/refman/8.0/en/performance-schema-connection-attribute-tables.html
const defaultConnectAttributes = {
_client_name: 'Node-MySQL-2',
_client_version: version,
};
this.connectAttributes = {
...defaultConnectAttributes,
...(options.connectAttributes || {}),
};
this.maxPreparedStatements = options.maxPreparedStatements || 16000;
this.jsonStrings = options.jsonStrings || false;
this.gracefulEnd = options.gracefulEnd || false;
}
static mergeFlags(default_flags, user_flags) {
let flags = 0x0,
i;
if (!Array.isArray(user_flags)) {
user_flags = String(user_flags || '')
.toUpperCase()
.split(/\s*,+\s*/);
}
// add default flags unless "blacklisted"
for (i in default_flags) {
if (user_flags.indexOf(`-${default_flags[i]}`) >= 0) {
continue;
}
flags |= ClientConstants[default_flags[i]] || 0x0;
}
// add user flags unless already already added
for (i in user_flags) {
if (user_flags[i][0] === '-') {
continue;
}
if (default_flags.indexOf(user_flags[i]) >= 0) {
continue;
}
flags |= ClientConstants[user_flags[i]] || 0x0;
}
return flags;
}
static getDefaultFlags(options) {
const defaultFlags = [
'LONG_PASSWORD',
'FOUND_ROWS',
'LONG_FLAG',
'CONNECT_WITH_DB',
'ODBC',
'LOCAL_FILES',
'IGNORE_SPACE',
'PROTOCOL_41',
'IGNORE_SIGPIPE',
'TRANSACTIONS',
'RESERVED',
'SECURE_CONNECTION',
'MULTI_RESULTS',
'TRANSACTIONS',
'SESSION_TRACK',
'CONNECT_ATTRS',
];
if (options && options.multipleStatements) {
defaultFlags.push('MULTI_STATEMENTS');
}
defaultFlags.push('PLUGIN_AUTH');
defaultFlags.push('PLUGIN_AUTH_LENENC_CLIENT_DATA');
return defaultFlags;
}
static getCharsetNumber(charset) {
const num = Charsets[charset.toUpperCase()];
if (num === undefined) {
throw new TypeError(`Unknown charset '${charset}'`);
}
return num;
}
static getSSLProfile(name) {
if (!SSLProfiles) {
SSLProfiles = require('./constants/ssl_profiles.js');
}
const ssl = SSLProfiles[name];
if (ssl === undefined) {
throw new TypeError(`Unknown SSL profile '${name}'`);
}
return ssl;
}
static parseUrl(url) {
const parsedUrl = new URL(url);
const options = {
host: decodeURIComponent(parsedUrl.hostname),
port: parseInt(parsedUrl.port, 10),
database: decodeURIComponent(parsedUrl.pathname.slice(1)),
user: decodeURIComponent(parsedUrl.username),
password: decodeURIComponent(parsedUrl.password),
};
parsedUrl.searchParams.forEach((value, key) => {
try {
// Try to parse this as a JSON expression first
options[key] = JSON.parse(value);
} catch (err) {
// Otherwise assume it is a plain string
options[key] = value;
}
});
return options;
}
}
module.exports = ConnectionConfig;

316
node_modules/mysql2/lib/constants/charset_encodings.js generated vendored Normal file
View File

@@ -0,0 +1,316 @@
'use strict';
// see tools/generate-charset-mapping.js
// basicalliy result of "SHOW COLLATION" query
module.exports = [
'utf8',
'big5',
'latin2',
'dec8',
'cp850',
'latin1',
'hp8',
'koi8r',
'latin1',
'latin2',
'swe7',
'ascii',
'eucjp',
'sjis',
'cp1251',
'latin1',
'hebrew',
'utf8',
'tis620',
'euckr',
'latin7',
'latin2',
'koi8u',
'cp1251',
'gb2312',
'greek',
'cp1250',
'latin2',
'gbk',
'cp1257',
'latin5',
'latin1',
'armscii8',
'cesu8',
'cp1250',
'ucs2',
'cp866',
'keybcs2',
'macintosh',
'macroman',
'cp852',
'latin7',
'latin7',
'macintosh',
'cp1250',
'utf8',
'utf8',
'latin1',
'latin1',
'latin1',
'cp1251',
'cp1251',
'cp1251',
'macroman',
'utf16',
'utf16',
'utf16-le',
'cp1256',
'cp1257',
'cp1257',
'utf32',
'utf32',
'utf16-le',
'binary',
'armscii8',
'ascii',
'cp1250',
'cp1256',
'cp866',
'dec8',
'greek',
'hebrew',
'hp8',
'keybcs2',
'koi8r',
'koi8u',
'cesu8',
'latin2',
'latin5',
'latin7',
'cp850',
'cp852',
'swe7',
'cesu8',
'big5',
'euckr',
'gb2312',
'gbk',
'sjis',
'tis620',
'ucs2',
'eucjp',
'geostd8',
'geostd8',
'latin1',
'cp932',
'cp932',
'eucjpms',
'eucjpms',
'cp1250',
'utf16',
'utf16',
'utf16',
'utf16',
'utf16',
'utf16',
'utf16',
'utf16',
'utf16',
'utf16',
'utf16',
'utf16',
'utf16',
'utf16',
'utf16',
'utf16',
'utf16',
'utf16',
'utf16',
'utf16',
'utf16',
'utf16',
'utf16',
'utf16',
'utf16',
'utf8',
'utf8',
'utf8',
'ucs2',
'ucs2',
'ucs2',
'ucs2',
'ucs2',
'ucs2',
'ucs2',
'ucs2',
'ucs2',
'ucs2',
'ucs2',
'ucs2',
'ucs2',
'ucs2',
'ucs2',
'ucs2',
'ucs2',
'ucs2',
'ucs2',
'ucs2',
'ucs2',
'ucs2',
'ucs2',
'ucs2',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'ucs2',
'utf32',
'utf32',
'utf32',
'utf32',
'utf32',
'utf32',
'utf32',
'utf32',
'utf32',
'utf32',
'utf32',
'utf32',
'utf32',
'utf32',
'utf32',
'utf32',
'utf32',
'utf32',
'utf32',
'utf32',
'utf32',
'utf32',
'utf32',
'utf32',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'cesu8',
'cesu8',
'cesu8',
'cesu8',
'cesu8',
'cesu8',
'cesu8',
'cesu8',
'cesu8',
'cesu8',
'cesu8',
'cesu8',
'cesu8',
'cesu8',
'cesu8',
'cesu8',
'cesu8',
'cesu8',
'cesu8',
'cesu8',
'cesu8',
'cesu8',
'cesu8',
'cesu8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'cesu8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'gb18030',
'gb18030',
'gb18030',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
'utf8',
];

317
node_modules/mysql2/lib/constants/charsets.js generated vendored Normal file
View File

@@ -0,0 +1,317 @@
'use strict';
exports.BIG5_CHINESE_CI = 1;
exports.LATIN2_CZECH_CS = 2;
exports.DEC8_SWEDISH_CI = 3;
exports.CP850_GENERAL_CI = 4;
exports.LATIN1_GERMAN1_CI = 5;
exports.HP8_ENGLISH_CI = 6;
exports.KOI8R_GENERAL_CI = 7;
exports.LATIN1_SWEDISH_CI = 8;
exports.LATIN2_GENERAL_CI = 9;
exports.SWE7_SWEDISH_CI = 10;
exports.ASCII_GENERAL_CI = 11;
exports.UJIS_JAPANESE_CI = 12;
exports.SJIS_JAPANESE_CI = 13;
exports.CP1251_BULGARIAN_CI = 14;
exports.LATIN1_DANISH_CI = 15;
exports.HEBREW_GENERAL_CI = 16;
exports.TIS620_THAI_CI = 18;
exports.EUCKR_KOREAN_CI = 19;
exports.LATIN7_ESTONIAN_CS = 20;
exports.LATIN2_HUNGARIAN_CI = 21;
exports.KOI8U_GENERAL_CI = 22;
exports.CP1251_UKRAINIAN_CI = 23;
exports.GB2312_CHINESE_CI = 24;
exports.GREEK_GENERAL_CI = 25;
exports.CP1250_GENERAL_CI = 26;
exports.LATIN2_CROATIAN_CI = 27;
exports.GBK_CHINESE_CI = 28;
exports.CP1257_LITHUANIAN_CI = 29;
exports.LATIN5_TURKISH_CI = 30;
exports.LATIN1_GERMAN2_CI = 31;
exports.ARMSCII8_GENERAL_CI = 32;
exports.UTF8_GENERAL_CI = 33;
exports.CP1250_CZECH_CS = 34;
exports.UCS2_GENERAL_CI = 35;
exports.CP866_GENERAL_CI = 36;
exports.KEYBCS2_GENERAL_CI = 37;
exports.MACCE_GENERAL_CI = 38;
exports.MACROMAN_GENERAL_CI = 39;
exports.CP852_GENERAL_CI = 40;
exports.LATIN7_GENERAL_CI = 41;
exports.LATIN7_GENERAL_CS = 42;
exports.MACCE_BIN = 43;
exports.CP1250_CROATIAN_CI = 44;
exports.UTF8MB4_GENERAL_CI = 45;
exports.UTF8MB4_BIN = 46;
exports.LATIN1_BIN = 47;
exports.LATIN1_GENERAL_CI = 48;
exports.LATIN1_GENERAL_CS = 49;
exports.CP1251_BIN = 50;
exports.CP1251_GENERAL_CI = 51;
exports.CP1251_GENERAL_CS = 52;
exports.MACROMAN_BIN = 53;
exports.UTF16_GENERAL_CI = 54;
exports.UTF16_BIN = 55;
exports.UTF16LE_GENERAL_CI = 56;
exports.CP1256_GENERAL_CI = 57;
exports.CP1257_BIN = 58;
exports.CP1257_GENERAL_CI = 59;
exports.UTF32_GENERAL_CI = 60;
exports.UTF32_BIN = 61;
exports.UTF16LE_BIN = 62;
exports.BINARY = 63;
exports.ARMSCII8_BIN = 64;
exports.ASCII_BIN = 65;
exports.CP1250_BIN = 66;
exports.CP1256_BIN = 67;
exports.CP866_BIN = 68;
exports.DEC8_BIN = 69;
exports.GREEK_BIN = 70;
exports.HEBREW_BIN = 71;
exports.HP8_BIN = 72;
exports.KEYBCS2_BIN = 73;
exports.KOI8R_BIN = 74;
exports.KOI8U_BIN = 75;
exports.UTF8_TOLOWER_CI = 76;
exports.LATIN2_BIN = 77;
exports.LATIN5_BIN = 78;
exports.LATIN7_BIN = 79;
exports.CP850_BIN = 80;
exports.CP852_BIN = 81;
exports.SWE7_BIN = 82;
exports.UTF8_BIN = 83;
exports.BIG5_BIN = 84;
exports.EUCKR_BIN = 85;
exports.GB2312_BIN = 86;
exports.GBK_BIN = 87;
exports.SJIS_BIN = 88;
exports.TIS620_BIN = 89;
exports.UCS2_BIN = 90;
exports.UJIS_BIN = 91;
exports.GEOSTD8_GENERAL_CI = 92;
exports.GEOSTD8_BIN = 93;
exports.LATIN1_SPANISH_CI = 94;
exports.CP932_JAPANESE_CI = 95;
exports.CP932_BIN = 96;
exports.EUCJPMS_JAPANESE_CI = 97;
exports.EUCJPMS_BIN = 98;
exports.CP1250_POLISH_CI = 99;
exports.UTF16_UNICODE_CI = 101;
exports.UTF16_ICELANDIC_CI = 102;
exports.UTF16_LATVIAN_CI = 103;
exports.UTF16_ROMANIAN_CI = 104;
exports.UTF16_SLOVENIAN_CI = 105;
exports.UTF16_POLISH_CI = 106;
exports.UTF16_ESTONIAN_CI = 107;
exports.UTF16_SPANISH_CI = 108;
exports.UTF16_SWEDISH_CI = 109;
exports.UTF16_TURKISH_CI = 110;
exports.UTF16_CZECH_CI = 111;
exports.UTF16_DANISH_CI = 112;
exports.UTF16_LITHUANIAN_CI = 113;
exports.UTF16_SLOVAK_CI = 114;
exports.UTF16_SPANISH2_CI = 115;
exports.UTF16_ROMAN_CI = 116;
exports.UTF16_PERSIAN_CI = 117;
exports.UTF16_ESPERANTO_CI = 118;
exports.UTF16_HUNGARIAN_CI = 119;
exports.UTF16_SINHALA_CI = 120;
exports.UTF16_GERMAN2_CI = 121;
exports.UTF16_CROATIAN_CI = 122;
exports.UTF16_UNICODE_520_CI = 123;
exports.UTF16_VIETNAMESE_CI = 124;
exports.UCS2_UNICODE_CI = 128;
exports.UCS2_ICELANDIC_CI = 129;
exports.UCS2_LATVIAN_CI = 130;
exports.UCS2_ROMANIAN_CI = 131;
exports.UCS2_SLOVENIAN_CI = 132;
exports.UCS2_POLISH_CI = 133;
exports.UCS2_ESTONIAN_CI = 134;
exports.UCS2_SPANISH_CI = 135;
exports.UCS2_SWEDISH_CI = 136;
exports.UCS2_TURKISH_CI = 137;
exports.UCS2_CZECH_CI = 138;
exports.UCS2_DANISH_CI = 139;
exports.UCS2_LITHUANIAN_CI = 140;
exports.UCS2_SLOVAK_CI = 141;
exports.UCS2_SPANISH2_CI = 142;
exports.UCS2_ROMAN_CI = 143;
exports.UCS2_PERSIAN_CI = 144;
exports.UCS2_ESPERANTO_CI = 145;
exports.UCS2_HUNGARIAN_CI = 146;
exports.UCS2_SINHALA_CI = 147;
exports.UCS2_GERMAN2_CI = 148;
exports.UCS2_CROATIAN_CI = 149;
exports.UCS2_UNICODE_520_CI = 150;
exports.UCS2_VIETNAMESE_CI = 151;
exports.UCS2_GENERAL_MYSQL500_CI = 159;
exports.UTF32_UNICODE_CI = 160;
exports.UTF32_ICELANDIC_CI = 161;
exports.UTF32_LATVIAN_CI = 162;
exports.UTF32_ROMANIAN_CI = 163;
exports.UTF32_SLOVENIAN_CI = 164;
exports.UTF32_POLISH_CI = 165;
exports.UTF32_ESTONIAN_CI = 166;
exports.UTF32_SPANISH_CI = 167;
exports.UTF32_SWEDISH_CI = 168;
exports.UTF32_TURKISH_CI = 169;
exports.UTF32_CZECH_CI = 170;
exports.UTF32_DANISH_CI = 171;
exports.UTF32_LITHUANIAN_CI = 172;
exports.UTF32_SLOVAK_CI = 173;
exports.UTF32_SPANISH2_CI = 174;
exports.UTF32_ROMAN_CI = 175;
exports.UTF32_PERSIAN_CI = 176;
exports.UTF32_ESPERANTO_CI = 177;
exports.UTF32_HUNGARIAN_CI = 178;
exports.UTF32_SINHALA_CI = 179;
exports.UTF32_GERMAN2_CI = 180;
exports.UTF32_CROATIAN_CI = 181;
exports.UTF32_UNICODE_520_CI = 182;
exports.UTF32_VIETNAMESE_CI = 183;
exports.UTF8_UNICODE_CI = 192;
exports.UTF8_ICELANDIC_CI = 193;
exports.UTF8_LATVIAN_CI = 194;
exports.UTF8_ROMANIAN_CI = 195;
exports.UTF8_SLOVENIAN_CI = 196;
exports.UTF8_POLISH_CI = 197;
exports.UTF8_ESTONIAN_CI = 198;
exports.UTF8_SPANISH_CI = 199;
exports.UTF8_SWEDISH_CI = 200;
exports.UTF8_TURKISH_CI = 201;
exports.UTF8_CZECH_CI = 202;
exports.UTF8_DANISH_CI = 203;
exports.UTF8_LITHUANIAN_CI = 204;
exports.UTF8_SLOVAK_CI = 205;
exports.UTF8_SPANISH2_CI = 206;
exports.UTF8_ROMAN_CI = 207;
exports.UTF8_PERSIAN_CI = 208;
exports.UTF8_ESPERANTO_CI = 209;
exports.UTF8_HUNGARIAN_CI = 210;
exports.UTF8_SINHALA_CI = 211;
exports.UTF8_GERMAN2_CI = 212;
exports.UTF8_CROATIAN_CI = 213;
exports.UTF8_UNICODE_520_CI = 214;
exports.UTF8_VIETNAMESE_CI = 215;
exports.UTF8_GENERAL_MYSQL500_CI = 223;
exports.UTF8MB4_UNICODE_CI = 224;
exports.UTF8MB4_ICELANDIC_CI = 225;
exports.UTF8MB4_LATVIAN_CI = 226;
exports.UTF8MB4_ROMANIAN_CI = 227;
exports.UTF8MB4_SLOVENIAN_CI = 228;
exports.UTF8MB4_POLISH_CI = 229;
exports.UTF8MB4_ESTONIAN_CI = 230;
exports.UTF8MB4_SPANISH_CI = 231;
exports.UTF8MB4_SWEDISH_CI = 232;
exports.UTF8MB4_TURKISH_CI = 233;
exports.UTF8MB4_CZECH_CI = 234;
exports.UTF8MB4_DANISH_CI = 235;
exports.UTF8MB4_LITHUANIAN_CI = 236;
exports.UTF8MB4_SLOVAK_CI = 237;
exports.UTF8MB4_SPANISH2_CI = 238;
exports.UTF8MB4_ROMAN_CI = 239;
exports.UTF8MB4_PERSIAN_CI = 240;
exports.UTF8MB4_ESPERANTO_CI = 241;
exports.UTF8MB4_HUNGARIAN_CI = 242;
exports.UTF8MB4_SINHALA_CI = 243;
exports.UTF8MB4_GERMAN2_CI = 244;
exports.UTF8MB4_CROATIAN_CI = 245;
exports.UTF8MB4_UNICODE_520_CI = 246;
exports.UTF8MB4_VIETNAMESE_CI = 247;
exports.GB18030_CHINESE_CI = 248;
exports.GB18030_BIN = 249;
exports.GB18030_UNICODE_520_CI = 250;
exports.UTF8_GENERAL50_CI = 253; // deprecated
exports.UTF8MB4_0900_AI_CI = 255;
exports.UTF8MB4_DE_PB_0900_AI_CI = 256;
exports.UTF8MB4_IS_0900_AI_CI = 257;
exports.UTF8MB4_LV_0900_AI_CI = 258;
exports.UTF8MB4_RO_0900_AI_CI = 259;
exports.UTF8MB4_SL_0900_AI_CI = 260;
exports.UTF8MB4_PL_0900_AI_CI = 261;
exports.UTF8MB4_ET_0900_AI_CI = 262;
exports.UTF8MB4_ES_0900_AI_CI = 263;
exports.UTF8MB4_SV_0900_AI_CI = 264;
exports.UTF8MB4_TR_0900_AI_CI = 265;
exports.UTF8MB4_CS_0900_AI_CI = 266;
exports.UTF8MB4_DA_0900_AI_CI = 267;
exports.UTF8MB4_LT_0900_AI_CI = 268;
exports.UTF8MB4_SK_0900_AI_CI = 269;
exports.UTF8MB4_ES_TRAD_0900_AI_CI = 270;
exports.UTF8MB4_LA_0900_AI_CI = 271;
exports.UTF8MB4_EO_0900_AI_CI = 273;
exports.UTF8MB4_HU_0900_AI_CI = 274;
exports.UTF8MB4_HR_0900_AI_CI = 275;
exports.UTF8MB4_VI_0900_AI_CI = 277;
exports.UTF8MB4_0900_AS_CS = 278;
exports.UTF8MB4_DE_PB_0900_AS_CS = 279;
exports.UTF8MB4_IS_0900_AS_CS = 280;
exports.UTF8MB4_LV_0900_AS_CS = 281;
exports.UTF8MB4_RO_0900_AS_CS = 282;
exports.UTF8MB4_SL_0900_AS_CS = 283;
exports.UTF8MB4_PL_0900_AS_CS = 284;
exports.UTF8MB4_ET_0900_AS_CS = 285;
exports.UTF8MB4_ES_0900_AS_CS = 286;
exports.UTF8MB4_SV_0900_AS_CS = 287;
exports.UTF8MB4_TR_0900_AS_CS = 288;
exports.UTF8MB4_CS_0900_AS_CS = 289;
exports.UTF8MB4_DA_0900_AS_CS = 290;
exports.UTF8MB4_LT_0900_AS_CS = 291;
exports.UTF8MB4_SK_0900_AS_CS = 292;
exports.UTF8MB4_ES_TRAD_0900_AS_CS = 293;
exports.UTF8MB4_LA_0900_AS_CS = 294;
exports.UTF8MB4_EO_0900_AS_CS = 296;
exports.UTF8MB4_HU_0900_AS_CS = 297;
exports.UTF8MB4_HR_0900_AS_CS = 298;
exports.UTF8MB4_VI_0900_AS_CS = 300;
exports.UTF8MB4_JA_0900_AS_CS = 303;
exports.UTF8MB4_JA_0900_AS_CS_KS = 304;
exports.UTF8MB4_0900_AS_CI = 305;
exports.UTF8MB4_RU_0900_AI_CI = 306;
exports.UTF8MB4_RU_0900_AS_CS = 307;
exports.UTF8MB4_ZH_0900_AS_CS = 308;
exports.UTF8MB4_0900_BIN = 309;
// short aliases
exports.BIG5 = exports.BIG5_CHINESE_CI;
exports.DEC8 = exports.DEC8_SWEDISH_CI;
exports.CP850 = exports.CP850_GENERAL_CI;
exports.HP8 = exports.HP8_ENGLISH_CI;
exports.KOI8R = exports.KOI8R_GENERAL_CI;
exports.LATIN1 = exports.LATIN1_SWEDISH_CI;
exports.LATIN2 = exports.LATIN2_GENERAL_CI;
exports.SWE7 = exports.SWE7_SWEDISH_CI;
exports.ASCII = exports.ASCII_GENERAL_CI;
exports.UJIS = exports.UJIS_JAPANESE_CI;
exports.SJIS = exports.SJIS_JAPANESE_CI;
exports.HEBREW = exports.HEBREW_GENERAL_CI;
exports.TIS620 = exports.TIS620_THAI_CI;
exports.EUCKR = exports.EUCKR_KOREAN_CI;
exports.KOI8U = exports.KOI8U_GENERAL_CI;
exports.GB2312 = exports.GB2312_CHINESE_CI;
exports.GREEK = exports.GREEK_GENERAL_CI;
exports.CP1250 = exports.CP1250_GENERAL_CI;
exports.GBK = exports.GBK_CHINESE_CI;
exports.LATIN5 = exports.LATIN5_TURKISH_CI;
exports.ARMSCII8 = exports.ARMSCII8_GENERAL_CI;
exports.UTF8 = exports.UTF8_GENERAL_CI;
exports.UCS2 = exports.UCS2_GENERAL_CI;
exports.CP866 = exports.CP866_GENERAL_CI;
exports.KEYBCS2 = exports.KEYBCS2_GENERAL_CI;
exports.MACCE = exports.MACCE_GENERAL_CI;
exports.MACROMAN = exports.MACROMAN_GENERAL_CI;
exports.CP852 = exports.CP852_GENERAL_CI;
exports.LATIN7 = exports.LATIN7_GENERAL_CI;
exports.UTF8MB4 = exports.UTF8MB4_GENERAL_CI;
exports.CP1251 = exports.CP1251_GENERAL_CI;
exports.UTF16 = exports.UTF16_GENERAL_CI;
exports.UTF16LE = exports.UTF16LE_GENERAL_CI;
exports.CP1256 = exports.CP1256_GENERAL_CI;
exports.CP1257 = exports.CP1257_GENERAL_CI;
exports.UTF32 = exports.UTF32_GENERAL_CI;
exports.CP932 = exports.CP932_JAPANESE_CI;
exports.EUCJPMS = exports.EUCJPMS_JAPANESE_CI;
exports.GB18030 = exports.GB18030_CHINESE_CI;
exports.GEOSTD8 = exports.GEOSTD8_GENERAL_CI;

39
node_modules/mysql2/lib/constants/client.js generated vendored Normal file
View File

@@ -0,0 +1,39 @@
// This file was modified by Oracle on September 21, 2021.
// New capability for multi-factor authentication based on mandatory session
// trackers, that are signaled with an extra single-byte prefix on new
// versions of the MySQL server.
// Modifications copyright (c) 2021, Oracle and/or its affiliates.
'use strict';
// Manually extracted from mysql-5.5.23/include/mysql_com.h
exports.LONG_PASSWORD = 0x00000001; /* new more secure passwords */
exports.FOUND_ROWS = 0x00000002; /* found instead of affected rows */
exports.LONG_FLAG = 0x00000004; /* get all column flags */
exports.CONNECT_WITH_DB = 0x00000008; /* one can specify db on connect */
exports.NO_SCHEMA = 0x00000010; /* don't allow database.table.column */
exports.COMPRESS = 0x00000020; /* can use compression protocol */
exports.ODBC = 0x00000040; /* odbc client */
exports.LOCAL_FILES = 0x00000080; /* can use LOAD DATA LOCAL */
exports.IGNORE_SPACE = 0x00000100; /* ignore spaces before '' */
exports.PROTOCOL_41 = 0x00000200; /* new 4.1 protocol */
exports.INTERACTIVE = 0x00000400; /* this is an interactive client */
exports.SSL = 0x00000800; /* switch to ssl after handshake */
exports.IGNORE_SIGPIPE = 0x00001000; /* IGNORE sigpipes */
exports.TRANSACTIONS = 0x00002000; /* client knows about transactions */
exports.RESERVED = 0x00004000; /* old flag for 4.1 protocol */
exports.SECURE_CONNECTION = 0x00008000; /* new 4.1 authentication */
exports.MULTI_STATEMENTS = 0x00010000; /* enable/disable multi-stmt support */
exports.MULTI_RESULTS = 0x00020000; /* enable/disable multi-results */
exports.PS_MULTI_RESULTS = 0x00040000; /* multi-results in ps-protocol */
exports.PLUGIN_AUTH = 0x00080000; /* client supports plugin authentication */
exports.CONNECT_ATTRS = 0x00100000; /* permits connection attributes */
exports.PLUGIN_AUTH_LENENC_CLIENT_DATA = 0x00200000; /* Understands length-encoded integer for auth response data in Protocol::HandshakeResponse41. */
exports.CAN_HANDLE_EXPIRED_PASSWORDS = 0x00400000; /* Announces support for expired password extension. */
exports.SESSION_TRACK = 0x00800000; /* Can set SERVER_SESSION_STATE_CHANGED in the Status Flags and send session-state change data after a OK packet. */
exports.DEPRECATE_EOF = 0x01000000; /* Can send OK after a Text Resultset. */
exports.SSL_VERIFY_SERVER_CERT = 0x40000000;
exports.REMEMBER_OPTIONS = 0x80000000;
exports.MULTI_FACTOR_AUTHENTICATION = 0x10000000; /* multi-factor authentication */

36
node_modules/mysql2/lib/constants/commands.js generated vendored Normal file
View File

@@ -0,0 +1,36 @@
'use strict';
module.exports = {
SLEEP: 0x00, // deprecated
QUIT: 0x01,
INIT_DB: 0x02,
QUERY: 0x03,
FIELD_LIST: 0x04,
CREATE_DB: 0x05,
DROP_DB: 0x06,
REFRESH: 0x07,
SHUTDOWN: 0x08,
STATISTICS: 0x09,
PROCESS_INFO: 0x0a, // deprecated
CONNECT: 0x0b, // deprecated
PROCESS_KILL: 0x0c,
DEBUG: 0x0d,
PING: 0x0e,
TIME: 0x0f, // deprecated
DELAYED_INSERT: 0x10, // deprecated
CHANGE_USER: 0x11,
BINLOG_DUMP: 0x12,
TABLE_DUMP: 0x13,
CONNECT_OUT: 0x14,
REGISTER_SLAVE: 0x15,
STMT_PREPARE: 0x16,
STMT_EXECUTE: 0x17,
STMT_SEND_LONG_DATA: 0x18,
STMT_CLOSE: 0x19,
STMT_RESET: 0x1a,
SET_OPTION: 0x1b,
STMT_FETCH: 0x1c,
DAEMON: 0x1d, // deprecated
BINLOG_DUMP_GTID: 0x1e,
UNKNOWN: 0xff, // bad!
};

8
node_modules/mysql2/lib/constants/cursor.js generated vendored Normal file
View File

@@ -0,0 +1,8 @@
'use strict';
module.exports = {
NO_CURSOR: 0,
READ_ONLY: 1,
FOR_UPDATE: 2,
SCROLLABLE: 3,
};

50
node_modules/mysql2/lib/constants/encoding_charset.js generated vendored Normal file
View File

@@ -0,0 +1,50 @@
'use strict';
// inverse of charset_encodings
// given encoding, get matching mysql charset number
module.exports = {
big5: 1,
latin2: 2,
dec8: 3,
cp850: 4,
latin1: 5,
hp8: 6,
koi8r: 7,
swe7: 10,
ascii: 11,
eucjp: 12,
sjis: 13,
cp1251: 14,
hebrew: 16,
tis620: 18,
euckr: 19,
latin7: 20,
koi8u: 22,
gb2312: 24,
greek: 25,
cp1250: 26,
gbk: 28,
cp1257: 29,
latin5: 30,
armscii8: 32,
cesu8: 33,
ucs2: 35,
cp866: 36,
keybcs2: 37,
macintosh: 38,
macroman: 39,
cp852: 40,
utf8: 45,
utf8mb4: 45,
utf16: 54,
utf16le: 56,
cp1256: 57,
utf32: 60,
binary: 63,
geostd8: 92,
cp932: 95,
eucjpms: 97,
gb18030: 248,
utf8mb3: 192,
};

3973
node_modules/mysql2/lib/constants/errors.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

20
node_modules/mysql2/lib/constants/field_flags.js generated vendored Normal file
View File

@@ -0,0 +1,20 @@
'use strict';
// Manually extracted from mysql-5.5.23/include/mysql_com.h
exports.NOT_NULL = 1; /* Field can't be NULL */
exports.PRI_KEY = 2; /* Field is part of a primary key */
exports.UNIQUE_KEY = 4; /* Field is part of a unique key */
exports.MULTIPLE_KEY = 8; /* Field is part of a key */
exports.BLOB = 16; /* Field is a blob */
exports.UNSIGNED = 32; /* Field is unsigned */
exports.ZEROFILL = 64; /* Field is zerofill */
exports.BINARY = 128; /* Field is binary */
/* The following are only sent to new clients */
exports.ENUM = 256; /* field is an enum */
exports.AUTO_INCREMENT = 512; /* field is a autoincrement field */
exports.TIMESTAMP = 1024; /* Field is a timestamp */
exports.SET = 2048; /* field is a set */
exports.NO_DEFAULT_VALUE = 4096; /* Field doesn't have default value */
exports.ON_UPDATE_NOW = 8192; /* Field is set to NOW on UPDATE */
exports.NUM = 32768; /* Field is num (for clients) */

44
node_modules/mysql2/lib/constants/server_status.js generated vendored Normal file
View File

@@ -0,0 +1,44 @@
'use strict';
// Manually extracted from mysql-5.5.23/include/mysql_com.h
/**
Is raised when a multi-statement transaction
has been started, either explicitly, by means
of BEGIN or COMMIT AND CHAIN, or
implicitly, by the first transactional
statement, when autocommit=off.
*/
exports.SERVER_STATUS_IN_TRANS = 1;
exports.SERVER_STATUS_AUTOCOMMIT = 2; /* Server in auto_commit mode */
exports.SERVER_MORE_RESULTS_EXISTS = 8; /* Multi query - next query exists */
exports.SERVER_QUERY_NO_GOOD_INDEX_USED = 16;
exports.SERVER_QUERY_NO_INDEX_USED = 32;
/**
The server was able to fulfill the clients request and opened a
read-only non-scrollable cursor for a query. This flag comes
in reply to COM_STMT_EXECUTE and COM_STMT_FETCH commands.
*/
exports.SERVER_STATUS_CURSOR_EXISTS = 64;
/**
This flag is sent when a read-only cursor is exhausted, in reply to
COM_STMT_FETCH command.
*/
exports.SERVER_STATUS_LAST_ROW_SENT = 128;
exports.SERVER_STATUS_DB_DROPPED = 256; /* A database was dropped */
exports.SERVER_STATUS_NO_BACKSLASH_ESCAPES = 512;
/**
Sent to the client if after a prepared statement reprepare
we discovered that the new statement returns a different
number of result set columns.
*/
exports.SERVER_STATUS_METADATA_CHANGED = 1024;
exports.SERVER_QUERY_WAS_SLOW = 2048;
/**
To mark ResultSet containing output parameter values.
*/
exports.SERVER_PS_OUT_PARAMS = 4096;
exports.SERVER_STATUS_IN_TRANS_READONLY = 0x2000; // in a read-only transaction
exports.SERVER_SESSION_STATE_CHANGED = 0x4000;

11
node_modules/mysql2/lib/constants/session_track.js generated vendored Normal file
View File

@@ -0,0 +1,11 @@
'use strict';
exports.SYSTEM_VARIABLES = 0;
exports.SCHEMA = 1;
exports.STATE_CHANGE = 2;
exports.STATE_GTIDS = 3;
exports.TRANSACTION_CHARACTERISTICS = 4;
exports.TRANSACTION_STATE = 5;
exports.FIRST_KEY = exports.SYSTEM_VARIABLES;
exports.LAST_KEY = exports.TRANSACTION_STATE;

11
node_modules/mysql2/lib/constants/ssl_profiles.js generated vendored Normal file
View File

@@ -0,0 +1,11 @@
'use strict';
const awsCaBundle = require('aws-ssl-profiles');
/**
* @deprecated
* Please, use [**aws-ssl-profiles**](https://github.com/mysqljs/aws-ssl-profiles).
*/
exports['Amazon RDS'] = {
ca: awsCaBundle.ca,
};

64
node_modules/mysql2/lib/constants/types.js generated vendored Normal file
View File

@@ -0,0 +1,64 @@
'use strict';
module.exports = {
0x00: 'DECIMAL', // aka DECIMAL
0x01: 'TINY', // aka TINYINT, 1 byte
0x02: 'SHORT', // aka SMALLINT, 2 bytes
0x03: 'LONG', // aka INT, 4 bytes
0x04: 'FLOAT', // aka FLOAT, 4-8 bytes
0x05: 'DOUBLE', // aka DOUBLE, 8 bytes
0x06: 'NULL', // NULL (used for prepared statements, I think)
0x07: 'TIMESTAMP', // aka TIMESTAMP
0x08: 'LONGLONG', // aka BIGINT, 8 bytes
0x09: 'INT24', // aka MEDIUMINT, 3 bytes
0x0a: 'DATE', // aka DATE
0x0b: 'TIME', // aka TIME
0x0c: 'DATETIME', // aka DATETIME
0x0d: 'YEAR', // aka YEAR, 1 byte (don't ask)
0x0e: 'NEWDATE', // aka ?
0x0f: 'VARCHAR', // aka VARCHAR (?)
0x10: 'BIT', // aka BIT, 1-8 byte
0xf5: 'JSON',
0xf6: 'NEWDECIMAL', // aka DECIMAL
0xf7: 'ENUM', // aka ENUM
0xf8: 'SET', // aka SET
0xf9: 'TINY_BLOB', // aka TINYBLOB, TINYTEXT
0xfa: 'MEDIUM_BLOB', // aka MEDIUMBLOB, MEDIUMTEXT
0xfb: 'LONG_BLOB', // aka LONGBLOG, LONGTEXT
0xfc: 'BLOB', // aka BLOB, TEXT
0xfd: 'VAR_STRING', // aka VARCHAR, VARBINARY
0xfe: 'STRING', // aka CHAR, BINARY
0xff: 'GEOMETRY', // aka GEOMETRY
};
// Manually extracted from mysql-5.5.23/include/mysql_com.h
// some more info here: http://dev.mysql.com/doc/refman/5.5/en/c-api-prepared-statement-type-codes.html
module.exports.DECIMAL = 0x00; // aka DECIMAL (http://dev.mysql.com/doc/refman/5.0/en/precision-math-decimal-changes.html)
module.exports.TINY = 0x01; // aka TINYINT, 1 byte
module.exports.SHORT = 0x02; // aka SMALLINT, 2 bytes
module.exports.LONG = 0x03; // aka INT, 4 bytes
module.exports.FLOAT = 0x04; // aka FLOAT, 4-8 bytes
module.exports.DOUBLE = 0x05; // aka DOUBLE, 8 bytes
module.exports.NULL = 0x06; // NULL (used for prepared statements, I think)
module.exports.TIMESTAMP = 0x07; // aka TIMESTAMP
module.exports.LONGLONG = 0x08; // aka BIGINT, 8 bytes
module.exports.INT24 = 0x09; // aka MEDIUMINT, 3 bytes
module.exports.DATE = 0x0a; // aka DATE
module.exports.TIME = 0x0b; // aka TIME
module.exports.DATETIME = 0x0c; // aka DATETIME
module.exports.YEAR = 0x0d; // aka YEAR, 1 byte (don't ask)
module.exports.NEWDATE = 0x0e; // aka ?
module.exports.VARCHAR = 0x0f; // aka VARCHAR (?)
module.exports.BIT = 0x10; // aka BIT, 1-8 byte
module.exports.VECTOR = 0xf2;
module.exports.JSON = 0xf5;
module.exports.NEWDECIMAL = 0xf6; // aka DECIMAL
module.exports.ENUM = 0xf7; // aka ENUM
module.exports.SET = 0xf8; // aka SET
module.exports.TINY_BLOB = 0xf9; // aka TINYBLOB, TINYTEXT
module.exports.MEDIUM_BLOB = 0xfa; // aka MEDIUMBLOB, MEDIUMTEXT
module.exports.LONG_BLOB = 0xfb; // aka LONGBLOG, LONGTEXT
module.exports.BLOB = 0xfc; // aka BLOB, TEXT
module.exports.VAR_STRING = 0xfd; // aka VARCHAR, VARBINARY
module.exports.STRING = 0xfe; // aka CHAR, BINARY
module.exports.GEOMETRY = 0xff; // aka GEOMETRY

10
node_modules/mysql2/lib/create_connection.js generated vendored Normal file
View File

@@ -0,0 +1,10 @@
'use strict';
const Connection = require('./connection.js');
const ConnectionConfig = require('./connection_config.js');
function createConnection(opts) {
return new Connection({ config: new ConnectionConfig(opts) });
}
module.exports = createConnection;

10
node_modules/mysql2/lib/create_pool.js generated vendored Normal file
View File

@@ -0,0 +1,10 @@
'use strict';
const Pool = require('./pool.js');
const PoolConfig = require('./pool_config.js');
function createPool(config) {
return new Pool({ config: new PoolConfig(config) });
}
module.exports = createPool;

9
node_modules/mysql2/lib/create_pool_cluster.js generated vendored Normal file
View File

@@ -0,0 +1,9 @@
'use strict';
const PoolCluster = require('./pool_cluster.js');
function createPoolCluster(config) {
return new PoolCluster(config);
}
module.exports = createPoolCluster;

86
node_modules/mysql2/lib/helpers.js generated vendored Normal file
View File

@@ -0,0 +1,86 @@
'use strict';
/*
this seems to be not only shorter, but faster than
string.replace(/\\/g, '\\\\').
replace(/\u0008/g, '\\b').
replace(/\t/g, '\\t').
replace(/\n/g, '\\n').
replace(/\f/g, '\\f').
replace(/\r/g, '\\r').
replace(/'/g, '\\\'').
replace(/"/g, '\\"');
or string.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&")
see http://jsperf.com/string-escape-regexp-vs-json-stringify
*/
function srcEscape(str) {
return JSON.stringify({
[str]: 1,
}).slice(1, -3);
}
exports.srcEscape = srcEscape;
let highlightFn;
let cardinalRecommended = false;
try {
// the purpose of this is to prevent projects using Webpack from displaying a warning during runtime if cardinal is not a dependency
const REQUIRE_TERMINATOR = '';
highlightFn = require(`cardinal${REQUIRE_TERMINATOR}`).highlight;
} catch (err) {
highlightFn = (text) => {
if (!cardinalRecommended) {
// eslint-disable-next-line no-console
console.log('For nicer debug output consider install cardinal@^2.0.0');
cardinalRecommended = true;
}
return text;
};
}
/**
* Prints debug message with code frame, will try to use `cardinal` if available.
*/
function printDebugWithCode(msg, code) {
// eslint-disable-next-line no-console
console.log(`\n\n${msg}:\n`);
// eslint-disable-next-line no-console
console.log(`${highlightFn(code)}\n`);
}
exports.printDebugWithCode = printDebugWithCode;
/**
* checks whether the `type` is in the `list`
*/
function typeMatch(type, list, Types) {
if (Array.isArray(list)) {
return list.some((t) => type === Types[t]);
}
return !!list;
}
exports.typeMatch = typeMatch;
const privateObjectProps = new Set([
'__defineGetter__',
'__defineSetter__',
'__lookupGetter__',
'__lookupSetter__',
'__proto__',
]);
exports.privateObjectProps = privateObjectProps;
const fieldEscape = (field, isEval = true) => {
if (privateObjectProps.has(field)) {
throw new Error(
`The field name (${field}) can't be the same as an object's private property.`
);
}
return isEval ? srcEscape(field) : field;
};
exports.fieldEscape = fieldEscape;

195
node_modules/mysql2/lib/packet_parser.js generated vendored Normal file
View File

@@ -0,0 +1,195 @@
'use strict';
const Packet = require('./packets/packet.js');
const MAX_PACKET_LENGTH = 16777215;
function readPacketLength(b, off) {
const b0 = b[off];
const b1 = b[off + 1];
const b2 = b[off + 2];
if (b1 + b2 === 0) {
return b0;
}
return b0 + (b1 << 8) + (b2 << 16);
}
class PacketParser {
constructor(onPacket, packetHeaderLength) {
// 4 for normal packets, 7 for comprssed protocol packets
if (typeof packetHeaderLength === 'undefined') {
packetHeaderLength = 4;
}
// array of last payload chunks
// only used when current payload is not complete
this.buffer = [];
// total length of chunks on buffer
this.bufferLength = 0;
this.packetHeaderLength = packetHeaderLength;
// incomplete header state: number of header bytes received
this.headerLen = 0;
// expected payload length
this.length = 0;
this.largePacketParts = [];
this.firstPacketSequenceId = 0;
this.onPacket = onPacket;
this.execute = PacketParser.prototype.executeStart;
this._flushLargePacket =
packetHeaderLength === 7
? this._flushLargePacket7
: this._flushLargePacket4;
}
_flushLargePacket4() {
const numPackets = this.largePacketParts.length;
this.largePacketParts.unshift(Buffer.from([0, 0, 0, 0])); // insert header
const body = Buffer.concat(this.largePacketParts);
const packet = new Packet(this.firstPacketSequenceId, body, 0, body.length);
this.largePacketParts.length = 0;
packet.numPackets = numPackets;
this.onPacket(packet);
}
_flushLargePacket7() {
const numPackets = this.largePacketParts.length;
this.largePacketParts.unshift(Buffer.from([0, 0, 0, 0, 0, 0, 0])); // insert header
const body = Buffer.concat(this.largePacketParts);
this.largePacketParts.length = 0;
const packet = new Packet(this.firstPacketSequenceId, body, 0, body.length);
packet.numPackets = numPackets;
this.onPacket(packet);
}
executeStart(chunk) {
let start = 0;
const end = chunk.length;
while (end - start >= 3) {
this.length = readPacketLength(chunk, start);
if (end - start >= this.length + this.packetHeaderLength) {
// at least one full packet
const sequenceId = chunk[start + 3];
if (
this.length < MAX_PACKET_LENGTH &&
this.largePacketParts.length === 0
) {
this.onPacket(
new Packet(
sequenceId,
chunk,
start,
start + this.packetHeaderLength + this.length
)
);
} else {
// first large packet - remember it's id
if (this.largePacketParts.length === 0) {
this.firstPacketSequenceId = sequenceId;
}
this.largePacketParts.push(
chunk.slice(
start + this.packetHeaderLength,
start + this.packetHeaderLength + this.length
)
);
if (this.length < MAX_PACKET_LENGTH) {
this._flushLargePacket();
}
}
start += this.packetHeaderLength + this.length;
} else {
// payload is incomplete
this.buffer = [chunk.slice(start + 3, end)];
this.bufferLength = end - start - 3;
this.execute = PacketParser.prototype.executePayload;
return;
}
}
if (end - start > 0) {
// there is start of length header, but it's not full 3 bytes
this.headerLen = end - start; // 1 or 2 bytes
this.length = chunk[start];
if (this.headerLen === 2) {
this.length = chunk[start] + (chunk[start + 1] << 8);
this.execute = PacketParser.prototype.executeHeader3;
} else {
this.execute = PacketParser.prototype.executeHeader2;
}
}
}
executePayload(chunk) {
let start = 0;
const end = chunk.length;
const remainingPayload =
this.length - this.bufferLength + this.packetHeaderLength - 3;
if (end - start >= remainingPayload) {
// last chunk for payload
const payload = Buffer.allocUnsafe(this.length + this.packetHeaderLength);
let offset = 3;
for (let i = 0; i < this.buffer.length; ++i) {
this.buffer[i].copy(payload, offset);
offset += this.buffer[i].length;
}
chunk.copy(payload, offset, start, start + remainingPayload);
const sequenceId = payload[3];
if (
this.length < MAX_PACKET_LENGTH &&
this.largePacketParts.length === 0
) {
this.onPacket(
new Packet(
sequenceId,
payload,
0,
this.length + this.packetHeaderLength
)
);
} else {
// first large packet - remember it's id
if (this.largePacketParts.length === 0) {
this.firstPacketSequenceId = sequenceId;
}
this.largePacketParts.push(
payload.slice(
this.packetHeaderLength,
this.packetHeaderLength + this.length
)
);
if (this.length < MAX_PACKET_LENGTH) {
this._flushLargePacket();
}
}
this.buffer = [];
this.bufferLength = 0;
this.execute = PacketParser.prototype.executeStart;
start += remainingPayload;
if (end - start > 0) {
return this.execute(chunk.slice(start, end));
}
} else {
this.buffer.push(chunk);
this.bufferLength += chunk.length;
}
return null;
}
executeHeader2(chunk) {
this.length += chunk[0] << 8;
if (chunk.length > 1) {
this.length += chunk[1] << 16;
this.execute = PacketParser.prototype.executePayload;
return this.executePayload(chunk.slice(2));
}
this.execute = PacketParser.prototype.executeHeader3;
return null;
}
executeHeader3(chunk) {
this.length += chunk[0] << 16;
this.execute = PacketParser.prototype.executePayload;
return this.executePayload(chunk.slice(1));
}
}
module.exports = PacketParser;

35
node_modules/mysql2/lib/packets/auth_next_factor.js generated vendored Normal file
View File

@@ -0,0 +1,35 @@
// Copyright (c) 2021, Oracle and/or its affiliates.
'use strict';
const Packet = require('../packets/packet');
class AuthNextFactor {
constructor(opts) {
this.pluginName = opts.pluginName;
this.pluginData = opts.pluginData;
}
toPacket(encoding) {
const length = 6 + this.pluginName.length + this.pluginData.length;
const buffer = Buffer.allocUnsafe(length);
const packet = new Packet(0, buffer, 0, length);
packet.offset = 4;
packet.writeInt8(0x02);
packet.writeNullTerminatedString(this.pluginName, encoding);
packet.writeBuffer(this.pluginData);
return packet;
}
static fromPacket(packet, encoding) {
packet.readInt8(); // marker
const name = packet.readNullTerminatedString(encoding);
const data = packet.readBuffer();
return new AuthNextFactor({
pluginName: name,
pluginData: data,
});
}
}
module.exports = AuthNextFactor;

38
node_modules/mysql2/lib/packets/auth_switch_request.js generated vendored Normal file
View File

@@ -0,0 +1,38 @@
'use strict';
// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::AuthSwitchRequest
const Packet = require('../packets/packet');
class AuthSwitchRequest {
constructor(opts) {
this.pluginName = opts.pluginName;
this.pluginData = opts.pluginData;
}
toPacket() {
const length = 6 + this.pluginName.length + this.pluginData.length;
const buffer = Buffer.allocUnsafe(length);
const packet = new Packet(0, buffer, 0, length);
packet.offset = 4;
packet.writeInt8(0xfe);
// TODO: use server encoding
packet.writeNullTerminatedString(this.pluginName, 'cesu8');
packet.writeBuffer(this.pluginData);
return packet;
}
static fromPacket(packet) {
packet.readInt8(); // marker
// assert marker == 0xfe?
// TODO: use server encoding
const name = packet.readNullTerminatedString('cesu8');
const data = packet.readBuffer();
return new AuthSwitchRequest({
pluginName: name,
pluginData: data,
});
}
}
module.exports = AuthSwitchRequest;

View File

@@ -0,0 +1,33 @@
'use strict';
// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::AuthSwitchRequest
const Packet = require('../packets/packet');
class AuthSwitchRequestMoreData {
constructor(data) {
this.data = data;
}
toPacket() {
const length = 5 + this.data.length;
const buffer = Buffer.allocUnsafe(length);
const packet = new Packet(0, buffer, 0, length);
packet.offset = 4;
packet.writeInt8(0x01);
packet.writeBuffer(this.data);
return packet;
}
static fromPacket(packet) {
packet.readInt8(); // marker
const data = packet.readBuffer();
return new AuthSwitchRequestMoreData(data);
}
static verifyMarker(packet) {
return packet.peekByte() === 0x01;
}
}
module.exports = AuthSwitchRequestMoreData;

View File

@@ -0,0 +1,30 @@
'use strict';
// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::AuthSwitchRequest
const Packet = require('../packets/packet');
class AuthSwitchResponse {
constructor(data) {
if (!Buffer.isBuffer(data)) {
data = Buffer.from(data);
}
this.data = data;
}
toPacket() {
const length = 4 + this.data.length;
const buffer = Buffer.allocUnsafe(length);
const packet = new Packet(0, buffer, 0, length);
packet.offset = 4;
packet.writeBuffer(this.data);
return packet;
}
static fromPacket(packet) {
const data = packet.readBuffer();
return new AuthSwitchResponse(data);
}
}
module.exports = AuthSwitchResponse;

95
node_modules/mysql2/lib/packets/binary_row.js generated vendored Normal file
View File

@@ -0,0 +1,95 @@
'use strict';
const Types = require('../constants/types');
const Packet = require('../packets/packet');
const binaryReader = new Array(256);
class BinaryRow {
constructor(columns) {
this.columns = columns || [];
}
static toPacket(columns, encoding) {
// throw new Error('Not implemented');
const sequenceId = 0; // TODO remove, this is calculated now in connecton
let length = 0;
columns.forEach((val) => {
if (val === null || typeof val === 'undefined') {
++length;
return;
}
length += Packet.lengthCodedStringLength(val.toString(10), encoding);
});
length = length + 2;
const buffer = Buffer.allocUnsafe(length + 4);
const packet = new Packet(sequenceId, buffer, 0, length + 4);
packet.offset = 4;
packet.writeInt8(0);
let bitmap = 0;
let bitValue = 1;
columns.forEach((parameter) => {
if (parameter.type === Types.NULL) {
bitmap += bitValue;
}
bitValue *= 2;
if (bitValue === 256) {
packet.writeInt8(bitmap);
bitmap = 0;
bitValue = 1;
}
});
if (bitValue !== 1) {
packet.writeInt8(bitmap);
}
columns.forEach((val) => {
if (val === null) {
packet.writeNull();
return;
}
if (typeof val === 'undefined') {
packet.writeInt8(0);
return;
}
packet.writeLengthCodedString(val.toString(10), encoding);
});
return packet;
}
// TODO: complete list of types...
static fromPacket(fields, packet) {
const columns = new Array(fields.length);
packet.readInt8(); // TODO check it's 0
const nullBitmapLength = Math.floor((fields.length + 7 + 2) / 8);
// TODO: read and interpret null bitmap
packet.skip(nullBitmapLength);
for (let i = 0; i < columns.length; ++i) {
columns[i] = binaryReader[fields[i].columnType].apply(packet);
}
return new BinaryRow(columns);
}
}
// TODO: replace with constants.MYSQL_TYPE_*
binaryReader[Types.DECIMAL] = Packet.prototype.readLengthCodedString;
binaryReader[1] = Packet.prototype.readInt8; // tiny
binaryReader[2] = Packet.prototype.readInt16; // short
binaryReader[3] = Packet.prototype.readInt32; // long
binaryReader[4] = Packet.prototype.readFloat; // float
binaryReader[5] = Packet.prototype.readDouble; // double
binaryReader[6] = Packet.prototype.assertInvalid; // null, should be skipped vie null bitmap
binaryReader[7] = Packet.prototype.readTimestamp; // timestamp, http://dev.mysql.com/doc/internals/en/prepared-statements.html#packet-ProtocolBinary::MYSQL_TYPE_TIMESTAMP
binaryReader[8] = Packet.prototype.readInt64; // long long
binaryReader[9] = Packet.prototype.readInt32; // int24
binaryReader[10] = Packet.prototype.readTimestamp; // date
binaryReader[11] = Packet.prototype.readTime; // time, http://dev.mysql.com/doc/internals/en/prepared-statements.html#packet-ProtocolBinary::MYSQL_TYPE_TIME
binaryReader[12] = Packet.prototype.readDateTime; // datetime, http://dev.mysql.com/doc/internals/en/prepared-statements.html#packet-ProtocolBinary::MYSQL_TYPE_DATETIME
binaryReader[13] = Packet.prototype.readInt16; // year
binaryReader[Types.VAR_STRING] = Packet.prototype.readLengthCodedString; // var string
module.exports = BinaryRow;

33
node_modules/mysql2/lib/packets/binlog_dump.js generated vendored Normal file
View File

@@ -0,0 +1,33 @@
'use strict';
// http://dev.mysql.com/doc/internals/en/com-binlog-dump.html#packet-COM_BINLOG_DUMP
const Packet = require('../packets/packet');
const CommandCodes = require('../constants/commands');
// TODO: add flag to constants
// 0x01 - BINLOG_DUMP_NON_BLOCK
// send EOF instead of blocking
class BinlogDump {
constructor(opts) {
this.binlogPos = opts.binlogPos || 0;
this.serverId = opts.serverId || 0;
this.flags = opts.flags || 0;
this.filename = opts.filename || '';
}
toPacket() {
const length = 15 + Buffer.byteLength(this.filename, 'utf8'); // TODO: should be ascii?
const buffer = Buffer.allocUnsafe(length);
const packet = new Packet(0, buffer, 0, length);
packet.offset = 4;
packet.writeInt8(CommandCodes.BINLOG_DUMP);
packet.writeInt32(this.binlogPos);
packet.writeInt16(this.flags);
packet.writeInt32(this.serverId);
packet.writeString(this.filename);
return packet;
}
}
module.exports = BinlogDump;

View File

@@ -0,0 +1,115 @@
'use strict';
// http://dev.mysql.com/doc/internals/en/query-event.html
const keys = {
FLAGS2: 0,
SQL_MODE: 1,
CATALOG: 2,
AUTO_INCREMENT: 3,
CHARSET: 4,
TIME_ZONE: 5,
CATALOG_NZ: 6,
LC_TIME_NAMES: 7,
CHARSET_DATABASE: 8,
TABLE_MAP_FOR_UPDATE: 9,
MASTER_DATA_WRITTEN: 10,
INVOKERS: 11,
UPDATED_DB_NAMES: 12,
MICROSECONDS: 3,
};
module.exports = function parseStatusVars(buffer) {
const result = {};
let offset = 0;
let key, length, prevOffset;
while (offset < buffer.length) {
key = buffer[offset++];
switch (key) {
case keys.FLAGS2:
result.flags = buffer.readUInt32LE(offset);
offset += 4;
break;
case keys.SQL_MODE:
// value is 8 bytes, but all dcumented flags are in first 4 bytes
result.sqlMode = buffer.readUInt32LE(offset);
offset += 8;
break;
case keys.CATALOG:
length = buffer[offset++];
result.catalog = buffer.toString('utf8', offset, offset + length);
offset += length + 1; // null byte after string
break;
case keys.CHARSET:
result.clientCharset = buffer.readUInt16LE(offset);
result.connectionCollation = buffer.readUInt16LE(offset + 2);
result.serverCharset = buffer.readUInt16LE(offset + 4);
offset += 6;
break;
case keys.TIME_ZONE:
length = buffer[offset++];
result.timeZone = buffer.toString('utf8', offset, offset + length);
offset += length; // no null byte
break;
case keys.CATALOG_NZ:
length = buffer[offset++];
result.catalogNz = buffer.toString('utf8', offset, offset + length);
offset += length; // no null byte
break;
case keys.LC_TIME_NAMES:
result.lcTimeNames = buffer.readUInt16LE(offset);
offset += 2;
break;
case keys.CHARSET_DATABASE:
result.schemaCharset = buffer.readUInt16LE(offset);
offset += 2;
break;
case keys.TABLE_MAP_FOR_UPDATE:
result.mapForUpdate1 = buffer.readUInt32LE(offset);
result.mapForUpdate2 = buffer.readUInt32LE(offset + 4);
offset += 8;
break;
case keys.MASTER_DATA_WRITTEN:
result.masterDataWritten = buffer.readUInt32LE(offset);
offset += 4;
break;
case keys.INVOKERS:
length = buffer[offset++];
result.invokerUsername = buffer.toString(
'utf8',
offset,
offset + length
);
offset += length;
length = buffer[offset++];
result.invokerHostname = buffer.toString(
'utf8',
offset,
offset + length
);
offset += length;
break;
case keys.UPDATED_DB_NAMES:
length = buffer[offset++];
// length - number of null-terminated strings
result.updatedDBs = []; // we'll store them as array here
for (; length; --length) {
prevOffset = offset;
// fast forward to null terminating byte
while (buffer[offset++] && offset < buffer.length) {
// empty body, everything inside while condition
}
result.updatedDBs.push(
buffer.toString('utf8', prevOffset, offset - 1)
);
}
break;
case keys.MICROSECONDS:
result.microseconds =
// REVIEW: INVALID UNKNOWN VARIABLE!
buffer.readInt16LE(offset) + (buffer[offset + 2] << 16);
offset += 3;
}
}
return result;
};

97
node_modules/mysql2/lib/packets/change_user.js generated vendored Normal file
View File

@@ -0,0 +1,97 @@
'use strict';
const CommandCode = require('../constants/commands.js');
const ClientConstants = require('../constants/client.js');
const Packet = require('../packets/packet.js');
const auth41 = require('../auth_41.js');
const CharsetToEncoding = require('../constants/charset_encodings.js');
// https://dev.mysql.com/doc/internals/en/com-change-user.html#packet-COM_CHANGE_USER
class ChangeUser {
constructor(opts) {
this.flags = opts.flags;
this.user = opts.user || '';
this.database = opts.database || '';
this.password = opts.password || '';
this.passwordSha1 = opts.passwordSha1;
this.authPluginData1 = opts.authPluginData1;
this.authPluginData2 = opts.authPluginData2;
this.connectAttributes = opts.connectAttrinutes || {};
let authToken;
if (this.passwordSha1) {
authToken = auth41.calculateTokenFromPasswordSha(
this.passwordSha1,
this.authPluginData1,
this.authPluginData2
);
} else {
authToken = auth41.calculateToken(
this.password,
this.authPluginData1,
this.authPluginData2
);
}
this.authToken = authToken;
this.charsetNumber = opts.charsetNumber;
}
// TODO
// ChangeUser.fromPacket = function(packet)
// };
serializeToBuffer(buffer) {
const isSet = (flag) => this.flags & ClientConstants[flag];
const packet = new Packet(0, buffer, 0, buffer.length);
packet.offset = 4;
const encoding = CharsetToEncoding[this.charsetNumber];
packet.writeInt8(CommandCode.CHANGE_USER);
packet.writeNullTerminatedString(this.user, encoding);
if (isSet('SECURE_CONNECTION')) {
packet.writeInt8(this.authToken.length);
packet.writeBuffer(this.authToken);
} else {
packet.writeBuffer(this.authToken);
packet.writeInt8(0);
}
packet.writeNullTerminatedString(this.database, encoding);
packet.writeInt16(this.charsetNumber);
if (isSet('PLUGIN_AUTH')) {
// TODO: read this from parameters
packet.writeNullTerminatedString('mysql_native_password', 'latin1');
}
if (isSet('CONNECT_ATTRS')) {
const connectAttributes = this.connectAttributes;
const attrNames = Object.keys(connectAttributes);
let keysLength = 0;
for (let k = 0; k < attrNames.length; ++k) {
keysLength += Packet.lengthCodedStringLength(attrNames[k], encoding);
keysLength += Packet.lengthCodedStringLength(
connectAttributes[attrNames[k]],
encoding
);
}
packet.writeLengthCodedNumber(keysLength);
for (let k = 0; k < attrNames.length; ++k) {
packet.writeLengthCodedString(attrNames[k], encoding);
packet.writeLengthCodedString(
connectAttributes[attrNames[k]],
encoding
);
}
}
return packet;
}
toPacket() {
if (typeof this.user !== 'string') {
throw new Error('"user" connection config property must be a string');
}
if (typeof this.database !== 'string') {
throw new Error('"database" connection config property must be a string');
}
// dry run: calculate resulting packet length
const p = this.serializeToBuffer(Packet.MockBuffer());
return this.serializeToBuffer(Buffer.allocUnsafe(p.offset));
}
}
module.exports = ChangeUser;

21
node_modules/mysql2/lib/packets/close_statement.js generated vendored Normal file
View File

@@ -0,0 +1,21 @@
'use strict';
const Packet = require('../packets/packet');
const CommandCodes = require('../constants/commands');
class CloseStatement {
constructor(id) {
this.id = id;
}
// note: no response sent back
toPacket() {
const packet = new Packet(0, Buffer.allocUnsafe(9), 0, 9);
packet.offset = 4;
packet.writeInt8(CommandCodes.STMT_CLOSE);
packet.writeInt32(this.id);
return packet;
}
}
module.exports = CloseStatement;

291
node_modules/mysql2/lib/packets/column_definition.js generated vendored Normal file
View File

@@ -0,0 +1,291 @@
'use strict';
const Packet = require('../packets/packet');
const StringParser = require('../parsers/string');
const CharsetToEncoding = require('../constants/charset_encodings.js');
const fields = ['catalog', 'schema', 'table', 'orgTable', 'name', 'orgName'];
// creating JS string is relatively expensive (compared to
// reading few bytes from buffer) because all string properties
// except for name are unlikely to be used we postpone
// string conversion until property access
//
// TODO: watch for integration benchmarks (one with real network buffer)
// there could be bad side effect as keeping reference to a buffer makes it
// sit in the memory longer (usually until final .query() callback)
// Latest v8 perform much better in regard to bufferer -> string conversion,
// at some point of time this optimisation might become unnecessary
// see https://github.com/sidorares/node-mysql2/pull/137
//
class ColumnDefinition {
constructor(packet, clientEncoding) {
this._buf = packet.buffer;
this._clientEncoding = clientEncoding;
this._catalogLength = packet.readLengthCodedNumber();
this._catalogStart = packet.offset;
packet.offset += this._catalogLength;
this._schemaLength = packet.readLengthCodedNumber();
this._schemaStart = packet.offset;
packet.offset += this._schemaLength;
this._tableLength = packet.readLengthCodedNumber();
this._tableStart = packet.offset;
packet.offset += this._tableLength;
this._orgTableLength = packet.readLengthCodedNumber();
this._orgTableStart = packet.offset;
packet.offset += this._orgTableLength;
// name is always used, don't make it lazy
const _nameLength = packet.readLengthCodedNumber();
const _nameStart = packet.offset;
packet.offset += _nameLength;
this._orgNameLength = packet.readLengthCodedNumber();
this._orgNameStart = packet.offset;
packet.offset += this._orgNameLength;
packet.skip(1); // length of the following fields (always 0x0c)
this.characterSet = packet.readInt16();
this.encoding = CharsetToEncoding[this.characterSet];
this.name = StringParser.decode(
this._buf,
this.encoding === 'binary' ? this._clientEncoding : this.encoding,
_nameStart,
_nameStart + _nameLength
);
this.columnLength = packet.readInt32();
this.columnType = packet.readInt8();
this.type = this.columnType;
this.flags = packet.readInt16();
this.decimals = packet.readInt8();
}
inspect() {
return {
catalog: this.catalog,
schema: this.schema,
name: this.name,
orgName: this.orgName,
table: this.table,
orgTable: this.orgTable,
characterSet: this.characterSet,
encoding: this.encoding,
columnLength: this.columnLength,
type: this.columnType,
flags: this.flags,
decimals: this.decimals,
};
}
[Symbol.for('nodejs.util.inspect.custom')](depth, inspectOptions, inspect) {
const Types = require('../constants/types.js');
const typeNames = [];
for (const t in Types) {
typeNames[Types[t]] = t;
}
const fiedFlags = require('../constants/field_flags.js');
const flagNames = [];
// TODO: respect inspectOptions.showHidden
//const inspectFlags = inspectOptions.showHidden ? this.flags : this.flags & ~fiedFlags.PRI_KEY;
const inspectFlags = this.flags;
for (const f in fiedFlags) {
if (inspectFlags & fiedFlags[f]) {
if (f === 'PRI_KEY') {
flagNames.push('PRIMARY KEY');
} else if (f === 'NOT_NULL') {
flagNames.push('NOT NULL');
} else if (f === 'BINARY') {
// ignore flag for now
} else if (f === 'MULTIPLE_KEY') {
// not sure if that should be part of inspection.
// in the schema usually this is part of index definition
// example: UNIQUE KEY `my_uniq_id` (`id_box_elements`,`id_router`)
// note that only first column has MULTIPLE_KEY flag set in this case
// so there is no good way of knowing that this is part of index just
// by looking at indifidual field flags
} else if (f === 'NO_DEFAULT_VALUE') {
// almost the same as NOT_NULL?
} else if (f === 'BLOB') {
// included in the type
} else if (f === 'UNSIGNED') {
// this should be first after type
} else if (f === 'TIMESTAMP') {
// timestamp flag is redundant for inspection - already included in type
} else if (f === 'ON_UPDATE_NOW') {
flagNames.push('ON UPDATE CURRENT_TIMESTAMP');
} else {
flagNames.push(f);
}
}
}
if (depth > 1) {
return inspect({
...this.inspect(),
typeName: typeNames[this.columnType],
flags: flagNames,
});
}
const isUnsigned = this.flags & fiedFlags.UNSIGNED;
let typeName = typeNames[this.columnType];
if (typeName === 'BLOB') {
// TODO: check for non-utf8mb4 encoding
if (this.columnLength === 4294967295) {
typeName = 'LONGTEXT';
} else if (this.columnLength === 67108860) {
typeName = 'MEDIUMTEXT';
} else if (this.columnLength === 262140) {
typeName = 'TEXT';
} else if (this.columnLength === 1020) {
// 255*4
typeName = 'TINYTEXT';
} else {
typeName = `BLOB(${this.columnLength})`;
}
} else if (typeName === 'VAR_STRING') {
// TODO: check for non-utf8mb4 encoding
typeName = `VARCHAR(${Math.ceil(this.columnLength / 4)})`;
} else if (typeName === 'TINY') {
if (
(this.columnLength === 3 && isUnsigned) ||
(this.columnLength === 4 && !isUnsigned)
) {
typeName = 'TINYINT';
} else {
typeName = `TINYINT(${this.columnLength})`;
}
} else if (typeName === 'LONGLONG') {
if (this.columnLength === 20) {
typeName = 'BIGINT';
} else {
typeName = `BIGINT(${this.columnLength})`;
}
} else if (typeName === 'SHORT') {
if (isUnsigned && this.columnLength === 5) {
typeName = 'SMALLINT';
} else if (!isUnsigned && this.columnLength === 6) {
typeName = 'SMALLINT';
} else {
typeName = `SMALLINT(${this.columnLength})`;
}
} else if (typeName === 'LONG') {
if (isUnsigned && this.columnLength === 10) {
typeName = 'INT';
} else if (!isUnsigned && this.columnLength === 11) {
typeName = 'INT';
} else {
typeName = `INT(${this.columnLength})`;
}
} else if (typeName === 'INT24') {
if (isUnsigned && this.columnLength === 8) {
typeName = 'MEDIUMINT';
} else if (!isUnsigned && this.columnLength === 9) {
typeName = 'MEDIUMINT';
} else {
typeName = `MEDIUMINT(${this.columnLength})`;
}
} else if (typeName === 'DOUBLE') {
// DOUBLE without modifiers is reported as DOUBLE(22, 31)
if (this.columnLength === 22 && this.decimals === 31) {
typeName = 'DOUBLE';
} else {
typeName = `DOUBLE(${this.columnLength},${this.decimals})`;
}
} else if (typeName === 'FLOAT') {
// FLOAT without modifiers is reported as FLOAT(12, 31)
if (this.columnLength === 12 && this.decimals === 31) {
typeName = 'FLOAT';
} else {
typeName = `FLOAT(${this.columnLength},${this.decimals})`;
}
} else if (typeName === 'NEWDECIMAL') {
if (this.columnLength === 11 && this.decimals === 0) {
typeName = 'DECIMAL';
} else if (this.decimals === 0) {
// not sure why, but DECIMAL(13) is reported as DECIMAL(14, 0)
// and DECIMAL(13, 9) is reported as NEWDECIMAL(15, 9)
if (isUnsigned) {
typeName = `DECIMAL(${this.columnLength})`;
} else {
typeName = `DECIMAL(${this.columnLength - 1})`;
}
} else {
typeName = `DECIMAL(${this.columnLength - 2},${this.decimals})`;
}
} else {
typeName = `${typeNames[this.columnType]}(${this.columnLength})`;
}
if (isUnsigned) {
typeName += ' UNSIGNED';
}
// TODO respect colors option
return `\`${this.name}\` ${[typeName, ...flagNames].join(' ')}`;
}
static toPacket(column, sequenceId) {
let length = 17; // = 4 padding + 1 + 12 for the rest
fields.forEach((field) => {
length += Packet.lengthCodedStringLength(
column[field],
CharsetToEncoding[column.characterSet]
);
});
const buffer = Buffer.allocUnsafe(length);
const packet = new Packet(sequenceId, buffer, 0, length);
function writeField(name) {
packet.writeLengthCodedString(
column[name],
CharsetToEncoding[column.characterSet]
);
}
packet.offset = 4;
fields.forEach(writeField);
packet.writeInt8(0x0c);
packet.writeInt16(column.characterSet);
packet.writeInt32(column.columnLength);
packet.writeInt8(column.columnType);
packet.writeInt16(column.flags);
packet.writeInt8(column.decimals);
packet.writeInt16(0); // filler
return packet;
}
// node-mysql compatibility: alias "db" to "schema"
get db() {
return this.schema;
}
}
const addString = function (name) {
Object.defineProperty(ColumnDefinition.prototype, name, {
get: function () {
const start = this[`_${name}Start`];
const end = start + this[`_${name}Length`];
const val = StringParser.decode(
this._buf,
this.encoding === 'binary' ? this._clientEncoding : this.encoding,
start,
end
);
Object.defineProperty(this, name, {
value: val,
writable: false,
configurable: false,
enumerable: false,
});
return val;
},
});
};
addString('catalog');
addString('schema');
addString('table');
addString('orgTable');
addString('orgName');
module.exports = ColumnDefinition;

214
node_modules/mysql2/lib/packets/execute.js generated vendored Normal file
View File

@@ -0,0 +1,214 @@
'use strict';
const CursorType = require('../constants/cursor');
const CommandCodes = require('../constants/commands');
const Types = require('../constants/types');
const Packet = require('../packets/packet');
const CharsetToEncoding = require('../constants/charset_encodings.js');
function isJSON(value) {
return (
Array.isArray(value) ||
value.constructor === Object ||
(typeof value.toJSON === 'function' && !Buffer.isBuffer(value))
);
}
/**
* Converts a value to an object describing type, String/Buffer representation and length
* @param {*} value
*/
function toParameter(value, encoding, timezone) {
let type = Types.VAR_STRING;
let length;
let writer = function (value) {
// eslint-disable-next-line no-invalid-this
return Packet.prototype.writeLengthCodedString.call(this, value, encoding);
};
if (value !== null) {
switch (typeof value) {
case 'undefined':
throw new TypeError('Bind parameters must not contain undefined');
case 'number':
type = Types.DOUBLE;
length = 8;
writer = Packet.prototype.writeDouble;
break;
case 'boolean':
value = value | 0;
type = Types.TINY;
length = 1;
writer = Packet.prototype.writeInt8;
break;
case 'object':
if (Object.prototype.toString.call(value) === '[object Date]') {
type = Types.DATETIME;
length = 12;
writer = function (value) {
// eslint-disable-next-line no-invalid-this
return Packet.prototype.writeDate.call(this, value, timezone);
};
} else if (isJSON(value)) {
value = JSON.stringify(value);
type = Types.JSON;
} else if (Buffer.isBuffer(value)) {
length = Packet.lengthCodedNumberLength(value.length) + value.length;
writer = Packet.prototype.writeLengthCodedBuffer;
}
break;
default:
value = value.toString();
}
} else {
value = '';
type = Types.NULL;
}
if (!length) {
length = Packet.lengthCodedStringLength(value, encoding);
}
return { value, type, length, writer };
}
class Execute {
constructor(id, parameters, charsetNumber, timezone) {
this.id = id;
this.parameters = parameters;
this.encoding = CharsetToEncoding[charsetNumber];
this.timezone = timezone;
}
static fromPacket(packet, encoding) {
const stmtId = packet.readInt32();
const flags = packet.readInt8();
const iterationCount = packet.readInt32();
let i = packet.offset;
while (i < packet.end - 1) {
if (
(packet.buffer[i + 1] === Types.VAR_STRING ||
packet.buffer[i + 1] === Types.NULL ||
packet.buffer[i + 1] === Types.DOUBLE ||
packet.buffer[i + 1] === Types.TINY ||
packet.buffer[i + 1] === Types.DATETIME ||
packet.buffer[i + 1] === Types.JSON) &&
packet.buffer[i] === 1 &&
packet.buffer[i + 2] === 0
) {
break;
} else {
packet.readInt8();
}
i++;
}
const types = [];
for (let i = packet.offset + 1; i < packet.end - 1; i++) {
if (
(packet.buffer[i] === Types.VAR_STRING ||
packet.buffer[i] === Types.NULL ||
packet.buffer[i] === Types.DOUBLE ||
packet.buffer[i] === Types.TINY ||
packet.buffer[i] === Types.DATETIME ||
packet.buffer[i] === Types.JSON) &&
packet.buffer[i + 1] === 0
) {
types.push(packet.buffer[i]);
packet.skip(2);
}
}
packet.skip(1);
const values = [];
for (let i = 0; i < types.length; i++) {
if (types[i] === Types.VAR_STRING) {
values.push(packet.readLengthCodedString(encoding));
} else if (types[i] === Types.DOUBLE) {
values.push(packet.readDouble());
} else if (types[i] === Types.TINY) {
values.push(packet.readInt8());
} else if (types[i] === Types.DATETIME) {
values.push(packet.readDateTime());
} else if (types[i] === Types.JSON) {
values.push(JSON.parse(packet.readLengthCodedString(encoding)));
}
if (types[i] === Types.NULL) {
values.push(null);
}
}
return { stmtId, flags, iterationCount, values };
}
toPacket() {
// TODO: don't try to calculate packet length in advance, allocate some big buffer in advance (header + 256 bytes?)
// and copy + reallocate if not enough
// 0 + 4 - length, seqId
// 4 + 1 - COM_EXECUTE
// 5 + 4 - stmtId
// 9 + 1 - flags
// 10 + 4 - iteration-count (always 1)
let length = 14;
let parameters;
if (this.parameters && this.parameters.length > 0) {
length += Math.floor((this.parameters.length + 7) / 8);
length += 1; // new-params-bound-flag
length += 2 * this.parameters.length; // type byte for each parameter if new-params-bound-flag is set
parameters = this.parameters.map((value) =>
toParameter(value, this.encoding, this.timezone)
);
length += parameters.reduce(
(accumulator, parameter) => accumulator + parameter.length,
0
);
}
const buffer = Buffer.allocUnsafe(length);
const packet = new Packet(0, buffer, 0, length);
packet.offset = 4;
packet.writeInt8(CommandCodes.STMT_EXECUTE);
packet.writeInt32(this.id);
packet.writeInt8(CursorType.NO_CURSOR); // flags
packet.writeInt32(1); // iteration-count, always 1
if (parameters) {
let bitmap = 0;
let bitValue = 1;
parameters.forEach((parameter) => {
if (parameter.type === Types.NULL) {
bitmap += bitValue;
}
bitValue *= 2;
if (bitValue === 256) {
packet.writeInt8(bitmap);
bitmap = 0;
bitValue = 1;
}
});
if (bitValue !== 1) {
packet.writeInt8(bitmap);
}
// TODO: explain meaning of the flag
// afaik, if set n*2 bytes with type of parameter are sent before parameters
// if not, previous execution types are used (TODO prooflink)
packet.writeInt8(1); // new-params-bound-flag
// Write parameter types
parameters.forEach((parameter) => {
packet.writeInt8(parameter.type); // field type
packet.writeInt8(0); // parameter flag
});
// Write parameter values
parameters.forEach((parameter) => {
if (parameter.type !== Types.NULL) {
parameter.writer.call(packet, parameter.value);
}
});
}
return packet;
}
}
module.exports = Execute;

112
node_modules/mysql2/lib/packets/handshake.js generated vendored Normal file
View File

@@ -0,0 +1,112 @@
'use strict';
const Packet = require('../packets/packet');
const ClientConstants = require('../constants/client.js');
// https://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::Handshake
class Handshake {
constructor(args) {
this.protocolVersion = args.protocolVersion;
this.serverVersion = args.serverVersion;
this.capabilityFlags = args.capabilityFlags;
this.connectionId = args.connectionId;
this.authPluginData1 = args.authPluginData1;
this.authPluginData2 = args.authPluginData2;
this.characterSet = args.characterSet;
this.statusFlags = args.statusFlags;
this.authPluginName = args.authPluginName;
}
setScrambleData(cb) {
require('crypto').randomBytes(20, (err, data) => {
if (err) {
cb(err);
return;
}
this.authPluginData1 = data.slice(0, 8);
this.authPluginData2 = data.slice(8, 20);
cb();
});
}
toPacket(sequenceId) {
const length = 68 + Buffer.byteLength(this.serverVersion, 'utf8');
const buffer = Buffer.alloc(length + 4, 0); // zero fill, 10 bytes filler later needs to contain zeros
const packet = new Packet(sequenceId, buffer, 0, length + 4);
packet.offset = 4;
packet.writeInt8(this.protocolVersion);
packet.writeString(this.serverVersion, 'cesu8');
packet.writeInt8(0);
packet.writeInt32(this.connectionId);
packet.writeBuffer(this.authPluginData1);
packet.writeInt8(0);
const capabilityFlagsBuffer = Buffer.allocUnsafe(4);
capabilityFlagsBuffer.writeUInt32LE(this.capabilityFlags, 0);
packet.writeBuffer(capabilityFlagsBuffer.slice(0, 2));
packet.writeInt8(this.characterSet);
packet.writeInt16(this.statusFlags);
packet.writeBuffer(capabilityFlagsBuffer.slice(2, 4));
packet.writeInt8(21); // authPluginDataLength
packet.skip(10);
packet.writeBuffer(this.authPluginData2);
packet.writeInt8(0);
packet.writeString('mysql_native_password', 'latin1');
packet.writeInt8(0);
return packet;
}
static fromPacket(packet) {
const args = {};
args.protocolVersion = packet.readInt8();
args.serverVersion = packet.readNullTerminatedString('cesu8');
args.connectionId = packet.readInt32();
args.authPluginData1 = packet.readBuffer(8);
packet.skip(1);
const capabilityFlagsBuffer = Buffer.allocUnsafe(4);
capabilityFlagsBuffer[0] = packet.readInt8();
capabilityFlagsBuffer[1] = packet.readInt8();
if (packet.haveMoreData()) {
args.characterSet = packet.readInt8();
args.statusFlags = packet.readInt16();
// upper 2 bytes
capabilityFlagsBuffer[2] = packet.readInt8();
capabilityFlagsBuffer[3] = packet.readInt8();
args.capabilityFlags = capabilityFlagsBuffer.readUInt32LE(0);
if (args.capabilityFlags & ClientConstants.PLUGIN_AUTH) {
args.authPluginDataLength = packet.readInt8();
} else {
args.authPluginDataLength = 0;
packet.skip(1);
}
packet.skip(10);
} else {
args.capabilityFlags = capabilityFlagsBuffer.readUInt16LE(0);
}
const isSecureConnection =
args.capabilityFlags & ClientConstants.SECURE_CONNECTION;
if (isSecureConnection) {
const authPluginDataLength = args.authPluginDataLength;
if (authPluginDataLength === 0) {
// for Secure Password Authentication
args.authPluginDataLength = 20;
args.authPluginData2 = packet.readBuffer(12);
packet.skip(1);
} else {
// length > 0
// for Custom Auth Plugin (PLUGIN_AUTH)
const len = Math.max(13, authPluginDataLength - 8);
args.authPluginData2 = packet.readBuffer(len);
}
}
if (args.capabilityFlags & ClientConstants.PLUGIN_AUTH) {
args.authPluginName = packet.readNullTerminatedString('ascii');
}
return new Handshake(args);
}
}
module.exports = Handshake;

144
node_modules/mysql2/lib/packets/handshake_response.js generated vendored Normal file
View File

@@ -0,0 +1,144 @@
'use strict';
const ClientConstants = require('../constants/client.js');
const CharsetToEncoding = require('../constants/charset_encodings.js');
const Packet = require('../packets/packet.js');
const auth41 = require('../auth_41.js');
class HandshakeResponse {
constructor(handshake) {
this.user = handshake.user || '';
this.database = handshake.database || '';
this.password = handshake.password || '';
this.passwordSha1 = handshake.passwordSha1;
this.authPluginData1 = handshake.authPluginData1;
this.authPluginData2 = handshake.authPluginData2;
this.compress = handshake.compress;
this.clientFlags = handshake.flags;
// TODO: pre-4.1 auth support
let authToken;
if (this.passwordSha1) {
authToken = auth41.calculateTokenFromPasswordSha(
this.passwordSha1,
this.authPluginData1,
this.authPluginData2
);
} else {
authToken = auth41.calculateToken(
this.password,
this.authPluginData1,
this.authPluginData2
);
}
this.authToken = authToken;
this.charsetNumber = handshake.charsetNumber;
this.encoding = CharsetToEncoding[handshake.charsetNumber];
this.connectAttributes = handshake.connectAttributes;
}
serializeResponse(buffer) {
const isSet = (flag) => this.clientFlags & ClientConstants[flag];
const packet = new Packet(0, buffer, 0, buffer.length);
packet.offset = 4;
packet.writeInt32(this.clientFlags);
packet.writeInt32(0); // max packet size. todo: move to config
packet.writeInt8(this.charsetNumber);
packet.skip(23);
const encoding = this.encoding;
packet.writeNullTerminatedString(this.user, encoding);
let k;
if (isSet('PLUGIN_AUTH_LENENC_CLIENT_DATA')) {
packet.writeLengthCodedNumber(this.authToken.length);
packet.writeBuffer(this.authToken);
} else if (isSet('SECURE_CONNECTION')) {
packet.writeInt8(this.authToken.length);
packet.writeBuffer(this.authToken);
} else {
packet.writeBuffer(this.authToken);
packet.writeInt8(0);
}
if (isSet('CONNECT_WITH_DB')) {
packet.writeNullTerminatedString(this.database, encoding);
}
if (isSet('PLUGIN_AUTH')) {
// TODO: pass from config
packet.writeNullTerminatedString('mysql_native_password', 'latin1');
}
if (isSet('CONNECT_ATTRS')) {
const connectAttributes = this.connectAttributes || {};
const attrNames = Object.keys(connectAttributes);
let keysLength = 0;
for (k = 0; k < attrNames.length; ++k) {
keysLength += Packet.lengthCodedStringLength(attrNames[k], encoding);
keysLength += Packet.lengthCodedStringLength(
connectAttributes[attrNames[k]],
encoding
);
}
packet.writeLengthCodedNumber(keysLength);
for (k = 0; k < attrNames.length; ++k) {
packet.writeLengthCodedString(attrNames[k], encoding);
packet.writeLengthCodedString(
connectAttributes[attrNames[k]],
encoding
);
}
}
return packet;
}
toPacket() {
if (typeof this.user !== 'string') {
throw new Error('"user" connection config property must be a string');
}
if (typeof this.database !== 'string') {
throw new Error('"database" connection config property must be a string');
}
// dry run: calculate resulting packet length
const p = this.serializeResponse(Packet.MockBuffer());
return this.serializeResponse(Buffer.alloc(p.offset));
}
static fromPacket(packet) {
const args = {};
args.clientFlags = packet.readInt32();
function isSet(flag) {
return args.clientFlags & ClientConstants[flag];
}
args.maxPacketSize = packet.readInt32();
args.charsetNumber = packet.readInt8();
const encoding = CharsetToEncoding[args.charsetNumber];
args.encoding = encoding;
packet.skip(23);
args.user = packet.readNullTerminatedString(encoding);
let authTokenLength;
if (isSet('PLUGIN_AUTH_LENENC_CLIENT_DATA')) {
authTokenLength = packet.readLengthCodedNumber(encoding);
args.authToken = packet.readBuffer(authTokenLength);
} else if (isSet('SECURE_CONNECTION')) {
authTokenLength = packet.readInt8();
args.authToken = packet.readBuffer(authTokenLength);
} else {
args.authToken = packet.readNullTerminatedString(encoding);
}
if (isSet('CONNECT_WITH_DB')) {
args.database = packet.readNullTerminatedString(encoding);
}
if (isSet('PLUGIN_AUTH')) {
args.authPluginName = packet.readNullTerminatedString(encoding);
}
if (isSet('CONNECT_ATTRS')) {
const keysLength = packet.readLengthCodedNumber(encoding);
const keysEnd = packet.offset + keysLength;
const attrs = {};
while (packet.offset < keysEnd) {
attrs[packet.readLengthCodedString(encoding)] =
packet.readLengthCodedString(encoding);
}
args.connectAttributes = attrs;
}
return args;
}
}
module.exports = HandshakeResponse;

152
node_modules/mysql2/lib/packets/index.js generated vendored Normal file
View File

@@ -0,0 +1,152 @@
// This file was modified by Oracle on June 1, 2021.
// A utility method was introduced to generate an Error instance from a
// binary server packet.
// Modifications copyright (c) 2021, Oracle and/or its affiliates.
// This file was modified by Oracle on September 21, 2021.
// The new AuthNextFactor packet is now available.
// Modifications copyright (c) 2021, Oracle and/or its affiliates.
'use strict';
const process = require('process');
const AuthNextFactor = require('./auth_next_factor');
const AuthSwitchRequest = require('./auth_switch_request');
const AuthSwitchRequestMoreData = require('./auth_switch_request_more_data');
const AuthSwitchResponse = require('./auth_switch_response');
const BinaryRow = require('./binary_row');
const BinlogDump = require('./binlog_dump');
const ChangeUser = require('./change_user');
const CloseStatement = require('./close_statement');
const ColumnDefinition = require('./column_definition');
const Execute = require('./execute');
const Handshake = require('./handshake');
const HandshakeResponse = require('./handshake_response');
const PrepareStatement = require('./prepare_statement');
const PreparedStatementHeader = require('./prepared_statement_header');
const Query = require('./query');
const RegisterSlave = require('./register_slave');
const ResultSetHeader = require('./resultset_header');
const SSLRequest = require('./ssl_request');
const TextRow = require('./text_row');
const ctorMap = {
AuthNextFactor,
AuthSwitchRequest,
AuthSwitchRequestMoreData,
AuthSwitchResponse,
BinaryRow,
BinlogDump,
ChangeUser,
CloseStatement,
ColumnDefinition,
Execute,
Handshake,
HandshakeResponse,
PrepareStatement,
PreparedStatementHeader,
Query,
RegisterSlave,
ResultSetHeader,
SSLRequest,
TextRow,
};
Object.entries(ctorMap).forEach(([name, ctor]) => {
module.exports[name] = ctor;
// monkey-patch it to include name if debug is on
if (process.env.NODE_DEBUG) {
if (ctor.prototype.toPacket) {
const old = ctor.prototype.toPacket;
ctor.prototype.toPacket = function () {
const p = old.call(this);
p._name = name;
return p;
};
}
}
});
// simple packets:
const Packet = require('./packet');
exports.Packet = Packet;
class OK {
static toPacket(args, encoding) {
args = args || {};
const affectedRows = args.affectedRows || 0;
const insertId = args.insertId || 0;
const serverStatus = args.serverStatus || 0;
const warningCount = args.warningCount || 0;
const message = args.message || '';
let length = 9 + Packet.lengthCodedNumberLength(affectedRows);
length += Packet.lengthCodedNumberLength(insertId);
const buffer = Buffer.allocUnsafe(length);
const packet = new Packet(0, buffer, 0, length);
packet.offset = 4;
packet.writeInt8(0);
packet.writeLengthCodedNumber(affectedRows);
packet.writeLengthCodedNumber(insertId);
packet.writeInt16(serverStatus);
packet.writeInt16(warningCount);
packet.writeString(message, encoding);
packet._name = 'OK';
return packet;
}
}
exports.OK = OK;
// warnings, statusFlags
class EOF {
static toPacket(warnings, statusFlags) {
if (typeof warnings === 'undefined') {
warnings = 0;
}
if (typeof statusFlags === 'undefined') {
statusFlags = 0;
}
const packet = new Packet(0, Buffer.allocUnsafe(9), 0, 9);
packet.offset = 4;
packet.writeInt8(0xfe);
packet.writeInt16(warnings);
packet.writeInt16(statusFlags);
packet._name = 'EOF';
return packet;
}
}
exports.EOF = EOF;
class Error {
static toPacket(args, encoding) {
const length = 13 + Buffer.byteLength(args.message, 'utf8');
const packet = new Packet(0, Buffer.allocUnsafe(length), 0, length);
packet.offset = 4;
packet.writeInt8(0xff);
packet.writeInt16(args.code);
// TODO: sql state parameter
packet.writeString('#_____', encoding);
packet.writeString(args.message, encoding);
packet._name = 'Error';
return packet;
}
static fromPacket(packet) {
packet.readInt8(); // marker
const code = packet.readInt16();
packet.readString(1, 'ascii'); // sql state marker
// The SQL state of the ERR_Packet which is always 5 bytes long.
// https://dev.mysql.com/doc/dev/mysql-server/8.0.11/page_protocol_basic_dt_strings.html#sect_protocol_basic_dt_string_fix
packet.readString(5, 'ascii'); // sql state (ignore for now)
const message = packet.readNullTerminatedString('utf8');
const error = new Error();
error.message = message;
error.code = code;
return error;
}
}
exports.Error = Error;

931
node_modules/mysql2/lib/packets/packet.js generated vendored Normal file
View File

@@ -0,0 +1,931 @@
// This file was modified by Oracle on June 1, 2021.
// A comment describing some changes in the strict default SQL mode regarding
// non-standard dates was introduced.
// Modifications copyright (c) 2021, Oracle and/or its affiliates.
'use strict';
const ErrorCodeToName = require('../constants/errors.js');
const NativeBuffer = require('buffer').Buffer;
const Long = require('long');
const StringParser = require('../parsers/string.js');
const Types = require('../constants/types.js');
const INVALID_DATE = new Date(NaN);
// this is nearly duplicate of previous function so generated code is not slower
// due to "if (dateStrings)" branching
const pad = '000000000000';
function leftPad(num, value) {
const s = value.toString();
// if we don't need to pad
if (s.length >= num) {
return s;
}
return (pad + s).slice(-num);
}
// The whole reason parse* function below exist
// is because String creation is relatively expensive (at least with V8), and if we have
// a buffer with "12345" content ideally we would like to bypass intermediate
// "12345" string creation and directly build 12345 number out of
// <Buffer 31 32 33 34 35> data.
// In my benchmarks the difference is ~25M 8-digit numbers per second vs
// 4.5 M using Number(packet.readLengthCodedString())
// not used when size is close to max precision as series of *10 accumulate error
// and approximate result mihgt be diffreent from (approximate as well) Number(bigNumStringValue))
// In the futire node version if speed difference is smaller parse* functions might be removed
// don't consider them as Packet public API
const minus = '-'.charCodeAt(0);
const plus = '+'.charCodeAt(0);
// TODO: handle E notation
const dot = '.'.charCodeAt(0);
const exponent = 'e'.charCodeAt(0);
const exponentCapital = 'E'.charCodeAt(0);
class Packet {
constructor(id, buffer, start, end) {
// hot path, enable checks when testing only
// if (!Buffer.isBuffer(buffer) || typeof start == 'undefined' || typeof end == 'undefined')
// throw new Error('invalid packet');
this.sequenceId = id;
this.numPackets = 1;
this.buffer = buffer;
this.start = start;
this.offset = start + 4;
this.end = end;
}
// ==============================
// readers
// ==============================
reset() {
this.offset = this.start + 4;
}
length() {
return this.end - this.start;
}
slice() {
return this.buffer.slice(this.start, this.end);
}
dump() {
// eslint-disable-next-line no-console
console.log(
[this.buffer.asciiSlice(this.start, this.end)],
this.buffer.slice(this.start, this.end),
this.length(),
this.sequenceId
);
}
haveMoreData() {
return this.end > this.offset;
}
skip(num) {
this.offset += num;
}
readInt8() {
return this.buffer[this.offset++];
}
readInt16() {
this.offset += 2;
return this.buffer.readUInt16LE(this.offset - 2);
}
readInt24() {
return this.readInt16() + (this.readInt8() << 16);
}
readInt32() {
this.offset += 4;
return this.buffer.readUInt32LE(this.offset - 4);
}
readSInt8() {
return this.buffer.readInt8(this.offset++);
}
readSInt16() {
this.offset += 2;
return this.buffer.readInt16LE(this.offset - 2);
}
readSInt32() {
this.offset += 4;
return this.buffer.readInt32LE(this.offset - 4);
}
readInt64JSNumber() {
const word0 = this.readInt32();
const word1 = this.readInt32();
const l = new Long(word0, word1, true);
return l.toNumber();
}
readSInt64JSNumber() {
const word0 = this.readInt32();
const word1 = this.readInt32();
if (!(word1 & 0x80000000)) {
return word0 + 0x100000000 * word1;
}
const l = new Long(word0, word1, false);
return l.toNumber();
}
readInt64String() {
const word0 = this.readInt32();
const word1 = this.readInt32();
const res = new Long(word0, word1, true);
return res.toString();
}
readSInt64String() {
const word0 = this.readInt32();
const word1 = this.readInt32();
const res = new Long(word0, word1, false);
return res.toString();
}
readInt64() {
const word0 = this.readInt32();
const word1 = this.readInt32();
let res = new Long(word0, word1, true);
const resNumber = res.toNumber();
const resString = res.toString();
res = resNumber.toString() === resString ? resNumber : resString;
return res;
}
readSInt64() {
const word0 = this.readInt32();
const word1 = this.readInt32();
let res = new Long(word0, word1, false);
const resNumber = res.toNumber();
const resString = res.toString();
res = resNumber.toString() === resString ? resNumber : resString;
return res;
}
isEOF() {
return this.buffer[this.offset] === 0xfe && this.length() < 13;
}
eofStatusFlags() {
return this.buffer.readInt16LE(this.offset + 3);
}
eofWarningCount() {
return this.buffer.readInt16LE(this.offset + 1);
}
readLengthCodedNumber(bigNumberStrings, signed) {
const byte1 = this.buffer[this.offset++];
if (byte1 < 251) {
return byte1;
}
return this.readLengthCodedNumberExt(byte1, bigNumberStrings, signed);
}
readLengthCodedNumberSigned(bigNumberStrings) {
return this.readLengthCodedNumber(bigNumberStrings, true);
}
readLengthCodedNumberExt(tag, bigNumberStrings, signed) {
let word0, word1;
let res;
if (tag === 0xfb) {
return null;
}
if (tag === 0xfc) {
return this.readInt8() + (this.readInt8() << 8);
}
if (tag === 0xfd) {
return this.readInt8() + (this.readInt8() << 8) + (this.readInt8() << 16);
}
if (tag === 0xfe) {
// TODO: check version
// Up to MySQL 3.22, 0xfe was followed by a 4-byte integer.
word0 = this.readInt32();
word1 = this.readInt32();
if (word1 === 0) {
return word0; // don't convert to float if possible
}
if (word1 < 2097152) {
// max exact float point int, 2^52 / 2^32
return word1 * 0x100000000 + word0;
}
res = new Long(word0, word1, !signed); // Long need unsigned
const resNumber = res.toNumber();
const resString = res.toString();
res = resNumber.toString() === resString ? resNumber : resString;
return bigNumberStrings ? resString : res;
}
// eslint-disable-next-line no-console
console.trace();
throw new Error(`Should not reach here: ${tag}`);
}
readFloat() {
const res = this.buffer.readFloatLE(this.offset);
this.offset += 4;
return res;
}
readDouble() {
const res = this.buffer.readDoubleLE(this.offset);
this.offset += 8;
return res;
}
readBuffer(len) {
if (typeof len === 'undefined') {
len = this.end - this.offset;
}
this.offset += len;
return this.buffer.slice(this.offset - len, this.offset);
}
// DATE, DATETIME and TIMESTAMP
readDateTime(timezone) {
if (!timezone || timezone === 'Z' || timezone === 'local') {
const length = this.readInt8();
if (length === 0xfb) {
return null;
}
let y = 0;
let m = 0;
let d = 0;
let H = 0;
let M = 0;
let S = 0;
let ms = 0;
if (length > 3) {
y = this.readInt16();
m = this.readInt8();
d = this.readInt8();
}
if (length > 6) {
H = this.readInt8();
M = this.readInt8();
S = this.readInt8();
}
if (length > 10) {
ms = this.readInt32() / 1000;
}
// NO_ZERO_DATE mode and NO_ZERO_IN_DATE mode are part of the strict
// default SQL mode used by MySQL 8.0. This means that non-standard
// dates like '0000-00-00' become NULL. For older versions and other
// possible MySQL flavours we still need to account for the
// non-standard behaviour.
if (y + m + d + H + M + S + ms === 0) {
return INVALID_DATE;
}
if (timezone === 'Z') {
return new Date(Date.UTC(y, m - 1, d, H, M, S, ms));
}
return new Date(y, m - 1, d, H, M, S, ms);
}
let str = this.readDateTimeString(6, 'T', null);
if (str.length === 10) {
str += 'T00:00:00';
}
return new Date(str + timezone);
}
readDateTimeString(decimals, timeSep, columnType) {
const length = this.readInt8();
let y = 0;
let m = 0;
let d = 0;
let H = 0;
let M = 0;
let S = 0;
let ms = 0;
let str;
if (length > 3) {
y = this.readInt16();
m = this.readInt8();
d = this.readInt8();
str = [leftPad(4, y), leftPad(2, m), leftPad(2, d)].join('-');
}
if (length > 6) {
H = this.readInt8();
M = this.readInt8();
S = this.readInt8();
str += `${timeSep || ' '}${[
leftPad(2, H),
leftPad(2, M),
leftPad(2, S),
].join(':')}`;
} else if (columnType === Types.DATETIME) {
str += ' 00:00:00';
}
if (length > 10) {
ms = this.readInt32();
str += '.';
if (decimals) {
ms = leftPad(6, ms);
if (ms.length > decimals) {
ms = ms.substring(0, decimals); // rounding is done at the MySQL side, only 0 are here
}
}
str += ms;
}
return str;
}
// TIME - value as a string, Can be negative
readTimeString(convertTtoMs) {
const length = this.readInt8();
if (length === 0) {
return '00:00:00';
}
const sign = this.readInt8() ? -1 : 1; // 'isNegative' flag byte
let d = 0;
let H = 0;
let M = 0;
let S = 0;
let ms = 0;
if (length > 6) {
d = this.readInt32();
H = this.readInt8();
M = this.readInt8();
S = this.readInt8();
}
if (length > 10) {
ms = this.readInt32();
}
if (convertTtoMs) {
H += d * 24;
M += H * 60;
S += M * 60;
ms += S * 1000;
ms *= sign;
return ms;
}
// Format follows mySQL TIME format ([-][h]hh:mm:ss[.u[u[u[u[u[u]]]]]])
// For positive times below 24 hours, this makes it equal to ISO 8601 times
return (
(sign === -1 ? '-' : '') +
[leftPad(2, d * 24 + H), leftPad(2, M), leftPad(2, S)].join(':') +
(ms ? `.${ms}`.replace(/0+$/, '') : '')
);
}
readLengthCodedString(encoding) {
const len = this.readLengthCodedNumber();
// TODO: check manually first byte here to avoid polymorphic return type?
if (len === null) {
return null;
}
this.offset += len;
// TODO: Use characterSetCode to get proper encoding
// https://github.com/sidorares/node-mysql2/pull/374
return StringParser.decode(
this.buffer,
encoding,
this.offset - len,
this.offset
);
}
readLengthCodedBuffer() {
const len = this.readLengthCodedNumber();
if (len === null) {
return null;
}
return this.readBuffer(len);
}
readNullTerminatedString(encoding) {
const start = this.offset;
let end = this.offset;
while (this.buffer[end]) {
end = end + 1; // TODO: handle OOB check
}
this.offset = end + 1;
return StringParser.decode(this.buffer, encoding, start, end);
}
// TODO reuse?
readString(len, encoding) {
if (typeof len === 'string' && typeof encoding === 'undefined') {
encoding = len;
len = undefined;
}
if (typeof len === 'undefined') {
len = this.end - this.offset;
}
this.offset += len;
return StringParser.decode(
this.buffer,
encoding,
this.offset - len,
this.offset
);
}
parseInt(len, supportBigNumbers) {
if (len === null) {
return null;
}
if (len >= 14 && !supportBigNumbers) {
const s = this.buffer.toString('ascii', this.offset, this.offset + len);
this.offset += len;
return Number(s);
}
let result = 0;
const start = this.offset;
const end = this.offset + len;
let sign = 1;
if (len === 0) {
return 0; // TODO: assert? exception?
}
if (this.buffer[this.offset] === minus) {
this.offset++;
sign = -1;
}
// max precise int is 9007199254740992
let str;
const numDigits = end - this.offset;
if (supportBigNumbers) {
if (numDigits >= 15) {
str = this.readString(end - this.offset, 'binary');
result = parseInt(str, 10);
if (result.toString() === str) {
return sign * result;
}
return sign === -1 ? `-${str}` : str;
}
if (numDigits > 16) {
str = this.readString(end - this.offset);
return sign === -1 ? `-${str}` : str;
}
}
if (this.buffer[this.offset] === plus) {
this.offset++; // just ignore
}
while (this.offset < end) {
result *= 10;
result += this.buffer[this.offset] - 48;
this.offset++;
}
const num = result * sign;
if (!supportBigNumbers) {
return num;
}
str = this.buffer.toString('ascii', start, end);
if (num.toString() === str) {
return num;
}
return str;
}
// note that if value of inputNumberAsString is bigger than MAX_SAFE_INTEGER
// ( or smaller than MIN_SAFE_INTEGER ) the parseIntNoBigCheck result might be
// different from what you would get from Number(inputNumberAsString)
// String(parseIntNoBigCheck) <> String(Number(inputNumberAsString)) <> inputNumberAsString
parseIntNoBigCheck(len) {
if (len === null) {
return null;
}
let result = 0;
const end = this.offset + len;
let sign = 1;
if (len === 0) {
return 0; // TODO: assert? exception?
}
if (this.buffer[this.offset] === minus) {
this.offset++;
sign = -1;
}
if (this.buffer[this.offset] === plus) {
this.offset++; // just ignore
}
while (this.offset < end) {
result *= 10;
result += this.buffer[this.offset] - 48;
this.offset++;
}
return result * sign;
}
// copy-paste from https://github.com/mysqljs/mysql/blob/master/lib/protocol/Parser.js
parseGeometryValue() {
const buffer = this.readLengthCodedBuffer();
let offset = 4;
if (buffer === null || !buffer.length) {
return null;
}
function parseGeometry() {
let x, y, i, j, numPoints, line;
let result = null;
const byteOrder = buffer.readUInt8(offset);
offset += 1;
const wkbType = byteOrder
? buffer.readUInt32LE(offset)
: buffer.readUInt32BE(offset);
offset += 4;
switch (wkbType) {
case 1: // WKBPoint
x = byteOrder
? buffer.readDoubleLE(offset)
: buffer.readDoubleBE(offset);
offset += 8;
y = byteOrder
? buffer.readDoubleLE(offset)
: buffer.readDoubleBE(offset);
offset += 8;
result = { x: x, y: y };
break;
case 2: // WKBLineString
numPoints = byteOrder
? buffer.readUInt32LE(offset)
: buffer.readUInt32BE(offset);
offset += 4;
result = [];
for (i = numPoints; i > 0; i--) {
x = byteOrder
? buffer.readDoubleLE(offset)
: buffer.readDoubleBE(offset);
offset += 8;
y = byteOrder
? buffer.readDoubleLE(offset)
: buffer.readDoubleBE(offset);
offset += 8;
result.push({ x: x, y: y });
}
break;
case 3: // WKBPolygon
// eslint-disable-next-line no-case-declarations
const numRings = byteOrder
? buffer.readUInt32LE(offset)
: buffer.readUInt32BE(offset);
offset += 4;
result = [];
for (i = numRings; i > 0; i--) {
numPoints = byteOrder
? buffer.readUInt32LE(offset)
: buffer.readUInt32BE(offset);
offset += 4;
line = [];
for (j = numPoints; j > 0; j--) {
x = byteOrder
? buffer.readDoubleLE(offset)
: buffer.readDoubleBE(offset);
offset += 8;
y = byteOrder
? buffer.readDoubleLE(offset)
: buffer.readDoubleBE(offset);
offset += 8;
line.push({ x: x, y: y });
}
result.push(line);
}
break;
case 4: // WKBMultiPoint
case 5: // WKBMultiLineString
case 6: // WKBMultiPolygon
case 7: // WKBGeometryCollection
// eslint-disable-next-line no-case-declarations
const num = byteOrder
? buffer.readUInt32LE(offset)
: buffer.readUInt32BE(offset);
offset += 4;
result = [];
for (i = num; i > 0; i--) {
result.push(parseGeometry());
}
break;
}
return result;
}
return parseGeometry();
}
parseVector() {
const bufLen = this.readLengthCodedNumber();
const vectorEnd = this.offset + bufLen;
const result = [];
while (this.offset < vectorEnd && this.offset < this.end) {
result.push(this.readFloat());
}
return result;
}
parseDate(timezone) {
const strLen = this.readLengthCodedNumber();
if (strLen === null) {
return null;
}
if (strLen !== 10) {
// we expect only YYYY-MM-DD here.
// if for some reason it's not the case return invalid date
return new Date(NaN);
}
const y = this.parseInt(4);
this.offset++; // -
const m = this.parseInt(2);
this.offset++; // -
const d = this.parseInt(2);
if (!timezone || timezone === 'local') {
return new Date(y, m - 1, d);
}
if (timezone === 'Z') {
return new Date(Date.UTC(y, m - 1, d));
}
return new Date(
`${leftPad(4, y)}-${leftPad(2, m)}-${leftPad(2, d)}T00:00:00${timezone}`
);
}
parseDateTime(timezone) {
const str = this.readLengthCodedString('binary');
if (str === null) {
return null;
}
if (!timezone || timezone === 'local') {
return new Date(str);
}
return new Date(`${str}${timezone}`);
}
parseFloat(len) {
if (len === null) {
return null;
}
let result = 0;
const end = this.offset + len;
let factor = 1;
let pastDot = false;
let charCode = 0;
if (len === 0) {
return 0; // TODO: assert? exception?
}
if (this.buffer[this.offset] === minus) {
this.offset++;
factor = -1;
}
if (this.buffer[this.offset] === plus) {
this.offset++; // just ignore
}
while (this.offset < end) {
charCode = this.buffer[this.offset];
if (charCode === dot) {
pastDot = true;
this.offset++;
} else if (charCode === exponent || charCode === exponentCapital) {
this.offset++;
const exponentValue = this.parseInt(end - this.offset);
return (result / factor) * Math.pow(10, exponentValue);
} else {
result *= 10;
result += this.buffer[this.offset] - 48;
this.offset++;
if (pastDot) {
factor = factor * 10;
}
}
}
return result / factor;
}
parseLengthCodedIntNoBigCheck() {
return this.parseIntNoBigCheck(this.readLengthCodedNumber());
}
parseLengthCodedInt(supportBigNumbers) {
return this.parseInt(this.readLengthCodedNumber(), supportBigNumbers);
}
parseLengthCodedIntString() {
return this.readLengthCodedString('binary');
}
parseLengthCodedFloat() {
return this.parseFloat(this.readLengthCodedNumber());
}
peekByte() {
return this.buffer[this.offset];
}
// OxFE is often used as "Alt" flag - not ok, not error.
// For example, it's first byte of AuthSwitchRequest
isAlt() {
return this.peekByte() === 0xfe;
}
isError() {
return this.peekByte() === 0xff;
}
asError(encoding) {
this.reset();
this.readInt8(); // fieldCount
const errorCode = this.readInt16();
let sqlState = '';
if (this.buffer[this.offset] === 0x23) {
this.skip(1);
sqlState = this.readBuffer(5).toString();
}
const message = this.readString(undefined, encoding);
const err = new Error(message);
err.code = ErrorCodeToName[errorCode];
err.errno = errorCode;
err.sqlState = sqlState;
err.sqlMessage = message;
return err;
}
writeInt32(n) {
this.buffer.writeUInt32LE(n, this.offset);
this.offset += 4;
}
writeInt24(n) {
this.writeInt8(n & 0xff);
this.writeInt16(n >> 8);
}
writeInt16(n) {
this.buffer.writeUInt16LE(n, this.offset);
this.offset += 2;
}
writeInt8(n) {
this.buffer.writeUInt8(n, this.offset);
this.offset++;
}
writeDouble(n) {
this.buffer.writeDoubleLE(n, this.offset);
this.offset += 8;
}
writeBuffer(b) {
b.copy(this.buffer, this.offset);
this.offset += b.length;
}
writeNull() {
this.buffer[this.offset] = 0xfb;
this.offset++;
}
// TODO: refactor following three?
writeNullTerminatedString(s, encoding) {
const buf = StringParser.encode(s, encoding);
this.buffer.length && buf.copy(this.buffer, this.offset);
this.offset += buf.length;
this.writeInt8(0);
}
writeString(s, encoding) {
if (s === null) {
this.writeInt8(0xfb);
return;
}
if (s.length === 0) {
return;
}
// const bytes = Buffer.byteLength(s, 'utf8');
// this.buffer.write(s, this.offset, bytes, 'utf8');
// this.offset += bytes;
const buf = StringParser.encode(s, encoding);
this.buffer.length && buf.copy(this.buffer, this.offset);
this.offset += buf.length;
}
writeLengthCodedString(s, encoding) {
const buf = StringParser.encode(s, encoding);
this.writeLengthCodedNumber(buf.length);
this.buffer.length && buf.copy(this.buffer, this.offset);
this.offset += buf.length;
}
writeLengthCodedBuffer(b) {
this.writeLengthCodedNumber(b.length);
b.copy(this.buffer, this.offset);
this.offset += b.length;
}
writeLengthCodedNumber(n) {
if (n < 0xfb) {
return this.writeInt8(n);
}
if (n < 0xffff) {
this.writeInt8(0xfc);
return this.writeInt16(n);
}
if (n < 0xffffff) {
this.writeInt8(0xfd);
return this.writeInt24(n);
}
if (n === null) {
return this.writeInt8(0xfb);
}
// TODO: check that n is out of int precision
this.writeInt8(0xfe);
this.buffer.writeUInt32LE(n, this.offset);
this.offset += 4;
this.buffer.writeUInt32LE(n >> 32, this.offset);
this.offset += 4;
return this.offset;
}
writeDate(d, timezone) {
this.buffer.writeUInt8(11, this.offset);
if (!timezone || timezone === 'local') {
this.buffer.writeUInt16LE(d.getFullYear(), this.offset + 1);
this.buffer.writeUInt8(d.getMonth() + 1, this.offset + 3);
this.buffer.writeUInt8(d.getDate(), this.offset + 4);
this.buffer.writeUInt8(d.getHours(), this.offset + 5);
this.buffer.writeUInt8(d.getMinutes(), this.offset + 6);
this.buffer.writeUInt8(d.getSeconds(), this.offset + 7);
this.buffer.writeUInt32LE(d.getMilliseconds() * 1000, this.offset + 8);
} else {
if (timezone !== 'Z') {
const offset =
(timezone[0] === '-' ? -1 : 1) *
(parseInt(timezone.substring(1, 3), 10) * 60 +
parseInt(timezone.substring(4), 10));
if (offset !== 0) {
d = new Date(d.getTime() + 60000 * offset);
}
}
this.buffer.writeUInt16LE(d.getUTCFullYear(), this.offset + 1);
this.buffer.writeUInt8(d.getUTCMonth() + 1, this.offset + 3);
this.buffer.writeUInt8(d.getUTCDate(), this.offset + 4);
this.buffer.writeUInt8(d.getUTCHours(), this.offset + 5);
this.buffer.writeUInt8(d.getUTCMinutes(), this.offset + 6);
this.buffer.writeUInt8(d.getUTCSeconds(), this.offset + 7);
this.buffer.writeUInt32LE(d.getUTCMilliseconds() * 1000, this.offset + 8);
}
this.offset += 12;
}
writeHeader(sequenceId) {
const offset = this.offset;
this.offset = 0;
this.writeInt24(this.buffer.length - 4);
this.writeInt8(sequenceId);
this.offset = offset;
}
clone() {
return new Packet(this.sequenceId, this.buffer, this.start, this.end);
}
type() {
if (this.isEOF()) {
return 'EOF';
}
if (this.isError()) {
return 'Error';
}
if (this.buffer[this.offset] === 0) {
return 'maybeOK'; // could be other packet types as well
}
return '';
}
static lengthCodedNumberLength(n) {
if (n < 0xfb) {
return 1;
}
if (n < 0xffff) {
return 3;
}
if (n < 0xffffff) {
return 5;
}
return 9;
}
static lengthCodedStringLength(str, encoding) {
const buf = StringParser.encode(str, encoding);
const slen = buf.length;
return Packet.lengthCodedNumberLength(slen) + slen;
}
static MockBuffer() {
const noop = function () {};
const res = Buffer.alloc(0);
for (const op in NativeBuffer.prototype) {
if (typeof res[op] === 'function') {
res[op] = noop;
}
}
return res;
}
}
module.exports = Packet;

27
node_modules/mysql2/lib/packets/prepare_statement.js generated vendored Normal file
View File

@@ -0,0 +1,27 @@
'use strict';
const Packet = require('../packets/packet');
const CommandCodes = require('../constants/commands');
const StringParser = require('../parsers/string.js');
const CharsetToEncoding = require('../constants/charset_encodings.js');
class PrepareStatement {
constructor(sql, charsetNumber) {
this.query = sql;
this.charsetNumber = charsetNumber;
this.encoding = CharsetToEncoding[charsetNumber];
}
toPacket() {
const buf = StringParser.encode(this.query, this.encoding);
const length = 5 + buf.length;
const buffer = Buffer.allocUnsafe(length);
const packet = new Packet(0, buffer, 0, length);
packet.offset = 4;
packet.writeInt8(CommandCodes.STMT_PREPARE);
packet.writeBuffer(buf);
return packet;
}
}
module.exports = PrepareStatement;

View File

@@ -0,0 +1,16 @@
'use strict';
class PreparedStatementHeader {
constructor(packet) {
packet.skip(1); // should be 0
this.id = packet.readInt32();
this.fieldCount = packet.readInt16();
this.parameterCount = packet.readInt16();
packet.skip(1); // should be 0
this.warningCount = packet.readInt16();
}
}
// TODO: toPacket
module.exports = PreparedStatementHeader;

27
node_modules/mysql2/lib/packets/query.js generated vendored Normal file
View File

@@ -0,0 +1,27 @@
'use strict';
const Packet = require('../packets/packet.js');
const CommandCode = require('../constants/commands.js');
const StringParser = require('../parsers/string.js');
const CharsetToEncoding = require('../constants/charset_encodings.js');
class Query {
constructor(sql, charsetNumber) {
this.query = sql;
this.charsetNumber = charsetNumber;
this.encoding = CharsetToEncoding[charsetNumber];
}
toPacket() {
const buf = StringParser.encode(this.query, this.encoding);
const length = 5 + buf.length;
const buffer = Buffer.allocUnsafe(length);
const packet = new Packet(0, buffer, 0, length);
packet.offset = 4;
packet.writeInt8(CommandCode.QUERY);
packet.writeBuffer(buf);
return packet;
}
}
module.exports = Query;

46
node_modules/mysql2/lib/packets/register_slave.js generated vendored Normal file
View File

@@ -0,0 +1,46 @@
'use strict';
// http://dev.mysql.com/doc/internals/en/com-register-slave.html
// note that documentation is incorrect, for example command code is actually 0x15 but documented as 0x14
const Packet = require('../packets/packet');
const CommandCodes = require('../constants/commands');
class RegisterSlave {
constructor(opts) {
this.serverId = opts.serverId || 0;
this.slaveHostname = opts.slaveHostname || '';
this.slaveUser = opts.slaveUser || '';
this.slavePassword = opts.slavePassword || '';
this.slavePort = opts.slavePort || 0;
this.replicationRank = opts.replicationRank || 0;
this.masterId = opts.masterId || 0;
}
toPacket() {
const length =
15 + // TODO: should be ascii?
Buffer.byteLength(this.slaveHostname, 'utf8') +
Buffer.byteLength(this.slaveUser, 'utf8') +
Buffer.byteLength(this.slavePassword, 'utf8') +
3 +
4;
const buffer = Buffer.allocUnsafe(length);
const packet = new Packet(0, buffer, 0, length);
packet.offset = 4;
packet.writeInt8(CommandCodes.REGISTER_SLAVE);
packet.writeInt32(this.serverId);
packet.writeInt8(Buffer.byteLength(this.slaveHostname, 'utf8'));
packet.writeString(this.slaveHostname);
packet.writeInt8(Buffer.byteLength(this.slaveUser, 'utf8'));
packet.writeString(this.slaveUser);
packet.writeInt8(Buffer.byteLength(this.slavePassword, 'utf8'));
packet.writeString(this.slavePassword);
packet.writeInt16(this.slavePort);
packet.writeInt32(this.replicationRank);
packet.writeInt32(this.masterId);
return packet;
}
}
module.exports = RegisterSlave;

124
node_modules/mysql2/lib/packets/resultset_header.js generated vendored Normal file
View File

@@ -0,0 +1,124 @@
'use strict';
// TODO: rename to OK packet
// https://dev.mysql.com/doc/internals/en/packet-OK_Packet.html
const Packet = require('./packet.js');
const ClientConstants = require('../constants/client.js');
const ServerSatusFlags = require('../constants/server_status.js');
const EncodingToCharset = require('../constants/encoding_charset.js');
const sessionInfoTypes = require('../constants/session_track.js');
class ResultSetHeader {
constructor(packet, connection) {
const bigNumberStrings = connection.config.bigNumberStrings;
const encoding = connection.serverEncoding;
const flags = connection._handshakePacket.capabilityFlags;
const isSet = function (flag) {
return flags & ClientConstants[flag];
};
if (packet.buffer[packet.offset] !== 0) {
this.fieldCount = packet.readLengthCodedNumber();
if (this.fieldCount === null) {
this.infileName = packet.readString(undefined, encoding);
}
return;
}
this.fieldCount = packet.readInt8(); // skip OK byte
this.affectedRows = packet.readLengthCodedNumber(bigNumberStrings);
this.insertId = packet.readLengthCodedNumberSigned(bigNumberStrings);
this.info = '';
if (isSet('PROTOCOL_41')) {
this.serverStatus = packet.readInt16();
this.warningStatus = packet.readInt16();
} else if (isSet('TRANSACTIONS')) {
this.serverStatus = packet.readInt16();
}
let stateChanges = null;
if (isSet('SESSION_TRACK') && packet.offset < packet.end) {
this.info = packet.readLengthCodedString(encoding);
if (this.serverStatus && ServerSatusFlags.SERVER_SESSION_STATE_CHANGED) {
// session change info record - see
// https://dev.mysql.com/doc/internals/en/packet-OK_Packet.html#cs-sect-packet-ok-sessioninfo
let len =
packet.offset < packet.end ? packet.readLengthCodedNumber() : 0;
const end = packet.offset + len;
let type, key, stateEnd;
if (len > 0) {
stateChanges = {
systemVariables: {},
schema: null,
gtids: [],
trackStateChange: null,
};
}
while (packet.offset < end) {
type = packet.readInt8();
len = packet.readLengthCodedNumber();
stateEnd = packet.offset + len;
if (type === sessionInfoTypes.SYSTEM_VARIABLES) {
key = packet.readLengthCodedString(encoding);
const val = packet.readLengthCodedString(encoding);
stateChanges.systemVariables[key] = val;
if (key === 'character_set_client') {
const charsetNumber = EncodingToCharset[val];
// TODO - better api for driver users to handle unknown encodings?
// maybe custom coverter in the config?
// For now just ignore character_set_client command if there is
// no known mapping from reported encoding to a charset code
if (typeof charsetNumber !== 'undefined') {
connection.config.charsetNumber = charsetNumber;
}
}
} else if (type === sessionInfoTypes.SCHEMA) {
key = packet.readLengthCodedString(encoding);
stateChanges.schema = key;
} else if (type === sessionInfoTypes.STATE_CHANGE) {
stateChanges.trackStateChange =
packet.readLengthCodedString(encoding);
} else if (type === sessionInfoTypes.STATE_GTIDS) {
// TODO: find if the first length coded string means anything. Usually comes as empty
// eslint-disable-next-line no-unused-vars
const _unknownString = packet.readLengthCodedString(encoding);
const gtid = packet.readLengthCodedString(encoding);
stateChanges.gtids = gtid.split(',');
} else {
// unsupported session track type. For now just ignore
}
packet.offset = stateEnd;
}
}
} else {
this.info = packet.readString(undefined, encoding);
}
if (stateChanges) {
this.stateChanges = stateChanges;
}
const m = this.info.match(/\schanged:\s*(\d+)/i);
if (m !== null) {
this.changedRows = parseInt(m[1], 10);
} else {
this.changedRows = 0;
}
}
// TODO: should be consistent instance member, but it's just easier here to have just function
static toPacket(fieldCount, insertId) {
let length = 4 + Packet.lengthCodedNumberLength(fieldCount);
if (typeof insertId !== 'undefined') {
length += Packet.lengthCodedNumberLength(insertId);
}
const buffer = Buffer.allocUnsafe(length);
const packet = new Packet(0, buffer, 0, length);
packet.offset = 4;
packet.writeLengthCodedNumber(fieldCount);
if (typeof insertId !== 'undefined') {
packet.writeLengthCodedNumber(insertId);
}
return packet;
}
}
module.exports = ResultSetHeader;

25
node_modules/mysql2/lib/packets/ssl_request.js generated vendored Normal file
View File

@@ -0,0 +1,25 @@
'use strict';
const ClientConstants = require('../constants/client');
const Packet = require('../packets/packet');
class SSLRequest {
constructor(flags, charset) {
this.clientFlags = flags | ClientConstants.SSL;
this.charset = charset;
}
toPacket() {
const length = 36;
const buffer = Buffer.allocUnsafe(length);
const packet = new Packet(0, buffer, 0, length);
buffer.fill(0);
packet.offset = 4;
packet.writeInt32(this.clientFlags);
packet.writeInt32(0); // max packet size. todo: move to config
packet.writeInt8(this.charset);
return packet;
}
}
module.exports = SSLRequest;

47
node_modules/mysql2/lib/packets/text_row.js generated vendored Normal file
View File

@@ -0,0 +1,47 @@
'use strict';
const Packet = require('../packets/packet');
class TextRow {
constructor(columns) {
this.columns = columns || [];
}
static fromPacket(packet) {
// packet.reset(); // set offset to starting point?
const columns = [];
while (packet.haveMoreData()) {
columns.push(packet.readLengthCodedString());
}
return new TextRow(columns);
}
static toPacket(columns, encoding) {
const sequenceId = 0; // TODO remove, this is calculated now in connecton
let length = 0;
columns.forEach((val) => {
if (val === null || typeof val === 'undefined') {
++length;
return;
}
length += Packet.lengthCodedStringLength(val.toString(10), encoding);
});
const buffer = Buffer.allocUnsafe(length + 4);
const packet = new Packet(sequenceId, buffer, 0, length + 4);
packet.offset = 4;
columns.forEach((val) => {
if (val === null) {
packet.writeNull();
return;
}
if (typeof val === 'undefined') {
packet.writeInt8(0);
return;
}
packet.writeLengthCodedString(val.toString(10), encoding);
});
return packet;
}
}
module.exports = TextRow;

235
node_modules/mysql2/lib/parsers/binary_parser.js generated vendored Normal file
View File

@@ -0,0 +1,235 @@
'use strict';
const FieldFlags = require('../constants/field_flags.js');
const Charsets = require('../constants/charsets.js');
const Types = require('../constants/types.js');
const helpers = require('../helpers');
const genFunc = require('generate-function');
const parserCache = require('./parser_cache.js');
const typeNames = [];
for (const t in Types) {
typeNames[Types[t]] = t;
}
function readCodeFor(field, config, options, fieldNum) {
const supportBigNumbers = Boolean(
options.supportBigNumbers || config.supportBigNumbers
);
const bigNumberStrings = Boolean(
options.bigNumberStrings || config.bigNumberStrings
);
const timezone = options.timezone || config.timezone;
const dateStrings = options.dateStrings || config.dateStrings;
const unsigned = field.flags & FieldFlags.UNSIGNED;
switch (field.columnType) {
case Types.TINY:
return unsigned ? 'packet.readInt8();' : 'packet.readSInt8();';
case Types.SHORT:
return unsigned ? 'packet.readInt16();' : 'packet.readSInt16();';
case Types.LONG:
case Types.INT24: // in binary protocol int24 is encoded in 4 bytes int32
return unsigned ? 'packet.readInt32();' : 'packet.readSInt32();';
case Types.YEAR:
return 'packet.readInt16()';
case Types.FLOAT:
return 'packet.readFloat();';
case Types.DOUBLE:
return 'packet.readDouble();';
case Types.NULL:
return 'null;';
case Types.DATE:
case Types.DATETIME:
case Types.TIMESTAMP:
case Types.NEWDATE:
if (helpers.typeMatch(field.columnType, dateStrings, Types)) {
return `packet.readDateTimeString(${parseInt(field.decimals, 10)}, ${null}, ${field.columnType});`;
}
return `packet.readDateTime(${helpers.srcEscape(timezone)});`;
case Types.TIME:
return 'packet.readTimeString()';
case Types.DECIMAL:
case Types.NEWDECIMAL:
if (config.decimalNumbers) {
return 'packet.parseLengthCodedFloat();';
}
return 'packet.readLengthCodedString("ascii");';
case Types.GEOMETRY:
return 'packet.parseGeometryValue();';
case Types.VECTOR:
return 'packet.parseVector()';
case Types.JSON:
// Since for JSON columns mysql always returns charset 63 (BINARY),
// we have to handle it according to JSON specs and use "utf8",
// see https://github.com/sidorares/node-mysql2/issues/409
return config.jsonStrings
? 'packet.readLengthCodedString("utf8")'
: 'JSON.parse(packet.readLengthCodedString("utf8"));';
case Types.LONGLONG:
if (!supportBigNumbers) {
return unsigned
? 'packet.readInt64JSNumber();'
: 'packet.readSInt64JSNumber();';
}
if (bigNumberStrings) {
return unsigned
? 'packet.readInt64String();'
: 'packet.readSInt64String();';
}
return unsigned ? 'packet.readInt64();' : 'packet.readSInt64();';
default:
if (field.characterSet === Charsets.BINARY) {
return 'packet.readLengthCodedBuffer();';
}
return `packet.readLengthCodedString(fields[${fieldNum}].encoding)`;
}
}
function compile(fields, options, config) {
const parserFn = genFunc();
const nullBitmapLength = Math.floor((fields.length + 7 + 2) / 8);
function wrap(field, packet) {
return {
type: typeNames[field.columnType],
length: field.columnLength,
db: field.schema,
table: field.table,
name: field.name,
string: function (encoding = field.encoding) {
if (field.columnType === Types.JSON && encoding === field.encoding) {
// Since for JSON columns mysql always returns charset 63 (BINARY),
// we have to handle it according to JSON specs and use "utf8",
// see https://github.com/sidorares/node-mysql2/issues/1661
console.warn(
`typeCast: JSON column "${field.name}" is interpreted as BINARY by default, recommended to manually set utf8 encoding: \`field.string("utf8")\``
);
}
if (
[Types.DATETIME, Types.NEWDATE, Types.TIMESTAMP, Types.DATE].includes(
field.columnType
)
) {
return packet.readDateTimeString(
parseInt(field.decimals, 10),
' ',
field.columnType
);
}
if (field.columnType === Types.TINY) {
const unsigned = field.flags & FieldFlags.UNSIGNED;
return String(unsigned ? packet.readInt8() : packet.readSInt8());
}
if (field.columnType === Types.TIME) {
return packet.readTimeString();
}
return packet.readLengthCodedString(encoding);
},
buffer: function () {
return packet.readLengthCodedBuffer();
},
geometry: function () {
return packet.parseGeometryValue();
},
};
}
parserFn('(function(){');
parserFn('return class BinaryRow {');
parserFn('constructor() {');
parserFn('}');
parserFn('next(packet, fields, options) {');
if (options.rowsAsArray) {
parserFn(`const result = new Array(${fields.length});`);
} else {
parserFn('const result = {};');
}
// Global typeCast
if (
typeof config.typeCast === 'function' &&
typeof options.typeCast !== 'function'
) {
options.typeCast = config.typeCast;
}
parserFn('packet.readInt8();'); // status byte
for (let i = 0; i < nullBitmapLength; ++i) {
parserFn(`const nullBitmaskByte${i} = packet.readInt8();`);
}
let lvalue = '';
let currentFieldNullBit = 4;
let nullByteIndex = 0;
let fieldName = '';
let tableName = '';
for (let i = 0; i < fields.length; i++) {
fieldName = helpers.fieldEscape(fields[i].name);
// parserFn(`// ${fieldName}: ${typeNames[fields[i].columnType]}`);
if (typeof options.nestTables === 'string') {
lvalue = `result[${helpers.fieldEscape(fields[i].table + options.nestTables + fields[i].name)}]`;
} else if (options.nestTables === true) {
tableName = helpers.fieldEscape(fields[i].table);
parserFn(`if (!result[${tableName}]) result[${tableName}] = {};`);
lvalue = `result[${tableName}][${fieldName}]`;
} else if (options.rowsAsArray) {
lvalue = `result[${i.toString(10)}]`;
} else {
lvalue = `result[${fieldName}]`;
}
parserFn(`if (nullBitmaskByte${nullByteIndex} & ${currentFieldNullBit}) `);
parserFn(`${lvalue} = null;`);
parserFn('else {');
if (options.typeCast === false) {
parserFn(`${lvalue} = packet.readLengthCodedBuffer();`);
} else {
const fieldWrapperVar = `fieldWrapper${i}`;
parserFn(`const ${fieldWrapperVar} = wrap(fields[${i}], packet);`);
const readCode = readCodeFor(fields[i], config, options, i);
if (typeof options.typeCast === 'function') {
parserFn(
`${lvalue} = options.typeCast(${fieldWrapperVar}, function() { return ${readCode} });`
);
} else {
parserFn(`${lvalue} = ${readCode};`);
}
}
parserFn('}');
currentFieldNullBit *= 2;
if (currentFieldNullBit === 0x100) {
currentFieldNullBit = 1;
nullByteIndex++;
}
}
parserFn('return result;');
parserFn('}');
parserFn('};')('})()');
if (config.debug) {
helpers.printDebugWithCode(
'Compiled binary protocol row parser',
parserFn.toString()
);
}
return parserFn.toFunction({ wrap });
}
function getBinaryParser(fields, options, config) {
return parserCache.getParser('binary', fields, options, config, compile);
}
module.exports = getBinaryParser;

68
node_modules/mysql2/lib/parsers/parser_cache.js generated vendored Normal file
View File

@@ -0,0 +1,68 @@
'use strict';
const { createLRU } = require('lru.min');
const parserCache = createLRU({
max: 15000,
});
function keyFromFields(type, fields, options, config) {
const res = [
type,
typeof options.nestTables,
options.nestTables,
Boolean(options.rowsAsArray),
Boolean(options.supportBigNumbers || config.supportBigNumbers),
Boolean(options.bigNumberStrings || config.bigNumberStrings),
typeof options.typeCast === 'boolean'
? options.typeCast
: typeof options.typeCast,
options.timezone || config.timezone,
Boolean(options.decimalNumbers),
options.dateStrings,
];
for (let i = 0; i < fields.length; ++i) {
const field = fields[i];
res.push([
field.name,
field.columnType,
field.length,
field.schema,
field.table,
field.flags,
field.characterSet,
]);
}
return JSON.stringify(res, null, 0);
}
function getParser(type, fields, options, config, compiler) {
const key = keyFromFields(type, fields, options, config);
let parser = parserCache.get(key);
if (parser) {
return parser;
}
parser = compiler(fields, options, config);
parserCache.set(key, parser);
return parser;
}
function setMaxCache(max) {
parserCache.resize(max);
}
function clearCache() {
parserCache.clear();
}
module.exports = {
getParser: getParser,
setMaxCache: setMaxCache,
clearCache: clearCache,
_keyFromFields: keyFromFields,
};

213
node_modules/mysql2/lib/parsers/static_binary_parser.js generated vendored Normal file
View File

@@ -0,0 +1,213 @@
'use strict';
const FieldFlags = require('../constants/field_flags.js');
const Charsets = require('../constants/charsets.js');
const Types = require('../constants/types.js');
const helpers = require('../helpers');
const typeNames = [];
for (const t in Types) {
typeNames[Types[t]] = t;
}
function getBinaryParser(fields, _options, config) {
function readCode(field, config, options, fieldNum, packet) {
const supportBigNumbers = Boolean(
options.supportBigNumbers || config.supportBigNumbers
);
const bigNumberStrings = Boolean(
options.bigNumberStrings || config.bigNumberStrings
);
const timezone = options.timezone || config.timezone;
const dateStrings = options.dateStrings || config.dateStrings;
const unsigned = field.flags & FieldFlags.UNSIGNED;
switch (field.columnType) {
case Types.TINY:
return unsigned ? packet.readInt8() : packet.readSInt8();
case Types.SHORT:
return unsigned ? packet.readInt16() : packet.readSInt16();
case Types.LONG:
case Types.INT24: // in binary protocol int24 is encoded in 4 bytes int32
return unsigned ? packet.readInt32() : packet.readSInt32();
case Types.YEAR:
return packet.readInt16();
case Types.FLOAT:
return packet.readFloat();
case Types.DOUBLE:
return packet.readDouble();
case Types.NULL:
return null;
case Types.DATE:
case Types.DATETIME:
case Types.TIMESTAMP:
case Types.NEWDATE:
return helpers.typeMatch(field.columnType, dateStrings, Types)
? packet.readDateTimeString(
parseInt(field.decimals, 10),
null,
field.columnType
)
: packet.readDateTime(timezone);
case Types.TIME:
return packet.readTimeString();
case Types.DECIMAL:
case Types.NEWDECIMAL:
return config.decimalNumbers
? packet.parseLengthCodedFloat()
: packet.readLengthCodedString('ascii');
case Types.GEOMETRY:
return packet.parseGeometryValue();
case Types.VECTOR:
return packet.parseVector();
case Types.JSON:
// Since for JSON columns mysql always returns charset 63 (BINARY),
// we have to handle it according to JSON specs and use "utf8",
// see https://github.com/sidorares/node-mysql2/issues/409
return config.jsonStrings
? packet.readLengthCodedString('utf8')
: JSON.parse(packet.readLengthCodedString('utf8'));
case Types.LONGLONG:
if (!supportBigNumbers)
return unsigned
? packet.readInt64JSNumber()
: packet.readSInt64JSNumber();
return bigNumberStrings
? unsigned
? packet.readInt64String()
: packet.readSInt64String()
: unsigned
? packet.readInt64()
: packet.readSInt64();
default:
return field.characterSet === Charsets.BINARY
? packet.readLengthCodedBuffer()
: packet.readLengthCodedString(fields[fieldNum].encoding);
}
}
return class BinaryRow {
constructor() {}
next(packet, fields, options) {
packet.readInt8(); // status byte
const nullBitmapLength = Math.floor((fields.length + 7 + 2) / 8);
const nullBitmaskBytes = new Array(nullBitmapLength);
for (let i = 0; i < nullBitmapLength; i++) {
nullBitmaskBytes[i] = packet.readInt8();
}
const result = options.rowsAsArray ? new Array(fields.length) : {};
let currentFieldNullBit = 4;
let nullByteIndex = 0;
for (let i = 0; i < fields.length; i++) {
const field = fields[i];
const typeCast =
options.typeCast !== undefined ? options.typeCast : config.typeCast;
let value;
if (nullBitmaskBytes[nullByteIndex] & currentFieldNullBit) {
value = null;
} else if (options.typeCast === false) {
value = packet.readLengthCodedBuffer();
} else {
const next = () => readCode(field, config, options, i, packet);
value =
typeof typeCast === 'function'
? typeCast(
{
type: typeNames[field.columnType],
length: field.columnLength,
db: field.schema,
table: field.table,
name: field.name,
string: function (encoding = field.encoding) {
if (
field.columnType === Types.JSON &&
encoding === field.encoding
) {
// Since for JSON columns mysql always returns charset 63 (BINARY),
// we have to handle it according to JSON specs and use "utf8",
// see https://github.com/sidorares/node-mysql2/issues/1661
console.warn(
`typeCast: JSON column "${field.name}" is interpreted as BINARY by default, recommended to manually set utf8 encoding: \`field.string("utf8")\``
);
}
if (
[
Types.DATETIME,
Types.NEWDATE,
Types.TIMESTAMP,
Types.DATE,
].includes(field.columnType)
) {
return packet.readDateTimeString(
parseInt(field.decimals, 10),
' ',
field.columnType
);
}
if (field.columnType === Types.TINY) {
const unsigned = field.flags & FieldFlags.UNSIGNED;
return String(
unsigned ? packet.readInt8() : packet.readSInt8()
);
}
if (field.columnType === Types.TIME) {
return packet.readTimeString();
}
return packet.readLengthCodedString(encoding);
},
buffer: function () {
return packet.readLengthCodedBuffer();
},
geometry: function () {
return packet.parseGeometryValue();
},
},
next
)
: next();
}
if (options.rowsAsArray) {
result[i] = value;
} else if (typeof options.nestTables === 'string') {
const key = helpers.fieldEscape(
field.table + options.nestTables + field.name,
false
);
result[key] = value;
} else if (options.nestTables === true) {
const tableName = helpers.fieldEscape(field.table, false);
if (!result[tableName]) {
result[tableName] = {};
}
const fieldName = helpers.fieldEscape(field.name, false);
result[tableName][fieldName] = value;
} else {
const key = helpers.fieldEscape(field.name, false);
result[key] = value;
}
currentFieldNullBit *= 2;
if (currentFieldNullBit === 0x100) {
currentFieldNullBit = 1;
nullByteIndex++;
}
}
return result;
}
};
}
module.exports = getBinaryParser;

152
node_modules/mysql2/lib/parsers/static_text_parser.js generated vendored Normal file
View File

@@ -0,0 +1,152 @@
'use strict';
const Types = require('../constants/types.js');
const Charsets = require('../constants/charsets.js');
const helpers = require('../helpers');
const typeNames = [];
for (const t in Types) {
typeNames[Types[t]] = t;
}
function readField({ packet, type, charset, encoding, config, options }) {
const supportBigNumbers = Boolean(
options.supportBigNumbers || config.supportBigNumbers
);
const bigNumberStrings = Boolean(
options.bigNumberStrings || config.bigNumberStrings
);
const timezone = options.timezone || config.timezone;
const dateStrings = options.dateStrings || config.dateStrings;
switch (type) {
case Types.TINY:
case Types.SHORT:
case Types.LONG:
case Types.INT24:
case Types.YEAR:
return packet.parseLengthCodedIntNoBigCheck();
case Types.LONGLONG:
if (supportBigNumbers && bigNumberStrings) {
return packet.parseLengthCodedIntString();
}
return packet.parseLengthCodedInt(supportBigNumbers);
case Types.FLOAT:
case Types.DOUBLE:
return packet.parseLengthCodedFloat();
case Types.NULL:
case Types.DECIMAL:
case Types.NEWDECIMAL:
if (config.decimalNumbers) {
return packet.parseLengthCodedFloat();
}
return packet.readLengthCodedString('ascii');
case Types.DATE:
if (helpers.typeMatch(type, dateStrings, Types)) {
return packet.readLengthCodedString('ascii');
}
return packet.parseDate(timezone);
case Types.DATETIME:
case Types.TIMESTAMP:
if (helpers.typeMatch(type, dateStrings, Types)) {
return packet.readLengthCodedString('ascii');
}
return packet.parseDateTime(timezone);
case Types.TIME:
return packet.readLengthCodedString('ascii');
case Types.GEOMETRY:
return packet.parseGeometryValue();
case Types.VECTOR:
return packet.parseVector();
case Types.JSON:
// Since for JSON columns mysql always returns charset 63 (BINARY),
// we have to handle it according to JSON specs and use "utf8",
// see https://github.com/sidorares/node-mysql2/issues/409
return config.jsonStrings
? packet.readLengthCodedString('utf8')
: JSON.parse(packet.readLengthCodedString('utf8'));
default:
if (charset === Charsets.BINARY) {
return packet.readLengthCodedBuffer();
}
return packet.readLengthCodedString(encoding);
}
}
function createTypecastField(field, packet) {
return {
type: typeNames[field.columnType],
length: field.columnLength,
db: field.schema,
table: field.table,
name: field.name,
string: function (encoding = field.encoding) {
if (field.columnType === Types.JSON && encoding === field.encoding) {
// Since for JSON columns mysql always returns charset 63 (BINARY),
// we have to handle it according to JSON specs and use "utf8",
// see https://github.com/sidorares/node-mysql2/issues/1661
console.warn(
`typeCast: JSON column "${field.name}" is interpreted as BINARY by default, recommended to manually set utf8 encoding: \`field.string("utf8")\``
);
}
return packet.readLengthCodedString(encoding);
},
buffer: function () {
return packet.readLengthCodedBuffer();
},
geometry: function () {
return packet.parseGeometryValue();
},
};
}
function getTextParser(_fields, _options, config) {
return {
next(packet, fields, options) {
const result = options.rowsAsArray ? [] : {};
for (let i = 0; i < fields.length; i++) {
const field = fields[i];
const typeCast = options.typeCast ? options.typeCast : config.typeCast;
const next = () =>
readField({
packet,
type: field.columnType,
encoding: field.encoding,
charset: field.characterSet,
config,
options,
});
let value;
if (options.typeCast === false) {
value = packet.readLengthCodedBuffer();
} else if (typeof typeCast === 'function') {
value = typeCast(createTypecastField(field, packet), next);
} else {
value = next();
}
if (options.rowsAsArray) {
result.push(value);
} else if (typeof options.nestTables === 'string') {
result[
`${helpers.fieldEscape(field.table, false)}${options.nestTables}${helpers.fieldEscape(field.name, false)}`
] = value;
} else if (options.nestTables) {
const tableName = helpers.fieldEscape(field.table, false);
if (!result[tableName]) {
result[tableName] = {};
}
result[tableName][helpers.fieldEscape(field.name, false)] = value;
} else {
result[helpers.fieldEscape(field.name, false)] = value;
}
}
return result;
},
};
}
module.exports = getTextParser;

50
node_modules/mysql2/lib/parsers/string.js generated vendored Normal file
View File

@@ -0,0 +1,50 @@
'use strict';
const Iconv = require('iconv-lite');
const { createLRU } = require('lru.min');
const decoderCache = createLRU({
max: 500,
});
exports.decode = function (buffer, encoding, start, end, options) {
if (Buffer.isEncoding(encoding)) {
return buffer.toString(encoding, start, end);
}
// Optimize for common case: encoding="short_string", options=undefined.
let decoder;
if (!options) {
decoder = decoderCache.get(encoding);
if (!decoder) {
decoder = Iconv.getDecoder(encoding);
decoderCache.set(encoding, decoder);
}
} else {
const decoderArgs = { encoding, options };
const decoderKey = JSON.stringify(decoderArgs);
decoder = decoderCache.get(decoderKey);
if (!decoder) {
decoder = Iconv.getDecoder(decoderArgs.encoding, decoderArgs.options);
decoderCache.set(decoderKey, decoder);
}
}
const res = decoder.write(buffer.slice(start, end));
const trail = decoder.end();
return trail ? res + trail : res;
};
exports.encode = function (string, encoding, options) {
if (Buffer.isEncoding(encoding)) {
return Buffer.from(string, encoding);
}
const encoder = Iconv.getEncoder(encoding, options || {});
const res = encoder.write(string);
const trail = encoder.end();
return trail && trail.length > 0 ? Buffer.concat([res, trail]) : res;
};

214
node_modules/mysql2/lib/parsers/text_parser.js generated vendored Normal file
View File

@@ -0,0 +1,214 @@
'use strict';
const Types = require('../constants/types.js');
const Charsets = require('../constants/charsets.js');
const helpers = require('../helpers');
const genFunc = require('generate-function');
const parserCache = require('./parser_cache.js');
const typeNames = [];
for (const t in Types) {
typeNames[Types[t]] = t;
}
function readCodeFor(type, charset, encodingExpr, config, options) {
const supportBigNumbers = Boolean(
options.supportBigNumbers || config.supportBigNumbers
);
const bigNumberStrings = Boolean(
options.bigNumberStrings || config.bigNumberStrings
);
const timezone = options.timezone || config.timezone;
const dateStrings = options.dateStrings || config.dateStrings;
switch (type) {
case Types.TINY:
case Types.SHORT:
case Types.LONG:
case Types.INT24:
case Types.YEAR:
return 'packet.parseLengthCodedIntNoBigCheck()';
case Types.LONGLONG:
if (supportBigNumbers && bigNumberStrings) {
return 'packet.parseLengthCodedIntString()';
}
return `packet.parseLengthCodedInt(${supportBigNumbers})`;
case Types.FLOAT:
case Types.DOUBLE:
return 'packet.parseLengthCodedFloat()';
case Types.NULL:
return 'packet.readLengthCodedNumber()';
case Types.DECIMAL:
case Types.NEWDECIMAL:
if (config.decimalNumbers) {
return 'packet.parseLengthCodedFloat()';
}
return 'packet.readLengthCodedString("ascii")';
case Types.DATE:
if (helpers.typeMatch(type, dateStrings, Types)) {
return 'packet.readLengthCodedString("ascii")';
}
return `packet.parseDate(${helpers.srcEscape(timezone)})`;
case Types.DATETIME:
case Types.TIMESTAMP:
if (helpers.typeMatch(type, dateStrings, Types)) {
return 'packet.readLengthCodedString("ascii")';
}
return `packet.parseDateTime(${helpers.srcEscape(timezone)})`;
case Types.TIME:
return 'packet.readLengthCodedString("ascii")';
case Types.GEOMETRY:
return 'packet.parseGeometryValue()';
case Types.VECTOR:
return 'packet.parseVector()';
case Types.JSON:
// Since for JSON columns mysql always returns charset 63 (BINARY),
// we have to handle it according to JSON specs and use "utf8",
// see https://github.com/sidorares/node-mysql2/issues/409
return config.jsonStrings
? 'packet.readLengthCodedString("utf8")'
: 'JSON.parse(packet.readLengthCodedString("utf8"))';
default:
if (charset === Charsets.BINARY) {
return 'packet.readLengthCodedBuffer()';
}
return `packet.readLengthCodedString(${encodingExpr})`;
}
}
function compile(fields, options, config) {
// use global typeCast if current query doesn't specify one
if (
typeof config.typeCast === 'function' &&
typeof options.typeCast !== 'function'
) {
options.typeCast = config.typeCast;
}
function wrap(field, _this) {
return {
type: typeNames[field.columnType],
length: field.columnLength,
db: field.schema,
table: field.table,
name: field.name,
string: function (encoding = field.encoding) {
if (field.columnType === Types.JSON && encoding === field.encoding) {
// Since for JSON columns mysql always returns charset 63 (BINARY),
// we have to handle it according to JSON specs and use "utf8",
// see https://github.com/sidorares/node-mysql2/issues/1661
console.warn(
`typeCast: JSON column "${field.name}" is interpreted as BINARY by default, recommended to manually set utf8 encoding: \`field.string("utf8")\``
);
}
return _this.packet.readLengthCodedString(encoding);
},
buffer: function () {
return _this.packet.readLengthCodedBuffer();
},
geometry: function () {
return _this.packet.parseGeometryValue();
},
};
}
const parserFn = genFunc();
parserFn('(function () {')('return class TextRow {');
// constructor method
parserFn('constructor(fields) {');
// node-mysql typeCast compatibility wrapper
// see https://github.com/mysqljs/mysql/blob/96fdd0566b654436624e2375c7b6604b1f50f825/lib/protocol/packets/Field.js
if (typeof options.typeCast === 'function') {
parserFn('const _this = this;');
parserFn('for(let i=0; i<fields.length; ++i) {');
parserFn('this[`wrap${i}`] = wrap(fields[i], _this);');
parserFn('}');
}
parserFn('}');
// next method
parserFn('next(packet, fields, options) {');
parserFn('this.packet = packet;');
if (options.rowsAsArray) {
parserFn(`const result = new Array(${fields.length});`);
} else {
parserFn('const result = {};');
}
const resultTables = {};
let resultTablesArray = [];
if (options.nestTables === true) {
for (let i = 0; i < fields.length; i++) {
resultTables[fields[i].table] = 1;
}
resultTablesArray = Object.keys(resultTables);
for (let i = 0; i < resultTablesArray.length; i++) {
parserFn(`result[${helpers.fieldEscape(resultTablesArray[i])}] = {};`);
}
}
let lvalue = '';
let fieldName = '';
let tableName = '';
for (let i = 0; i < fields.length; i++) {
fieldName = helpers.fieldEscape(fields[i].name);
// parserFn(`// ${fieldName}: ${typeNames[fields[i].columnType]}`);
if (typeof options.nestTables === 'string') {
lvalue = `result[${helpers.fieldEscape(fields[i].table + options.nestTables + fields[i].name)}]`;
} else if (options.nestTables === true) {
tableName = helpers.fieldEscape(fields[i].table);
parserFn(`if (!result[${tableName}]) result[${tableName}] = {};`);
lvalue = `result[${tableName}][${fieldName}]`;
} else if (options.rowsAsArray) {
lvalue = `result[${i.toString(10)}]`;
} else {
lvalue = `result[${fieldName}]`;
}
if (options.typeCast === false) {
parserFn(`${lvalue} = packet.readLengthCodedBuffer();`);
} else {
const encodingExpr = `fields[${i}].encoding`;
const readCode = readCodeFor(
fields[i].columnType,
fields[i].characterSet,
encodingExpr,
config,
options
);
if (typeof options.typeCast === 'function') {
parserFn(
`${lvalue} = options.typeCast(this.wrap${i}, function() { return ${readCode} });`
);
} else {
parserFn(`${lvalue} = ${readCode};`);
}
}
}
parserFn('return result;');
parserFn('}');
parserFn('};')('})()');
if (config.debug) {
helpers.printDebugWithCode(
'Compiled text protocol row parser',
parserFn.toString()
);
}
if (typeof options.typeCast === 'function') {
return parserFn.toFunction({ wrap });
}
return parserFn.toFunction();
}
function getTextParser(fields, options, config) {
return parserCache.getParser('text', fields, options, config, compile);
}
module.exports = getTextParser;

12
node_modules/mysql2/lib/pool.js generated vendored Normal file
View File

@@ -0,0 +1,12 @@
'use strict';
const BasePool = require('./base/pool.js');
class Pool extends BasePool {
promise(promiseImpl) {
const PromisePool = require('./promise/pool.js');
return new PromisePool(this, promiseImpl);
}
}
module.exports = Pool;

369
node_modules/mysql2/lib/pool_cluster.js generated vendored Normal file
View File

@@ -0,0 +1,369 @@
'use strict';
const process = require('process');
const Pool = require('./pool.js');
const PoolConfig = require('./pool_config.js');
const Connection = require('./connection.js');
const EventEmitter = require('events').EventEmitter;
/**
* Selector
*/
const makeSelector = {
RR() {
let index = 0;
return (clusterIds) => clusterIds[index++ % clusterIds.length];
},
RANDOM() {
return (clusterIds) =>
clusterIds[Math.floor(Math.random() * clusterIds.length)];
},
ORDER() {
return (clusterIds) => clusterIds[0];
},
};
const getMonotonicMilliseconds = function () {
let ms;
if (typeof process.hrtime === 'function') {
ms = process.hrtime();
ms = ms[0] * 1e3 + ms[1] * 1e-6;
} else {
ms = process.uptime() * 1000;
}
return Math.floor(ms);
};
const patternRegExp = function (pattern) {
if (pattern instanceof RegExp) {
return pattern;
}
const source = pattern
.replace(/([.+?^=!:${}()|[\]/\\])/g, '\\$1')
.replace(/\*/g, '.*');
return new RegExp(`^${source}$`);
};
class PoolNamespace {
constructor(cluster, pattern, selector) {
this._cluster = cluster;
this._pattern = pattern;
this._selector = makeSelector[selector]();
}
getConnection(cb) {
const clusterNode = this._getClusterNode();
if (clusterNode === null) {
let err = new Error('Pool does Not exist.');
err.code = 'POOL_NOEXIST';
if (this._cluster._findNodeIds(this._pattern, true).length !== 0) {
err = new Error('Pool does Not have online node.');
err.code = 'POOL_NONEONLINE';
}
return cb(err);
}
return this._cluster._getConnection(clusterNode, (err, connection) => {
if (err) {
if (
this._cluster._canRetry &&
this._cluster._findNodeIds(this._pattern).length !== 0
) {
this._cluster.emit('warn', err);
return this.getConnection(cb);
}
return cb(err);
}
return cb(null, connection);
});
}
/**
* pool cluster query
* @param {*} sql
* @param {*} values
* @param {*} cb
* @returns query
*/
query(sql, values, cb) {
const query = Connection.createQuery(sql, values, cb, {});
this.getConnection((err, conn) => {
if (err) {
if (typeof query.onResult === 'function') {
query.onResult(err);
} else {
query.emit('error', err);
}
return;
}
try {
conn.query(query).once('end', () => {
conn.release();
});
} catch (e) {
conn.release();
throw e;
}
});
return query;
}
/**
* pool cluster execute
* @param {*} sql
* @param {*} values
* @param {*} cb
*/
execute(sql, values, cb) {
if (typeof values === 'function') {
cb = values;
values = [];
}
this.getConnection((err, conn) => {
if (err) {
return cb(err);
}
try {
conn.execute(sql, values, cb).once('end', () => {
conn.release();
});
} catch (e) {
conn.release();
throw e;
}
});
}
_getClusterNode() {
const foundNodeIds = this._cluster._findNodeIds(this._pattern);
if (foundNodeIds.length === 0) {
return null;
}
const nodeId =
foundNodeIds.length === 1
? foundNodeIds[0]
: this._selector(foundNodeIds);
return this._cluster._getNode(nodeId);
}
}
class PoolCluster extends EventEmitter {
constructor(config) {
super();
config = config || {};
this._canRetry =
typeof config.canRetry === 'undefined' ? true : config.canRetry;
this._removeNodeErrorCount = config.removeNodeErrorCount || 5;
this._restoreNodeTimeout = config.restoreNodeTimeout || 0;
this._defaultSelector = config.defaultSelector || 'RR';
this._closed = false;
this._lastId = 0;
this._nodes = {};
this._serviceableNodeIds = [];
this._namespaces = {};
this._findCaches = {};
}
of(pattern, selector) {
pattern = pattern || '*';
selector = selector || this._defaultSelector;
selector = selector.toUpperCase();
if (!makeSelector[selector] === 'undefined') {
selector = this._defaultSelector;
}
const key = pattern + selector;
if (typeof this._namespaces[key] === 'undefined') {
this._namespaces[key] = new PoolNamespace(this, pattern, selector);
}
return this._namespaces[key];
}
add(id, config) {
if (typeof id === 'object') {
config = id;
id = `CLUSTER::${++this._lastId}`;
}
if (typeof this._nodes[id] === 'undefined') {
this._nodes[id] = {
id: id,
errorCount: 0,
pool: new Pool({ config: new PoolConfig(config) }),
_offlineUntil: 0,
};
this._serviceableNodeIds.push(id);
this._clearFindCaches();
}
}
remove(pattern) {
const foundNodeIds = this._findNodeIds(pattern, true);
for (let i = 0; i < foundNodeIds.length; i++) {
const node = this._getNode(foundNodeIds[i]);
if (node) {
this._removeNode(node);
}
}
}
getConnection(pattern, selector, cb) {
let namespace;
if (typeof pattern === 'function') {
cb = pattern;
namespace = this.of();
} else {
if (typeof selector === 'function') {
cb = selector;
selector = this._defaultSelector;
}
namespace = this.of(pattern, selector);
}
namespace.getConnection(cb);
}
end(callback) {
const cb =
callback !== undefined
? callback
: (err) => {
if (err) {
throw err;
}
};
if (this._closed) {
process.nextTick(cb);
return;
}
this._closed = true;
let calledBack = false;
let waitingClose = 0;
const onEnd = (err) => {
if (!calledBack && (err || --waitingClose <= 0)) {
calledBack = true;
return cb(err);
}
};
for (const id in this._nodes) {
waitingClose++;
this._nodes[id].pool.end(onEnd);
}
if (waitingClose === 0) {
process.nextTick(onEnd);
}
}
_findNodeIds(pattern, includeOffline) {
let currentTime = 0;
let foundNodeIds = this._findCaches[pattern];
if (foundNodeIds === undefined) {
const expression = patternRegExp(pattern);
foundNodeIds = this._serviceableNodeIds.filter((id) =>
id.match(expression)
);
}
this._findCaches[pattern] = foundNodeIds;
if (includeOffline) {
return foundNodeIds;
}
return foundNodeIds.filter((nodeId) => {
const node = this._getNode(nodeId);
if (!node._offlineUntil) {
return true;
}
if (!currentTime) {
currentTime = getMonotonicMilliseconds();
}
return node._offlineUntil <= currentTime;
});
}
_getNode(id) {
return this._nodes[id] || null;
}
_increaseErrorCount(node) {
const errorCount = ++node.errorCount;
if (this._removeNodeErrorCount > errorCount) {
return;
}
if (this._restoreNodeTimeout > 0) {
node._offlineUntil =
getMonotonicMilliseconds() + this._restoreNodeTimeout;
this.emit('offline', node.id);
return;
}
this._removeNode(node);
this.emit('remove', node.id);
}
_decreaseErrorCount(node) {
let errorCount = node.errorCount;
if (errorCount > this._removeNodeErrorCount) {
errorCount = this._removeNodeErrorCount;
}
if (errorCount < 1) {
errorCount = 1;
}
node.errorCount = errorCount - 1;
if (node._offlineUntil) {
node._offlineUntil = 0;
this.emit('online', node.id);
}
}
_getConnection(node, cb) {
node.pool.getConnection((err, connection) => {
if (err) {
this._increaseErrorCount(node);
return cb(err);
}
this._decreaseErrorCount(node);
connection._clusterId = node.id;
return cb(null, connection);
});
}
_removeNode(node) {
const index = this._serviceableNodeIds.indexOf(node.id);
if (index !== -1) {
this._serviceableNodeIds.splice(index, 1);
delete this._nodes[node.id];
this._clearFindCaches();
node.pool.end();
}
}
_clearFindCaches() {
this._findCaches = {};
}
}
module.exports = PoolCluster;

30
node_modules/mysql2/lib/pool_config.js generated vendored Normal file
View File

@@ -0,0 +1,30 @@
'use strict';
const ConnectionConfig = require('./connection_config.js');
class PoolConfig {
constructor(options) {
if (typeof options === 'string') {
options = ConnectionConfig.parseUrl(options);
}
this.connectionConfig = new ConnectionConfig(options);
this.waitForConnections =
options.waitForConnections === undefined
? true
: Boolean(options.waitForConnections);
this.connectionLimit = isNaN(options.connectionLimit)
? 10
: Number(options.connectionLimit);
this.maxIdle = isNaN(options.maxIdle)
? this.connectionLimit
: Number(options.maxIdle);
this.idleTimeout = isNaN(options.idleTimeout)
? 60000
: Number(options.idleTimeout);
this.queueLimit = isNaN(options.queueLimit)
? 0
: Number(options.queueLimit);
}
}
module.exports = PoolConfig;

12
node_modules/mysql2/lib/pool_connection.js generated vendored Normal file
View File

@@ -0,0 +1,12 @@
'use strict';
const BasePoolConnection = require('./base/pool_connection.js');
class PoolConnection extends BasePoolConnection {
promise(promiseImpl) {
const PromisePoolConnection = require('./promise/pool_connection.js');
return new PromisePoolConnection(this, promiseImpl);
}
}
module.exports = PoolConnection;

222
node_modules/mysql2/lib/promise/connection.js generated vendored Normal file
View File

@@ -0,0 +1,222 @@
'use strict';
const EventEmitter = require('events').EventEmitter;
const PromisePreparedStatementInfo = require('./prepared_statement_info.js');
const makeDoneCb = require('./make_done_cb.js');
const inheritEvents = require('./inherit_events.js');
const BaseConnection = require('../base/connection.js');
class PromiseConnection extends EventEmitter {
constructor(connection, promiseImpl) {
super();
this.connection = connection;
this.Promise = promiseImpl || Promise;
inheritEvents(connection, this, [
'error',
'drain',
'connect',
'end',
'enqueue',
]);
}
release() {
this.connection.release();
}
query(query, params) {
const c = this.connection;
const localErr = new Error();
if (typeof params === 'function') {
throw new Error(
'Callback function is not available with promise clients.'
);
}
return new this.Promise((resolve, reject) => {
const done = makeDoneCb(resolve, reject, localErr);
if (params !== undefined) {
c.query(query, params, done);
} else {
c.query(query, done);
}
});
}
execute(query, params) {
const c = this.connection;
const localErr = new Error();
if (typeof params === 'function') {
throw new Error(
'Callback function is not available with promise clients.'
);
}
return new this.Promise((resolve, reject) => {
const done = makeDoneCb(resolve, reject, localErr);
if (params !== undefined) {
c.execute(query, params, done);
} else {
c.execute(query, done);
}
});
}
end() {
return new this.Promise((resolve) => {
this.connection.end(resolve);
});
}
beginTransaction() {
const c = this.connection;
const localErr = new Error();
return new this.Promise((resolve, reject) => {
const done = makeDoneCb(resolve, reject, localErr);
c.beginTransaction(done);
});
}
commit() {
const c = this.connection;
const localErr = new Error();
return new this.Promise((resolve, reject) => {
const done = makeDoneCb(resolve, reject, localErr);
c.commit(done);
});
}
rollback() {
const c = this.connection;
const localErr = new Error();
return new this.Promise((resolve, reject) => {
const done = makeDoneCb(resolve, reject, localErr);
c.rollback(done);
});
}
ping() {
const c = this.connection;
const localErr = new Error();
return new this.Promise((resolve, reject) => {
c.ping((err) => {
if (err) {
localErr.message = err.message;
localErr.code = err.code;
localErr.errno = err.errno;
localErr.sqlState = err.sqlState;
localErr.sqlMessage = err.sqlMessage;
reject(localErr);
} else {
resolve(true);
}
});
});
}
connect() {
const c = this.connection;
const localErr = new Error();
return new this.Promise((resolve, reject) => {
c.connect((err, param) => {
if (err) {
localErr.message = err.message;
localErr.code = err.code;
localErr.errno = err.errno;
localErr.sqlState = err.sqlState;
localErr.sqlMessage = err.sqlMessage;
reject(localErr);
} else {
resolve(param);
}
});
});
}
prepare(options) {
const c = this.connection;
const promiseImpl = this.Promise;
const localErr = new Error();
return new this.Promise((resolve, reject) => {
c.prepare(options, (err, statement) => {
if (err) {
localErr.message = err.message;
localErr.code = err.code;
localErr.errno = err.errno;
localErr.sqlState = err.sqlState;
localErr.sqlMessage = err.sqlMessage;
reject(localErr);
} else {
const wrappedStatement = new PromisePreparedStatementInfo(
statement,
promiseImpl
);
resolve(wrappedStatement);
}
});
});
}
changeUser(options) {
const c = this.connection;
const localErr = new Error();
return new this.Promise((resolve, reject) => {
c.changeUser(options, (err) => {
if (err) {
localErr.message = err.message;
localErr.code = err.code;
localErr.errno = err.errno;
localErr.sqlState = err.sqlState;
localErr.sqlMessage = err.sqlMessage;
reject(localErr);
} else {
resolve();
}
});
});
}
get config() {
return this.connection.config;
}
get threadId() {
return this.connection.threadId;
}
}
// patching PromiseConnection
// create facade functions for prototype functions on "Connection" that are not yet
// implemented with PromiseConnection
// proxy synchronous functions only
(function (functionsToWrap) {
for (let i = 0; functionsToWrap && i < functionsToWrap.length; i++) {
const func = functionsToWrap[i];
if (
typeof BaseConnection.prototype[func] === 'function' &&
PromiseConnection.prototype[func] === undefined
) {
PromiseConnection.prototype[func] = (function factory(funcName) {
return function () {
return BaseConnection.prototype[funcName].apply(
this.connection,
arguments
);
};
})(func);
}
}
})([
// synchronous functions
'close',
'createBinlogStream',
'destroy',
'escape',
'escapeId',
'format',
'pause',
'pipe',
'resume',
'unprepare',
]);
module.exports = PromiseConnection;

27
node_modules/mysql2/lib/promise/inherit_events.js generated vendored Normal file
View File

@@ -0,0 +1,27 @@
'use strict';
function inheritEvents(source, target, events) {
const listeners = {};
target
.on('newListener', (eventName) => {
if (events.indexOf(eventName) >= 0 && !target.listenerCount(eventName)) {
source.on(
eventName,
(listeners[eventName] = function () {
const args = [].slice.call(arguments);
args.unshift(eventName);
target.emit.apply(target, args);
})
);
}
})
.on('removeListener', (eventName) => {
if (events.indexOf(eventName) >= 0 && !target.listenerCount(eventName)) {
source.removeListener(eventName, listeners[eventName]);
delete listeners[eventName];
}
});
}
module.exports = inheritEvents;

19
node_modules/mysql2/lib/promise/make_done_cb.js generated vendored Normal file
View File

@@ -0,0 +1,19 @@
'use strict';
function makeDoneCb(resolve, reject, localErr) {
return function (err, rows, fields) {
if (err) {
localErr.message = err.message;
localErr.code = err.code;
localErr.errno = err.errno;
localErr.sql = err.sql;
localErr.sqlState = err.sqlState;
localErr.sqlMessage = err.sqlMessage;
reject(localErr);
} else {
resolve([rows, fields]);
}
};
}
module.exports = makeDoneCb;

112
node_modules/mysql2/lib/promise/pool.js generated vendored Normal file
View File

@@ -0,0 +1,112 @@
'use strict';
const EventEmitter = require('events').EventEmitter;
const makeDoneCb = require('./make_done_cb.js');
const PromisePoolConnection = require('./pool_connection.js');
const inheritEvents = require('./inherit_events.js');
const BasePool = require('../base/pool.js');
class PromisePool extends EventEmitter {
constructor(pool, thePromise) {
super();
this.pool = pool;
this.Promise = thePromise || Promise;
inheritEvents(pool, this, ['acquire', 'connection', 'enqueue', 'release']);
}
getConnection() {
const corePool = this.pool;
return new this.Promise((resolve, reject) => {
corePool.getConnection((err, coreConnection) => {
if (err) {
reject(err);
} else {
resolve(new PromisePoolConnection(coreConnection, this.Promise));
}
});
});
}
releaseConnection(connection) {
if (connection instanceof PromisePoolConnection) connection.release();
}
query(sql, args) {
const corePool = this.pool;
const localErr = new Error();
if (typeof args === 'function') {
throw new Error(
'Callback function is not available with promise clients.'
);
}
return new this.Promise((resolve, reject) => {
const done = makeDoneCb(resolve, reject, localErr);
if (args !== undefined) {
corePool.query(sql, args, done);
} else {
corePool.query(sql, done);
}
});
}
execute(sql, args) {
const corePool = this.pool;
const localErr = new Error();
if (typeof args === 'function') {
throw new Error(
'Callback function is not available with promise clients.'
);
}
return new this.Promise((resolve, reject) => {
const done = makeDoneCb(resolve, reject, localErr);
if (args) {
corePool.execute(sql, args, done);
} else {
corePool.execute(sql, done);
}
});
}
end() {
const corePool = this.pool;
const localErr = new Error();
return new this.Promise((resolve, reject) => {
corePool.end((err) => {
if (err) {
localErr.message = err.message;
localErr.code = err.code;
localErr.errno = err.errno;
localErr.sqlState = err.sqlState;
localErr.sqlMessage = err.sqlMessage;
reject(localErr);
} else {
resolve();
}
});
});
}
}
(function (functionsToWrap) {
for (let i = 0; functionsToWrap && i < functionsToWrap.length; i++) {
const func = functionsToWrap[i];
if (
typeof BasePool.prototype[func] === 'function' &&
PromisePool.prototype[func] === undefined
) {
PromisePool.prototype[func] = (function factory(funcName) {
return function () {
return BasePool.prototype[funcName].apply(this.pool, arguments);
};
})(func);
}
}
})([
// synchronous functions
'escape',
'escapeId',
'format',
]);
module.exports = PromisePool;

54
node_modules/mysql2/lib/promise/pool_cluster.js generated vendored Normal file
View File

@@ -0,0 +1,54 @@
'use strict';
const PromisePoolConnection = require('./pool_connection');
const makeDoneCb = require('./make_done_cb');
class PromisePoolNamespace {
constructor(poolNamespace, thePromise) {
this.poolNamespace = poolNamespace;
this.Promise = thePromise || Promise;
}
getConnection() {
const corePoolNamespace = this.poolNamespace;
return new this.Promise((resolve, reject) => {
corePoolNamespace.getConnection((err, coreConnection) => {
if (err) {
reject(err);
} else {
resolve(new PromisePoolConnection(coreConnection, this.Promise));
}
});
});
}
query(sql, values) {
const corePoolNamespace = this.poolNamespace;
const localErr = new Error();
if (typeof values === 'function') {
throw new Error(
'Callback function is not available with promise clients.'
);
}
return new this.Promise((resolve, reject) => {
const done = makeDoneCb(resolve, reject, localErr);
corePoolNamespace.query(sql, values, done);
});
}
execute(sql, values) {
const corePoolNamespace = this.poolNamespace;
const localErr = new Error();
if (typeof values === 'function') {
throw new Error(
'Callback function is not available with promise clients.'
);
}
return new this.Promise((resolve, reject) => {
const done = makeDoneCb(resolve, reject, localErr);
corePoolNamespace.execute(sql, values, done);
});
}
}
module.exports = PromisePoolNamespace;

19
node_modules/mysql2/lib/promise/pool_connection.js generated vendored Normal file
View File

@@ -0,0 +1,19 @@
'use strict';
const PromiseConnection = require('./connection.js');
const BasePoolConnection = require('../base/pool_connection.js');
class PromisePoolConnection extends PromiseConnection {
constructor(connection, promiseImpl) {
super(connection, promiseImpl);
}
destroy() {
return BasePoolConnection.prototype.destroy.apply(
this.connection,
arguments
);
}
}
module.exports = PromisePoolConnection;

View File

@@ -0,0 +1,32 @@
'use strict';
const makeDoneCb = require('./make_done_cb.js');
class PromisePreparedStatementInfo {
constructor(statement, promiseImpl) {
this.statement = statement;
this.Promise = promiseImpl;
}
execute(parameters) {
const s = this.statement;
const localErr = new Error();
return new this.Promise((resolve, reject) => {
const done = makeDoneCb(resolve, reject, localErr);
if (parameters) {
s.execute(parameters, done);
} else {
s.execute(done);
}
});
}
close() {
return new this.Promise((resolve) => {
this.statement.close();
resolve();
});
}
}
module.exports = PromisePreparedStatementInfo;

38
node_modules/mysql2/lib/results_stream.js generated vendored Normal file
View File

@@ -0,0 +1,38 @@
'use strict';
const Readable = require('stream').Readable;
// copy-paste from https://github.com/mysqljs/mysql/blob/master/lib/protocol/sequences/Query.js
module.exports = function (command, connectionStream) {
command.stream = function (options) {
let stream;
options = options || {};
options.objectMode = true;
(stream = new Readable(options)),
(stream._read = function () {
connectionStream.resume();
});
this.on('result', (row, i) => {
if (!stream.push(row)) {
connectionStream.pause();
}
stream.emit('result', row, i); // replicate old emitter
});
this.on('error', (err) => {
stream.emit('error', err); // Pass on any errors
});
this.on('end', () => {
stream.push(null); // pushing null, indicating EOF
});
this.on('fields', (fields, i) => {
stream.emit('fields', fields, i); // replicate old emitter
});
return stream;
};
};

37
node_modules/mysql2/lib/server.js generated vendored Normal file
View File

@@ -0,0 +1,37 @@
'use strict';
const net = require('net');
const EventEmitter = require('events').EventEmitter;
const Connection = require('./connection');
const ConnectionConfig = require('./connection_config');
// TODO: inherit Server from net.Server
class Server extends EventEmitter {
constructor() {
super();
this.connections = [];
this._server = net.createServer(this._handleConnection.bind(this));
}
_handleConnection(socket) {
const connectionConfig = new ConnectionConfig({
stream: socket,
isServer: true,
});
const connection = new Connection({ config: connectionConfig });
this.emit('connection', connection);
}
listen(port) {
this._port = port;
this._server.listen.apply(this._server, arguments);
return this;
}
close(cb) {
this._server.close(cb);
}
}
module.exports = Server;

View File

@@ -0,0 +1,236 @@
## 0.7.0
### 🐞 Bug fixes
* Handle split surrogate pairs when encoding utf8 - by [@yosion-p](https://github.com/yosion-p) and [@ashtuchkin](https://github.com/ashtuchkin) in [#282](https://github.com/ashtuchkin/iconv-lite/pull/282):
Handle a case where streaming utf8 encoder (converting js strings -> buffers) encounters
surrogate pairs split between chunks (last character of one chunk is high surrogate and first
character of the next chunk is a low surrogate).
* Avoid false positives in encodingExists by using objects without a prototype - by [@bjohansebas](https://github.com/bjohansebas) in [#328](https://github.com/ashtuchkin/iconv-lite/pull/328)
The encodingExists method could return incorrect results if the lookup matched properties inherited
from the prototype of the object that stores the encodings, such as constructor and others. This change
replaces that object with one that has no prototype, ensuring that only explicitly defined valid encodings
in the library are considered. In addition, the fix is applied to the internal cache system to avoid the same
kind of false positives
### 🚀 Improvements
* Make explicit that decode() method supports Uint8Array input - by [@jardicc](https://github.com/jardicc) in [#271](https://github.com/ashtuchkin/iconv-lite/pull/271)
* Remove compatibility check for StringDecoder.end method - by [@bjohansebas](https://github.com/bjohansebas) in [#331](https://github.com/ashtuchkin/iconv-lite/pull/331)
## 0.6.3 / 2021-05-23
* Fix HKSCS encoding to prefer Big5 codes if both Big5 and HKSCS codes are possible (#264)
## 0.6.2 / 2020-07-08
* Support Uint8Array-s decoding without conversion to Buffers, plus fix an edge case.
## 0.6.1 / 2020-06-28
* Support Uint8Array-s directly when decoding (#246, by @gyzerok)
* Unify package.json version ranges to be strictly semver-compatible (#241)
* Fix minor issue in UTF-32 decoder's endianness detection code.
## 0.6.0 / 2020-06-08
* Updated 'gb18030' encoding to :2005 edition (see https://github.com/whatwg/encoding/issues/22).
* Removed `iconv.extendNodeEncodings()` mechanism. It was deprecated 5 years ago and didn't work
in recent Node versions.
* Reworked Streaming API behavior in browser environments to fix #204. Streaming API will be
excluded by default in browser packs, saving ~100Kb bundle size, unless enabled explicitly using
`iconv.enableStreamingAPI(require('stream'))`.
* Updates to development environment & tests:
* Added ./test/webpack private package to test complex new use cases that need custom environment.
It's tested as a separate job in Travis CI.
* Updated generation code for the new EUC-KR index file format from Encoding Standard.
* Removed Buffer() constructor in tests (#197 by @gabrielschulhof).
## 0.5.2 / 2020-06-08
* Added `iconv.getEncoder()` and `iconv.getDecoder()` methods to typescript definitions (#229).
* Fixed semver version to 6.1.2 to support Node 8.x (by @tanandara).
* Capped iconv version to 2.x as 3.x has dropped support for older Node versions.
* Switched from instanbul to c8 for code coverage.
## 0.5.1 / 2020-01-18
* Added cp720 encoding (#221, by @kr-deps)
* (minor) Changed Changelog.md formatting to use h2.
## 0.5.0 / 2019-06-26
* Added UTF-32 encoding, both little-endian and big-endian variants (UTF-32LE, UTF32-BE). If endianness
is not provided for decoding, it's deduced automatically from the stream using a heuristic similar to
what we use in UTF-16. (great work in #216 by @kshetline)
* Several minor updates to README (#217 by @oldj, plus some more)
* Added Node versions 10 and 12 to Travis test harness.
## 0.4.24 / 2018-08-22
* Added MIK encoding (#196, by @Ivan-Kalatchev)
## 0.4.23 / 2018-05-07
* Fix deprecation warning in Node v10 due to the last usage of `new Buffer` (#185, by @felixbuenemann)
* Switched from NodeBuffer to Buffer in typings (#155 by @felixfbecker, #186 by @larssn)
## 0.4.22 / 2018-05-05
* Use older semver style for dependencies to be compatible with Node version 0.10 (#182, by @dougwilson)
* Fix tests to accomodate fixes in Node v10 (#182, by @dougwilson)
## 0.4.21 / 2018-04-06
* Fix encoding canonicalization (#156)
* Fix the paths in the "browser" field in package.json (#174 by @LMLB)
* Removed "contributors" section in package.json - see Git history instead.
## 0.4.20 / 2018-04-06
* Updated `new Buffer()` usages with recommended replacements as it's being deprecated in Node v10 (#176, #178 by @ChALkeR)
## 0.4.19 / 2017-09-09
* Fixed iso8859-1 codec regression in handling untranslatable characters (#162, caused by #147)
* Re-generated windows1255 codec, because it was updated in iconv project
* Fixed grammar in error message when iconv-lite is loaded with encoding other than utf8
## 0.4.18 / 2017-06-13
* Fixed CESU-8 regression in Node v8.
## 0.4.17 / 2017-04-22
* Updated typescript definition file to support Angular 2 AoT mode (#153 by @larssn)
## 0.4.16 / 2017-04-22
* Added support for React Native (#150)
* Changed iso8859-1 encoding to usine internal 'binary' encoding, as it's the same thing (#147 by @mscdex)
* Fixed typo in Readme (#138 by @jiangzhuo)
* Fixed build for Node v6.10+ by making correct version comparison
* Added a warning if iconv-lite is loaded not as utf-8 (see #142)
## 0.4.15 / 2016-11-21
* Fixed typescript type definition (#137)
## 0.4.14 / 2016-11-20
* Preparation for v1.0
* Added Node v6 and latest Node versions to Travis CI test rig
* Deprecated Node v0.8 support
* Typescript typings (@larssn)
* Fix encoding of Euro character in GB 18030 (inspired by @lygstate)
* Add ms prefix to dbcs windows encodings (@rokoroku)
## 0.4.13 / 2015-10-01
* Fix silly mistake in deprecation notice.
## 0.4.12 / 2015-09-26
* Node v4 support:
* Added CESU-8 decoding (#106)
* Added deprecation notice for `extendNodeEncodings`
* Added Travis tests for Node v4 and io.js latest (#105 by @Mithgol)
## 0.4.11 / 2015-07-03
* Added CESU-8 encoding.
## 0.4.10 / 2015-05-26
* Changed UTF-16 endianness heuristic to take into account any ASCII chars, not
just spaces. This should minimize the importance of "default" endianness.
## 0.4.9 / 2015-05-24
* Streamlined BOM handling: strip BOM by default, add BOM when encoding if
addBOM: true. Added docs to Readme.
* UTF16 now uses UTF16-LE by default.
* Fixed minor issue with big5 encoding.
* Added io.js testing on Travis; updated node-iconv version to test against.
Now we just skip testing SBCS encodings that node-iconv doesn't support.
* (internal refactoring) Updated codec interface to use classes.
* Use strict mode in all files.
## 0.4.8 / 2015-04-14
* added alias UNICODE-1-1-UTF-7 for UTF-7 encoding (#94)
## 0.4.7 / 2015-02-05
* stop official support of Node.js v0.8. Should still work, but no guarantees.
reason: Packages needed for testing are hard to get on Travis CI.
* work in environment where Object.prototype is monkey patched with enumerable
props (#89).
## 0.4.6 / 2015-01-12
* fix rare aliases of single-byte encodings (thanks @mscdex)
* double the timeout for dbcs tests to make them less flaky on travis
## 0.4.5 / 2014-11-20
* fix windows-31j and x-sjis encoding support (@nleush)
* minor fix: undefined variable reference when internal error happens
## 0.4.4 / 2014-07-16
* added encodings UTF-7 (RFC2152) and UTF-7-IMAP (RFC3501 Section 5.1.3)
* fixed streaming base64 encoding
## 0.4.3 / 2014-06-14
* added encodings UTF-16BE and UTF-16 with BOM
## 0.4.2 / 2014-06-12
* don't throw exception if `extendNodeEncodings()` is called more than once
## 0.4.1 / 2014-06-11
* codepage 808 added
## 0.4.0 / 2014-06-10
* code is rewritten from scratch
* all widespread encodings are supported
* streaming interface added
* browserify compatibility added
* (optional) extend core primitive encodings to make usage even simpler
* moved from vows to mocha as the testing framework

21
node_modules/mysql2/node_modules/iconv-lite/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
Copyright (c) 2011 Alexander Shtuchkin
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

138
node_modules/mysql2/node_modules/iconv-lite/README.md generated vendored Normal file
View File

@@ -0,0 +1,138 @@
## iconv-lite: Pure JS character encoding conversion
[![NPM Version][npm-version-image]][npm-url]
[![NPM Downloads][npm-downloads-image]][npm-downloads-url]
[![License][license-image]][license-url]
[![NPM Install Size][npm-install-size-image]][npm-install-size-url]
* No need for native code compilation. Quick to install, works on Windows, Web, and in sandboxed environments.
* Used in popular projects like [Express.js (body_parser)](https://github.com/expressjs/body-parser),
[Grunt](http://gruntjs.com/), [Nodemailer](http://www.nodemailer.com/), [Yeoman](http://yeoman.io/) and others.
* Faster than [node-iconv](https://github.com/bnoordhuis/node-iconv) (see below for performance comparison).
* Intuitive encode/decode API, including Streaming support.
* In-browser usage via [browserify](https://github.com/substack/node-browserify) or [webpack](https://webpack.js.org/) (~180kb gzip compressed with Buffer shim included).
* Typescript [type definition file](https://github.com/ashtuchkin/iconv-lite/blob/master/lib/index.d.ts) included.
* React Native is supported (need to install `stream` module to enable Streaming API).
## Usage
### Basic API
```javascript
var iconv = require('iconv-lite');
// Convert from an encoded buffer to a js string.
str = iconv.decode(Buffer.from([0x68, 0x65, 0x6c, 0x6c, 0x6f]), 'win1251');
// Convert from a js string to an encoded buffer.
buf = iconv.encode("Sample input string", 'win1251');
// Check if encoding is supported
iconv.encodingExists("us-ascii")
```
### Streaming API
```javascript
// Decode stream (from binary data stream to js strings)
http.createServer(function(req, res) {
var converterStream = iconv.decodeStream('win1251');
req.pipe(converterStream);
converterStream.on('data', function(str) {
console.log(str); // Do something with decoded strings, chunk-by-chunk.
});
});
// Convert encoding streaming example
fs.createReadStream('file-in-win1251.txt')
.pipe(iconv.decodeStream('win1251'))
.pipe(iconv.encodeStream('ucs2'))
.pipe(fs.createWriteStream('file-in-ucs2.txt'));
// Sugar: all encode/decode streams have .collect(cb) method to accumulate data.
http.createServer(function(req, res) {
req.pipe(iconv.decodeStream('win1251')).collect(function(err, body) {
assert(typeof body == 'string');
console.log(body); // full request body string
});
});
```
## Supported encodings
* All node.js native encodings: utf8, ucs2 / utf16-le, ascii, binary, base64, hex.
* Additional unicode encodings: utf16, utf16-be, utf-7, utf-7-imap, utf32, utf32-le, and utf32-be.
* All widespread singlebyte encodings: Windows 125x family, ISO-8859 family,
IBM/DOS codepages, Macintosh family, KOI8 family, all others supported by iconv library.
Aliases like 'latin1', 'us-ascii' also supported.
* All widespread multibyte encodings: CP932, CP936, CP949, CP950, GB2312, GBK, GB18030, Big5, Shift_JIS, EUC-JP.
See [all supported encodings on wiki](https://github.com/ashtuchkin/iconv-lite/wiki/Supported-Encodings).
Most singlebyte encodings are generated automatically from [node-iconv](https://github.com/bnoordhuis/node-iconv). Thank you Ben Noordhuis and libiconv authors!
Multibyte encodings are generated from [Unicode.org mappings](http://www.unicode.org/Public/MAPPINGS/) and [WHATWG Encoding Standard mappings](http://encoding.spec.whatwg.org/). Thank you, respective authors!
## Encoding/decoding speed
Comparison with node-iconv module (1000x256kb, on MacBook Pro, Core i5/2.6 GHz, Node v0.12.0).
Note: your results may vary, so please always check on your hardware.
operation iconv@2.1.4 iconv-lite@0.4.7
----------------------------------------------------------
encode('win1251') ~96 Mb/s ~320 Mb/s
decode('win1251') ~95 Mb/s ~246 Mb/s
## BOM handling
* Decoding: BOM is stripped by default, unless overridden by passing `stripBOM: false` in options
(f.ex. `iconv.decode(buf, enc, {stripBOM: false})`).
A callback might also be given as a `stripBOM` parameter - it'll be called if BOM character was actually found.
* If you want to detect UTF-8 BOM when decoding other encodings, use [node-autodetect-decoder-stream](https://github.com/danielgindi/node-autodetect-decoder-stream) module.
* Encoding: No BOM added, unless overridden by `addBOM: true` option.
## UTF-16 Encodings
This library supports UTF-16LE, UTF-16BE and UTF-16 encodings. First two are straightforward, but UTF-16 is trying to be
smart about endianness in the following ways:
* Decoding: uses BOM and 'spaces heuristic' to determine input endianness. Default is UTF-16LE, but can be
overridden with `defaultEncoding: 'utf-16be'` option. Strips BOM unless `stripBOM: false`.
* Encoding: uses UTF-16LE and writes BOM by default. Use `addBOM: false` to override.
## UTF-32 Encodings
This library supports UTF-32LE, UTF-32BE and UTF-32 encodings. Like the UTF-16 encoding above, UTF-32 defaults to UTF-32LE, but uses BOM and 'spaces heuristics' to determine input endianness.
* The default of UTF-32LE can be overridden with the `defaultEncoding: 'utf-32be'` option. Strips BOM unless `stripBOM: false`.
* Encoding: uses UTF-32LE and writes BOM by default. Use `addBOM: false` to override. (`defaultEncoding: 'utf-32be'` can also be used here to change encoding.)
## Other notes
When decoding, be sure to supply a Buffer to decode() method, otherwise [bad things usually happen](https://github.com/ashtuchkin/iconv-lite/wiki/Use-Buffers-when-decoding).
Untranslatable characters are set to <20> or ?. No transliteration is currently supported.
Node versions 0.10.31 and 0.11.13 are buggy, don't use them (see [#65](https://github.com/ashtuchkin/iconv-lite/issues/65), [#77](https://github.com/ashtuchkin/iconv-lite/issues/77)).
## Testing
```sh
git clone git@github.com:ashtuchkin/iconv-lite.git
cd iconv-lite
npm install
npm test
# To view performance:
npm run test:performance
# To view test coverage:
npm run test:cov
open coverage/index.html
```
[npm-downloads-image]: https://badgen.net/npm/dm/iconv-lite
[npm-downloads-url]: https://npmcharts.com/compare/iconv-lite?minimal=true
[npm-url]: https://npmjs.org/package/iconv-lite
[npm-version-image]: https://badgen.net/npm/v/iconv-lite
[npm-install-size-image]: https://badgen.net/packagephobia/install/iconv-lite
[npm-install-size-url]: https://packagephobia.com/result?p=iconv-lite
[license-image]: https://img.shields.io/npm/l/iconv-lite.svg
[license-url]: https://github.com/ashtuchkin/iconv-lite/blob/HEAD/LICENSE

View File

@@ -0,0 +1,532 @@
"use strict"
var Buffer = require("safer-buffer").Buffer
// Multibyte codec. In this scheme, a character is represented by 1 or more bytes.
// Our codec supports UTF-16 surrogates, extensions for GB18030 and unicode sequences.
// To save memory and loading time, we read table files only when requested.
exports._dbcs = DBCSCodec
var UNASSIGNED = -1
var GB18030_CODE = -2
var SEQ_START = -10
var NODE_START = -1000
var UNASSIGNED_NODE = new Array(0x100)
var DEF_CHAR = -1
for (var i = 0; i < 0x100; i++) { UNASSIGNED_NODE[i] = UNASSIGNED }
// Class DBCSCodec reads and initializes mapping tables.
function DBCSCodec (codecOptions, iconv) {
this.encodingName = codecOptions.encodingName
if (!codecOptions) { throw new Error("DBCS codec is called without the data.") }
if (!codecOptions.table) { throw new Error("Encoding '" + this.encodingName + "' has no data.") }
// Load tables.
var mappingTable = codecOptions.table()
// Decode tables: MBCS -> Unicode.
// decodeTables is a trie, encoded as an array of arrays of integers. Internal arrays are trie nodes and all have len = 256.
// Trie root is decodeTables[0].
// Values: >= 0 -> unicode character code. can be > 0xFFFF
// == UNASSIGNED -> unknown/unassigned sequence.
// == GB18030_CODE -> this is the end of a GB18030 4-byte sequence.
// <= NODE_START -> index of the next node in our trie to process next byte.
// <= SEQ_START -> index of the start of a character code sequence, in decodeTableSeq.
this.decodeTables = []
this.decodeTables[0] = UNASSIGNED_NODE.slice(0) // Create root node.
// Sometimes a MBCS char corresponds to a sequence of unicode chars. We store them as arrays of integers here.
this.decodeTableSeq = []
// Actual mapping tables consist of chunks. Use them to fill up decode tables.
for (var i = 0; i < mappingTable.length; i++) { this._addDecodeChunk(mappingTable[i]) }
// Load & create GB18030 tables when needed.
if (typeof codecOptions.gb18030 === "function") {
this.gb18030 = codecOptions.gb18030() // Load GB18030 ranges.
// Add GB18030 common decode nodes.
var commonThirdByteNodeIdx = this.decodeTables.length
this.decodeTables.push(UNASSIGNED_NODE.slice(0))
var commonFourthByteNodeIdx = this.decodeTables.length
this.decodeTables.push(UNASSIGNED_NODE.slice(0))
// Fill out the tree
var firstByteNode = this.decodeTables[0]
for (var i = 0x81; i <= 0xFE; i++) {
var secondByteNode = this.decodeTables[NODE_START - firstByteNode[i]]
for (var j = 0x30; j <= 0x39; j++) {
if (secondByteNode[j] === UNASSIGNED) {
secondByteNode[j] = NODE_START - commonThirdByteNodeIdx
} else if (secondByteNode[j] > NODE_START) {
throw new Error("gb18030 decode tables conflict at byte 2")
}
var thirdByteNode = this.decodeTables[NODE_START - secondByteNode[j]]
for (var k = 0x81; k <= 0xFE; k++) {
if (thirdByteNode[k] === UNASSIGNED) {
thirdByteNode[k] = NODE_START - commonFourthByteNodeIdx
} else if (thirdByteNode[k] === NODE_START - commonFourthByteNodeIdx) {
continue
} else if (thirdByteNode[k] > NODE_START) {
throw new Error("gb18030 decode tables conflict at byte 3")
}
var fourthByteNode = this.decodeTables[NODE_START - thirdByteNode[k]]
for (var l = 0x30; l <= 0x39; l++) {
if (fourthByteNode[l] === UNASSIGNED) { fourthByteNode[l] = GB18030_CODE }
}
}
}
}
}
this.defaultCharUnicode = iconv.defaultCharUnicode
// Encode tables: Unicode -> DBCS.
// `encodeTable` is array mapping from unicode char to encoded char. All its values are integers for performance.
// Because it can be sparse, it is represented as array of buckets by 256 chars each. Bucket can be null.
// Values: >= 0 -> it is a normal char. Write the value (if <=256 then 1 byte, if <=65536 then 2 bytes, etc.).
// == UNASSIGNED -> no conversion found. Output a default char.
// <= SEQ_START -> it's an index in encodeTableSeq, see below. The character starts a sequence.
this.encodeTable = []
// `encodeTableSeq` is used when a sequence of unicode characters is encoded as a single code. We use a tree of
// objects where keys correspond to characters in sequence and leafs are the encoded dbcs values. A special DEF_CHAR key
// means end of sequence (needed when one sequence is a strict subsequence of another).
// Objects are kept separately from encodeTable to increase performance.
this.encodeTableSeq = []
// Some chars can be decoded, but need not be encoded.
var skipEncodeChars = {}
if (codecOptions.encodeSkipVals) {
for (var i = 0; i < codecOptions.encodeSkipVals.length; i++) {
var val = codecOptions.encodeSkipVals[i]
if (typeof val === "number") { skipEncodeChars[val] = true } else {
for (var j = val.from; j <= val.to; j++) { skipEncodeChars[j] = true }
}
}
}
// Use decode trie to recursively fill out encode tables.
this._fillEncodeTable(0, 0, skipEncodeChars)
// Add more encoding pairs when needed.
if (codecOptions.encodeAdd) {
for (var uChar in codecOptions.encodeAdd) {
if (Object.prototype.hasOwnProperty.call(codecOptions.encodeAdd, uChar)) { this._setEncodeChar(uChar.charCodeAt(0), codecOptions.encodeAdd[uChar]) }
}
}
this.defCharSB = this.encodeTable[0][iconv.defaultCharSingleByte.charCodeAt(0)]
if (this.defCharSB === UNASSIGNED) this.defCharSB = this.encodeTable[0]["?"]
if (this.defCharSB === UNASSIGNED) this.defCharSB = "?".charCodeAt(0)
}
DBCSCodec.prototype.encoder = DBCSEncoder
DBCSCodec.prototype.decoder = DBCSDecoder
// Decoder helpers
DBCSCodec.prototype._getDecodeTrieNode = function (addr) {
var bytes = []
for (; addr > 0; addr >>>= 8) { bytes.push(addr & 0xFF) }
if (bytes.length == 0) { bytes.push(0) }
var node = this.decodeTables[0]
for (var i = bytes.length - 1; i > 0; i--) { // Traverse nodes deeper into the trie.
var val = node[bytes[i]]
if (val == UNASSIGNED) { // Create new node.
node[bytes[i]] = NODE_START - this.decodeTables.length
this.decodeTables.push(node = UNASSIGNED_NODE.slice(0))
} else if (val <= NODE_START) { // Existing node.
node = this.decodeTables[NODE_START - val]
} else { throw new Error("Overwrite byte in " + this.encodingName + ", addr: " + addr.toString(16)) }
}
return node
}
DBCSCodec.prototype._addDecodeChunk = function (chunk) {
// First element of chunk is the hex mbcs code where we start.
var curAddr = parseInt(chunk[0], 16)
// Choose the decoding node where we'll write our chars.
var writeTable = this._getDecodeTrieNode(curAddr)
curAddr = curAddr & 0xFF
// Write all other elements of the chunk to the table.
for (var k = 1; k < chunk.length; k++) {
var part = chunk[k]
if (typeof part === "string") { // String, write as-is.
for (var l = 0; l < part.length;) {
var code = part.charCodeAt(l++)
if (code >= 0xD800 && code < 0xDC00) { // Decode surrogate
var codeTrail = part.charCodeAt(l++)
if (codeTrail >= 0xDC00 && codeTrail < 0xE000) { writeTable[curAddr++] = 0x10000 + (code - 0xD800) * 0x400 + (codeTrail - 0xDC00) } else { throw new Error("Incorrect surrogate pair in " + this.encodingName + " at chunk " + chunk[0]) }
} else if (code > 0x0FF0 && code <= 0x0FFF) { // Character sequence (our own encoding used)
var len = 0xFFF - code + 2
var seq = []
for (var m = 0; m < len; m++) { seq.push(part.charCodeAt(l++)) } // Simple variation: don't support surrogates or subsequences in seq.
writeTable[curAddr++] = SEQ_START - this.decodeTableSeq.length
this.decodeTableSeq.push(seq)
} else { writeTable[curAddr++] = code } // Basic char
}
} else if (typeof part === "number") { // Integer, meaning increasing sequence starting with prev character.
var charCode = writeTable[curAddr - 1] + 1
for (var l = 0; l < part; l++) { writeTable[curAddr++] = charCode++ }
} else { throw new Error("Incorrect type '" + typeof part + "' given in " + this.encodingName + " at chunk " + chunk[0]) }
}
if (curAddr > 0xFF) { throw new Error("Incorrect chunk in " + this.encodingName + " at addr " + chunk[0] + ": too long" + curAddr) }
}
// Encoder helpers
DBCSCodec.prototype._getEncodeBucket = function (uCode) {
var high = uCode >> 8 // This could be > 0xFF because of astral characters.
if (this.encodeTable[high] === undefined) {
this.encodeTable[high] = UNASSIGNED_NODE.slice(0)
} // Create bucket on demand.
return this.encodeTable[high]
}
DBCSCodec.prototype._setEncodeChar = function (uCode, dbcsCode) {
var bucket = this._getEncodeBucket(uCode)
var low = uCode & 0xFF
if (bucket[low] <= SEQ_START) { this.encodeTableSeq[SEQ_START - bucket[low]][DEF_CHAR] = dbcsCode } // There's already a sequence, set a single-char subsequence of it.
else if (bucket[low] == UNASSIGNED) { bucket[low] = dbcsCode }
}
DBCSCodec.prototype._setEncodeSequence = function (seq, dbcsCode) {
// Get the root of character tree according to first character of the sequence.
var uCode = seq[0]
var bucket = this._getEncodeBucket(uCode)
var low = uCode & 0xFF
var node
if (bucket[low] <= SEQ_START) {
// There's already a sequence with - use it.
node = this.encodeTableSeq[SEQ_START - bucket[low]]
} else {
// There was no sequence object - allocate a new one.
node = {}
if (bucket[low] !== UNASSIGNED) node[DEF_CHAR] = bucket[low] // If a char was set before - make it a single-char subsequence.
bucket[low] = SEQ_START - this.encodeTableSeq.length
this.encodeTableSeq.push(node)
}
// Traverse the character tree, allocating new nodes as needed.
for (var j = 1; j < seq.length - 1; j++) {
var oldVal = node[uCode]
if (typeof oldVal === "object") { node = oldVal } else {
node = node[uCode] = {}
if (oldVal !== undefined) { node[DEF_CHAR] = oldVal }
}
}
// Set the leaf to given dbcsCode.
uCode = seq[seq.length - 1]
node[uCode] = dbcsCode
}
DBCSCodec.prototype._fillEncodeTable = function (nodeIdx, prefix, skipEncodeChars) {
var node = this.decodeTables[nodeIdx]
var hasValues = false
var subNodeEmpty = {}
for (var i = 0; i < 0x100; i++) {
var uCode = node[i]
var mbCode = prefix + i
if (skipEncodeChars[mbCode]) { continue }
if (uCode >= 0) {
this._setEncodeChar(uCode, mbCode)
hasValues = true
} else if (uCode <= NODE_START) {
var subNodeIdx = NODE_START - uCode
if (!subNodeEmpty[subNodeIdx]) { // Skip empty subtrees (they are too large in gb18030).
var newPrefix = (mbCode << 8) >>> 0 // NOTE: '>>> 0' keeps 32-bit num positive.
if (this._fillEncodeTable(subNodeIdx, newPrefix, skipEncodeChars)) { hasValues = true } else { subNodeEmpty[subNodeIdx] = true }
}
} else if (uCode <= SEQ_START) {
this._setEncodeSequence(this.decodeTableSeq[SEQ_START - uCode], mbCode)
hasValues = true
}
}
return hasValues
}
// == Encoder ==================================================================
function DBCSEncoder (options, codec) {
// Encoder state
this.leadSurrogate = -1
this.seqObj = undefined
// Static data
this.encodeTable = codec.encodeTable
this.encodeTableSeq = codec.encodeTableSeq
this.defaultCharSingleByte = codec.defCharSB
this.gb18030 = codec.gb18030
}
DBCSEncoder.prototype.write = function (str) {
var newBuf = Buffer.alloc(str.length * (this.gb18030 ? 4 : 3))
var leadSurrogate = this.leadSurrogate
var seqObj = this.seqObj
var nextChar = -1
var i = 0; var j = 0
while (true) {
// 0. Get next character.
if (nextChar === -1) {
if (i == str.length) break
var uCode = str.charCodeAt(i++)
} else {
var uCode = nextChar
nextChar = -1
}
// 1. Handle surrogates.
if (uCode >= 0xD800 && uCode < 0xE000) { // Char is one of surrogates.
if (uCode < 0xDC00) { // We've got lead surrogate.
if (leadSurrogate === -1) {
leadSurrogate = uCode
continue
} else {
leadSurrogate = uCode
// Double lead surrogate found.
uCode = UNASSIGNED
}
} else { // We've got trail surrogate.
if (leadSurrogate !== -1) {
uCode = 0x10000 + (leadSurrogate - 0xD800) * 0x400 + (uCode - 0xDC00)
leadSurrogate = -1
} else {
// Incomplete surrogate pair - only trail surrogate found.
uCode = UNASSIGNED
}
}
} else if (leadSurrogate !== -1) {
// Incomplete surrogate pair - only lead surrogate found.
nextChar = uCode; uCode = UNASSIGNED // Write an error, then current char.
leadSurrogate = -1
}
// 2. Convert uCode character.
var dbcsCode = UNASSIGNED
if (seqObj !== undefined && uCode != UNASSIGNED) { // We are in the middle of the sequence
var resCode = seqObj[uCode]
if (typeof resCode === "object") { // Sequence continues.
seqObj = resCode
continue
} else if (typeof resCode === "number") { // Sequence finished. Write it.
dbcsCode = resCode
} else if (resCode == undefined) { // Current character is not part of the sequence.
// Try default character for this sequence
resCode = seqObj[DEF_CHAR]
if (resCode !== undefined) {
dbcsCode = resCode // Found. Write it.
nextChar = uCode // Current character will be written too in the next iteration.
} else {
// TODO: What if we have no default? (resCode == undefined)
// Then, we should write first char of the sequence as-is and try the rest recursively.
// Didn't do it for now because no encoding has this situation yet.
// Currently, just skip the sequence and write current char.
}
}
seqObj = undefined
} else if (uCode >= 0) { // Regular character
var subtable = this.encodeTable[uCode >> 8]
if (subtable !== undefined) { dbcsCode = subtable[uCode & 0xFF] }
if (dbcsCode <= SEQ_START) { // Sequence start
seqObj = this.encodeTableSeq[SEQ_START - dbcsCode]
continue
}
if (dbcsCode == UNASSIGNED && this.gb18030) {
// Use GB18030 algorithm to find character(s) to write.
var idx = findIdx(this.gb18030.uChars, uCode)
if (idx != -1) {
var dbcsCode = this.gb18030.gbChars[idx] + (uCode - this.gb18030.uChars[idx])
newBuf[j++] = 0x81 + Math.floor(dbcsCode / 12600); dbcsCode = dbcsCode % 12600
newBuf[j++] = 0x30 + Math.floor(dbcsCode / 1260); dbcsCode = dbcsCode % 1260
newBuf[j++] = 0x81 + Math.floor(dbcsCode / 10); dbcsCode = dbcsCode % 10
newBuf[j++] = 0x30 + dbcsCode
continue
}
}
}
// 3. Write dbcsCode character.
if (dbcsCode === UNASSIGNED) { dbcsCode = this.defaultCharSingleByte }
if (dbcsCode < 0x100) {
newBuf[j++] = dbcsCode
} else if (dbcsCode < 0x10000) {
newBuf[j++] = dbcsCode >> 8 // high byte
newBuf[j++] = dbcsCode & 0xFF // low byte
} else if (dbcsCode < 0x1000000) {
newBuf[j++] = dbcsCode >> 16
newBuf[j++] = (dbcsCode >> 8) & 0xFF
newBuf[j++] = dbcsCode & 0xFF
} else {
newBuf[j++] = dbcsCode >>> 24
newBuf[j++] = (dbcsCode >>> 16) & 0xFF
newBuf[j++] = (dbcsCode >>> 8) & 0xFF
newBuf[j++] = dbcsCode & 0xFF
}
}
this.seqObj = seqObj
this.leadSurrogate = leadSurrogate
return newBuf.slice(0, j)
}
DBCSEncoder.prototype.end = function () {
if (this.leadSurrogate === -1 && this.seqObj === undefined) { return } // All clean. Most often case.
var newBuf = Buffer.alloc(10); var j = 0
if (this.seqObj) { // We're in the sequence.
var dbcsCode = this.seqObj[DEF_CHAR]
if (dbcsCode !== undefined) { // Write beginning of the sequence.
if (dbcsCode < 0x100) {
newBuf[j++] = dbcsCode
} else {
newBuf[j++] = dbcsCode >> 8 // high byte
newBuf[j++] = dbcsCode & 0xFF // low byte
}
} else {
// See todo above.
}
this.seqObj = undefined
}
if (this.leadSurrogate !== -1) {
// Incomplete surrogate pair - only lead surrogate found.
newBuf[j++] = this.defaultCharSingleByte
this.leadSurrogate = -1
}
return newBuf.slice(0, j)
}
// Export for testing
DBCSEncoder.prototype.findIdx = findIdx
// == Decoder ==================================================================
function DBCSDecoder (options, codec) {
// Decoder state
this.nodeIdx = 0
this.prevBytes = []
// Static data
this.decodeTables = codec.decodeTables
this.decodeTableSeq = codec.decodeTableSeq
this.defaultCharUnicode = codec.defaultCharUnicode
this.gb18030 = codec.gb18030
}
DBCSDecoder.prototype.write = function (buf) {
var newBuf = Buffer.alloc(buf.length * 2)
var nodeIdx = this.nodeIdx
var prevBytes = this.prevBytes; var prevOffset = this.prevBytes.length
var seqStart = -this.prevBytes.length // idx of the start of current parsed sequence.
var uCode
for (var i = 0, j = 0; i < buf.length; i++) {
var curByte = (i >= 0) ? buf[i] : prevBytes[i + prevOffset]
// Lookup in current trie node.
var uCode = this.decodeTables[nodeIdx][curByte]
if (uCode >= 0) {
// Normal character, just use it.
} else if (uCode === UNASSIGNED) { // Unknown char.
// TODO: Callback with seq.
uCode = this.defaultCharUnicode.charCodeAt(0)
i = seqStart // Skip one byte ('i' will be incremented by the for loop) and try to parse again.
} else if (uCode === GB18030_CODE) {
if (i >= 3) {
var ptr = (buf[i - 3] - 0x81) * 12600 + (buf[i - 2] - 0x30) * 1260 + (buf[i - 1] - 0x81) * 10 + (curByte - 0x30)
} else {
var ptr = (prevBytes[i - 3 + prevOffset] - 0x81) * 12600 +
(((i - 2 >= 0) ? buf[i - 2] : prevBytes[i - 2 + prevOffset]) - 0x30) * 1260 +
(((i - 1 >= 0) ? buf[i - 1] : prevBytes[i - 1 + prevOffset]) - 0x81) * 10 +
(curByte - 0x30)
}
var idx = findIdx(this.gb18030.gbChars, ptr)
uCode = this.gb18030.uChars[idx] + ptr - this.gb18030.gbChars[idx]
} else if (uCode <= NODE_START) { // Go to next trie node.
nodeIdx = NODE_START - uCode
continue
} else if (uCode <= SEQ_START) { // Output a sequence of chars.
var seq = this.decodeTableSeq[SEQ_START - uCode]
for (var k = 0; k < seq.length - 1; k++) {
uCode = seq[k]
newBuf[j++] = uCode & 0xFF
newBuf[j++] = uCode >> 8
}
uCode = seq[seq.length - 1]
} else { throw new Error("iconv-lite internal error: invalid decoding table value " + uCode + " at " + nodeIdx + "/" + curByte) }
// Write the character to buffer, handling higher planes using surrogate pair.
if (uCode >= 0x10000) {
uCode -= 0x10000
var uCodeLead = 0xD800 | (uCode >> 10)
newBuf[j++] = uCodeLead & 0xFF
newBuf[j++] = uCodeLead >> 8
uCode = 0xDC00 | (uCode & 0x3FF)
}
newBuf[j++] = uCode & 0xFF
newBuf[j++] = uCode >> 8
// Reset trie node.
nodeIdx = 0; seqStart = i + 1
}
this.nodeIdx = nodeIdx
this.prevBytes = (seqStart >= 0)
? Array.prototype.slice.call(buf, seqStart)
: prevBytes.slice(seqStart + prevOffset).concat(Array.prototype.slice.call(buf))
return newBuf.slice(0, j).toString("ucs2")
}
DBCSDecoder.prototype.end = function () {
var ret = ""
// Try to parse all remaining chars.
while (this.prevBytes.length > 0) {
// Skip 1 character in the buffer.
ret += this.defaultCharUnicode
var bytesArr = this.prevBytes.slice(1)
// Parse remaining as usual.
this.prevBytes = []
this.nodeIdx = 0
if (bytesArr.length > 0) { ret += this.write(bytesArr) }
}
this.prevBytes = []
this.nodeIdx = 0
return ret
}
// Binary search for GB18030. Returns largest i such that table[i] <= val.
function findIdx (table, val) {
if (table[0] > val) { return -1 }
var l = 0; var r = table.length
while (l < r - 1) { // always table[l] <= val < table[r]
var mid = l + ((r - l + 1) >> 1)
if (table[mid] <= val) { l = mid } else { r = mid }
}
return l
}

View File

@@ -0,0 +1,185 @@
"use strict"
// Description of supported double byte encodings and aliases.
// Tables are not require()-d until they are needed to speed up library load.
// require()-s are direct to support Browserify.
module.exports = {
// == Japanese/ShiftJIS ====================================================
// All japanese encodings are based on JIS X set of standards:
// JIS X 0201 - Single-byte encoding of ASCII + ¥ + Kana chars at 0xA1-0xDF.
// JIS X 0208 - Main set of 6879 characters, placed in 94x94 plane, to be encoded by 2 bytes.
// Has several variations in 1978, 1983, 1990 and 1997.
// JIS X 0212 - Supplementary plane of 6067 chars in 94x94 plane. 1990. Effectively dead.
// JIS X 0213 - Extension and modern replacement of 0208 and 0212. Total chars: 11233.
// 2 planes, first is superset of 0208, second - revised 0212.
// Introduced in 2000, revised 2004. Some characters are in Unicode Plane 2 (0x2xxxx)
// Byte encodings are:
// * Shift_JIS: Compatible with 0201, uses not defined chars in top half as lead bytes for double-byte
// encoding of 0208. Lead byte ranges: 0x81-0x9F, 0xE0-0xEF; Trail byte ranges: 0x40-0x7E, 0x80-0x9E, 0x9F-0xFC.
// Windows CP932 is a superset of Shift_JIS. Some companies added more chars, notably KDDI.
// * EUC-JP: Up to 3 bytes per character. Used mostly on *nixes.
// 0x00-0x7F - lower part of 0201
// 0x8E, 0xA1-0xDF - upper part of 0201
// (0xA1-0xFE)x2 - 0208 plane (94x94).
// 0x8F, (0xA1-0xFE)x2 - 0212 plane (94x94).
// * JIS X 208: 7-bit, direct encoding of 0208. Byte ranges: 0x21-0x7E (94 values). Uncommon.
// Used as-is in ISO2022 family.
// * ISO2022-JP: Stateful encoding, with escape sequences to switch between ASCII,
// 0201-1976 Roman, 0208-1978, 0208-1983.
// * ISO2022-JP-1: Adds esc seq for 0212-1990.
// * ISO2022-JP-2: Adds esc seq for GB2313-1980, KSX1001-1992, ISO8859-1, ISO8859-7.
// * ISO2022-JP-3: Adds esc seq for 0201-1976 Kana set, 0213-2000 Planes 1, 2.
// * ISO2022-JP-2004: Adds 0213-2004 Plane 1.
//
// After JIS X 0213 appeared, Shift_JIS-2004, EUC-JISX0213 and ISO2022-JP-2004 followed, with just changing the planes.
//
// Overall, it seems that it's a mess :( http://www8.plala.or.jp/tkubota1/unicode-symbols-map2.html
shiftjis: {
type: "_dbcs",
table: function () { return require("./tables/shiftjis.json") },
encodeAdd: { "\u00a5": 0x5C, "\u203E": 0x7E },
encodeSkipVals: [{ from: 0xED40, to: 0xF940 }]
},
csshiftjis: "shiftjis",
mskanji: "shiftjis",
sjis: "shiftjis",
windows31j: "shiftjis",
ms31j: "shiftjis",
xsjis: "shiftjis",
windows932: "shiftjis",
ms932: "shiftjis",
932: "shiftjis",
cp932: "shiftjis",
eucjp: {
type: "_dbcs",
table: function () { return require("./tables/eucjp.json") },
encodeAdd: { "\u00a5": 0x5C, "\u203E": 0x7E }
},
// TODO: KDDI extension to Shift_JIS
// TODO: IBM CCSID 942 = CP932, but F0-F9 custom chars and other char changes.
// TODO: IBM CCSID 943 = Shift_JIS = CP932 with original Shift_JIS lower 128 chars.
// == Chinese/GBK ==========================================================
// http://en.wikipedia.org/wiki/GBK
// We mostly implement W3C recommendation: https://www.w3.org/TR/encoding/#gbk-encoder
// Oldest GB2312 (1981, ~7600 chars) is a subset of CP936
gb2312: "cp936",
gb231280: "cp936",
gb23121980: "cp936",
csgb2312: "cp936",
csiso58gb231280: "cp936",
euccn: "cp936",
// Microsoft's CP936 is a subset and approximation of GBK.
windows936: "cp936",
ms936: "cp936",
936: "cp936",
cp936: {
type: "_dbcs",
table: function () { return require("./tables/cp936.json") }
},
// GBK (~22000 chars) is an extension of CP936 that added user-mapped chars and some other.
gbk: {
type: "_dbcs",
table: function () { return require("./tables/cp936.json").concat(require("./tables/gbk-added.json")) }
},
xgbk: "gbk",
isoir58: "gbk",
// GB18030 is an algorithmic extension of GBK.
// Main source: https://www.w3.org/TR/encoding/#gbk-encoder
// http://icu-project.org/docs/papers/gb18030.html
// http://source.icu-project.org/repos/icu/data/trunk/charset/data/xml/gb-18030-2000.xml
// http://www.khngai.com/chinese/charmap/tblgbk.php?page=0
gb18030: {
type: "_dbcs",
table: function () { return require("./tables/cp936.json").concat(require("./tables/gbk-added.json")) },
gb18030: function () { return require("./tables/gb18030-ranges.json") },
encodeSkipVals: [0x80],
encodeAdd: { "€": 0xA2E3 }
},
chinese: "gb18030",
// == Korean ===============================================================
// EUC-KR, KS_C_5601 and KS X 1001 are exactly the same.
windows949: "cp949",
ms949: "cp949",
949: "cp949",
cp949: {
type: "_dbcs",
table: function () { return require("./tables/cp949.json") }
},
cseuckr: "cp949",
csksc56011987: "cp949",
euckr: "cp949",
isoir149: "cp949",
korean: "cp949",
ksc56011987: "cp949",
ksc56011989: "cp949",
ksc5601: "cp949",
// == Big5/Taiwan/Hong Kong ================================================
// There are lots of tables for Big5 and cp950. Please see the following links for history:
// http://moztw.org/docs/big5/ http://www.haible.de/bruno/charsets/conversion-tables/Big5.html
// Variations, in roughly number of defined chars:
// * Windows CP 950: Microsoft variant of Big5. Canonical: http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP950.TXT
// * Windows CP 951: Microsoft variant of Big5-HKSCS-2001. Seems to be never public. http://me.abelcheung.org/articles/research/what-is-cp951/
// * Big5-2003 (Taiwan standard) almost superset of cp950.
// * Unicode-at-on (UAO) / Mozilla 1.8. Falling out of use on the Web. Not supported by other browsers.
// * Big5-HKSCS (-2001, -2004, -2008). Hong Kong standard.
// many unicode code points moved from PUA to Supplementary plane (U+2XXXX) over the years.
// Plus, it has 4 combining sequences.
// Seems that Mozilla refused to support it for 10 yrs. https://bugzilla.mozilla.org/show_bug.cgi?id=162431 https://bugzilla.mozilla.org/show_bug.cgi?id=310299
// because big5-hkscs is the only encoding to include astral characters in non-algorithmic way.
// Implementations are not consistent within browsers; sometimes labeled as just big5.
// MS Internet Explorer switches from big5 to big5-hkscs when a patch applied.
// Great discussion & recap of what's going on https://bugzilla.mozilla.org/show_bug.cgi?id=912470#c31
// In the encoder, it might make sense to support encoding old PUA mappings to Big5 bytes seq-s.
// Official spec: http://www.ogcio.gov.hk/en/business/tech_promotion/ccli/terms/doc/2003cmp_2008.txt
// http://www.ogcio.gov.hk/tc/business/tech_promotion/ccli/terms/doc/hkscs-2008-big5-iso.txt
//
// Current understanding of how to deal with Big5(-HKSCS) is in the Encoding Standard, http://encoding.spec.whatwg.org/#big5-encoder
// Unicode mapping (http://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/OTHER/BIG5.TXT) is said to be wrong.
windows950: "cp950",
ms950: "cp950",
950: "cp950",
cp950: {
type: "_dbcs",
table: function () { return require("./tables/cp950.json") }
},
// Big5 has many variations and is an extension of cp950. We use Encoding Standard's as a consensus.
big5: "big5hkscs",
big5hkscs: {
type: "_dbcs",
table: function () { return require("./tables/cp950.json").concat(require("./tables/big5-added.json")) },
encodeSkipVals: [
// Although Encoding Standard says we should avoid encoding to HKSCS area (See Step 1 of
// https://encoding.spec.whatwg.org/#index-big5-pointer), we still do it to increase compatibility with ICU.
// But if a single unicode point can be encoded both as HKSCS and regular Big5, we prefer the latter.
0x8e69, 0x8e6f, 0x8e7e, 0x8eab, 0x8eb4, 0x8ecd, 0x8ed0, 0x8f57, 0x8f69, 0x8f6e, 0x8fcb, 0x8ffe,
0x906d, 0x907a, 0x90c4, 0x90dc, 0x90f1, 0x91bf, 0x92af, 0x92b0, 0x92b1, 0x92b2, 0x92d1, 0x9447, 0x94ca,
0x95d9, 0x96fc, 0x9975, 0x9b76, 0x9b78, 0x9b7b, 0x9bc6, 0x9bde, 0x9bec, 0x9bf6, 0x9c42, 0x9c53, 0x9c62,
0x9c68, 0x9c6b, 0x9c77, 0x9cbc, 0x9cbd, 0x9cd0, 0x9d57, 0x9d5a, 0x9dc4, 0x9def, 0x9dfb, 0x9ea9, 0x9eef,
0x9efd, 0x9f60, 0x9fcb, 0xa077, 0xa0dc, 0xa0df, 0x8fcc, 0x92c8, 0x9644, 0x96ed,
// Step 2 of https://encoding.spec.whatwg.org/#index-big5-pointer: Use last pointer for U+2550, U+255E, U+2561, U+256A, U+5341, or U+5345
0xa2a4, 0xa2a5, 0xa2a7, 0xa2a6, 0xa2cc, 0xa2ce
]
},
cnbig5: "big5hkscs",
csbig5: "big5hkscs",
xxbig5: "big5hkscs"
}

View File

@@ -0,0 +1,23 @@
"use strict"
var mergeModules = require("../lib/helpers/merge-exports")
// Update this array if you add/rename/remove files in this directory.
// We support Browserify by skipping automatic module discovery and requiring modules directly.
var modules = [
require("./internal"),
require("./utf32"),
require("./utf16"),
require("./utf7"),
require("./sbcs-codec"),
require("./sbcs-data"),
require("./sbcs-data-generated"),
require("./dbcs-codec"),
require("./dbcs-data")
]
// Put all encoding/alias/codec definitions to single object and export it.
for (var i = 0; i < modules.length; i++) {
var module = modules[i]
mergeModules(exports, module)
}

View File

@@ -0,0 +1,218 @@
"use strict"
var Buffer = require("safer-buffer").Buffer
// Export Node.js internal encodings.
module.exports = {
// Encodings
utf8: { type: "_internal", bomAware: true },
cesu8: { type: "_internal", bomAware: true },
unicode11utf8: "utf8",
ucs2: { type: "_internal", bomAware: true },
utf16le: "ucs2",
binary: { type: "_internal" },
base64: { type: "_internal" },
hex: { type: "_internal" },
// Codec.
_internal: InternalCodec
}
// ------------------------------------------------------------------------------
function InternalCodec (codecOptions, iconv) {
this.enc = codecOptions.encodingName
this.bomAware = codecOptions.bomAware
if (this.enc === "base64") { this.encoder = InternalEncoderBase64 } else if (this.enc === "utf8") { this.encoder = InternalEncoderUtf8 } else if (this.enc === "cesu8") {
this.enc = "utf8" // Use utf8 for decoding.
this.encoder = InternalEncoderCesu8
// Add decoder for versions of Node not supporting CESU-8
if (Buffer.from("eda0bdedb2a9", "hex").toString() !== "💩") {
this.decoder = InternalDecoderCesu8
this.defaultCharUnicode = iconv.defaultCharUnicode
}
}
}
InternalCodec.prototype.encoder = InternalEncoder
InternalCodec.prototype.decoder = InternalDecoder
// ------------------------------------------------------------------------------
// We use node.js internal decoder. Its signature is the same as ours.
var StringDecoder = require("string_decoder").StringDecoder
function InternalDecoder (options, codec) {
this.decoder = new StringDecoder(codec.enc)
}
InternalDecoder.prototype.write = function (buf) {
if (!Buffer.isBuffer(buf)) {
buf = Buffer.from(buf)
}
return this.decoder.write(buf)
}
InternalDecoder.prototype.end = function () {
return this.decoder.end()
}
// ------------------------------------------------------------------------------
// Encoder is mostly trivial
function InternalEncoder (options, codec) {
this.enc = codec.enc
}
InternalEncoder.prototype.write = function (str) {
return Buffer.from(str, this.enc)
}
InternalEncoder.prototype.end = function () {
}
// ------------------------------------------------------------------------------
// Except base64 encoder, which must keep its state.
function InternalEncoderBase64 (options, codec) {
this.prevStr = ""
}
InternalEncoderBase64.prototype.write = function (str) {
str = this.prevStr + str
var completeQuads = str.length - (str.length % 4)
this.prevStr = str.slice(completeQuads)
str = str.slice(0, completeQuads)
return Buffer.from(str, "base64")
}
InternalEncoderBase64.prototype.end = function () {
return Buffer.from(this.prevStr, "base64")
}
// ------------------------------------------------------------------------------
// CESU-8 encoder is also special.
function InternalEncoderCesu8 (options, codec) {
}
InternalEncoderCesu8.prototype.write = function (str) {
var buf = Buffer.alloc(str.length * 3); var bufIdx = 0
for (var i = 0; i < str.length; i++) {
var charCode = str.charCodeAt(i)
// Naive implementation, but it works because CESU-8 is especially easy
// to convert from UTF-16 (which all JS strings are encoded in).
if (charCode < 0x80) { buf[bufIdx++] = charCode } else if (charCode < 0x800) {
buf[bufIdx++] = 0xC0 + (charCode >>> 6)
buf[bufIdx++] = 0x80 + (charCode & 0x3f)
} else { // charCode will always be < 0x10000 in javascript.
buf[bufIdx++] = 0xE0 + (charCode >>> 12)
buf[bufIdx++] = 0x80 + ((charCode >>> 6) & 0x3f)
buf[bufIdx++] = 0x80 + (charCode & 0x3f)
}
}
return buf.slice(0, bufIdx)
}
InternalEncoderCesu8.prototype.end = function () {
}
// ------------------------------------------------------------------------------
// CESU-8 decoder is not implemented in Node v4.0+
function InternalDecoderCesu8 (options, codec) {
this.acc = 0
this.contBytes = 0
this.accBytes = 0
this.defaultCharUnicode = codec.defaultCharUnicode
}
InternalDecoderCesu8.prototype.write = function (buf) {
var acc = this.acc; var contBytes = this.contBytes; var accBytes = this.accBytes
var res = ""
for (var i = 0; i < buf.length; i++) {
var curByte = buf[i]
if ((curByte & 0xC0) !== 0x80) { // Leading byte
if (contBytes > 0) { // Previous code is invalid
res += this.defaultCharUnicode
contBytes = 0
}
if (curByte < 0x80) { // Single-byte code
res += String.fromCharCode(curByte)
} else if (curByte < 0xE0) { // Two-byte code
acc = curByte & 0x1F
contBytes = 1; accBytes = 1
} else if (curByte < 0xF0) { // Three-byte code
acc = curByte & 0x0F
contBytes = 2; accBytes = 1
} else { // Four or more are not supported for CESU-8.
res += this.defaultCharUnicode
}
} else { // Continuation byte
if (contBytes > 0) { // We're waiting for it.
acc = (acc << 6) | (curByte & 0x3f)
contBytes--; accBytes++
if (contBytes === 0) {
// Check for overlong encoding, but support Modified UTF-8 (encoding NULL as C0 80)
if (accBytes === 2 && acc < 0x80 && acc > 0) {
res += this.defaultCharUnicode
} else if (accBytes === 3 && acc < 0x800) {
res += this.defaultCharUnicode
} else {
// Actually add character.
res += String.fromCharCode(acc)
}
}
} else { // Unexpected continuation byte
res += this.defaultCharUnicode
}
}
}
this.acc = acc; this.contBytes = contBytes; this.accBytes = accBytes
return res
}
InternalDecoderCesu8.prototype.end = function () {
var res = 0
if (this.contBytes > 0) { res += this.defaultCharUnicode }
return res
}
// ------------------------------------------------------------------------------
// check the chunk boundaries for surrogate pair
function InternalEncoderUtf8 (options, codec) {
this.highSurrogate = ""
}
InternalEncoderUtf8.prototype.write = function (str) {
if (this.highSurrogate) {
str = this.highSurrogate + str
this.highSurrogate = ""
}
if (str.length > 0) {
var charCode = str.charCodeAt(str.length - 1)
if (charCode >= 0xd800 && charCode < 0xdc00) {
this.highSurrogate = str[str.length - 1]
str = str.slice(0, str.length - 1)
}
}
return Buffer.from(str, this.enc)
}
InternalEncoderUtf8.prototype.end = function () {
if (this.highSurrogate) {
var str = this.highSurrogate
this.highSurrogate = ""
return Buffer.from(str, this.enc)
}
}

View File

@@ -0,0 +1,75 @@
"use strict"
var Buffer = require("safer-buffer").Buffer
// Single-byte codec. Needs a 'chars' string parameter that contains 256 or 128 chars that
// correspond to encoded bytes (if 128 - then lower half is ASCII).
exports._sbcs = SBCSCodec
function SBCSCodec (codecOptions, iconv) {
if (!codecOptions) {
throw new Error("SBCS codec is called without the data.")
}
// Prepare char buffer for decoding.
if (!codecOptions.chars || (codecOptions.chars.length !== 128 && codecOptions.chars.length !== 256)) {
throw new Error("Encoding '" + codecOptions.type + "' has incorrect 'chars' (must be of len 128 or 256)")
}
if (codecOptions.chars.length === 128) {
var asciiString = ""
for (var i = 0; i < 128; i++) {
asciiString += String.fromCharCode(i)
}
codecOptions.chars = asciiString + codecOptions.chars
}
this.decodeBuf = Buffer.from(codecOptions.chars, "ucs2")
// Encoding buffer.
var encodeBuf = Buffer.alloc(65536, iconv.defaultCharSingleByte.charCodeAt(0))
for (var i = 0; i < codecOptions.chars.length; i++) {
encodeBuf[codecOptions.chars.charCodeAt(i)] = i
}
this.encodeBuf = encodeBuf
}
SBCSCodec.prototype.encoder = SBCSEncoder
SBCSCodec.prototype.decoder = SBCSDecoder
function SBCSEncoder (options, codec) {
this.encodeBuf = codec.encodeBuf
}
SBCSEncoder.prototype.write = function (str) {
var buf = Buffer.alloc(str.length)
for (var i = 0; i < str.length; i++) {
buf[i] = this.encodeBuf[str.charCodeAt(i)]
}
return buf
}
SBCSEncoder.prototype.end = function () {
}
function SBCSDecoder (options, codec) {
this.decodeBuf = codec.decodeBuf
}
SBCSDecoder.prototype.write = function (buf) {
// Strings are immutable in JS -> we use ucs2 buffer to speed up computations.
var decodeBuf = this.decodeBuf
var newBuf = Buffer.alloc(buf.length * 2)
var idx1 = 0; var idx2 = 0
for (var i = 0; i < buf.length; i++) {
idx1 = buf[i] * 2; idx2 = i * 2
newBuf[idx2] = decodeBuf[idx1]
newBuf[idx2 + 1] = decodeBuf[idx1 + 1]
}
return newBuf.toString("ucs2")
}
SBCSDecoder.prototype.end = function () {
}

View File

@@ -0,0 +1,451 @@
"use strict";
// Generated data for sbcs codec. Don't edit manually. Regenerate using generation/gen-sbcs.js script.
module.exports = {
"437": "cp437",
"737": "cp737",
"775": "cp775",
"850": "cp850",
"852": "cp852",
"855": "cp855",
"856": "cp856",
"857": "cp857",
"858": "cp858",
"860": "cp860",
"861": "cp861",
"862": "cp862",
"863": "cp863",
"864": "cp864",
"865": "cp865",
"866": "cp866",
"869": "cp869",
"874": "windows874",
"922": "cp922",
"1046": "cp1046",
"1124": "cp1124",
"1125": "cp1125",
"1129": "cp1129",
"1133": "cp1133",
"1161": "cp1161",
"1162": "cp1162",
"1163": "cp1163",
"1250": "windows1250",
"1251": "windows1251",
"1252": "windows1252",
"1253": "windows1253",
"1254": "windows1254",
"1255": "windows1255",
"1256": "windows1256",
"1257": "windows1257",
"1258": "windows1258",
"28591": "iso88591",
"28592": "iso88592",
"28593": "iso88593",
"28594": "iso88594",
"28595": "iso88595",
"28596": "iso88596",
"28597": "iso88597",
"28598": "iso88598",
"28599": "iso88599",
"28600": "iso885910",
"28601": "iso885911",
"28603": "iso885913",
"28604": "iso885914",
"28605": "iso885915",
"28606": "iso885916",
"windows874": {
"type": "_sbcs",
"chars": "€<><E282AC><EFBFBD><EFBFBD><EFBFBD><E280A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>“”•<E28093><E28094><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู<E0B8B9><E0B8BA><EFBFBD><EFBFBD>฿เแโใไๅๆ็่้๊๋์ํ๎๏๑๒๓๔๕๖๗๘๙๚๛<E0B99A><E0B99B><EFBFBD><EFBFBD>"
},
"win874": "windows874",
"cp874": "windows874",
"windows1250": {
"type": "_sbcs",
"chars": "€<><EFBFBD>„…†‡<E280A0>‰ŠŚŤŽŹ<C5BD>“”•<E28093>™šśťžź ˇ˘Ł¤Ą¦§¨©Ş«¬­®Ż°±˛ł´µ¶·¸ąş»Ľ˝ľżŔÁÂĂÄĹĆÇČÉĘËĚÍÎĎĐŃŇÓÔŐÖ×ŘŮÚŰÜÝŢßŕáâăäĺćçčéęëěíîďđńňóôőö÷řůúűüýţ˙"
},
"win1250": "windows1250",
"cp1250": "windows1250",
"windows1251": {
"type": "_sbcs",
"chars": "ЂЃѓ„…†‡€‰ЉЊЌЋЏђ“”•<E28093>™љњќћџ ЎўЈ¤Ґ¦§Ё©Є«¬­®Ї°±Ііґµ¶·ё№є»јЅѕїАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя"
},
"win1251": "windows1251",
"cp1251": "windows1251",
"windows1252": {
"type": "_sbcs",
"chars": "€<>ƒ„…†‡ˆ‰ŠŒ<E280B9>Ž<EFBFBD><C5BD>“”•˜™šœ<E280BA>žŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ"
},
"win1252": "windows1252",
"cp1252": "windows1252",
"windows1253": {
"type": "_sbcs",
"chars": "€<>ƒ„…†‡<E280A0><EFBFBD><EFBFBD><E280B9><EFBFBD><EFBFBD><EFBFBD>“”•<E28093><EFBFBD><EFBFBD><E280BA><EFBFBD><EFBFBD> ΅Ά£¤¥¦§¨©<C2A8>«¬­®―°±²³΄µ¶·ΈΉΊ»Ό½ΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ<CEA0>ΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώ<CF8D>"
},
"win1253": "windows1253",
"cp1253": "windows1253",
"windows1254": {
"type": "_sbcs",
"chars": "€<>ƒ„…†‡ˆ‰ŠŒ<E280B9><C592><EFBFBD><EFBFBD>“”•˜™šœ<E280BA><C593>Ÿ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏĞÑÒÓÔÕÖרÙÚÛÜİŞßàáâãäåæçèéêëìíîïğñòóôõö÷øùúûüışÿ"
},
"win1254": "windows1254",
"cp1254": "windows1254",
"windows1255": {
"type": "_sbcs",
"chars": "€<>ƒ„…†‡ˆ<CB86><EFBFBD><E280B9><EFBFBD><EFBFBD><EFBFBD>“”•˜<CB9C><EFBFBD><E280BA><EFBFBD><EFBFBD> ¡¢£₪¥¦§¨©×«¬­®¯°±²³´µ¶·¸¹÷»¼½¾¿ְֱֲֳִֵֶַָֹֺֻּֽ־ֿ׀ׁׂ׃װױײ׳״<D7B3><D7B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>אבגדהוזחטיךכלםמןנסעףפץצקרשת<D7A9><D7AA><E2808E>"
},
"win1255": "windows1255",
"cp1255": "windows1255",
"windows1256": {
"type": "_sbcs",
"chars": "€پ‚ƒ„…†‡ˆ‰ٹ‹Œچژڈگ‘’“”•–—ک™ڑ›œ‌‍ں ،¢£¤¥¦§¨©ھ«¬­®¯°±²³´µ¶·¸¹؛»¼½¾؟ہءآأؤإئابةتثجحخدذرزسشصض×طظعغـفقكàلâمنهوçèéêëىيîïًٌٍَôُِ÷ّùْûü‎‏ے"
},
"win1256": "windows1256",
"cp1256": "windows1256",
"windows1257": {
"type": "_sbcs",
"chars": "€<><EFBFBD>„…†‡<E280A0><EFBFBD><EFBFBD>¨ˇ¸<CB87>“”•<E28093><EFBFBD><EFBFBD>¯˛<C2AF> <EFBFBD>¢£¤<C2A3>¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙"
},
"win1257": "windows1257",
"cp1257": "windows1257",
"windows1258": {
"type": "_sbcs",
"chars": "€<>ƒ„…†‡ˆ<CB86>Œ<E280B9><C592><EFBFBD><EFBFBD>“”•˜<CB9C>œ<E280BA><C593>Ÿ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂĂÄÅÆÇÈÉÊË̀ÍÎÏĐÑ̉ÓÔƠÖרÙÚÛÜỮßàáâăäåæçèéêë́íîïđṇ̃óôơö÷øùúûüư₫ÿ"
},
"win1258": "windows1258",
"cp1258": "windows1258",
"iso88591": {
"type": "_sbcs",
"chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ"
},
"cp28591": "iso88591",
"iso88592": {
"type": "_sbcs",
"chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ Ą˘Ł¤ĽŚ§¨ŠŞŤŹ­ŽŻ°ą˛ł´ľśˇ¸šşťź˝žżŔÁÂĂÄĹĆÇČÉĘËĚÍÎĎĐŃŇÓÔŐÖ×ŘŮÚŰÜÝŢßŕáâăäĺćçčéęëěíîďđńňóôőö÷řůúűüýţ˙"
},
"cp28592": "iso88592",
"iso88593": {
"type": "_sbcs",
"chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ Ħ˘£¤<C2A3>Ĥ§¨İŞĞĴ­<C4B4>ݰħ²³´µĥ·¸ışğĵ½<C4B5>żÀÁÂ<C381>ÄĊĈÇÈÉÊËÌÍÎÏ<C38E>ÑÒÓÔĠÖ×ĜÙÚÛÜŬŜßàáâ<C3A1>äċĉçèéêëìíîï<C3AE>ñòóôġö÷ĝùúûüŭŝ˙"
},
"cp28593": "iso88593",
"iso88594": {
"type": "_sbcs",
"chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ĄĸŖ¤Ĩϧ¨ŠĒĢŦ­Ž¯°ą˛ŗ´ĩšēģŧŊžŋĀÁÂÃÄÅÆĮČÉĘËĖÍÎĪĐŅŌĶÔÕÖרŲÚÛÜŨŪßāáâãäåæįčéęëėíîīđņōķôõö÷øųúûüũū˙"
},
"cp28594": "iso88594",
"iso88595": {
"type": "_sbcs",
"chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ЁЂЃЄЅІЇЈЉЊЋЌ­ЎЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя№ёђѓєѕіїјљњћќ§ўџ"
},
"cp28595": "iso88595",
"iso88596": {
"type": "_sbcs",
"chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ <C29F><C2A0><EFBFBD>¤<EFBFBD><C2A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>،­<D88C><C2AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>؛<EFBFBD><D89B><EFBFBD>؟<EFBFBD>ءآأؤإئابةتثجحخدذرزسشصضطظعغ<D8B9><D8BA><EFBFBD><EFBFBD><EFBFBD>ـفقكلمنهوىيًٌٍَُِّْ<D991><D992><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
},
"cp28596": "iso88596",
"iso88597": {
"type": "_sbcs",
"chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ £€₯¦§¨©ͺ«¬­<C2AC>―°±²³΄΅Ά·ΈΉΊ»Ό½ΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ<CEA0>ΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώ<CF8D>"
},
"cp28597": "iso88597",
"iso88598": {
"type": "_sbcs",
"chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ <C29F>¢£¤¥¦§¨©×«¬­®¯°±²³´µ¶·¸¹÷»¼½¾<C2BD><C2BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>‗אבגדהוזחטיךכלםמןנסעףפץצקרשת<D7A9><D7AA><E2808E>"
},
"cp28598": "iso88598",
"iso88599": {
"type": "_sbcs",
"chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏĞÑÒÓÔÕÖרÙÚÛÜİŞßàáâãäåæçèéêëìíîïğñòóôõö÷øùúûüışÿ"
},
"cp28599": "iso88599",
"iso885910": {
"type": "_sbcs",
"chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ĄĒĢĪĨͧĻĐŠŦŽ­ŪŊ°ąēģīĩķ·ļđšŧž―ūŋĀÁÂÃÄÅÆĮČÉĘËĖÍÎÏÐŅŌÓÔÕÖŨØŲÚÛÜÝÞßāáâãäåæįčéęëėíîïðņōóôõöũøųúûüýþĸ"
},
"cp28600": "iso885910",
"iso885911": {
"type": "_sbcs",
"chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู<E0B8B9><E0B8BA><EFBFBD><EFBFBD>฿เแโใไๅๆ็่้๊๋์ํ๎๏๑๒๓๔๕๖๗๘๙๚๛<E0B99A><E0B99B><EFBFBD><EFBFBD>"
},
"cp28601": "iso885911",
"iso885913": {
"type": "_sbcs",
"chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ”¢£¤„¦§Ø©Ŗ«¬­®Æ°±²³“µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž’"
},
"cp28603": "iso885913",
"iso885914": {
"type": "_sbcs",
"chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ Ḃḃ£ĊċḊ§Ẁ©ẂḋỲ­®ŸḞḟĠġṀṁ¶ṖẁṗẃṠỳẄẅṡÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏŴÑÒÓÔÕÖṪØÙÚÛÜÝŶßàáâãäåæçèéêëìíîïŵñòóôõöṫøùúûüýŷÿ"
},
"cp28604": "iso885914",
"iso885915": {
"type": "_sbcs",
"chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£€¥Š§š©ª«¬­®¯°±²³Žµ¶·ž¹º»ŒœŸ¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ"
},
"cp28605": "iso885915",
"iso885916": {
"type": "_sbcs",
"chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ĄąŁ€„Чš©Ș«Ź­źŻ°±ČłŽ”¶·žčș»ŒœŸżÀÁÂĂÄĆÆÇÈÉÊËÌÍÎÏĐŃÒÓÔŐÖŚŰÙÚÛÜĘȚßàáâăäćæçèéêëìíîïđńòóôőöśűùúûüęțÿ"
},
"cp28606": "iso885916",
"cp437": {
"type": "_sbcs",
"chars": "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "
},
"ibm437": "cp437",
"csibm437": "cp437",
"cp737": {
"type": "_sbcs",
"chars": "ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρσςτυφχψ░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀ωάέήϊίόύϋώΆΈΉΊΌΎΏ±≥≤ΪΫ÷≈°∙·√ⁿ²■ "
},
"ibm737": "cp737",
"csibm737": "cp737",
"cp775": {
"type": "_sbcs",
"chars": "ĆüéāäģåćłēŖŗīŹÄÅÉæÆōöĢ¢ŚśÖÜø£Ø×¤ĀĪóŻżź”¦©®¬½¼Ł«»░▒▓│┤ĄČĘĖ╣║╗╝ĮŠ┐└┴┬├─┼ŲŪ╚╔╩╦╠═╬Žąčęėįšųūž┘┌█▄▌▐▀ÓßŌŃõÕµńĶķĻļņĒŅ’­±“¾¶§÷„°∙·¹³²■ "
},
"ibm775": "cp775",
"csibm775": "cp775",
"cp850": {
"type": "_sbcs",
"chars": "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø×ƒáíóúñѪº¿®¬½¼¡«»░▒▓│┤ÁÂÀ©╣║╗╝¢¥┐└┴┬├─┼ãÃ╚╔╩╦╠═╬¤ðÐÊËÈıÍÎÏ┘┌█▄¦Ì▀ÓßÔÒõÕµþÞÚÛÙýݯ´­±‗¾¶§÷¸°¨·¹³²■ "
},
"ibm850": "cp850",
"csibm850": "cp850",
"cp852": {
"type": "_sbcs",
"chars": "ÇüéâäůćçłëŐőîŹÄĆÉĹĺôöĽľŚśÖÜŤťŁ×čáíóúĄąŽžĘ꬟Ⱥ«»░▒▓│┤ÁÂĚŞ╣║╗╝Żż┐└┴┬├─┼Ăă╚╔╩╦╠═╬¤đĐĎËďŇÍÎě┘┌█▄ŢŮ▀ÓßÔŃńňŠšŔÚŕŰýÝţ´­˝˛ˇ˘§÷¸°¨˙űŘř■ "
},
"ibm852": "cp852",
"csibm852": "cp852",
"cp855": {
"type": "_sbcs",
"chars": "ђЂѓЃёЁєЄѕЅіІїЇјЈљЉњЊћЋќЌўЎџЏюЮъЪаАбБцЦдДеЕфФгГ«»░▒▓│┤хХиИ╣║╗╝йЙ┐└┴┬├─┼кК╚╔╩╦╠═╬¤лЛмМнНоОп┘┌█▄Пя▀ЯрРсСтТуУжЖвВьЬ№­ыЫзЗшШэЭщЩчЧ§■ "
},
"ibm855": "cp855",
"csibm855": "cp855",
"cp856": {
"type": "_sbcs",
"chars": "אבגדהוזחטיךכלםמןנסעףפץצקרשת<D7A9>£<EFBFBD>×<EFBFBD><C397><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>®¬½¼<C2BD>«»░▒▓│┤<E29482><E294A4><EFBFBD>©╣║╗╝¢¥┐└┴┬├─┼<E29480><E294BC>╚╔╩╦╠═╬¤<E295AC><C2A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>┘┌█▄¦<E29684><EFBFBD><E29680><EFBFBD><EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD><C2B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¯´­±‗¾¶§÷¸°¨·¹³²■ "
},
"ibm856": "cp856",
"csibm856": "cp856",
"cp857": {
"type": "_sbcs",
"chars": "ÇüéâäàåçêëèïîıÄÅÉæÆôöòûùİÖÜø£ØŞşáíóúñÑĞ𿮬½¼¡«»░▒▓│┤ÁÂÀ©╣║╗╝¢¥┐└┴┬├─┼ãÃ╚╔╩╦╠═╬¤ºªÊËÈ<C38B>ÍÎÏ┘┌█▄¦Ì▀ÓßÔÒõÕµ<C395>×ÚÛÙìÿ¯´­±<C2AD>¾¶§÷¸°¨·¹³²■ "
},
"ibm857": "cp857",
"csibm857": "cp857",
"cp858": {
"type": "_sbcs",
"chars": "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø×ƒáíóúñѪº¿®¬½¼¡«»░▒▓│┤ÁÂÀ©╣║╗╝¢¥┐└┴┬├─┼ãÃ╚╔╩╦╠═╬¤ðÐÊËÈ€ÍÎÏ┘┌█▄¦Ì▀ÓßÔÒõÕµþÞÚÛÙýݯ´­±‗¾¶§÷¸°¨·¹³²■ "
},
"ibm858": "cp858",
"csibm858": "cp858",
"cp860": {
"type": "_sbcs",
"chars": "ÇüéâãàÁçêÊèÍÔìÃÂÉÀÈôõòÚùÌÕÜ¢£Ù₧ÓáíóúñѪº¿Ò¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "
},
"ibm860": "cp860",
"csibm860": "cp860",
"cp861": {
"type": "_sbcs",
"chars": "ÇüéâäàåçêëèÐðÞÄÅÉæÆôöþûÝýÖÜø£Ø₧ƒáíóúÁÍÓÚ¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "
},
"ibm861": "cp861",
"csibm861": "cp861",
"cp862": {
"type": "_sbcs",
"chars": "אבגדהוזחטיךכלםמןנסעףפץצקרשת¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "
},
"ibm862": "cp862",
"csibm862": "cp862",
"cp863": {
"type": "_sbcs",
"chars": "ÇüéâÂà¶çêëèïî‗À§ÉÈÊôËÏûù¤ÔÜ¢£ÙÛƒ¦´óú¨¸³¯Î⌐¬½¼¾«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "
},
"ibm863": "cp863",
"csibm863": "cp863",
"cp864": {
"type": "_sbcs",
"chars": "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$٪&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~°·∙√▒─│┼┤┬├┴┐┌└┘β∞φ±½¼≈«»ﻷﻸ<EFBBB7><EFBBB8>ﻻﻼ<EFBBBB> ­ﺂ£¤ﺄ<C2A4><EFBA84>ﺏﺕﺙ،ﺝﺡﺥ٠١٢٣٤٥٦٧٨٩ﻑ؛ﺱﺵﺹ؟¢ﺀﺁﺃﺅﻊﺋﺑﺓﺗﺛﺟﺣﺧﺩﺫﺭﺯﺳﺷﺻﺿﻁﻅﻋﻏ¦¬÷×ﻉـﻓﻗﻛﻟﻣﻧﻭﻯﻳﺽﻌﻎﻍﻡﹽّﻥﻰﻲﻐﻕﻵﻶﻝﻙﻱ■<EFBBB1>"
},
"ibm864": "cp864",
"csibm864": "cp864",
"cp865": {
"type": "_sbcs",
"chars": "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø₧ƒáíóúñѪº¿⌐¬½¼¡«¤░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "
},
"ibm865": "cp865",
"csibm865": "cp865",
"cp866": {
"type": "_sbcs",
"chars": "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀рстуфхцчшщъыьэюяЁёЄєЇїЎў°∙·√№¤■ "
},
"ibm866": "cp866",
"csibm866": "cp866",
"cp869": {
"type": "_sbcs",
"chars": "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ά<EFBFBD>·¬¦Έ―ΉΊΪΌ<CEAA><CE8C>ΎΫ©Ώ²³ά£έήίϊΐόύΑΒΓΔΕΖΗ½ΘΙ«»░▒▓│┤ΚΛΜΝ╣║╗╝ΞΟ┐└┴┬├─┼ΠΡ╚╔╩╦╠═╬ΣΤΥΦΧΨΩαβγ┘┌█▄δε▀ζηθικλμνξοπρσςτ΄­±υφχ§ψ΅°¨ωϋΰώ■ "
},
"ibm869": "cp869",
"csibm869": "cp869",
"cp922": {
"type": "_sbcs",
"chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®‾°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏŠÑÒÓÔÕÖרÙÚÛÜÝŽßàáâãäåæçèéêëìíîïšñòóôõö÷øùúûüýžÿ"
},
"ibm922": "cp922",
"csibm922": "cp922",
"cp1046": {
"type": "_sbcs",
"chars": "ﺈ×÷ﹱˆ■│─┐┌└┘ﹹﹻﹽﹿﹷﺊﻰﻳﻲﻎﻏﻐﻶﻸﻺﻼ ¤ﺋﺑﺗﺛﺟﺣ،­ﺧﺳ٠١٢٣٤٥٦٧٨٩ﺷ؛ﺻﺿﻊ؟ﻋءآأؤإئابةتثجحخدذرزسشصضطﻇعغﻌﺂﺄﻓـفقكلمنهوىيًٌٍَُِّْﻗﻛﻟﻵﻷﻹﻻﻣﻧ<EFBBAC>"
},
"ibm1046": "cp1046",
"csibm1046": "cp1046",
"cp1124": {
"type": "_sbcs",
"chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ЁЂҐЄЅІЇЈЉЊЋЌ­ЎЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя№ёђґєѕіїјљњћќ§ўџ"
},
"ibm1124": "cp1124",
"csibm1124": "cp1124",
"cp1125": {
"type": "_sbcs",
"chars": "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀рстуфхцчшщъыьэюяЁёҐґЄєІіЇї·√№¤■ "
},
"ibm1125": "cp1125",
"csibm1125": "cp1125",
"cp1129": {
"type": "_sbcs",
"chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§œ©ª«¬­®¯°±²³Ÿµ¶·Œ¹º»¼½¾¿ÀÁÂĂÄÅÆÇÈÉÊË̀ÍÎÏĐÑ̉ÓÔƠÖרÙÚÛÜỮßàáâăäåæçèéêë́íîïđṇ̃óôơö÷øùúûüư₫ÿ"
},
"ibm1129": "cp1129",
"csibm1129": "cp1129",
"cp1133": {
"type": "_sbcs",
"chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ກຂຄງຈສຊຍດຕຖທນບປຜຝພຟມຢຣລວຫອຮ<E0BAAD><E0BAAE><EFBFBD>ຯະາຳິີຶືຸູຼັົຽ<E0BABB><E0BABD><EFBFBD>ເແໂໃໄ່້໊໋໌ໍໆ<E0BB8D>ໜໝ₭<E0BB9D><E282AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>໑໒໓໔໕໖໗໘໙<E0BB98><E0BB99>¢¬¦<C2AC>"
},
"ibm1133": "cp1133",
"csibm1133": "cp1133",
"cp1161": {
"type": "_sbcs",
"chars": "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>่กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู้๊๋€฿เแโใไๅๆ็่้๊๋์ํ๎๏๑๒๓๔๕๖๗๘๙๚๛¢¬¦ "
},
"ibm1161": "cp1161",
"csibm1161": "cp1161",
"cp1162": {
"type": "_sbcs",
"chars": "€‚ƒ„†‡ˆ‰Š‹ŒŽ“”•˜™š›œžŸ กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู<E0B8B9><E0B8BA><EFBFBD><EFBFBD>฿เแโใไๅๆ็่้๊๋์ํ๎๏๑๒๓๔๕๖๗๘๙๚๛<E0B99A><E0B99B><EFBFBD><EFBFBD>"
},
"ibm1162": "cp1162",
"csibm1162": "cp1162",
"cp1163": {
"type": "_sbcs",
"chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£€¥¦§œ©ª«¬­®¯°±²³Ÿµ¶·Œ¹º»¼½¾¿ÀÁÂĂÄÅÆÇÈÉÊË̀ÍÎÏĐÑ̉ÓÔƠÖרÙÚÛÜỮßàáâăäåæçèéêë́íîïđṇ̃óôơö÷øùúûüư₫ÿ"
},
"ibm1163": "cp1163",
"csibm1163": "cp1163",
"maccroatian": {
"type": "_sbcs",
"chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®Š™´¨≠ŽØ∞±≤≥∆µ∂∑∏š∫ªºΩžø¿¡¬√ƒ≈ƫȅ ÀÃÕŒœĐ—“”÷◊<C3B7>©¤Æ»·„‰ÂćÁčÈÍÎÏÌÓÔđÒÚÛÙıˆ˜¯πË˚¸Êæˇ"
},
"maccyrillic": {
"type": "_sbcs",
"chars": "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ†°¢£§•¶І®©™Ђђ≠Ѓѓ∞±≤≥іµ∂ЈЄєЇїЉљЊњјЅ¬√ƒ≈∆«»… ЋћЌќѕ–—“”‘’÷„ЎўЏџ№Ёёяабвгдежзийклмнопрстуфхцчшщъыьэю¤"
},
"macgreek": {
"type": "_sbcs",
"chars": "Ĺ²É³ÖÜ΅àâä΄¨çéèê룙î‰ôö¦­ùûü†ΓΔΘΛΞΠß®©ΣΪ§≠°·Α±≤≥¥ΒΕΖΗΙΚΜΦΫΨΩάΝ¬ΟΡΤ«»… ΥΧΆΈœ―“”÷ΉΊΌΎέήίόΏύαβψδεφγηιξκλμνοπώρστθωςχυζϊϋΐΰ<CE90>"
},
"maciceland": {
"type": "_sbcs",
"chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûüݰ¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ—“”÷◊ÿŸ¤ÐðÞþý·„‰ÂÊÁËÈÍÎÏÌÓÔ<C393>ÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ"
},
"macroman": {
"type": "_sbcs",
"chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ—“”÷◊ÿŸ¤fifl‡·„‰ÂÊÁËÈÍÎÏÌÓÔ<C393>ÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ"
},
"macromania": {
"type": "_sbcs",
"chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ĂŞ∞±≤≥¥µ∂∑∏π∫ªºΩăş¿¡¬√ƒ≈∆«»… ÀÃÕŒœ—“”÷◊ÿŸ¤Ţţ‡·„‰ÂÊÁËÈÍÎÏÌÓÔ<C393>ÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ"
},
"macthai": {
"type": "_sbcs",
"chars": "«»…“”<E2809D>•<E28098> กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู—฿เแโใไๅๆ็่้๊๋์ํ™๏๑๒๓๔๕๖๗๘๙®©<C2AE><C2A9><EFBFBD><EFBFBD>"
},
"macturkish": {
"type": "_sbcs",
"chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ—“”÷◊ÿŸĞğİıŞş‡·„‰ÂÊÁËÈÍÎÏÌÓÔ<C393>ÒÚÛÙ<C39B>ˆ˜¯˘˙˚¸˝˛ˇ"
},
"macukraine": {
"type": "_sbcs",
"chars": "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ†°Ґ£§•¶І®©™Ђђ≠Ѓѓ∞±≤≥іµґЈЄєЇїЉљЊњјЅ¬√ƒ≈∆«»… ЋћЌќѕ–—“”‘’÷„ЎўЏџ№Ёёяабвгдежзийклмнопрстуфхцчшщъыьэю¤"
},
"koi8r": {
"type": "_sbcs",
"chars": "─│┌┐└┘├┤┬┴┼▀▄█▌▐░▒▓⌠■∙√≈≤≥ ⌡°²·÷═║╒ё╓╔╕╖╗╘╙╚╛╜╝╞╟╠╡Ё╢╣╤╥╦╧╨╩╪╫╬©юабцдефгхийклмнопярстужвьызшэщчъЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪ"
},
"koi8u": {
"type": "_sbcs",
"chars": "─│┌┐└┘├┤┬┴┼▀▄█▌▐░▒▓⌠■∙√≈≤≥ ⌡°²·÷═║╒ёє╔ії╗╘╙╚╛ґ╝╞╟╠╡ЁЄ╣ІЇ╦╧╨╩╪Ґ╬©юабцдефгхийклмнопярстужвьызшэщчъЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪ"
},
"koi8ru": {
"type": "_sbcs",
"chars": "─│┌┐└┘├┤┬┴┼▀▄█▌▐░▒▓⌠■∙√≈≤≥ ⌡°²·÷═║╒ёє╔ії╗╘╙╚╛ґў╞╟╠╡ЁЄ╣ІЇ╦╧╨╩╪ҐЎ©юабцдефгхийклмнопярстужвьызшэщчъЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪ"
},
"koi8t": {
"type": "_sbcs",
"chars": "қғҒ„…†‡<E280A0>‰ҳҲҷҶ<D2B7>Қ“”•<E28093><EFBFBD><EFBFBD><E280BA><EFBFBD><EFBFBD><EFBFBD>ӯӮё¤ӣ¦§<C2A6><C2A7><EFBFBD>«¬­®<C2AD>°±²Ё<C2B2>Ӣ¶·<C2B6><EFBFBD>»<EFBFBD><C2BB><EFBFBD>©юабцдефгхийклмнопярстужвьызшэщчъЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪ"
},
"armscii8": {
"type": "_sbcs",
"chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ <C29F>և։)(»«—.՝,-֊…՜՛՞ԱաԲբԳգԴդԵեԶզԷէԸըԹթԺժԻիԼլԽխԾծԿկՀհՁձՂղՃճՄմՅյՆնՇշՈոՉչՊպՋջՌռՍսՎվՏտՐրՑցՒւՓփՔքՕօՖֆ՚<D686>"
},
"rk1048": {
"type": "_sbcs",
"chars": "ЂЃѓ„…†‡€‰ЉЊҚҺЏђ“”•<E28093>™љњқһџ ҰұӘ¤Ө¦§Ё©Ғ«¬­®Ү°±Ііөµ¶·ё№ғ»әҢңүАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя"
},
"tcvn": {
"type": "_sbcs",
"chars": "\u0000ÚỤ\u0003ỪỬỮ\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010ỨỰỲỶỸÝỴ\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÀẢÃÁẠẶẬÈẺẼÉẸỆÌỈĨÍỊÒỎÕÓỌỘỜỞỠỚỢÙỦŨ ĂÂÊÔƠƯĐăâêôơưđẶ̀̀̉̃́àảãáạẲằẳẵắẴẮẦẨẪẤỀặầẩẫấậèỂẻẽéẹềểễếệìỉỄẾỒĩíịòỔỏõóọồổỗốộờởỡớợùỖủũúụừửữứựỳỷỹýỵỐ"
},
"georgianacademy": {
"type": "_sbcs",
"chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿აბგდევზთიკლმნოპჟრსტუფქღყშჩცძწჭხჯჰჱჲჳჴჵჶçèéêëìíîïðñòóôõö÷øùúûüýþÿ"
},
"georgianps": {
"type": "_sbcs",
"chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿აბგდევზჱთიკლმნჲოპჟრსტჳუფქღყშჩცძწჭხჴჯჰჵæçèéêëìíîïðñòóôõö÷øùúûüýþÿ"
},
"pt154": {
"type": "_sbcs",
"chars": "ҖҒӮғ„…ҶҮҲүҠӢҢҚҺҸҗ‘’“”•–—ҳҷҡӣңқһҹ ЎўЈӨҘҰ§Ё©Ә«¬ӯ®Ҝ°ұІіҙө¶·ё№ә»јҪҫҝАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя"
},
"viscii": {
"type": "_sbcs",
"chars": "\u0000\u0001Ẳ\u0003\u0004ẴẪ\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013Ỷ\u0015\u0016\u0017\u0018Ỹ\u001a\u001b\u001c\u001dỴ\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ẠẮẰẶẤẦẨẬẼẸẾỀỂỄỆỐỒỔỖỘỢỚỜỞỊỎỌỈỦŨỤỲÕắằặấầẩậẽẹếềểễệốồổỗỠƠộờởịỰỨỪỬơớƯÀÁÂÃẢĂẳẵÈÉÊẺÌÍĨỳĐứÒÓÔạỷừửÙÚỹỵÝỡưàáâãảăữẫèéêẻìíĩỉđựòóôõỏọụùúũủýợỮ"
},
"iso646cn": {
"type": "_sbcs",
"chars": "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#¥%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}‾<E280BE><7F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
},
"iso646jp": {
"type": "_sbcs",
"chars": "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[¥]^_`abcdefghijklmnopqrstuvwxyz{|}‾<E280BE><7F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
},
"hproman8": {
"type": "_sbcs",
"chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ÀÂÈÊËÎÏ´ˋˆ¨˜ÙÛ₤¯Ýý°ÇçÑñ¡¿¤£¥§ƒ¢âêôûáéóúàèòùäëöüÅîØÆåíøæÄìÖÜÉïßÔÁÃãÐðÍÌÓÒÕõŠšÚŸÿÞþ·µ¶¾—¼½ªº«■»±<C2BB>"
},
"macintosh": {
"type": "_sbcs",
"chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ—“”÷◊ÿŸ¤fifl‡·„‰ÂÊÁËÈÍÎÏÌÓÔ<C393>ÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ"
},
"ascii": {
"type": "_sbcs",
"chars": "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
},
"tis620": {
"type": "_sbcs",
"chars": "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู<E0B8B9><E0B8BA><EFBFBD><EFBFBD>฿เแโใไๅๆ็่้๊๋์ํ๎๏๑๒๓๔๕๖๗๘๙๚๛<E0B99A><E0B99B><EFBFBD><EFBFBD>"
}
}

View File

@@ -0,0 +1,178 @@
"use strict"
// Manually added data to be used by sbcs codec in addition to generated one.
module.exports = {
// Not supported by iconv, not sure why.
10029: "maccenteuro",
maccenteuro: {
type: "_sbcs",
chars: "ÄĀāÉĄÖÜáąČäčĆć鏟ĎíďĒēĖóėôöõúĚěü†°Ę£§•¶ß®©™ę¨≠ģĮįĪ≤≥īĶ∂∑łĻļĽľĹĺŅņѬ√ńŇ∆«»… ňŐÕőŌ–—“”‘’÷◊ōŔŕŘ‹›řŖŗŠ‚„šŚśÁŤťÍŽžŪÓÔūŮÚůŰűŲųÝýķŻŁżĢˇ"
},
808: "cp808",
ibm808: "cp808",
cp808: {
type: "_sbcs",
chars: "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀рстуфхцчшщъыьэюяЁёЄєЇїЎў°∙·√№€■ "
},
mik: {
type: "_sbcs",
chars: "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя└┴┬├─┼╣║╚╔╩╦╠═╬┐░▒▓│┤№§╗╝┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "
},
cp720: {
type: "_sbcs",
chars: "\x80\x81éâ\x84à\x86çêëèïî\x8d\x8e\x8f\x90\u0651\u0652ô¤ـûùءآأؤ£إئابةتثجحخدذرزسشص«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀ضطظعغفµقكلمنهوىي≡\u064b\u064c\u064d\u064e\u064f\u0650≈°∙·√ⁿ²■\u00a0"
},
// Aliases of generated encodings.
ascii8bit: "ascii",
usascii: "ascii",
ansix34: "ascii",
ansix341968: "ascii",
ansix341986: "ascii",
csascii: "ascii",
cp367: "ascii",
ibm367: "ascii",
isoir6: "ascii",
iso646us: "ascii",
iso646irv: "ascii",
us: "ascii",
latin1: "iso88591",
latin2: "iso88592",
latin3: "iso88593",
latin4: "iso88594",
latin5: "iso88599",
latin6: "iso885910",
latin7: "iso885913",
latin8: "iso885914",
latin9: "iso885915",
latin10: "iso885916",
csisolatin1: "iso88591",
csisolatin2: "iso88592",
csisolatin3: "iso88593",
csisolatin4: "iso88594",
csisolatincyrillic: "iso88595",
csisolatinarabic: "iso88596",
csisolatingreek: "iso88597",
csisolatinhebrew: "iso88598",
csisolatin5: "iso88599",
csisolatin6: "iso885910",
l1: "iso88591",
l2: "iso88592",
l3: "iso88593",
l4: "iso88594",
l5: "iso88599",
l6: "iso885910",
l7: "iso885913",
l8: "iso885914",
l9: "iso885915",
l10: "iso885916",
isoir14: "iso646jp",
isoir57: "iso646cn",
isoir100: "iso88591",
isoir101: "iso88592",
isoir109: "iso88593",
isoir110: "iso88594",
isoir144: "iso88595",
isoir127: "iso88596",
isoir126: "iso88597",
isoir138: "iso88598",
isoir148: "iso88599",
isoir157: "iso885910",
isoir166: "tis620",
isoir179: "iso885913",
isoir199: "iso885914",
isoir203: "iso885915",
isoir226: "iso885916",
cp819: "iso88591",
ibm819: "iso88591",
cyrillic: "iso88595",
arabic: "iso88596",
arabic8: "iso88596",
ecma114: "iso88596",
asmo708: "iso88596",
greek: "iso88597",
greek8: "iso88597",
ecma118: "iso88597",
elot928: "iso88597",
hebrew: "iso88598",
hebrew8: "iso88598",
turkish: "iso88599",
turkish8: "iso88599",
thai: "iso885911",
thai8: "iso885911",
celtic: "iso885914",
celtic8: "iso885914",
isoceltic: "iso885914",
tis6200: "tis620",
tis62025291: "tis620",
tis62025330: "tis620",
10000: "macroman",
10006: "macgreek",
10007: "maccyrillic",
10079: "maciceland",
10081: "macturkish",
cspc8codepage437: "cp437",
cspc775baltic: "cp775",
cspc850multilingual: "cp850",
cspcp852: "cp852",
cspc862latinhebrew: "cp862",
cpgr: "cp869",
msee: "cp1250",
mscyrl: "cp1251",
msansi: "cp1252",
msgreek: "cp1253",
msturk: "cp1254",
mshebr: "cp1255",
msarab: "cp1256",
winbaltrim: "cp1257",
cp20866: "koi8r",
20866: "koi8r",
ibm878: "koi8r",
cskoi8r: "koi8r",
cp21866: "koi8u",
21866: "koi8u",
ibm1168: "koi8u",
strk10482002: "rk1048",
tcvn5712: "tcvn",
tcvn57121: "tcvn",
gb198880: "iso646cn",
cn: "iso646cn",
csiso14jisc6220ro: "iso646jp",
jisc62201969ro: "iso646jp",
jp: "iso646jp",
cshproman8: "hproman8",
r8: "hproman8",
roman8: "hproman8",
xroman8: "hproman8",
ibm1051: "hproman8",
mac: "macintosh",
csmacintosh: "macintosh"
}

View File

@@ -0,0 +1,122 @@
[
["8740","䏰䰲䘃䖦䕸𧉧䵷䖳𧲱䳢𧳅㮕䜶䝄䱇䱀𤊿𣘗𧍒𦺋𧃒䱗𪍑䝏䗚䲅𧱬䴇䪤䚡𦬣爥𥩔𡩣𣸆𣽡晍囻"],
["8767","綕夝𨮹㷴霴𧯯寛𡵞媤㘥𩺰嫑宷峼杮薓𩥅瑡璝㡵𡵓𣚞𦀡㻬"],
["87a1","𥣞㫵竼龗𤅡𨤍𣇪𠪊𣉞䌊蒄龖鐯䤰蘓墖靊鈘秐稲晠権袝瑌篅枂稬剏遆㓦珄𥶹瓆鿇垳䤯呌䄱𣚎堘穲𧭥讏䚮𦺈䆁𥶙箮𢒼鿈𢓁𢓉𢓌鿉蔄𣖻䂴鿊䓡𪷿拁灮鿋"],
["8840","㇀",4,"𠄌㇅𠃑𠃍㇆㇇𠃋𡿨㇈𠃊㇉㇊㇋㇌𠄎㇍㇎ĀÁǍÀĒÉĚÈŌÓǑÒ࿿Ê̄Ế࿿Ê̌ỀÊāáǎàɑēéěèīíǐìōóǒòūúǔùǖǘǚ"],
["88a1","ǜü࿿ê̄ế࿿ê̌ềêɡ⏚⏛"],
["8940","𪎩𡅅"],
["8943","攊"],
["8946","丽滝鵎釟"],
["894c","𧜵撑会伨侨兖兴农凤务动医华发变团声处备夲头学实実岚庆总斉柾栄桥济炼电纤纬纺织经统缆缷艺苏药视设询车轧轮"],
["89a1","琑糼緍楆竉刧"],
["89ab","醌碸酞肼"],
["89b0","贋胶𠧧"],
["89b5","肟黇䳍鷉鸌䰾𩷶𧀎鸊𪄳㗁"],
["89c1","溚舾甙"],
["89c5","䤑马骏龙禇𨑬𡷊𠗐𢫦两亁亀亇亿仫伷㑌侽㹈倃傈㑽㒓㒥円夅凛凼刅争剹劐匧㗇厩㕑厰㕓参吣㕭㕲㚁咓咣咴咹哐哯唘唣唨㖘唿㖥㖿嗗㗅"],
["8a40","𧶄唥"],
["8a43","𠱂𠴕𥄫喐𢳆㧬𠍁蹆𤶸𩓥䁓𨂾睺𢰸㨴䟕𨅝𦧲𤷪擝𠵼𠾴𠳕𡃴撍蹾𠺖𠰋𠽤𢲩𨉖𤓓"],
["8a64","𠵆𩩍𨃩䟴𤺧𢳂骲㩧𩗴㿭㔆𥋇𩟔𧣈𢵄鵮頕"],
["8a76","䏙𦂥撴哣𢵌𢯊𡁷㧻𡁯"],
["8aa1","𦛚𦜖𧦠擪𥁒𠱃蹨𢆡𨭌𠜱"],
["8aac","䠋𠆩㿺塳𢶍"],
["8ab2","𤗈𠓼𦂗𠽌𠶖啹䂻䎺"],
["8abb","䪴𢩦𡂝膪飵𠶜捹㧾𢝵跀嚡摼㹃"],
["8ac9","𪘁𠸉𢫏𢳉"],
["8ace","𡃈𣧂㦒㨆𨊛㕸𥹉𢃇噒𠼱𢲲𩜠㒼氽𤸻"],
["8adf","𧕴𢺋𢈈𪙛𨳍𠹺𠰴𦠜羓𡃏𢠃𢤹㗻𥇣𠺌𠾍𠺪㾓𠼰𠵇𡅏𠹌"],
["8af6","𠺫𠮩𠵈𡃀𡄽㿹𢚖搲𠾭"],
["8b40","𣏴𧘹𢯎𠵾𠵿𢱑𢱕㨘𠺘𡃇𠼮𪘲𦭐𨳒𨶙𨳊閪哌苄喹"],
["8b55","𩻃鰦骶𧝞𢷮煀腭胬尜𦕲脴㞗卟𨂽醶𠻺𠸏𠹷𠻻㗝𤷫㘉𠳖嚯𢞵𡃉𠸐𠹸𡁸𡅈𨈇𡑕𠹹𤹐𢶤婔𡀝𡀞𡃵𡃶垜𠸑"],
["8ba1","𧚔𨋍𠾵𠹻𥅾㜃𠾶𡆀𥋘𪊽𤧚𡠺𤅷𨉼墙剨㘚𥜽箲孨䠀䬬鼧䧧鰟鮍𥭴𣄽嗻㗲嚉丨夂𡯁屮靑𠂆乛亻㔾尣彑忄㣺扌攵歺氵氺灬爫丬犭𤣩罒礻糹罓𦉪㓁"],
["8bde","𦍋耂肀𦘒𦥑卝衤见𧢲讠贝钅镸长门𨸏韦页风飞饣𩠐鱼鸟黄歯龜丷𠂇阝户钢"],
["8c40","倻淾𩱳龦㷉袏𤅎灷峵䬠𥇍㕙𥴰愢𨨲辧釶熑朙玺𣊁𪄇㲋𡦀䬐磤琂冮𨜏䀉橣𪊺䈣蘏𠩯稪𩥇𨫪靕灍匤𢁾鏴盙𨧣龧矝亣俰傼丯众龨吴綋墒壐𡶶庒庙忂𢜒斋"],
["8ca1","𣏹椙橃𣱣泿"],
["8ca7","爀𤔅玌㻛𤨓嬕璹讃𥲤𥚕窓篬糃繬苸薗龩袐龪躹龫迏蕟駠鈡龬𨶹𡐿䁱䊢娚"],
["8cc9","顨杫䉶圽"],
["8cce","藖𤥻芿𧄍䲁𦵴嵻𦬕𦾾龭龮宖龯曧繛湗秊㶈䓃𣉖𢞖䎚䔶"],
["8ce6","峕𣬚諹屸㴒𣕑嵸龲煗䕘𤃬𡸣䱷㥸㑊𠆤𦱁諌侴𠈹妿腬顖𩣺弻"],
["8d40","𠮟"],
["8d42","𢇁𨥭䄂䚻𩁹㼇龳𪆵䃸㟖䛷𦱆䅼𨚲𧏿䕭㣔𥒚䕡䔛䶉䱻䵶䗪㿈𤬏㙡䓞䒽䇭崾嵈嵖㷼㠏嶤嶹㠠㠸幂庽弥徃㤈㤔㤿㥍惗愽峥㦉憷憹懏㦸戬抐拥挘㧸嚱"],
["8da1","㨃揢揻搇摚㩋擀崕嘡龟㪗斆㪽旿晓㫲暒㬢朖㭂枤栀㭘桊梄㭲㭱㭻椉楃牜楤榟榅㮼槖㯝橥橴橱檂㯬檙㯲檫檵櫔櫶殁毁毪汵沪㳋洂洆洦涁㳯涤涱渕渘温溆𨧀溻滢滚齿滨滩漤漴㵆𣽁澁澾㵪㵵熷岙㶊瀬㶑灐灔灯灿炉𠌥䏁㗱𠻘"],
["8e40","𣻗垾𦻓焾𥟠㙎榢𨯩孴穉𥣡𩓙穥穽𥦬窻窰竂竃燑𦒍䇊竚竝竪䇯咲𥰁笋筕笩𥌎𥳾箢筯莜𥮴𦱿篐萡箒箸𥴠㶭𥱥蒒篺簆簵𥳁籄粃𤢂粦晽𤕸糉糇糦籴糳糵糎"],
["8ea1","繧䔝𦹄絝𦻖璍綉綫焵綳緒𤁗𦀩緤㴓緵𡟹緥𨍭縝𦄡𦅚繮纒䌫鑬縧罀罁罇礶𦋐駡羗𦍑羣𡙡𠁨䕜𣝦䔃𨌺翺𦒉者耈耝耨耯𪂇𦳃耻耼聡𢜔䦉𦘦𣷣𦛨朥肧𨩈脇脚墰𢛶汿𦒘𤾸擧𡒊舘𡡞橓𤩥𤪕䑺舩𠬍𦩒𣵾俹𡓽蓢荢𦬊𤦧𣔰𡝳𣷸芪椛芳䇛"],
["8f40","蕋苐茚𠸖𡞴㛁𣅽𣕚艻苢茘𣺋𦶣𦬅𦮗𣗎㶿茝嗬莅䔋𦶥莬菁菓㑾𦻔橗蕚㒖𦹂𢻯葘𥯤葱㷓䓤檧葊𣲵祘蒨𦮖𦹷𦹃蓞萏莑䒠蒓蓤𥲑䉀𥳀䕃蔴嫲𦺙䔧蕳䔖枿蘖"],
["8fa1","𨘥𨘻藁𧂈蘂𡖂𧃍䕫䕪蘨㙈𡢢号𧎚虾蝱𪃸蟮𢰧螱蟚蠏噡虬桖䘏衅衆𧗠𣶹𧗤衞袜䙛袴袵揁装睷𧜏覇覊覦覩覧覼𨨥觧𧤤𧪽誜瞓釾誐𧩙竩𧬺𣾏䜓𧬸煼謌謟𥐰𥕥謿譌譍誩𤩺讐讛誯𡛟䘕衏貛𧵔𧶏貫㜥𧵓賖𧶘𧶽贒贃𡤐賛灜贑𤳉㻐起"],
["9040","趩𨀂𡀔𤦊㭼𨆼𧄌竧躭躶軃鋔輙輭𨍥𨐒辥錃𪊟𠩐辳䤪𨧞𨔽𣶻廸𣉢迹𪀔𨚼𨔁𢌥㦀𦻗逷𨔼𧪾遡𨕬𨘋邨𨜓郄𨛦邮都酧㫰醩釄粬𨤳𡺉鈎沟鉁鉢𥖹銹𨫆𣲛𨬌𥗛"],
["90a1","𠴱錬鍫𨫡𨯫炏嫃𨫢𨫥䥥鉄𨯬𨰹𨯿鍳鑛躼閅閦鐦閠濶䊹𢙺𨛘𡉼𣸮䧟氜陻隖䅬隣𦻕懚隶磵𨫠隽双䦡𦲸𠉴𦐐𩂯𩃥𤫑𡤕𣌊霱虂霶䨏䔽䖅𤫩灵孁霛靜𩇕靗孊𩇫靟鐥僐𣂷𣂼鞉鞟鞱鞾韀韒韠𥑬韮琜𩐳響韵𩐝𧥺䫑頴頳顋顦㬎𧅵㵑𠘰𤅜"],
["9140","𥜆飊颷飈飇䫿𦴧𡛓喰飡飦飬鍸餹𤨩䭲𩡗𩤅駵騌騻騐驘𥜥㛄𩂱𩯕髠髢𩬅髴䰎鬔鬭𨘀倴鬴𦦨㣃𣁽魐魀𩴾婅𡡣鮎𤉋鰂鯿鰌𩹨鷔𩾷𪆒𪆫𪃡𪄣𪇟鵾鶃𪄴鸎梈"],
["91a1","鷄𢅛𪆓𪈠𡤻𪈳鴹𪂹𪊴麐麕麞麢䴴麪麯𤍤黁㭠㧥㴝伲㞾𨰫鼂鼈䮖鐤𦶢鼗鼖鼹嚟嚊齅馸𩂋韲葿齢齩竜龎爖䮾𤥵𤦻煷𤧸𤍈𤩑玞𨯚𡣺禟𨥾𨸶鍩鏳𨩄鋬鎁鏋𨥬𤒹爗㻫睲穃烐𤑳𤏸煾𡟯炣𡢾𣖙㻇𡢅𥐯𡟸㜢𡛻𡠹㛡𡝴𡣑𥽋㜣𡛀坛𤨥𡏾𡊨"],
["9240","𡏆𡒶蔃𣚦蔃葕𤦔𧅥𣸱𥕜𣻻𧁒䓴𣛮𩦝𦼦柹㜳㰕㷧塬𡤢栐䁗𣜿𤃡𤂋𤄏𦰡哋嚞𦚱嚒𠿟𠮨𠸍鏆𨬓鎜仸儫㠙𤐶亼𠑥𠍿佋侊𥙑婨𠆫𠏋㦙𠌊𠐔㐵伩𠋀𨺳𠉵諚𠈌亘"],
["92a1","働儍侢伃𤨎𣺊佂倮偬傁俌俥偘僼兙兛兝兞湶𣖕𣸹𣺿浲𡢄𣺉冨凃𠗠䓝𠒣𠒒𠒑赺𨪜𠜎剙劤𠡳勡鍮䙺熌𤎌𠰠𤦬𡃤槑𠸝瑹㻞璙琔瑖玘䮎𤪼𤂍叐㖄爏𤃉喴𠍅响𠯆圝鉝雴鍦埝垍坿㘾壋媙𨩆𡛺𡝯𡜐娬妸銏婾嫏娒𥥆𡧳𡡡𤊕㛵洅瑃娡𥺃"],
["9340","媁𨯗𠐓鏠璌𡌃焅䥲鐈𨧻鎽㞠尞岞幞幈𡦖𡥼𣫮廍孏𡤃𡤄㜁𡢠㛝𡛾㛓脪𨩇𡶺𣑲𨦨弌弎𡤧𡞫婫𡜻孄蘔𧗽衠恾𢡠𢘫忛㺸𢖯𢖾𩂈𦽳懀𠀾𠁆𢘛憙憘恵𢲛𢴇𤛔𩅍"],
["93a1","摱𤙥𢭪㨩𢬢𣑐𩣪𢹸挷𪑛撶挱揑𤧣𢵧护𢲡搻敫楲㯴𣂎𣊭𤦉𣊫唍𣋠𡣙𩐿曎𣊉𣆳㫠䆐𥖄𨬢𥖏𡛼𥕛𥐥磮𣄃𡠪𣈴㑤𣈏𣆂𤋉暎𦴤晫䮓昰𧡰𡷫晣𣋒𣋡昞𥡲㣑𣠺𣞼㮙𣞢𣏾瓐㮖枏𤘪梶栞㯄檾㡣𣟕𤒇樳橒櫉欅𡤒攑梘橌㯗橺歗𣿀𣲚鎠鋲𨯪𨫋"],
["9440","銉𨀞𨧜鑧涥漋𤧬浧𣽿㶏渄𤀼娽渊塇洤硂焻𤌚𤉶烱牐犇犔𤞏𤜥兹𤪤𠗫瑺𣻸𣙟𤩊𤤗𥿡㼆㺱𤫟𨰣𣼵悧㻳瓌琼鎇琷䒟𦷪䕑疃㽣𤳙𤴆㽘畕癳𪗆㬙瑨𨫌𤦫𤦎㫻"],
["94a1","㷍𤩎㻿𤧅𤣳釺圲鍂𨫣𡡤僟𥈡𥇧睸𣈲眎眏睻𤚗𣞁㩞𤣰琸璛㺿𤪺𤫇䃈𤪖𦆮錇𥖁砞碍碈磒珐祙𧝁𥛣䄎禛蒖禥樭𣻺稺秴䅮𡛦䄲鈵秱𠵌𤦌𠊙𣶺𡝮㖗啫㕰㚪𠇔𠰍竢婙𢛵𥪯𥪜娍𠉛磰娪𥯆竾䇹籝籭䈑𥮳𥺼𥺦糍𤧹𡞰粎籼粮檲緜縇緓罎𦉡"],
["9540","𦅜𧭈綗𥺂䉪𦭵𠤖柖𠁎𣗏埄𦐒𦏸𤥢翝笧𠠬𥫩𥵃笌𥸎駦虅驣樜𣐿㧢𤧷𦖭騟𦖠蒀𧄧𦳑䓪脷䐂胆脉腂𦞴飃𦩂艢艥𦩑葓𦶧蘐𧈛媆䅿𡡀嬫𡢡嫤𡣘蚠蜨𣶏蠭𧐢娂"],
["95a1","衮佅袇袿裦襥襍𥚃襔𧞅𧞄𨯵𨯙𨮜𨧹㺭蒣䛵䛏㟲訽訜𩑈彍鈫𤊄旔焩烄𡡅鵭貟賩𧷜妚矃姰䍮㛔踪躧𤰉輰轊䋴汘澻𢌡䢛潹溋𡟚鯩㚵𤤯邻邗啱䤆醻鐄𨩋䁢𨫼鐧𨰝𨰻蓥訫閙閧閗閖𨴴瑅㻂𤣿𤩂𤏪㻧𣈥随𨻧𨹦𨹥㻌𤧭𤩸𣿮琒瑫㻼靁𩂰"],
["9640","桇䨝𩂓𥟟靝鍨𨦉𨰦𨬯𦎾銺嬑譩䤼珹𤈛鞛靱餸𠼦巁𨯅𤪲頟𩓚鋶𩗗釥䓀𨭐𤩧𨭤飜𨩅㼀鈪䤥萔餻饍𧬆㷽馛䭯馪驜𨭥𥣈檏騡嫾騯𩣱䮐𩥈馼䮽䮗鍽塲𡌂堢𤦸"],
["96a1","𡓨硄𢜟𣶸棅㵽鑘㤧慐𢞁𢥫愇鱏鱓鱻鰵鰐魿鯏𩸭鮟𪇵𪃾鴡䲮𤄄鸘䲰鴌𪆴𪃭𪃳𩤯鶥蒽𦸒𦿟𦮂藼䔳𦶤𦺄𦷰萠藮𦸀𣟗𦁤秢𣖜𣙀䤭𤧞㵢鏛銾鍈𠊿碹鉷鑍俤㑀遤𥕝砽硔碶硋𡝗𣇉𤥁㚚佲濚濙瀞瀞吔𤆵垻壳垊鴖埗焴㒯𤆬燫𦱀𤾗嬨𡞵𨩉"],
["9740","愌嫎娋䊼𤒈㜬䭻𨧼鎻鎸𡣖𠼝葲𦳀𡐓𤋺𢰦𤏁妔𣶷𦝁綨𦅛𦂤𤦹𤦋𨧺鋥珢㻩璴𨭣𡢟㻡𤪳櫘珳珻㻖𤨾𤪔𡟙𤩦𠎧𡐤𤧥瑈𤤖炥𤥶銄珦鍟𠓾錱𨫎𨨖鎆𨯧𥗕䤵𨪂煫"],
["97a1","𤥃𠳿嚤𠘚𠯫𠲸唂秄𡟺緾𡛂𤩐𡡒䔮鐁㜊𨫀𤦭妰𡢿𡢃𧒄媡㛢𣵛㚰鉟婹𨪁𡡢鍴㳍𠪴䪖㦊僴㵩㵌𡎜煵䋻𨈘渏𩃤䓫浗𧹏灧沯㳖𣿭𣸭渂漌㵯𠏵畑㚼㓈䚀㻚䡱姄鉮䤾轁𨰜𦯀堒埈㛖𡑒烾𤍢𤩱𢿣𡊰𢎽梹楧𡎘𣓥𧯴𣛟𨪃𣟖𣏺𤲟樚𣚭𦲷萾䓟䓎"],
["9840","𦴦𦵑𦲂𦿞漗𧄉茽𡜺菭𦲀𧁓𡟛妉媂𡞳婡婱𡤅𤇼㜭姯𡜼㛇熎鎐暚𤊥婮娫𤊓樫𣻹𧜶𤑛𤋊焝𤉙𨧡侰𦴨峂𤓎𧹍𤎽樌𤉖𡌄炦焳𤏩㶥泟勇𤩏繥姫崯㷳彜𤩝𡟟綤萦"],
["98a1","咅𣫺𣌀𠈔坾𠣕𠘙㿥𡾞𪊶瀃𩅛嵰玏糓𨩙𩐠俈翧狍猐𧫴猸猹𥛶獁獈㺩𧬘遬燵𤣲珡臶㻊県㻑沢国琙琞琟㻢㻰㻴㻺瓓㼎㽓畂畭畲疍㽼痈痜㿀癍㿗癴㿜発𤽜熈嘣覀塩䀝睃䀹条䁅㗛瞘䁪䁯属瞾矋売砘点砜䂨砹硇硑硦葈𥔵礳栃礲䄃"],
["9940","䄉禑禙辻稆込䅧窑䆲窼艹䇄竏竛䇏両筢筬筻簒簛䉠䉺类粜䊌粸䊔糭输烀𠳏総緔緐緽羮羴犟䎗耠耥笹耮耱联㷌垴炠肷胩䏭脌猪脎脒畠脔䐁㬹腖腙腚"],
["99a1","䐓堺腼膄䐥膓䐭膥埯臁臤艔䒏芦艶苊苘苿䒰荗险榊萅烵葤惣蒈䔄蒾蓡蓸蔐蔸蕒䔻蕯蕰藠䕷虲蚒蚲蛯际螋䘆䘗袮裿褤襇覑𧥧訩訸誔誴豑賔賲贜䞘塟跃䟭仮踺嗘坔蹱嗵躰䠷軎転軤軭軲辷迁迊迌逳駄䢭飠鈓䤞鈨鉘鉫銱銮銿"],
["9a40","鋣鋫鋳鋴鋽鍃鎄鎭䥅䥑麿鐗匁鐝鐭鐾䥪鑔鑹锭関䦧间阳䧥枠䨤靀䨵鞲韂噔䫤惨颹䬙飱塄餎餙冴餜餷饂饝饢䭰駅䮝騼鬏窃魩鮁鯝鯱鯴䱭鰠㝯𡯂鵉鰺"],
["9aa1","黾噐鶓鶽鷀鷼银辶鹻麬麱麽黆铜黢黱黸竈齄𠂔𠊷𠎠椚铃妬𠓗塀铁㞹𠗕𠘕𠙶𡚺块煳𠫂𠫍𠮿呪吆𠯋咞𠯻𠰻𠱓𠱥𠱼惧𠲍噺𠲵𠳝𠳭𠵯𠶲𠷈楕鰯螥𠸄𠸎𠻗𠾐𠼭𠹳尠𠾼帋𡁜𡁏𡁶朞𡁻𡂈𡂖㙇𡂿𡃓𡄯𡄻卤蒭𡋣𡍵𡌶讁𡕷𡘙𡟃𡟇乸炻𡠭𡥪"],
["9b40","𡨭𡩅𡰪𡱰𡲬𡻈拃𡻕𡼕熘桕𢁅槩㛈𢉼𢏗𢏺𢜪𢡱𢥏苽𢥧𢦓𢫕覥𢫨辠𢬎鞸𢬿顇骽𢱌"],
["9b62","𢲈𢲷𥯨𢴈𢴒𢶷𢶕𢹂𢽴𢿌𣀳𣁦𣌟𣏞徱晈暿𧩹𣕧𣗳爁𤦺矗𣘚𣜖纇𠍆墵朎"],
["9ba1","椘𣪧𧙗𥿢𣸑𣺹𧗾𢂚䣐䪸𤄙𨪚𤋮𤌍𤀻𤌴𤎖𤩅𠗊凒𠘑妟𡺨㮾𣳿𤐄𤓖垈𤙴㦛𤜯𨗨𩧉㝢𢇃譞𨭎駖𤠒𤣻𤨕爉𤫀𠱸奥𤺥𤾆𠝹軚𥀬劏圿煱𥊙𥐙𣽊𤪧喼𥑆𥑮𦭒釔㑳𥔿𧘲𥕞䜘𥕢𥕦𥟇𤤿𥡝偦㓻𣏌惞𥤃䝼𨥈𥪮𥮉𥰆𡶐垡煑澶𦄂𧰒遖𦆲𤾚譢𦐂𦑊"],
["9c40","嵛𦯷輶𦒄𡤜諪𤧶𦒈𣿯𦔒䯀𦖿𦚵𢜛鑥𥟡憕娧晉侻嚹𤔡𦛼乪𤤴陖涏𦲽㘘襷𦞙𦡮𦐑𦡞營𦣇筂𩃀𠨑𦤦鄄𦤹穅鷰𦧺騦𦨭㙟𦑩𠀡禃𦨴𦭛崬𣔙菏𦮝䛐𦲤画补𦶮墶"],
["9ca1","㜜𢖍𧁋𧇍㱔𧊀𧊅銁𢅺𧊋錰𧋦𤧐氹钟𧑐𠻸蠧裵𢤦𨑳𡞱溸𤨪𡠠㦤㚹尐秣䔿暶𩲭𩢤襃𧟌𧡘囖䃟𡘊㦡𣜯𨃨𡏅熭荦𧧝𩆨婧䲷𧂯𨦫𧧽𧨊𧬋𧵦𤅺筃祾𨀉澵𪋟樃𨌘厢𦸇鎿栶靝𨅯𨀣𦦵𡏭𣈯𨁈嶅𨰰𨂃圕頣𨥉嶫𤦈斾槕叒𤪥𣾁㰑朶𨂐𨃴𨄮𡾡𨅏"],
["9d40","𨆉𨆯𨈚𨌆𨌯𨎊㗊𨑨𨚪䣺揦𨥖砈鉕𨦸䏲𨧧䏟𨧨𨭆𨯔姸𨰉輋𨿅𩃬筑𩄐𩄼㷷𩅞𤫊运犏嚋𩓧𩗩𩖰𩖸𩜲𩣑𩥉𩥪𩧃𩨨𩬎𩵚𩶛纟𩻸𩼣䲤镇𪊓熢𪋿䶑递𪗋䶜𠲜达嗁"],
["9da1","辺𢒰边𤪓䔉繿潖檱仪㓤𨬬𧢝㜺躀𡟵𨀤𨭬𨮙𧨾𦚯㷫𧙕𣲷𥘵𥥖亚𥺁𦉘嚿𠹭踎孭𣺈𤲞揞拐𡟶𡡻攰嘭𥱊吚𥌑㷆𩶘䱽嘢嘞罉𥻘奵𣵀蝰东𠿪𠵉𣚺脗鵞贘瘻鱅癎瞹鍅吲腈苷嘥脲萘肽嗪祢噃吖𠺝㗎嘅嗱曱𨋢㘭甴嗰喺咗啲𠱁𠲖廐𥅈𠹶𢱢"],
["9e40","𠺢麫絚嗞𡁵抝靭咔賍燶酶揼掹揾啩𢭃鱲𢺳冚㓟𠶧冧呍唞唓癦踭𦢊疱肶蠄螆裇膶萜𡃁䓬猄𤜆宐茋𦢓噻𢛴𧴯𤆣𧵳𦻐𧊶酰𡇙鈈𣳼𪚩𠺬𠻹牦𡲢䝎𤿂𧿹𠿫䃺"],
["9ea1","鱝攟𢶠䣳𤟠𩵼𠿬𠸊恢𧖣𠿭"],
["9ead","𦁈𡆇熣纎鵐业丄㕷嬍沲卧㚬㧜卽㚥𤘘墚𤭮舭呋垪𥪕𠥹"],
["9ec5","㩒𢑥獴𩺬䴉鯭𣳾𩼰䱛𤾩𩖞𩿞葜𣶶𧊲𦞳𣜠挮紥𣻷𣸬㨪逈勌㹴㙺䗩𠒎癀嫰𠺶硺𧼮墧䂿噼鮋嵴癔𪐴麅䳡痹㟻愙𣃚𤏲"],
["9ef5","噝𡊩垧𤥣𩸆刴𧂮㖭汊鵼"],
["9f40","籖鬹埞𡝬屓擓𩓐𦌵𧅤蚭𠴨𦴢𤫢𠵱"],
["9f4f","凾𡼏嶎霃𡷑麁遌笟鬂峑箣扨挵髿篏鬪籾鬮籂粆鰕篼鬉鼗鰛𤤾齚啳寃俽麘俲剠㸆勑坧偖妷帒韈鶫轜呩鞴饀鞺匬愰"],
["9fa1","椬叚鰊鴂䰻陁榀傦畆𡝭駚剳"],
["9fae","酙隁酜"],
["9fb2","酑𨺗捿𦴣櫊嘑醎畺抅𠏼獏籰𥰡𣳽"],
["9fc1","𤤙盖鮝个𠳔莾衂"],
["9fc9","届槀僭坺刟巵从氱𠇲伹咜哚劚趂㗾弌㗳"],
["9fdb","歒酼龥鮗頮颴骺麨麄煺笔"],
["9fe7","毺蠘罸"],
["9feb","嘠𪙊蹷齓"],
["9ff0","跔蹏鸜踁抂𨍽踨蹵竓𤩷稾磘泪詧瘇"],
["a040","𨩚鼦泎蟖痃𪊲硓咢贌狢獱謭猂瓱賫𤪻蘯徺袠䒷"],
["a055","𡠻𦸅"],
["a058","詾𢔛"],
["a05b","惽癧髗鵄鍮鮏蟵"],
["a063","蠏賷猬霡鮰㗖犲䰇籑饊𦅙慙䰄麖慽"],
["a073","坟慯抦戹拎㩜懢厪𣏵捤栂㗒"],
["a0a1","嵗𨯂迚𨸹"],
["a0a6","僙𡵆礆匲阸𠼻䁥"],
["a0ae","矾"],
["a0b0","糂𥼚糚稭聦聣絍甅瓲覔舚朌聢𧒆聛瓰脃眤覉𦟌畓𦻑螩蟎臈螌詉貭譃眫瓸蓚㘵榲趦"],
["a0d4","覩瑨涹蟁𤀑瓧㷛煶悤憜㳑煢恷"],
["a0e2","罱𨬭牐惩䭾删㰘𣳇𥻗𧙖𥔱𡥄𡋾𩤃𦷜𧂭峁𦆭𨨏𣙷𠃮𦡆𤼎䕢嬟𦍌齐麦𦉫"],
["a3c0","␀",31,"␡"],
["c6a1","①",9,"⑴",9,"",9,"丶丿亅亠冂冖冫勹匸卩厶夊宀巛⼳广廴彐彡攴无疒癶辵隶¨ˆヽヾゝゞ〃仝々〆〇ー[]✽ぁ",23],
["c740","す",58,"ァアィイ"],
["c7a1","ゥ",81,"А",5,"ЁЖ",4],
["c840","Л",26,"ёж",25,"⇧↸↹㇏𠃌乚𠂊刂䒑"],
["c8a1","龰冈龱𧘇"],
["c8cd","¬¦'"㈱№℡゛゜⺀⺄⺆⺇⺈⺊⺌⺍⺕⺜⺝⺥⺧⺪⺬⺮⺶⺼⺾⻆⻊⻌⻍⻏⻖⻗⻞⻣"],
["c8f5","ʃɐɛɔɵœøŋʊɪ"],
["f9fe","■"],
["fa40","𠕇鋛𠗟𣿅蕌䊵珯况㙉𤥂𨧤鍄𡧛苮𣳈砼杄拟𤤳𨦪𠊠𦮳𡌅侫𢓭倈𦴩𧪄𣘀𤪱𢔓倩𠍾徤𠎀𠍇滛𠐟偽儁㑺儎顬㝃萖𤦤𠒇兠𣎴兪𠯿𢃼𠋥𢔰𠖎𣈳𡦃宂蝽𠖳𣲙冲冸"],
["faa1","鴴凉减凑㳜凓𤪦决凢卂凭菍椾𣜭彻刋刦刼劵剗劔効勅簕蕂勠蘍𦬓包𨫞啉滙𣾀𠥔𣿬匳卄𠯢泋𡜦栛珕恊㺪㣌𡛨燝䒢卭却𨚫卾卿𡖖𡘓矦厓𨪛厠厫厮玧𥝲㽙玜叁叅汉义埾叙㪫𠮏叠𣿫𢶣叶𠱷吓灹唫晗浛呭𦭓𠵴啝咏咤䞦𡜍𠻝㶴𠵍"],
["fb40","𨦼𢚘啇䳭启琗喆喩嘅𡣗𤀺䕒𤐵暳𡂴嘷曍𣊊暤暭噍噏磱囱鞇叾圀囯园𨭦㘣𡉏坆𤆥汮炋坂㚱𦱾埦𡐖堃𡑔𤍣堦𤯵塜墪㕡壠壜𡈼壻寿坃𪅐𤉸鏓㖡够梦㛃湙"],
["fba1","𡘾娤啓𡚒蔅姉𠵎𦲁𦴪𡟜姙𡟻𡞲𦶦浱𡠨𡛕姹𦹅媫婣㛦𤦩婷㜈媖瑥嫓𦾡𢕔㶅𡤑㜲𡚸広勐孶斈孼𧨎䀄䡝𠈄寕慠𡨴𥧌𠖥寳宝䴐尅𡭄尓珎尔𡲥𦬨屉䣝岅峩峯嶋𡷹𡸷崐崘嵆𡺤岺巗苼㠭𤤁𢁉𢅳芇㠶㯂帮檊幵幺𤒼𠳓厦亷廐厨𡝱帉廴𨒂"],
["fc40","廹廻㢠廼栾鐛弍𠇁弢㫞䢮𡌺强𦢈𢏐彘𢑱彣鞽𦹮彲鍀𨨶徧嶶㵟𥉐𡽪𧃸𢙨釖𠊞𨨩怱暅𡡷㥣㷇㘹垐𢞴祱㹀悞悤悳𤦂𤦏𧩓璤僡媠慤萤慂慈𦻒憁凴𠙖憇宪𣾷"],
["fca1","𢡟懓𨮝𩥝懐㤲𢦀𢣁怣慜攞掋𠄘担𡝰拕𢸍捬𤧟㨗搸揸𡎎𡟼撐澊𢸶頔𤂌𥜝擡擥鑻㩦携㩗敍漖𤨨𤨣斅敭敟𣁾斵𤥀䬷旑䃘𡠩无旣忟𣐀昘𣇷𣇸晄𣆤𣆥晋𠹵晧𥇦晳晴𡸽𣈱𨗴𣇈𥌓矅𢣷馤朂𤎜𤨡㬫槺𣟂杞杧杢𤇍𩃭柗䓩栢湐鈼栁𣏦𦶠桝"],
["fd40","𣑯槡樋𨫟楳棃𣗍椁椀㴲㨁𣘼㮀枬楡𨩊䋼椶榘㮡𠏉荣傐槹𣙙𢄪橅𣜃檝㯳枱櫈𩆜㰍欝𠤣惞欵歴𢟍溵𣫛𠎵𡥘㝀吡𣭚毡𣻼毜氷𢒋𤣱𦭑汚舦汹𣶼䓅𣶽𤆤𤤌𤤀"],
["fda1","𣳉㛥㳫𠴲鮃𣇹𢒑羏样𦴥𦶡𦷫涖浜湼漄𤥿𤂅𦹲蔳𦽴凇沜渝萮𨬡港𣸯瑓𣾂秌湏媑𣁋濸㜍澝𣸰滺𡒗𤀽䕕鏰潄潜㵎潴𩅰㴻澟𤅄濓𤂑𤅕𤀹𣿰𣾴𤄿凟𤅖𤅗𤅀𦇝灋灾炧炁烌烕烖烟䄄㷨熴熖𤉷焫煅媈煊煮岜𤍥煏鍢𤋁焬𤑚𤨧𤨢熺𨯨炽爎"],
["fe40","鑂爕夑鑃爤鍁𥘅爮牀𤥴梽牕牗㹕𣁄栍漽犂猪猫𤠣𨠫䣭𨠄猨献珏玪𠰺𦨮珉瑉𤇢𡛧𤨤昣㛅𤦷𤦍𤧻珷琕椃𤨦琹𠗃㻗瑜𢢭瑠𨺲瑇珤瑶莹瑬㜰瑴鏱樬璂䥓𤪌"],
["fea1","𤅟𤩹𨮏孆𨰃𡢞瓈𡦈甎瓩甞𨻙𡩋寗𨺬鎅畍畊畧畮𤾂㼄𤴓疎瑝疞疴瘂瘬癑癏癯癶𦏵皐臯㟸𦤑𦤎皡皥皷盌𦾟葢𥂝𥅽𡸜眞眦着撯𥈠睘𣊬瞯𨥤𨥨𡛁矴砉𡍶𤨒棊碯磇磓隥礮𥗠磗礴碱𧘌辸袄𨬫𦂃𢘜禆褀椂禀𥡗禝𧬹礼禩渪𧄦㺨秆𩄍秔"]
]

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