├── .prettierrc ├── src ├── deno │ ├── buffer.d.ts │ ├── README.md │ ├── deferred.d.ts │ ├── deferred.js │ ├── LICENSE │ ├── buffer.js │ └── workers-override.ts ├── driver │ └── mysql │ │ ├── 62edfb469c0dbacd90273cf9a0d7a478.wasm │ │ ├── README.md │ │ ├── edgeworkerizer.py │ │ ├── LICENSE │ │ ├── index.d.ts │ │ └── index.js └── index.ts ├── .gitignore ├── wrangler.toml ├── tsconfig.json ├── .github └── workflows │ └── semgrep.yml ├── scripts └── mysql │ └── docker-compose.yml ├── package.json ├── LICENSE_MIT ├── README.md ├── CODE_OF_CONDUCT.md └── LICENSE_APACHE /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "semi": false, 4 | "trailingComma": "all", 5 | "tabWidth": 2, 6 | "printWidth": 80 7 | } 8 | -------------------------------------------------------------------------------- /src/deno/buffer.d.ts: -------------------------------------------------------------------------------- 1 | export class Buffer { 2 | write(p: Uint8Array): Promise; 3 | read(p: Uint8Array): Promise; 4 | get length(): number; 5 | } -------------------------------------------------------------------------------- /src/driver/mysql/62edfb469c0dbacd90273cf9a0d7a478.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudflare/worker-template-mysql/HEAD/src/driver/mysql/62edfb469c0dbacd90273cf9a0d7a478.wasm -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /dist 3 | /tscOutDir 4 | **/*.rs.bk 5 | Cargo.lock 6 | bin/ 7 | pkg/ 8 | wasm-pack.log 9 | worker/ 10 | node_modules/ 11 | .cargo-ok 12 | .DS_Store 13 | -------------------------------------------------------------------------------- /src/deno/README.md: -------------------------------------------------------------------------------- 1 | ## Bundle Deno sources 2 | 3 | deno bundle https://deno.land/std@0.110.0/io/buffer.ts > buffer.js 4 | deno bundle https://deno.land/std@0.114.0/async/deferred.ts > deferred.js -------------------------------------------------------------------------------- /src/deno/deferred.d.ts: -------------------------------------------------------------------------------- 1 | export interface Deferred extends Promise { 2 | readonly state: "pending" | "fulfilled" | "rejected"; 3 | resolve(value?: T | PromiseLike): void; 4 | // deno-lint-ignore no-explicit-any 5 | reject(reason?: any): void; 6 | } 7 | 8 | export function deferred(): Deferred; -------------------------------------------------------------------------------- /src/driver/mysql/README.md: -------------------------------------------------------------------------------- 1 | This directory contains the source for the original bundled driver as well as artifacts created by 2 | `edgeworkerizer.py` to enable it to run on Cloudflare Workers. 3 | 4 | ### Bundle Deno MySQL driver 5 | 6 | ```sh 7 | deno bundle https://deno.land/x/mysql@v2.10.1/mod.ts > mysql.js.deno 8 | python3 ../edgeworkerizer.py mysql.js.deno > index.js 9 | cp *.wasm ../../../dist/ 10 | ``` -------------------------------------------------------------------------------- /wrangler.toml: -------------------------------------------------------------------------------- 1 | name = "worker-template-mysql" 2 | type = "javascript" 3 | account_id = "" 4 | workers_dev = true 5 | route = "" 6 | zone_id = "" 7 | compatibility_date = "2021-10-07" 8 | 9 | [build] 10 | command = "npm install && npm run build && cp ./src/driver/**/*.wasm ./dist" 11 | 12 | [build.upload] 13 | format = "modules" 14 | main = "./index.mjs" 15 | dir = "./dist" 16 | 17 | [[build.upload.rules]] 18 | type = "CompiledWasm" 19 | globs = ["**/*.wasm"] 20 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "lib": ["esnext", "webworker"], 5 | "alwaysStrict": true, 6 | "strict": true, 7 | "noEmitOnError": true, 8 | "moduleResolution": "node", 9 | "outDir": "tscOutDir", 10 | "preserveConstEnums": true, 11 | "esModuleInterop": true, 12 | "allowJs": true, 13 | "types": ["@cloudflare/workers-types", "node", "jest"] 14 | }, 15 | "include": ["src/**/*", "src/types"], 16 | "exclude": ["node_modules", "dist"] 17 | } -------------------------------------------------------------------------------- /src/deno/deferred.js: -------------------------------------------------------------------------------- 1 | function deferred1() { 2 | let methods; 3 | let state = "pending"; 4 | const promise = new Promise((resolve, reject)=>{ 5 | methods = { 6 | async resolve (value) { 7 | await value; 8 | state = "fulfilled"; 9 | resolve(value); 10 | }, 11 | reject (reason) { 12 | state = "rejected"; 13 | reject(reason); 14 | } 15 | }; 16 | }); 17 | Object.defineProperty(promise, "state", { 18 | get: ()=>state 19 | }); 20 | return Object.assign(promise, methods); 21 | } 22 | export { deferred1 as deferred }; 23 | 24 | -------------------------------------------------------------------------------- /.github/workflows/semgrep.yml: -------------------------------------------------------------------------------- 1 | 2 | on: 3 | pull_request: {} 4 | workflow_dispatch: {} 5 | push: 6 | branches: 7 | - main 8 | - master 9 | schedule: 10 | - cron: '0 0 * * *' 11 | name: Semgrep config 12 | jobs: 13 | semgrep: 14 | name: semgrep/ci 15 | runs-on: ubuntu-20.04 16 | env: 17 | SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }} 18 | SEMGREP_URL: https://cloudflare.semgrep.dev 19 | SEMGREP_APP_URL: https://cloudflare.semgrep.dev 20 | SEMGREP_VERSION_CHECK_URL: https://cloudflare.semgrep.dev/api/check-version 21 | container: 22 | image: returntocorp/semgrep 23 | steps: 24 | - uses: actions/checkout@v3 25 | - run: semgrep ci 26 | -------------------------------------------------------------------------------- /scripts/mysql/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.3' 2 | services: 3 | mysql: 4 | image: mysql:5.7 5 | restart: always 6 | environment: 7 | MYSQL_DATABASE: 'appdb' 8 | MYSQL_USER: 'user' 9 | MYSQL_PASSWORD: 'password' 10 | MYSQL_ROOT_PASSWORD: 'password' 11 | ports: 12 | - '3306:3306' 13 | expose: 14 | - '3306' 15 | volumes: 16 | - my-db:/var/lib/mysql 17 | cloudflared: 18 | image: cloudflare/cloudflared:2021.10.5 19 | environment: 20 | - TUNNEL_HOSTNAME=${TUNNEL_HOSTNAME} 21 | volumes: 22 | - '~/.cloudflared:/etc/cloudflared' 23 | command: tunnel --url tcp://mysql:3306 --name dev -f 24 | depends_on: 25 | - mysql 26 | 27 | volumes: 28 | my-db: 29 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "worker-template-mysql", 4 | "version": "1.0.0", 5 | "description": "A template for kick starting a Cloudflare Workers project", 6 | "module": "./dist/index.mjs", 7 | "scripts": { 8 | "build": "esbuild --bundle --sourcemap --outfile=dist/index.mjs --minify --format=esm ./src/index.js --external:*.wasm --inject:./src/deno/workers-override.ts", 9 | "format": "prettier --write '**/*.{js,css,json,md}'" 10 | }, 11 | "author": "Cloudflare Workers Team ", 12 | "license": "MIT", 13 | "devDependencies": { 14 | "@cloudflare/workers-types": "^3.0.0", 15 | "@types/jest": "^26.0.23", 16 | "esbuild": "^0.13.10", 17 | "isomorphic-fetch": "^3.0.0", 18 | "jest": "^27.2.5", 19 | "prettier": "^1.19.1", 20 | "ts-jest": "^27.0.5", 21 | "tslib": "^2.2.0", 22 | "typescript": "^4.2.4" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/driver/mysql/edgeworkerizer.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import re 3 | from base64 import b64decode 4 | import hashlib 5 | 6 | # This regex is written to match against the wasm dynamically loaded by Deno's hash library 7 | regex = r'const (wasmModule.?) = new WebAssembly\.Module\(decode.?\("(.*?)".*?\);' 8 | 9 | def repl(m): 10 | b64_wasm = m.group(2).replace('\n', '').replace('\\', '') 11 | wasm = b64decode(b64_wasm) 12 | md5 = hashlib.md5(wasm).hexdigest() 13 | 14 | # Use module md5 to avoid duplication 15 | fname = f'{md5}.wasm' 16 | 17 | # Write the module to a file 18 | with open(fname, "wb") as f: 19 | f.write(wasm) 20 | 21 | replace = f'import {m.group(1)} from \'./{fname}\';' 22 | 23 | return replace 24 | 25 | def main(argv): 26 | if len(argv) != 1: 27 | print("Specify input file") 28 | exit(1) 29 | 30 | with open(argv[0]) as f: 31 | program = f.read() 32 | print(re.sub(regex, repl, program, flags=re.DOTALL)) 33 | 34 | if __name__ == "__main__": 35 | main(sys.argv[1:]) 36 | -------------------------------------------------------------------------------- /src/deno/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright 2018-2021 the Deno authors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /src/driver/mysql/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 EnokMan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /LICENSE_MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2021 Cloudflare, Inc. 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { Client } from './driver/mysql' 2 | 3 | export default { 4 | async fetch(request: Request, env, ctx: ExecutionContext) { 5 | // Add Cloudflare Access Service Token credentials as global variables, used when Worker 6 | // establishes the connection to Cloudflare Tunnel. This ensures only approved services can 7 | // connect to your Tunnel. 8 | // globalThis.CF_CLIENT_ID = env.CF_CLIENT_ID || undefined 9 | // globalThis.CF_CLIENT_SECRET = env.CF_CLIENT_SECRET || undefined 10 | // NOTE: You may omit these values, however your Tunnel will accept traffic from _any_ source 11 | // on the Internet which may result in extra load on your database. 12 | 13 | try { 14 | // Configure the database client and create a connection. 15 | const mysql = new Client() 16 | const mysqlClient = await mysql.connect({ 17 | username: 'user', 18 | db: 'appdb', 19 | // hostname is the full URL to your pre-created Cloudflare Tunnel, see documentation here: 20 | // https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/create-tunnel 21 | hostname: env.TUNNEL_HOST || 'https://dev.example.com', 22 | password: 'password', // use a secret to store passwords 23 | }) 24 | 25 | // Query the database. 26 | const param = 42 27 | const result = await mysqlClient.query('SELECT ?;', [param]) 28 | 29 | // Return result from database. 30 | return new Response(JSON.stringify({ result })) 31 | } catch (e) { 32 | return new Response((e as Error).message) 33 | } 34 | }, 35 | } 36 | -------------------------------------------------------------------------------- /src/driver/mysql/index.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Client Config 3 | */ 4 | export interface ClientConfig { 5 | /** Database hostname */ 6 | hostname?: string; 7 | /** Database UNIX domain socket path. When used, `hostname` and `port` are ignored. */ 8 | socketPath?: string; 9 | /** Database username */ 10 | username?: string; 11 | /** Database password */ 12 | password?: string; 13 | /** Database port */ 14 | port?: number; 15 | /** Database name */ 16 | db?: string; 17 | /** Whether to display packet debugging information */ 18 | debug?: boolean; 19 | /** Connection read timeout (default: 30 seconds) */ 20 | timeout?: number; 21 | /** Connection pool size (default: 1) */ 22 | poolSize?: number; 23 | /** Connection pool idle timeout in microseconds (default: 4 hours) */ 24 | idleTimeout?: number; 25 | /** charset */ 26 | charset?: string; 27 | } 28 | 29 | export class Client { 30 | connect(config: ClientConfig): Promise 31 | 32 | query(sql: string, params?: any[]): Promise 33 | execute(sql: string, params?: any[]): Promise 34 | 35 | // @ts-ignore 36 | useConnection(fn: (conn: Connection) => Promise) 37 | 38 | transaction(processor: TransactionProcessor): Promise 39 | 40 | } 41 | 42 | /** 43 | * Result for execute sql 44 | */ 45 | export type ExecuteResult = { 46 | affectedRows?: number; 47 | lastInsertId?: number; 48 | fields?: FieldInfo[]; 49 | rows?: any[]; 50 | iterator?: any; 51 | }; 52 | 53 | /** @ignore */ 54 | export interface FieldInfo { 55 | catalog: string; 56 | schema: string; 57 | table: string; 58 | originTable: string; 59 | name: string; 60 | originName: string; 61 | encoding: number; 62 | fieldLen: number; 63 | fieldType: number; 64 | fieldFlag: number; 65 | decimals: number; 66 | defaultVal: string; 67 | } 68 | 69 | export class Connection { } 70 | 71 | export interface TransactionProcessor { 72 | (connection: Connection): Promise; 73 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Cloudflare Workers + MySQL 2 | 3 | This repo contains example code and a MySQL driver that can be used in any Workers project. If you 4 | are interested in using the driver _outside_ of this template, copy the `driver/mysql` module 5 | into your project's `node_modules` or directly alongside your source. 6 | 7 | ## Usage 8 | 9 | Before you start, please refer to the **[official tutorial](https://developers.cloudflare.com/workers/tutorials/query-postgres-from-workers-using-database-connectors)**. 10 | 11 | ```typescript 12 | const mysql = new Client() 13 | const mysqlClient = await mysql.connect({ 14 | username: '', 15 | db: '', 16 | // hostname is the full URL to your pre-created Cloudflare Tunnel, see documentation here: 17 | // https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/create-tunnel 18 | hostname: env.TUNNEL_HOST || 'https://dev.example.com', 19 | password: env.DATABASE_PASSWORD, // use a secret to store passwords 20 | }) 21 | ``` 22 | 23 | **Please Note:** 24 | - you must use this config object format vs. a database connection string 25 | - the `hostname` property must be the URL to your Cloudflare Tunnel, _NOT_ your database host 26 | - your Tunnel will be configured to connect to your database host 27 | 28 | ## Running the MySQL Demo 29 | 30 | `mysql/docker-compose.yml` 31 | 32 | This docker-compose composition will get you up and running with a local instance of `mysql` and a 33 | copy of `cloudflared` to enable your applications to securely connect through an encrypted tunnel. 34 | Unlike the PostgreSQL example, this does not contain any server-side connection pool, but you can 35 | configure one behind `cloudflared` should it be necessary. 36 | 37 | ### Usage 38 | 39 | > from within `scripts/mysql`, run: 40 | 41 | 1. **Create credentials file (first time only)** 42 | ```sh 43 | docker run -v ~/.cloudflared:/etc/cloudflared cloudflare/cloudflared:2021.10.5 login 44 | ``` 45 | 46 | 2. **Start a local dev stack (cloudflared/mysql)** 47 | ```sh 48 | TUNNEL_HOSTNAME=dev.example.com docker-compose up 49 | ``` -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | - Using welcoming and inclusive language 18 | - Being respectful of differing viewpoints and experiences 19 | - Gracefully accepting constructive criticism 20 | - Focusing on what is best for the community 21 | - Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | - The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | - Trolling, insulting/derogatory comments, and personal or political attacks 28 | - Public or private harassment 29 | - Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | - Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at ag_dubs@cloudflare.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /src/deno/buffer.js: -------------------------------------------------------------------------------- 1 | class DenoStdInternalError extends Error { 2 | constructor(message){ 3 | super(message); 4 | this.name = "DenoStdInternalError"; 5 | } 6 | } 7 | function assert(expr, msg = "") { 8 | if (!expr) { 9 | throw new DenoStdInternalError(msg); 10 | } 11 | } 12 | function copy(src, dst, off = 0) { 13 | off = Math.max(0, Math.min(off, dst.byteLength)); 14 | const dstBytesAvailable = dst.byteLength - off; 15 | if (src.byteLength > dstBytesAvailable) { 16 | src = src.subarray(0, dstBytesAvailable); 17 | } 18 | dst.set(src, off); 19 | return src.byteLength; 20 | } 21 | const MIN_READ = 32 * 1024; 22 | const MAX_SIZE = 2 ** 32 - 2; 23 | class Buffer1 { 24 | #buf; 25 | #off = 0; 26 | constructor(ab){ 27 | this.#buf = ab === undefined ? new Uint8Array(0) : new Uint8Array(ab); 28 | } 29 | bytes(options = { 30 | copy: true 31 | }) { 32 | if (options.copy === false) return this.#buf.subarray(this.#off); 33 | return this.#buf.slice(this.#off); 34 | } 35 | empty() { 36 | return this.#buf.byteLength <= this.#off; 37 | } 38 | get length() { 39 | return this.#buf.byteLength - this.#off; 40 | } 41 | get capacity() { 42 | return this.#buf.buffer.byteLength; 43 | } 44 | truncate(n) { 45 | if (n === 0) { 46 | this.reset(); 47 | return; 48 | } 49 | if (n < 0 || n > this.length) { 50 | throw Error("bytes.Buffer: truncation out of range"); 51 | } 52 | this.#reslice(this.#off + n); 53 | } 54 | reset() { 55 | this.#reslice(0); 56 | this.#off = 0; 57 | } 58 | #tryGrowByReslice(n) { 59 | const l = this.#buf.byteLength; 60 | if (n <= this.capacity - l) { 61 | this.#reslice(l + n); 62 | return l; 63 | } 64 | return -1; 65 | } 66 | #reslice(len) { 67 | assert(len <= this.#buf.buffer.byteLength); 68 | this.#buf = new Uint8Array(this.#buf.buffer, 0, len); 69 | } 70 | readSync(p) { 71 | if (this.empty()) { 72 | this.reset(); 73 | if (p.byteLength === 0) { 74 | return 0; 75 | } 76 | return null; 77 | } 78 | const nread = copy(this.#buf.subarray(this.#off), p); 79 | this.#off += nread; 80 | return nread; 81 | } 82 | read(p) { 83 | const rr = this.readSync(p); 84 | return Promise.resolve(rr); 85 | } 86 | writeSync(p) { 87 | const m = this.#grow(p.byteLength); 88 | return copy(p, this.#buf, m); 89 | } 90 | write(p) { 91 | const n = this.writeSync(p); 92 | return Promise.resolve(n); 93 | } 94 | #grow(n) { 95 | const m = this.length; 96 | if (m === 0 && this.#off !== 0) { 97 | this.reset(); 98 | } 99 | const i = this.#tryGrowByReslice(n); 100 | if (i >= 0) { 101 | return i; 102 | } 103 | const c = this.capacity; 104 | if (n <= Math.floor(c / 2) - m) { 105 | copy(this.#buf.subarray(this.#off), this.#buf); 106 | } else if (c + n > MAX_SIZE) { 107 | throw new Error("The buffer cannot be grown beyond the maximum size."); 108 | } else { 109 | const buf = new Uint8Array(Math.min(2 * c + n, MAX_SIZE)); 110 | copy(this.#buf.subarray(this.#off), buf); 111 | this.#buf = buf; 112 | } 113 | this.#off = 0; 114 | this.#reslice(Math.min(m + n, MAX_SIZE)); 115 | return m; 116 | } 117 | grow(n) { 118 | if (n < 0) { 119 | throw Error("Buffer.grow: negative count"); 120 | } 121 | const m = this.#grow(n); 122 | this.#reslice(m); 123 | } 124 | async readFrom(r) { 125 | let n = 0; 126 | const tmp = new Uint8Array(MIN_READ); 127 | while(true){ 128 | const shouldGrow = this.capacity - this.length < MIN_READ; 129 | const buf = shouldGrow ? tmp : new Uint8Array(this.#buf.buffer, this.length); 130 | const nread = await r.read(buf); 131 | if (nread === null) { 132 | return n; 133 | } 134 | if (shouldGrow) this.writeSync(buf.subarray(0, nread)); 135 | else this.#reslice(this.length + nread); 136 | n += nread; 137 | } 138 | } 139 | readFromSync(r) { 140 | let n = 0; 141 | const tmp = new Uint8Array(MIN_READ); 142 | while(true){ 143 | const shouldGrow = this.capacity - this.length < MIN_READ; 144 | const buf = shouldGrow ? tmp : new Uint8Array(this.#buf.buffer, this.length); 145 | const nread = r.readSync(buf); 146 | if (nread === null) { 147 | return n; 148 | } 149 | if (shouldGrow) this.writeSync(buf.subarray(0, nread)); 150 | else this.#reslice(this.length + nread); 151 | n += nread; 152 | } 153 | } 154 | } 155 | // export { Buffer1 as Buffer }; 156 | export const Buffer = Buffer1; 157 | -------------------------------------------------------------------------------- /src/deno/workers-override.ts: -------------------------------------------------------------------------------- 1 | import { Buffer } from './buffer' 2 | import { Deferred, deferred } from './deferred' 3 | 4 | namespace Deno { 5 | export interface Reader { 6 | read(p: Uint8Array): Promise 7 | } 8 | 9 | export interface ReaderSync { 10 | readSync(p: Uint8Array): number | null 11 | } 12 | 13 | export interface Writer { 14 | write(p: Uint8Array): Promise 15 | } 16 | 17 | export interface WriterSync { 18 | writeSync(p: Uint8Array): number 19 | } 20 | 21 | export interface Closer { 22 | close(): void 23 | } 24 | 25 | export enum SeekMode { 26 | Start = 0, 27 | Current = 1, 28 | End = 2, 29 | } 30 | export interface Seeker { 31 | seek(offset: number, whence: SeekMode): Promise 32 | } 33 | export interface SeekerSync { 34 | seekSync(offset: number, whence: SeekMode): number 35 | } 36 | 37 | export interface ConnectOptions { 38 | /** The port to connect to. */ 39 | port: number 40 | /** A literal IP address or host name that can be resolved to an IP address. 41 | * If not specified, defaults to `127.0.0.1`. */ 42 | hostname?: string 43 | transport?: 'tcp' 44 | } 45 | 46 | export interface NetAddr { 47 | transport: 'tcp' | 'udp' 48 | hostname: string 49 | port: number 50 | } 51 | 52 | export interface UnixAddr { 53 | transport: 'unix' | 'unixpacket' 54 | path: string 55 | } 56 | 57 | export type Addr = NetAddr | UnixAddr 58 | 59 | export interface Conn extends Reader, Writer, Closer { 60 | /** The local address of the connection. */ 61 | readonly localAddr: Addr 62 | /** The remote address of the connection. */ 63 | readonly remoteAddr: Addr 64 | /** The resource ID of the connection. */ 65 | readonly rid: number 66 | /** Shuts down (`shutdown(2)`) the write side of the connection. Most 67 | * callers should just use `close()`. */ 68 | closeWrite(): Promise 69 | } 70 | 71 | export class TcpOverWebsocketConn implements Conn { 72 | localAddr: Addr = { transport: 'tcp', hostname: 'localhost', port: 5432 } 73 | remoteAddr: Addr = { transport: 'tcp', hostname: 'localhost', port: 5432 } 74 | rid: number = 1 75 | 76 | ws: WebSocket 77 | buffer: Buffer 78 | empty_notifier: Deferred 79 | 80 | constructor(ws: WebSocket) { 81 | this.ws = ws 82 | 83 | // @ts-ignore 84 | this.buffer = new Buffer() 85 | 86 | this.empty_notifier = deferred() 87 | 88 | // Incoming messages get written to a buffer 89 | this.ws.addEventListener('message', msg => { 90 | const data = new Uint8Array(msg.data) 91 | 92 | // @ts-ignore 93 | this.buffer.write(data).then(() => { 94 | this.empty_notifier.resolve() 95 | }) 96 | }) 97 | 98 | this.ws.addEventListener('error', err => { 99 | console.log('ws error') 100 | }) 101 | this.ws.addEventListener('close', () => { 102 | this.empty_notifier.resolve() 103 | console.log('ws close') 104 | }) 105 | this.ws.addEventListener('open', () => { 106 | console.log('ws open') 107 | }) 108 | } 109 | 110 | closeWrite(): Promise { 111 | throw new Error('Method not implemented.') 112 | } 113 | 114 | // Reads up to p.length bytes from our buffer 115 | read(p: Uint8Array): Promise { 116 | //If the buffer is empty, we need to block until there is data 117 | if (this.buffer.length === 0) { 118 | return new Promise(async (resolve, reject) => { 119 | this.empty_notifier = deferred() 120 | await this.empty_notifier 121 | 122 | if (this.buffer.length === 0) { 123 | reject(0) // TODO what is the correct way to handle errors 124 | } else { 125 | // @ts-ignore 126 | const bytes = await this.buffer.read(p) 127 | resolve(bytes) 128 | } 129 | }) 130 | } else { 131 | // @ts-ignore 132 | return this.buffer.read(p) 133 | } 134 | } 135 | 136 | write(p: Uint8Array): Promise { 137 | this.ws.send(p) 138 | 139 | // We have to assume the socket buffered our entire message 140 | return Promise.resolve(p.byteLength) 141 | } 142 | 143 | close(): void { 144 | this.ws.close() 145 | } 146 | } 147 | 148 | export function startTls(connection: Conn): Promise { 149 | return Promise.resolve(connection) 150 | } 151 | 152 | export function connect(options: ConnectOptions): Promise { 153 | return new Promise((resolve, reject) => { 154 | // Allows user to connect to Tunnel unauthenticated, or with a Service Token from Access 155 | // by setting the CF_CLIENT_ID and CF_CLIENT_SECRET secrets in their Worker 156 | let cfAccess = {} 157 | 158 | // @ts-ignore 159 | if (globalThis.CF_CLIENT_ID && globalThis.CF_CLIENT_SECRET) { 160 | cfAccess = { 161 | // @ts-ignore 162 | 'CF-Access-Client-ID': globalThis.CF_CLIENT_ID, 163 | // @ts-ignore 164 | 'CF-Access-Client-Secret': globalThis.CF_CLIENT_SECRET, 165 | } 166 | } 167 | if (options.hostname === undefined) { 168 | throw new Error('Tunnel hostname undefined') 169 | } 170 | const resp = fetch(options.hostname, { 171 | headers: { 172 | ...cfAccess, 173 | Upgrade: 'websocket', 174 | }, 175 | }) 176 | .then(resp => { 177 | // N.B. `webSocket` property exists on Workers `Response` type. 178 | // @ts-ignore 179 | if (resp.webSocket) { 180 | // @ts-ignore 181 | resp.webSocket.accept() 182 | // @ts-ignore 183 | let c = new TcpOverWebsocketConn(resp.webSocket) 184 | resolve(c) 185 | } else { 186 | throw new Error( 187 | `Failed to create WebSocket connection: ${resp.status} ${resp.statusText}`, 188 | ) 189 | } 190 | }) 191 | .catch(e => { 192 | console.log((e as Error).message) 193 | reject(e) //TODO error handling 194 | }) 195 | 196 | return resp 197 | }) 198 | } 199 | 200 | export namespace env { 201 | export function get(s: string) { 202 | // TODO env variables come from env context, which we do not have here 203 | return undefined 204 | } 205 | } 206 | 207 | export namespace errors { 208 | export class NotFound extends Error {} 209 | export class PermissionDenied extends Error {} 210 | export class ConnectionRefused extends Error {} 211 | export class ConnectionReset extends Error {} 212 | export class ConnectionAborted extends Error {} 213 | export class NotConnected extends Error {} 214 | export class AddrInUse extends Error {} 215 | export class AddrNotAvailable extends Error {} 216 | export class BrokenPipe extends Error {} 217 | export class AlreadyExists extends Error {} 218 | export class InvalidData extends Error {} 219 | export class TimedOut extends Error {} 220 | export class Interrupted extends Error {} 221 | export class WriteZero extends Error {} 222 | export class UnexpectedEof extends Error {} 223 | export class BadResource extends Error {} 224 | export class Http extends Error {} 225 | export class Busy extends Error {} 226 | } 227 | } 228 | 229 | // @ts-expect-error ignore 230 | globalThis.Deno = Deno 231 | 232 | export class FinalizationRegistry { 233 | constructor() {} 234 | 235 | register() {} 236 | unregister() {} 237 | } 238 | 239 | // @ts-ignore 240 | globalThis.FinalizationRegistry = FinalizationRegistry 241 | -------------------------------------------------------------------------------- /LICENSE_APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | -------------------------------------------------------------------------------- /src/driver/mysql/index.js: -------------------------------------------------------------------------------- 1 | class ConnnectionError extends Error { 2 | constructor(msg){ 3 | super(msg); 4 | } 5 | } 6 | class WriteError extends ConnnectionError { 7 | constructor(msg){ 8 | super(msg); 9 | } 10 | } 11 | class ReadError extends ConnnectionError { 12 | constructor(msg){ 13 | super(msg); 14 | } 15 | } 16 | class ResponseTimeoutError extends ConnnectionError { 17 | constructor(msg){ 18 | super(msg); 19 | } 20 | } 21 | class ProtocolError extends ConnnectionError { 22 | constructor(msg){ 23 | super(msg); 24 | } 25 | } 26 | function deferred() { 27 | let methods; 28 | let state = "pending"; 29 | const promise = new Promise((resolve, reject)=>{ 30 | methods = { 31 | async resolve (value) { 32 | await value; 33 | state = "fulfilled"; 34 | resolve(value); 35 | }, 36 | reject (reason) { 37 | state = "rejected"; 38 | reject(reason); 39 | } 40 | }; 41 | }); 42 | Object.defineProperty(promise, "state", { 43 | get: ()=>state 44 | }); 45 | return Object.assign(promise, methods); 46 | } 47 | const noColor = globalThis.Deno?.noColor ?? true; 48 | let enabled = !noColor; 49 | function code(open, close) { 50 | return { 51 | open: `\x1b[${open.join(";")}m`, 52 | close: `\x1b[${close}m`, 53 | regexp: new RegExp(`\\x1b\\[${close}m`, "g") 54 | }; 55 | } 56 | function run(str, code) { 57 | return enabled ? `${code.open}${str.replace(code.regexp, code.open)}${code.close}` : str; 58 | } 59 | function green(str) { 60 | return run(str, code([ 61 | 32 62 | ], 39)); 63 | } 64 | new RegExp([ 65 | "[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)", 66 | "(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))", 67 | ].join("|"), "g"); 68 | function format(data) { 69 | const bytes = new Uint8Array(data.buffer); 70 | let out = " +-------------------------------------------------+\n"; 71 | out += ` |${green(" 0 1 2 3 4 5 6 7 8 9 a b c d e f ")}|\n`; 72 | out += "+--------+-------------------------------------------------+----------------+\n"; 73 | const lineCount = Math.ceil(bytes.length / 16); 74 | for(let line = 0; line < lineCount; line++){ 75 | const start = line * 16; 76 | const addr = start.toString(16).padStart(8, "0"); 77 | const lineBytes = bytes.slice(start, start + 16); 78 | out += `|${green(addr)}| `; 79 | lineBytes.forEach((__byte)=>out += __byte.toString(16).padStart(2, "0") + " " 80 | ); 81 | if (lineBytes.length < 16) { 82 | out += " ".repeat(16 - lineBytes.length); 83 | } 84 | out += "|"; 85 | lineBytes.forEach(function(__byte) { 86 | return out += __byte > 31 && __byte < 127 ? green(String.fromCharCode(__byte)) : "."; 87 | }); 88 | if (lineBytes.length < 16) { 89 | out += " ".repeat(16 - lineBytes.length); 90 | } 91 | out += "|\n"; 92 | } 93 | out += "+--------+-------------------------------------------------+----------------+"; 94 | return out; 95 | } 96 | const base64abc = [ 97 | "A", 98 | "B", 99 | "C", 100 | "D", 101 | "E", 102 | "F", 103 | "G", 104 | "H", 105 | "I", 106 | "J", 107 | "K", 108 | "L", 109 | "M", 110 | "N", 111 | "O", 112 | "P", 113 | "Q", 114 | "R", 115 | "S", 116 | "T", 117 | "U", 118 | "V", 119 | "W", 120 | "X", 121 | "Y", 122 | "Z", 123 | "a", 124 | "b", 125 | "c", 126 | "d", 127 | "e", 128 | "f", 129 | "g", 130 | "h", 131 | "i", 132 | "j", 133 | "k", 134 | "l", 135 | "m", 136 | "n", 137 | "o", 138 | "p", 139 | "q", 140 | "r", 141 | "s", 142 | "t", 143 | "u", 144 | "v", 145 | "w", 146 | "x", 147 | "y", 148 | "z", 149 | "0", 150 | "1", 151 | "2", 152 | "3", 153 | "4", 154 | "5", 155 | "6", 156 | "7", 157 | "8", 158 | "9", 159 | "+", 160 | "/" 161 | ]; 162 | function encode(data) { 163 | const uint8 = typeof data === "string" ? new TextEncoder().encode(data) : data instanceof Uint8Array ? data : new Uint8Array(data); 164 | let result = "", i; 165 | const l = uint8.length; 166 | for(i = 2; i < l; i += 3){ 167 | result += base64abc[uint8[i - 2] >> 2]; 168 | result += base64abc[(uint8[i - 2] & 3) << 4 | uint8[i - 1] >> 4]; 169 | result += base64abc[(uint8[i - 1] & 15) << 2 | uint8[i] >> 6]; 170 | result += base64abc[uint8[i] & 63]; 171 | } 172 | if (i === l + 1) { 173 | result += base64abc[uint8[i - 2] >> 2]; 174 | result += base64abc[(uint8[i - 2] & 3) << 4]; 175 | result += "=="; 176 | } 177 | if (i === l) { 178 | result += base64abc[uint8[i - 2] >> 2]; 179 | result += base64abc[(uint8[i - 2] & 3) << 4 | uint8[i - 1] >> 4]; 180 | result += base64abc[(uint8[i - 1] & 15) << 2]; 181 | result += "="; 182 | } 183 | return result; 184 | } 185 | function decode(b64) { 186 | const binString = atob(b64); 187 | const size = binString.length; 188 | const bytes = new Uint8Array(size); 189 | for(let i = 0; i < size; i++){ 190 | bytes[i] = binString.charCodeAt(i); 191 | } 192 | return bytes; 193 | } 194 | let cachedTextDecoder = new TextDecoder("utf-8", { 195 | ignoreBOM: true, 196 | fatal: true 197 | }); 198 | cachedTextDecoder.decode(); 199 | let cachegetUint8Memory0 = null; 200 | function getUint8Memory0() { 201 | if (cachegetUint8Memory0 === null || cachegetUint8Memory0.buffer !== wasm.memory.buffer) { 202 | cachegetUint8Memory0 = new Uint8Array(wasm.memory.buffer); 203 | } 204 | return cachegetUint8Memory0; 205 | } 206 | function getStringFromWasm0(ptr, len) { 207 | return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len)); 208 | } 209 | const heap = new Array(32).fill(undefined); 210 | heap.push(undefined, null, true, false); 211 | let heap_next = heap.length; 212 | function addHeapObject(obj) { 213 | if (heap_next === heap.length) heap.push(heap.length + 1); 214 | const idx = heap_next; 215 | heap_next = heap[idx]; 216 | heap[idx] = obj; 217 | return idx; 218 | } 219 | function getObject(idx) { 220 | return heap[idx]; 221 | } 222 | function dropObject(idx) { 223 | if (idx < 36) return; 224 | heap[idx] = heap_next; 225 | heap_next = idx; 226 | } 227 | function takeObject(idx) { 228 | const ret = getObject(idx); 229 | dropObject(idx); 230 | return ret; 231 | } 232 | let WASM_VECTOR_LEN = 0; 233 | let cachedTextEncoder = new TextEncoder("utf-8"); 234 | const encodeString = function(arg, view) { 235 | return cachedTextEncoder.encodeInto(arg, view); 236 | }; 237 | function passStringToWasm0(arg, malloc, realloc) { 238 | if (realloc === undefined) { 239 | const buf = cachedTextEncoder.encode(arg); 240 | const ptr = malloc(buf.length); 241 | getUint8Memory0().subarray(ptr, ptr + buf.length).set(buf); 242 | WASM_VECTOR_LEN = buf.length; 243 | return ptr; 244 | } 245 | let len = arg.length; 246 | let ptr = malloc(len); 247 | const mem = getUint8Memory0(); 248 | let offset = 0; 249 | for(; offset < len; offset++){ 250 | const code = arg.charCodeAt(offset); 251 | if (code > 127) break; 252 | mem[ptr + offset] = code; 253 | } 254 | if (offset !== len) { 255 | if (offset !== 0) { 256 | arg = arg.slice(offset); 257 | } 258 | ptr = realloc(ptr, len, len = offset + arg.length * 3); 259 | const view = getUint8Memory0().subarray(ptr + offset, ptr + len); 260 | const ret = encodeString(arg, view); 261 | offset += ret.written; 262 | } 263 | WASM_VECTOR_LEN = offset; 264 | return ptr; 265 | } 266 | function create_hash(algorithm) { 267 | var ptr0 = passStringToWasm0(algorithm, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); 268 | var len0 = WASM_VECTOR_LEN; 269 | var ret = wasm.create_hash(ptr0, len0); 270 | return DenoHash.__wrap(ret); 271 | } 272 | function _assertClass(instance, klass) { 273 | if (!(instance instanceof klass)) { 274 | throw new Error(`expected instance of ${klass.name}`); 275 | } 276 | return instance.ptr; 277 | } 278 | function passArray8ToWasm0(arg, malloc) { 279 | const ptr = malloc(arg.length * 1); 280 | getUint8Memory0().set(arg, ptr / 1); 281 | WASM_VECTOR_LEN = arg.length; 282 | return ptr; 283 | } 284 | function update_hash(hash, data) { 285 | _assertClass(hash, DenoHash); 286 | var ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc); 287 | var len0 = WASM_VECTOR_LEN; 288 | wasm.update_hash(hash.ptr, ptr0, len0); 289 | } 290 | let cachegetInt32Memory0 = null; 291 | function getInt32Memory0() { 292 | if (cachegetInt32Memory0 === null || cachegetInt32Memory0.buffer !== wasm.memory.buffer) { 293 | cachegetInt32Memory0 = new Int32Array(wasm.memory.buffer); 294 | } 295 | return cachegetInt32Memory0; 296 | } 297 | function getArrayU8FromWasm0(ptr, len) { 298 | return getUint8Memory0().subarray(ptr / 1, ptr / 1 + len); 299 | } 300 | function digest_hash(hash) { 301 | try { 302 | const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); 303 | _assertClass(hash, DenoHash); 304 | wasm.digest_hash(retptr, hash.ptr); 305 | var r0 = getInt32Memory0()[retptr / 4 + 0]; 306 | var r1 = getInt32Memory0()[retptr / 4 + 1]; 307 | var v0 = getArrayU8FromWasm0(r0, r1).slice(); 308 | wasm.__wbindgen_free(r0, r1 * 1); 309 | return v0; 310 | } finally{ 311 | wasm.__wbindgen_add_to_stack_pointer(16); 312 | } 313 | } 314 | const DenoHashFinalization = new FinalizationRegistry((ptr)=>wasm.__wbg_denohash_free(ptr) 315 | ); 316 | class DenoHash { 317 | static __wrap(ptr) { 318 | const obj = Object.create(DenoHash.prototype); 319 | obj.ptr = ptr; 320 | DenoHashFinalization.register(obj, obj.ptr, obj); 321 | return obj; 322 | } 323 | __destroy_into_raw() { 324 | const ptr = this.ptr; 325 | this.ptr = 0; 326 | DenoHashFinalization.unregister(this); 327 | return ptr; 328 | } 329 | free() { 330 | const ptr = this.__destroy_into_raw(); 331 | wasm.__wbg_denohash_free(ptr); 332 | } 333 | } 334 | const imports = { 335 | __wbindgen_placeholder__: { 336 | __wbindgen_string_new: function(arg0, arg1) { 337 | var ret = getStringFromWasm0(arg0, arg1); 338 | return addHeapObject(ret); 339 | }, 340 | __wbindgen_throw: function(arg0, arg1) { 341 | throw new Error(getStringFromWasm0(arg0, arg1)); 342 | }, 343 | __wbindgen_rethrow: function(arg0) { 344 | throw takeObject(arg0); 345 | } 346 | } 347 | }; 348 | import wasmModule from './62edfb469c0dbacd90273cf9a0d7a478.wasm'; 349 | const wasmInstance = new WebAssembly.Instance(wasmModule, imports); 350 | const wasm = wasmInstance.exports; 351 | const hexTable = new TextEncoder().encode("0123456789abcdef"); 352 | function encode1(src) { 353 | const dst = new Uint8Array(src.length * 2); 354 | for(let i = 0; i < dst.length; i++){ 355 | const v = src[i]; 356 | dst[i * 2] = hexTable[v >> 4]; 357 | dst[i * 2 + 1] = hexTable[v & 15]; 358 | } 359 | return dst; 360 | } 361 | class Hash { 362 | #hash; 363 | #digested; 364 | constructor(algorithm){ 365 | this.#hash = create_hash(algorithm); 366 | this.#digested = false; 367 | } 368 | update(message) { 369 | let view; 370 | if (message instanceof Uint8Array) { 371 | view = message; 372 | } else if (typeof message === "string") { 373 | view = new TextEncoder().encode(message); 374 | } else if (ArrayBuffer.isView(message)) { 375 | view = new Uint8Array(message.buffer, message.byteOffset, message.byteLength); 376 | } else if (message instanceof ArrayBuffer) { 377 | view = new Uint8Array(message); 378 | } else { 379 | throw new Error("hash: `data` is invalid type"); 380 | } 381 | const chunkSize = 65536; 382 | for(let offset = 0; offset < view.byteLength; offset += chunkSize){ 383 | update_hash(this.#hash, new Uint8Array(view.buffer, view.byteOffset + offset, Math.min(65536, view.byteLength - offset))); 384 | } 385 | return this; 386 | } 387 | digest() { 388 | if (this.#digested) throw new Error("hash: already digested"); 389 | this.#digested = true; 390 | return digest_hash(this.#hash); 391 | } 392 | toString(format = "hex") { 393 | const finalized = new Uint8Array(this.digest()); 394 | switch(format){ 395 | case "hex": 396 | return new TextDecoder().decode(encode1(finalized)); 397 | case "base64": 398 | return encode(finalized); 399 | default: 400 | throw new Error("hash: invalid format"); 401 | } 402 | } 403 | } 404 | function createHash(algorithm) { 405 | return new Hash(algorithm); 406 | } 407 | function replaceParams(sql, params) { 408 | if (!params) return sql; 409 | let paramIndex = 0; 410 | sql = sql.replace(/('[^'\\]*(?:\\.[^'\\]*)*')|("[^"\\]*(?:\\.[^"\\]*)*")|(\?\?)|(\?)/g, (str)=>{ 411 | if (paramIndex >= params.length) return str; 412 | if (/".*"/g.test(str) || /'.*'/g.test(str)) { 413 | return str; 414 | } 415 | if (str === "??") { 416 | const val = params[paramIndex++]; 417 | if (val instanceof Array) { 418 | return `(${val.map((item)=>replaceParams("??", [ 419 | item 420 | ]) 421 | ).join(",")})`; 422 | } else if (val === "*") { 423 | return val; 424 | } else if (typeof val === "string" && val.includes(".")) { 425 | const _arr = val.split("."); 426 | return replaceParams(_arr.map(()=>"??" 427 | ).join("."), _arr); 428 | } else if (typeof val === "string" && (val.includes(" as ") || val.includes(" AS "))) { 429 | const newVal = val.replace(" as ", " AS "); 430 | const _arr = newVal.split(" AS "); 431 | return replaceParams(_arr.map(()=>"??" 432 | ).join(" AS "), _arr); 433 | } else { 434 | return [ 435 | "`", 436 | val, 437 | "`" 438 | ].join(""); 439 | } 440 | } 441 | const val = params[paramIndex++]; 442 | if (val === null) return "NULL"; 443 | switch(typeof val){ 444 | case "object": 445 | if (val instanceof Date) return `"${formatDate(val)}"`; 446 | if (val instanceof Array) { 447 | return `(${val.map((item)=>replaceParams("?", [ 448 | item 449 | ]) 450 | ).join(",")})`; 451 | } 452 | case "string": 453 | return `"${escapeString(val)}"`; 454 | case "undefined": 455 | return "NULL"; 456 | case "number": 457 | case "boolean": 458 | default: 459 | return val; 460 | } 461 | }); 462 | return sql; 463 | } 464 | function formatDate(date) { 465 | const year = date.getFullYear(); 466 | const month = (date.getMonth() + 1).toString().padStart(2, "0"); 467 | const days = date.getDate().toString().padStart(2, "0"); 468 | const hours = date.getHours().toString().padStart(2, "0"); 469 | const minutes = date.getMinutes().toString().padStart(2, "0"); 470 | const seconds = date.getSeconds().toString().padStart(2, "0"); 471 | const milliseconds = date.getMilliseconds().toString().padStart(3, "0"); 472 | return `${year}-${month}-${days} ${hours}:${minutes}:${seconds}.${milliseconds}`; 473 | } 474 | function escapeString(str) { 475 | return str.replaceAll("\\", "\\\\").replaceAll('"', '\\"'); 476 | } 477 | var LogLevels; 478 | (function(LogLevels) { 479 | LogLevels[LogLevels["NOTSET"] = 0] = "NOTSET"; 480 | LogLevels[LogLevels["DEBUG"] = 10] = "DEBUG"; 481 | LogLevels[LogLevels["INFO"] = 20] = "INFO"; 482 | LogLevels[LogLevels["WARNING"] = 30] = "WARNING"; 483 | LogLevels[LogLevels["ERROR"] = 40] = "ERROR"; 484 | LogLevels[LogLevels["CRITICAL"] = 50] = "CRITICAL"; 485 | })(LogLevels || (LogLevels = { 486 | })); 487 | Object.keys(LogLevels).filter((key)=>isNaN(Number(key)) 488 | ); 489 | const byLevel = { 490 | [String(LogLevels.NOTSET)]: "NOTSET", 491 | [String(LogLevels.DEBUG)]: "DEBUG", 492 | [String(LogLevels.INFO)]: "INFO", 493 | [String(LogLevels.WARNING)]: "WARNING", 494 | [String(LogLevels.ERROR)]: "ERROR", 495 | [String(LogLevels.CRITICAL)]: "CRITICAL" 496 | }; 497 | function getLevelByName(name) { 498 | switch(name){ 499 | case "NOTSET": 500 | return LogLevels.NOTSET; 501 | case "DEBUG": 502 | return LogLevels.DEBUG; 503 | case "INFO": 504 | return LogLevels.INFO; 505 | case "WARNING": 506 | return LogLevels.WARNING; 507 | case "ERROR": 508 | return LogLevels.ERROR; 509 | case "CRITICAL": 510 | return LogLevels.CRITICAL; 511 | default: 512 | throw new Error(`no log level found for "${name}"`); 513 | } 514 | } 515 | function getLevelName(level) { 516 | const levelName = byLevel[level]; 517 | if (levelName) { 518 | return levelName; 519 | } 520 | throw new Error(`no level name found for level: ${level}`); 521 | } 522 | class LogRecord { 523 | msg; 524 | #args; 525 | #datetime; 526 | level; 527 | levelName; 528 | loggerName; 529 | constructor(options){ 530 | this.msg = options.msg; 531 | this.#args = [ 532 | ...options.args 533 | ]; 534 | this.level = options.level; 535 | this.loggerName = options.loggerName; 536 | this.#datetime = new Date(); 537 | this.levelName = getLevelName(options.level); 538 | } 539 | get args() { 540 | return [ 541 | ...this.#args 542 | ]; 543 | } 544 | get datetime() { 545 | return new Date(this.#datetime.getTime()); 546 | } 547 | } 548 | class Logger { 549 | #level; 550 | #handlers; 551 | #loggerName; 552 | constructor(loggerName, levelName, options = { 553 | }){ 554 | this.#loggerName = loggerName; 555 | this.#level = getLevelByName(levelName); 556 | this.#handlers = options.handlers || []; 557 | } 558 | get level() { 559 | return this.#level; 560 | } 561 | set level(level) { 562 | this.#level = level; 563 | } 564 | get levelName() { 565 | return getLevelName(this.#level); 566 | } 567 | set levelName(levelName) { 568 | this.#level = getLevelByName(levelName); 569 | } 570 | get loggerName() { 571 | return this.#loggerName; 572 | } 573 | set handlers(hndls) { 574 | this.#handlers = hndls; 575 | } 576 | get handlers() { 577 | return this.#handlers; 578 | } 579 | _log(level, msg, ...args) { 580 | if (this.level > level) { 581 | return msg instanceof Function ? undefined : msg; 582 | } 583 | let fnResult; 584 | let logMessage; 585 | if (msg instanceof Function) { 586 | fnResult = msg(); 587 | logMessage = this.asString(fnResult); 588 | } else { 589 | logMessage = this.asString(msg); 590 | } 591 | const record = new LogRecord({ 592 | msg: logMessage, 593 | args: args, 594 | level: level, 595 | loggerName: this.loggerName 596 | }); 597 | this.#handlers.forEach((handler)=>{ 598 | handler.handle(record); 599 | }); 600 | return msg instanceof Function ? fnResult : msg; 601 | } 602 | asString(data) { 603 | if (typeof data === "string") { 604 | return data; 605 | } else if (data === null || typeof data === "number" || typeof data === "bigint" || typeof data === "boolean" || typeof data === "undefined" || typeof data === "symbol") { 606 | return String(data); 607 | } else if (data instanceof Error) { 608 | return data.stack; 609 | } else if (typeof data === "object") { 610 | return JSON.stringify(data); 611 | } 612 | return "undefined"; 613 | } 614 | debug(msg, ...args) { 615 | return this._log(LogLevels.DEBUG, msg, ...args); 616 | } 617 | info(msg, ...args) { 618 | return this._log(LogLevels.INFO, msg, ...args); 619 | } 620 | warning(msg, ...args) { 621 | return this._log(LogLevels.WARNING, msg, ...args); 622 | } 623 | error(msg, ...args) { 624 | return this._log(LogLevels.ERROR, msg, ...args); 625 | } 626 | critical(msg, ...args) { 627 | return this._log(LogLevels.CRITICAL, msg, ...args); 628 | } 629 | } 630 | const { Deno } = globalThis; 631 | const noColor1 = typeof Deno?.noColor === "boolean" ? Deno.noColor : true; 632 | let enabled1 = !noColor1; 633 | function code1(open, close) { 634 | return { 635 | open: `\x1b[${open.join(";")}m`, 636 | close: `\x1b[${close}m`, 637 | regexp: new RegExp(`\\x1b\\[${close}m`, "g") 638 | }; 639 | } 640 | function run1(str, code) { 641 | return enabled1 ? `${code.open}${str.replace(code.regexp, code.open)}${code.close}` : str; 642 | } 643 | function bold(str) { 644 | return run1(str, code1([ 645 | 1 646 | ], 22)); 647 | } 648 | function red(str) { 649 | return run1(str, code1([ 650 | 31 651 | ], 39)); 652 | } 653 | function yellow(str) { 654 | return run1(str, code1([ 655 | 33 656 | ], 39)); 657 | } 658 | function blue(str) { 659 | return run1(str, code1([ 660 | 34 661 | ], 39)); 662 | } 663 | new RegExp([ 664 | "[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)", 665 | "(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))", 666 | ].join("|"), "g"); 667 | async function exists(filePath) { 668 | try { 669 | await Deno.lstat(filePath); 670 | return true; 671 | } catch (err) { 672 | if (err instanceof Deno.errors.NotFound) { 673 | return false; 674 | } 675 | throw err; 676 | } 677 | } 678 | function existsSync(filePath) { 679 | try { 680 | Deno.lstatSync(filePath); 681 | return true; 682 | } catch (err) { 683 | if (err instanceof Deno.errors.NotFound) { 684 | return false; 685 | } 686 | throw err; 687 | } 688 | } 689 | function copy(src, dst, off = 0) { 690 | off = Math.max(0, Math.min(off, dst.byteLength)); 691 | const dstBytesAvailable = dst.byteLength - off; 692 | if (src.byteLength > dstBytesAvailable) { 693 | src = src.subarray(0, dstBytesAvailable); 694 | } 695 | dst.set(src, off); 696 | return src.byteLength; 697 | } 698 | class DenoStdInternalError extends Error { 699 | constructor(message){ 700 | super(message); 701 | this.name = "DenoStdInternalError"; 702 | } 703 | } 704 | function assert(expr, msg = "") { 705 | if (!expr) { 706 | throw new DenoStdInternalError(msg); 707 | } 708 | } 709 | var DiffType; 710 | (function(DiffType) { 711 | DiffType["removed"] = "removed"; 712 | DiffType["common"] = "common"; 713 | DiffType["added"] = "added"; 714 | })(DiffType || (DiffType = { 715 | })); 716 | async function writeAll(w, arr) { 717 | let nwritten = 0; 718 | while(nwritten < arr.length){ 719 | nwritten += await w.write(arr.subarray(nwritten)); 720 | } 721 | } 722 | function writeAllSync(w, arr) { 723 | let nwritten = 0; 724 | while(nwritten < arr.length){ 725 | nwritten += w.writeSync(arr.subarray(nwritten)); 726 | } 727 | } 728 | const DEFAULT_BUF_SIZE = 4096; 729 | const MIN_BUF_SIZE = 16; 730 | const CR = "\r".charCodeAt(0); 731 | const LF = "\n".charCodeAt(0); 732 | class BufferFullError extends Error { 733 | partial; 734 | name = "BufferFullError"; 735 | constructor(partial){ 736 | super("Buffer full"); 737 | this.partial = partial; 738 | } 739 | } 740 | class PartialReadError extends Error { 741 | name = "PartialReadError"; 742 | partial; 743 | constructor(){ 744 | super("Encountered UnexpectedEof, data only partially read"); 745 | } 746 | } 747 | class BufReader { 748 | buf; 749 | rd; 750 | r = 0; 751 | w = 0; 752 | eof = false; 753 | static create(r, size = 4096) { 754 | return r instanceof BufReader ? r : new BufReader(r, size); 755 | } 756 | constructor(rd, size = 4096){ 757 | if (size < 16) { 758 | size = MIN_BUF_SIZE; 759 | } 760 | this._reset(new Uint8Array(size), rd); 761 | } 762 | size() { 763 | return this.buf.byteLength; 764 | } 765 | buffered() { 766 | return this.w - this.r; 767 | } 768 | async _fill() { 769 | if (this.r > 0) { 770 | this.buf.copyWithin(0, this.r, this.w); 771 | this.w -= this.r; 772 | this.r = 0; 773 | } 774 | if (this.w >= this.buf.byteLength) { 775 | throw Error("bufio: tried to fill full buffer"); 776 | } 777 | for(let i = 100; i > 0; i--){ 778 | const rr = await this.rd.read(this.buf.subarray(this.w)); 779 | if (rr === null) { 780 | this.eof = true; 781 | return; 782 | } 783 | assert(rr >= 0, "negative read"); 784 | this.w += rr; 785 | if (rr > 0) { 786 | return; 787 | } 788 | } 789 | throw new Error(`No progress after ${100} read() calls`); 790 | } 791 | reset(r) { 792 | this._reset(this.buf, r); 793 | } 794 | _reset(buf, rd) { 795 | this.buf = buf; 796 | this.rd = rd; 797 | this.eof = false; 798 | } 799 | async read(p) { 800 | let rr = p.byteLength; 801 | if (p.byteLength === 0) return rr; 802 | if (this.r === this.w) { 803 | if (p.byteLength >= this.buf.byteLength) { 804 | const rr = await this.rd.read(p); 805 | const nread = rr ?? 0; 806 | assert(nread >= 0, "negative read"); 807 | return rr; 808 | } 809 | this.r = 0; 810 | this.w = 0; 811 | rr = await this.rd.read(this.buf); 812 | if (rr === 0 || rr === null) return rr; 813 | assert(rr >= 0, "negative read"); 814 | this.w += rr; 815 | } 816 | const copied = copy(this.buf.subarray(this.r, this.w), p, 0); 817 | this.r += copied; 818 | return copied; 819 | } 820 | async readFull(p) { 821 | let bytesRead = 0; 822 | while(bytesRead < p.length){ 823 | try { 824 | const rr = await this.read(p.subarray(bytesRead)); 825 | if (rr === null) { 826 | if (bytesRead === 0) { 827 | return null; 828 | } else { 829 | throw new PartialReadError(); 830 | } 831 | } 832 | bytesRead += rr; 833 | } catch (err) { 834 | err.partial = p.subarray(0, bytesRead); 835 | throw err; 836 | } 837 | } 838 | return p; 839 | } 840 | async readByte() { 841 | while(this.r === this.w){ 842 | if (this.eof) return null; 843 | await this._fill(); 844 | } 845 | const c = this.buf[this.r]; 846 | this.r++; 847 | return c; 848 | } 849 | async readString(delim) { 850 | if (delim.length !== 1) { 851 | throw new Error("Delimiter should be a single character"); 852 | } 853 | const buffer = await this.readSlice(delim.charCodeAt(0)); 854 | if (buffer === null) return null; 855 | return new TextDecoder().decode(buffer); 856 | } 857 | async readLine() { 858 | let line; 859 | try { 860 | line = await this.readSlice(LF); 861 | } catch (err) { 862 | if (err instanceof Deno.errors.BadResource) { 863 | throw err; 864 | } 865 | let { partial } = err; 866 | assert(partial instanceof Uint8Array, "bufio: caught error from `readSlice()` without `partial` property"); 867 | if (!(err instanceof BufferFullError)) { 868 | throw err; 869 | } 870 | if (!this.eof && partial.byteLength > 0 && partial[partial.byteLength - 1] === CR) { 871 | assert(this.r > 0, "bufio: tried to rewind past start of buffer"); 872 | this.r--; 873 | partial = partial.subarray(0, partial.byteLength - 1); 874 | } 875 | return { 876 | line: partial, 877 | more: !this.eof 878 | }; 879 | } 880 | if (line === null) { 881 | return null; 882 | } 883 | if (line.byteLength === 0) { 884 | return { 885 | line, 886 | more: false 887 | }; 888 | } 889 | if (line[line.byteLength - 1] == LF) { 890 | let drop = 1; 891 | if (line.byteLength > 1 && line[line.byteLength - 2] === CR) { 892 | drop = 2; 893 | } 894 | line = line.subarray(0, line.byteLength - drop); 895 | } 896 | return { 897 | line, 898 | more: false 899 | }; 900 | } 901 | async readSlice(delim) { 902 | let s = 0; 903 | let slice; 904 | while(true){ 905 | let i = this.buf.subarray(this.r + s, this.w).indexOf(delim); 906 | if (i >= 0) { 907 | i += s; 908 | slice = this.buf.subarray(this.r, this.r + i + 1); 909 | this.r += i + 1; 910 | break; 911 | } 912 | if (this.eof) { 913 | if (this.r === this.w) { 914 | return null; 915 | } 916 | slice = this.buf.subarray(this.r, this.w); 917 | this.r = this.w; 918 | break; 919 | } 920 | if (this.buffered() >= this.buf.byteLength) { 921 | this.r = this.w; 922 | const oldbuf = this.buf; 923 | const newbuf = this.buf.slice(0); 924 | this.buf = newbuf; 925 | throw new BufferFullError(oldbuf); 926 | } 927 | s = this.w - this.r; 928 | try { 929 | await this._fill(); 930 | } catch (err) { 931 | err.partial = slice; 932 | throw err; 933 | } 934 | } 935 | return slice; 936 | } 937 | async peek(n) { 938 | if (n < 0) { 939 | throw Error("negative count"); 940 | } 941 | let avail = this.w - this.r; 942 | while(avail < n && avail < this.buf.byteLength && !this.eof){ 943 | try { 944 | await this._fill(); 945 | } catch (err) { 946 | err.partial = this.buf.subarray(this.r, this.w); 947 | throw err; 948 | } 949 | avail = this.w - this.r; 950 | } 951 | if (avail === 0 && this.eof) { 952 | return null; 953 | } else if (avail < n && this.eof) { 954 | return this.buf.subarray(this.r, this.r + avail); 955 | } else if (avail < n) { 956 | throw new BufferFullError(this.buf.subarray(this.r, this.w)); 957 | } 958 | return this.buf.subarray(this.r, this.r + n); 959 | } 960 | } 961 | class AbstractBufBase { 962 | buf; 963 | usedBufferBytes = 0; 964 | err = null; 965 | size() { 966 | return this.buf.byteLength; 967 | } 968 | available() { 969 | return this.buf.byteLength - this.usedBufferBytes; 970 | } 971 | buffered() { 972 | return this.usedBufferBytes; 973 | } 974 | } 975 | class BufWriter extends AbstractBufBase { 976 | writer; 977 | static create(writer, size = 4096) { 978 | return writer instanceof BufWriter ? writer : new BufWriter(writer, size); 979 | } 980 | constructor(writer, size = 4096){ 981 | super(); 982 | this.writer = writer; 983 | if (size <= 0) { 984 | size = DEFAULT_BUF_SIZE; 985 | } 986 | this.buf = new Uint8Array(size); 987 | } 988 | reset(w) { 989 | this.err = null; 990 | this.usedBufferBytes = 0; 991 | this.writer = w; 992 | } 993 | async flush() { 994 | if (this.err !== null) throw this.err; 995 | if (this.usedBufferBytes === 0) return; 996 | try { 997 | await writeAll(this.writer, this.buf.subarray(0, this.usedBufferBytes)); 998 | } catch (e) { 999 | this.err = e; 1000 | throw e; 1001 | } 1002 | this.buf = new Uint8Array(this.buf.length); 1003 | this.usedBufferBytes = 0; 1004 | } 1005 | async write(data) { 1006 | if (this.err !== null) throw this.err; 1007 | if (data.length === 0) return 0; 1008 | let totalBytesWritten = 0; 1009 | let numBytesWritten = 0; 1010 | while(data.byteLength > this.available()){ 1011 | if (this.buffered() === 0) { 1012 | try { 1013 | numBytesWritten = await this.writer.write(data); 1014 | } catch (e) { 1015 | this.err = e; 1016 | throw e; 1017 | } 1018 | } else { 1019 | numBytesWritten = copy(data, this.buf, this.usedBufferBytes); 1020 | this.usedBufferBytes += numBytesWritten; 1021 | await this.flush(); 1022 | } 1023 | totalBytesWritten += numBytesWritten; 1024 | data = data.subarray(numBytesWritten); 1025 | } 1026 | numBytesWritten = copy(data, this.buf, this.usedBufferBytes); 1027 | this.usedBufferBytes += numBytesWritten; 1028 | totalBytesWritten += numBytesWritten; 1029 | return totalBytesWritten; 1030 | } 1031 | } 1032 | class BufWriterSync extends AbstractBufBase { 1033 | writer; 1034 | static create(writer, size = 4096) { 1035 | return writer instanceof BufWriterSync ? writer : new BufWriterSync(writer, size); 1036 | } 1037 | constructor(writer, size = 4096){ 1038 | super(); 1039 | this.writer = writer; 1040 | if (size <= 0) { 1041 | size = DEFAULT_BUF_SIZE; 1042 | } 1043 | this.buf = new Uint8Array(size); 1044 | } 1045 | reset(w) { 1046 | this.err = null; 1047 | this.usedBufferBytes = 0; 1048 | this.writer = w; 1049 | } 1050 | flush() { 1051 | if (this.err !== null) throw this.err; 1052 | if (this.usedBufferBytes === 0) return; 1053 | try { 1054 | writeAllSync(this.writer, this.buf.subarray(0, this.usedBufferBytes)); 1055 | } catch (e) { 1056 | this.err = e; 1057 | throw e; 1058 | } 1059 | this.buf = new Uint8Array(this.buf.length); 1060 | this.usedBufferBytes = 0; 1061 | } 1062 | writeSync(data) { 1063 | if (this.err !== null) throw this.err; 1064 | if (data.length === 0) return 0; 1065 | let totalBytesWritten = 0; 1066 | let numBytesWritten = 0; 1067 | while(data.byteLength > this.available()){ 1068 | if (this.buffered() === 0) { 1069 | try { 1070 | numBytesWritten = this.writer.writeSync(data); 1071 | } catch (e) { 1072 | this.err = e; 1073 | throw e; 1074 | } 1075 | } else { 1076 | numBytesWritten = copy(data, this.buf, this.usedBufferBytes); 1077 | this.usedBufferBytes += numBytesWritten; 1078 | this.flush(); 1079 | } 1080 | totalBytesWritten += numBytesWritten; 1081 | data = data.subarray(numBytesWritten); 1082 | } 1083 | numBytesWritten = copy(data, this.buf, this.usedBufferBytes); 1084 | this.usedBufferBytes += numBytesWritten; 1085 | totalBytesWritten += numBytesWritten; 1086 | return totalBytesWritten; 1087 | } 1088 | } 1089 | const DEFAULT_FORMATTER = "{levelName} {msg}"; 1090 | class BaseHandler { 1091 | level; 1092 | levelName; 1093 | formatter; 1094 | constructor(levelName, options = { 1095 | }){ 1096 | this.level = getLevelByName(levelName); 1097 | this.levelName = levelName; 1098 | this.formatter = options.formatter || DEFAULT_FORMATTER; 1099 | } 1100 | handle(logRecord) { 1101 | if (this.level > logRecord.level) return; 1102 | const msg = this.format(logRecord); 1103 | return this.log(msg); 1104 | } 1105 | format(logRecord) { 1106 | if (this.formatter instanceof Function) { 1107 | return this.formatter(logRecord); 1108 | } 1109 | return this.formatter.replace(/{(\S+)}/g, (match, p1)=>{ 1110 | const value = logRecord[p1]; 1111 | if (value == null) { 1112 | return match; 1113 | } 1114 | return String(value); 1115 | }); 1116 | } 1117 | log(_msg) { 1118 | } 1119 | async setup() { 1120 | } 1121 | async destroy() { 1122 | } 1123 | } 1124 | class ConsoleHandler extends BaseHandler { 1125 | format(logRecord) { 1126 | let msg = super.format(logRecord); 1127 | switch(logRecord.level){ 1128 | case LogLevels.INFO: 1129 | msg = blue(msg); 1130 | break; 1131 | case LogLevels.WARNING: 1132 | msg = yellow(msg); 1133 | break; 1134 | case LogLevels.ERROR: 1135 | msg = red(msg); 1136 | break; 1137 | case LogLevels.CRITICAL: 1138 | msg = bold(red(msg)); 1139 | break; 1140 | default: 1141 | break; 1142 | } 1143 | return msg; 1144 | } 1145 | log(msg) { 1146 | console.log(msg); 1147 | } 1148 | } 1149 | class WriterHandler extends BaseHandler { 1150 | _writer; 1151 | #encoder = new TextEncoder(); 1152 | } 1153 | class FileHandler extends WriterHandler { 1154 | _file; 1155 | _buf; 1156 | _filename; 1157 | _mode; 1158 | _openOptions; 1159 | _encoder = new TextEncoder(); 1160 | #unloadCallback() { 1161 | this.destroy(); 1162 | } 1163 | constructor(levelName, options){ 1164 | super(levelName, options); 1165 | this._filename = options.filename; 1166 | this._mode = options.mode ? options.mode : "a"; 1167 | this._openOptions = { 1168 | createNew: this._mode === "x", 1169 | create: this._mode !== "x", 1170 | append: this._mode === "a", 1171 | truncate: this._mode !== "a", 1172 | write: true 1173 | }; 1174 | } 1175 | async setup() { 1176 | this._file = await Deno.open(this._filename, this._openOptions); 1177 | this._writer = this._file; 1178 | this._buf = new BufWriterSync(this._file); 1179 | addEventListener("unload", this.#unloadCallback.bind(this)); 1180 | } 1181 | handle(logRecord) { 1182 | super.handle(logRecord); 1183 | if (logRecord.level > LogLevels.ERROR) { 1184 | this.flush(); 1185 | } 1186 | } 1187 | log(msg) { 1188 | this._buf.writeSync(this._encoder.encode(msg + "\n")); 1189 | } 1190 | flush() { 1191 | if (this._buf?.buffered() > 0) { 1192 | this._buf.flush(); 1193 | } 1194 | } 1195 | destroy() { 1196 | this.flush(); 1197 | this._file?.close(); 1198 | this._file = undefined; 1199 | removeEventListener("unload", this.#unloadCallback); 1200 | return Promise.resolve(); 1201 | } 1202 | } 1203 | class RotatingFileHandler extends FileHandler { 1204 | #maxBytes; 1205 | #maxBackupCount; 1206 | #currentFileSize = 0; 1207 | constructor(levelName, options){ 1208 | super(levelName, options); 1209 | this.#maxBytes = options.maxBytes; 1210 | this.#maxBackupCount = options.maxBackupCount; 1211 | } 1212 | async setup() { 1213 | if (this.#maxBytes < 1) { 1214 | this.destroy(); 1215 | throw new Error("maxBytes cannot be less than 1"); 1216 | } 1217 | if (this.#maxBackupCount < 1) { 1218 | this.destroy(); 1219 | throw new Error("maxBackupCount cannot be less than 1"); 1220 | } 1221 | await super.setup(); 1222 | if (this._mode === "w") { 1223 | for(let i = 1; i <= this.#maxBackupCount; i++){ 1224 | if (await exists(this._filename + "." + i)) { 1225 | await Deno.remove(this._filename + "." + i); 1226 | } 1227 | } 1228 | } else if (this._mode === "x") { 1229 | for(let i = 1; i <= this.#maxBackupCount; i++){ 1230 | if (await exists(this._filename + "." + i)) { 1231 | this.destroy(); 1232 | throw new Deno.errors.AlreadyExists("Backup log file " + this._filename + "." + i + " already exists"); 1233 | } 1234 | } 1235 | } else { 1236 | this.#currentFileSize = (await Deno.stat(this._filename)).size; 1237 | } 1238 | } 1239 | log(msg) { 1240 | const msgByteLength = this._encoder.encode(msg).byteLength + 1; 1241 | if (this.#currentFileSize + msgByteLength > this.#maxBytes) { 1242 | this.rotateLogFiles(); 1243 | this.#currentFileSize = 0; 1244 | } 1245 | this._buf.writeSync(this._encoder.encode(msg + "\n")); 1246 | this.#currentFileSize += msgByteLength; 1247 | } 1248 | rotateLogFiles() { 1249 | this._buf.flush(); 1250 | Deno.close(this._file.rid); 1251 | for(let i = this.#maxBackupCount - 1; i >= 0; i--){ 1252 | const source = this._filename + (i === 0 ? "" : "." + i); 1253 | const dest = this._filename + "." + (i + 1); 1254 | if (existsSync(source)) { 1255 | Deno.renameSync(source, dest); 1256 | } 1257 | } 1258 | this._file = Deno.openSync(this._filename, this._openOptions); 1259 | this._writer = this._file; 1260 | this._buf = new BufWriterSync(this._file); 1261 | } 1262 | } 1263 | class LoggerConfig { 1264 | level; 1265 | handlers; 1266 | } 1267 | const DEFAULT_LEVEL = "INFO"; 1268 | const DEFAULT_CONFIG = { 1269 | handlers: { 1270 | default: new ConsoleHandler(DEFAULT_LEVEL) 1271 | }, 1272 | loggers: { 1273 | default: { 1274 | level: DEFAULT_LEVEL, 1275 | handlers: [ 1276 | "default" 1277 | ] 1278 | } 1279 | } 1280 | }; 1281 | const state1 = { 1282 | handlers: new Map(), 1283 | loggers: new Map(), 1284 | config: DEFAULT_CONFIG 1285 | }; 1286 | const handlers1 = { 1287 | BaseHandler, 1288 | ConsoleHandler, 1289 | WriterHandler, 1290 | FileHandler, 1291 | RotatingFileHandler 1292 | }; 1293 | function getLogger(name) { 1294 | if (!name) { 1295 | const d = state1.loggers.get("default"); 1296 | assert(d != null, `"default" logger must be set for getting logger without name`); 1297 | return d; 1298 | } 1299 | const result = state1.loggers.get(name); 1300 | if (!result) { 1301 | const logger = new Logger(name, "NOTSET", { 1302 | handlers: [] 1303 | }); 1304 | state1.loggers.set(name, logger); 1305 | return logger; 1306 | } 1307 | return result; 1308 | } 1309 | function debug(msg, ...args) { 1310 | if (msg instanceof Function) { 1311 | return getLogger("default").debug(msg, ...args); 1312 | } 1313 | return getLogger("default").debug(msg, ...args); 1314 | } 1315 | function info(msg, ...args) { 1316 | if (msg instanceof Function) { 1317 | return getLogger("default").info(msg, ...args); 1318 | } 1319 | return getLogger("default").info(msg, ...args); 1320 | } 1321 | function warning(msg, ...args) { 1322 | if (msg instanceof Function) { 1323 | return getLogger("default").warning(msg, ...args); 1324 | } 1325 | return getLogger("default").warning(msg, ...args); 1326 | } 1327 | function error(msg, ...args) { 1328 | if (msg instanceof Function) { 1329 | return getLogger("default").error(msg, ...args); 1330 | } 1331 | return getLogger("default").error(msg, ...args); 1332 | } 1333 | function critical(msg, ...args) { 1334 | if (msg instanceof Function) { 1335 | return getLogger("default").critical(msg, ...args); 1336 | } 1337 | return getLogger("default").critical(msg, ...args); 1338 | } 1339 | async function setup(config) { 1340 | state1.config = { 1341 | handlers: { 1342 | ...DEFAULT_CONFIG.handlers, 1343 | ...config.handlers 1344 | }, 1345 | loggers: { 1346 | ...DEFAULT_CONFIG.loggers, 1347 | ...config.loggers 1348 | } 1349 | }; 1350 | state1.handlers.forEach((handler)=>{ 1351 | handler.destroy(); 1352 | }); 1353 | state1.handlers.clear(); 1354 | const handlers = state1.config.handlers || { 1355 | }; 1356 | for(const handlerName in handlers){ 1357 | const handler = handlers[handlerName]; 1358 | await handler.setup(); 1359 | state1.handlers.set(handlerName, handler); 1360 | } 1361 | state1.loggers.clear(); 1362 | const loggers = state1.config.loggers || { 1363 | }; 1364 | for(const loggerName in loggers){ 1365 | const loggerConfig = loggers[loggerName]; 1366 | const handlerNames = loggerConfig.handlers || []; 1367 | const handlers = []; 1368 | handlerNames.forEach((handlerName)=>{ 1369 | const handler = state1.handlers.get(handlerName); 1370 | if (handler) { 1371 | handlers.push(handler); 1372 | } 1373 | }); 1374 | const levelName = loggerConfig.level || DEFAULT_LEVEL; 1375 | const logger = new Logger(loggerName, levelName, { 1376 | handlers: handlers 1377 | }); 1378 | state1.loggers.set(loggerName, logger); 1379 | } 1380 | } 1381 | await setup(DEFAULT_CONFIG); 1382 | const mod = await async function() { 1383 | return { 1384 | LogLevels: LogLevels, 1385 | Logger: Logger, 1386 | handlers: handlers1, 1387 | LoggerConfig: LoggerConfig, 1388 | getLogger: getLogger, 1389 | debug: debug, 1390 | info: info, 1391 | warning: warning, 1392 | error: error, 1393 | critical: critical, 1394 | setup: setup 1395 | }; 1396 | }(); 1397 | let logger = mod.getLogger(); 1398 | let isDebug = false; 1399 | function debug1(func) { 1400 | if (isDebug) { 1401 | func(); 1402 | } 1403 | } 1404 | async function configLogger1(config) { 1405 | let { enable =true , level ="INFO" } = config; 1406 | if (config.logger) level = config.logger.levelName; 1407 | isDebug = level == "DEBUG"; 1408 | if (!enable) { 1409 | logger = new mod.Logger("fakeLogger", "NOTSET", { 1410 | }); 1411 | logger.level = 100; 1412 | } else { 1413 | if (!config.logger) { 1414 | await mod.setup({ 1415 | handlers: { 1416 | console: new mod.handlers.ConsoleHandler(level) 1417 | }, 1418 | loggers: { 1419 | default: { 1420 | level: "DEBUG", 1421 | handlers: [ 1422 | "console" 1423 | ] 1424 | } 1425 | } 1426 | }); 1427 | logger = mod.getLogger(); 1428 | } else { 1429 | logger = config.logger; 1430 | } 1431 | } 1432 | } 1433 | function xor(a, b) { 1434 | return a.map((__byte, index)=>{ 1435 | return __byte ^ b[index]; 1436 | }); 1437 | } 1438 | const encoder = new TextEncoder(); 1439 | const decoder = new TextDecoder(); 1440 | function encode2(input) { 1441 | return encoder.encode(input); 1442 | } 1443 | function decode1(input) { 1444 | return decoder.decode(input); 1445 | } 1446 | class BufferReader { 1447 | buffer; 1448 | pos = 0; 1449 | constructor(buffer){ 1450 | this.buffer = buffer; 1451 | } 1452 | get finished() { 1453 | return this.pos >= this.buffer.length; 1454 | } 1455 | skip(len) { 1456 | this.pos += len; 1457 | return this; 1458 | } 1459 | readBuffer(len) { 1460 | const buffer = this.buffer.slice(this.pos, this.pos + len); 1461 | this.pos += len; 1462 | return buffer; 1463 | } 1464 | readUints(len) { 1465 | let num = 0; 1466 | for(let n = 0; n < len; n++){ 1467 | num += this.buffer[this.pos++] << 8 * n; 1468 | } 1469 | return num; 1470 | } 1471 | readUint8() { 1472 | return this.buffer[this.pos++]; 1473 | } 1474 | readUint16() { 1475 | return this.readUints(2); 1476 | } 1477 | readUint32() { 1478 | return this.readUints(4); 1479 | } 1480 | readUint64() { 1481 | return this.readUints(8); 1482 | } 1483 | readNullTerminatedString() { 1484 | let end = this.buffer.indexOf(0, this.pos); 1485 | if (end === -1) end = this.buffer.length; 1486 | const buf = this.buffer.slice(this.pos, end); 1487 | this.pos += buf.length + 1; 1488 | return decode1(buf); 1489 | } 1490 | readString(len) { 1491 | const str = decode1(this.buffer.slice(this.pos, this.pos + len)); 1492 | this.pos += len; 1493 | return str; 1494 | } 1495 | readEncodedLen() { 1496 | const first = this.readUint8(); 1497 | if (first < 251) { 1498 | return first; 1499 | } else { 1500 | if (first == 252) { 1501 | return this.readUint16(); 1502 | } else if (first == 253) { 1503 | return this.readUints(3); 1504 | } else if (first == 254) { 1505 | return this.readUints(8); 1506 | } 1507 | } 1508 | return -1; 1509 | } 1510 | readLenCodeString() { 1511 | const len = this.readEncodedLen(); 1512 | if (len == -1) return null; 1513 | return this.readString(len); 1514 | } 1515 | } 1516 | class BufferWriter { 1517 | buffer; 1518 | pos = 0; 1519 | constructor(buffer){ 1520 | this.buffer = buffer; 1521 | } 1522 | get wroteData() { 1523 | return this.buffer.slice(0, this.pos); 1524 | } 1525 | get length() { 1526 | return this.pos; 1527 | } 1528 | get capacity() { 1529 | return this.buffer.length - this.pos; 1530 | } 1531 | skip(len) { 1532 | this.pos += len; 1533 | return this; 1534 | } 1535 | writeBuffer(buffer) { 1536 | if (buffer.length > this.capacity) { 1537 | buffer = buffer.slice(0, this.capacity); 1538 | } 1539 | this.buffer.set(buffer, this.pos); 1540 | this.pos += buffer.length; 1541 | return this; 1542 | } 1543 | write(__byte) { 1544 | this.buffer[this.pos++] = __byte; 1545 | return this; 1546 | } 1547 | writeInt16LE(num) { 1548 | } 1549 | writeIntLE(num, len) { 1550 | const __int = new Int32Array(1); 1551 | __int[0] = 40; 1552 | console.log(__int); 1553 | } 1554 | writeUint16(num) { 1555 | return this.writeUints(2, num); 1556 | } 1557 | writeUint32(num) { 1558 | return this.writeUints(4, num); 1559 | } 1560 | writeUint64(num) { 1561 | return this.writeUints(8, num); 1562 | } 1563 | writeUints(len, num) { 1564 | for(let n = 0; n < len; n++){ 1565 | this.buffer[this.pos++] = num >> n * 8 & 255; 1566 | } 1567 | return this; 1568 | } 1569 | writeNullTerminatedString(str) { 1570 | return this.writeString(str).write(0); 1571 | } 1572 | writeString(str) { 1573 | const buf = encode2(str); 1574 | this.buffer.set(buf, this.pos); 1575 | this.pos += buf.length; 1576 | return this; 1577 | } 1578 | } 1579 | function hash(algorithm, data) { 1580 | return new Uint8Array(createHash(algorithm).update(data).digest()); 1581 | } 1582 | function mysqlNativePassword(password, seed) { 1583 | const pwd1 = hash("sha1", encode2(password)); 1584 | const pwd2 = hash("sha1", pwd1); 1585 | let seedAndPwd2 = new Uint8Array(seed.length + pwd2.length); 1586 | seedAndPwd2.set(seed); 1587 | seedAndPwd2.set(pwd2, seed.length); 1588 | seedAndPwd2 = hash("sha1", seedAndPwd2); 1589 | return xor(seedAndPwd2, pwd1); 1590 | } 1591 | function cachingSha2Password(password, seed) { 1592 | const stage1 = hash("sha256", encode2(password)); 1593 | const stage2 = hash("sha256", stage1); 1594 | const stage3 = hash("sha256", Uint8Array.from([ 1595 | ...stage2, 1596 | ...seed 1597 | ])); 1598 | return xor(stage1, stage3); 1599 | } 1600 | function auth(authPluginName, password, seed) { 1601 | switch(authPluginName){ 1602 | case "mysql_native_password": 1603 | return mysqlNativePassword(password, seed); 1604 | case "caching_sha2_password": 1605 | return cachingSha2Password(password, seed); 1606 | default: 1607 | throw new Error("Not supported"); 1608 | } 1609 | } 1610 | var ServerCapabilities; 1611 | (function(ServerCapabilities) { 1612 | ServerCapabilities[ServerCapabilities["CLIENT_PROTOCOL_41"] = 512] = "CLIENT_PROTOCOL_41"; 1613 | ServerCapabilities[ServerCapabilities["CLIENT_CONNECT_WITH_DB"] = 8] = "CLIENT_CONNECT_WITH_DB"; 1614 | ServerCapabilities[ServerCapabilities["CLIENT_LONG_FLAG"] = 4] = "CLIENT_LONG_FLAG"; 1615 | ServerCapabilities[ServerCapabilities["CLIENT_DEPRECATE_EOF"] = 16777216] = "CLIENT_DEPRECATE_EOF"; 1616 | ServerCapabilities[ServerCapabilities["CLIENT_LONG_PASSWORD"] = 1] = "CLIENT_LONG_PASSWORD"; 1617 | ServerCapabilities[ServerCapabilities["CLIENT_TRANSACTIONS"] = 8192] = "CLIENT_TRANSACTIONS"; 1618 | ServerCapabilities[ServerCapabilities["CLIENT_MULTI_RESULTS"] = 131072] = "CLIENT_MULTI_RESULTS"; 1619 | ServerCapabilities[ServerCapabilities["CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA"] = 2097152] = "CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA"; 1620 | ServerCapabilities[ServerCapabilities["CLIENT_PLUGIN_AUTH"] = 524288] = "CLIENT_PLUGIN_AUTH"; 1621 | ServerCapabilities[ServerCapabilities["CLIENT_SECURE_CONNECTION"] = 32768] = "CLIENT_SECURE_CONNECTION"; 1622 | ServerCapabilities[ServerCapabilities["CLIENT_FOUND_ROWS"] = 2] = "CLIENT_FOUND_ROWS"; 1623 | ServerCapabilities[ServerCapabilities["CLIENT_CONNECT_ATTRS"] = 1048576] = "CLIENT_CONNECT_ATTRS"; 1624 | ServerCapabilities[ServerCapabilities["CLIENT_IGNORE_SPACE"] = 256] = "CLIENT_IGNORE_SPACE"; 1625 | ServerCapabilities[ServerCapabilities["CLIENT_IGNORE_SIGPIPE"] = 4096] = "CLIENT_IGNORE_SIGPIPE"; 1626 | ServerCapabilities[ServerCapabilities["CLIENT_RESERVED"] = 16384] = "CLIENT_RESERVED"; 1627 | ServerCapabilities[ServerCapabilities["CLIENT_PS_MULTI_RESULTS"] = 262144] = "CLIENT_PS_MULTI_RESULTS"; 1628 | })(ServerCapabilities || (ServerCapabilities = { 1629 | })); 1630 | var Charset; 1631 | (function(Charset) { 1632 | Charset[Charset["BIG5_CHINESE_CI"] = 1] = "BIG5_CHINESE_CI"; 1633 | Charset[Charset["LATIN2_CZECH_CS"] = 2] = "LATIN2_CZECH_CS"; 1634 | Charset[Charset["DEC8_SWEDISH_CI"] = 3] = "DEC8_SWEDISH_CI"; 1635 | Charset[Charset["CP850_GENERAL_CI"] = 4] = "CP850_GENERAL_CI"; 1636 | Charset[Charset["LATIN1_GERMAN1_CI"] = 5] = "LATIN1_GERMAN1_CI"; 1637 | Charset[Charset["HP8_ENGLISH_CI"] = 6] = "HP8_ENGLISH_CI"; 1638 | Charset[Charset["KOI8R_GENERAL_CI"] = 7] = "KOI8R_GENERAL_CI"; 1639 | Charset[Charset["LATIN1_SWEDISH_CI"] = 8] = "LATIN1_SWEDISH_CI"; 1640 | Charset[Charset["LATIN2_GENERAL_CI"] = 9] = "LATIN2_GENERAL_CI"; 1641 | Charset[Charset["SWE7_SWEDISH_CI"] = 10] = "SWE7_SWEDISH_CI"; 1642 | Charset[Charset["ASCII_GENERAL_CI"] = 11] = "ASCII_GENERAL_CI"; 1643 | Charset[Charset["UJIS_JAPANESE_CI"] = 12] = "UJIS_JAPANESE_CI"; 1644 | Charset[Charset["SJIS_JAPANESE_CI"] = 13] = "SJIS_JAPANESE_CI"; 1645 | Charset[Charset["CP1251_BULGARIAN_CI"] = 14] = "CP1251_BULGARIAN_CI"; 1646 | Charset[Charset["LATIN1_DANISH_CI"] = 15] = "LATIN1_DANISH_CI"; 1647 | Charset[Charset["HEBREW_GENERAL_CI"] = 16] = "HEBREW_GENERAL_CI"; 1648 | Charset[Charset["TIS620_THAI_CI"] = 18] = "TIS620_THAI_CI"; 1649 | Charset[Charset["EUCKR_KOREAN_CI"] = 19] = "EUCKR_KOREAN_CI"; 1650 | Charset[Charset["LATIN7_ESTONIAN_CS"] = 20] = "LATIN7_ESTONIAN_CS"; 1651 | Charset[Charset["LATIN2_HUNGARIAN_CI"] = 21] = "LATIN2_HUNGARIAN_CI"; 1652 | Charset[Charset["KOI8U_GENERAL_CI"] = 22] = "KOI8U_GENERAL_CI"; 1653 | Charset[Charset["CP1251_UKRAINIAN_CI"] = 23] = "CP1251_UKRAINIAN_CI"; 1654 | Charset[Charset["GB2312_CHINESE_CI"] = 24] = "GB2312_CHINESE_CI"; 1655 | Charset[Charset["GREEK_GENERAL_CI"] = 25] = "GREEK_GENERAL_CI"; 1656 | Charset[Charset["CP1250_GENERAL_CI"] = 26] = "CP1250_GENERAL_CI"; 1657 | Charset[Charset["LATIN2_CROATIAN_CI"] = 27] = "LATIN2_CROATIAN_CI"; 1658 | Charset[Charset["GBK_CHINESE_CI"] = 28] = "GBK_CHINESE_CI"; 1659 | Charset[Charset["CP1257_LITHUANIAN_CI"] = 29] = "CP1257_LITHUANIAN_CI"; 1660 | Charset[Charset["LATIN5_TURKISH_CI"] = 30] = "LATIN5_TURKISH_CI"; 1661 | Charset[Charset["LATIN1_GERMAN2_CI"] = 31] = "LATIN1_GERMAN2_CI"; 1662 | Charset[Charset["ARMSCII8_GENERAL_CI"] = 32] = "ARMSCII8_GENERAL_CI"; 1663 | Charset[Charset["UTF8_GENERAL_CI"] = 33] = "UTF8_GENERAL_CI"; 1664 | Charset[Charset["CP1250_CZECH_CS"] = 34] = "CP1250_CZECH_CS"; 1665 | Charset[Charset["UCS2_GENERAL_CI"] = 35] = "UCS2_GENERAL_CI"; 1666 | Charset[Charset["CP866_GENERAL_CI"] = 36] = "CP866_GENERAL_CI"; 1667 | Charset[Charset["KEYBCS2_GENERAL_CI"] = 37] = "KEYBCS2_GENERAL_CI"; 1668 | Charset[Charset["MACCE_GENERAL_CI"] = 38] = "MACCE_GENERAL_CI"; 1669 | Charset[Charset["MACROMAN_GENERAL_CI"] = 39] = "MACROMAN_GENERAL_CI"; 1670 | Charset[Charset["CP852_GENERAL_CI"] = 40] = "CP852_GENERAL_CI"; 1671 | Charset[Charset["LATIN7_GENERAL_CI"] = 41] = "LATIN7_GENERAL_CI"; 1672 | Charset[Charset["LATIN7_GENERAL_CS"] = 42] = "LATIN7_GENERAL_CS"; 1673 | Charset[Charset["MACCE_BIN"] = 43] = "MACCE_BIN"; 1674 | Charset[Charset["CP1250_CROATIAN_CI"] = 44] = "CP1250_CROATIAN_CI"; 1675 | Charset[Charset["UTF8MB4_GENERAL_CI"] = 45] = "UTF8MB4_GENERAL_CI"; 1676 | Charset[Charset["UTF8MB4_BIN"] = 46] = "UTF8MB4_BIN"; 1677 | Charset[Charset["LATIN1_BIN"] = 47] = "LATIN1_BIN"; 1678 | Charset[Charset["LATIN1_GENERAL_CI"] = 48] = "LATIN1_GENERAL_CI"; 1679 | Charset[Charset["LATIN1_GENERAL_CS"] = 49] = "LATIN1_GENERAL_CS"; 1680 | Charset[Charset["CP1251_BIN"] = 50] = "CP1251_BIN"; 1681 | Charset[Charset["CP1251_GENERAL_CI"] = 51] = "CP1251_GENERAL_CI"; 1682 | Charset[Charset["CP1251_GENERAL_CS"] = 52] = "CP1251_GENERAL_CS"; 1683 | Charset[Charset["MACROMAN_BIN"] = 53] = "MACROMAN_BIN"; 1684 | Charset[Charset["UTF16_GENERAL_CI"] = 54] = "UTF16_GENERAL_CI"; 1685 | Charset[Charset["UTF16_BIN"] = 55] = "UTF16_BIN"; 1686 | Charset[Charset["UTF16LE_GENERAL_CI"] = 56] = "UTF16LE_GENERAL_CI"; 1687 | Charset[Charset["CP1256_GENERAL_CI"] = 57] = "CP1256_GENERAL_CI"; 1688 | Charset[Charset["CP1257_BIN"] = 58] = "CP1257_BIN"; 1689 | Charset[Charset["CP1257_GENERAL_CI"] = 59] = "CP1257_GENERAL_CI"; 1690 | Charset[Charset["UTF32_GENERAL_CI"] = 60] = "UTF32_GENERAL_CI"; 1691 | Charset[Charset["UTF32_BIN"] = 61] = "UTF32_BIN"; 1692 | Charset[Charset["UTF16LE_BIN"] = 62] = "UTF16LE_BIN"; 1693 | Charset[Charset["BINARY"] = 63] = "BINARY"; 1694 | Charset[Charset["ARMSCII8_BIN"] = 64] = "ARMSCII8_BIN"; 1695 | Charset[Charset["ASCII_BIN"] = 65] = "ASCII_BIN"; 1696 | Charset[Charset["CP1250_BIN"] = 66] = "CP1250_BIN"; 1697 | Charset[Charset["CP1256_BIN"] = 67] = "CP1256_BIN"; 1698 | Charset[Charset["CP866_BIN"] = 68] = "CP866_BIN"; 1699 | Charset[Charset["DEC8_BIN"] = 69] = "DEC8_BIN"; 1700 | Charset[Charset["GREEK_BIN"] = 70] = "GREEK_BIN"; 1701 | Charset[Charset["HEBREW_BIN"] = 71] = "HEBREW_BIN"; 1702 | Charset[Charset["HP8_BIN"] = 72] = "HP8_BIN"; 1703 | Charset[Charset["KEYBCS2_BIN"] = 73] = "KEYBCS2_BIN"; 1704 | Charset[Charset["KOI8R_BIN"] = 74] = "KOI8R_BIN"; 1705 | Charset[Charset["KOI8U_BIN"] = 75] = "KOI8U_BIN"; 1706 | Charset[Charset["LATIN2_BIN"] = 77] = "LATIN2_BIN"; 1707 | Charset[Charset["LATIN5_BIN"] = 78] = "LATIN5_BIN"; 1708 | Charset[Charset["LATIN7_BIN"] = 79] = "LATIN7_BIN"; 1709 | Charset[Charset["CP850_BIN"] = 80] = "CP850_BIN"; 1710 | Charset[Charset["CP852_BIN"] = 81] = "CP852_BIN"; 1711 | Charset[Charset["SWE7_BIN"] = 82] = "SWE7_BIN"; 1712 | Charset[Charset["UTF8_BIN"] = 83] = "UTF8_BIN"; 1713 | Charset[Charset["BIG5_BIN"] = 84] = "BIG5_BIN"; 1714 | Charset[Charset["EUCKR_BIN"] = 85] = "EUCKR_BIN"; 1715 | Charset[Charset["GB2312_BIN"] = 86] = "GB2312_BIN"; 1716 | Charset[Charset["GBK_BIN"] = 87] = "GBK_BIN"; 1717 | Charset[Charset["SJIS_BIN"] = 88] = "SJIS_BIN"; 1718 | Charset[Charset["TIS620_BIN"] = 89] = "TIS620_BIN"; 1719 | Charset[Charset["UCS2_BIN"] = 90] = "UCS2_BIN"; 1720 | Charset[Charset["UJIS_BIN"] = 91] = "UJIS_BIN"; 1721 | Charset[Charset["GEOSTD8_GENERAL_CI"] = 92] = "GEOSTD8_GENERAL_CI"; 1722 | Charset[Charset["GEOSTD8_BIN"] = 93] = "GEOSTD8_BIN"; 1723 | Charset[Charset["LATIN1_SPANISH_CI"] = 94] = "LATIN1_SPANISH_CI"; 1724 | Charset[Charset["CP932_JAPANESE_CI"] = 95] = "CP932_JAPANESE_CI"; 1725 | Charset[Charset["CP932_BIN"] = 96] = "CP932_BIN"; 1726 | Charset[Charset["EUCJPMS_JAPANESE_CI"] = 97] = "EUCJPMS_JAPANESE_CI"; 1727 | Charset[Charset["EUCJPMS_BIN"] = 98] = "EUCJPMS_BIN"; 1728 | Charset[Charset["CP1250_POLISH_CI"] = 99] = "CP1250_POLISH_CI"; 1729 | Charset[Charset["UTF16_UNICODE_CI"] = 101] = "UTF16_UNICODE_CI"; 1730 | Charset[Charset["UTF16_ICELANDIC_CI"] = 102] = "UTF16_ICELANDIC_CI"; 1731 | Charset[Charset["UTF16_LATVIAN_CI"] = 103] = "UTF16_LATVIAN_CI"; 1732 | Charset[Charset["UTF16_ROMANIAN_CI"] = 104] = "UTF16_ROMANIAN_CI"; 1733 | Charset[Charset["UTF16_SLOVENIAN_CI"] = 105] = "UTF16_SLOVENIAN_CI"; 1734 | Charset[Charset["UTF16_POLISH_CI"] = 106] = "UTF16_POLISH_CI"; 1735 | Charset[Charset["UTF16_ESTONIAN_CI"] = 107] = "UTF16_ESTONIAN_CI"; 1736 | Charset[Charset["UTF16_SPANISH_CI"] = 108] = "UTF16_SPANISH_CI"; 1737 | Charset[Charset["UTF16_SWEDISH_CI"] = 109] = "UTF16_SWEDISH_CI"; 1738 | Charset[Charset["UTF16_TURKISH_CI"] = 110] = "UTF16_TURKISH_CI"; 1739 | Charset[Charset["UTF16_CZECH_CI"] = 111] = "UTF16_CZECH_CI"; 1740 | Charset[Charset["UTF16_DANISH_CI"] = 112] = "UTF16_DANISH_CI"; 1741 | Charset[Charset["UTF16_LITHUANIAN_CI"] = 113] = "UTF16_LITHUANIAN_CI"; 1742 | Charset[Charset["UTF16_SLOVAK_CI"] = 114] = "UTF16_SLOVAK_CI"; 1743 | Charset[Charset["UTF16_SPANISH2_CI"] = 115] = "UTF16_SPANISH2_CI"; 1744 | Charset[Charset["UTF16_ROMAN_CI"] = 116] = "UTF16_ROMAN_CI"; 1745 | Charset[Charset["UTF16_PERSIAN_CI"] = 117] = "UTF16_PERSIAN_CI"; 1746 | Charset[Charset["UTF16_ESPERANTO_CI"] = 118] = "UTF16_ESPERANTO_CI"; 1747 | Charset[Charset["UTF16_HUNGARIAN_CI"] = 119] = "UTF16_HUNGARIAN_CI"; 1748 | Charset[Charset["UTF16_SINHALA_CI"] = 120] = "UTF16_SINHALA_CI"; 1749 | Charset[Charset["UTF16_GERMAN2_CI"] = 121] = "UTF16_GERMAN2_CI"; 1750 | Charset[Charset["UTF16_CROATIAN_MYSQL561_CI"] = 122] = "UTF16_CROATIAN_MYSQL561_CI"; 1751 | Charset[Charset["UTF16_UNICODE_520_CI"] = 123] = "UTF16_UNICODE_520_CI"; 1752 | Charset[Charset["UTF16_VIETNAMESE_CI"] = 124] = "UTF16_VIETNAMESE_CI"; 1753 | Charset[Charset["UCS2_UNICODE_CI"] = 128] = "UCS2_UNICODE_CI"; 1754 | Charset[Charset["UCS2_ICELANDIC_CI"] = 129] = "UCS2_ICELANDIC_CI"; 1755 | Charset[Charset["UCS2_LATVIAN_CI"] = 130] = "UCS2_LATVIAN_CI"; 1756 | Charset[Charset["UCS2_ROMANIAN_CI"] = 131] = "UCS2_ROMANIAN_CI"; 1757 | Charset[Charset["UCS2_SLOVENIAN_CI"] = 132] = "UCS2_SLOVENIAN_CI"; 1758 | Charset[Charset["UCS2_POLISH_CI"] = 133] = "UCS2_POLISH_CI"; 1759 | Charset[Charset["UCS2_ESTONIAN_CI"] = 134] = "UCS2_ESTONIAN_CI"; 1760 | Charset[Charset["UCS2_SPANISH_CI"] = 135] = "UCS2_SPANISH_CI"; 1761 | Charset[Charset["UCS2_SWEDISH_CI"] = 136] = "UCS2_SWEDISH_CI"; 1762 | Charset[Charset["UCS2_TURKISH_CI"] = 137] = "UCS2_TURKISH_CI"; 1763 | Charset[Charset["UCS2_CZECH_CI"] = 138] = "UCS2_CZECH_CI"; 1764 | Charset[Charset["UCS2_DANISH_CI"] = 139] = "UCS2_DANISH_CI"; 1765 | Charset[Charset["UCS2_LITHUANIAN_CI"] = 140] = "UCS2_LITHUANIAN_CI"; 1766 | Charset[Charset["UCS2_SLOVAK_CI"] = 141] = "UCS2_SLOVAK_CI"; 1767 | Charset[Charset["UCS2_SPANISH2_CI"] = 142] = "UCS2_SPANISH2_CI"; 1768 | Charset[Charset["UCS2_ROMAN_CI"] = 143] = "UCS2_ROMAN_CI"; 1769 | Charset[Charset["UCS2_PERSIAN_CI"] = 144] = "UCS2_PERSIAN_CI"; 1770 | Charset[Charset["UCS2_ESPERANTO_CI"] = 145] = "UCS2_ESPERANTO_CI"; 1771 | Charset[Charset["UCS2_HUNGARIAN_CI"] = 146] = "UCS2_HUNGARIAN_CI"; 1772 | Charset[Charset["UCS2_SINHALA_CI"] = 147] = "UCS2_SINHALA_CI"; 1773 | Charset[Charset["UCS2_GERMAN2_CI"] = 148] = "UCS2_GERMAN2_CI"; 1774 | Charset[Charset["UCS2_CROATIAN_MYSQL561_CI"] = 149] = "UCS2_CROATIAN_MYSQL561_CI"; 1775 | Charset[Charset["UCS2_UNICODE_520_CI"] = 150] = "UCS2_UNICODE_520_CI"; 1776 | Charset[Charset["UCS2_VIETNAMESE_CI"] = 151] = "UCS2_VIETNAMESE_CI"; 1777 | Charset[Charset["UCS2_GENERAL_MYSQL500_CI"] = 159] = "UCS2_GENERAL_MYSQL500_CI"; 1778 | Charset[Charset["UTF32_UNICODE_CI"] = 160] = "UTF32_UNICODE_CI"; 1779 | Charset[Charset["UTF32_ICELANDIC_CI"] = 161] = "UTF32_ICELANDIC_CI"; 1780 | Charset[Charset["UTF32_LATVIAN_CI"] = 162] = "UTF32_LATVIAN_CI"; 1781 | Charset[Charset["UTF32_ROMANIAN_CI"] = 163] = "UTF32_ROMANIAN_CI"; 1782 | Charset[Charset["UTF32_SLOVENIAN_CI"] = 164] = "UTF32_SLOVENIAN_CI"; 1783 | Charset[Charset["UTF32_POLISH_CI"] = 165] = "UTF32_POLISH_CI"; 1784 | Charset[Charset["UTF32_ESTONIAN_CI"] = 166] = "UTF32_ESTONIAN_CI"; 1785 | Charset[Charset["UTF32_SPANISH_CI"] = 167] = "UTF32_SPANISH_CI"; 1786 | Charset[Charset["UTF32_SWEDISH_CI"] = 168] = "UTF32_SWEDISH_CI"; 1787 | Charset[Charset["UTF32_TURKISH_CI"] = 169] = "UTF32_TURKISH_CI"; 1788 | Charset[Charset["UTF32_CZECH_CI"] = 170] = "UTF32_CZECH_CI"; 1789 | Charset[Charset["UTF32_DANISH_CI"] = 171] = "UTF32_DANISH_CI"; 1790 | Charset[Charset["UTF32_LITHUANIAN_CI"] = 172] = "UTF32_LITHUANIAN_CI"; 1791 | Charset[Charset["UTF32_SLOVAK_CI"] = 173] = "UTF32_SLOVAK_CI"; 1792 | Charset[Charset["UTF32_SPANISH2_CI"] = 174] = "UTF32_SPANISH2_CI"; 1793 | Charset[Charset["UTF32_ROMAN_CI"] = 175] = "UTF32_ROMAN_CI"; 1794 | Charset[Charset["UTF32_PERSIAN_CI"] = 176] = "UTF32_PERSIAN_CI"; 1795 | Charset[Charset["UTF32_ESPERANTO_CI"] = 177] = "UTF32_ESPERANTO_CI"; 1796 | Charset[Charset["UTF32_HUNGARIAN_CI"] = 178] = "UTF32_HUNGARIAN_CI"; 1797 | Charset[Charset["UTF32_SINHALA_CI"] = 179] = "UTF32_SINHALA_CI"; 1798 | Charset[Charset["UTF32_GERMAN2_CI"] = 180] = "UTF32_GERMAN2_CI"; 1799 | Charset[Charset["UTF32_CROATIAN_MYSQL561_CI"] = 181] = "UTF32_CROATIAN_MYSQL561_CI"; 1800 | Charset[Charset["UTF32_UNICODE_520_CI"] = 182] = "UTF32_UNICODE_520_CI"; 1801 | Charset[Charset["UTF32_VIETNAMESE_CI"] = 183] = "UTF32_VIETNAMESE_CI"; 1802 | Charset[Charset["UTF8_UNICODE_CI"] = 192] = "UTF8_UNICODE_CI"; 1803 | Charset[Charset["UTF8_ICELANDIC_CI"] = 193] = "UTF8_ICELANDIC_CI"; 1804 | Charset[Charset["UTF8_LATVIAN_CI"] = 194] = "UTF8_LATVIAN_CI"; 1805 | Charset[Charset["UTF8_ROMANIAN_CI"] = 195] = "UTF8_ROMANIAN_CI"; 1806 | Charset[Charset["UTF8_SLOVENIAN_CI"] = 196] = "UTF8_SLOVENIAN_CI"; 1807 | Charset[Charset["UTF8_POLISH_CI"] = 197] = "UTF8_POLISH_CI"; 1808 | Charset[Charset["UTF8_ESTONIAN_CI"] = 198] = "UTF8_ESTONIAN_CI"; 1809 | Charset[Charset["UTF8_SPANISH_CI"] = 199] = "UTF8_SPANISH_CI"; 1810 | Charset[Charset["UTF8_SWEDISH_CI"] = 200] = "UTF8_SWEDISH_CI"; 1811 | Charset[Charset["UTF8_TURKISH_CI"] = 201] = "UTF8_TURKISH_CI"; 1812 | Charset[Charset["UTF8_CZECH_CI"] = 202] = "UTF8_CZECH_CI"; 1813 | Charset[Charset["UTF8_DANISH_CI"] = 203] = "UTF8_DANISH_CI"; 1814 | Charset[Charset["UTF8_LITHUANIAN_CI"] = 204] = "UTF8_LITHUANIAN_CI"; 1815 | Charset[Charset["UTF8_SLOVAK_CI"] = 205] = "UTF8_SLOVAK_CI"; 1816 | Charset[Charset["UTF8_SPANISH2_CI"] = 206] = "UTF8_SPANISH2_CI"; 1817 | Charset[Charset["UTF8_ROMAN_CI"] = 207] = "UTF8_ROMAN_CI"; 1818 | Charset[Charset["UTF8_PERSIAN_CI"] = 208] = "UTF8_PERSIAN_CI"; 1819 | Charset[Charset["UTF8_ESPERANTO_CI"] = 209] = "UTF8_ESPERANTO_CI"; 1820 | Charset[Charset["UTF8_HUNGARIAN_CI"] = 210] = "UTF8_HUNGARIAN_CI"; 1821 | Charset[Charset["UTF8_SINHALA_CI"] = 211] = "UTF8_SINHALA_CI"; 1822 | Charset[Charset["UTF8_GERMAN2_CI"] = 212] = "UTF8_GERMAN2_CI"; 1823 | Charset[Charset["UTF8_CROATIAN_MYSQL561_CI"] = 213] = "UTF8_CROATIAN_MYSQL561_CI"; 1824 | Charset[Charset["UTF8_UNICODE_520_CI"] = 214] = "UTF8_UNICODE_520_CI"; 1825 | Charset[Charset["UTF8_VIETNAMESE_CI"] = 215] = "UTF8_VIETNAMESE_CI"; 1826 | Charset[Charset["UTF8_GENERAL_MYSQL500_CI"] = 223] = "UTF8_GENERAL_MYSQL500_CI"; 1827 | Charset[Charset["UTF8MB4_UNICODE_CI"] = 224] = "UTF8MB4_UNICODE_CI"; 1828 | Charset[Charset["UTF8MB4_ICELANDIC_CI"] = 225] = "UTF8MB4_ICELANDIC_CI"; 1829 | Charset[Charset["UTF8MB4_LATVIAN_CI"] = 226] = "UTF8MB4_LATVIAN_CI"; 1830 | Charset[Charset["UTF8MB4_ROMANIAN_CI"] = 227] = "UTF8MB4_ROMANIAN_CI"; 1831 | Charset[Charset["UTF8MB4_SLOVENIAN_CI"] = 228] = "UTF8MB4_SLOVENIAN_CI"; 1832 | Charset[Charset["UTF8MB4_POLISH_CI"] = 229] = "UTF8MB4_POLISH_CI"; 1833 | Charset[Charset["UTF8MB4_ESTONIAN_CI"] = 230] = "UTF8MB4_ESTONIAN_CI"; 1834 | Charset[Charset["UTF8MB4_SPANISH_CI"] = 231] = "UTF8MB4_SPANISH_CI"; 1835 | Charset[Charset["UTF8MB4_SWEDISH_CI"] = 232] = "UTF8MB4_SWEDISH_CI"; 1836 | Charset[Charset["UTF8MB4_TURKISH_CI"] = 233] = "UTF8MB4_TURKISH_CI"; 1837 | Charset[Charset["UTF8MB4_CZECH_CI"] = 234] = "UTF8MB4_CZECH_CI"; 1838 | Charset[Charset["UTF8MB4_DANISH_CI"] = 235] = "UTF8MB4_DANISH_CI"; 1839 | Charset[Charset["UTF8MB4_LITHUANIAN_CI"] = 236] = "UTF8MB4_LITHUANIAN_CI"; 1840 | Charset[Charset["UTF8MB4_SLOVAK_CI"] = 237] = "UTF8MB4_SLOVAK_CI"; 1841 | Charset[Charset["UTF8MB4_SPANISH2_CI"] = 238] = "UTF8MB4_SPANISH2_CI"; 1842 | Charset[Charset["UTF8MB4_ROMAN_CI"] = 239] = "UTF8MB4_ROMAN_CI"; 1843 | Charset[Charset["UTF8MB4_PERSIAN_CI"] = 240] = "UTF8MB4_PERSIAN_CI"; 1844 | Charset[Charset["UTF8MB4_ESPERANTO_CI"] = 241] = "UTF8MB4_ESPERANTO_CI"; 1845 | Charset[Charset["UTF8MB4_HUNGARIAN_CI"] = 242] = "UTF8MB4_HUNGARIAN_CI"; 1846 | Charset[Charset["UTF8MB4_SINHALA_CI"] = 243] = "UTF8MB4_SINHALA_CI"; 1847 | Charset[Charset["UTF8MB4_GERMAN2_CI"] = 244] = "UTF8MB4_GERMAN2_CI"; 1848 | Charset[Charset["UTF8MB4_CROATIAN_MYSQL561_CI"] = 245] = "UTF8MB4_CROATIAN_MYSQL561_CI"; 1849 | Charset[Charset["UTF8MB4_UNICODE_520_CI"] = 246] = "UTF8MB4_UNICODE_520_CI"; 1850 | Charset[Charset["UTF8MB4_VIETNAMESE_CI"] = 247] = "UTF8MB4_VIETNAMESE_CI"; 1851 | Charset[Charset["UTF8_GENERAL50_CI"] = 253] = "UTF8_GENERAL50_CI"; 1852 | Charset[Charset["ARMSCII8"] = 32] = "ARMSCII8"; 1853 | Charset[Charset["ASCII"] = 11] = "ASCII"; 1854 | Charset[Charset["BIG5"] = 1] = "BIG5"; 1855 | Charset[Charset["CP1250"] = 26] = "CP1250"; 1856 | Charset[Charset["CP1251"] = 51] = "CP1251"; 1857 | Charset[Charset["CP1256"] = 57] = "CP1256"; 1858 | Charset[Charset["CP1257"] = 59] = "CP1257"; 1859 | Charset[Charset["CP866"] = 36] = "CP866"; 1860 | Charset[Charset["CP850"] = 4] = "CP850"; 1861 | Charset[Charset["CP852"] = 40] = "CP852"; 1862 | Charset[Charset["CP932"] = 95] = "CP932"; 1863 | Charset[Charset["DEC8"] = 3] = "DEC8"; 1864 | Charset[Charset["EUCJPMS"] = 97] = "EUCJPMS"; 1865 | Charset[Charset["EUCKR"] = 19] = "EUCKR"; 1866 | Charset[Charset["GB2312"] = 24] = "GB2312"; 1867 | Charset[Charset["GBK"] = 28] = "GBK"; 1868 | Charset[Charset["GEOSTD8"] = 92] = "GEOSTD8"; 1869 | Charset[Charset["GREEK"] = 25] = "GREEK"; 1870 | Charset[Charset["HEBREW"] = 16] = "HEBREW"; 1871 | Charset[Charset["HP8"] = 6] = "HP8"; 1872 | Charset[Charset["KEYBCS2"] = 37] = "KEYBCS2"; 1873 | Charset[Charset["KOI8R"] = 7] = "KOI8R"; 1874 | Charset[Charset["KOI8U"] = 22] = "KOI8U"; 1875 | Charset[Charset["LATIN1"] = 8] = "LATIN1"; 1876 | Charset[Charset["LATIN2"] = 9] = "LATIN2"; 1877 | Charset[Charset["LATIN5"] = 30] = "LATIN5"; 1878 | Charset[Charset["LATIN7"] = 41] = "LATIN7"; 1879 | Charset[Charset["MACCE"] = 38] = "MACCE"; 1880 | Charset[Charset["MACROMAN"] = 39] = "MACROMAN"; 1881 | Charset[Charset["SJIS"] = 13] = "SJIS"; 1882 | Charset[Charset["SWE7"] = 10] = "SWE7"; 1883 | Charset[Charset["TIS620"] = 18] = "TIS620"; 1884 | Charset[Charset["UCS2"] = 35] = "UCS2"; 1885 | Charset[Charset["UJIS"] = 12] = "UJIS"; 1886 | Charset[Charset["UTF16"] = 54] = "UTF16"; 1887 | Charset[Charset["UTF16LE"] = 56] = "UTF16LE"; 1888 | Charset[Charset["UTF8"] = 33] = "UTF8"; 1889 | Charset[Charset["UTF8MB4"] = 45] = "UTF8MB4"; 1890 | Charset[Charset["UTF32"] = 60] = "UTF32"; 1891 | })(Charset || (Charset = { 1892 | })); 1893 | function buildAuth(packet, params) { 1894 | const clientParam = (params.db ? ServerCapabilities.CLIENT_CONNECT_WITH_DB : 0) | ServerCapabilities.CLIENT_PLUGIN_AUTH | ServerCapabilities.CLIENT_LONG_PASSWORD | ServerCapabilities.CLIENT_PROTOCOL_41 | ServerCapabilities.CLIENT_TRANSACTIONS | ServerCapabilities.CLIENT_MULTI_RESULTS | ServerCapabilities.CLIENT_SECURE_CONNECTION | ServerCapabilities.CLIENT_LONG_FLAG & packet.serverCapabilities | ServerCapabilities.CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA & packet.serverCapabilities | ServerCapabilities.CLIENT_DEPRECATE_EOF & packet.serverCapabilities; 1895 | if (packet.serverCapabilities & ServerCapabilities.CLIENT_PLUGIN_AUTH) { 1896 | const writer = new BufferWriter(new Uint8Array(1000)); 1897 | writer.writeUint32(clientParam).writeUint32(2 ** 24 - 1).write(Charset.UTF8_GENERAL_CI).skip(23).writeNullTerminatedString(params.username); 1898 | if (params.password) { 1899 | const authData = auth(packet.authPluginName, params.password, packet.seed); 1900 | if (clientParam & ServerCapabilities.CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA || clientParam & ServerCapabilities.CLIENT_SECURE_CONNECTION) { 1901 | writer.write(authData.length); 1902 | writer.writeBuffer(authData); 1903 | } else { 1904 | writer.writeBuffer(authData); 1905 | writer.write(0); 1906 | } 1907 | } else { 1908 | writer.write(0); 1909 | } 1910 | if (clientParam & ServerCapabilities.CLIENT_CONNECT_WITH_DB && params.db) { 1911 | writer.writeNullTerminatedString(params.db); 1912 | } 1913 | if (clientParam & ServerCapabilities.CLIENT_PLUGIN_AUTH) { 1914 | writer.writeNullTerminatedString(packet.authPluginName); 1915 | } 1916 | return writer.wroteData; 1917 | } 1918 | return Uint8Array.from([]); 1919 | } 1920 | function buildQuery(sql, params = []) { 1921 | const data = encode2(replaceParams(sql, params)); 1922 | const writer = new BufferWriter(new Uint8Array(data.length + 1)); 1923 | writer.write(3); 1924 | writer.writeBuffer(data); 1925 | return writer.buffer; 1926 | } 1927 | var PacketType; 1928 | (function(PacketType) { 1929 | PacketType[PacketType["OK_Packet"] = 0] = "OK_Packet"; 1930 | PacketType[PacketType["EOF_Packet"] = 254] = "EOF_Packet"; 1931 | PacketType[PacketType["ERR_Packet"] = 255] = "ERR_Packet"; 1932 | PacketType[PacketType["Result"] = 256] = "Result"; 1933 | })(PacketType || (PacketType = { 1934 | })); 1935 | class SendPacket { 1936 | body; 1937 | header; 1938 | constructor(body, no){ 1939 | this.body = body; 1940 | this.header = { 1941 | size: body.length, 1942 | no 1943 | }; 1944 | } 1945 | async send(conn) { 1946 | const body = this.body; 1947 | const data = new BufferWriter(new Uint8Array(4 + body.length)); 1948 | data.writeUints(3, this.header.size); 1949 | data.write(this.header.no); 1950 | data.writeBuffer(body); 1951 | logger.debug(`send: ${data.length}B \n${format(data.buffer)}\n`); 1952 | try { 1953 | let wrote = 0; 1954 | do { 1955 | wrote += await conn.write(data.buffer.subarray(wrote)); 1956 | }while (wrote < data.length) 1957 | } catch (error) { 1958 | throw new WriteError(error.message); 1959 | } 1960 | } 1961 | } 1962 | class ReceivePacket { 1963 | header; 1964 | body; 1965 | type; 1966 | async parse(reader) { 1967 | const header = new BufferReader(new Uint8Array(4)); 1968 | let readCount = 0; 1969 | let nread = await this.read(reader, header.buffer); 1970 | if (nread === null) return null; 1971 | readCount = nread; 1972 | const bodySize = header.readUints(3); 1973 | this.header = { 1974 | size: bodySize, 1975 | no: header.readUint8() 1976 | }; 1977 | this.body = new BufferReader(new Uint8Array(bodySize)); 1978 | nread = await this.read(reader, this.body.buffer); 1979 | if (nread === null) return null; 1980 | readCount += nread; 1981 | const { OK_Packet , ERR_Packet , EOF_Packet , Result } = PacketType; 1982 | switch(this.body.buffer[0]){ 1983 | case OK_Packet: 1984 | this.type = OK_Packet; 1985 | break; 1986 | case 255: 1987 | this.type = ERR_Packet; 1988 | break; 1989 | case 254: 1990 | this.type = EOF_Packet; 1991 | break; 1992 | default: 1993 | this.type = Result; 1994 | break; 1995 | } 1996 | debug1(()=>{ 1997 | const data = new Uint8Array(readCount); 1998 | data.set(header.buffer); 1999 | data.set(this.body.buffer, 4); 2000 | logger.debug(`receive: ${readCount}B, size = ${this.header.size}, no = ${this.header.no} \n${format(data)}\n`); 2001 | }); 2002 | return this; 2003 | } 2004 | async read(reader, buffer) { 2005 | const size = buffer.length; 2006 | let haveRead = 0; 2007 | while(haveRead < size){ 2008 | const nread = await reader.read(buffer.subarray(haveRead)); 2009 | if (nread === null) return null; 2010 | haveRead += nread; 2011 | } 2012 | return haveRead; 2013 | } 2014 | } 2015 | function parseError(reader, conn) { 2016 | const code = reader.readUint16(); 2017 | const packet = { 2018 | code, 2019 | message: "" 2020 | }; 2021 | if (conn.capabilities & ServerCapabilities.CLIENT_PROTOCOL_41) { 2022 | packet.sqlStateMarker = reader.readUint8(); 2023 | packet.sqlState = reader.readUints(5); 2024 | } 2025 | packet.message = reader.readNullTerminatedString(); 2026 | return packet; 2027 | } 2028 | function parseHandshake(reader) { 2029 | const protocolVersion = reader.readUint8(); 2030 | const serverVersion = reader.readNullTerminatedString(); 2031 | const threadId = reader.readUint32(); 2032 | const seedWriter = new BufferWriter(new Uint8Array(20)); 2033 | seedWriter.writeBuffer(reader.readBuffer(8)); 2034 | reader.skip(1); 2035 | let serverCapabilities = reader.readUint16(); 2036 | let characterSet = 0, statusFlags = 0, authPluginDataLength = 0, authPluginName = ""; 2037 | if (!reader.finished) { 2038 | characterSet = reader.readUint8(); 2039 | statusFlags = reader.readUint16(); 2040 | serverCapabilities |= reader.readUint16() << 16; 2041 | if ((serverCapabilities & ServerCapabilities.CLIENT_PLUGIN_AUTH) != 0) { 2042 | authPluginDataLength = reader.readUint8(); 2043 | } else { 2044 | reader.skip(1); 2045 | } 2046 | reader.skip(10); 2047 | if ((serverCapabilities & ServerCapabilities.CLIENT_SECURE_CONNECTION) != 0) { 2048 | seedWriter.writeBuffer(reader.readBuffer(Math.max(13, authPluginDataLength - 8))); 2049 | } 2050 | if ((serverCapabilities & ServerCapabilities.CLIENT_PLUGIN_AUTH) != 0) { 2051 | authPluginName = reader.readNullTerminatedString(); 2052 | } 2053 | } 2054 | return { 2055 | protocolVersion, 2056 | serverVersion, 2057 | threadId, 2058 | seed: seedWriter.buffer, 2059 | serverCapabilities, 2060 | characterSet, 2061 | statusFlags, 2062 | authPluginName 2063 | }; 2064 | } 2065 | var AuthResult; 2066 | (function(AuthResult) { 2067 | AuthResult[AuthResult["AuthPassed"] = 0] = "AuthPassed"; 2068 | AuthResult[AuthResult["MethodMismatch"] = 1] = "MethodMismatch"; 2069 | AuthResult[AuthResult["AuthMoreRequired"] = 2] = "AuthMoreRequired"; 2070 | })(AuthResult || (AuthResult = { 2071 | })); 2072 | function parseAuth(packet) { 2073 | switch(packet.type){ 2074 | case PacketType.EOF_Packet: 2075 | return AuthResult.MethodMismatch; 2076 | case PacketType.Result: 2077 | return AuthResult.AuthMoreRequired; 2078 | case PacketType.OK_Packet: 2079 | return AuthResult.AuthPassed; 2080 | default: 2081 | return AuthResult.AuthPassed; 2082 | } 2083 | } 2084 | function parseField(reader) { 2085 | const catalog = reader.readLenCodeString(); 2086 | const schema = reader.readLenCodeString(); 2087 | const table = reader.readLenCodeString(); 2088 | const originTable = reader.readLenCodeString(); 2089 | const name = reader.readLenCodeString(); 2090 | const originName = reader.readLenCodeString(); 2091 | reader.skip(1); 2092 | const encoding = reader.readUint16(); 2093 | const fieldLen = reader.readUint32(); 2094 | const fieldType = reader.readUint8(); 2095 | const fieldFlag = reader.readUint16(); 2096 | const decimals = reader.readUint8(); 2097 | reader.skip(1); 2098 | const defaultVal = reader.readLenCodeString(); 2099 | return { 2100 | catalog, 2101 | schema, 2102 | table, 2103 | originName, 2104 | fieldFlag, 2105 | originTable, 2106 | fieldLen, 2107 | name, 2108 | fieldType, 2109 | encoding, 2110 | decimals, 2111 | defaultVal 2112 | }; 2113 | } 2114 | function parseRow(reader, fields) { 2115 | const row = { 2116 | }; 2117 | for (const field of fields){ 2118 | const name = field.name; 2119 | const val = reader.readLenCodeString(); 2120 | row[name] = val === null ? null : convertType(field, val); 2121 | } 2122 | return row; 2123 | } 2124 | function convertType(field, val) { 2125 | const { fieldType , fieldLen } = field; 2126 | switch(fieldType){ 2127 | case 0: 2128 | case 5: 2129 | case 4: 2130 | case 18: 2131 | return parseFloat(val); 2132 | case 246: 2133 | return val; 2134 | case 1: 2135 | case 2: 2136 | case 3: 2137 | case 9: 2138 | return parseInt(val); 2139 | case 8: 2140 | if (Number(val) < Number.MIN_SAFE_INTEGER || Number(val) > Number.MAX_SAFE_INTEGER) { 2141 | return BigInt(val); 2142 | } else { 2143 | return parseInt(val); 2144 | } 2145 | case 15: 2146 | case 253: 2147 | case 254: 2148 | case 11: 2149 | case 19: 2150 | return val; 2151 | case 10: 2152 | case 7: 2153 | case 12: 2154 | case 14: 2155 | case 17: 2156 | case 18: 2157 | return new Date(val); 2158 | default: 2159 | return val; 2160 | } 2161 | } 2162 | function power_mod(n, p, m) { 2163 | if (p === 1n) return n; 2164 | if (p % 2n === 0n) { 2165 | const t = power_mod(n, p >> 1n, m); 2166 | return t * t % m; 2167 | } else { 2168 | const t = power_mod(n, p >> 1n, m); 2169 | return t * t * n % m; 2170 | } 2171 | } 2172 | const base64abc1 = [ 2173 | "A", 2174 | "B", 2175 | "C", 2176 | "D", 2177 | "E", 2178 | "F", 2179 | "G", 2180 | "H", 2181 | "I", 2182 | "J", 2183 | "K", 2184 | "L", 2185 | "M", 2186 | "N", 2187 | "O", 2188 | "P", 2189 | "Q", 2190 | "R", 2191 | "S", 2192 | "T", 2193 | "U", 2194 | "V", 2195 | "W", 2196 | "X", 2197 | "Y", 2198 | "Z", 2199 | "a", 2200 | "b", 2201 | "c", 2202 | "d", 2203 | "e", 2204 | "f", 2205 | "g", 2206 | "h", 2207 | "i", 2208 | "j", 2209 | "k", 2210 | "l", 2211 | "m", 2212 | "n", 2213 | "o", 2214 | "p", 2215 | "q", 2216 | "r", 2217 | "s", 2218 | "t", 2219 | "u", 2220 | "v", 2221 | "w", 2222 | "x", 2223 | "y", 2224 | "z", 2225 | "0", 2226 | "1", 2227 | "2", 2228 | "3", 2229 | "4", 2230 | "5", 2231 | "6", 2232 | "7", 2233 | "8", 2234 | "9", 2235 | "+", 2236 | "/" 2237 | ]; 2238 | function encode3(data) { 2239 | const uint8 = typeof data === "string" ? new TextEncoder().encode(data) : data instanceof Uint8Array ? data : new Uint8Array(data); 2240 | let result = "", i; 2241 | const l = uint8.length; 2242 | for(i = 2; i < l; i += 3){ 2243 | result += base64abc1[uint8[i - 2] >> 2]; 2244 | result += base64abc1[(uint8[i - 2] & 3) << 4 | uint8[i - 1] >> 4]; 2245 | result += base64abc1[(uint8[i - 1] & 15) << 2 | uint8[i] >> 6]; 2246 | result += base64abc1[uint8[i] & 63]; 2247 | } 2248 | if (i === l + 1) { 2249 | result += base64abc1[uint8[i - 2] >> 2]; 2250 | result += base64abc1[(uint8[i - 2] & 3) << 4]; 2251 | result += "=="; 2252 | } 2253 | if (i === l) { 2254 | result += base64abc1[uint8[i - 2] >> 2]; 2255 | result += base64abc1[(uint8[i - 2] & 3) << 4 | uint8[i - 1] >> 4]; 2256 | result += base64abc1[(uint8[i - 1] & 15) << 2]; 2257 | result += "="; 2258 | } 2259 | return result; 2260 | } 2261 | function decode2(b64) { 2262 | const binString = atob(b64); 2263 | const size = binString.length; 2264 | const bytes = new Uint8Array(size); 2265 | for(let i = 0; i < size; i++){ 2266 | bytes[i] = binString.charCodeAt(i); 2267 | } 2268 | return bytes; 2269 | } 2270 | let cachedTextDecoder1 = new TextDecoder("utf-8", { 2271 | ignoreBOM: true, 2272 | fatal: true 2273 | }); 2274 | cachedTextDecoder1.decode(); 2275 | let cachegetUint8Memory01 = null; 2276 | function getUint8Memory01() { 2277 | if (cachegetUint8Memory01 === null || cachegetUint8Memory01.buffer !== wasm1.memory.buffer) { 2278 | cachegetUint8Memory01 = new Uint8Array(wasm1.memory.buffer); 2279 | } 2280 | return cachegetUint8Memory01; 2281 | } 2282 | function getStringFromWasm01(ptr, len) { 2283 | return cachedTextDecoder1.decode(getUint8Memory01().subarray(ptr, ptr + len)); 2284 | } 2285 | const heap1 = new Array(32).fill(undefined); 2286 | heap1.push(undefined, null, true, false); 2287 | let heap_next1 = heap1.length; 2288 | function addHeapObject1(obj) { 2289 | if (heap_next1 === heap1.length) heap1.push(heap1.length + 1); 2290 | const idx = heap_next1; 2291 | heap_next1 = heap1[idx]; 2292 | heap1[idx] = obj; 2293 | return idx; 2294 | } 2295 | function getObject1(idx) { 2296 | return heap1[idx]; 2297 | } 2298 | function dropObject1(idx) { 2299 | if (idx < 36) return; 2300 | heap1[idx] = heap_next1; 2301 | heap_next1 = idx; 2302 | } 2303 | function takeObject1(idx) { 2304 | const ret = getObject1(idx); 2305 | dropObject1(idx); 2306 | return ret; 2307 | } 2308 | let WASM_VECTOR_LEN1 = 0; 2309 | let cachedTextEncoder1 = new TextEncoder("utf-8"); 2310 | const encodeString1 = function(arg, view) { 2311 | return cachedTextEncoder1.encodeInto(arg, view); 2312 | }; 2313 | function passStringToWasm01(arg, malloc, realloc) { 2314 | if (realloc === undefined) { 2315 | const buf = cachedTextEncoder1.encode(arg); 2316 | const ptr = malloc(buf.length); 2317 | getUint8Memory01().subarray(ptr, ptr + buf.length).set(buf); 2318 | WASM_VECTOR_LEN1 = buf.length; 2319 | return ptr; 2320 | } 2321 | let len = arg.length; 2322 | let ptr = malloc(len); 2323 | const mem = getUint8Memory01(); 2324 | let offset = 0; 2325 | for(; offset < len; offset++){ 2326 | const code = arg.charCodeAt(offset); 2327 | if (code > 127) break; 2328 | mem[ptr + offset] = code; 2329 | } 2330 | if (offset !== len) { 2331 | if (offset !== 0) { 2332 | arg = arg.slice(offset); 2333 | } 2334 | ptr = realloc(ptr, len, len = offset + arg.length * 3); 2335 | const view = getUint8Memory01().subarray(ptr + offset, ptr + len); 2336 | const ret = encodeString1(arg, view); 2337 | offset += ret.written; 2338 | } 2339 | WASM_VECTOR_LEN1 = offset; 2340 | return ptr; 2341 | } 2342 | function create_hash1(algorithm) { 2343 | var ptr0 = passStringToWasm01(algorithm, wasm1.__wbindgen_malloc, wasm1.__wbindgen_realloc); 2344 | var len0 = WASM_VECTOR_LEN1; 2345 | var ret = wasm1.create_hash(ptr0, len0); 2346 | return DenoHash1.__wrap(ret); 2347 | } 2348 | function _assertClass1(instance, klass) { 2349 | if (!(instance instanceof klass)) { 2350 | throw new Error(`expected instance of ${klass.name}`); 2351 | } 2352 | return instance.ptr; 2353 | } 2354 | function passArray8ToWasm01(arg, malloc) { 2355 | const ptr = malloc(arg.length * 1); 2356 | getUint8Memory01().set(arg, ptr / 1); 2357 | WASM_VECTOR_LEN1 = arg.length; 2358 | return ptr; 2359 | } 2360 | function update_hash1(hash, data) { 2361 | _assertClass1(hash, DenoHash1); 2362 | var ptr0 = passArray8ToWasm01(data, wasm1.__wbindgen_malloc); 2363 | var len0 = WASM_VECTOR_LEN1; 2364 | wasm1.update_hash(hash.ptr, ptr0, len0); 2365 | } 2366 | let cachegetInt32Memory01 = null; 2367 | function getInt32Memory01() { 2368 | if (cachegetInt32Memory01 === null || cachegetInt32Memory01.buffer !== wasm1.memory.buffer) { 2369 | cachegetInt32Memory01 = new Int32Array(wasm1.memory.buffer); 2370 | } 2371 | return cachegetInt32Memory01; 2372 | } 2373 | function getArrayU8FromWasm01(ptr, len) { 2374 | return getUint8Memory01().subarray(ptr / 1, ptr / 1 + len); 2375 | } 2376 | function digest_hash1(hash) { 2377 | try { 2378 | const retptr = wasm1.__wbindgen_add_to_stack_pointer(-16); 2379 | _assertClass1(hash, DenoHash1); 2380 | wasm1.digest_hash(retptr, hash.ptr); 2381 | var r0 = getInt32Memory01()[retptr / 4 + 0]; 2382 | var r1 = getInt32Memory01()[retptr / 4 + 1]; 2383 | var v0 = getArrayU8FromWasm01(r0, r1).slice(); 2384 | wasm1.__wbindgen_free(r0, r1 * 1); 2385 | return v0; 2386 | } finally{ 2387 | wasm1.__wbindgen_add_to_stack_pointer(16); 2388 | } 2389 | } 2390 | const DenoHashFinalization1 = new FinalizationRegistry((ptr)=>wasm1.__wbg_denohash_free(ptr) 2391 | ); 2392 | class DenoHash1 { 2393 | static __wrap(ptr) { 2394 | const obj = Object.create(DenoHash1.prototype); 2395 | obj.ptr = ptr; 2396 | DenoHashFinalization1.register(obj, obj.ptr, obj); 2397 | return obj; 2398 | } 2399 | __destroy_into_raw() { 2400 | const ptr = this.ptr; 2401 | this.ptr = 0; 2402 | DenoHashFinalization1.unregister(this); 2403 | return ptr; 2404 | } 2405 | free() { 2406 | const ptr = this.__destroy_into_raw(); 2407 | wasm1.__wbg_denohash_free(ptr); 2408 | } 2409 | } 2410 | const imports1 = { 2411 | __wbindgen_placeholder__: { 2412 | __wbindgen_string_new: function(arg0, arg1) { 2413 | var ret = getStringFromWasm01(arg0, arg1); 2414 | return addHeapObject1(ret); 2415 | }, 2416 | __wbindgen_throw: function(arg0, arg1) { 2417 | throw new Error(getStringFromWasm01(arg0, arg1)); 2418 | }, 2419 | __wbindgen_rethrow: function(arg0) { 2420 | throw takeObject1(arg0); 2421 | } 2422 | } 2423 | }; 2424 | import wasmModule1 from './62edfb469c0dbacd90273cf9a0d7a478.wasm'; 2425 | const wasmInstance1 = new WebAssembly.Instance(wasmModule1, imports1); 2426 | const wasm1 = wasmInstance1.exports; 2427 | const hexTable1 = new TextEncoder().encode("0123456789abcdef"); 2428 | function encode4(src) { 2429 | const dst = new Uint8Array(src.length * 2); 2430 | for(let i = 0; i < dst.length; i++){ 2431 | const v = src[i]; 2432 | dst[i * 2] = hexTable1[v >> 4]; 2433 | dst[i * 2 + 1] = hexTable1[v & 15]; 2434 | } 2435 | return dst; 2436 | } 2437 | class Hash1 { 2438 | #hash; 2439 | #digested; 2440 | constructor(algorithm){ 2441 | this.#hash = create_hash1(algorithm); 2442 | this.#digested = false; 2443 | } 2444 | update(message) { 2445 | let view; 2446 | if (message instanceof Uint8Array) { 2447 | view = message; 2448 | } else if (typeof message === "string") { 2449 | view = new TextEncoder().encode(message); 2450 | } else if (ArrayBuffer.isView(message)) { 2451 | view = new Uint8Array(message.buffer, message.byteOffset, message.byteLength); 2452 | } else if (message instanceof ArrayBuffer) { 2453 | view = new Uint8Array(message); 2454 | } else { 2455 | throw new Error("hash: `data` is invalid type"); 2456 | } 2457 | const chunkSize = 65536; 2458 | for(let offset = 0; offset < view.byteLength; offset += chunkSize){ 2459 | update_hash1(this.#hash, new Uint8Array(view.buffer, view.byteOffset + offset, Math.min(65536, view.byteLength - offset))); 2460 | } 2461 | return this; 2462 | } 2463 | digest() { 2464 | if (this.#digested) throw new Error("hash: already digested"); 2465 | this.#digested = true; 2466 | return digest_hash1(this.#hash); 2467 | } 2468 | toString(format = "hex") { 2469 | const finalized = new Uint8Array(this.digest()); 2470 | switch(format){ 2471 | case "hex": 2472 | return new TextDecoder().decode(encode4(finalized)); 2473 | case "base64": 2474 | return encode3(finalized); 2475 | default: 2476 | throw new Error("hash: invalid format"); 2477 | } 2478 | } 2479 | } 2480 | function createHash1(algorithm) { 2481 | return new Hash1(algorithm); 2482 | } 2483 | function i2osp(x, length) { 2484 | const t = new Uint8Array(length); 2485 | for(let i = length - 1; i >= 0; i--){ 2486 | if (x === 0n) break; 2487 | t[i] = Number(x & 255n); 2488 | x = x >> 8n; 2489 | } 2490 | return t; 2491 | } 2492 | function os2ip(m) { 2493 | let n = 0n; 2494 | for (const c of m)n = (n << 8n) + BigInt(c); 2495 | return n; 2496 | } 2497 | function mgf1(seed, length, hash) { 2498 | let counter = 0n; 2499 | let output = []; 2500 | while(output.length < length){ 2501 | let h; 2502 | const c = i2osp(counter, 4); 2503 | if (typeof hash === 'function') { 2504 | h = hash(new Uint8Array([ 2505 | ...seed, 2506 | ...c 2507 | ])); 2508 | } else { 2509 | h = new Uint8Array(createHash1(hash).update(new Uint8Array([ 2510 | ...seed, 2511 | ...c 2512 | ])).digest()); 2513 | } 2514 | output = [ 2515 | ...output, 2516 | ...h 2517 | ]; 2518 | counter++; 2519 | } 2520 | return new Uint8Array(output.slice(0, length)); 2521 | } 2522 | function str2bytes(str) { 2523 | const encoder = new TextEncoder(); 2524 | return encoder.encode(str); 2525 | } 2526 | function xor1(a, b) { 2527 | const c = new Uint8Array(a.length); 2528 | for(let i = 0; i < c.length; i++){ 2529 | c[i] = a[i] ^ b[i % b.length]; 2530 | } 2531 | return c; 2532 | } 2533 | function concat(...arg) { 2534 | const length = arg.reduce((a, b)=>a + b.length 2535 | , 0); 2536 | const c = new Uint8Array(length); 2537 | let ptr = 0; 2538 | for(let i = 0; i < arg.length; i++){ 2539 | c.set(arg[i], ptr); 2540 | ptr += arg[i].length; 2541 | } 2542 | return c; 2543 | } 2544 | function random_bytes(length) { 2545 | const n = new Uint8Array(length); 2546 | for(let i = 0; i < length; i++)n[i] = (Math.random() * 254 | 0) + 1; 2547 | return n; 2548 | } 2549 | function get_key_size(n) { 2550 | const size_list = [ 2551 | 64n, 2552 | 128n, 2553 | 256n, 2554 | 512n, 2555 | 1024n 2556 | ]; 2557 | for (const size of size_list){ 2558 | if (n < 1n << size * 8n) return Number(size); 2559 | } 2560 | return 2048; 2561 | } 2562 | function base64_to_binary(b) { 2563 | const base64_map = [ 2564 | -2, 2565 | -2, 2566 | -2, 2567 | -2, 2568 | -2, 2569 | -2, 2570 | -2, 2571 | -2, 2572 | -2, 2573 | -2, 2574 | -1, 2575 | -2, 2576 | -2, 2577 | -1, 2578 | -2, 2579 | -2, 2580 | -2, 2581 | -2, 2582 | -2, 2583 | -2, 2584 | -2, 2585 | -2, 2586 | -2, 2587 | -2, 2588 | -2, 2589 | -2, 2590 | -2, 2591 | -2, 2592 | -2, 2593 | -2, 2594 | -2, 2595 | -2, 2596 | -1, 2597 | -2, 2598 | -2, 2599 | -2, 2600 | -2, 2601 | -2, 2602 | -2, 2603 | -2, 2604 | -2, 2605 | -2, 2606 | -2, 2607 | 62, 2608 | -2, 2609 | -2, 2610 | -2, 2611 | 63, 2612 | 52, 2613 | 53, 2614 | 54, 2615 | 55, 2616 | 56, 2617 | 57, 2618 | 58, 2619 | 59, 2620 | 60, 2621 | 61, 2622 | -2, 2623 | -2, 2624 | -2, 2625 | -1, 2626 | -2, 2627 | -2, 2628 | -2, 2629 | 0, 2630 | 1, 2631 | 2, 2632 | 3, 2633 | 4, 2634 | 5, 2635 | 6, 2636 | 7, 2637 | 8, 2638 | 9, 2639 | 10, 2640 | 11, 2641 | 12, 2642 | 13, 2643 | 14, 2644 | 15, 2645 | 16, 2646 | 17, 2647 | 18, 2648 | 19, 2649 | 20, 2650 | 21, 2651 | 22, 2652 | 23, 2653 | 24, 2654 | 25, 2655 | -2, 2656 | -2, 2657 | -2, 2658 | -2, 2659 | -2, 2660 | -2, 2661 | 26, 2662 | 27, 2663 | 28, 2664 | 29, 2665 | 30, 2666 | 31, 2667 | 32, 2668 | 33, 2669 | 34, 2670 | 35, 2671 | 36, 2672 | 37, 2673 | 38, 2674 | 39, 2675 | 40, 2676 | 41, 2677 | 42, 2678 | 43, 2679 | 44, 2680 | 45, 2681 | 46, 2682 | 47, 2683 | 48, 2684 | 49, 2685 | 50, 2686 | 51, 2687 | -2, 2688 | -2, 2689 | -2, 2690 | -2, 2691 | -2, 2692 | -2, 2693 | -2, 2694 | -2, 2695 | -2, 2696 | -2, 2697 | -2, 2698 | -2, 2699 | -2, 2700 | -2, 2701 | -2, 2702 | -2, 2703 | -2, 2704 | -2, 2705 | -2, 2706 | -2, 2707 | -2, 2708 | -2, 2709 | -2, 2710 | -2, 2711 | -2, 2712 | -2, 2713 | -2, 2714 | -2, 2715 | -2, 2716 | -2, 2717 | -2, 2718 | -2, 2719 | -2, 2720 | -2, 2721 | -2, 2722 | -2, 2723 | -2, 2724 | -2, 2725 | -2, 2726 | -2, 2727 | -2, 2728 | -2, 2729 | -2, 2730 | -2, 2731 | -2, 2732 | -2, 2733 | -2, 2734 | -2, 2735 | -2, 2736 | -2, 2737 | -2, 2738 | -2, 2739 | -2, 2740 | -2, 2741 | -2, 2742 | -2, 2743 | -2, 2744 | -2, 2745 | -2, 2746 | -2, 2747 | -2, 2748 | -2, 2749 | -2, 2750 | -2, 2751 | -2, 2752 | -2, 2753 | -2, 2754 | -2, 2755 | -2, 2756 | -2, 2757 | -2, 2758 | -2, 2759 | -2, 2760 | -2, 2761 | -2, 2762 | -2, 2763 | -2, 2764 | -2, 2765 | -2, 2766 | -2, 2767 | -2, 2768 | -2, 2769 | -2, 2770 | -2, 2771 | -2, 2772 | -2, 2773 | -2, 2774 | -2, 2775 | -2, 2776 | -2, 2777 | -2, 2778 | -2, 2779 | -2, 2780 | -2, 2781 | -2, 2782 | -2, 2783 | -2, 2784 | -2, 2785 | -2, 2786 | -2, 2787 | -2, 2788 | -2, 2789 | -2, 2790 | -2, 2791 | -2, 2792 | -2, 2793 | -2, 2794 | -2, 2795 | -2, 2796 | -2, 2797 | -2, 2798 | -2, 2799 | -2, 2800 | -2, 2801 | -2, 2802 | -2, 2803 | -2, 2804 | -2, 2805 | -2, 2806 | -2, 2807 | -2, 2808 | -2, 2809 | -2, 2810 | -2, 2811 | -2, 2812 | -2, 2813 | -2, 2814 | -2, 2815 | -2, 2816 | -2, 2817 | -2, 2818 | -2, 2819 | -2 2820 | ]; 2821 | let e = ""; 2822 | for (const c of b){ 2823 | const v = base64_map[c.charCodeAt(0)]; 2824 | if (v === -2) throw "Invalid"; 2825 | if (v >= 0) e += c; 2826 | } 2827 | const bytes = new Uint8Array(Math.floor(e.length * 6 / 8)); 2828 | let ptr = 0; 2829 | for(let i = 0; i < e.length; i += 4){ 2830 | const remain = e.length - i; 2831 | if (remain >= 4) { 2832 | const v = (base64_map[e.charCodeAt(i)] << 18) + (base64_map[e.charCodeAt(i + 1)] << 12) + (base64_map[e.charCodeAt(i + 2)] << 6) + base64_map[e.charCodeAt(i + 3)]; 2833 | bytes[ptr++] = v >> 16 % 256; 2834 | bytes[ptr++] = v >> 8 % 256; 2835 | bytes[ptr++] = v % 256; 2836 | } else if (remain === 3) { 2837 | const v = (base64_map[e.charCodeAt(i)] << 10) + (base64_map[e.charCodeAt(i + 1)] << 4) + (base64_map[e.charCodeAt(i + 2)] >> 2); 2838 | bytes[ptr++] = v >> 8 % 256; 2839 | bytes[ptr++] = v % 256; 2840 | } else if (remain === 2) { 2841 | bytes[ptr++] = (base64_map[e.charCodeAt(i)] << 2) + (base64_map[e.charCodeAt(i + 1)] >> 4); 2842 | } 2843 | } 2844 | return bytes; 2845 | } 2846 | function eme_oaep_encode(label, m, k, algorithm) { 2847 | const labelHash = new Uint8Array(createHash1(algorithm).update(label).digest()); 2848 | const ps = new Uint8Array(k - labelHash.length * 2 - 2 - m.length); 2849 | const db = concat(labelHash, ps, [ 2850 | 1 2851 | ], m); 2852 | const seed = random_bytes(labelHash.length); 2853 | const dbMask = mgf1(seed, k - labelHash.length - 1, algorithm); 2854 | const maskedDb = xor1(db, dbMask); 2855 | const seedMask = mgf1(maskedDb, labelHash.length, algorithm); 2856 | const maskedSeed = xor1(seed, seedMask); 2857 | return concat([ 2858 | 0 2859 | ], maskedSeed, maskedDb); 2860 | } 2861 | function eme_oaep_decode(label, c, k, algorithm) { 2862 | const labelHash = new Uint8Array(createHash1(algorithm).update(label).digest()); 2863 | const maskedSeed = c.slice(1, 1 + labelHash.length); 2864 | const maskedDb = c.slice(1 + labelHash.length); 2865 | const seedMask = mgf1(maskedDb, labelHash.length, algorithm); 2866 | const seed = xor1(maskedSeed, seedMask); 2867 | const dbMask = mgf1(seed, k - labelHash.length - 1, algorithm); 2868 | const db = xor1(maskedDb, dbMask); 2869 | let ptr = labelHash.length; 2870 | while(ptr < db.length && db[ptr] === 0)ptr++; 2871 | return db.slice(ptr + 1); 2872 | } 2873 | function rsaep(n, e, m) { 2874 | return power_mod(m, e, n); 2875 | } 2876 | function rsadp(n, d, c) { 2877 | return power_mod(c, d, n); 2878 | } 2879 | function rsa_oaep_encrypt(bytes, n, e, m, algorithm) { 2880 | const em = eme_oaep_encode(new Uint8Array(0), m, bytes, algorithm); 2881 | const msg = os2ip(em); 2882 | const c = rsaep(n, e, msg); 2883 | return i2osp(c, bytes); 2884 | } 2885 | function rsa_oaep_decrypt(bytes, n, d, c, algorithm) { 2886 | const em = rsadp(n, d, os2ip(c)); 2887 | const m = eme_oaep_decode(new Uint8Array(0), i2osp(em, bytes), bytes, algorithm); 2888 | return m; 2889 | } 2890 | function rsa_pkcs1_encrypt(bytes, n, e, m) { 2891 | const p = concat([ 2892 | 0, 2893 | 2 2894 | ], random_bytes(bytes - m.length - 3), [ 2895 | 0 2896 | ], m); 2897 | const msg = os2ip(p); 2898 | const c = rsaep(n, e, msg); 2899 | return i2osp(c, bytes); 2900 | } 2901 | function rsa_pkcs1_decrypt(bytes, n, d, c) { 2902 | const em = i2osp(rsadp(n, d, os2ip(c)), bytes); 2903 | if (em[0] !== 0) throw "Decryption error"; 2904 | if (em[1] !== 2) throw "Decryption error"; 2905 | let psCursor = 2; 2906 | for(; psCursor < em.length; psCursor++){ 2907 | if (em[psCursor] === 0) break; 2908 | } 2909 | if (psCursor < 10) throw "Decryption error"; 2910 | return em.slice(psCursor + 1); 2911 | } 2912 | function ber_decode(bytes, from, to) { 2913 | return ber_next(bytes); 2914 | } 2915 | function ber_sequence(bytes, from, length) { 2916 | const end = from + length; 2917 | let res = []; 2918 | let ptr = from; 2919 | while(ptr < end){ 2920 | const next = ber_next(bytes, ptr); 2921 | res.push(next); 2922 | ptr += next.totalLength; 2923 | } 2924 | return res; 2925 | } 2926 | function ber_integer(bytes, from, length) { 2927 | let n = 0n; 2928 | for (const b of bytes.slice(from, from + length)){ 2929 | n = (n << 8n) + BigInt(b); 2930 | } 2931 | return n; 2932 | } 2933 | function ber_oid(bytes, from, length) { 2934 | const id = [ 2935 | bytes[from] / 40 | 0, 2936 | bytes[from] % 40, 2937 | ]; 2938 | let value = 0; 2939 | for (const b of bytes.slice(from + 1, from + length)){ 2940 | if (b > 128) value += value * 127 + (b - 128); 2941 | else { 2942 | value = value * 128 + b; 2943 | id.push(value); 2944 | value = 0; 2945 | } 2946 | } 2947 | return id.join("."); 2948 | } 2949 | function ber_unknown(bytes, from, length) { 2950 | return bytes.slice(from, from + length); 2951 | } 2952 | function ber_simple(n) { 2953 | if (Array.isArray(n.value)) return n.value.map((x)=>ber_simple(x) 2954 | ); 2955 | return n.value; 2956 | } 2957 | function ber_next(bytes, from, to) { 2958 | if (!from) from = 0; 2959 | if (!to) to = bytes.length; 2960 | let ptr = from; 2961 | const type = bytes[ptr++]; 2962 | let size = bytes[ptr++]; 2963 | if ((size & 128) > 0) { 2964 | let ext = size - 128; 2965 | size = 0; 2966 | while(--ext >= 0){ 2967 | size = (size << 8) + bytes[ptr++]; 2968 | } 2969 | } 2970 | let value = null; 2971 | if (type === 48) { 2972 | value = ber_sequence(bytes, ptr, size); 2973 | } else if (type === 2) { 2974 | value = ber_integer(bytes, ptr, size); 2975 | } else if (type === 3) { 2976 | value = ber_sequence(bytes, ptr + 1, size - 1); 2977 | } else if (type === 5) { 2978 | value = null; 2979 | } else if (type === 6) { 2980 | value = ber_oid(bytes, ptr, size); 2981 | } else { 2982 | value = ber_unknown(bytes, ptr, size); 2983 | } 2984 | return { 2985 | totalLength: ptr - from + size, 2986 | type, 2987 | length: size, 2988 | value 2989 | }; 2990 | } 2991 | class RSA { 2992 | static encrypt(message, key, options) { 2993 | if (!key.e) throw "Invalid RSA key"; 2994 | const computedOptions = { 2995 | hash: "sha1", 2996 | padding: "oaep", 2997 | ...options 2998 | }; 2999 | const computedMessage = typeof message === "string" ? str2bytes(message) : message; 3000 | if (computedOptions.padding === "oaep") { 3001 | return rsa_oaep_encrypt(key.length, key.n, key.e, computedMessage, computedOptions.hash); 3002 | } else if (computedOptions.padding === "pkcs1") { 3003 | return rsa_pkcs1_encrypt(key.length, key.n, key.e, computedMessage); 3004 | } 3005 | throw "Invalid parameters"; 3006 | } 3007 | static decrypt(ciper, key, options) { 3008 | if (!key.d) throw "Invalid RSA key"; 3009 | const computedOptions = { 3010 | hash: "sha1", 3011 | padding: "oaep", 3012 | ...options 3013 | }; 3014 | if (computedOptions.padding === "oaep") { 3015 | return rsa_oaep_decrypt(key.length, key.n, key.d, ciper, computedOptions.hash); 3016 | } else if (computedOptions.padding === "pkcs1") { 3017 | return rsa_pkcs1_decrypt(key.length, key.n, key.d, ciper); 3018 | } 3019 | throw "Invalid parameters"; 3020 | } 3021 | static parseKey(key) { 3022 | if (key.indexOf("-----BEGIN RSA PRIVATE KEY-----") === 0) { 3023 | const trimmedKey = key.substr(31, key.length - 61); 3024 | const parseKey = ber_simple(ber_decode(base64_to_binary(trimmedKey))); 3025 | return { 3026 | n: parseKey[1], 3027 | d: parseKey[3], 3028 | e: parseKey[2], 3029 | length: get_key_size(parseKey[1]) 3030 | }; 3031 | } else if (key.indexOf("-----BEGIN PUBLIC KEY-----") === 0) { 3032 | const trimmedKey = key.substr(26, key.length - 51); 3033 | const parseKey = ber_simple(ber_decode(base64_to_binary(trimmedKey))); 3034 | return { 3035 | length: get_key_size(parseKey[1][0][0]), 3036 | n: parseKey[1][0][0], 3037 | e: parseKey[1][0][1] 3038 | }; 3039 | } 3040 | throw "Invalid key format"; 3041 | } 3042 | } 3043 | function encryptWithPublicKey(key, data) { 3044 | const publicKey = RSA.parseKey(key); 3045 | return RSA.encrypt(data, publicKey); 3046 | } 3047 | let scramble, password; 3048 | function start(scramble_, password_) { 3049 | scramble = scramble_; 3050 | password = password_; 3051 | return { 3052 | done: false, 3053 | next: authMoreResponse 3054 | }; 3055 | } 3056 | function authMoreResponse(packet) { 3057 | var AuthStatusFlags; 3058 | (function(AuthStatusFlags) { 3059 | AuthStatusFlags[AuthStatusFlags["FullAuth"] = 4] = "FullAuth"; 3060 | AuthStatusFlags[AuthStatusFlags["FastPath"] = 3] = "FastPath"; 3061 | })(AuthStatusFlags || (AuthStatusFlags = { 3062 | })); 3063 | const REQUEST_PUBLIC_KEY = 2; 3064 | const statusFlag = packet.body.skip(1).readUint8(); 3065 | let authMoreData, done = true, next, quickRead = false; 3066 | if (statusFlag === AuthStatusFlags.FullAuth) { 3067 | authMoreData = new Uint8Array([ 3068 | REQUEST_PUBLIC_KEY 3069 | ]); 3070 | done = false; 3071 | next = encryptWithKey; 3072 | } 3073 | if (statusFlag === AuthStatusFlags.FastPath) { 3074 | done = false; 3075 | quickRead = true; 3076 | next = terminate; 3077 | } 3078 | return { 3079 | done, 3080 | next, 3081 | quickRead, 3082 | data: authMoreData 3083 | }; 3084 | } 3085 | function encryptWithKey(packet) { 3086 | const publicKey = parsePublicKey(packet); 3087 | const len = password.length; 3088 | let passwordBuffer = new Uint8Array(len + 1); 3089 | for(let n = 0; n < len; n++){ 3090 | passwordBuffer[n] = password.charCodeAt(n); 3091 | } 3092 | passwordBuffer[len] = 0; 3093 | const encryptedPassword = encrypt(passwordBuffer, scramble, publicKey); 3094 | return { 3095 | done: false, 3096 | next: terminate, 3097 | data: encryptedPassword 3098 | }; 3099 | } 3100 | function parsePublicKey(packet) { 3101 | return packet.body.skip(1).readNullTerminatedString(); 3102 | } 3103 | function encrypt(password, scramble, key) { 3104 | const stage1 = xor(password, scramble); 3105 | const encrypted = encryptWithPublicKey(key, stage1); 3106 | return encrypted; 3107 | } 3108 | function terminate() { 3109 | return { 3110 | done: true 3111 | }; 3112 | } 3113 | const mod1 = { 3114 | start: start 3115 | }; 3116 | const __default = { 3117 | caching_sha2_password: mod1 3118 | }; 3119 | var ConnectionState; 3120 | (function(ConnectionState) { 3121 | ConnectionState[ConnectionState["CONNECTING"] = 0] = "CONNECTING"; 3122 | ConnectionState[ConnectionState["CONNECTED"] = 1] = "CONNECTED"; 3123 | ConnectionState[ConnectionState["CLOSING"] = 2] = "CLOSING"; 3124 | ConnectionState[ConnectionState["CLOSED"] = 3] = "CLOSED"; 3125 | })(ConnectionState || (ConnectionState = { 3126 | })); 3127 | class Connection1 { 3128 | config; 3129 | state = ConnectionState.CONNECTING; 3130 | capabilities = 0; 3131 | serverVersion = ""; 3132 | conn = undefined; 3133 | _timedOut = false; 3134 | get remoteAddr() { 3135 | return this.config.socketPath ? `unix:${this.config.socketPath}` : `${this.config.hostname}:${this.config.port}`; 3136 | } 3137 | constructor(config){ 3138 | this.config = config; 3139 | } 3140 | async _connect() { 3141 | const { hostname , port =3306 , socketPath , username ="" , password } = this.config; 3142 | logger.info(`connecting ${this.remoteAddr}`); 3143 | this.conn = !socketPath ? await Deno.connect({ 3144 | transport: "tcp", 3145 | hostname, 3146 | port 3147 | }) : await Deno.connect({ 3148 | transport: "unix", 3149 | path: socketPath 3150 | }); 3151 | try { 3152 | let receive = await this.nextPacket(); 3153 | const handshakePacket = parseHandshake(receive.body); 3154 | const data = buildAuth(handshakePacket, { 3155 | username, 3156 | password, 3157 | db: this.config.db 3158 | }); 3159 | await new SendPacket(data, 1).send(this.conn); 3160 | this.state = ConnectionState.CONNECTING; 3161 | this.serverVersion = handshakePacket.serverVersion; 3162 | this.capabilities = handshakePacket.serverCapabilities; 3163 | receive = await this.nextPacket(); 3164 | const authResult = parseAuth(receive); 3165 | let handler; 3166 | switch(authResult){ 3167 | case AuthResult.AuthMoreRequired: 3168 | const adaptedPlugin = __default[handshakePacket.authPluginName]; 3169 | handler = adaptedPlugin; 3170 | break; 3171 | case AuthResult.MethodMismatch: 3172 | throw new Error("Currently cannot support auth method mismatch!"); 3173 | } 3174 | let result; 3175 | if (handler) { 3176 | result = handler.start(handshakePacket.seed, password); 3177 | while(!result.done){ 3178 | if (result.data) { 3179 | const sequenceNumber = receive.header.no + 1; 3180 | await new SendPacket(result.data, sequenceNumber).send(this.conn); 3181 | receive = await this.nextPacket(); 3182 | } 3183 | if (result.quickRead) { 3184 | await this.nextPacket(); 3185 | } 3186 | if (result.next) { 3187 | result = result.next(receive); 3188 | } 3189 | } 3190 | } 3191 | const header = receive.body.readUint8(); 3192 | if (header === 255) { 3193 | const error = parseError(receive.body, this); 3194 | logger.error(`connect error(${error.code}): ${error.message}`); 3195 | this.close(); 3196 | throw new Error(error.message); 3197 | } else { 3198 | logger.info(`connected to ${this.remoteAddr}`); 3199 | this.state = ConnectionState.CONNECTED; 3200 | } 3201 | if (this.config.charset) { 3202 | await this.execute(`SET NAMES ${this.config.charset}`); 3203 | } 3204 | } catch (error) { 3205 | this.close(); 3206 | throw error; 3207 | } 3208 | } 3209 | async connect() { 3210 | await this._connect(); 3211 | } 3212 | async nextPacket() { 3213 | if (!this.conn) { 3214 | throw new ConnnectionError("Not connected"); 3215 | } 3216 | const timeoutTimer = this.config.timeout ? setTimeout(this._timeoutCallback, this.config.timeout) : null; 3217 | let packet; 3218 | try { 3219 | packet = await new ReceivePacket().parse(this.conn); 3220 | } catch (error) { 3221 | if (this._timedOut) { 3222 | throw new ResponseTimeoutError("Connection read timed out"); 3223 | } 3224 | timeoutTimer && clearTimeout(timeoutTimer); 3225 | this.close(); 3226 | throw error; 3227 | } 3228 | timeoutTimer && clearTimeout(timeoutTimer); 3229 | if (!packet) { 3230 | this.close(); 3231 | throw new ReadError("Connection closed unexpectedly"); 3232 | } 3233 | if (packet.type === PacketType.ERR_Packet) { 3234 | packet.body.skip(1); 3235 | const error = parseError(packet.body, this); 3236 | throw new Error(error.message); 3237 | } 3238 | return packet; 3239 | } 3240 | _timeoutCallback = ()=>{ 3241 | logger.info("connection read timed out"); 3242 | this._timedOut = true; 3243 | this.close(); 3244 | }; 3245 | lessThan5_7() { 3246 | const version = this.serverVersion; 3247 | if (!version.includes("MariaDB")) return version < "5.7.0"; 3248 | const segments = version.split("-"); 3249 | if (segments[1] === "MariaDB") return segments[0] < "5.7.0"; 3250 | return false; 3251 | } 3252 | isMariaDBAndVersion10_0Or10_1() { 3253 | const version = this.serverVersion; 3254 | if (!version.includes("MariaDB")) return false; 3255 | return version.includes("5.5.5-10.1") || version.includes("5.5.5-10.0"); 3256 | } 3257 | close() { 3258 | if (this.state != ConnectionState.CLOSED) { 3259 | logger.info("close connection"); 3260 | this.conn?.close(); 3261 | this.state = ConnectionState.CLOSED; 3262 | } 3263 | } 3264 | async query(sql, params) { 3265 | const result = await this.execute(sql, params); 3266 | if (result && result.rows) { 3267 | return result.rows; 3268 | } else { 3269 | return result; 3270 | } 3271 | } 3272 | async execute(sql, params, iterator = false) { 3273 | if (this.state != ConnectionState.CONNECTED) { 3274 | if (this.state == ConnectionState.CLOSED) { 3275 | throw new ConnnectionError("Connection is closed"); 3276 | } else { 3277 | throw new ConnnectionError("Must be connected first"); 3278 | } 3279 | } 3280 | const data = buildQuery(sql, params); 3281 | try { 3282 | await new SendPacket(data, 0).send(this.conn); 3283 | let receive = await this.nextPacket(); 3284 | if (receive.type === PacketType.OK_Packet) { 3285 | receive.body.skip(1); 3286 | return { 3287 | affectedRows: receive.body.readEncodedLen(), 3288 | lastInsertId: receive.body.readEncodedLen() 3289 | }; 3290 | } else if (receive.type !== PacketType.Result) { 3291 | throw new ProtocolError(); 3292 | } 3293 | let fieldCount = receive.body.readEncodedLen(); 3294 | const fields = []; 3295 | while(fieldCount--){ 3296 | const packet = await this.nextPacket(); 3297 | if (packet) { 3298 | const field = parseField(packet.body); 3299 | fields.push(field); 3300 | } 3301 | } 3302 | const rows = []; 3303 | if (this.lessThan5_7() || this.isMariaDBAndVersion10_0Or10_1()) { 3304 | receive = await this.nextPacket(); 3305 | if (receive.type !== PacketType.EOF_Packet) { 3306 | throw new ProtocolError(); 3307 | } 3308 | } 3309 | if (!iterator) { 3310 | while(true){ 3311 | receive = await this.nextPacket(); 3312 | if (receive.type === PacketType.EOF_Packet) { 3313 | break; 3314 | } else { 3315 | const row = parseRow(receive.body, fields); 3316 | rows.push(row); 3317 | } 3318 | } 3319 | return { 3320 | rows, 3321 | fields 3322 | }; 3323 | } 3324 | return { 3325 | fields, 3326 | iterator: this.buildIterator(fields) 3327 | }; 3328 | } catch (error) { 3329 | this.close(); 3330 | throw error; 3331 | } 3332 | } 3333 | buildIterator(fields) { 3334 | const next = async ()=>{ 3335 | const receive = await this.nextPacket(); 3336 | if (receive.type === PacketType.EOF_Packet) { 3337 | return { 3338 | done: true 3339 | }; 3340 | } 3341 | const value = parseRow(receive.body, fields); 3342 | return { 3343 | done: false, 3344 | value 3345 | }; 3346 | }; 3347 | return { 3348 | [Symbol.asyncIterator]: ()=>{ 3349 | return { 3350 | next 3351 | }; 3352 | } 3353 | }; 3354 | } 3355 | } 3356 | class DeferredStack { 3357 | _maxSize; 3358 | _array; 3359 | creator; 3360 | _queue = []; 3361 | _size = 0; 3362 | constructor(_maxSize, _array = [], creator){ 3363 | this._maxSize = _maxSize; 3364 | this._array = _array; 3365 | this.creator = creator; 3366 | this._size = _array.length; 3367 | } 3368 | get size() { 3369 | return this._size; 3370 | } 3371 | get maxSize() { 3372 | return this._maxSize; 3373 | } 3374 | get available() { 3375 | return this._array.length; 3376 | } 3377 | async pop() { 3378 | if (this._array.length) { 3379 | return this._array.pop(); 3380 | } else if (this._size < this._maxSize) { 3381 | this._size++; 3382 | let item; 3383 | try { 3384 | item = await this.creator(); 3385 | } catch (err) { 3386 | this._size--; 3387 | throw err; 3388 | } 3389 | return item; 3390 | } 3391 | const defer = deferred(); 3392 | this._queue.push(defer); 3393 | return await defer; 3394 | } 3395 | push(item) { 3396 | if (this._queue.length) { 3397 | this._queue.shift().resolve(item); 3398 | return false; 3399 | } else { 3400 | this._array.push(item); 3401 | return true; 3402 | } 3403 | } 3404 | tryPopAvailable() { 3405 | return this._array.pop(); 3406 | } 3407 | remove(item) { 3408 | const index = this._array.indexOf(item); 3409 | if (index < 0) return false; 3410 | this._array.splice(index, 1); 3411 | this._size--; 3412 | return true; 3413 | } 3414 | reduceSize() { 3415 | this._size--; 3416 | } 3417 | } 3418 | class PoolConnection extends Connection1 { 3419 | _pool = undefined; 3420 | _idleTimer = undefined; 3421 | _idle = false; 3422 | enterIdle() { 3423 | this._idle = true; 3424 | if (this.config.idleTimeout) { 3425 | this._idleTimer = setTimeout(()=>{ 3426 | logger.info("connection idle timeout"); 3427 | this._pool.remove(this); 3428 | try { 3429 | this.close(); 3430 | } catch (error) { 3431 | logger.warning(`error closing idle connection`, error); 3432 | } 3433 | }, this.config.idleTimeout); 3434 | } 3435 | } 3436 | exitIdle() { 3437 | this._idle = false; 3438 | if (this._idleTimer !== undefined) { 3439 | clearTimeout(this._idleTimer); 3440 | } 3441 | } 3442 | removeFromPool() { 3443 | this._pool.reduceSize(); 3444 | this._pool = undefined; 3445 | } 3446 | returnToPool() { 3447 | this._pool?.push(this); 3448 | } 3449 | } 3450 | class ConnectionPool { 3451 | _deferred; 3452 | _connections = []; 3453 | _closed = false; 3454 | constructor(maxSize, creator){ 3455 | this._deferred = new DeferredStack(maxSize, this._connections, async ()=>{ 3456 | const conn = await creator(); 3457 | conn._pool = this; 3458 | return conn; 3459 | }); 3460 | } 3461 | get info() { 3462 | return { 3463 | size: this._deferred.size, 3464 | maxSize: this._deferred.maxSize, 3465 | available: this._deferred.available 3466 | }; 3467 | } 3468 | push(conn) { 3469 | if (this._closed) { 3470 | conn.close(); 3471 | this.reduceSize(); 3472 | } 3473 | if (this._deferred.push(conn)) { 3474 | conn.enterIdle(); 3475 | } 3476 | } 3477 | async pop() { 3478 | if (this._closed) { 3479 | throw new Error("Connection pool is closed"); 3480 | } 3481 | let conn = this._deferred.tryPopAvailable(); 3482 | if (conn) { 3483 | conn.exitIdle(); 3484 | } else { 3485 | conn = await this._deferred.pop(); 3486 | } 3487 | return conn; 3488 | } 3489 | remove(conn) { 3490 | return this._deferred.remove(conn); 3491 | } 3492 | close() { 3493 | this._closed = true; 3494 | let conn; 3495 | while(conn = this._deferred.tryPopAvailable()){ 3496 | conn.exitIdle(); 3497 | conn.close(); 3498 | this.reduceSize(); 3499 | } 3500 | } 3501 | reduceSize() { 3502 | this._deferred.reduceSize(); 3503 | } 3504 | } 3505 | class Client1 { 3506 | config = { 3507 | }; 3508 | _pool; 3509 | async createConnection() { 3510 | let connection = new PoolConnection(this.config); 3511 | await connection.connect(); 3512 | return connection; 3513 | } 3514 | get pool() { 3515 | return this._pool?.info; 3516 | } 3517 | async connect(config) { 3518 | this.config = { 3519 | hostname: "127.0.0.1", 3520 | username: "root", 3521 | port: 3306, 3522 | poolSize: 1, 3523 | timeout: 30 * 1000, 3524 | idleTimeout: 4 * 3600 * 1000, 3525 | ...config 3526 | }; 3527 | Object.freeze(this.config); 3528 | this._pool = new ConnectionPool(this.config.poolSize || 10, this.createConnection.bind(this)); 3529 | return this; 3530 | } 3531 | async query(sql, params) { 3532 | return await this.useConnection(async (connection)=>{ 3533 | return await connection.query(sql, params); 3534 | }); 3535 | } 3536 | async execute(sql, params) { 3537 | return await this.useConnection(async (connection)=>{ 3538 | return await connection.execute(sql, params); 3539 | }); 3540 | } 3541 | async useConnection(fn) { 3542 | if (!this._pool) { 3543 | throw new Error("Unconnected"); 3544 | } 3545 | const connection = await this._pool.pop(); 3546 | try { 3547 | return await fn(connection); 3548 | } finally{ 3549 | if (connection.state == ConnectionState.CLOSED) { 3550 | connection.removeFromPool(); 3551 | } else { 3552 | connection.returnToPool(); 3553 | } 3554 | } 3555 | } 3556 | async transaction(processor) { 3557 | return await this.useConnection(async (connection)=>{ 3558 | try { 3559 | await connection.execute("BEGIN"); 3560 | const result = await processor(connection); 3561 | await connection.execute("COMMIT"); 3562 | return result; 3563 | } catch (error) { 3564 | if (connection.state == ConnectionState.CONNECTED) { 3565 | logger.info(`ROLLBACK: ${error.message}`); 3566 | await connection.execute("ROLLBACK"); 3567 | } 3568 | throw error; 3569 | } 3570 | }); 3571 | } 3572 | async close() { 3573 | if (this._pool) { 3574 | this._pool.close(); 3575 | this._pool = undefined; 3576 | } 3577 | } 3578 | } 3579 | export { Client1 as Client }; 3580 | export { Connection1 as Connection }; 3581 | export { configLogger1 as configLogger }; 3582 | export { mod as log }; 3583 | 3584 | 3585 | --------------------------------------------------------------------------------