parent
8910c59468
commit
bc59053d11
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Eslint config file
|
||||
* Documentation: https://eslint.org/docs/user-guide/configuring/
|
||||
* Install the Eslint extension before using this feature.
|
||||
*/
|
||||
module.exports = {
|
||||
env: {
|
||||
es6: true,
|
||||
browser: true,
|
||||
node: true,
|
||||
},
|
||||
ecmaFeatures: {
|
||||
modules: true,
|
||||
},
|
||||
parserOptions: {
|
||||
ecmaVersion: 2018,
|
||||
sourceType: 'module',
|
||||
},
|
||||
globals: {
|
||||
wx: true,
|
||||
App: true,
|
||||
Page: true,
|
||||
getCurrentPages: true,
|
||||
getApp: true,
|
||||
Component: true,
|
||||
requirePlugin: true,
|
||||
requireMiniProgram: true,
|
||||
},
|
||||
// extends: 'eslint:recommended',
|
||||
rules: {},
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"permissions": {
|
||||
"openapi": [
|
||||
]
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*|*MINGW*|*MSYS*)
|
||||
if command -v cygpath > /dev/null 2>&1; then
|
||||
basedir=`cygpath -w "$basedir"`
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../node-xlsx/dist/bin/cli.js" "$@"
|
||||
else
|
||||
exec node "$basedir/../node-xlsx/dist/bin/cli.js" "$@"
|
||||
fi
|
@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\node-xlsx\dist\bin\cli.js" %*
|
@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../node-xlsx/dist/bin/cli.js" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../node-xlsx/dist/bin/cli.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../node-xlsx/dist/bin/cli.js" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../node-xlsx/dist/bin/cli.js" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*|*MINGW*|*MSYS*)
|
||||
if command -v cygpath > /dev/null 2>&1; then
|
||||
basedir=`cygpath -w "$basedir"`
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../semver/bin/semver" "$@"
|
||||
else
|
||||
exec node "$basedir/../semver/bin/semver" "$@"
|
||||
fi
|
@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\semver\bin\semver" %*
|
@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../semver/bin/semver" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../semver/bin/semver" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../semver/bin/semver" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../semver/bin/semver" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*|*MINGW*|*MSYS*)
|
||||
if command -v cygpath > /dev/null 2>&1; then
|
||||
basedir=`cygpath -w "$basedir"`
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../sshpk/bin/sshpk-conv" "$@"
|
||||
else
|
||||
exec node "$basedir/../sshpk/bin/sshpk-conv" "$@"
|
||||
fi
|
@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\sshpk\bin\sshpk-conv" %*
|
@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../sshpk/bin/sshpk-conv" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../sshpk/bin/sshpk-conv" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../sshpk/bin/sshpk-conv" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../sshpk/bin/sshpk-conv" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*|*MINGW*|*MSYS*)
|
||||
if command -v cygpath > /dev/null 2>&1; then
|
||||
basedir=`cygpath -w "$basedir"`
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../sshpk/bin/sshpk-sign" "$@"
|
||||
else
|
||||
exec node "$basedir/../sshpk/bin/sshpk-sign" "$@"
|
||||
fi
|
@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\sshpk\bin\sshpk-sign" %*
|
@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../sshpk/bin/sshpk-sign" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../sshpk/bin/sshpk-sign" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../sshpk/bin/sshpk-sign" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../sshpk/bin/sshpk-sign" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*|*MINGW*|*MSYS*)
|
||||
if command -v cygpath > /dev/null 2>&1; then
|
||||
basedir=`cygpath -w "$basedir"`
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../sshpk/bin/sshpk-verify" "$@"
|
||||
else
|
||||
exec node "$basedir/../sshpk/bin/sshpk-verify" "$@"
|
||||
fi
|
@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\sshpk\bin\sshpk-verify" %*
|
@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../sshpk/bin/sshpk-verify" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../sshpk/bin/sshpk-verify" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../sshpk/bin/sshpk-verify" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../sshpk/bin/sshpk-verify" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*|*MINGW*|*MSYS*)
|
||||
if command -v cygpath > /dev/null 2>&1; then
|
||||
basedir=`cygpath -w "$basedir"`
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../uuid/bin/uuid" "$@"
|
||||
else
|
||||
exec node "$basedir/../uuid/bin/uuid" "$@"
|
||||
fi
|
@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\uuid\bin\uuid" %*
|
@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../uuid/bin/uuid" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../uuid/bin/uuid" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../uuid/bin/uuid" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../uuid/bin/uuid" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*|*MINGW*|*MSYS*)
|
||||
if command -v cygpath > /dev/null 2>&1; then
|
||||
basedir=`cygpath -w "$basedir"`
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../xlsx/bin/xlsx.njs" "$@"
|
||||
else
|
||||
exec node "$basedir/../xlsx/bin/xlsx.njs" "$@"
|
||||
fi
|
@ -0,0 +1,17 @@
|
||||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\xlsx\bin\xlsx.njs" %*
|
@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../xlsx/bin/xlsx.njs" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../xlsx/bin/xlsx.njs" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../xlsx/bin/xlsx.njs" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../xlsx/bin/xlsx.njs" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,9 @@
|
||||
root = true
|
||||
|
||||
[!{node_modules}/**]
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
|
||||
[{*.js,*.ts}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
@ -0,0 +1 @@
|
||||
dist/
|
@ -0,0 +1,43 @@
|
||||
{
|
||||
"extends": [
|
||||
"prettier"
|
||||
],
|
||||
"plugins": [
|
||||
"typescript"
|
||||
],
|
||||
"rules": {
|
||||
"indent": [
|
||||
"error",
|
||||
2,
|
||||
{
|
||||
"SwitchCase": 1,
|
||||
"flatTernaryExpressions": true
|
||||
}
|
||||
],
|
||||
"no-unused-vars": "warn",
|
||||
"typescript/no-unused-vars": "warn",
|
||||
"semi": [
|
||||
"error",
|
||||
"never"
|
||||
],
|
||||
"quotes": [
|
||||
"error",
|
||||
"single",
|
||||
{
|
||||
"avoidEscape": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"env": {
|
||||
"es6": true,
|
||||
"node": true
|
||||
},
|
||||
"parser": "typescript-eslint-parser",
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2018,
|
||||
"sourceType": "module",
|
||||
"ecmaFeatures": {
|
||||
"modules": true
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
module.exports = {
|
||||
// 一行最多 100 字符
|
||||
printWidth: 100,
|
||||
// 使用 2 个空格缩进
|
||||
tabWidth: 2,
|
||||
// 不使用缩进符,而使用空格
|
||||
useTabs: false,
|
||||
// 行尾无分号
|
||||
semi: false,
|
||||
// 使用单引号
|
||||
singleQuote: true,
|
||||
// 对象的 key 仅在必要时用引号
|
||||
quoteProps: 'as-needed',
|
||||
// 末尾不需要逗号
|
||||
trailingComma: 'none',
|
||||
// 大括号内的首尾需要空格
|
||||
bracketSpacing: true,
|
||||
// 每个文件格式化的范围是文件的全部内容
|
||||
rangeStart: 0,
|
||||
rangeEnd: Infinity,
|
||||
// 不需要写文件开头的 @prettier
|
||||
requirePragma: false,
|
||||
// 不需要自动在文件开头插入 @prettier
|
||||
insertPragma: false,
|
||||
// 使用默认的折行标准
|
||||
proseWrap: 'preserve',
|
||||
// 换行符使用 lf
|
||||
endOfLine: 'lf'
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
export declare class ObjectId {
|
||||
id: string;
|
||||
constructor({ id }?: {
|
||||
id?: string;
|
||||
});
|
||||
readonly _internalType: import("../utils/symbol").InternalSymbol;
|
||||
parse(): {
|
||||
$oid: string;
|
||||
};
|
||||
}
|
||||
export declare function ObjectIdConstructor(opt: any): ObjectId;
|
@ -0,0 +1,21 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const symbol_1 = require("../helper/symbol");
|
||||
class ObjectId {
|
||||
constructor({ id = '' } = {}) {
|
||||
this.id = id;
|
||||
}
|
||||
get _internalType() {
|
||||
return symbol_1.SYMBOL_OBJECTID;
|
||||
}
|
||||
parse() {
|
||||
return {
|
||||
$oid: this.id
|
||||
};
|
||||
}
|
||||
}
|
||||
exports.ObjectId = ObjectId;
|
||||
function ObjectIdConstructor(opt) {
|
||||
return new ObjectId(opt);
|
||||
}
|
||||
exports.ObjectIdConstructor = ObjectIdConstructor;
|
@ -0,0 +1,29 @@
|
||||
export default class Aggregation {
|
||||
_db: any;
|
||||
_request: any;
|
||||
_stages: any[];
|
||||
_collectionName: string;
|
||||
constructor(db?: any, collectionName?: any, rawPipeline?: any);
|
||||
end(): Promise<any>;
|
||||
unwrap(): any[];
|
||||
done(): {
|
||||
[x: number]: any;
|
||||
}[];
|
||||
_pipe(stage: any, param: any, raw?: boolean): this;
|
||||
addFields(param: any): this;
|
||||
bucket(param: any): this;
|
||||
bucketAuto(param: any): this;
|
||||
count(param: any): this;
|
||||
geoNear(param: any): this;
|
||||
group(param: any): this;
|
||||
limit(param: any): this;
|
||||
match(param: any): this;
|
||||
project(param: any): this;
|
||||
lookup(param: any): this;
|
||||
replaceRoot(param: any): this;
|
||||
sample(param: any): this;
|
||||
skip(param: any): this;
|
||||
sort(param: any): this;
|
||||
sortByCount(param: any): this;
|
||||
unwind(param: any): this;
|
||||
}
|
124
CLASS1/cloudfunctions/excel/node_modules/@cloudbase/database/dist/commonjs/aggregate.js
generated
vendored
124
CLASS1/cloudfunctions/excel/node_modules/@cloudbase/database/dist/commonjs/aggregate.js
generated
vendored
@ -0,0 +1,124 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const index_1 = require("./index");
|
||||
const bson_1 = require("bson");
|
||||
const query_1 = require("./serializer/query");
|
||||
const utils_1 = require("./utils/utils");
|
||||
const type_1 = require("./utils/type");
|
||||
const validate_1 = require("./validate");
|
||||
const point_1 = require("./geo/point");
|
||||
class Aggregation {
|
||||
constructor(db, collectionName, rawPipeline) {
|
||||
this._stages = [];
|
||||
if (db && collectionName) {
|
||||
this._db = db;
|
||||
this._request = new index_1.Db.reqClass(this._db.config);
|
||||
this._collectionName = collectionName;
|
||||
if (rawPipeline && rawPipeline.length > 0) {
|
||||
rawPipeline.forEach((stage) => {
|
||||
validate_1.Validate.isValidAggregation(stage);
|
||||
const stageName = Object.keys(stage)[0];
|
||||
this._pipe(stageName, stage[stageName], true);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
async end() {
|
||||
if (!this._collectionName || !this._db) {
|
||||
throw new Error('Aggregation pipeline cannot send request');
|
||||
}
|
||||
const result = await this._request.send('database.aggregateDocuments', {
|
||||
collectionName: this._collectionName,
|
||||
stages: this._stages
|
||||
});
|
||||
if (result && result.data && result.data.list) {
|
||||
return {
|
||||
requestId: result.requestId,
|
||||
data: result.data.list.map(bson_1.EJSON.parse)
|
||||
};
|
||||
}
|
||||
return result;
|
||||
}
|
||||
unwrap() {
|
||||
return this._stages;
|
||||
}
|
||||
done() {
|
||||
return this._stages.map(({ stageKey, stageValue }) => {
|
||||
return {
|
||||
[stageKey]: JSON.parse(stageValue)
|
||||
};
|
||||
});
|
||||
}
|
||||
_pipe(stage, param, raw = false) {
|
||||
let transformParam = '';
|
||||
if (type_1.getType(param) === 'object') {
|
||||
transformParam = utils_1.stringifyByEJSON(param);
|
||||
}
|
||||
else {
|
||||
transformParam = JSON.stringify(param);
|
||||
}
|
||||
this._stages.push({
|
||||
stageKey: raw ? stage : `$${stage}`,
|
||||
stageValue: transformParam
|
||||
});
|
||||
return this;
|
||||
}
|
||||
addFields(param) {
|
||||
return this._pipe('addFields', param);
|
||||
}
|
||||
bucket(param) {
|
||||
return this._pipe('bucket', param);
|
||||
}
|
||||
bucketAuto(param) {
|
||||
return this._pipe('bucketAuto', param);
|
||||
}
|
||||
count(param) {
|
||||
return this._pipe('count', param);
|
||||
}
|
||||
geoNear(param) {
|
||||
if (param.query) {
|
||||
param.query = query_1.QuerySerializer.encode(param.query);
|
||||
}
|
||||
if (param.distanceMultiplier && typeof (param.distanceMultiplier) === 'number') {
|
||||
param.distanceMultiplier = param.distanceMultiplier;
|
||||
}
|
||||
if (param.near) {
|
||||
param.near = new point_1.Point(param.near.longitude, param.near.latitude).toJSON();
|
||||
}
|
||||
return this._pipe('geoNear', param);
|
||||
}
|
||||
group(param) {
|
||||
return this._pipe('group', param);
|
||||
}
|
||||
limit(param) {
|
||||
return this._pipe('limit', param);
|
||||
}
|
||||
match(param) {
|
||||
return this._pipe('match', query_1.QuerySerializer.encode(param));
|
||||
}
|
||||
project(param) {
|
||||
return this._pipe('project', param);
|
||||
}
|
||||
lookup(param) {
|
||||
return this._pipe('lookup', param);
|
||||
}
|
||||
replaceRoot(param) {
|
||||
return this._pipe('replaceRoot', param);
|
||||
}
|
||||
sample(param) {
|
||||
return this._pipe('sample', param);
|
||||
}
|
||||
skip(param) {
|
||||
return this._pipe('skip', param);
|
||||
}
|
||||
sort(param) {
|
||||
return this._pipe('sort', param);
|
||||
}
|
||||
sortByCount(param) {
|
||||
return this._pipe('sortByCount', param);
|
||||
}
|
||||
unwind(param) {
|
||||
return this._pipe('unwind', param);
|
||||
}
|
||||
}
|
||||
exports.default = Aggregation;
|
@ -0,0 +1,17 @@
|
||||
import { DocumentReference } from './document';
|
||||
import { Query, QueryOption, UpdateOption } from './query';
|
||||
import Aggregation from './aggregate';
|
||||
export declare class CollectionReference extends Query {
|
||||
protected _transactionId: string;
|
||||
readonly name: string;
|
||||
doc(docID: string | number): DocumentReference;
|
||||
add(data: any): Promise<{
|
||||
ids?: string[];
|
||||
id?: string;
|
||||
inserted?: number;
|
||||
ok?: number;
|
||||
requestId: string;
|
||||
}>;
|
||||
aggregate(rawPipeline?: object[]): Aggregation;
|
||||
options(apiOptions: QueryOption | UpdateOption): CollectionReference;
|
||||
}
|
72
CLASS1/cloudfunctions/excel/node_modules/@cloudbase/database/dist/commonjs/collection.js
generated
vendored
72
CLASS1/cloudfunctions/excel/node_modules/@cloudbase/database/dist/commonjs/collection.js
generated
vendored
@ -0,0 +1,72 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const document_1 = require("./document");
|
||||
const query_1 = require("./query");
|
||||
const aggregate_1 = require("./aggregate");
|
||||
const datatype_1 = require("./serializer/datatype");
|
||||
const utils_1 = require("./utils/utils");
|
||||
const validate_1 = require("./validate");
|
||||
const type_1 = require("./utils/type");
|
||||
class CollectionReference extends query_1.Query {
|
||||
constructor(db, coll, apiOptions, transactionId) {
|
||||
super(db, coll, '', apiOptions, transactionId);
|
||||
if (transactionId) {
|
||||
this._transactionId = transactionId;
|
||||
}
|
||||
}
|
||||
get name() {
|
||||
return this._coll;
|
||||
}
|
||||
doc(docID) {
|
||||
if (typeof docID !== 'string' && typeof docID !== 'number') {
|
||||
throw new Error('docId必须为字符串或数字');
|
||||
}
|
||||
return new document_1.DocumentReference(this._db, this._coll, this._apiOptions, docID, this._transactionId);
|
||||
}
|
||||
async add(data) {
|
||||
let transformData = data;
|
||||
if (!type_1.isArray(data)) {
|
||||
transformData = [data];
|
||||
}
|
||||
transformData = transformData.map(item => {
|
||||
return utils_1.stringifyByEJSON(datatype_1.serialize(item));
|
||||
});
|
||||
let params = {
|
||||
collectionName: this._coll,
|
||||
data: transformData
|
||||
};
|
||||
if (this._transactionId) {
|
||||
params.transactionId = this._transactionId;
|
||||
}
|
||||
const res = await this._request.send('database.insertDocument', params, utils_1.getReqOpts(this._apiOptions));
|
||||
if (res.code) {
|
||||
return res;
|
||||
}
|
||||
if (!type_1.isArray(data)) {
|
||||
if (this._transactionId) {
|
||||
return {
|
||||
inserted: 1,
|
||||
ok: 1,
|
||||
id: res.data.insertedIds[0],
|
||||
requestId: res.requestId
|
||||
};
|
||||
}
|
||||
return {
|
||||
id: res.data.insertedIds[0],
|
||||
requestId: res.requestId
|
||||
};
|
||||
}
|
||||
return {
|
||||
ids: res.data.insertedIds,
|
||||
requestId: res.requestId
|
||||
};
|
||||
}
|
||||
aggregate(rawPipeline = []) {
|
||||
return new aggregate_1.default(this._db, this._coll, (this._apiOptions.raw || false) ? rawPipeline : []);
|
||||
}
|
||||
options(apiOptions) {
|
||||
validate_1.Validate.isValidOptions(apiOptions);
|
||||
return new CollectionReference(this._db, this._coll, apiOptions, this._transactionId);
|
||||
}
|
||||
}
|
||||
exports.CollectionReference = CollectionReference;
|
175
CLASS1/cloudfunctions/excel/node_modules/@cloudbase/database/dist/commonjs/command.d.ts
generated
vendored
175
CLASS1/cloudfunctions/excel/node_modules/@cloudbase/database/dist/commonjs/command.d.ts
generated
vendored
@ -0,0 +1,175 @@
|
||||
import { QueryCommand } from './commands/query';
|
||||
import { LogicCommand } from './commands/logic';
|
||||
import { UpdateCommand } from './commands/update';
|
||||
import Aggregation from './aggregate';
|
||||
export declare type IQueryCondition = Record<string, any> | LogicCommand;
|
||||
export declare const Command: {
|
||||
eq(val: any): QueryCommand;
|
||||
neq(val: any): QueryCommand;
|
||||
lt(val: any): QueryCommand;
|
||||
lte(val: any): QueryCommand;
|
||||
gt(val: any): QueryCommand;
|
||||
gte(val: any): QueryCommand;
|
||||
in(val: any): QueryCommand;
|
||||
nin(val: any): QueryCommand;
|
||||
all(val: any): QueryCommand;
|
||||
elemMatch(val: any): QueryCommand;
|
||||
exists(val: boolean): QueryCommand;
|
||||
size(val: number): QueryCommand;
|
||||
mod(): QueryCommand;
|
||||
geoNear(val: any): QueryCommand;
|
||||
geoWithin(val: any): QueryCommand;
|
||||
geoIntersects(val: any): QueryCommand;
|
||||
and(...__expressions__: import("./serializer/datatype").IQueryCondition[]): LogicCommand;
|
||||
nor(...__expressions__: import("./serializer/datatype").IQueryCondition[]): LogicCommand;
|
||||
or(...__expressions__: import("./serializer/datatype").IQueryCondition[]): LogicCommand;
|
||||
not(...__expressions__: import("./serializer/datatype").IQueryCondition[]): LogicCommand;
|
||||
set(val: any): UpdateCommand;
|
||||
remove(): UpdateCommand;
|
||||
inc(val: number): UpdateCommand;
|
||||
mul(val: number): UpdateCommand;
|
||||
push(...args: any[]): UpdateCommand;
|
||||
pull(values: any): UpdateCommand;
|
||||
pullAll(values: any): UpdateCommand;
|
||||
pop(): UpdateCommand;
|
||||
shift(): UpdateCommand;
|
||||
unshift(...__values__: any[]): UpdateCommand;
|
||||
addToSet(values: any): UpdateCommand;
|
||||
rename(values: any): UpdateCommand;
|
||||
bit(values: any): UpdateCommand;
|
||||
max(values: any): UpdateCommand;
|
||||
min(values: any): UpdateCommand;
|
||||
expr(values: AggregationOperator): {
|
||||
$expr: AggregationOperator;
|
||||
};
|
||||
jsonSchema(schema: any): {
|
||||
$jsonSchema: any;
|
||||
};
|
||||
text(values: string | {
|
||||
search: string;
|
||||
language?: string;
|
||||
caseSensitive?: boolean;
|
||||
diacriticSensitive: boolean;
|
||||
}): {
|
||||
$search: {
|
||||
(regexp: string | RegExp): number;
|
||||
(searcher: {
|
||||
[Symbol.search](string: string): number;
|
||||
}): number;
|
||||
};
|
||||
$language?: undefined;
|
||||
$caseSensitive?: undefined;
|
||||
$diacriticSensitive?: undefined;
|
||||
} | {
|
||||
$search: string;
|
||||
$language: string;
|
||||
$caseSensitive: boolean;
|
||||
$diacriticSensitive: boolean;
|
||||
};
|
||||
aggregate: {
|
||||
pipeline(): Aggregation;
|
||||
abs: (param: any) => AggregationOperator;
|
||||
add: (param: any) => AggregationOperator;
|
||||
ceil: (param: any) => AggregationOperator;
|
||||
divide: (param: any) => AggregationOperator;
|
||||
exp: (param: any) => AggregationOperator;
|
||||
floor: (param: any) => AggregationOperator;
|
||||
ln: (param: any) => AggregationOperator;
|
||||
log: (param: any) => AggregationOperator;
|
||||
log10: (param: any) => AggregationOperator;
|
||||
mod: (param: any) => AggregationOperator;
|
||||
multiply: (param: any) => AggregationOperator;
|
||||
pow: (param: any) => AggregationOperator;
|
||||
sqrt: (param: any) => AggregationOperator;
|
||||
subtract: (param: any) => AggregationOperator;
|
||||
trunc: (param: any) => AggregationOperator;
|
||||
arrayElemAt: (param: any) => AggregationOperator;
|
||||
arrayToObject: (param: any) => AggregationOperator;
|
||||
concatArrays: (param: any) => AggregationOperator;
|
||||
filter: (param: any) => AggregationOperator;
|
||||
in: (param: any) => AggregationOperator;
|
||||
indexOfArray: (param: any) => AggregationOperator;
|
||||
isArray: (param: any) => AggregationOperator;
|
||||
map: (param: any) => AggregationOperator;
|
||||
range: (param: any) => AggregationOperator;
|
||||
reduce: (param: any) => AggregationOperator;
|
||||
reverseArray: (param: any) => AggregationOperator;
|
||||
size: (param: any) => AggregationOperator;
|
||||
slice: (param: any) => AggregationOperator;
|
||||
zip: (param: any) => AggregationOperator;
|
||||
and: (param: any) => AggregationOperator;
|
||||
not: (param: any) => AggregationOperator;
|
||||
or: (param: any) => AggregationOperator;
|
||||
cmp: (param: any) => AggregationOperator;
|
||||
eq: (param: any) => AggregationOperator;
|
||||
gt: (param: any) => AggregationOperator;
|
||||
gte: (param: any) => AggregationOperator;
|
||||
lt: (param: any) => AggregationOperator;
|
||||
lte: (param: any) => AggregationOperator;
|
||||
neq: (param: any) => AggregationOperator;
|
||||
cond: (param: any) => AggregationOperator;
|
||||
ifNull: (param: any) => AggregationOperator;
|
||||
switch: (param: any) => AggregationOperator;
|
||||
dateFromParts: (param: any) => AggregationOperator;
|
||||
dateFromString: (param: any) => AggregationOperator;
|
||||
dayOfMonth: (param: any) => AggregationOperator;
|
||||
dayOfWeek: (param: any) => AggregationOperator;
|
||||
dayOfYear: (param: any) => AggregationOperator;
|
||||
isoDayOfWeek: (param: any) => AggregationOperator;
|
||||
isoWeek: (param: any) => AggregationOperator;
|
||||
isoWeekYear: (param: any) => AggregationOperator;
|
||||
millisecond: (param: any) => AggregationOperator;
|
||||
minute: (param: any) => AggregationOperator;
|
||||
month: (param: any) => AggregationOperator;
|
||||
second: (param: any) => AggregationOperator;
|
||||
hour: (param: any) => AggregationOperator;
|
||||
week: (param: any) => AggregationOperator;
|
||||
year: (param: any) => AggregationOperator;
|
||||
literal: (param: any) => AggregationOperator;
|
||||
mergeObjects: (param: any) => AggregationOperator;
|
||||
objectToArray: (param: any) => AggregationOperator;
|
||||
allElementsTrue: (param: any) => AggregationOperator;
|
||||
anyElementTrue: (param: any) => AggregationOperator;
|
||||
setDifference: (param: any) => AggregationOperator;
|
||||
setEquals: (param: any) => AggregationOperator;
|
||||
setIntersection: (param: any) => AggregationOperator;
|
||||
setIsSubset: (param: any) => AggregationOperator;
|
||||
setUnion: (param: any) => AggregationOperator;
|
||||
concat: (param: any) => AggregationOperator;
|
||||
dateToString: (param: any) => AggregationOperator;
|
||||
indexOfBytes: (param: any) => AggregationOperator;
|
||||
indexOfCP: (param: any) => AggregationOperator;
|
||||
split: (param: any) => AggregationOperator;
|
||||
strLenBytes: (param: any) => AggregationOperator;
|
||||
strLenCP: (param: any) => AggregationOperator;
|
||||
strcasecmp: (param: any) => AggregationOperator;
|
||||
substr: (param: any) => AggregationOperator;
|
||||
substrBytes: (param: any) => AggregationOperator;
|
||||
substrCP: (param: any) => AggregationOperator;
|
||||
toLower: (param: any) => AggregationOperator;
|
||||
toUpper: (param: any) => AggregationOperator;
|
||||
meta: (param: any) => AggregationOperator;
|
||||
addToSet: (param: any) => AggregationOperator;
|
||||
avg: (param: any) => AggregationOperator;
|
||||
first: (param: any) => AggregationOperator;
|
||||
last: (param: any) => AggregationOperator;
|
||||
max: (param: any) => AggregationOperator;
|
||||
min: (param: any) => AggregationOperator;
|
||||
push: (param: any) => AggregationOperator;
|
||||
stdDevPop: (param: any) => AggregationOperator;
|
||||
stdDevSamp: (param: any) => AggregationOperator;
|
||||
sum: (param: any) => AggregationOperator;
|
||||
let: (param: any) => AggregationOperator;
|
||||
};
|
||||
project: {
|
||||
slice: (param: any) => ProjectionOperator;
|
||||
elemMatch: (param: any) => ProjectionOperator;
|
||||
};
|
||||
};
|
||||
export declare class AggregationOperator {
|
||||
constructor(name: any, param: any);
|
||||
}
|
||||
export declare class ProjectionOperator {
|
||||
constructor(name: any, param: any);
|
||||
}
|
||||
export default Command;
|
285
CLASS1/cloudfunctions/excel/node_modules/@cloudbase/database/dist/commonjs/command.js
generated
vendored
285
CLASS1/cloudfunctions/excel/node_modules/@cloudbase/database/dist/commonjs/command.js
generated
vendored
@ -0,0 +1,285 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const query_1 = require("./commands/query");
|
||||
const logic_1 = require("./commands/logic");
|
||||
const update_1 = require("./commands/update");
|
||||
const type_1 = require("./utils/type");
|
||||
const aggregate_1 = require("./aggregate");
|
||||
exports.Command = {
|
||||
eq(val) {
|
||||
return new query_1.QueryCommand(query_1.QUERY_COMMANDS_LITERAL.EQ, [val]);
|
||||
},
|
||||
neq(val) {
|
||||
return new query_1.QueryCommand(query_1.QUERY_COMMANDS_LITERAL.NEQ, [val]);
|
||||
},
|
||||
lt(val) {
|
||||
return new query_1.QueryCommand(query_1.QUERY_COMMANDS_LITERAL.LT, [val]);
|
||||
},
|
||||
lte(val) {
|
||||
return new query_1.QueryCommand(query_1.QUERY_COMMANDS_LITERAL.LTE, [val]);
|
||||
},
|
||||
gt(val) {
|
||||
return new query_1.QueryCommand(query_1.QUERY_COMMANDS_LITERAL.GT, [val]);
|
||||
},
|
||||
gte(val) {
|
||||
return new query_1.QueryCommand(query_1.QUERY_COMMANDS_LITERAL.GTE, [val]);
|
||||
},
|
||||
in(val) {
|
||||
return new query_1.QueryCommand(query_1.QUERY_COMMANDS_LITERAL.IN, val);
|
||||
},
|
||||
nin(val) {
|
||||
return new query_1.QueryCommand(query_1.QUERY_COMMANDS_LITERAL.NIN, val);
|
||||
},
|
||||
all(val) {
|
||||
return new query_1.QueryCommand(query_1.QUERY_COMMANDS_LITERAL.ALL, val);
|
||||
},
|
||||
elemMatch(val) {
|
||||
return new query_1.QueryCommand(query_1.QUERY_COMMANDS_LITERAL.ELEM_MATCH, [val]);
|
||||
},
|
||||
exists(val) {
|
||||
return new query_1.QueryCommand(query_1.QUERY_COMMANDS_LITERAL.EXISTS, [val]);
|
||||
},
|
||||
size(val) {
|
||||
return new query_1.QueryCommand(query_1.QUERY_COMMANDS_LITERAL.SIZE, [val]);
|
||||
},
|
||||
mod() {
|
||||
if (arguments.length == 1)
|
||||
return new query_1.QueryCommand(query_1.QUERY_COMMANDS_LITERAL.MOD, [arguments[0]]);
|
||||
if (arguments.length == 2)
|
||||
return new query_1.QueryCommand(query_1.QUERY_COMMANDS_LITERAL.MOD, [[arguments[0], arguments[1]]]);
|
||||
return new query_1.QueryCommand(query_1.QUERY_COMMANDS_LITERAL.MOD, arguments);
|
||||
},
|
||||
geoNear(val) {
|
||||
return new query_1.QueryCommand(query_1.QUERY_COMMANDS_LITERAL.GEO_NEAR, [val]);
|
||||
},
|
||||
geoWithin(val) {
|
||||
return new query_1.QueryCommand(query_1.QUERY_COMMANDS_LITERAL.GEO_WITHIN, [val]);
|
||||
},
|
||||
geoIntersects(val) {
|
||||
return new query_1.QueryCommand(query_1.QUERY_COMMANDS_LITERAL.GEO_INTERSECTS, [val]);
|
||||
},
|
||||
and(...__expressions__) {
|
||||
const expressions = type_1.isArray(arguments[0]) ? arguments[0] : Array.from(arguments);
|
||||
return new logic_1.LogicCommand(logic_1.LOGIC_COMMANDS_LITERAL.AND, expressions);
|
||||
},
|
||||
nor(...__expressions__) {
|
||||
const expressions = type_1.isArray(arguments[0]) ? arguments[0] : Array.from(arguments);
|
||||
return new logic_1.LogicCommand(logic_1.LOGIC_COMMANDS_LITERAL.NOR, expressions);
|
||||
},
|
||||
or(...__expressions__) {
|
||||
const expressions = type_1.isArray(arguments[0]) ? arguments[0] : Array.from(arguments);
|
||||
return new logic_1.LogicCommand(logic_1.LOGIC_COMMANDS_LITERAL.OR, expressions);
|
||||
},
|
||||
not(...__expressions__) {
|
||||
const expressions = type_1.isArray(arguments[0]) ? arguments[0] : Array.from(arguments);
|
||||
return new logic_1.LogicCommand(logic_1.LOGIC_COMMANDS_LITERAL.NOT, expressions);
|
||||
},
|
||||
set(val) {
|
||||
return new update_1.UpdateCommand(update_1.UPDATE_COMMANDS_LITERAL.SET, [val]);
|
||||
},
|
||||
remove() {
|
||||
return new update_1.UpdateCommand(update_1.UPDATE_COMMANDS_LITERAL.REMOVE, []);
|
||||
},
|
||||
inc(val) {
|
||||
return new update_1.UpdateCommand(update_1.UPDATE_COMMANDS_LITERAL.INC, [val]);
|
||||
},
|
||||
mul(val) {
|
||||
return new update_1.UpdateCommand(update_1.UPDATE_COMMANDS_LITERAL.MUL, [val]);
|
||||
},
|
||||
push(...args) {
|
||||
let values;
|
||||
if (type_1.isObject(args[0]) && args[0].hasOwnProperty('each')) {
|
||||
values = {};
|
||||
const options = args[0];
|
||||
if (options.each !== undefined) {
|
||||
values['$each'] = options.each;
|
||||
}
|
||||
if (options.position !== undefined) {
|
||||
values['$position'] = options.position;
|
||||
}
|
||||
if (options.sort !== undefined) {
|
||||
values['$sort'] = options.sort;
|
||||
}
|
||||
if (options.slice !== undefined) {
|
||||
values['$slice'] = options.slice;
|
||||
}
|
||||
}
|
||||
else if (type_1.isArray(args[0])) {
|
||||
values = args[0];
|
||||
}
|
||||
else {
|
||||
values = Array.from(args);
|
||||
}
|
||||
return new update_1.UpdateCommand(update_1.UPDATE_COMMANDS_LITERAL.PUSH, values);
|
||||
},
|
||||
pull(values) {
|
||||
return new update_1.UpdateCommand(update_1.UPDATE_COMMANDS_LITERAL.PULL, values);
|
||||
},
|
||||
pullAll(values) {
|
||||
return new update_1.UpdateCommand(update_1.UPDATE_COMMANDS_LITERAL.PULL_ALL, values);
|
||||
},
|
||||
pop() {
|
||||
return new update_1.UpdateCommand(update_1.UPDATE_COMMANDS_LITERAL.POP, []);
|
||||
},
|
||||
shift() {
|
||||
return new update_1.UpdateCommand(update_1.UPDATE_COMMANDS_LITERAL.SHIFT, []);
|
||||
},
|
||||
unshift(...__values__) {
|
||||
const values = type_1.isArray(arguments[0]) ? arguments[0] : Array.from(arguments);
|
||||
return new update_1.UpdateCommand(update_1.UPDATE_COMMANDS_LITERAL.UNSHIFT, values);
|
||||
},
|
||||
addToSet(values) {
|
||||
return new update_1.UpdateCommand(update_1.UPDATE_COMMANDS_LITERAL.ADD_TO_SET, values);
|
||||
},
|
||||
rename(values) {
|
||||
return new update_1.UpdateCommand(update_1.UPDATE_COMMANDS_LITERAL.RENAME, [values]);
|
||||
},
|
||||
bit(values) {
|
||||
return new update_1.UpdateCommand(update_1.UPDATE_COMMANDS_LITERAL.BIT, [values]);
|
||||
},
|
||||
max(values) {
|
||||
return new update_1.UpdateCommand(update_1.UPDATE_COMMANDS_LITERAL.MAX, [values]);
|
||||
},
|
||||
min(values) {
|
||||
return new update_1.UpdateCommand(update_1.UPDATE_COMMANDS_LITERAL.MIN, [values]);
|
||||
},
|
||||
expr(values) {
|
||||
return {
|
||||
$expr: values
|
||||
};
|
||||
},
|
||||
jsonSchema(schema) {
|
||||
return {
|
||||
$jsonSchema: schema
|
||||
};
|
||||
},
|
||||
text(values) {
|
||||
if (type_1.isString(values)) {
|
||||
return {
|
||||
$search: values.search
|
||||
};
|
||||
}
|
||||
else {
|
||||
return {
|
||||
$search: values.search,
|
||||
$language: values.language,
|
||||
$caseSensitive: values.caseSensitive,
|
||||
$diacriticSensitive: values.diacriticSensitive
|
||||
};
|
||||
}
|
||||
},
|
||||
aggregate: {
|
||||
pipeline() {
|
||||
return new aggregate_1.default();
|
||||
},
|
||||
abs: param => new AggregationOperator('abs', param),
|
||||
add: param => new AggregationOperator('add', param),
|
||||
ceil: param => new AggregationOperator('ceil', param),
|
||||
divide: param => new AggregationOperator('divide', param),
|
||||
exp: param => new AggregationOperator('exp', param),
|
||||
floor: param => new AggregationOperator('floor', param),
|
||||
ln: param => new AggregationOperator('ln', param),
|
||||
log: param => new AggregationOperator('log', param),
|
||||
log10: param => new AggregationOperator('log10', param),
|
||||
mod: param => new AggregationOperator('mod', param),
|
||||
multiply: param => new AggregationOperator('multiply', param),
|
||||
pow: param => new AggregationOperator('pow', param),
|
||||
sqrt: param => new AggregationOperator('sqrt', param),
|
||||
subtract: param => new AggregationOperator('subtract', param),
|
||||
trunc: param => new AggregationOperator('trunc', param),
|
||||
arrayElemAt: param => new AggregationOperator('arrayElemAt', param),
|
||||
arrayToObject: param => new AggregationOperator('arrayToObject', param),
|
||||
concatArrays: param => new AggregationOperator('concatArrays', param),
|
||||
filter: param => new AggregationOperator('filter', param),
|
||||
in: param => new AggregationOperator('in', param),
|
||||
indexOfArray: param => new AggregationOperator('indexOfArray', param),
|
||||
isArray: param => new AggregationOperator('isArray', param),
|
||||
map: param => new AggregationOperator('map', param),
|
||||
range: param => new AggregationOperator('range', param),
|
||||
reduce: param => new AggregationOperator('reduce', param),
|
||||
reverseArray: param => new AggregationOperator('reverseArray', param),
|
||||
size: param => new AggregationOperator('size', param),
|
||||
slice: param => new AggregationOperator('slice', param),
|
||||
zip: param => new AggregationOperator('zip', param),
|
||||
and: param => new AggregationOperator('and', param),
|
||||
not: param => new AggregationOperator('not', param),
|
||||
or: param => new AggregationOperator('or', param),
|
||||
cmp: param => new AggregationOperator('cmp', param),
|
||||
eq: param => new AggregationOperator('eq', param),
|
||||
gt: param => new AggregationOperator('gt', param),
|
||||
gte: param => new AggregationOperator('gte', param),
|
||||
lt: param => new AggregationOperator('lt', param),
|
||||
lte: param => new AggregationOperator('lte', param),
|
||||
neq: param => new AggregationOperator('ne', param),
|
||||
cond: param => new AggregationOperator('cond', param),
|
||||
ifNull: param => new AggregationOperator('ifNull', param),
|
||||
switch: param => new AggregationOperator('switch', param),
|
||||
dateFromParts: param => new AggregationOperator('dateFromParts', param),
|
||||
dateFromString: param => new AggregationOperator('dateFromString', param),
|
||||
dayOfMonth: param => new AggregationOperator('dayOfMonth', param),
|
||||
dayOfWeek: param => new AggregationOperator('dayOfWeek', param),
|
||||
dayOfYear: param => new AggregationOperator('dayOfYear', param),
|
||||
isoDayOfWeek: param => new AggregationOperator('isoDayOfWeek', param),
|
||||
isoWeek: param => new AggregationOperator('isoWeek', param),
|
||||
isoWeekYear: param => new AggregationOperator('isoWeekYear', param),
|
||||
millisecond: param => new AggregationOperator('millisecond', param),
|
||||
minute: param => new AggregationOperator('minute', param),
|
||||
month: param => new AggregationOperator('month', param),
|
||||
second: param => new AggregationOperator('second', param),
|
||||
hour: param => new AggregationOperator('hour', param),
|
||||
week: param => new AggregationOperator('week', param),
|
||||
year: param => new AggregationOperator('year', param),
|
||||
literal: param => new AggregationOperator('literal', param),
|
||||
mergeObjects: param => new AggregationOperator('mergeObjects', param),
|
||||
objectToArray: param => new AggregationOperator('objectToArray', param),
|
||||
allElementsTrue: param => new AggregationOperator('allElementsTrue', param),
|
||||
anyElementTrue: param => new AggregationOperator('anyElementTrue', param),
|
||||
setDifference: param => new AggregationOperator('setDifference', param),
|
||||
setEquals: param => new AggregationOperator('setEquals', param),
|
||||
setIntersection: param => new AggregationOperator('setIntersection', param),
|
||||
setIsSubset: param => new AggregationOperator('setIsSubset', param),
|
||||
setUnion: param => new AggregationOperator('setUnion', param),
|
||||
concat: param => new AggregationOperator('concat', param),
|
||||
dateToString: param => new AggregationOperator('dateToString', param),
|
||||
indexOfBytes: param => new AggregationOperator('indexOfBytes', param),
|
||||
indexOfCP: param => new AggregationOperator('indexOfCP', param),
|
||||
split: param => new AggregationOperator('split', param),
|
||||
strLenBytes: param => new AggregationOperator('strLenBytes', param),
|
||||
strLenCP: param => new AggregationOperator('strLenCP', param),
|
||||
strcasecmp: param => new AggregationOperator('strcasecmp', param),
|
||||
substr: param => new AggregationOperator('substr', param),
|
||||
substrBytes: param => new AggregationOperator('substrBytes', param),
|
||||
substrCP: param => new AggregationOperator('substrCP', param),
|
||||
toLower: param => new AggregationOperator('toLower', param),
|
||||
toUpper: param => new AggregationOperator('toUpper', param),
|
||||
meta: param => new AggregationOperator('meta', param),
|
||||
addToSet: param => new AggregationOperator('addToSet', param),
|
||||
avg: param => new AggregationOperator('avg', param),
|
||||
first: param => new AggregationOperator('first', param),
|
||||
last: param => new AggregationOperator('last', param),
|
||||
max: param => new AggregationOperator('max', param),
|
||||
min: param => new AggregationOperator('min', param),
|
||||
push: param => new AggregationOperator('push', param),
|
||||
stdDevPop: param => new AggregationOperator('stdDevPop', param),
|
||||
stdDevSamp: param => new AggregationOperator('stdDevSamp', param),
|
||||
sum: param => new AggregationOperator('sum', param),
|
||||
let: param => new AggregationOperator('let', param)
|
||||
},
|
||||
project: {
|
||||
slice: param => new ProjectionOperator('slice', param),
|
||||
elemMatch: param => new ProjectionOperator('elemMatch', param)
|
||||
}
|
||||
};
|
||||
class AggregationOperator {
|
||||
constructor(name, param) {
|
||||
this['$' + name] = param;
|
||||
}
|
||||
}
|
||||
exports.AggregationOperator = AggregationOperator;
|
||||
class ProjectionOperator {
|
||||
constructor(name, param) {
|
||||
this['$' + name] = param;
|
||||
}
|
||||
}
|
||||
exports.ProjectionOperator = ProjectionOperator;
|
||||
exports.default = exports.Command;
|
@ -0,0 +1,24 @@
|
||||
import { InternalSymbol } from '../helper/symbol';
|
||||
export declare const AND = "and";
|
||||
export declare const OR = "or";
|
||||
export declare const NOT = "not";
|
||||
export declare const NOR = "nor";
|
||||
export declare enum LOGIC_COMMANDS_LITERAL {
|
||||
AND = "and",
|
||||
OR = "or",
|
||||
NOT = "not",
|
||||
NOR = "nor"
|
||||
}
|
||||
export declare class LogicCommand {
|
||||
fieldName: string | InternalSymbol;
|
||||
operator: LOGIC_COMMANDS_LITERAL | string;
|
||||
operands: any[];
|
||||
_internalType: InternalSymbol;
|
||||
constructor(operator: LOGIC_COMMANDS_LITERAL | string, operands: any, fieldName?: string | InternalSymbol);
|
||||
_setFieldName(fieldName: string): LogicCommand;
|
||||
and(...__expressions__: LogicCommand[]): LogicCommand;
|
||||
or(...__expressions__: LogicCommand[]): LogicCommand;
|
||||
}
|
||||
export declare function isLogicCommand(object: any): object is LogicCommand;
|
||||
export declare function isKnownLogicCommand(object: any): object is LogicCommand;
|
||||
export default LogicCommand;
|
@ -0,0 +1,79 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const symbol_1 = require("../helper/symbol");
|
||||
const query_1 = require("./query");
|
||||
exports.AND = 'and';
|
||||
exports.OR = 'or';
|
||||
exports.NOT = 'not';
|
||||
exports.NOR = 'nor';
|
||||
var LOGIC_COMMANDS_LITERAL;
|
||||
(function (LOGIC_COMMANDS_LITERAL) {
|
||||
LOGIC_COMMANDS_LITERAL["AND"] = "and";
|
||||
LOGIC_COMMANDS_LITERAL["OR"] = "or";
|
||||
LOGIC_COMMANDS_LITERAL["NOT"] = "not";
|
||||
LOGIC_COMMANDS_LITERAL["NOR"] = "nor";
|
||||
})(LOGIC_COMMANDS_LITERAL = exports.LOGIC_COMMANDS_LITERAL || (exports.LOGIC_COMMANDS_LITERAL = {}));
|
||||
class LogicCommand {
|
||||
constructor(operator, operands, fieldName) {
|
||||
this._internalType = symbol_1.SYMBOL_LOGIC_COMMAND;
|
||||
Object.defineProperties(this, {
|
||||
_internalType: {
|
||||
enumerable: false,
|
||||
configurable: false,
|
||||
},
|
||||
});
|
||||
this.operator = operator;
|
||||
this.operands = operands;
|
||||
this.fieldName = fieldName || symbol_1.SYMBOL_UNSET_FIELD_NAME;
|
||||
if (this.fieldName !== symbol_1.SYMBOL_UNSET_FIELD_NAME) {
|
||||
if (Array.isArray(operands)) {
|
||||
operands = operands.slice();
|
||||
this.operands = operands;
|
||||
for (let i = 0, len = operands.length; i < len; i++) {
|
||||
const query = operands[i];
|
||||
if (isLogicCommand(query) || query_1.isQueryCommand(query)) {
|
||||
operands[i] = query._setFieldName(this.fieldName);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
const query = operands;
|
||||
if (isLogicCommand(query) || query_1.isQueryCommand(query)) {
|
||||
operands = query._setFieldName(this.fieldName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_setFieldName(fieldName) {
|
||||
const operands = this.operands.map(operand => {
|
||||
if (operand instanceof LogicCommand) {
|
||||
return operand._setFieldName(fieldName);
|
||||
}
|
||||
else {
|
||||
return operand;
|
||||
}
|
||||
});
|
||||
const command = new LogicCommand(this.operator, operands, fieldName);
|
||||
return command;
|
||||
}
|
||||
and(...__expressions__) {
|
||||
const expressions = Array.isArray(arguments[0]) ? arguments[0] : Array.from(arguments);
|
||||
expressions.unshift(this);
|
||||
return new LogicCommand(LOGIC_COMMANDS_LITERAL.AND, expressions, this.fieldName);
|
||||
}
|
||||
or(...__expressions__) {
|
||||
const expressions = Array.isArray(arguments[0]) ? arguments[0] : Array.from(arguments);
|
||||
expressions.unshift(this);
|
||||
return new LogicCommand(LOGIC_COMMANDS_LITERAL.OR, expressions, this.fieldName);
|
||||
}
|
||||
}
|
||||
exports.LogicCommand = LogicCommand;
|
||||
function isLogicCommand(object) {
|
||||
return object && (object instanceof LogicCommand) && (object._internalType === symbol_1.SYMBOL_LOGIC_COMMAND);
|
||||
}
|
||||
exports.isLogicCommand = isLogicCommand;
|
||||
function isKnownLogicCommand(object) {
|
||||
return isLogicCommand && (object.operator.toUpperCase() in LOGIC_COMMANDS_LITERAL);
|
||||
}
|
||||
exports.isKnownLogicCommand = isKnownLogicCommand;
|
||||
exports.default = LogicCommand;
|
@ -0,0 +1,73 @@
|
||||
import { LogicCommand } from './logic';
|
||||
import { InternalSymbol } from '../helper/symbol';
|
||||
import { Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon } from '../geo/index';
|
||||
import { CenterSphere } from '../typings';
|
||||
export declare const EQ = "eq";
|
||||
export declare const NEQ = "neq";
|
||||
export declare const GT = "gt";
|
||||
export declare const GTE = "gte";
|
||||
export declare const LT = "lt";
|
||||
export declare const LTE = "lte";
|
||||
export declare const IN = "in";
|
||||
export declare const NIN = "nin";
|
||||
export declare const ALL = "all";
|
||||
export declare const ELEM_MATCH = "elemMatch";
|
||||
export declare const EXISTS = "exists";
|
||||
export declare const SIZE = "size";
|
||||
export declare const MOD = "mod";
|
||||
export declare enum QUERY_COMMANDS_LITERAL {
|
||||
EQ = "eq",
|
||||
NEQ = "neq",
|
||||
GT = "gt",
|
||||
GTE = "gte",
|
||||
LT = "lt",
|
||||
LTE = "lte",
|
||||
IN = "in",
|
||||
NIN = "nin",
|
||||
ALL = "all",
|
||||
ELEM_MATCH = "elemMatch",
|
||||
EXISTS = "exists",
|
||||
SIZE = "size",
|
||||
MOD = "mod",
|
||||
GEO_NEAR = "geoNear",
|
||||
GEO_WITHIN = "geoWithin",
|
||||
GEO_INTERSECTS = "geoIntersects"
|
||||
}
|
||||
export declare class QueryCommand extends LogicCommand {
|
||||
operator: QUERY_COMMANDS_LITERAL;
|
||||
constructor(operator: QUERY_COMMANDS_LITERAL, operands: any, fieldName?: string | InternalSymbol);
|
||||
toJSON(): {
|
||||
['$ne']: any;
|
||||
} | {
|
||||
[x: string]: any;
|
||||
$ne?: undefined;
|
||||
};
|
||||
_setFieldName(fieldName: string): QueryCommand;
|
||||
eq(val: any): LogicCommand;
|
||||
neq(val: any): LogicCommand;
|
||||
gt(val: any): LogicCommand;
|
||||
gte(val: any): LogicCommand;
|
||||
lt(val: any): LogicCommand;
|
||||
lte(val: any): LogicCommand;
|
||||
in(list: any[]): LogicCommand;
|
||||
nin(list: any[]): LogicCommand;
|
||||
geoNear(val: IGeoNearOptions): LogicCommand;
|
||||
geoWithin(val: IGeoWithinOptions): LogicCommand;
|
||||
geoIntersects(val: IGeoIntersectsOptions): LogicCommand;
|
||||
}
|
||||
export declare function isQueryCommand(object: any): object is QueryCommand;
|
||||
export declare function isKnownQueryCommand(object: any): object is QueryCommand;
|
||||
export declare function isComparisonCommand(object: any): object is QueryCommand;
|
||||
export default QueryCommand;
|
||||
export interface IGeoNearOptions {
|
||||
geometry: Point;
|
||||
maxDistance?: number;
|
||||
minDistance?: number;
|
||||
}
|
||||
export interface IGeoWithinOptions {
|
||||
geometry?: Polygon | MultiPolygon;
|
||||
centerSphere?: CenterSphere;
|
||||
}
|
||||
export interface IGeoIntersectsOptions {
|
||||
geometry: Point | LineString | Polygon | MultiPoint | MultiLineString | MultiPolygon;
|
||||
}
|
147
CLASS1/cloudfunctions/excel/node_modules/@cloudbase/database/dist/commonjs/commands/query.js
generated
vendored
147
CLASS1/cloudfunctions/excel/node_modules/@cloudbase/database/dist/commonjs/commands/query.js
generated
vendored
@ -0,0 +1,147 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const logic_1 = require("./logic");
|
||||
const symbol_1 = require("../helper/symbol");
|
||||
const index_1 = require("../geo/index");
|
||||
const type_1 = require("../utils/type");
|
||||
const validate_1 = require("../validate");
|
||||
exports.EQ = 'eq';
|
||||
exports.NEQ = 'neq';
|
||||
exports.GT = 'gt';
|
||||
exports.GTE = 'gte';
|
||||
exports.LT = 'lt';
|
||||
exports.LTE = 'lte';
|
||||
exports.IN = 'in';
|
||||
exports.NIN = 'nin';
|
||||
exports.ALL = 'all';
|
||||
exports.ELEM_MATCH = 'elemMatch';
|
||||
exports.EXISTS = 'exists';
|
||||
exports.SIZE = 'size';
|
||||
exports.MOD = 'mod';
|
||||
var QUERY_COMMANDS_LITERAL;
|
||||
(function (QUERY_COMMANDS_LITERAL) {
|
||||
QUERY_COMMANDS_LITERAL["EQ"] = "eq";
|
||||
QUERY_COMMANDS_LITERAL["NEQ"] = "neq";
|
||||
QUERY_COMMANDS_LITERAL["GT"] = "gt";
|
||||
QUERY_COMMANDS_LITERAL["GTE"] = "gte";
|
||||
QUERY_COMMANDS_LITERAL["LT"] = "lt";
|
||||
QUERY_COMMANDS_LITERAL["LTE"] = "lte";
|
||||
QUERY_COMMANDS_LITERAL["IN"] = "in";
|
||||
QUERY_COMMANDS_LITERAL["NIN"] = "nin";
|
||||
QUERY_COMMANDS_LITERAL["ALL"] = "all";
|
||||
QUERY_COMMANDS_LITERAL["ELEM_MATCH"] = "elemMatch";
|
||||
QUERY_COMMANDS_LITERAL["EXISTS"] = "exists";
|
||||
QUERY_COMMANDS_LITERAL["SIZE"] = "size";
|
||||
QUERY_COMMANDS_LITERAL["MOD"] = "mod";
|
||||
QUERY_COMMANDS_LITERAL["GEO_NEAR"] = "geoNear";
|
||||
QUERY_COMMANDS_LITERAL["GEO_WITHIN"] = "geoWithin";
|
||||
QUERY_COMMANDS_LITERAL["GEO_INTERSECTS"] = "geoIntersects";
|
||||
})(QUERY_COMMANDS_LITERAL = exports.QUERY_COMMANDS_LITERAL || (exports.QUERY_COMMANDS_LITERAL = {}));
|
||||
class QueryCommand extends logic_1.LogicCommand {
|
||||
constructor(operator, operands, fieldName) {
|
||||
super(operator, operands, fieldName);
|
||||
this.operator = operator;
|
||||
this._internalType = symbol_1.SYMBOL_QUERY_COMMAND;
|
||||
}
|
||||
toJSON() {
|
||||
switch (this.operator) {
|
||||
case QUERY_COMMANDS_LITERAL.IN:
|
||||
case QUERY_COMMANDS_LITERAL.NIN:
|
||||
return {
|
||||
['$' + this.operator]: this.operands
|
||||
};
|
||||
case QUERY_COMMANDS_LITERAL.NEQ:
|
||||
return {
|
||||
['$ne']: this.operands[0]
|
||||
};
|
||||
default:
|
||||
return {
|
||||
['$' + this.operator]: this.operands[0]
|
||||
};
|
||||
}
|
||||
}
|
||||
_setFieldName(fieldName) {
|
||||
const command = new QueryCommand(this.operator, this.operands, fieldName);
|
||||
return command;
|
||||
}
|
||||
eq(val) {
|
||||
const command = new QueryCommand(QUERY_COMMANDS_LITERAL.EQ, [val], this.fieldName);
|
||||
return this.and(command);
|
||||
}
|
||||
neq(val) {
|
||||
const command = new QueryCommand(QUERY_COMMANDS_LITERAL.NEQ, [val], this.fieldName);
|
||||
return this.and(command);
|
||||
}
|
||||
gt(val) {
|
||||
const command = new QueryCommand(QUERY_COMMANDS_LITERAL.GT, [val], this.fieldName);
|
||||
return this.and(command);
|
||||
}
|
||||
gte(val) {
|
||||
const command = new QueryCommand(QUERY_COMMANDS_LITERAL.GTE, [val], this.fieldName);
|
||||
return this.and(command);
|
||||
}
|
||||
lt(val) {
|
||||
const command = new QueryCommand(QUERY_COMMANDS_LITERAL.LT, [val], this.fieldName);
|
||||
return this.and(command);
|
||||
}
|
||||
lte(val) {
|
||||
const command = new QueryCommand(QUERY_COMMANDS_LITERAL.LTE, [val], this.fieldName);
|
||||
return this.and(command);
|
||||
}
|
||||
in(list) {
|
||||
const command = new QueryCommand(QUERY_COMMANDS_LITERAL.IN, list, this.fieldName);
|
||||
return this.and(command);
|
||||
}
|
||||
nin(list) {
|
||||
const command = new QueryCommand(QUERY_COMMANDS_LITERAL.NIN, list, this.fieldName);
|
||||
return this.and(command);
|
||||
}
|
||||
geoNear(val) {
|
||||
if (!(val.geometry instanceof index_1.Point)) {
|
||||
throw new TypeError(`"geometry" must be of type Point. Received type ${typeof val.geometry}`);
|
||||
}
|
||||
if (val.maxDistance !== undefined && !type_1.isNumber(val.maxDistance)) {
|
||||
throw new TypeError(`"maxDistance" must be of type Number. Received type ${typeof val.maxDistance}`);
|
||||
}
|
||||
if (val.minDistance !== undefined && !type_1.isNumber(val.minDistance)) {
|
||||
throw new TypeError(`"minDistance" must be of type Number. Received type ${typeof val.minDistance}`);
|
||||
}
|
||||
const command = new QueryCommand(QUERY_COMMANDS_LITERAL.GEO_NEAR, [val], this.fieldName);
|
||||
return this.and(command);
|
||||
}
|
||||
geoWithin(val) {
|
||||
if (!(val.geometry instanceof index_1.MultiPolygon) &&
|
||||
!(val.geometry instanceof index_1.Polygon) &&
|
||||
!validate_1.Validate.isCentersPhere(val.centerSphere)) {
|
||||
throw new TypeError(`"geometry" must be of type Polygon or MultiPolygon. Received type ${typeof val.geometry}`);
|
||||
}
|
||||
const command = new QueryCommand(QUERY_COMMANDS_LITERAL.GEO_WITHIN, [val], this.fieldName);
|
||||
return this.and(command);
|
||||
}
|
||||
geoIntersects(val) {
|
||||
if (!(val.geometry instanceof index_1.Point) &&
|
||||
!(val.geometry instanceof index_1.LineString) &&
|
||||
!(val.geometry instanceof index_1.Polygon) &&
|
||||
!(val.geometry instanceof index_1.MultiPoint) &&
|
||||
!(val.geometry instanceof index_1.MultiLineString) &&
|
||||
!(val.geometry instanceof index_1.MultiPolygon)) {
|
||||
throw new TypeError(`"geometry" must be of type Point, LineString, Polygon, MultiPoint, MultiLineString or MultiPolygon. Received type ${typeof val.geometry}`);
|
||||
}
|
||||
const command = new QueryCommand(QUERY_COMMANDS_LITERAL.GEO_INTERSECTS, [val], this.fieldName);
|
||||
return this.and(command);
|
||||
}
|
||||
}
|
||||
exports.QueryCommand = QueryCommand;
|
||||
function isQueryCommand(object) {
|
||||
return object && object instanceof QueryCommand && object._internalType === symbol_1.SYMBOL_QUERY_COMMAND;
|
||||
}
|
||||
exports.isQueryCommand = isQueryCommand;
|
||||
function isKnownQueryCommand(object) {
|
||||
return isQueryCommand(object) && object.operator.toUpperCase() in QUERY_COMMANDS_LITERAL;
|
||||
}
|
||||
exports.isKnownQueryCommand = isKnownQueryCommand;
|
||||
function isComparisonCommand(object) {
|
||||
return isQueryCommand(object);
|
||||
}
|
||||
exports.isComparisonCommand = isComparisonCommand;
|
||||
exports.default = QueryCommand;
|
@ -0,0 +1,29 @@
|
||||
import { InternalSymbol } from '../helper/symbol';
|
||||
export declare enum UPDATE_COMMANDS_LITERAL {
|
||||
SET = "set",
|
||||
REMOVE = "remove",
|
||||
INC = "inc",
|
||||
MUL = "mul",
|
||||
PUSH = "push",
|
||||
PULL = "pull",
|
||||
PULL_ALL = "pullAll",
|
||||
POP = "pop",
|
||||
SHIFT = "shift",
|
||||
UNSHIFT = "unshift",
|
||||
ADD_TO_SET = "addToSet",
|
||||
BIT = "bit",
|
||||
RENAME = "rename",
|
||||
MAX = "max",
|
||||
MIN = "min"
|
||||
}
|
||||
export declare class UpdateCommand {
|
||||
fieldName: string | InternalSymbol;
|
||||
operator: UPDATE_COMMANDS_LITERAL;
|
||||
operands: any;
|
||||
_internalType: InternalSymbol;
|
||||
constructor(operator: UPDATE_COMMANDS_LITERAL, operands?: any, fieldName?: string | InternalSymbol);
|
||||
_setFieldName(fieldName: string): UpdateCommand;
|
||||
}
|
||||
export declare function isUpdateCommand(object: any): object is UpdateCommand;
|
||||
export declare function isKnownUpdateCommand(object: any): object is UpdateCommand;
|
||||
export default UpdateCommand;
|
@ -0,0 +1,49 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const symbol_1 = require("../helper/symbol");
|
||||
var UPDATE_COMMANDS_LITERAL;
|
||||
(function (UPDATE_COMMANDS_LITERAL) {
|
||||
UPDATE_COMMANDS_LITERAL["SET"] = "set";
|
||||
UPDATE_COMMANDS_LITERAL["REMOVE"] = "remove";
|
||||
UPDATE_COMMANDS_LITERAL["INC"] = "inc";
|
||||
UPDATE_COMMANDS_LITERAL["MUL"] = "mul";
|
||||
UPDATE_COMMANDS_LITERAL["PUSH"] = "push";
|
||||
UPDATE_COMMANDS_LITERAL["PULL"] = "pull";
|
||||
UPDATE_COMMANDS_LITERAL["PULL_ALL"] = "pullAll";
|
||||
UPDATE_COMMANDS_LITERAL["POP"] = "pop";
|
||||
UPDATE_COMMANDS_LITERAL["SHIFT"] = "shift";
|
||||
UPDATE_COMMANDS_LITERAL["UNSHIFT"] = "unshift";
|
||||
UPDATE_COMMANDS_LITERAL["ADD_TO_SET"] = "addToSet";
|
||||
UPDATE_COMMANDS_LITERAL["BIT"] = "bit";
|
||||
UPDATE_COMMANDS_LITERAL["RENAME"] = "rename";
|
||||
UPDATE_COMMANDS_LITERAL["MAX"] = "max";
|
||||
UPDATE_COMMANDS_LITERAL["MIN"] = "min";
|
||||
})(UPDATE_COMMANDS_LITERAL = exports.UPDATE_COMMANDS_LITERAL || (exports.UPDATE_COMMANDS_LITERAL = {}));
|
||||
class UpdateCommand {
|
||||
constructor(operator, operands, fieldName) {
|
||||
this._internalType = symbol_1.SYMBOL_UPDATE_COMMAND;
|
||||
Object.defineProperties(this, {
|
||||
_internalType: {
|
||||
enumerable: false,
|
||||
configurable: false,
|
||||
},
|
||||
});
|
||||
this.operator = operator;
|
||||
this.operands = operands;
|
||||
this.fieldName = fieldName || symbol_1.SYMBOL_UNSET_FIELD_NAME;
|
||||
}
|
||||
_setFieldName(fieldName) {
|
||||
const command = new UpdateCommand(this.operator, this.operands, fieldName);
|
||||
return command;
|
||||
}
|
||||
}
|
||||
exports.UpdateCommand = UpdateCommand;
|
||||
function isUpdateCommand(object) {
|
||||
return object && (object instanceof UpdateCommand) && (object._internalType === symbol_1.SYMBOL_UPDATE_COMMAND);
|
||||
}
|
||||
exports.isUpdateCommand = isUpdateCommand;
|
||||
function isKnownUpdateCommand(object) {
|
||||
return isUpdateCommand(object) && (object.operator.toUpperCase() in UPDATE_COMMANDS_LITERAL);
|
||||
}
|
||||
exports.isKnownUpdateCommand = isKnownUpdateCommand;
|
||||
exports.default = UpdateCommand;
|
@ -0,0 +1,6 @@
|
||||
declare const _default: {
|
||||
db_doc_size_limit: number;
|
||||
db_realtime_ping_interval: number;
|
||||
db_realtime_pong_wait_timeout: number;
|
||||
};
|
||||
export default _default;
|
@ -0,0 +1,7 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.default = {
|
||||
db_doc_size_limit: 512 * 1024,
|
||||
db_realtime_ping_interval: 15 * 1000,
|
||||
db_realtime_pong_wait_timeout: 15 * 1000,
|
||||
};
|
@ -0,0 +1,3 @@
|
||||
export declare const ERR_CODE: {
|
||||
[key: string]: string | number;
|
||||
};
|
@ -0,0 +1,15 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ERR_CODE = {
|
||||
UNKNOWN_ERROR: 'UNKNOWN_ERROR',
|
||||
SDK_DATABASE_REALTIME_LISTENER_INIT_WATCH_FAIL: 'SDK_DATABASE_REALTIME_LISTENER_INIT_WATCH_FAIL',
|
||||
SDK_DATABASE_REALTIME_LISTENER_RECONNECT_WATCH_FAIL: 'SDK_DATABASE_REALTIME_LISTENER_RECONNECT_WATCH_FAIL',
|
||||
SDK_DATABASE_REALTIME_LISTENER_REBUILD_WATCH_FAIL: 'SDK_DATABASE_REALTIME_LISTENER_REBUILD_WATCH_FAIL',
|
||||
SDK_DATABASE_REALTIME_LISTENER_CLOSE_WATCH_FAIL: 'SDK_DATABASE_REALTIME_LISTENER_CLOSE_WATCH_FAIL',
|
||||
SDK_DATABASE_REALTIME_LISTENER_SERVER_ERROR_MSG: 'SDK_DATABASE_REALTIME_LISTENER_SERVER_ERROR_MSG',
|
||||
SDK_DATABASE_REALTIME_LISTENER_RECEIVE_INVALID_SERVER_DATA: 'SDK_DATABASE_REALTIME_LISTENER_RECEIVE_INVALID_SERVER_DATA',
|
||||
SDK_DATABASE_REALTIME_LISTENER_WEBSOCKET_CONNECTION_ERROR: 'SDK_DATABASE_REALTIME_LISTENER_WEBSOCKET_CONNECTION_ERROR',
|
||||
SDK_DATABASE_REALTIME_LISTENER_WEBSOCKET_CONNECTION_CLOSED: 'SDK_DATABASE_REALTIME_LISTENER_WEBSOCKET_CONNECTION_CLOSED',
|
||||
SDK_DATABASE_REALTIME_LISTENER_CHECK_LAST_FAIL: 'SDK_DATABASE_REALTIME_LISTENER_CHECK_LAST_FAIL',
|
||||
SDK_DATABASE_REALTIME_LISTENER_UNEXPECTED_FATAL_ERROR: 'SDK_DATABASE_REALTIME_LISTENER_UNEXPECTED_FATAL_ERROR'
|
||||
};
|
@ -0,0 +1,34 @@
|
||||
export declare const ERRORS: {
|
||||
CREATE_WATCH_NET_ERROR: {
|
||||
code: string;
|
||||
message: string;
|
||||
};
|
||||
CREATE_WACTH_EXCEED_ERROR: {
|
||||
code: string;
|
||||
message: string;
|
||||
};
|
||||
CREATE_WATCH_SERVER_ERROR: {
|
||||
code: string;
|
||||
message: string;
|
||||
};
|
||||
CONN_ERROR: {
|
||||
code: string;
|
||||
message: string;
|
||||
};
|
||||
INVALID_PARAM: {
|
||||
code: string;
|
||||
message: string;
|
||||
};
|
||||
INSERT_DOC_FAIL: {
|
||||
code: string;
|
||||
message: string;
|
||||
};
|
||||
DATABASE_TRANSACTION_CONFLICT: {
|
||||
code: string;
|
||||
message: string;
|
||||
};
|
||||
DATABASE_REQUEST_FAILED: {
|
||||
code: string;
|
||||
message: string;
|
||||
};
|
||||
};
|
36
CLASS1/cloudfunctions/excel/node_modules/@cloudbase/database/dist/commonjs/const/code.js
generated
vendored
36
CLASS1/cloudfunctions/excel/node_modules/@cloudbase/database/dist/commonjs/const/code.js
generated
vendored
@ -0,0 +1,36 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ERRORS = {
|
||||
CREATE_WATCH_NET_ERROR: {
|
||||
code: 'CREATE_WATCH_NET_ERROR',
|
||||
message: 'create watch network error'
|
||||
},
|
||||
CREATE_WACTH_EXCEED_ERROR: {
|
||||
code: 'CREATE_WACTH_EXCEED_ERROR',
|
||||
message: 'maximum connections exceed'
|
||||
},
|
||||
CREATE_WATCH_SERVER_ERROR: {
|
||||
code: 'CREATE_WATCH_SERVER_ERROR',
|
||||
message: 'create watch server error'
|
||||
},
|
||||
CONN_ERROR: {
|
||||
code: 'CONN_ERROR',
|
||||
message: 'connection error'
|
||||
},
|
||||
INVALID_PARAM: {
|
||||
code: 'INVALID_PARAM',
|
||||
message: 'Invalid request param'
|
||||
},
|
||||
INSERT_DOC_FAIL: {
|
||||
code: 'INSERT_DOC_FAIL',
|
||||
message: 'insert document failed'
|
||||
},
|
||||
DATABASE_TRANSACTION_CONFLICT: {
|
||||
code: 'DATABASE_TRANSACTION_CONFLICT',
|
||||
message: 'database transaction conflict'
|
||||
},
|
||||
DATABASE_REQUEST_FAILED: {
|
||||
code: 'DATABASE_REQUEST_FAILED',
|
||||
message: 'database request failed'
|
||||
}
|
||||
};
|
54
CLASS1/cloudfunctions/excel/node_modules/@cloudbase/database/dist/commonjs/constant.d.ts
generated
vendored
54
CLASS1/cloudfunctions/excel/node_modules/@cloudbase/database/dist/commonjs/constant.d.ts
generated
vendored
@ -0,0 +1,54 @@
|
||||
declare enum ErrorCode {
|
||||
DocIDError = "\u6587\u6863ID\u4E0D\u5408\u6CD5",
|
||||
CollNameError = "\u96C6\u5408\u540D\u79F0\u4E0D\u5408\u6CD5",
|
||||
OpStrError = "\u64CD\u4F5C\u7B26\u4E0D\u5408\u6CD5",
|
||||
DirectionError = "\u6392\u5E8F\u5B57\u7B26\u4E0D\u5408\u6CD5",
|
||||
IntergerError = "must be integer",
|
||||
BooleanError = "must be boolean",
|
||||
ArrayError = "must be array",
|
||||
QueryParamTypeError = "\u67E5\u8BE2\u53C2\u6570\u5FC5\u987B\u4E3A\u5BF9\u8C61",
|
||||
QueryParamValueError = "\u67E5\u8BE2\u53C2\u6570\u5BF9\u8C61\u503C\u4E0D\u80FD\u5747\u4E3Aundefined",
|
||||
CentersPhereError = "centersPhere\u7ED3\u6784\u4E0D\u5408\u6CD5"
|
||||
}
|
||||
declare const FieldType: {
|
||||
String: string;
|
||||
Number: string;
|
||||
Object: string;
|
||||
Array: string;
|
||||
Boolean: string;
|
||||
Null: string;
|
||||
GeoPoint: string;
|
||||
GeoLineString: string;
|
||||
GeoPolygon: string;
|
||||
GeoMultiPoint: string;
|
||||
GeoMultiLineString: string;
|
||||
GeoMultiPolygon: string;
|
||||
Date: string;
|
||||
Command: string;
|
||||
ServerDate: string;
|
||||
BsonDate: string;
|
||||
};
|
||||
declare type OrderByDirection = 'desc' | 'asc';
|
||||
declare const OrderDirectionList: string[];
|
||||
declare type WhereFilterOp = '<' | '<=' | '==' | '>=' | '>';
|
||||
declare const WhereFilterOpList: string[];
|
||||
declare enum Opeartor {
|
||||
lt = "<",
|
||||
gt = ">",
|
||||
lte = "<=",
|
||||
gte = ">=",
|
||||
eq = "=="
|
||||
}
|
||||
declare const OperatorMap: {
|
||||
[Opeartor.eq]: string;
|
||||
[Opeartor.lt]: string;
|
||||
[Opeartor.lte]: string;
|
||||
[Opeartor.gt]: string;
|
||||
[Opeartor.gte]: string;
|
||||
};
|
||||
declare const UpdateOperatorList: string[];
|
||||
declare enum QueryType {
|
||||
WHERE = "WHERE",
|
||||
DOC = "DOC"
|
||||
}
|
||||
export { ErrorCode, FieldType, WhereFilterOp, WhereFilterOpList, Opeartor, OperatorMap, OrderByDirection, OrderDirectionList, UpdateOperatorList, QueryType };
|
76
CLASS1/cloudfunctions/excel/node_modules/@cloudbase/database/dist/commonjs/constant.js
generated
vendored
76
CLASS1/cloudfunctions/excel/node_modules/@cloudbase/database/dist/commonjs/constant.js
generated
vendored
@ -0,0 +1,76 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var ErrorCode;
|
||||
(function (ErrorCode) {
|
||||
ErrorCode["DocIDError"] = "\u6587\u6863ID\u4E0D\u5408\u6CD5";
|
||||
ErrorCode["CollNameError"] = "\u96C6\u5408\u540D\u79F0\u4E0D\u5408\u6CD5";
|
||||
ErrorCode["OpStrError"] = "\u64CD\u4F5C\u7B26\u4E0D\u5408\u6CD5";
|
||||
ErrorCode["DirectionError"] = "\u6392\u5E8F\u5B57\u7B26\u4E0D\u5408\u6CD5";
|
||||
ErrorCode["IntergerError"] = "must be integer";
|
||||
ErrorCode["BooleanError"] = "must be boolean";
|
||||
ErrorCode["ArrayError"] = "must be array";
|
||||
ErrorCode["QueryParamTypeError"] = "\u67E5\u8BE2\u53C2\u6570\u5FC5\u987B\u4E3A\u5BF9\u8C61";
|
||||
ErrorCode["QueryParamValueError"] = "\u67E5\u8BE2\u53C2\u6570\u5BF9\u8C61\u503C\u4E0D\u80FD\u5747\u4E3Aundefined";
|
||||
ErrorCode["CentersPhereError"] = "centersPhere\u7ED3\u6784\u4E0D\u5408\u6CD5";
|
||||
})(ErrorCode || (ErrorCode = {}));
|
||||
exports.ErrorCode = ErrorCode;
|
||||
const FieldType = {
|
||||
String: 'String',
|
||||
Number: 'Number',
|
||||
Object: 'Object',
|
||||
Array: 'Array',
|
||||
Boolean: 'Boolean',
|
||||
Null: 'Null',
|
||||
GeoPoint: 'GeoPoint',
|
||||
GeoLineString: 'GeoLineString',
|
||||
GeoPolygon: 'GeoPolygon',
|
||||
GeoMultiPoint: 'GeoMultiPoint',
|
||||
GeoMultiLineString: 'GeoMultiLineString',
|
||||
GeoMultiPolygon: 'GeoMultiPolygon',
|
||||
Date: 'Date',
|
||||
Command: 'Command',
|
||||
ServerDate: 'ServerDate',
|
||||
BsonDate: 'BsonDate'
|
||||
};
|
||||
exports.FieldType = FieldType;
|
||||
const OrderDirectionList = ['desc', 'asc'];
|
||||
exports.OrderDirectionList = OrderDirectionList;
|
||||
const WhereFilterOpList = ['<', '<=', '==', '>=', '>'];
|
||||
exports.WhereFilterOpList = WhereFilterOpList;
|
||||
var Opeartor;
|
||||
(function (Opeartor) {
|
||||
Opeartor["lt"] = "<";
|
||||
Opeartor["gt"] = ">";
|
||||
Opeartor["lte"] = "<=";
|
||||
Opeartor["gte"] = ">=";
|
||||
Opeartor["eq"] = "==";
|
||||
})(Opeartor || (Opeartor = {}));
|
||||
exports.Opeartor = Opeartor;
|
||||
const OperatorMap = {
|
||||
[Opeartor.eq]: '$eq',
|
||||
[Opeartor.lt]: '$lt',
|
||||
[Opeartor.lte]: '$lte',
|
||||
[Opeartor.gt]: '$gt',
|
||||
[Opeartor.gte]: '$gte'
|
||||
};
|
||||
exports.OperatorMap = OperatorMap;
|
||||
const UpdateOperatorList = [
|
||||
'$set',
|
||||
'$inc',
|
||||
'$mul',
|
||||
'$unset',
|
||||
'$push',
|
||||
'$pop',
|
||||
'$unshift',
|
||||
'$shift',
|
||||
'$currentDate',
|
||||
'$each',
|
||||
'$position'
|
||||
];
|
||||
exports.UpdateOperatorList = UpdateOperatorList;
|
||||
var QueryType;
|
||||
(function (QueryType) {
|
||||
QueryType["WHERE"] = "WHERE";
|
||||
QueryType["DOC"] = "DOC";
|
||||
})(QueryType || (QueryType = {}));
|
||||
exports.QueryType = QueryType;
|
14
CLASS1/cloudfunctions/excel/node_modules/@cloudbase/database/dist/commonjs/document.d.ts
generated
vendored
14
CLASS1/cloudfunctions/excel/node_modules/@cloudbase/database/dist/commonjs/document.d.ts
generated
vendored
@ -0,0 +1,14 @@
|
||||
import { IWatchOptions, DBRealtimeListener } from './typings/index';
|
||||
export declare class DocumentReference {
|
||||
readonly id: string | number;
|
||||
readonly _transactionId: string;
|
||||
readonly projection: Object;
|
||||
private _apiOptions;
|
||||
set(data: Object): Promise<any>;
|
||||
update(data: Object): Promise<any>;
|
||||
delete(): Promise<any>;
|
||||
remove(): Promise<any>;
|
||||
get(): Promise<any>;
|
||||
field(projection: Object): DocumentReference;
|
||||
watch: (options: IWatchOptions) => DBRealtimeListener;
|
||||
}
|
219
CLASS1/cloudfunctions/excel/node_modules/@cloudbase/database/dist/commonjs/document.js
generated
vendored
219
CLASS1/cloudfunctions/excel/node_modules/@cloudbase/database/dist/commonjs/document.js
generated
vendored
@ -0,0 +1,219 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const index_1 = require("./index");
|
||||
const util_1 = require("./util");
|
||||
const update_1 = require("./serializer/update");
|
||||
const datatype_1 = require("./serializer/datatype");
|
||||
const update_2 = require("./commands/update");
|
||||
const websocket_client_1 = require("./realtime/websocket-client");
|
||||
const constant_1 = require("./constant");
|
||||
const utils_1 = require("./utils/utils");
|
||||
const code_1 = require("./const/code");
|
||||
const bson_1 = require("bson");
|
||||
class DocumentReference {
|
||||
constructor(db, coll, apiOptions, docID, transactionId) {
|
||||
this.watch = (options) => {
|
||||
if (!index_1.Db.ws) {
|
||||
index_1.Db.ws = new websocket_client_1.RealtimeWebSocketClient({
|
||||
context: {
|
||||
appConfig: {
|
||||
docSizeLimit: 1000,
|
||||
realtimePingInterval: 10000,
|
||||
realtimePongWaitTimeout: 5000,
|
||||
request: this.request
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return index_1.Db.ws.watch(Object.assign(Object.assign({}, options), { envId: this._db.config.env, collectionName: this._coll, query: JSON.stringify({
|
||||
_id: this.id
|
||||
}) }));
|
||||
};
|
||||
this._db = db;
|
||||
this._coll = coll;
|
||||
this.id = docID;
|
||||
this._transactionId = transactionId;
|
||||
this.request = new index_1.Db.reqClass(this._db.config);
|
||||
this._apiOptions = apiOptions;
|
||||
}
|
||||
async create(data) {
|
||||
if (this.id) {
|
||||
data['_id'] = this.id;
|
||||
}
|
||||
let params = {
|
||||
collectionName: this._coll,
|
||||
data: [utils_1.stringifyByEJSON(datatype_1.serialize(data))],
|
||||
transactionId: this._transactionId
|
||||
};
|
||||
const res = await this.request.send('database.insertDocument', params, utils_1.getReqOpts(this._apiOptions));
|
||||
if (res.code) {
|
||||
return res;
|
||||
}
|
||||
if (this._transactionId) {
|
||||
return {
|
||||
inserted: 1,
|
||||
ok: 1,
|
||||
id: res.data.insertedIds[0],
|
||||
requestId: res.requestId
|
||||
};
|
||||
}
|
||||
return {
|
||||
id: res.data.insertedIds[0],
|
||||
requestId: res.requestId
|
||||
};
|
||||
}
|
||||
async set(data) {
|
||||
if (!this.id) {
|
||||
return utils_1.processReturn(this._db.config.throwOnCode, Object.assign(Object.assign({}, code_1.ERRORS.INVALID_PARAM), { message: 'docId不能为空' }));
|
||||
}
|
||||
if (!data || typeof data !== 'object') {
|
||||
return utils_1.processReturn(this._db.config.throwOnCode, Object.assign(Object.assign({}, code_1.ERRORS.INVALID_PARAM), { message: '参数必需是非空对象' }));
|
||||
}
|
||||
if (data.hasOwnProperty('_id')) {
|
||||
return utils_1.processReturn(this._db.config.throwOnCode, Object.assign(Object.assign({}, code_1.ERRORS.INVALID_PARAM), { message: '不能更新_id的值' }));
|
||||
}
|
||||
let hasOperator = false;
|
||||
const checkMixed = objs => {
|
||||
if (typeof objs === 'object') {
|
||||
for (let key in objs) {
|
||||
if (objs[key] instanceof update_2.UpdateCommand) {
|
||||
hasOperator = true;
|
||||
}
|
||||
else if (typeof objs[key] === 'object') {
|
||||
checkMixed(objs[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
checkMixed(data);
|
||||
if (hasOperator) {
|
||||
return utils_1.processReturn(this._db.config.throwOnCode, Object.assign(Object.assign({}, code_1.ERRORS.DATABASE_REQUEST_FAILED), { message: 'update operator complicit' }));
|
||||
}
|
||||
let param = {
|
||||
collectionName: this._coll,
|
||||
queryType: constant_1.QueryType.DOC,
|
||||
data: utils_1.stringifyByEJSON(datatype_1.serialize(data)),
|
||||
transactionId: this._transactionId,
|
||||
multi: false,
|
||||
merge: false,
|
||||
upsert: true
|
||||
};
|
||||
if (this.id) {
|
||||
param['query'] = utils_1.stringifyByEJSON({ _id: this.id });
|
||||
}
|
||||
const res = await this.request.send('database.modifyDocument', param, utils_1.getReqOpts(this._apiOptions));
|
||||
if (res.code) {
|
||||
return res;
|
||||
}
|
||||
if (this._transactionId) {
|
||||
return {
|
||||
updated: res.data.updated,
|
||||
upserted: [{ _id: res.data.upsert_id }],
|
||||
requestId: res.requestId
|
||||
};
|
||||
}
|
||||
return {
|
||||
updated: res.data.updated,
|
||||
upsertedId: res.data.upsert_id,
|
||||
requestId: res.requestId
|
||||
};
|
||||
}
|
||||
async update(data) {
|
||||
if (!data || typeof data !== 'object') {
|
||||
return utils_1.processReturn(this._db.config.throwOnCode, Object.assign(Object.assign({}, code_1.ERRORS.INVALID_PARAM), { message: '参数必需是非空对象' }));
|
||||
}
|
||||
if (data.hasOwnProperty('_id')) {
|
||||
return utils_1.processReturn(this._db.config.throwOnCode, Object.assign(Object.assign({}, code_1.ERRORS.INVALID_PARAM), { message: '不能更新_id的值' }));
|
||||
}
|
||||
const query = utils_1.stringifyByEJSON({ _id: this.id });
|
||||
const param = {
|
||||
collectionName: this._coll,
|
||||
transactionId: this._transactionId,
|
||||
data: update_1.UpdateSerializer.encodeEJSON(data, this._apiOptions.raw || false),
|
||||
query,
|
||||
queryType: constant_1.QueryType.DOC,
|
||||
multi: false,
|
||||
merge: true,
|
||||
upsert: false
|
||||
};
|
||||
const res = await this.request.send('database.modifyDocument', param, utils_1.getReqOpts(this._apiOptions));
|
||||
if (res.code) {
|
||||
return res;
|
||||
}
|
||||
return {
|
||||
updated: res.data.updated,
|
||||
requestId: res.requestId
|
||||
};
|
||||
}
|
||||
async delete() {
|
||||
return this.remove();
|
||||
}
|
||||
async remove() {
|
||||
const query = utils_1.stringifyByEJSON({ _id: this.id });
|
||||
const param = {
|
||||
collectionName: this._coll,
|
||||
transactionId: this._transactionId,
|
||||
query: query,
|
||||
queryType: constant_1.QueryType.DOC,
|
||||
multi: false
|
||||
};
|
||||
const res = await this.request.send('database.removeDocument', param, utils_1.getReqOpts(this._apiOptions));
|
||||
if (res.code) {
|
||||
return res;
|
||||
}
|
||||
return {
|
||||
deleted: res.data.deleted,
|
||||
requestId: res.requestId
|
||||
};
|
||||
}
|
||||
async get() {
|
||||
const query = utils_1.stringifyByEJSON({ _id: this.id });
|
||||
const { projection } = this._apiOptions;
|
||||
const param = {
|
||||
collectionName: this._coll,
|
||||
query,
|
||||
transactionId: this._transactionId,
|
||||
queryType: constant_1.QueryType.DOC,
|
||||
multi: false
|
||||
};
|
||||
if (projection) {
|
||||
param.projection = utils_1.stringifyByEJSON(projection);
|
||||
}
|
||||
const res = await this.request.send('database.getDocument', param, utils_1.getReqOpts(this._apiOptions));
|
||||
if (res.code) {
|
||||
return res;
|
||||
}
|
||||
const list = res.data.list.map(item => bson_1.EJSON.parse(item));
|
||||
const documents = util_1.Util.formatResDocumentData(list);
|
||||
if (this._transactionId) {
|
||||
return {
|
||||
data: documents[0] || null,
|
||||
requestId: res.requestId
|
||||
};
|
||||
}
|
||||
return {
|
||||
data: documents,
|
||||
requestId: res.requestId,
|
||||
offset: res.data.offset,
|
||||
limit: res.data.limit
|
||||
};
|
||||
}
|
||||
field(projection) {
|
||||
let transformProjection = {};
|
||||
for (let k in projection) {
|
||||
if (typeof projection[k] === 'boolean') {
|
||||
transformProjection[k] = projection[k] === true ? 1 : 0;
|
||||
}
|
||||
if (typeof projection[k] === 'number') {
|
||||
transformProjection[k] = projection[k] > 0 ? 1 : 0;
|
||||
}
|
||||
if (typeof projection[k] === 'object') {
|
||||
transformProjection[k] = projection[k];
|
||||
}
|
||||
}
|
||||
let newApiOption = Object.assign({}, this._apiOptions);
|
||||
newApiOption.projection = transformProjection;
|
||||
return new DocumentReference(this._db, this._coll, newApiOption, this.id, this._transactionId);
|
||||
}
|
||||
}
|
||||
exports.DocumentReference = DocumentReference;
|
@ -0,0 +1,6 @@
|
||||
export * from './point';
|
||||
export * from './lineString';
|
||||
export * from './polygon';
|
||||
export * from './multiPoint';
|
||||
export * from './multiLineString';
|
||||
export * from './multiPolygon';
|
11
CLASS1/cloudfunctions/excel/node_modules/@cloudbase/database/dist/commonjs/geo/index.js
generated
vendored
11
CLASS1/cloudfunctions/excel/node_modules/@cloudbase/database/dist/commonjs/geo/index.js
generated
vendored
@ -0,0 +1,11 @@
|
||||
"use strict";
|
||||
function __export(m) {
|
||||
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
|
||||
}
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
__export(require("./point"));
|
||||
__export(require("./lineString"));
|
||||
__export(require("./polygon"));
|
||||
__export(require("./multiPoint"));
|
||||
__export(require("./multiLineString"));
|
||||
__export(require("./multiPolygon"));
|
@ -0,0 +1,24 @@
|
||||
export interface ISerializedPoint {
|
||||
type: string;
|
||||
coordinates: [number, number];
|
||||
}
|
||||
export interface ISerializedLineString {
|
||||
type: string;
|
||||
coordinates: [number, number][];
|
||||
}
|
||||
export interface ISerializedPolygon {
|
||||
type: string;
|
||||
coordinates: [number, number][][];
|
||||
}
|
||||
export interface ISerializedMultiPoint {
|
||||
type: string;
|
||||
coordinates: [number, number][];
|
||||
}
|
||||
export interface ISerializedMultiLineString {
|
||||
type: string;
|
||||
coordinates: [number, number][][];
|
||||
}
|
||||
export interface ISerializedMultiPolygon {
|
||||
type: string;
|
||||
coordinates: [number, number][][][];
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
@ -0,0 +1,19 @@
|
||||
import { Point } from './point';
|
||||
import { ISerializedLineString } from './interface';
|
||||
export declare class LineString {
|
||||
readonly points: Point[];
|
||||
constructor(points: Point[]);
|
||||
parse(key: any): {
|
||||
[x: number]: {
|
||||
type: string;
|
||||
coordinates: number[][];
|
||||
};
|
||||
};
|
||||
toJSON(): {
|
||||
type: string;
|
||||
coordinates: number[][];
|
||||
};
|
||||
static validate(lineString: ISerializedLineString): boolean;
|
||||
static isClosed(lineString: LineString): boolean;
|
||||
readonly _internalType: import("../utils/symbol").InternalSymbol;
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const symbol_1 = require("../helper/symbol");
|
||||
const point_1 = require("./point");
|
||||
const type_1 = require("../utils/type");
|
||||
class LineString {
|
||||
constructor(points) {
|
||||
if (!type_1.isArray(points)) {
|
||||
throw new TypeError(`"points" must be of type Point[]. Received type ${typeof points}`);
|
||||
}
|
||||
if (points.length < 2) {
|
||||
throw new Error('"points" must contain 2 points at least');
|
||||
}
|
||||
points.forEach(point => {
|
||||
if (!(point instanceof point_1.Point)) {
|
||||
throw new TypeError(`"points" must be of type Point[]. Received type ${typeof point}[]`);
|
||||
}
|
||||
});
|
||||
this.points = points;
|
||||
}
|
||||
parse(key) {
|
||||
return {
|
||||
[key]: {
|
||||
type: 'LineString',
|
||||
coordinates: this.points.map(point => point.toJSON().coordinates)
|
||||
}
|
||||
};
|
||||
}
|
||||
toJSON() {
|
||||
return {
|
||||
type: 'LineString',
|
||||
coordinates: this.points.map(point => point.toJSON().coordinates)
|
||||
};
|
||||
}
|
||||
static validate(lineString) {
|
||||
if (lineString.type !== 'LineString' || !type_1.isArray(lineString.coordinates)) {
|
||||
return false;
|
||||
}
|
||||
for (let point of lineString.coordinates) {
|
||||
if (!type_1.isNumber(point[0]) || !type_1.isNumber(point[1])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
static isClosed(lineString) {
|
||||
const firstPoint = lineString.points[0];
|
||||
const lastPoint = lineString.points[lineString.points.length - 1];
|
||||
if (firstPoint.latitude === lastPoint.latitude && firstPoint.longitude === lastPoint.longitude) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
get _internalType() {
|
||||
return symbol_1.SYMBOL_GEO_LINE_STRING;
|
||||
}
|
||||
}
|
||||
exports.LineString = LineString;
|
@ -0,0 +1,18 @@
|
||||
import { LineString } from './lineString';
|
||||
import { ISerializedMultiLineString } from './interface';
|
||||
export declare class MultiLineString {
|
||||
readonly lines: LineString[];
|
||||
constructor(lines: LineString[]);
|
||||
parse(key: any): {
|
||||
[x: number]: {
|
||||
type: string;
|
||||
coordinates: number[][][];
|
||||
};
|
||||
};
|
||||
toJSON(): {
|
||||
type: string;
|
||||
coordinates: number[][][];
|
||||
};
|
||||
static validate(multiLineString: ISerializedMultiLineString): boolean;
|
||||
readonly _internalType: import("../utils/symbol").InternalSymbol;
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const symbol_1 = require("../helper/symbol");
|
||||
const type_1 = require("../utils/type");
|
||||
const lineString_1 = require("./lineString");
|
||||
class MultiLineString {
|
||||
constructor(lines) {
|
||||
if (!type_1.isArray(lines)) {
|
||||
throw new TypeError(`"lines" must be of type LineString[]. Received type ${typeof lines}`);
|
||||
}
|
||||
if (lines.length === 0) {
|
||||
throw new Error('Polygon must contain 1 linestring at least');
|
||||
}
|
||||
lines.forEach(line => {
|
||||
if (!(line instanceof lineString_1.LineString)) {
|
||||
throw new TypeError(`"lines" must be of type LineString[]. Received type ${typeof line}[]`);
|
||||
}
|
||||
});
|
||||
this.lines = lines;
|
||||
}
|
||||
parse(key) {
|
||||
return {
|
||||
[key]: {
|
||||
type: 'MultiLineString',
|
||||
coordinates: this.lines.map(line => {
|
||||
return line.points.map(point => [point.longitude, point.latitude]);
|
||||
})
|
||||
}
|
||||
};
|
||||
}
|
||||
toJSON() {
|
||||
return {
|
||||
type: 'MultiLineString',
|
||||
coordinates: this.lines.map(line => {
|
||||
return line.points.map(point => [point.longitude, point.latitude]);
|
||||
})
|
||||
};
|
||||
}
|
||||
static validate(multiLineString) {
|
||||
if (multiLineString.type !== 'MultiLineString' || !type_1.isArray(multiLineString.coordinates)) {
|
||||
return false;
|
||||
}
|
||||
for (let line of multiLineString.coordinates) {
|
||||
for (let point of line) {
|
||||
if (!type_1.isNumber(point[0]) || !type_1.isNumber(point[1])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
get _internalType() {
|
||||
return symbol_1.SYMBOL_GEO_MULTI_LINE_STRING;
|
||||
}
|
||||
}
|
||||
exports.MultiLineString = MultiLineString;
|
@ -0,0 +1,18 @@
|
||||
import { Point } from './point';
|
||||
import { ISerializedMultiPoint } from './interface';
|
||||
export declare class MultiPoint {
|
||||
readonly points: Point[];
|
||||
constructor(points: Point[]);
|
||||
parse(key: any): {
|
||||
[x: number]: {
|
||||
type: string;
|
||||
coordinates: number[][];
|
||||
};
|
||||
};
|
||||
toJSON(): {
|
||||
type: string;
|
||||
coordinates: number[][];
|
||||
};
|
||||
static validate(multiPoint: ISerializedMultiPoint): boolean;
|
||||
readonly _internalType: import("../utils/symbol").InternalSymbol;
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const symbol_1 = require("../helper/symbol");
|
||||
const point_1 = require("./point");
|
||||
const type_1 = require("../utils/type");
|
||||
class MultiPoint {
|
||||
constructor(points) {
|
||||
if (!type_1.isArray(points)) {
|
||||
throw new TypeError(`"points" must be of type Point[]. Received type ${typeof points}`);
|
||||
}
|
||||
if (points.length === 0) {
|
||||
throw new Error('"points" must contain 1 point at least');
|
||||
}
|
||||
points.forEach(point => {
|
||||
if (!(point instanceof point_1.Point)) {
|
||||
throw new TypeError(`"points" must be of type Point[]. Received type ${typeof point}[]`);
|
||||
}
|
||||
});
|
||||
this.points = points;
|
||||
}
|
||||
parse(key) {
|
||||
return {
|
||||
[key]: {
|
||||
type: 'MultiPoint',
|
||||
coordinates: this.points.map(point => point.toJSON().coordinates)
|
||||
}
|
||||
};
|
||||
}
|
||||
toJSON() {
|
||||
return {
|
||||
type: 'MultiPoint',
|
||||
coordinates: this.points.map(point => point.toJSON().coordinates)
|
||||
};
|
||||
}
|
||||
static validate(multiPoint) {
|
||||
if (multiPoint.type !== 'MultiPoint' || !type_1.isArray(multiPoint.coordinates)) {
|
||||
return false;
|
||||
}
|
||||
for (let point of multiPoint.coordinates) {
|
||||
if (!type_1.isNumber(point[0]) || !type_1.isNumber(point[1])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
get _internalType() {
|
||||
return symbol_1.SYMBOL_GEO_MULTI_POINT;
|
||||
}
|
||||
}
|
||||
exports.MultiPoint = MultiPoint;
|
@ -0,0 +1,18 @@
|
||||
import { Polygon } from './polygon';
|
||||
import { ISerializedMultiPolygon } from './interface';
|
||||
export declare class MultiPolygon {
|
||||
readonly polygons: Polygon[];
|
||||
constructor(polygons: Polygon[]);
|
||||
parse(key: any): {
|
||||
[x: number]: {
|
||||
type: string;
|
||||
coordinates: number[][][][];
|
||||
};
|
||||
};
|
||||
toJSON(): {
|
||||
type: string;
|
||||
coordinates: number[][][][];
|
||||
};
|
||||
static validate(multiPolygon: ISerializedMultiPolygon): boolean;
|
||||
readonly _internalType: import("../utils/symbol").InternalSymbol;
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const symbol_1 = require("../helper/symbol");
|
||||
const type_1 = require("../utils/type");
|
||||
const polygon_1 = require("./polygon");
|
||||
class MultiPolygon {
|
||||
constructor(polygons) {
|
||||
if (!type_1.isArray(polygons)) {
|
||||
throw new TypeError(`"polygons" must be of type Polygon[]. Received type ${typeof polygons}`);
|
||||
}
|
||||
if (polygons.length === 0) {
|
||||
throw new Error('MultiPolygon must contain 1 polygon at least');
|
||||
}
|
||||
for (let polygon of polygons) {
|
||||
if (!(polygon instanceof polygon_1.Polygon)) {
|
||||
throw new TypeError(`"polygon" must be of type Polygon[]. Received type ${typeof polygon}[]`);
|
||||
}
|
||||
}
|
||||
this.polygons = polygons;
|
||||
}
|
||||
parse(key) {
|
||||
return {
|
||||
[key]: {
|
||||
type: 'MultiPolygon',
|
||||
coordinates: this.polygons.map(polygon => {
|
||||
return polygon.lines.map(line => {
|
||||
return line.points.map(point => [point.longitude, point.latitude]);
|
||||
});
|
||||
})
|
||||
}
|
||||
};
|
||||
}
|
||||
toJSON() {
|
||||
return {
|
||||
type: 'MultiPolygon',
|
||||
coordinates: this.polygons.map(polygon => {
|
||||
return polygon.lines.map(line => {
|
||||
return line.points.map(point => [point.longitude, point.latitude]);
|
||||
});
|
||||
})
|
||||
};
|
||||
}
|
||||
static validate(multiPolygon) {
|
||||
if (multiPolygon.type !== 'MultiPolygon' || !type_1.isArray(multiPolygon.coordinates)) {
|
||||
return false;
|
||||
}
|
||||
for (let polygon of multiPolygon.coordinates) {
|
||||
for (let line of polygon) {
|
||||
for (let point of line) {
|
||||
if (!type_1.isNumber(point[0]) || !type_1.isNumber(point[1])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
get _internalType() {
|
||||
return symbol_1.SYMBOL_GEO_MULTI_POLYGON;
|
||||
}
|
||||
}
|
||||
exports.MultiPolygon = MultiPolygon;
|
@ -0,0 +1,19 @@
|
||||
import { ISerializedPoint } from './interface';
|
||||
export declare class Point {
|
||||
readonly latitude: number;
|
||||
readonly longitude: number;
|
||||
constructor(longitude: number, latitude: number);
|
||||
parse(key: any): {
|
||||
[x: number]: {
|
||||
type: string;
|
||||
coordinates: number[];
|
||||
};
|
||||
};
|
||||
toJSON(): {
|
||||
type: string;
|
||||
coordinates: number[];
|
||||
};
|
||||
toReadableString(): string;
|
||||
static validate(point: ISerializedPoint): boolean;
|
||||
readonly _internalType: import("../utils/symbol").InternalSymbol;
|
||||
}
|
43
CLASS1/cloudfunctions/excel/node_modules/@cloudbase/database/dist/commonjs/geo/point.js
generated
vendored
43
CLASS1/cloudfunctions/excel/node_modules/@cloudbase/database/dist/commonjs/geo/point.js
generated
vendored
@ -0,0 +1,43 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const validate_1 = require("../validate");
|
||||
const symbol_1 = require("../helper/symbol");
|
||||
const type_1 = require("../utils/type");
|
||||
class Point {
|
||||
constructor(longitude, latitude) {
|
||||
validate_1.Validate.isGeopoint('longitude', longitude);
|
||||
validate_1.Validate.isGeopoint('latitude', latitude);
|
||||
this.longitude = longitude;
|
||||
this.latitude = latitude;
|
||||
}
|
||||
parse(key) {
|
||||
return {
|
||||
[key]: {
|
||||
type: 'Point',
|
||||
coordinates: [this.longitude, this.latitude]
|
||||
}
|
||||
};
|
||||
}
|
||||
toJSON() {
|
||||
return {
|
||||
type: 'Point',
|
||||
coordinates: [
|
||||
this.longitude,
|
||||
this.latitude,
|
||||
],
|
||||
};
|
||||
}
|
||||
toReadableString() {
|
||||
return `[${this.longitude},${this.latitude}]`;
|
||||
}
|
||||
static validate(point) {
|
||||
return point.type === 'Point' &&
|
||||
type_1.isArray(point.coordinates) &&
|
||||
validate_1.Validate.isGeopoint('longitude', point.coordinates[0]) &&
|
||||
validate_1.Validate.isGeopoint('latitude', point.coordinates[1]);
|
||||
}
|
||||
get _internalType() {
|
||||
return symbol_1.SYMBOL_GEO_POINT;
|
||||
}
|
||||
}
|
||||
exports.Point = Point;
|
@ -0,0 +1,19 @@
|
||||
import { LineString } from './lineString';
|
||||
import { ISerializedPolygon } from './interface';
|
||||
export declare class Polygon {
|
||||
readonly lines: LineString[];
|
||||
constructor(lines: LineString[]);
|
||||
parse(key: any): {
|
||||
[x: number]: {
|
||||
type: string;
|
||||
coordinates: number[][][];
|
||||
};
|
||||
};
|
||||
toJSON(): {
|
||||
type: string;
|
||||
coordinates: number[][][];
|
||||
};
|
||||
static validate(polygon: ISerializedPolygon): boolean;
|
||||
static isCloseLineString(lineString: any): boolean;
|
||||
readonly _internalType: import("../utils/symbol").InternalSymbol;
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const symbol_1 = require("../helper/symbol");
|
||||
const type_1 = require("../utils/type");
|
||||
const lineString_1 = require("./lineString");
|
||||
class Polygon {
|
||||
constructor(lines) {
|
||||
if (!type_1.isArray(lines)) {
|
||||
throw new TypeError(`"lines" must be of type LineString[]. Received type ${typeof lines}`);
|
||||
}
|
||||
if (lines.length === 0) {
|
||||
throw new Error('Polygon must contain 1 linestring at least');
|
||||
}
|
||||
lines.forEach(line => {
|
||||
if (!(line instanceof lineString_1.LineString)) {
|
||||
throw new TypeError(`"lines" must be of type LineString[]. Received type ${typeof line}[]`);
|
||||
}
|
||||
if (!lineString_1.LineString.isClosed(line)) {
|
||||
throw new Error(`LineString ${line.points.map(p => p.toReadableString())} is not a closed cycle`);
|
||||
}
|
||||
});
|
||||
this.lines = lines;
|
||||
}
|
||||
parse(key) {
|
||||
return {
|
||||
[key]: {
|
||||
type: 'Polygon',
|
||||
coordinates: this.lines.map(line => {
|
||||
return line.points.map(point => [point.longitude, point.latitude]);
|
||||
})
|
||||
}
|
||||
};
|
||||
}
|
||||
toJSON() {
|
||||
return {
|
||||
type: 'Polygon',
|
||||
coordinates: this.lines.map(line => {
|
||||
return line.points.map(point => [point.longitude, point.latitude]);
|
||||
})
|
||||
};
|
||||
}
|
||||
static validate(polygon) {
|
||||
if (polygon.type !== 'Polygon' || !type_1.isArray(polygon.coordinates)) {
|
||||
return false;
|
||||
}
|
||||
for (let line of polygon.coordinates) {
|
||||
if (!this.isCloseLineString(line)) {
|
||||
return false;
|
||||
}
|
||||
for (let point of line) {
|
||||
if (!type_1.isNumber(point[0]) || !type_1.isNumber(point[1])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
static isCloseLineString(lineString) {
|
||||
const firstPoint = lineString[0];
|
||||
const lastPoint = lineString[lineString.length - 1];
|
||||
if (firstPoint[0] !== lastPoint[0] || firstPoint[1] !== lastPoint[1]) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
get _internalType() {
|
||||
return symbol_1.SYMBOL_GEO_POLYGON;
|
||||
}
|
||||
}
|
||||
exports.Polygon = Polygon;
|
@ -0,0 +1,15 @@
|
||||
import InternalSymbol from '../utils/symbol';
|
||||
export * from '../utils/symbol';
|
||||
export declare const SYMBOL_UNSET_FIELD_NAME: InternalSymbol;
|
||||
export declare const SYMBOL_UPDATE_COMMAND: InternalSymbol;
|
||||
export declare const SYMBOL_QUERY_COMMAND: InternalSymbol;
|
||||
export declare const SYMBOL_LOGIC_COMMAND: InternalSymbol;
|
||||
export declare const SYMBOL_GEO_POINT: InternalSymbol;
|
||||
export declare const SYMBOL_GEO_LINE_STRING: InternalSymbol;
|
||||
export declare const SYMBOL_GEO_POLYGON: InternalSymbol;
|
||||
export declare const SYMBOL_GEO_MULTI_POINT: InternalSymbol;
|
||||
export declare const SYMBOL_GEO_MULTI_LINE_STRING: InternalSymbol;
|
||||
export declare const SYMBOL_GEO_MULTI_POLYGON: InternalSymbol;
|
||||
export declare const SYMBOL_SERVER_DATE: InternalSymbol;
|
||||
export declare const SYMBOL_REGEXP: InternalSymbol;
|
||||
export declare const SYMBOL_OBJECTID: InternalSymbol;
|
@ -0,0 +1,20 @@
|
||||
"use strict";
|
||||
function __export(m) {
|
||||
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
|
||||
}
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const symbol_1 = require("../utils/symbol");
|
||||
__export(require("../utils/symbol"));
|
||||
exports.SYMBOL_UNSET_FIELD_NAME = symbol_1.default.for('UNSET_FIELD_NAME');
|
||||
exports.SYMBOL_UPDATE_COMMAND = symbol_1.default.for('UPDATE_COMMAND');
|
||||
exports.SYMBOL_QUERY_COMMAND = symbol_1.default.for('QUERY_COMMAND');
|
||||
exports.SYMBOL_LOGIC_COMMAND = symbol_1.default.for('LOGIC_COMMAND');
|
||||
exports.SYMBOL_GEO_POINT = symbol_1.default.for('GEO_POINT');
|
||||
exports.SYMBOL_GEO_LINE_STRING = symbol_1.default.for('SYMBOL_GEO_LINE_STRING');
|
||||
exports.SYMBOL_GEO_POLYGON = symbol_1.default.for('SYMBOL_GEO_POLYGON');
|
||||
exports.SYMBOL_GEO_MULTI_POINT = symbol_1.default.for('SYMBOL_GEO_MULTI_POINT');
|
||||
exports.SYMBOL_GEO_MULTI_LINE_STRING = symbol_1.default.for('SYMBOL_GEO_MULTI_LINE_STRING');
|
||||
exports.SYMBOL_GEO_MULTI_POLYGON = symbol_1.default.for('SYMBOL_GEO_MULTI_POLYGON');
|
||||
exports.SYMBOL_SERVER_DATE = symbol_1.default.for('SERVER_DATE');
|
||||
exports.SYMBOL_REGEXP = symbol_1.default.for('REGEXP');
|
||||
exports.SYMBOL_OBJECTID = symbol_1.default.for('OBJECTID');
|
50
CLASS1/cloudfunctions/excel/node_modules/@cloudbase/database/dist/commonjs/index.d.ts
generated
vendored
50
CLASS1/cloudfunctions/excel/node_modules/@cloudbase/database/dist/commonjs/index.d.ts
generated
vendored
@ -0,0 +1,50 @@
|
||||
import { Point } from './geo/point';
|
||||
import { CollectionReference } from './collection';
|
||||
import { Command } from './command';
|
||||
interface GeoTeyp {
|
||||
Point: typeof Point;
|
||||
}
|
||||
export { Query } from './query';
|
||||
export { CollectionReference } from './collection';
|
||||
export { DocumentReference } from './document';
|
||||
interface ICloudBaseConfig {
|
||||
timeout?: number;
|
||||
isHttp?: boolean;
|
||||
secretId?: string;
|
||||
secretKey?: string;
|
||||
envName?: string;
|
||||
env?: string;
|
||||
sessionToken?: string;
|
||||
serviceUrl?: string;
|
||||
headers?: any;
|
||||
proxy?: string;
|
||||
version?: string;
|
||||
credentials?: ICredentialsInfo;
|
||||
_useFeature?: boolean;
|
||||
throwOnCode?: boolean;
|
||||
}
|
||||
interface ICredentialsInfo {
|
||||
private_key_id: string;
|
||||
private_key: string;
|
||||
}
|
||||
export declare class Db {
|
||||
Geo: GeoTeyp;
|
||||
command: typeof Command;
|
||||
RegExp: any;
|
||||
serverDate: any;
|
||||
ObjectId: any;
|
||||
startTransaction: any;
|
||||
runTransaction: any;
|
||||
config: ICloudBaseConfig;
|
||||
static ws: any;
|
||||
static reqClass: any;
|
||||
static wsClass: any;
|
||||
static createSign: Function;
|
||||
static getAccessToken: Function;
|
||||
static dataVersion: string;
|
||||
static runtime: string;
|
||||
static appSecretInfo: any;
|
||||
constructor(config?: any);
|
||||
collection(collName: string): CollectionReference;
|
||||
createCollection(collName: string): any;
|
||||
}
|
41
CLASS1/cloudfunctions/excel/node_modules/@cloudbase/database/dist/commonjs/index.js
generated
vendored
41
CLASS1/cloudfunctions/excel/node_modules/@cloudbase/database/dist/commonjs/index.js
generated
vendored
@ -0,0 +1,41 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const Geo = require("./geo/index");
|
||||
const collection_1 = require("./collection");
|
||||
const command_1 = require("./command");
|
||||
const index_1 = require("./serverDate/index");
|
||||
const index_2 = require("./regexp/index");
|
||||
const index_3 = require("./transaction/index");
|
||||
const index_4 = require("./ObjectId/index");
|
||||
var query_1 = require("./query");
|
||||
exports.Query = query_1.Query;
|
||||
var collection_2 = require("./collection");
|
||||
exports.CollectionReference = collection_2.CollectionReference;
|
||||
var document_1 = require("./document");
|
||||
exports.DocumentReference = document_1.DocumentReference;
|
||||
class Db {
|
||||
constructor(config) {
|
||||
this.config = config;
|
||||
this.Geo = Geo;
|
||||
this.serverDate = index_1.ServerDateConstructor;
|
||||
this.command = command_1.Command;
|
||||
this.RegExp = index_2.RegExpConstructor;
|
||||
this.ObjectId = index_4.ObjectIdConstructor;
|
||||
this.startTransaction = index_3.startTransaction;
|
||||
this.runTransaction = index_3.runTransaction;
|
||||
}
|
||||
collection(collName) {
|
||||
if (!collName) {
|
||||
throw new Error('Collection name is required');
|
||||
}
|
||||
return new collection_1.CollectionReference(this, collName);
|
||||
}
|
||||
createCollection(collName) {
|
||||
let request = new Db.reqClass(this.config);
|
||||
const params = {
|
||||
collectionName: collName
|
||||
};
|
||||
return request.send('database.addCollection', params);
|
||||
}
|
||||
}
|
||||
exports.Db = Db;
|
@ -0,0 +1,4 @@
|
||||
export declare const OperatorMap: {
|
||||
[key: string]: string;
|
||||
};
|
||||
export declare function operatorToString(operator: string): string;
|
@ -0,0 +1,23 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const query_1 = require("./commands/query");
|
||||
const logic_1 = require("./commands/logic");
|
||||
const update_1 = require("./commands/update");
|
||||
exports.OperatorMap = {};
|
||||
for (const key in query_1.QUERY_COMMANDS_LITERAL) {
|
||||
exports.OperatorMap[key] = '$' + key;
|
||||
}
|
||||
for (const key in logic_1.LOGIC_COMMANDS_LITERAL) {
|
||||
exports.OperatorMap[key] = '$' + key;
|
||||
}
|
||||
for (const key in update_1.UPDATE_COMMANDS_LITERAL) {
|
||||
exports.OperatorMap[key] = '$' + key;
|
||||
}
|
||||
exports.OperatorMap[query_1.QUERY_COMMANDS_LITERAL.NEQ] = '$ne';
|
||||
exports.OperatorMap[update_1.UPDATE_COMMANDS_LITERAL.REMOVE] = '$unset';
|
||||
exports.OperatorMap[update_1.UPDATE_COMMANDS_LITERAL.SHIFT] = '$pop';
|
||||
exports.OperatorMap[update_1.UPDATE_COMMANDS_LITERAL.UNSHIFT] = '$push';
|
||||
function operatorToString(operator) {
|
||||
return exports.OperatorMap[operator] || '$' + operator;
|
||||
}
|
||||
exports.operatorToString = operatorToString;
|
38
CLASS1/cloudfunctions/excel/node_modules/@cloudbase/database/dist/commonjs/query.d.ts
generated
vendored
38
CLASS1/cloudfunctions/excel/node_modules/@cloudbase/database/dist/commonjs/query.d.ts
generated
vendored
@ -0,0 +1,38 @@
|
||||
import { OrderByDirection } from './constant';
|
||||
import { IWatchOptions, DBRealtimeListener } from './typings/index';
|
||||
interface GetRes {
|
||||
data: any[];
|
||||
requestId: string;
|
||||
total: number;
|
||||
limit: number;
|
||||
offset: number;
|
||||
}
|
||||
interface BaseOption {
|
||||
timeout?: number;
|
||||
raw?: boolean;
|
||||
}
|
||||
export interface QueryOption extends BaseOption {
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
projection?: Object;
|
||||
order?: Record<string, any>[];
|
||||
}
|
||||
export interface UpdateOption extends BaseOption {
|
||||
multiple?: boolean;
|
||||
}
|
||||
export declare class Query {
|
||||
protected _transactionId: string;
|
||||
get(): Promise<GetRes>;
|
||||
count(): Promise<any>;
|
||||
where(query: object): Query;
|
||||
options(apiOptions: QueryOption | UpdateOption): Query;
|
||||
orderBy(fieldPath: string, directionStr: OrderByDirection): Query;
|
||||
limit(limit: number): Query;
|
||||
skip(offset: number): Query;
|
||||
update(data: Object): Promise<any>;
|
||||
field(projection: any): Query;
|
||||
remove(): Promise<any>;
|
||||
updateAndReturn(data: Object): Promise<any>;
|
||||
watch: (options: IWatchOptions) => DBRealtimeListener;
|
||||
}
|
||||
export {};
|
247
CLASS1/cloudfunctions/excel/node_modules/@cloudbase/database/dist/commonjs/query.js
generated
vendored
247
CLASS1/cloudfunctions/excel/node_modules/@cloudbase/database/dist/commonjs/query.js
generated
vendored
@ -0,0 +1,247 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const constant_1 = require("./constant");
|
||||
const index_1 = require("./index");
|
||||
const validate_1 = require("./validate");
|
||||
const util_1 = require("./util");
|
||||
const query_1 = require("./serializer/query");
|
||||
const update_1 = require("./serializer/update");
|
||||
const websocket_client_1 = require("./realtime/websocket-client");
|
||||
const constant_2 = require("./constant");
|
||||
const utils_1 = require("./utils/utils");
|
||||
const code_1 = require("./const/code");
|
||||
const bson_1 = require("bson");
|
||||
class Query {
|
||||
constructor(db, coll, fieldFilters, apiOptions, transactionId) {
|
||||
this.watch = (options) => {
|
||||
if (!index_1.Db.ws) {
|
||||
index_1.Db.ws = new websocket_client_1.RealtimeWebSocketClient({
|
||||
context: {
|
||||
appConfig: {
|
||||
docSizeLimit: 1000,
|
||||
realtimePingInterval: 10000,
|
||||
realtimePongWaitTimeout: 5000,
|
||||
request: this._request
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
const { limit, order } = this._apiOptions;
|
||||
return index_1.Db.ws.watch(Object.assign(Object.assign({}, options), { envId: this._db.config.env, collectionName: this._coll, query: JSON.stringify(this._fieldFilters), limit, orderBy: order
|
||||
? order.reduce((acc, cur) => {
|
||||
acc[cur.field] = cur.direction;
|
||||
return acc;
|
||||
}, {})
|
||||
: undefined }));
|
||||
};
|
||||
this._db = db;
|
||||
this._coll = coll;
|
||||
this._fieldFilters = fieldFilters;
|
||||
this._apiOptions = apiOptions || {};
|
||||
this._request = new index_1.Db.reqClass(this._db.config);
|
||||
this._transactionId = transactionId;
|
||||
}
|
||||
async get() {
|
||||
const order = this._apiOptions.order;
|
||||
let param = {
|
||||
collectionName: this._coll,
|
||||
queryType: constant_1.QueryType.WHERE,
|
||||
transactionId: this._transactionId
|
||||
};
|
||||
if (this._fieldFilters) {
|
||||
param.query = this._fieldFilters;
|
||||
}
|
||||
if (order) {
|
||||
param.order = utils_1.stringifyByEJSON(order);
|
||||
}
|
||||
const offset = this._apiOptions.offset;
|
||||
if (offset) {
|
||||
param.offset = offset;
|
||||
}
|
||||
const limit = this._apiOptions.limit;
|
||||
if (limit) {
|
||||
param.limit = limit < 1000 ? limit : 1000;
|
||||
}
|
||||
else {
|
||||
param.limit = 100;
|
||||
}
|
||||
const projection = this._apiOptions.projection;
|
||||
if (projection) {
|
||||
param.projection = utils_1.stringifyByEJSON(projection);
|
||||
}
|
||||
const res = await this._request.send('database.getDocument', param, utils_1.getReqOpts(this._apiOptions));
|
||||
if (res.code) {
|
||||
return res;
|
||||
}
|
||||
const list = res.data.list.map(item => bson_1.EJSON.parse(item));
|
||||
const documents = util_1.Util.formatResDocumentData(list);
|
||||
const result = {
|
||||
data: documents,
|
||||
requestId: res.requestId
|
||||
};
|
||||
if (res.limit)
|
||||
result.limit = res.limit;
|
||||
if (res.offset)
|
||||
result.offset = res.offset;
|
||||
return result;
|
||||
}
|
||||
async count() {
|
||||
let param = {
|
||||
collectionName: this._coll,
|
||||
queryType: constant_1.QueryType.WHERE
|
||||
};
|
||||
if (this._fieldFilters) {
|
||||
param.query = this._fieldFilters;
|
||||
}
|
||||
const res = await this._request.send('database.calculateDocument', param, utils_1.getReqOpts(this._apiOptions));
|
||||
if (res.code) {
|
||||
return res;
|
||||
}
|
||||
return {
|
||||
requestId: res.requestId,
|
||||
total: res.data.total
|
||||
};
|
||||
}
|
||||
where(query) {
|
||||
if (Object.prototype.toString.call(query).slice(8, -1) !== 'Object') {
|
||||
throw Error(constant_2.ErrorCode.QueryParamTypeError);
|
||||
}
|
||||
const keys = Object.keys(query);
|
||||
const checkFlag = keys.some(item => {
|
||||
return query[item] !== undefined;
|
||||
});
|
||||
if (keys.length && !checkFlag) {
|
||||
throw Error(constant_2.ErrorCode.QueryParamValueError);
|
||||
}
|
||||
return new Query(this._db, this._coll, query_1.QuerySerializer.encodeEJSON(query, this._apiOptions.raw || false), this._apiOptions, this._transactionId);
|
||||
}
|
||||
options(apiOptions) {
|
||||
validate_1.Validate.isValidOptions(apiOptions);
|
||||
return new Query(this._db, this._coll, this._fieldFilters, apiOptions, this._transactionId);
|
||||
}
|
||||
orderBy(fieldPath, directionStr) {
|
||||
validate_1.Validate.isFieldPath(fieldPath);
|
||||
validate_1.Validate.isFieldOrder(directionStr);
|
||||
const newOrder = {
|
||||
[fieldPath]: directionStr === 'desc' ? -1 : 1
|
||||
};
|
||||
const order = this._apiOptions.order || {};
|
||||
const newApiOption = Object.assign({}, this._apiOptions, {
|
||||
order: Object.assign({}, order, newOrder)
|
||||
});
|
||||
return new Query(this._db, this._coll, this._fieldFilters, newApiOption, this._transactionId);
|
||||
}
|
||||
limit(limit) {
|
||||
validate_1.Validate.isInteger('limit', limit);
|
||||
let newApiOption = Object.assign({}, this._apiOptions);
|
||||
newApiOption.limit = limit;
|
||||
return new Query(this._db, this._coll, this._fieldFilters, newApiOption, this._transactionId);
|
||||
}
|
||||
skip(offset) {
|
||||
validate_1.Validate.isInteger('offset', offset);
|
||||
let newApiOption = Object.assign({}, this._apiOptions);
|
||||
newApiOption.offset = offset;
|
||||
return new Query(this._db, this._coll, this._fieldFilters, newApiOption, this._transactionId);
|
||||
}
|
||||
async update(data) {
|
||||
if (!data || typeof data !== 'object') {
|
||||
return utils_1.processReturn(this._db.config.throwOnCode, Object.assign(Object.assign({}, code_1.ERRORS.INVALID_PARAM), { message: '参数必需是非空对象' }));
|
||||
}
|
||||
if (data.hasOwnProperty('_id')) {
|
||||
return utils_1.processReturn(this._db.config.throwOnCode, Object.assign(Object.assign({}, code_1.ERRORS.INVALID_PARAM), { message: '不能更新_id的值' }));
|
||||
}
|
||||
let { multiple } = this._apiOptions;
|
||||
const multi = multiple === undefined ? true : multiple;
|
||||
let param = {
|
||||
collectionName: this._coll,
|
||||
queryType: constant_1.QueryType.WHERE,
|
||||
multi,
|
||||
merge: true,
|
||||
upsert: false,
|
||||
data: update_1.UpdateSerializer.encodeEJSON(data, this._apiOptions.raw || false)
|
||||
};
|
||||
if (this._fieldFilters) {
|
||||
param.query = this._fieldFilters;
|
||||
}
|
||||
const res = await this._request.send('database.modifyDocument', param, utils_1.getReqOpts(this._apiOptions));
|
||||
if (res.code) {
|
||||
return res;
|
||||
}
|
||||
return {
|
||||
requestId: res.requestId,
|
||||
updated: res.data.updated,
|
||||
upsertId: res.data.upsert_id
|
||||
};
|
||||
}
|
||||
field(projection) {
|
||||
let transformProjection = {};
|
||||
for (let k in projection) {
|
||||
if (typeof projection[k] === 'boolean') {
|
||||
transformProjection[k] = projection[k] === true ? 1 : 0;
|
||||
}
|
||||
if (typeof projection[k] === 'number') {
|
||||
transformProjection[k] = projection[k] > 0 ? 1 : 0;
|
||||
}
|
||||
if (typeof projection[k] === 'object') {
|
||||
transformProjection[k] = projection[k];
|
||||
}
|
||||
}
|
||||
let newApiOption = Object.assign({}, this._apiOptions);
|
||||
newApiOption.projection = transformProjection;
|
||||
return new Query(this._db, this._coll, this._fieldFilters, newApiOption, this._transactionId);
|
||||
}
|
||||
async remove() {
|
||||
const { offset, limit, projection, order } = this._apiOptions;
|
||||
if (offset !== undefined ||
|
||||
limit !== undefined ||
|
||||
projection !== undefined ||
|
||||
order !== undefined) {
|
||||
console.warn('`offset`, `limit`, `projection`, `orderBy` are not supported in remove() operation');
|
||||
}
|
||||
let { multiple } = this._apiOptions;
|
||||
const multi = multiple === undefined ? true : multiple;
|
||||
const param = {
|
||||
collectionName: this._coll,
|
||||
query: this._fieldFilters,
|
||||
queryType: constant_1.QueryType.WHERE,
|
||||
multi
|
||||
};
|
||||
const res = await this._request.send('database.removeDocument', param, utils_1.getReqOpts(this._apiOptions));
|
||||
if (res.code) {
|
||||
return res;
|
||||
}
|
||||
return {
|
||||
requestId: res.requestId,
|
||||
deleted: res.data.deleted
|
||||
};
|
||||
}
|
||||
async updateAndReturn(data) {
|
||||
if (!data || typeof data !== 'object') {
|
||||
return utils_1.processReturn(this._db.config.throwOnCode, Object.assign(Object.assign({}, code_1.ERRORS.INVALID_PARAM), { message: '参数必需是非空对象' }));
|
||||
}
|
||||
if (data.hasOwnProperty('_id')) {
|
||||
return utils_1.processReturn(this._db.config.throwOnCode, Object.assign(Object.assign({}, code_1.ERRORS.INVALID_PARAM), { message: '不能更新_id的值' }));
|
||||
}
|
||||
let param = {
|
||||
collectionName: this._coll,
|
||||
queryType: constant_1.QueryType.WHERE,
|
||||
data: update_1.UpdateSerializer.encodeEJSON(data, false)
|
||||
};
|
||||
if (this._transactionId) {
|
||||
param.transactionId = this._transactionId;
|
||||
}
|
||||
if (this._fieldFilters) {
|
||||
param.query = this._fieldFilters;
|
||||
}
|
||||
const res = await this._request.send('database.modifyAndReturnDoc', param, utils_1.getReqOpts(this._apiOptions));
|
||||
if (res.code) {
|
||||
return res;
|
||||
}
|
||||
return {
|
||||
requestId: res.requestId,
|
||||
updated: res.data.updated,
|
||||
doc: res.data.doc && bson_1.EJSON.parse(res.data.doc)
|
||||
};
|
||||
}
|
||||
}
|
||||
exports.Query = Query;
|
@ -0,0 +1,7 @@
|
||||
import { IResponseMessageErrorMsg } from '../typings/realtime';
|
||||
export declare class RealtimeErrorMessageError extends Error {
|
||||
isRealtimeErrorMessageError: boolean;
|
||||
payload: IResponseMessageErrorMsg;
|
||||
constructor(serverErrorMsg: IResponseMessageErrorMsg);
|
||||
}
|
||||
export declare const isRealtimeErrorMessageError: (e: any) => e is RealtimeErrorMessageError;
|
@ -0,0 +1,11 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
class RealtimeErrorMessageError extends Error {
|
||||
constructor(serverErrorMsg) {
|
||||
super(`Watch Error ${JSON.stringify(serverErrorMsg.msgData)} (requestid: ${serverErrorMsg.requestId})`);
|
||||
this.isRealtimeErrorMessageError = true;
|
||||
this.payload = serverErrorMsg;
|
||||
}
|
||||
}
|
||||
exports.RealtimeErrorMessageError = RealtimeErrorMessageError;
|
||||
exports.isRealtimeErrorMessageError = (e) => e && e.isRealtimeErrorMessageError;
|
@ -0,0 +1,14 @@
|
||||
import { VirtualWebSocketClient } from './virtual-websocket-client';
|
||||
import { IRealtimeListenerConstructorOptions, DBRealtimeListener } from '../typings/index';
|
||||
interface IRealtimeListenerOptions extends IRealtimeListenerConstructorOptions {
|
||||
close: () => void;
|
||||
debug?: boolean;
|
||||
virtualClient?: VirtualWebSocketClient;
|
||||
}
|
||||
export declare class RealtimeListener implements DBRealtimeListener {
|
||||
close: () => void;
|
||||
onChange: (res: any) => void;
|
||||
onError: (error: any) => void;
|
||||
constructor(options: IRealtimeListenerOptions);
|
||||
}
|
||||
export {};
|
@ -0,0 +1,17 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
class RealtimeListener {
|
||||
constructor(options) {
|
||||
this.close = options.close;
|
||||
this.onChange = options.onChange;
|
||||
this.onError = options.onError;
|
||||
if (options.debug) {
|
||||
Object.defineProperty(this, 'virtualClient', {
|
||||
get: () => {
|
||||
return options.virtualClient;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.RealtimeListener = RealtimeListener;
|
@ -0,0 +1,3 @@
|
||||
import { IResponseMessage, IResponseMessageInitEventMsg } from '../typings/realtime';
|
||||
export declare function genRequestId(prefix?: string): string;
|
||||
export declare function isInitEventMessage(msg: IResponseMessage): msg is IResponseMessageInitEventMsg;
|
@ -0,0 +1,10 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
function genRequestId(prefix = '') {
|
||||
return `${prefix ? `${prefix}_` : ''}${+new Date()}_${Math.random()}`;
|
||||
}
|
||||
exports.genRequestId = genRequestId;
|
||||
function isInitEventMessage(msg) {
|
||||
return msg.msgType === 'INIT_EVENT';
|
||||
}
|
||||
exports.isInitEventMessage = isInitEventMessage;
|
@ -0,0 +1,16 @@
|
||||
import { ISingleDBEvent, SnapshotType, ISnapshot } from '../typings/index';
|
||||
interface ISnapshotConstructorOptions {
|
||||
id: number;
|
||||
docChanges: ISingleDBEvent[];
|
||||
docs: Record<string, any>[];
|
||||
type?: SnapshotType;
|
||||
msgType?: String;
|
||||
}
|
||||
export declare class Snapshot implements ISnapshot {
|
||||
id: number;
|
||||
docChanges: ISingleDBEvent[];
|
||||
docs: Record<string, any>[];
|
||||
type?: 'init';
|
||||
constructor(options: ISnapshotConstructorOptions);
|
||||
}
|
||||
export {};
|
@ -0,0 +1,42 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
class Snapshot {
|
||||
constructor(options) {
|
||||
const { id, docChanges, docs, msgType, type } = options;
|
||||
let cachedDocChanges;
|
||||
let cachedDocs;
|
||||
Object.defineProperties(this, {
|
||||
id: {
|
||||
get: () => id,
|
||||
enumerable: true
|
||||
},
|
||||
docChanges: {
|
||||
get: () => {
|
||||
if (!cachedDocChanges) {
|
||||
cachedDocChanges = JSON.parse(JSON.stringify(docChanges));
|
||||
}
|
||||
return cachedDocChanges;
|
||||
},
|
||||
enumerable: true
|
||||
},
|
||||
docs: {
|
||||
get: () => {
|
||||
if (!cachedDocs) {
|
||||
cachedDocs = JSON.parse(JSON.stringify(docs));
|
||||
}
|
||||
return cachedDocs;
|
||||
},
|
||||
enumerable: true
|
||||
},
|
||||
msgType: {
|
||||
get: () => msgType,
|
||||
enumerable: true
|
||||
},
|
||||
type: {
|
||||
get: () => type,
|
||||
enumerable: true
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.Snapshot = Snapshot;
|
@ -0,0 +1,63 @@
|
||||
import { IResponseMessage } from '../typings/realtime';
|
||||
import { RealtimeListener } from './listener';
|
||||
import { IWSSendOptions } from './websocket-client';
|
||||
import { IWatchOptions } from '../typings/index';
|
||||
interface IVirtualWebSocketClientConstructorOptions extends IWatchOptions {
|
||||
envId?: string;
|
||||
collectionName: string;
|
||||
query: string;
|
||||
limit?: number;
|
||||
orderBy?: Record<string, string>;
|
||||
send: <T = any>(opts: IWSSendOptions) => Promise<T>;
|
||||
login: (envId?: string, refresh?: boolean) => Promise<any>;
|
||||
isWSConnected: () => boolean;
|
||||
onceWSConnected: () => Promise<void>;
|
||||
getWaitExpectedTimeoutLength: () => number;
|
||||
onWatchStart: (client: VirtualWebSocketClient, queryID: string) => void;
|
||||
onWatchClose: (client: VirtualWebSocketClient, queryID: string) => void;
|
||||
debug?: boolean;
|
||||
}
|
||||
export declare class VirtualWebSocketClient {
|
||||
watchId: string;
|
||||
private envId?;
|
||||
private collectionName;
|
||||
private query;
|
||||
private limit;
|
||||
private orderBy;
|
||||
private send;
|
||||
private login;
|
||||
private isWSConnected;
|
||||
private onceWSConnected;
|
||||
private getWaitExpectedTimeoutLength;
|
||||
private onWatchStart;
|
||||
private onWatchClose;
|
||||
private debug?;
|
||||
listener: RealtimeListener;
|
||||
private watchStatus;
|
||||
private _availableRetries;
|
||||
private _ackTimeoutId?;
|
||||
private _initWatchPromise?;
|
||||
private _rebuildWatchPromise?;
|
||||
private sessionInfo?;
|
||||
private _waitExpectedTimeoutId?;
|
||||
constructor(options: IVirtualWebSocketClientConstructorOptions);
|
||||
private _login;
|
||||
private initWatch;
|
||||
private rebuildWatch;
|
||||
private handleWatchEstablishmentError;
|
||||
private closeWatch;
|
||||
private scheduleSendACK;
|
||||
private clearACKSchedule;
|
||||
private sendACK;
|
||||
private handleCommonError;
|
||||
private useRetryTicket;
|
||||
private handleServerEvents;
|
||||
private _handleServerEvents;
|
||||
private _postHandleServerEventsValidityCheck;
|
||||
private clearWaitExpectedEvent;
|
||||
onMessage(msg: IResponseMessage): void;
|
||||
closeWithError(error: any): void;
|
||||
pause(): void;
|
||||
resume(): Promise<void>;
|
||||
}
|
||||
export {};
|
@ -0,0 +1,736 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const lodash_set_1 = require("lodash.set");
|
||||
const lodash_unset_1 = require("lodash.unset");
|
||||
const lodash_clonedeep_1 = require("lodash.clonedeep");
|
||||
const message_1 = require("./message");
|
||||
const error_1 = require("../utils/error");
|
||||
const error_config_1 = require("../config/error.config");
|
||||
const utils_1 = require("../utils/utils");
|
||||
const listener_1 = require("./listener");
|
||||
const snapshot_1 = require("./snapshot");
|
||||
const error_2 = require("./error");
|
||||
var WATCH_STATUS;
|
||||
(function (WATCH_STATUS) {
|
||||
WATCH_STATUS["LOGGINGIN"] = "LOGGINGIN";
|
||||
WATCH_STATUS["INITING"] = "INITING";
|
||||
WATCH_STATUS["REBUILDING"] = "REBUILDING";
|
||||
WATCH_STATUS["ACTIVE"] = "ACTIVE";
|
||||
WATCH_STATUS["ERRORED"] = "ERRORED";
|
||||
WATCH_STATUS["CLOSING"] = "CLOSING";
|
||||
WATCH_STATUS["CLOSED"] = "CLOSED";
|
||||
WATCH_STATUS["PAUSED"] = "PAUSED";
|
||||
WATCH_STATUS["RESUMING"] = "RESUMING";
|
||||
})(WATCH_STATUS || (WATCH_STATUS = {}));
|
||||
const DEFAULT_WAIT_TIME_ON_UNKNOWN_ERROR = 100;
|
||||
const DEFAULT_MAX_AUTO_RETRY_ON_ERROR = 2;
|
||||
const DEFAULT_MAX_SEND_ACK_AUTO_RETRY_ON_ERROR = 2;
|
||||
const DEFAULT_SEND_ACK_DEBOUNCE_TIMEOUT = 10 * 1000;
|
||||
const DEFAULT_INIT_WATCH_TIMEOUT = 10 * 1000;
|
||||
const DEFAULT_REBUILD_WATCH_TIMEOUT = 10 * 1000;
|
||||
class VirtualWebSocketClient {
|
||||
constructor(options) {
|
||||
this.watchStatus = WATCH_STATUS.INITING;
|
||||
this._login = async (envId, refresh) => {
|
||||
this.watchStatus = WATCH_STATUS.LOGGINGIN;
|
||||
const loginResult = await this.login(envId, refresh);
|
||||
if (!this.envId) {
|
||||
this.envId = loginResult.envId;
|
||||
}
|
||||
return loginResult;
|
||||
};
|
||||
this.initWatch = async (forceRefreshLogin) => {
|
||||
if (this._initWatchPromise) {
|
||||
return this._initWatchPromise;
|
||||
}
|
||||
this._initWatchPromise = new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
if (this.watchStatus === WATCH_STATUS.PAUSED) {
|
||||
console.log('[realtime] initWatch cancelled on pause');
|
||||
return resolve();
|
||||
}
|
||||
const { envId } = await this._login(this.envId, forceRefreshLogin);
|
||||
if (this.watchStatus === WATCH_STATUS.PAUSED) {
|
||||
console.log('[realtime] initWatch cancelled on pause');
|
||||
return resolve();
|
||||
}
|
||||
this.watchStatus = WATCH_STATUS.INITING;
|
||||
const initWatchMsg = {
|
||||
watchId: this.watchId,
|
||||
requestId: message_1.genRequestId(),
|
||||
msgType: 'INIT_WATCH',
|
||||
msgData: {
|
||||
envId,
|
||||
collName: this.collectionName,
|
||||
query: this.query,
|
||||
limit: this.limit,
|
||||
orderBy: this.orderBy
|
||||
}
|
||||
};
|
||||
const initEventMsg = await this.send({
|
||||
msg: initWatchMsg,
|
||||
waitResponse: true,
|
||||
skipOnMessage: true,
|
||||
timeout: DEFAULT_INIT_WATCH_TIMEOUT
|
||||
});
|
||||
const { events, currEvent } = initEventMsg.msgData;
|
||||
this.sessionInfo = {
|
||||
queryID: initEventMsg.msgData.queryID,
|
||||
currentEventId: currEvent - 1,
|
||||
currentDocs: []
|
||||
};
|
||||
if (events.length > 0) {
|
||||
for (const e of events) {
|
||||
e.ID = currEvent;
|
||||
}
|
||||
this.handleServerEvents(initEventMsg);
|
||||
}
|
||||
else {
|
||||
this.sessionInfo.currentEventId = currEvent;
|
||||
const snapshot = new snapshot_1.Snapshot({
|
||||
id: currEvent,
|
||||
docChanges: [],
|
||||
docs: [],
|
||||
type: 'init'
|
||||
});
|
||||
this.listener.onChange(snapshot);
|
||||
this.scheduleSendACK();
|
||||
}
|
||||
this.onWatchStart(this, this.sessionInfo.queryID);
|
||||
this.watchStatus = WATCH_STATUS.ACTIVE;
|
||||
this._availableRetries.INIT_WATCH = DEFAULT_MAX_AUTO_RETRY_ON_ERROR;
|
||||
resolve();
|
||||
}
|
||||
catch (e) {
|
||||
this.handleWatchEstablishmentError(e, {
|
||||
operationName: 'INIT_WATCH',
|
||||
resolve,
|
||||
reject
|
||||
});
|
||||
}
|
||||
});
|
||||
let success = false;
|
||||
try {
|
||||
await this._initWatchPromise;
|
||||
success = true;
|
||||
}
|
||||
finally {
|
||||
this._initWatchPromise = undefined;
|
||||
}
|
||||
console.log(`[realtime] initWatch ${success ? 'success' : 'fail'}`);
|
||||
};
|
||||
this.rebuildWatch = async (forceRefreshLogin) => {
|
||||
if (this._rebuildWatchPromise) {
|
||||
return this._rebuildWatchPromise;
|
||||
}
|
||||
this._rebuildWatchPromise = new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
if (this.watchStatus === WATCH_STATUS.PAUSED) {
|
||||
console.log('[realtime] rebuildWatch cancelled on pause');
|
||||
return resolve();
|
||||
}
|
||||
const { envId } = await this._login(this.envId, forceRefreshLogin);
|
||||
if (!this.sessionInfo) {
|
||||
throw new Error('can not rebuildWatch without a successful initWatch (lack of sessionInfo)');
|
||||
}
|
||||
if (this.watchStatus === WATCH_STATUS.PAUSED) {
|
||||
console.log('[realtime] rebuildWatch cancelled on pause');
|
||||
return resolve();
|
||||
}
|
||||
this.watchStatus = WATCH_STATUS.REBUILDING;
|
||||
const rebuildWatchMsg = {
|
||||
watchId: this.watchId,
|
||||
requestId: message_1.genRequestId(),
|
||||
msgType: 'REBUILD_WATCH',
|
||||
msgData: {
|
||||
envId,
|
||||
collName: this.collectionName,
|
||||
queryID: this.sessionInfo.queryID,
|
||||
eventID: this.sessionInfo.currentEventId
|
||||
}
|
||||
};
|
||||
const nextEventMsg = await this.send({
|
||||
msg: rebuildWatchMsg,
|
||||
waitResponse: true,
|
||||
skipOnMessage: false,
|
||||
timeout: DEFAULT_REBUILD_WATCH_TIMEOUT
|
||||
});
|
||||
this.handleServerEvents(nextEventMsg);
|
||||
this.watchStatus = WATCH_STATUS.ACTIVE;
|
||||
this._availableRetries.REBUILD_WATCH = DEFAULT_MAX_AUTO_RETRY_ON_ERROR;
|
||||
resolve();
|
||||
}
|
||||
catch (e) {
|
||||
this.handleWatchEstablishmentError(e, {
|
||||
operationName: 'REBUILD_WATCH',
|
||||
resolve,
|
||||
reject
|
||||
});
|
||||
}
|
||||
});
|
||||
let success = false;
|
||||
try {
|
||||
await this._rebuildWatchPromise;
|
||||
success = true;
|
||||
}
|
||||
finally {
|
||||
this._rebuildWatchPromise = undefined;
|
||||
}
|
||||
console.log(`[realtime] rebuildWatch ${success ? 'success' : 'fail'}`);
|
||||
};
|
||||
this.handleWatchEstablishmentError = async (e, options) => {
|
||||
const isInitWatch = options.operationName === 'INIT_WATCH';
|
||||
const abortWatch = () => {
|
||||
this.closeWithError(new error_1.CloudSDKError({
|
||||
errCode: isInitWatch
|
||||
? error_config_1.ERR_CODE.SDK_DATABASE_REALTIME_LISTENER_INIT_WATCH_FAIL
|
||||
: error_config_1.ERR_CODE.SDK_DATABASE_REALTIME_LISTENER_REBUILD_WATCH_FAIL,
|
||||
errMsg: e
|
||||
}));
|
||||
options.reject(e);
|
||||
};
|
||||
const retry = (refreshLogin) => {
|
||||
if (this.useRetryTicket(options.operationName)) {
|
||||
if (isInitWatch) {
|
||||
this._initWatchPromise = undefined;
|
||||
options.resolve(this.initWatch(refreshLogin));
|
||||
}
|
||||
else {
|
||||
this._rebuildWatchPromise = undefined;
|
||||
options.resolve(this.rebuildWatch(refreshLogin));
|
||||
}
|
||||
}
|
||||
else {
|
||||
abortWatch();
|
||||
}
|
||||
};
|
||||
this.handleCommonError(e, {
|
||||
onSignError: () => retry(true),
|
||||
onTimeoutError: () => retry(false),
|
||||
onNotRetryableError: abortWatch,
|
||||
onCancelledError: options.reject,
|
||||
onUnknownError: async () => {
|
||||
try {
|
||||
const onWSDisconnected = async () => {
|
||||
this.pause();
|
||||
await this.onceWSConnected();
|
||||
retry(true);
|
||||
};
|
||||
if (!this.isWSConnected()) {
|
||||
await onWSDisconnected();
|
||||
}
|
||||
else {
|
||||
await utils_1.sleep(DEFAULT_WAIT_TIME_ON_UNKNOWN_ERROR);
|
||||
if (this.watchStatus === WATCH_STATUS.PAUSED) {
|
||||
options.reject(new error_1.CancelledError(`${options.operationName} cancelled due to pause after unknownError`));
|
||||
}
|
||||
else if (!this.isWSConnected()) {
|
||||
await onWSDisconnected();
|
||||
}
|
||||
else {
|
||||
retry(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
retry(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
this.closeWatch = async () => {
|
||||
const queryId = this.sessionInfo ? this.sessionInfo.queryID : '';
|
||||
if (this.watchStatus !== WATCH_STATUS.ACTIVE) {
|
||||
this.watchStatus = WATCH_STATUS.CLOSED;
|
||||
this.onWatchClose(this, queryId);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
this.watchStatus = WATCH_STATUS.CLOSING;
|
||||
const closeWatchMsg = {
|
||||
watchId: this.watchId,
|
||||
requestId: message_1.genRequestId(),
|
||||
msgType: 'CLOSE_WATCH',
|
||||
msgData: null
|
||||
};
|
||||
await this.send({
|
||||
msg: closeWatchMsg
|
||||
});
|
||||
this.sessionInfo = undefined;
|
||||
this.watchStatus = WATCH_STATUS.CLOSED;
|
||||
}
|
||||
catch (e) {
|
||||
this.closeWithError(new error_1.CloudSDKError({
|
||||
errCode: error_config_1.ERR_CODE.SDK_DATABASE_REALTIME_LISTENER_CLOSE_WATCH_FAIL,
|
||||
errMsg: e
|
||||
}));
|
||||
}
|
||||
finally {
|
||||
this.onWatchClose(this, queryId);
|
||||
}
|
||||
};
|
||||
this.scheduleSendACK = () => {
|
||||
this.clearACKSchedule();
|
||||
this._ackTimeoutId = setTimeout(() => {
|
||||
if (this._waitExpectedTimeoutId) {
|
||||
this.scheduleSendACK();
|
||||
}
|
||||
else {
|
||||
this.sendACK();
|
||||
}
|
||||
}, DEFAULT_SEND_ACK_DEBOUNCE_TIMEOUT);
|
||||
};
|
||||
this.clearACKSchedule = () => {
|
||||
if (this._ackTimeoutId) {
|
||||
clearTimeout(this._ackTimeoutId);
|
||||
}
|
||||
};
|
||||
this.sendACK = async () => {
|
||||
try {
|
||||
if (this.watchStatus !== WATCH_STATUS.ACTIVE) {
|
||||
this.scheduleSendACK();
|
||||
return;
|
||||
}
|
||||
if (!this.sessionInfo) {
|
||||
console.warn('[realtime listener] can not send ack without a successful initWatch (lack of sessionInfo)');
|
||||
return;
|
||||
}
|
||||
const ackMsg = {
|
||||
watchId: this.watchId,
|
||||
requestId: message_1.genRequestId(),
|
||||
msgType: 'CHECK_LAST',
|
||||
msgData: {
|
||||
queryID: this.sessionInfo.queryID,
|
||||
eventID: this.sessionInfo.currentEventId
|
||||
}
|
||||
};
|
||||
await this.send({
|
||||
msg: ackMsg
|
||||
});
|
||||
this.scheduleSendACK();
|
||||
}
|
||||
catch (e) {
|
||||
if (error_2.isRealtimeErrorMessageError(e)) {
|
||||
const msg = e.payload;
|
||||
switch (msg.msgData.code) {
|
||||
case 'CHECK_LOGIN_FAILED':
|
||||
case 'SIGN_EXPIRED_ERROR':
|
||||
case 'SIGN_INVALID_ERROR':
|
||||
case 'SIGN_PARAM_INVALID': {
|
||||
this.rebuildWatch();
|
||||
return;
|
||||
}
|
||||
case 'QUERYID_INVALID_ERROR':
|
||||
case 'SYS_ERR':
|
||||
case 'INVALIID_ENV':
|
||||
case 'COLLECTION_PERMISSION_DENIED': {
|
||||
this.closeWithError(new error_1.CloudSDKError({
|
||||
errCode: error_config_1.ERR_CODE.SDK_DATABASE_REALTIME_LISTENER_CHECK_LAST_FAIL,
|
||||
errMsg: msg.msgData.code
|
||||
}));
|
||||
return;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this._availableRetries.CHECK_LAST &&
|
||||
this._availableRetries.CHECK_LAST > 0) {
|
||||
this._availableRetries.CHECK_LAST--;
|
||||
this.scheduleSendACK();
|
||||
}
|
||||
else {
|
||||
this.closeWithError(new error_1.CloudSDKError({
|
||||
errCode: error_config_1.ERR_CODE.SDK_DATABASE_REALTIME_LISTENER_CHECK_LAST_FAIL,
|
||||
errMsg: e
|
||||
}));
|
||||
}
|
||||
}
|
||||
};
|
||||
this.handleCommonError = (e, options) => {
|
||||
if (error_2.isRealtimeErrorMessageError(e)) {
|
||||
const msg = e.payload;
|
||||
switch (msg.msgData.code) {
|
||||
case 'CHECK_LOGIN_FAILED':
|
||||
case 'SIGN_EXPIRED_ERROR':
|
||||
case 'SIGN_INVALID_ERROR':
|
||||
case 'SIGN_PARAM_INVALID': {
|
||||
options.onSignError(e);
|
||||
return;
|
||||
}
|
||||
case 'QUERYID_INVALID_ERROR':
|
||||
case 'SYS_ERR':
|
||||
case 'INVALIID_ENV':
|
||||
case 'COLLECTION_PERMISSION_DENIED': {
|
||||
options.onNotRetryableError(e);
|
||||
return;
|
||||
}
|
||||
default: {
|
||||
options.onNotRetryableError(e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (error_1.isTimeoutError(e)) {
|
||||
options.onTimeoutError(e);
|
||||
return;
|
||||
}
|
||||
else if (error_1.isCancelledError(e)) {
|
||||
options.onCancelledError(e);
|
||||
return;
|
||||
}
|
||||
options.onUnknownError(e);
|
||||
};
|
||||
this.watchId = `watchid_${+new Date()}_${Math.random()}`;
|
||||
this.envId = options.envId;
|
||||
this.collectionName = options.collectionName;
|
||||
this.query = options.query;
|
||||
this.limit = options.limit;
|
||||
this.orderBy = options.orderBy;
|
||||
this.send = options.send;
|
||||
this.login = options.login;
|
||||
this.isWSConnected = options.isWSConnected;
|
||||
this.onceWSConnected = options.onceWSConnected;
|
||||
this.getWaitExpectedTimeoutLength = options.getWaitExpectedTimeoutLength;
|
||||
this.onWatchStart = options.onWatchStart;
|
||||
this.onWatchClose = options.onWatchClose;
|
||||
this.debug = options.debug;
|
||||
this._availableRetries = {
|
||||
INIT_WATCH: DEFAULT_MAX_AUTO_RETRY_ON_ERROR,
|
||||
REBUILD_WATCH: DEFAULT_MAX_AUTO_RETRY_ON_ERROR,
|
||||
CHECK_LAST: DEFAULT_MAX_SEND_ACK_AUTO_RETRY_ON_ERROR
|
||||
};
|
||||
this.listener = new listener_1.RealtimeListener({
|
||||
close: this.closeWatch,
|
||||
onChange: options.onChange,
|
||||
onError: options.onError,
|
||||
debug: this.debug,
|
||||
virtualClient: this
|
||||
});
|
||||
this.initWatch();
|
||||
}
|
||||
useRetryTicket(operationName) {
|
||||
if (this._availableRetries[operationName] &&
|
||||
this._availableRetries[operationName] > 0) {
|
||||
this._availableRetries[operationName]--;
|
||||
console.log(`[realtime] ${operationName} use a retry ticket, now only ${this._availableRetries[operationName]} retry left`);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
async handleServerEvents(msg) {
|
||||
try {
|
||||
this.scheduleSendACK();
|
||||
await this._handleServerEvents(msg);
|
||||
this._postHandleServerEventsValidityCheck(msg);
|
||||
}
|
||||
catch (e) {
|
||||
console.error('[realtime listener] internal non-fatal error: handle server events failed with error: ', e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
async _handleServerEvents(msg) {
|
||||
const { requestId } = msg;
|
||||
const { events } = msg.msgData;
|
||||
const { msgType } = msg;
|
||||
if (!events.length || !this.sessionInfo) {
|
||||
return;
|
||||
}
|
||||
const sessionInfo = this.sessionInfo;
|
||||
let allChangeEvents;
|
||||
try {
|
||||
allChangeEvents = events.map(getPublicEvent);
|
||||
}
|
||||
catch (e) {
|
||||
this.closeWithError(new error_1.CloudSDKError({
|
||||
errCode: error_config_1.ERR_CODE.SDK_DATABASE_REALTIME_LISTENER_RECEIVE_INVALID_SERVER_DATA,
|
||||
errMsg: e
|
||||
}));
|
||||
return;
|
||||
}
|
||||
let docs = [...sessionInfo.currentDocs];
|
||||
let initEncountered = false;
|
||||
for (let i = 0, len = allChangeEvents.length; i < len; i++) {
|
||||
const change = allChangeEvents[i];
|
||||
if (sessionInfo.currentEventId >= change.id) {
|
||||
if (!allChangeEvents[i - 1] || change.id > allChangeEvents[i - 1].id) {
|
||||
console.warn(`[realtime] duplicate event received, cur ${sessionInfo.currentEventId} but got ${change.id}`);
|
||||
}
|
||||
else {
|
||||
console.error(`[realtime listener] server non-fatal error: events out of order (the latter event's id is smaller than that of the former) (requestId ${requestId})`);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else if (sessionInfo.currentEventId === change.id - 1) {
|
||||
switch (change.dataType) {
|
||||
case 'update': {
|
||||
if (!change.doc) {
|
||||
switch (change.queueType) {
|
||||
case 'update':
|
||||
case 'dequeue': {
|
||||
const localDoc = docs.find(doc => doc._id === change.docId);
|
||||
if (localDoc) {
|
||||
const doc = lodash_clonedeep_1.default(localDoc);
|
||||
if (change.updatedFields) {
|
||||
for (const fieldPath in change.updatedFields) {
|
||||
lodash_set_1.default(doc, fieldPath, change.updatedFields[fieldPath]);
|
||||
}
|
||||
}
|
||||
if (change.removedFields) {
|
||||
for (const fieldPath of change.removedFields) {
|
||||
lodash_unset_1.default(doc, fieldPath);
|
||||
}
|
||||
}
|
||||
change.doc = doc;
|
||||
}
|
||||
else {
|
||||
console.error('[realtime listener] internal non-fatal server error: unexpected update dataType event where no doc is associated.');
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'enqueue': {
|
||||
const err = new error_1.CloudSDKError({
|
||||
errCode: error_config_1.ERR_CODE.SDK_DATABASE_REALTIME_LISTENER_UNEXPECTED_FATAL_ERROR,
|
||||
errMsg: `HandleServerEvents: full doc is not provided with dataType="update" and queueType="enqueue" (requestId ${msg.requestId})`
|
||||
});
|
||||
this.closeWithError(err);
|
||||
throw err;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'replace': {
|
||||
if (!change.doc) {
|
||||
const err = new error_1.CloudSDKError({
|
||||
errCode: error_config_1.ERR_CODE.SDK_DATABASE_REALTIME_LISTENER_UNEXPECTED_FATAL_ERROR,
|
||||
errMsg: `HandleServerEvents: full doc is not provided with dataType="replace" (requestId ${msg.requestId})`
|
||||
});
|
||||
this.closeWithError(err);
|
||||
throw err;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'remove': {
|
||||
const doc = docs.find(doc => doc._id === change.docId);
|
||||
if (doc) {
|
||||
change.doc = doc;
|
||||
}
|
||||
else {
|
||||
console.error('[realtime listener] internal non-fatal server error: unexpected remove event where no doc is associated.');
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'limit': {
|
||||
if (!change.doc) {
|
||||
switch (change.queueType) {
|
||||
case 'dequeue': {
|
||||
const doc = docs.find(doc => doc._id === change.docId);
|
||||
if (doc) {
|
||||
change.doc = doc;
|
||||
}
|
||||
else {
|
||||
console.error('[realtime listener] internal non-fatal server error: unexpected limit dataType event where no doc is associated.');
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'enqueue': {
|
||||
const err = new error_1.CloudSDKError({
|
||||
errCode: error_config_1.ERR_CODE.SDK_DATABASE_REALTIME_LISTENER_UNEXPECTED_FATAL_ERROR,
|
||||
errMsg: `HandleServerEvents: full doc is not provided with dataType="limit" and queueType="enqueue" (requestId ${msg.requestId})`
|
||||
});
|
||||
this.closeWithError(err);
|
||||
throw err;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
switch (change.queueType) {
|
||||
case 'init': {
|
||||
if (!initEncountered) {
|
||||
initEncountered = true;
|
||||
docs = [change.doc];
|
||||
}
|
||||
else {
|
||||
docs.push(change.doc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'enqueue': {
|
||||
docs.push(change.doc);
|
||||
break;
|
||||
}
|
||||
case 'dequeue': {
|
||||
const ind = docs.findIndex(doc => doc._id === change.docId);
|
||||
if (ind > -1) {
|
||||
docs.splice(ind, 1);
|
||||
}
|
||||
else {
|
||||
console.error('[realtime listener] internal non-fatal server error: unexpected dequeue event where no doc is associated.');
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'update': {
|
||||
const ind = docs.findIndex(doc => doc._id === change.docId);
|
||||
if (ind > -1) {
|
||||
docs[ind] = change.doc;
|
||||
}
|
||||
else {
|
||||
console.error('[realtime listener] internal non-fatal server error: unexpected queueType update event where no doc is associated.');
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i === len - 1 ||
|
||||
(allChangeEvents[i + 1] && allChangeEvents[i + 1].id !== change.id)) {
|
||||
const docsSnapshot = [...docs];
|
||||
const docChanges = allChangeEvents
|
||||
.slice(0, i + 1)
|
||||
.filter(c => c.id === change.id);
|
||||
this.sessionInfo.currentEventId = change.id;
|
||||
this.sessionInfo.currentDocs = docs;
|
||||
const snapshot = new snapshot_1.Snapshot({
|
||||
id: change.id,
|
||||
docChanges,
|
||||
docs: docsSnapshot,
|
||||
msgType
|
||||
});
|
||||
this.listener.onChange(snapshot);
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.warn(`[realtime listener] event received is out of order, cur ${this.sessionInfo.currentEventId} but got ${change.id}`);
|
||||
await this.rebuildWatch();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
_postHandleServerEventsValidityCheck(msg) {
|
||||
if (!this.sessionInfo) {
|
||||
console.error('[realtime listener] internal non-fatal error: sessionInfo lost after server event handling, this should never occur');
|
||||
return;
|
||||
}
|
||||
if (this.sessionInfo.expectEventId &&
|
||||
this.sessionInfo.currentEventId >= this.sessionInfo.expectEventId) {
|
||||
this.clearWaitExpectedEvent();
|
||||
}
|
||||
if (this.sessionInfo.currentEventId < msg.msgData.currEvent) {
|
||||
console.warn('[realtime listener] internal non-fatal error: client eventId does not match with server event id after server event handling');
|
||||
return;
|
||||
}
|
||||
}
|
||||
clearWaitExpectedEvent() {
|
||||
if (this._waitExpectedTimeoutId) {
|
||||
clearTimeout(this._waitExpectedTimeoutId);
|
||||
this._waitExpectedTimeoutId = undefined;
|
||||
}
|
||||
}
|
||||
onMessage(msg) {
|
||||
switch (this.watchStatus) {
|
||||
case WATCH_STATUS.PAUSED: {
|
||||
if (msg.msgType !== 'ERROR') {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WATCH_STATUS.LOGGINGIN:
|
||||
case WATCH_STATUS.INITING:
|
||||
case WATCH_STATUS.REBUILDING: {
|
||||
console.warn(`[realtime listener] internal non-fatal error: unexpected message received while ${this.watchStatus}`);
|
||||
return;
|
||||
}
|
||||
case WATCH_STATUS.CLOSED: {
|
||||
console.warn('[realtime listener] internal non-fatal error: unexpected message received when the watch has closed');
|
||||
return;
|
||||
}
|
||||
case WATCH_STATUS.ERRORED: {
|
||||
console.warn('[realtime listener] internal non-fatal error: unexpected message received when the watch has ended with error');
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!this.sessionInfo) {
|
||||
console.warn('[realtime listener] internal non-fatal error: sessionInfo not found while message is received.');
|
||||
return;
|
||||
}
|
||||
this.scheduleSendACK();
|
||||
switch (msg.msgType) {
|
||||
case 'NEXT_EVENT': {
|
||||
console.warn(`nextevent ${msg.msgData.currEvent} ignored`, msg);
|
||||
this.handleServerEvents(msg);
|
||||
break;
|
||||
}
|
||||
case 'CHECK_EVENT': {
|
||||
if (this.sessionInfo.currentEventId < msg.msgData.currEvent) {
|
||||
this.sessionInfo.expectEventId = msg.msgData.currEvent;
|
||||
this.clearWaitExpectedEvent();
|
||||
this._waitExpectedTimeoutId = setTimeout(() => {
|
||||
this.rebuildWatch();
|
||||
}, this.getWaitExpectedTimeoutLength());
|
||||
console.log(`[realtime] waitExpectedTimeoutLength ${this.getWaitExpectedTimeoutLength()}`);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'ERROR': {
|
||||
this.closeWithError(new error_1.CloudSDKError({
|
||||
errCode: error_config_1.ERR_CODE.SDK_DATABASE_REALTIME_LISTENER_SERVER_ERROR_MSG,
|
||||
errMsg: `${msg.msgData.code} - ${msg.msgData.message}`
|
||||
}));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
console.warn(`[realtime listener] virtual client receive unexpected msg ${msg.msgType}: `, msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
closeWithError(error) {
|
||||
this.watchStatus = WATCH_STATUS.ERRORED;
|
||||
this.clearACKSchedule();
|
||||
this.listener.onError(error);
|
||||
this.onWatchClose(this, (this.sessionInfo && this.sessionInfo.queryID) || '');
|
||||
console.log(`[realtime] client closed (${this.collectionName} ${this.query}) (watchId ${this.watchId})`);
|
||||
}
|
||||
pause() {
|
||||
this.watchStatus = WATCH_STATUS.PAUSED;
|
||||
console.log(`[realtime] client paused (${this.collectionName} ${this.query}) (watchId ${this.watchId})`);
|
||||
}
|
||||
async resume() {
|
||||
this.watchStatus = WATCH_STATUS.RESUMING;
|
||||
console.log(`[realtime] client resuming with ${this.sessionInfo ? 'REBUILD_WATCH' : 'INIT_WATCH'} (${this.collectionName} ${this.query}) (${this.watchId})`);
|
||||
try {
|
||||
await (this.sessionInfo ? this.rebuildWatch() : this.initWatch());
|
||||
console.log(`[realtime] client successfully resumed (${this.collectionName} ${this.query}) (${this.watchId})`);
|
||||
}
|
||||
catch (e) {
|
||||
console.error(`[realtime] client resume failed (${this.collectionName} ${this.query}) (${this.watchId})`, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.VirtualWebSocketClient = VirtualWebSocketClient;
|
||||
function getPublicEvent(event) {
|
||||
const e = {
|
||||
id: event.ID,
|
||||
dataType: event.DataType,
|
||||
queueType: event.QueueType,
|
||||
docId: event.DocID,
|
||||
doc: event.Doc && event.Doc !== '{}' ? JSON.parse(event.Doc) : undefined
|
||||
};
|
||||
if (event.DataType === 'update') {
|
||||
if (event.UpdatedFields) {
|
||||
e.updatedFields = JSON.parse(event.UpdatedFields);
|
||||
}
|
||||
if (event.removedFields || event.RemovedFields) {
|
||||
e.removedFields = JSON.parse(event.removedFields);
|
||||
}
|
||||
}
|
||||
return e;
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
import { VirtualWebSocketClient } from './virtual-websocket-client';
|
||||
import { IDatabaseServiceContext, IWatchOptions, DBRealtimeListener } from '../typings/index';
|
||||
import { IRequestMessage } from '../typings/realtime';
|
||||
import { CLOSE_EVENT_CODE } from './ws-event';
|
||||
export interface IRealtimeWebSocketClientConstructorOptions {
|
||||
maxReconnect?: number;
|
||||
reconnectInterval?: number;
|
||||
context: IDatabaseServiceContext;
|
||||
}
|
||||
export interface ISignature {
|
||||
envId: string;
|
||||
secretVersion: number;
|
||||
signStr: string;
|
||||
wsUrl: string;
|
||||
expireTS: number;
|
||||
}
|
||||
export interface ILoginInfo {
|
||||
loggedIn: boolean;
|
||||
loggingInPromise?: Promise<ILoginResult>;
|
||||
loginStartTS?: number;
|
||||
loginResult?: ILoginResult;
|
||||
}
|
||||
export interface ILoginResult {
|
||||
envId: string;
|
||||
}
|
||||
export interface IWSSendOptions {
|
||||
msg: IRequestMessage;
|
||||
waitResponse?: boolean;
|
||||
skipOnMessage?: boolean;
|
||||
timeout?: number;
|
||||
}
|
||||
export interface IWSWatchOptions extends IWatchOptions {
|
||||
envId?: string;
|
||||
collectionName: string;
|
||||
query: string;
|
||||
limit?: number;
|
||||
orderBy?: Record<string, string>;
|
||||
}
|
||||
export declare class RealtimeWebSocketClient {
|
||||
private _virtualWSClient;
|
||||
private _queryIdClientMap;
|
||||
private _watchIdClientMap;
|
||||
private _maxReconnect;
|
||||
private _reconnectInterval;
|
||||
private _context;
|
||||
private _ws?;
|
||||
private _lastPingSendTS?;
|
||||
private _pingFailed;
|
||||
private _pongMissed;
|
||||
private _pingTimeoutId?;
|
||||
private _pongTimeoutId?;
|
||||
private _logins;
|
||||
private _wsInitPromise?;
|
||||
private _wsReadySubsribers;
|
||||
private _wsResponseWait;
|
||||
private _rttObserved;
|
||||
private _reconnectState;
|
||||
private _wsSign;
|
||||
constructor(options: IRealtimeWebSocketClientConstructorOptions);
|
||||
private initWebSocketConnection;
|
||||
private initWebSocketEvent;
|
||||
private isWSConnected;
|
||||
private onceWSConnected;
|
||||
private webLogin;
|
||||
private getWsSign;
|
||||
private getWaitExpectedTimeoutLength;
|
||||
private heartbeat;
|
||||
clearHeartbeat(): void;
|
||||
private ping;
|
||||
send: <T = any>(opts: IWSSendOptions) => Promise<T>;
|
||||
close(code: CLOSE_EVENT_CODE): void;
|
||||
closeAllClients: (error: any) => void;
|
||||
pauseClients: (clients?: Set<VirtualWebSocketClient>) => void;
|
||||
resumeClients: (clients?: Set<VirtualWebSocketClient>) => void;
|
||||
private onWatchStart;
|
||||
private onWatchClose;
|
||||
watch(options: IWSWatchOptions): DBRealtimeListener;
|
||||
}
|
@ -0,0 +1,567 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const virtual_websocket_client_1 = require("./virtual-websocket-client");
|
||||
const utils_1 = require("../utils/utils");
|
||||
const message_1 = require("./message");
|
||||
const ws_event_1 = require("./ws-event");
|
||||
const error_1 = require("../utils/error");
|
||||
const error_2 = require("./error");
|
||||
const error_config_1 = require("../config/error.config");
|
||||
const __1 = require("../");
|
||||
const WS_READY_STATE = {
|
||||
CONNECTING: 0,
|
||||
OPEN: 1,
|
||||
CLOSING: 2,
|
||||
CLOSED: 3
|
||||
};
|
||||
const MAX_RTT_OBSERVED = 3;
|
||||
const DEFAULT_EXPECTED_EVENT_WAIT_TIME = 5000;
|
||||
const DEFAULT_UNTRUSTED_RTT_THRESHOLD = 10000;
|
||||
const DEFAULT_MAX_RECONNECT = 5;
|
||||
const DEFAULT_WS_RECONNECT_INTERVAL = 10000;
|
||||
const DEFAULT_PING_FAIL_TOLERANCE = 2;
|
||||
const DEFAULT_PONG_MISS_TOLERANCE = 2;
|
||||
const DEFAULT_LOGIN_TIMEOUT = 5000;
|
||||
class RealtimeWebSocketClient {
|
||||
constructor(options) {
|
||||
this._virtualWSClient = new Set();
|
||||
this._queryIdClientMap = new Map();
|
||||
this._watchIdClientMap = new Map();
|
||||
this._pingFailed = 0;
|
||||
this._pongMissed = 0;
|
||||
this._logins = new Map();
|
||||
this._wsReadySubsribers = [];
|
||||
this._wsResponseWait = new Map();
|
||||
this._rttObserved = [];
|
||||
this.initWebSocketConnection = async (reconnect, availableRetries = this._maxReconnect) => {
|
||||
if (reconnect && this._reconnectState) {
|
||||
return;
|
||||
}
|
||||
if (reconnect) {
|
||||
this._reconnectState = true;
|
||||
}
|
||||
if (this._wsInitPromise) {
|
||||
return this._wsInitPromise;
|
||||
}
|
||||
if (reconnect) {
|
||||
this.pauseClients();
|
||||
}
|
||||
this.close(ws_event_1.CLOSE_EVENT_CODE.ReconnectWebSocket);
|
||||
this._wsInitPromise = new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
const wsSign = await this.getWsSign();
|
||||
await new Promise(success => {
|
||||
const url = wsSign.wsUrl || 'wss://tcb-ws.tencentcloudapi.com';
|
||||
this._ws = __1.Db.wsClass ? new __1.Db.wsClass(url) : new WebSocket(url);
|
||||
success();
|
||||
});
|
||||
if (this._ws.connect) {
|
||||
await this._ws.connect();
|
||||
}
|
||||
await this.initWebSocketEvent();
|
||||
resolve();
|
||||
if (reconnect) {
|
||||
this.resumeClients();
|
||||
this._reconnectState = false;
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
console.error('[realtime] initWebSocketConnection connect fail', e);
|
||||
if (availableRetries > 0) {
|
||||
const isConnected = true;
|
||||
this._wsInitPromise = undefined;
|
||||
if (isConnected) {
|
||||
await utils_1.sleep(this._reconnectInterval);
|
||||
if (reconnect) {
|
||||
this._reconnectState = false;
|
||||
}
|
||||
}
|
||||
resolve(this.initWebSocketConnection(reconnect, availableRetries - 1));
|
||||
}
|
||||
else {
|
||||
reject(e);
|
||||
if (reconnect) {
|
||||
this.closeAllClients(new error_1.CloudSDKError({
|
||||
errCode: error_config_1.ERR_CODE.SDK_DATABASE_REALTIME_LISTENER_RECONNECT_WATCH_FAIL,
|
||||
errMsg: e
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
try {
|
||||
await this._wsInitPromise;
|
||||
this._wsReadySubsribers.forEach(({ resolve }) => resolve());
|
||||
}
|
||||
catch (e) {
|
||||
this._wsReadySubsribers.forEach(({ reject }) => reject());
|
||||
}
|
||||
finally {
|
||||
this._wsInitPromise = undefined;
|
||||
this._wsReadySubsribers = [];
|
||||
}
|
||||
};
|
||||
this.initWebSocketEvent = () => new Promise((resolve, reject) => {
|
||||
if (!this._ws) {
|
||||
throw new Error('can not initWebSocketEvent, ws not exists');
|
||||
}
|
||||
let wsOpened = false;
|
||||
this._ws.onopen = event => {
|
||||
console.warn('[realtime] ws event: open', event);
|
||||
wsOpened = true;
|
||||
resolve();
|
||||
};
|
||||
this._ws.onerror = event => {
|
||||
this._logins = new Map();
|
||||
if (!wsOpened) {
|
||||
console.error('[realtime] ws open failed with ws event: error', event);
|
||||
reject(event);
|
||||
}
|
||||
else {
|
||||
console.error('[realtime] ws event: error', event);
|
||||
this.clearHeartbeat();
|
||||
this._virtualWSClient.forEach(client => client.closeWithError(new error_1.CloudSDKError({
|
||||
errCode: error_config_1.ERR_CODE.SDK_DATABASE_REALTIME_LISTENER_WEBSOCKET_CONNECTION_ERROR,
|
||||
errMsg: event
|
||||
})));
|
||||
}
|
||||
};
|
||||
this._ws.onclose = closeEvent => {
|
||||
console.warn('[realtime] ws event: close', closeEvent);
|
||||
this._logins = new Map();
|
||||
this.clearHeartbeat();
|
||||
switch (closeEvent.code) {
|
||||
case ws_event_1.CLOSE_EVENT_CODE.ReconnectWebSocket: {
|
||||
break;
|
||||
}
|
||||
case ws_event_1.CLOSE_EVENT_CODE.NoRealtimeListeners: {
|
||||
break;
|
||||
}
|
||||
case ws_event_1.CLOSE_EVENT_CODE.HeartbeatPingError:
|
||||
case ws_event_1.CLOSE_EVENT_CODE.HeartbeatPongTimeoutError:
|
||||
case ws_event_1.CLOSE_EVENT_CODE.NormalClosure:
|
||||
case ws_event_1.CLOSE_EVENT_CODE.AbnormalClosure: {
|
||||
if (this._maxReconnect > 0) {
|
||||
this.initWebSocketConnection(true, this._maxReconnect);
|
||||
}
|
||||
else {
|
||||
this.closeAllClients(ws_event_1.getWSCloseError(closeEvent.code));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ws_event_1.CLOSE_EVENT_CODE.NoAuthentication: {
|
||||
this.closeAllClients(ws_event_1.getWSCloseError(closeEvent.code, closeEvent.reason));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
if (this._maxReconnect > 0) {
|
||||
this.initWebSocketConnection(true, this._maxReconnect);
|
||||
}
|
||||
else {
|
||||
this.closeAllClients(ws_event_1.getWSCloseError(closeEvent.code));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
this._ws.onmessage = res => {
|
||||
const rawMsg = res.data;
|
||||
this.heartbeat();
|
||||
let msg;
|
||||
try {
|
||||
msg = JSON.parse(rawMsg);
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error(`[realtime] onMessage parse res.data error: ${e}`);
|
||||
}
|
||||
if (msg.msgType === 'ERROR') {
|
||||
let virtualWatch = null;
|
||||
this._virtualWSClient.forEach(item => {
|
||||
if (item.watchId === msg.watchId) {
|
||||
virtualWatch = item;
|
||||
}
|
||||
});
|
||||
if (virtualWatch) {
|
||||
virtualWatch.listener.onError(msg);
|
||||
}
|
||||
}
|
||||
const responseWaitSpec = this._wsResponseWait.get(msg.requestId);
|
||||
if (responseWaitSpec) {
|
||||
try {
|
||||
if (msg.msgType === 'ERROR') {
|
||||
responseWaitSpec.reject(new error_2.RealtimeErrorMessageError(msg));
|
||||
}
|
||||
else {
|
||||
responseWaitSpec.resolve(msg);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
console.error('ws onMessage responseWaitSpec.resolve(msg) errored:', e);
|
||||
}
|
||||
finally {
|
||||
this._wsResponseWait.delete(msg.requestId);
|
||||
}
|
||||
if (responseWaitSpec.skipOnMessage) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (msg.msgType === 'PONG') {
|
||||
if (this._lastPingSendTS) {
|
||||
const rtt = Date.now() - this._lastPingSendTS;
|
||||
if (rtt > DEFAULT_UNTRUSTED_RTT_THRESHOLD) {
|
||||
console.warn(`[realtime] untrusted rtt observed: ${rtt}`);
|
||||
return;
|
||||
}
|
||||
if (this._rttObserved.length >= MAX_RTT_OBSERVED) {
|
||||
this._rttObserved.splice(0, this._rttObserved.length - MAX_RTT_OBSERVED + 1);
|
||||
}
|
||||
this._rttObserved.push(rtt);
|
||||
}
|
||||
return;
|
||||
}
|
||||
let client = msg.watchId && this._watchIdClientMap.get(msg.watchId);
|
||||
if (client) {
|
||||
client.onMessage(msg);
|
||||
}
|
||||
else {
|
||||
console.error(`[realtime] no realtime listener found responsible for watchId ${msg.watchId}: `, msg);
|
||||
switch (msg.msgType) {
|
||||
case 'INIT_EVENT':
|
||||
case 'NEXT_EVENT':
|
||||
case 'CHECK_EVENT': {
|
||||
client = this._queryIdClientMap.get(msg.msgData.queryID);
|
||||
if (client) {
|
||||
client.onMessage(msg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
for (const [, client] of this._watchIdClientMap) {
|
||||
client.onMessage(msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
this.heartbeat();
|
||||
});
|
||||
this.isWSConnected = () => {
|
||||
return Boolean(this._ws && this._ws.readyState === WS_READY_STATE.OPEN);
|
||||
};
|
||||
this.onceWSConnected = async () => {
|
||||
if (this.isWSConnected()) {
|
||||
return;
|
||||
}
|
||||
if (this._wsInitPromise) {
|
||||
return this._wsInitPromise;
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
this._wsReadySubsribers.push({
|
||||
resolve,
|
||||
reject
|
||||
});
|
||||
});
|
||||
};
|
||||
this.webLogin = async (envId, refresh) => {
|
||||
if (!refresh) {
|
||||
if (envId) {
|
||||
const loginInfo = this._logins.get(envId);
|
||||
if (loginInfo) {
|
||||
if (loginInfo.loggedIn && loginInfo.loginResult) {
|
||||
return loginInfo.loginResult;
|
||||
}
|
||||
else if (loginInfo.loggingInPromise) {
|
||||
return loginInfo.loggingInPromise;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
const emptyEnvLoginInfo = this._logins.get('');
|
||||
if (emptyEnvLoginInfo && emptyEnvLoginInfo.loggingInPromise) {
|
||||
return emptyEnvLoginInfo.loggingInPromise;
|
||||
}
|
||||
}
|
||||
}
|
||||
const promise = new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
const wsSign = await this.getWsSign();
|
||||
const msgData = {
|
||||
envId: wsSign.envId || '',
|
||||
accessToken: '',
|
||||
referrer: 'web',
|
||||
sdkVersion: '',
|
||||
dataVersion: __1.Db.dataVersion || ''
|
||||
};
|
||||
const loginMsg = {
|
||||
watchId: undefined,
|
||||
requestId: message_1.genRequestId(),
|
||||
msgType: 'LOGIN',
|
||||
msgData,
|
||||
exMsgData: {
|
||||
runtime: __1.Db.runtime,
|
||||
signStr: wsSign.signStr,
|
||||
secretVersion: wsSign.secretVersion
|
||||
}
|
||||
};
|
||||
const loginResMsg = await this.send({
|
||||
msg: loginMsg,
|
||||
waitResponse: true,
|
||||
skipOnMessage: true,
|
||||
timeout: DEFAULT_LOGIN_TIMEOUT
|
||||
});
|
||||
if (!loginResMsg.msgData.code) {
|
||||
resolve({
|
||||
envId: wsSign.envId
|
||||
});
|
||||
}
|
||||
else {
|
||||
reject(new Error(`${loginResMsg.msgData.code} ${loginResMsg.msgData.message}`));
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
});
|
||||
let loginInfo = envId && this._logins.get(envId);
|
||||
const loginStartTS = Date.now();
|
||||
if (loginInfo) {
|
||||
loginInfo.loggedIn = false;
|
||||
loginInfo.loggingInPromise = promise;
|
||||
loginInfo.loginStartTS = loginStartTS;
|
||||
}
|
||||
else {
|
||||
loginInfo = {
|
||||
loggedIn: false,
|
||||
loggingInPromise: promise,
|
||||
loginStartTS
|
||||
};
|
||||
this._logins.set(envId || '', loginInfo);
|
||||
}
|
||||
try {
|
||||
const loginResult = await promise;
|
||||
const curLoginInfo = envId && this._logins.get(envId);
|
||||
if (curLoginInfo &&
|
||||
curLoginInfo === loginInfo &&
|
||||
curLoginInfo.loginStartTS === loginStartTS) {
|
||||
loginInfo.loggedIn = true;
|
||||
loginInfo.loggingInPromise = undefined;
|
||||
loginInfo.loginStartTS = undefined;
|
||||
loginInfo.loginResult = loginResult;
|
||||
return loginResult;
|
||||
}
|
||||
else if (curLoginInfo) {
|
||||
if (curLoginInfo.loggedIn && curLoginInfo.loginResult) {
|
||||
return curLoginInfo.loginResult;
|
||||
}
|
||||
else if (curLoginInfo.loggingInPromise) {
|
||||
return curLoginInfo.loggingInPromise;
|
||||
}
|
||||
else {
|
||||
throw new Error('ws unexpected login info');
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new Error('ws login info reset');
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
loginInfo.loggedIn = false;
|
||||
loginInfo.loggingInPromise = undefined;
|
||||
loginInfo.loginStartTS = undefined;
|
||||
loginInfo.loginResult = undefined;
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
this.getWsSign = async () => {
|
||||
if (this._wsSign && this._wsSign.expiredTs > Date.now()) {
|
||||
return this._wsSign;
|
||||
}
|
||||
const expiredTs = Date.now() + 60000;
|
||||
const res = await this._context.appConfig.request.send('auth.wsWebSign', { runtime: __1.Db.runtime });
|
||||
if (res.code) {
|
||||
throw new Error(`[tcb-js-sdk] 获取实时数据推送登录票据失败: ${res.code}`);
|
||||
}
|
||||
if (res.data) {
|
||||
const { signStr, wsUrl, secretVersion, envId } = res.data;
|
||||
return {
|
||||
signStr,
|
||||
wsUrl,
|
||||
secretVersion,
|
||||
envId,
|
||||
expiredTs
|
||||
};
|
||||
}
|
||||
else {
|
||||
throw new Error('[tcb-js-sdk] 获取实时数据推送登录票据失败');
|
||||
}
|
||||
};
|
||||
this.getWaitExpectedTimeoutLength = () => {
|
||||
if (!this._rttObserved.length) {
|
||||
return DEFAULT_EXPECTED_EVENT_WAIT_TIME;
|
||||
}
|
||||
return ((this._rttObserved.reduce((acc, cur) => acc + cur) /
|
||||
this._rttObserved.length) *
|
||||
1.5);
|
||||
};
|
||||
this.ping = async () => {
|
||||
const msg = {
|
||||
watchId: undefined,
|
||||
requestId: message_1.genRequestId(),
|
||||
msgType: 'PING',
|
||||
msgData: null
|
||||
};
|
||||
await this.send({
|
||||
msg
|
||||
});
|
||||
};
|
||||
this.send = async (opts) => new Promise(async (_resolve, _reject) => {
|
||||
let timeoutId;
|
||||
let _hasResolved = false;
|
||||
let _hasRejected = false;
|
||||
const resolve = (value) => {
|
||||
_hasResolved = true;
|
||||
timeoutId && clearTimeout(timeoutId);
|
||||
_resolve(value);
|
||||
};
|
||||
const reject = (error) => {
|
||||
_hasRejected = true;
|
||||
timeoutId && clearTimeout(timeoutId);
|
||||
_reject(error);
|
||||
};
|
||||
if (opts.timeout) {
|
||||
timeoutId = setTimeout(async () => {
|
||||
if (!_hasResolved || !_hasRejected) {
|
||||
await utils_1.sleep(0);
|
||||
if (!_hasResolved || !_hasRejected) {
|
||||
reject(new error_1.TimeoutError('wsclient.send timedout'));
|
||||
}
|
||||
}
|
||||
}, opts.timeout);
|
||||
}
|
||||
try {
|
||||
if (this._wsInitPromise) {
|
||||
await this._wsInitPromise;
|
||||
}
|
||||
if (!this._ws) {
|
||||
reject(new Error('invalid state: ws connection not exists, can not send message'));
|
||||
return;
|
||||
}
|
||||
if (this._ws.readyState !== WS_READY_STATE.OPEN) {
|
||||
reject(new Error(`ws readyState invalid: ${this._ws.readyState}, can not send message`));
|
||||
return;
|
||||
}
|
||||
if (opts.waitResponse) {
|
||||
this._wsResponseWait.set(opts.msg.requestId, {
|
||||
resolve,
|
||||
reject,
|
||||
skipOnMessage: opts.skipOnMessage
|
||||
});
|
||||
}
|
||||
try {
|
||||
await this._ws.send(JSON.stringify(opts.msg));
|
||||
if (!opts.waitResponse) {
|
||||
resolve();
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
if (opts.waitResponse) {
|
||||
this._wsResponseWait.delete(opts.msg.requestId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
});
|
||||
this.closeAllClients = (error) => {
|
||||
this._virtualWSClient.forEach(client => {
|
||||
client.closeWithError(error);
|
||||
});
|
||||
};
|
||||
this.pauseClients = (clients) => {
|
||||
;
|
||||
(clients || this._virtualWSClient).forEach(client => {
|
||||
client.pause();
|
||||
});
|
||||
};
|
||||
this.resumeClients = (clients) => {
|
||||
;
|
||||
(clients || this._virtualWSClient).forEach(client => {
|
||||
client.resume();
|
||||
});
|
||||
};
|
||||
this.onWatchStart = (client, queryID) => {
|
||||
this._queryIdClientMap.set(queryID, client);
|
||||
};
|
||||
this.onWatchClose = (client, queryID) => {
|
||||
if (queryID) {
|
||||
this._queryIdClientMap.delete(queryID);
|
||||
}
|
||||
this._watchIdClientMap.delete(client.watchId);
|
||||
this._virtualWSClient.delete(client);
|
||||
if (!this._virtualWSClient.size) {
|
||||
this.close(ws_event_1.CLOSE_EVENT_CODE.NoRealtimeListeners);
|
||||
}
|
||||
};
|
||||
this._maxReconnect = options.maxReconnect || DEFAULT_MAX_RECONNECT;
|
||||
this._reconnectInterval =
|
||||
options.reconnectInterval || DEFAULT_WS_RECONNECT_INTERVAL;
|
||||
this._context = options.context;
|
||||
}
|
||||
heartbeat(immediate) {
|
||||
this.clearHeartbeat();
|
||||
this._pingTimeoutId = setTimeout(async () => {
|
||||
try {
|
||||
if (!this._ws || this._ws.readyState !== WS_READY_STATE.OPEN) {
|
||||
return;
|
||||
}
|
||||
this._lastPingSendTS = Date.now();
|
||||
await this.ping();
|
||||
this._pingFailed = 0;
|
||||
this._pongTimeoutId = setTimeout(() => {
|
||||
console.error('pong timed out');
|
||||
if (this._pongMissed < DEFAULT_PONG_MISS_TOLERANCE) {
|
||||
this._pongMissed++;
|
||||
this.heartbeat(true);
|
||||
}
|
||||
else {
|
||||
this.initWebSocketConnection(true);
|
||||
}
|
||||
}, this._context.appConfig.realtimePongWaitTimeout);
|
||||
}
|
||||
catch (e) {
|
||||
if (this._pingFailed < DEFAULT_PING_FAIL_TOLERANCE) {
|
||||
this._pingFailed++;
|
||||
this.heartbeat();
|
||||
}
|
||||
else {
|
||||
this.close(ws_event_1.CLOSE_EVENT_CODE.HeartbeatPingError);
|
||||
}
|
||||
}
|
||||
}, immediate ? 0 : this._context.appConfig.realtimePingInterval);
|
||||
}
|
||||
clearHeartbeat() {
|
||||
this._pingTimeoutId && clearTimeout(this._pingTimeoutId);
|
||||
this._pongTimeoutId && clearTimeout(this._pongTimeoutId);
|
||||
}
|
||||
close(code) {
|
||||
this.clearHeartbeat();
|
||||
if (this._ws) {
|
||||
this._ws.close(code, ws_event_1.CLOSE_EVENT_CODE_INFO[code].name);
|
||||
this._ws = undefined;
|
||||
}
|
||||
}
|
||||
watch(options) {
|
||||
if (!this._ws && !this._wsInitPromise) {
|
||||
this.initWebSocketConnection(false);
|
||||
}
|
||||
const virtualClient = new virtual_websocket_client_1.VirtualWebSocketClient(Object.assign(Object.assign({}, options), { send: this.send, login: this.webLogin, isWSConnected: this.isWSConnected, onceWSConnected: this.onceWSConnected, getWaitExpectedTimeoutLength: this.getWaitExpectedTimeoutLength, onWatchStart: this.onWatchStart, onWatchClose: this.onWatchClose, debug: true }));
|
||||
this._virtualWSClient.add(virtualClient);
|
||||
this._watchIdClientMap.set(virtualClient.watchId, virtualClient);
|
||||
return virtualClient.listener;
|
||||
}
|
||||
}
|
||||
exports.RealtimeWebSocketClient = RealtimeWebSocketClient;
|
@ -0,0 +1,126 @@
|
||||
import { CloudSDKError } from '../utils/error';
|
||||
export declare const CLOSE_EVENT_CODE_INFO: {
|
||||
1000: {
|
||||
code: number;
|
||||
name: string;
|
||||
description: string;
|
||||
};
|
||||
1001: {
|
||||
code: number;
|
||||
name: string;
|
||||
description: string;
|
||||
};
|
||||
1002: {
|
||||
code: number;
|
||||
name: string;
|
||||
description: string;
|
||||
};
|
||||
1003: {
|
||||
code: number;
|
||||
name: string;
|
||||
description: string;
|
||||
};
|
||||
1005: {
|
||||
code: number;
|
||||
name: string;
|
||||
description: string;
|
||||
};
|
||||
1006: {
|
||||
code: number;
|
||||
name: string;
|
||||
description: string;
|
||||
};
|
||||
1007: {
|
||||
code: number;
|
||||
name: string;
|
||||
description: string;
|
||||
};
|
||||
1008: {
|
||||
code: number;
|
||||
name: string;
|
||||
description: string;
|
||||
};
|
||||
1009: {
|
||||
code: number;
|
||||
name: string;
|
||||
description: string;
|
||||
};
|
||||
1010: {
|
||||
code: number;
|
||||
name: string;
|
||||
description: string;
|
||||
};
|
||||
1011: {
|
||||
code: number;
|
||||
name: string;
|
||||
description: string;
|
||||
};
|
||||
1012: {
|
||||
code: number;
|
||||
name: string;
|
||||
description: string;
|
||||
};
|
||||
1013: {
|
||||
code: number;
|
||||
name: string;
|
||||
description: string;
|
||||
};
|
||||
1014: {
|
||||
code: number;
|
||||
name: string;
|
||||
description: string;
|
||||
};
|
||||
1015: {
|
||||
code: number;
|
||||
name: string;
|
||||
description: string;
|
||||
};
|
||||
3000: {
|
||||
code: number;
|
||||
name: string;
|
||||
description: string;
|
||||
};
|
||||
3001: {
|
||||
code: number;
|
||||
name: string;
|
||||
description: string;
|
||||
};
|
||||
3002: {
|
||||
code: number;
|
||||
name: string;
|
||||
description: string;
|
||||
};
|
||||
3003: {
|
||||
code: number;
|
||||
name: string;
|
||||
description: string;
|
||||
};
|
||||
3050: {
|
||||
code: number;
|
||||
name: string;
|
||||
description: string;
|
||||
};
|
||||
};
|
||||
export declare enum CLOSE_EVENT_CODE {
|
||||
NormalClosure = 1000,
|
||||
GoingAway = 1001,
|
||||
ProtocolError = 1002,
|
||||
UnsupportedData = 1003,
|
||||
NoStatusReceived = 1005,
|
||||
AbnormalClosure = 1006,
|
||||
InvalidFramePayloadData = 1007,
|
||||
PolicyViolation = 1008,
|
||||
MessageTooBig = 1009,
|
||||
MissingExtension = 1010,
|
||||
InternalError = 1011,
|
||||
ServiceRestart = 1012,
|
||||
TryAgainLater = 1013,
|
||||
BadGateway = 1014,
|
||||
TLSHandshake = 1015,
|
||||
ReconnectWebSocket = 3000,
|
||||
NoRealtimeListeners = 3001,
|
||||
HeartbeatPingError = 3002,
|
||||
HeartbeatPongTimeoutError = 3003,
|
||||
NoAuthentication = 3050
|
||||
}
|
||||
export declare const getWSCloseError: (code: CLOSE_EVENT_CODE, reason?: string) => CloudSDKError;
|
@ -0,0 +1,139 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const error_1 = require("../utils/error");
|
||||
const error_config_1 = require("../config/error.config");
|
||||
exports.CLOSE_EVENT_CODE_INFO = {
|
||||
1000: {
|
||||
code: 1000,
|
||||
name: 'Normal Closure',
|
||||
description: 'Normal closure; the connection successfully completed whatever purpose for which it was created.'
|
||||
},
|
||||
1001: {
|
||||
code: 1001,
|
||||
name: 'Going Away',
|
||||
description: 'The endpoint is going away, either because of a server failure or because the browser is navigating away from the page that opened the connection.'
|
||||
},
|
||||
1002: {
|
||||
code: 1002,
|
||||
name: 'Protocol Error',
|
||||
description: 'The endpoint is terminating the connection due to a protocol error.'
|
||||
},
|
||||
1003: {
|
||||
code: 1003,
|
||||
name: 'Unsupported Data',
|
||||
description: 'The connection is being terminated because the endpoint received data of a type it cannot accept (for example, a text-only endpoint received binary data).'
|
||||
},
|
||||
1005: {
|
||||
code: 1005,
|
||||
name: 'No Status Received',
|
||||
description: 'Indicates that no status code was provided even though one was expected.'
|
||||
},
|
||||
1006: {
|
||||
code: 1006,
|
||||
name: 'Abnormal Closure',
|
||||
description: 'Used to indicate that a connection was closed abnormally (that is, with no close frame being sent) when a status code is expected.'
|
||||
},
|
||||
1007: {
|
||||
code: 1007,
|
||||
name: 'Invalid frame payload data',
|
||||
description: 'The endpoint is terminating the connection because a message was received that contained inconsistent data (e.g., non-UTF-8 data within a text message).'
|
||||
},
|
||||
1008: {
|
||||
code: 1008,
|
||||
name: 'Policy Violation',
|
||||
description: 'The endpoint is terminating the connection because it received a message that violates its policy. This is a generic status code, used when codes 1003 and 1009 are not suitable.'
|
||||
},
|
||||
1009: {
|
||||
code: 1009,
|
||||
name: 'Message too big',
|
||||
description: 'The endpoint is terminating the connection because a data frame was received that is too large.'
|
||||
},
|
||||
1010: {
|
||||
code: 1010,
|
||||
name: 'Missing Extension',
|
||||
description: "The client is terminating the connection because it expected the server to negotiate one or more extension, but the server didn't."
|
||||
},
|
||||
1011: {
|
||||
code: 1011,
|
||||
name: 'Internal Error',
|
||||
description: 'The server is terminating the connection because it encountered an unexpected condition that prevented it from fulfilling the request.'
|
||||
},
|
||||
1012: {
|
||||
code: 1012,
|
||||
name: 'Service Restart',
|
||||
description: 'The server is terminating the connection because it is restarting.'
|
||||
},
|
||||
1013: {
|
||||
code: 1013,
|
||||
name: 'Try Again Later',
|
||||
description: 'The server is terminating the connection due to a temporary condition, e.g. it is overloaded and is casting off some of its clients.'
|
||||
},
|
||||
1014: {
|
||||
code: 1014,
|
||||
name: 'Bad Gateway',
|
||||
description: 'The server was acting as a gateway or proxy and received an invalid response from the upstream server. This is similar to 502 HTTP Status Code.'
|
||||
},
|
||||
1015: {
|
||||
code: 1015,
|
||||
name: 'TLS Handshake',
|
||||
description: "Indicates that the connection was closed due to a failure to perform a TLS handshake (e.g., the server certificate can't be verified)."
|
||||
},
|
||||
3000: {
|
||||
code: 3000,
|
||||
name: 'Reconnect WebSocket',
|
||||
description: 'The client is terminating the connection because it wants to reconnect'
|
||||
},
|
||||
3001: {
|
||||
code: 3001,
|
||||
name: 'No Realtime Listeners',
|
||||
description: 'The client is terminating the connection because no more realtime listeners exist'
|
||||
},
|
||||
3002: {
|
||||
code: 3002,
|
||||
name: 'Heartbeat Ping Error',
|
||||
description: 'The client is terminating the connection due to its failure in sending heartbeat messages'
|
||||
},
|
||||
3003: {
|
||||
code: 3003,
|
||||
name: 'Heartbeat Pong Timeout Error',
|
||||
description: 'The client is terminating the connection because no heartbeat response is received from the server'
|
||||
},
|
||||
3050: {
|
||||
code: 3050,
|
||||
name: 'Server Close',
|
||||
description: 'The client is terminating the connection because no heartbeat response is received from the server'
|
||||
}
|
||||
};
|
||||
var CLOSE_EVENT_CODE;
|
||||
(function (CLOSE_EVENT_CODE) {
|
||||
CLOSE_EVENT_CODE[CLOSE_EVENT_CODE["NormalClosure"] = 1000] = "NormalClosure";
|
||||
CLOSE_EVENT_CODE[CLOSE_EVENT_CODE["GoingAway"] = 1001] = "GoingAway";
|
||||
CLOSE_EVENT_CODE[CLOSE_EVENT_CODE["ProtocolError"] = 1002] = "ProtocolError";
|
||||
CLOSE_EVENT_CODE[CLOSE_EVENT_CODE["UnsupportedData"] = 1003] = "UnsupportedData";
|
||||
CLOSE_EVENT_CODE[CLOSE_EVENT_CODE["NoStatusReceived"] = 1005] = "NoStatusReceived";
|
||||
CLOSE_EVENT_CODE[CLOSE_EVENT_CODE["AbnormalClosure"] = 1006] = "AbnormalClosure";
|
||||
CLOSE_EVENT_CODE[CLOSE_EVENT_CODE["InvalidFramePayloadData"] = 1007] = "InvalidFramePayloadData";
|
||||
CLOSE_EVENT_CODE[CLOSE_EVENT_CODE["PolicyViolation"] = 1008] = "PolicyViolation";
|
||||
CLOSE_EVENT_CODE[CLOSE_EVENT_CODE["MessageTooBig"] = 1009] = "MessageTooBig";
|
||||
CLOSE_EVENT_CODE[CLOSE_EVENT_CODE["MissingExtension"] = 1010] = "MissingExtension";
|
||||
CLOSE_EVENT_CODE[CLOSE_EVENT_CODE["InternalError"] = 1011] = "InternalError";
|
||||
CLOSE_EVENT_CODE[CLOSE_EVENT_CODE["ServiceRestart"] = 1012] = "ServiceRestart";
|
||||
CLOSE_EVENT_CODE[CLOSE_EVENT_CODE["TryAgainLater"] = 1013] = "TryAgainLater";
|
||||
CLOSE_EVENT_CODE[CLOSE_EVENT_CODE["BadGateway"] = 1014] = "BadGateway";
|
||||
CLOSE_EVENT_CODE[CLOSE_EVENT_CODE["TLSHandshake"] = 1015] = "TLSHandshake";
|
||||
CLOSE_EVENT_CODE[CLOSE_EVENT_CODE["ReconnectWebSocket"] = 3000] = "ReconnectWebSocket";
|
||||
CLOSE_EVENT_CODE[CLOSE_EVENT_CODE["NoRealtimeListeners"] = 3001] = "NoRealtimeListeners";
|
||||
CLOSE_EVENT_CODE[CLOSE_EVENT_CODE["HeartbeatPingError"] = 3002] = "HeartbeatPingError";
|
||||
CLOSE_EVENT_CODE[CLOSE_EVENT_CODE["HeartbeatPongTimeoutError"] = 3003] = "HeartbeatPongTimeoutError";
|
||||
CLOSE_EVENT_CODE[CLOSE_EVENT_CODE["NoAuthentication"] = 3050] = "NoAuthentication";
|
||||
})(CLOSE_EVENT_CODE = exports.CLOSE_EVENT_CODE || (exports.CLOSE_EVENT_CODE = {}));
|
||||
exports.getWSCloseError = (code, reason) => {
|
||||
const info = exports.CLOSE_EVENT_CODE_INFO[code];
|
||||
const errMsg = !info
|
||||
? `code ${code}`
|
||||
: `${info.name}, code ${code}, reason ${reason || info.description}`;
|
||||
return new error_1.CloudSDKError({
|
||||
errCode: error_config_1.ERR_CODE.SDK_DATABASE_REALTIME_LISTENER_WEBSOCKET_CONNECTION_CLOSED,
|
||||
errMsg
|
||||
});
|
||||
};
|
@ -0,0 +1,18 @@
|
||||
export declare class RegExp {
|
||||
$regularExpression?: {
|
||||
pattern?: string;
|
||||
options?: string;
|
||||
};
|
||||
constructor({ regexp, options }: {
|
||||
regexp: any;
|
||||
options: any;
|
||||
});
|
||||
parse(): {
|
||||
$regularExpression: {
|
||||
pattern: string;
|
||||
options: string;
|
||||
};
|
||||
};
|
||||
readonly _internalType: import("../utils/symbol").InternalSymbol;
|
||||
}
|
||||
export declare function RegExpConstructor(param: any): RegExp;
|
@ -0,0 +1,30 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const symbol_1 = require("../helper/symbol");
|
||||
class RegExp {
|
||||
constructor({ regexp, options }) {
|
||||
if (!regexp) {
|
||||
throw new TypeError('regexp must be a string');
|
||||
}
|
||||
this.$regularExpression = {
|
||||
pattern: regexp || '',
|
||||
options: options || ''
|
||||
};
|
||||
}
|
||||
parse() {
|
||||
return {
|
||||
$regularExpression: {
|
||||
pattern: this.$regularExpression.pattern,
|
||||
options: this.$regularExpression.options
|
||||
}
|
||||
};
|
||||
}
|
||||
get _internalType() {
|
||||
return symbol_1.SYMBOL_REGEXP;
|
||||
}
|
||||
}
|
||||
exports.RegExp = RegExp;
|
||||
function RegExpConstructor(param) {
|
||||
return new RegExp(param);
|
||||
}
|
||||
exports.RegExpConstructor = RegExpConstructor;
|
@ -0,0 +1,11 @@
|
||||
import { LogicCommand } from '../commands/logic';
|
||||
export declare type IQueryCondition = Record<string, any> | LogicCommand;
|
||||
export declare type AnyObject = {
|
||||
[x: string]: any;
|
||||
};
|
||||
export declare function flattenQueryObject(query: Record<string, any>): Record<string, any>;
|
||||
export declare function flattenObject(object: AnyObject): AnyObject;
|
||||
export declare function mergeConditionAfterEncode(query: Record<string, any>, condition: Record<string, any>, key: string): void;
|
||||
export declare function isConversionRequired(val: any): boolean;
|
||||
export declare function encodeInternalDataType(val: any): IQueryCondition;
|
||||
export declare function decodeInternalDataType(object: AnyObject): any;
|
@ -0,0 +1,90 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const type_1 = require("../utils/type");
|
||||
const datatype_1 = require("./datatype");
|
||||
function flatten(query, shouldPreserverObject, parents, visited) {
|
||||
const cloned = Object.assign({}, query);
|
||||
for (const key in query) {
|
||||
if (/^\$/.test(key))
|
||||
continue;
|
||||
const value = query[key];
|
||||
if (value === undefined) {
|
||||
delete cloned[key];
|
||||
continue;
|
||||
}
|
||||
if (!value)
|
||||
continue;
|
||||
if (type_1.isObject(value) && !shouldPreserverObject(value)) {
|
||||
if (visited.indexOf(value) > -1) {
|
||||
throw new Error('Cannot convert circular structure to JSON');
|
||||
}
|
||||
const newParents = [...parents, key];
|
||||
const newVisited = [...visited, value];
|
||||
const flattenedChild = flatten(value, shouldPreserverObject, newParents, newVisited);
|
||||
cloned[key] = flattenedChild;
|
||||
let hasKeyNotCombined = false;
|
||||
for (const childKey in flattenedChild) {
|
||||
if (!/^\$/.test(childKey)) {
|
||||
cloned[`${key}.${childKey}`] = flattenedChild[childKey];
|
||||
delete cloned[key][childKey];
|
||||
}
|
||||
else {
|
||||
hasKeyNotCombined = true;
|
||||
}
|
||||
}
|
||||
if (!hasKeyNotCombined) {
|
||||
delete cloned[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
return cloned;
|
||||
}
|
||||
function flattenQueryObject(query) {
|
||||
return flatten(query, isConversionRequired, [], [query]);
|
||||
}
|
||||
exports.flattenQueryObject = flattenQueryObject;
|
||||
function flattenObject(object) {
|
||||
return flatten(object, (_) => false, [], [object]);
|
||||
}
|
||||
exports.flattenObject = flattenObject;
|
||||
function mergeConditionAfterEncode(query, condition, key) {
|
||||
if (!condition[key]) {
|
||||
delete query[key];
|
||||
}
|
||||
for (const conditionKey in condition) {
|
||||
if (query[conditionKey]) {
|
||||
if (type_1.isArray(query[conditionKey])) {
|
||||
query[conditionKey].push(condition[conditionKey]);
|
||||
}
|
||||
else if (type_1.isObject(query[conditionKey])) {
|
||||
if (type_1.isObject(condition[conditionKey])) {
|
||||
Object.assign(query[conditionKey], condition[conditionKey]);
|
||||
}
|
||||
else {
|
||||
console.warn(`unmergable condition, query is object but condition is ${type_1.getType(condition)}, can only overwrite`, condition, key);
|
||||
query[conditionKey] = condition[conditionKey];
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.warn(`to-merge query is of type ${type_1.getType(query)}, can only overwrite`, query, condition, key);
|
||||
query[conditionKey] = condition[conditionKey];
|
||||
}
|
||||
}
|
||||
else {
|
||||
query[conditionKey] = condition[conditionKey];
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.mergeConditionAfterEncode = mergeConditionAfterEncode;
|
||||
function isConversionRequired(val) {
|
||||
return type_1.isInternalObject(val) || type_1.isDate(val) || type_1.isRegExp(val);
|
||||
}
|
||||
exports.isConversionRequired = isConversionRequired;
|
||||
function encodeInternalDataType(val) {
|
||||
return datatype_1.serialize(val);
|
||||
}
|
||||
exports.encodeInternalDataType = encodeInternalDataType;
|
||||
function decodeInternalDataType(object) {
|
||||
return datatype_1.deserialize(object);
|
||||
}
|
||||
exports.decodeInternalDataType = decodeInternalDataType;
|
@ -0,0 +1,7 @@
|
||||
import { LogicCommand } from '../commands/logic';
|
||||
export declare type IQueryCondition = Record<string, any> | LogicCommand;
|
||||
export declare type AnyObject = {
|
||||
[x: string]: any;
|
||||
};
|
||||
export declare function serialize(val: any): IQueryCondition;
|
||||
export declare function deserialize(object: AnyObject): any;
|
@ -0,0 +1,99 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const symbol_1 = require("../helper/symbol");
|
||||
const type_1 = require("../utils/type");
|
||||
const index_1 = require("../geo/index");
|
||||
const index_2 = require("../serverDate/index");
|
||||
function serialize(val) {
|
||||
return serializeHelper(val, [val]);
|
||||
}
|
||||
exports.serialize = serialize;
|
||||
function serializeHelper(val, visited) {
|
||||
if (type_1.isInternalObject(val)) {
|
||||
switch (val._internalType) {
|
||||
case symbol_1.SYMBOL_GEO_POINT: {
|
||||
return val.toJSON();
|
||||
}
|
||||
case symbol_1.SYMBOL_SERVER_DATE: {
|
||||
return val.parse();
|
||||
}
|
||||
case symbol_1.SYMBOL_REGEXP: {
|
||||
return val.parse();
|
||||
}
|
||||
case symbol_1.SYMBOL_OBJECTID: {
|
||||
return val.parse();
|
||||
}
|
||||
default: {
|
||||
return val.toJSON ? val.toJSON() : val;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (type_1.isDate(val)) {
|
||||
return val;
|
||||
}
|
||||
else if (type_1.isRegExp(val)) {
|
||||
return {
|
||||
$regularExpression: {
|
||||
pattern: val.source,
|
||||
options: val.flags
|
||||
}
|
||||
};
|
||||
}
|
||||
else if (type_1.isArray(val)) {
|
||||
return val.map(item => {
|
||||
if (visited.indexOf(item) > -1) {
|
||||
throw new Error('Cannot convert circular structure to JSON');
|
||||
}
|
||||
return serializeHelper(item, [...visited, item]);
|
||||
});
|
||||
}
|
||||
else if (type_1.isObject(val)) {
|
||||
const rawRet = Object.assign({}, val);
|
||||
const finalRet = {};
|
||||
for (const key in rawRet) {
|
||||
if (visited.indexOf(rawRet[key]) > -1) {
|
||||
throw new Error('Cannot convert circular structure to JSON');
|
||||
}
|
||||
if (rawRet[key] !== undefined) {
|
||||
finalRet[key] = serializeHelper(rawRet[key], [...visited, rawRet[key]]);
|
||||
}
|
||||
}
|
||||
return finalRet;
|
||||
}
|
||||
else {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
function deserialize(object) {
|
||||
const ret = Object.assign({}, object);
|
||||
for (const key in ret) {
|
||||
switch (key) {
|
||||
case '$date': {
|
||||
switch (type_1.getType(ret[key])) {
|
||||
case 'number': {
|
||||
return new Date(ret[key]);
|
||||
}
|
||||
case 'object': {
|
||||
return new index_2.ServerDate(ret[key]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'type': {
|
||||
switch (ret.type) {
|
||||
case 'Point': {
|
||||
if (type_1.isArray(ret.coordinates) &&
|
||||
type_1.isNumber(ret.coordinates[0]) &&
|
||||
type_1.isNumber(ret.coordinates[1])) {
|
||||
return new index_1.Point(ret.coordinates[0], ret.coordinates[1]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return object;
|
||||
}
|
||||
exports.deserialize = deserialize;
|
@ -0,0 +1,8 @@
|
||||
import { QueryCommand } from '../commands/query';
|
||||
import { LogicCommand } from '../commands/logic';
|
||||
export declare type IQueryCondition = Record<string, any> | LogicCommand;
|
||||
export declare class QuerySerializer {
|
||||
constructor();
|
||||
static encode(query: IQueryCondition | QueryCommand | LogicCommand): IQueryCondition;
|
||||
static encodeEJSON(query: IQueryCondition | QueryCommand | LogicCommand, raw: boolean): string;
|
||||
}
|
@ -0,0 +1,254 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const query_1 = require("../commands/query");
|
||||
const logic_1 = require("../commands/logic");
|
||||
const symbol_1 = require("../helper/symbol");
|
||||
const type_1 = require("../utils/type");
|
||||
const operator_map_1 = require("../operator-map");
|
||||
const common_1 = require("./common");
|
||||
const utils_1 = require("../utils/utils");
|
||||
const validate_1 = require("../validate");
|
||||
class QuerySerializer {
|
||||
constructor() { }
|
||||
static encode(query) {
|
||||
const encoder = new QueryEncoder();
|
||||
return encoder.encodeQuery(query);
|
||||
}
|
||||
static encodeEJSON(query, raw) {
|
||||
const encoder = new QueryEncoder();
|
||||
return utils_1.stringifyByEJSON(raw ? query : encoder.encodeQuery(query));
|
||||
}
|
||||
}
|
||||
exports.QuerySerializer = QuerySerializer;
|
||||
class QueryEncoder {
|
||||
encodeQuery(query, key) {
|
||||
if (common_1.isConversionRequired(query)) {
|
||||
if (logic_1.isLogicCommand(query)) {
|
||||
return this.encodeLogicCommand(query);
|
||||
}
|
||||
else if (query_1.isQueryCommand(query)) {
|
||||
return this.encodeQueryCommand(query);
|
||||
}
|
||||
else if (type_1.isRegExp(query)) {
|
||||
return { [key]: this.encodeRegExp(query) };
|
||||
}
|
||||
else if (type_1.isDate(query)) {
|
||||
return { [key]: query };
|
||||
}
|
||||
else {
|
||||
return { [key]: this.encodeQueryObject(query) };
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (type_1.isObject(query)) {
|
||||
return this.encodeQueryObject(query);
|
||||
}
|
||||
else {
|
||||
return query;
|
||||
}
|
||||
}
|
||||
}
|
||||
encodeRegExp(query) {
|
||||
return {
|
||||
$regularExpression: {
|
||||
pattern: query.source,
|
||||
options: query.flags
|
||||
}
|
||||
};
|
||||
}
|
||||
encodeLogicCommand(query) {
|
||||
switch (query.operator) {
|
||||
case logic_1.LOGIC_COMMANDS_LITERAL.NOR:
|
||||
case logic_1.LOGIC_COMMANDS_LITERAL.AND:
|
||||
case logic_1.LOGIC_COMMANDS_LITERAL.OR: {
|
||||
const $op = operator_map_1.operatorToString(query.operator);
|
||||
const subqueries = query.operands.map((oprand) => this.encodeQuery(oprand, query.fieldName));
|
||||
return {
|
||||
[$op]: subqueries
|
||||
};
|
||||
}
|
||||
case logic_1.LOGIC_COMMANDS_LITERAL.NOT: {
|
||||
const $op = operator_map_1.operatorToString(query.operator);
|
||||
const operatorExpression = query.operands[0];
|
||||
if (type_1.isRegExp(operatorExpression)) {
|
||||
return {
|
||||
[query.fieldName]: {
|
||||
[$op]: this.encodeRegExp(operatorExpression)
|
||||
}
|
||||
};
|
||||
}
|
||||
else {
|
||||
const subqueries = this.encodeQuery(operatorExpression)[query.fieldName];
|
||||
return {
|
||||
[query.fieldName]: {
|
||||
[$op]: subqueries
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
default: {
|
||||
const $op = operator_map_1.operatorToString(query.operator);
|
||||
if (query.operands.length === 1) {
|
||||
const subquery = this.encodeQuery(query.operands[0]);
|
||||
return {
|
||||
[$op]: subquery
|
||||
};
|
||||
}
|
||||
else {
|
||||
const subqueries = query.operands.map(this.encodeQuery.bind(this));
|
||||
return {
|
||||
[$op]: subqueries
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
encodeQueryCommand(query) {
|
||||
if (query_1.isComparisonCommand(query)) {
|
||||
return this.encodeComparisonCommand(query);
|
||||
}
|
||||
else {
|
||||
return this.encodeComparisonCommand(query);
|
||||
}
|
||||
}
|
||||
encodeComparisonCommand(query) {
|
||||
if (query.fieldName === symbol_1.SYMBOL_UNSET_FIELD_NAME) {
|
||||
throw new Error('Cannot encode a comparison command with unset field name');
|
||||
}
|
||||
const $op = operator_map_1.operatorToString(query.operator);
|
||||
switch (query.operator) {
|
||||
case query_1.QUERY_COMMANDS_LITERAL.EQ:
|
||||
case query_1.QUERY_COMMANDS_LITERAL.NEQ:
|
||||
case query_1.QUERY_COMMANDS_LITERAL.LT:
|
||||
case query_1.QUERY_COMMANDS_LITERAL.LTE:
|
||||
case query_1.QUERY_COMMANDS_LITERAL.GT:
|
||||
case query_1.QUERY_COMMANDS_LITERAL.GTE:
|
||||
case query_1.QUERY_COMMANDS_LITERAL.ELEM_MATCH:
|
||||
case query_1.QUERY_COMMANDS_LITERAL.EXISTS:
|
||||
case query_1.QUERY_COMMANDS_LITERAL.SIZE:
|
||||
case query_1.QUERY_COMMANDS_LITERAL.MOD: {
|
||||
return {
|
||||
[query.fieldName]: {
|
||||
[$op]: common_1.encodeInternalDataType(query.operands[0])
|
||||
}
|
||||
};
|
||||
}
|
||||
case query_1.QUERY_COMMANDS_LITERAL.IN:
|
||||
case query_1.QUERY_COMMANDS_LITERAL.NIN:
|
||||
case query_1.QUERY_COMMANDS_LITERAL.ALL: {
|
||||
return {
|
||||
[query.fieldName]: {
|
||||
[$op]: common_1.encodeInternalDataType(query.operands)
|
||||
}
|
||||
};
|
||||
}
|
||||
case query_1.QUERY_COMMANDS_LITERAL.GEO_NEAR: {
|
||||
const options = query.operands[0];
|
||||
return {
|
||||
[query.fieldName]: {
|
||||
$nearSphere: {
|
||||
$geometry: options.geometry.toJSON(),
|
||||
$maxDistance: options.maxDistance,
|
||||
$minDistance: options.minDistance
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
case query_1.QUERY_COMMANDS_LITERAL.GEO_WITHIN: {
|
||||
const options = query.operands[0];
|
||||
if (options.centerSphere) {
|
||||
validate_1.Validate.isCentersPhere(options.centerSphere);
|
||||
const centerSphere = options.centerSphere;
|
||||
if (centerSphere[0]._internalType === symbol_1.SYMBOL_GEO_POINT) {
|
||||
return {
|
||||
[query.fieldName]: {
|
||||
$geoWithin: {
|
||||
$centerSphere: [centerSphere[0].toJSON().coordinates, centerSphere[1]]
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
return {
|
||||
[query.fieldName]: {
|
||||
$geoWithin: {
|
||||
$centerSphere: options.centerSphere
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
return {
|
||||
[query.fieldName]: {
|
||||
$geoWithin: {
|
||||
$geometry: options.geometry.toJSON()
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
case query_1.QUERY_COMMANDS_LITERAL.GEO_INTERSECTS: {
|
||||
const options = query.operands[0];
|
||||
return {
|
||||
[query.fieldName]: {
|
||||
$geoIntersects: {
|
||||
$geometry: options.geometry.toJSON()
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
default: {
|
||||
return {
|
||||
[query.fieldName]: {
|
||||
[$op]: common_1.encodeInternalDataType(query.operands[0])
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
encodeQueryObject(query) {
|
||||
const flattened = common_1.flattenQueryObject(query);
|
||||
for (const key in flattened) {
|
||||
const val = flattened[key];
|
||||
if (logic_1.isLogicCommand(val)) {
|
||||
flattened[key] = val._setFieldName(key);
|
||||
const condition = this.encodeLogicCommand(flattened[key]);
|
||||
this.mergeConditionAfterEncode(flattened, condition, key);
|
||||
}
|
||||
else if (query_1.isComparisonCommand(val)) {
|
||||
flattened[key] = val._setFieldName(key);
|
||||
const condition = this.encodeComparisonCommand(flattened[key]);
|
||||
this.mergeConditionAfterEncode(flattened, condition, key);
|
||||
}
|
||||
else if (common_1.isConversionRequired(val)) {
|
||||
flattened[key] = common_1.encodeInternalDataType(val);
|
||||
}
|
||||
}
|
||||
return flattened;
|
||||
}
|
||||
mergeConditionAfterEncode(query, condition, key) {
|
||||
if (!condition[key]) {
|
||||
delete query[key];
|
||||
}
|
||||
for (const conditionKey in condition) {
|
||||
if (query[conditionKey]) {
|
||||
if (type_1.isArray(query[conditionKey])) {
|
||||
query[conditionKey] = query[conditionKey].concat(condition[conditionKey]);
|
||||
}
|
||||
else if (type_1.isObject(query[conditionKey])) {
|
||||
if (type_1.isObject(condition[conditionKey])) {
|
||||
Object.assign(query, condition);
|
||||
}
|
||||
else {
|
||||
console.warn(`unmergable condition, query is object but condition is ${type_1.getType(condition)}, can only overwrite`, condition, key);
|
||||
query[conditionKey] = condition[conditionKey];
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.warn(`to-merge query is of type ${type_1.getType(query)}, can only overwrite`, query, condition, key);
|
||||
query[conditionKey] = condition[conditionKey];
|
||||
}
|
||||
}
|
||||
else {
|
||||
query[conditionKey] = condition[conditionKey];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue