mirror of
https://github.com/ToolJet/ToolJet
synced 2026-05-23 00:48:25 +00:00
Merge branch 'develop' into docs/upgrade-docusaurus
This commit is contained in:
commit
a42e90a7e5
18 changed files with 2359 additions and 93 deletions
30
docs/build-latest-version.sh
Normal file → Executable file
30
docs/build-latest-version.sh
Normal file → Executable file
|
|
@ -1,9 +1,33 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
jq '[.[0]]' versions.json > tmp_versions.json
|
||||
mv tmp_versions.json versions.json
|
||||
CONFIG_FILE="docusaurus.config.js"
|
||||
|
||||
# Extract lastVersion from docusaurus.config.js using sed
|
||||
LAST_VERSION=$(sed -n "s/.*lastVersion: *'\\([^']*\\)'.*/\\1/p" "$CONFIG_FILE")
|
||||
if [ -z "$LAST_VERSION" ]; then
|
||||
echo "Error: lastVersion not found in $CONFIG_FILE"
|
||||
exit 1
|
||||
fi
|
||||
echo "Found lastVersion: $LAST_VERSION"
|
||||
|
||||
# Extract all version numbers from the entire file
|
||||
ALL_VERSIONS=$(grep -oE "'[0-9]+\.[0-9]+\.[0-9]+(-[A-Za-z]+)?'" "$CONFIG_FILE" | sed "s/'//g" | sort -u -V -r)
|
||||
if [ -z "$ALL_VERSIONS" ]; then
|
||||
echo "Error: No versions found in $CONFIG_FILE"
|
||||
exit 1
|
||||
fi
|
||||
echo "Found raw versions:"
|
||||
echo "$ALL_VERSIONS"
|
||||
|
||||
# Convert the extracted versions into a JSON array format
|
||||
VERSION_ARRAY=$(echo "$ALL_VERSIONS" | jq -R -s -c 'split("\n")[:-1] + ["'"$LAST_VERSION"'"] | unique')
|
||||
echo "Updating versions.json with: $VERSION_ARRAY"
|
||||
|
||||
# Update versions.json with combined data
|
||||
echo $VERSION_ARRAY | jq . > versions.json
|
||||
|
||||
# Install dependencies and build the project
|
||||
npm i && npm run build
|
||||
|
||||
exec "$@"
|
||||
exec "$@"
|
||||
|
|
@ -1,22 +1,29 @@
|
|||
module.exports = async () => {
|
||||
return {
|
||||
verbose: true,
|
||||
moduleFileExtensions: ['js', 'json', 'ts'],
|
||||
rootDir: '.',
|
||||
testEnvironment: 'node',
|
||||
testRegex: '.spec.ts$',
|
||||
testPathIgnorePatterns: ['.e2e-spec.ts$'],
|
||||
transform: {
|
||||
'^.+\\.(t|j)s$': 'ts-jest',
|
||||
},
|
||||
moduleNameMapper: {
|
||||
'dist/src/entities/(.*)': '<rootDir>/dist/src/entities/$1',
|
||||
'^src/(.*)': '<rootDir>/src/$1',
|
||||
'@dto/(.*)': '<rootDir>/src/dto/$1',
|
||||
'@plugins/(.*)': '<rootDir>/plugins/$1',
|
||||
'@services/(.*)': '<rootDir>/src/services/$1',
|
||||
'@controllers/(.*)': '<rootDir>/src/controllers/$1',
|
||||
'@ee/(.*)': '<rootDir>/ee/$1',
|
||||
},
|
||||
};
|
||||
import type { Config } from '@jest/types';
|
||||
|
||||
const config: Config.InitialOptions = {
|
||||
verbose: true,
|
||||
moduleFileExtensions: ['js', 'json', 'ts', 'node'],
|
||||
rootDir: '.',
|
||||
testEnvironment: 'node',
|
||||
testRegex: '.spec.ts$',
|
||||
transform: {
|
||||
'^.+\\.(t|j)s$': [
|
||||
'ts-jest',
|
||||
{
|
||||
tsconfig: 'tsconfig.json',
|
||||
},
|
||||
],
|
||||
},
|
||||
moduleNameMapper: {
|
||||
'^src/(.*)': '<rootDir>/src/$1',
|
||||
'@dto/(.*)': '<rootDir>/src/dto/$1',
|
||||
'@plugins/(.*)': '<rootDir>/plugins/$1',
|
||||
'@services/(.*)': '<rootDir>/src/services/$1',
|
||||
'@entities/(.*)': '<rootDir>/src/entities/$1',
|
||||
'@controllers/(.*)': '<rootDir>/src/controllers/$1',
|
||||
'@ee/(.*)': '<rootDir>/ee/$1',
|
||||
},
|
||||
testTimeout: 30000,
|
||||
};
|
||||
|
||||
export default config;
|
||||
|
|
|
|||
330
server/package-lock.json
generated
330
server/package-lock.json
generated
|
|
@ -67,13 +67,16 @@
|
|||
"@golevelup/ts-jest": "^0.3.2",
|
||||
"@nestjs/schematics": "^8.0.0",
|
||||
"@nestjs/testing": "^8.0.0",
|
||||
"@pollyjs/adapter-node-http": "^6.0.6",
|
||||
"@pollyjs/core": "^6.0.6",
|
||||
"@pollyjs/persister-fs": "^6.0.6",
|
||||
"@types/compression": "^1.7.2",
|
||||
"@types/cookie-parser": "^1.4.3",
|
||||
"@types/express": "^4.17.13",
|
||||
"@types/express-http-proxy": "^1.6.3",
|
||||
"@types/got": "^9.6.12",
|
||||
"@types/humps": "^2.0.1",
|
||||
"@types/jest": "^27.0.0",
|
||||
"@types/jest": "^27.5.2",
|
||||
"@types/multer": "^1.4.7",
|
||||
"@types/node": "^16.0.0",
|
||||
"@types/nodemailer": "^6.4.4",
|
||||
|
|
@ -93,8 +96,9 @@
|
|||
"prettier": "^2.3.2",
|
||||
"preview-email": "^3.0.19",
|
||||
"rimraf": "^3.0.2",
|
||||
"setup-polly-jest": "^0.11.0",
|
||||
"supertest": "^6.1.3",
|
||||
"ts-jest": "^29.1.1",
|
||||
"ts-jest": "^29.1.5",
|
||||
"ts-loader": "^9.2.3",
|
||||
"typescript": "^4.3.5"
|
||||
},
|
||||
|
|
@ -2776,6 +2780,95 @@
|
|||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@pollyjs/adapter": {
|
||||
"version": "6.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@pollyjs/adapter/-/adapter-6.0.6.tgz",
|
||||
"integrity": "sha512-szhys0NiFQqCJDMC0kpDyjhLqSI7aWc6m6iATCRKgcMcN/7QN85pb3GmRzvnNV8+/Bi2AUSCwxZljcsKhbYVWQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@pollyjs/utils": "^6.0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/@pollyjs/adapter-node-http": {
|
||||
"version": "6.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@pollyjs/adapter-node-http/-/adapter-node-http-6.0.6.tgz",
|
||||
"integrity": "sha512-jdJG7oncmSHZAtVMmRgOxh5A56b7G8H9ULlk/ZaVJ+jNrlFXhLmPpx8OQoSF4Cuq2ugdiWmwmAjFXHStcpY3Mw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@pollyjs/adapter": "^6.0.6",
|
||||
"@pollyjs/utils": "^6.0.6",
|
||||
"lodash-es": "^4.17.21",
|
||||
"nock": "^13.2.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@pollyjs/core": {
|
||||
"version": "6.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@pollyjs/core/-/core-6.0.6.tgz",
|
||||
"integrity": "sha512-1ZZcmojW8iSFmvHGeLlvuudM3WiDV842FsVvtPAo3HoAYE6jCNveLHJ+X4qvonL4enj1SyTF3hXA107UkQFQrA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@pollyjs/utils": "^6.0.6",
|
||||
"@sindresorhus/fnv1a": "^2.0.1",
|
||||
"blueimp-md5": "^2.19.0",
|
||||
"fast-json-stable-stringify": "^2.1.0",
|
||||
"is-absolute-url": "^3.0.3",
|
||||
"lodash-es": "^4.17.21",
|
||||
"loglevel": "^1.8.0",
|
||||
"route-recognizer": "^0.3.4",
|
||||
"slugify": "^1.6.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@pollyjs/node-server": {
|
||||
"version": "6.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@pollyjs/node-server/-/node-server-6.0.6.tgz",
|
||||
"integrity": "sha512-nkP1+hdNoVOlrRz9R84haXVsaSmo8Xmq7uYK9GeUMSLQy4Fs55ZZ9o2KI6vRA8F6ZqJSbC31xxwwIoTkjyP7Vg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@pollyjs/utils": "^6.0.6",
|
||||
"body-parser": "^1.19.0",
|
||||
"cors": "^2.8.5",
|
||||
"express": "^4.17.1",
|
||||
"fs-extra": "^10.0.0",
|
||||
"http-graceful-shutdown": "^3.1.5",
|
||||
"morgan": "^1.10.0",
|
||||
"nocache": "^3.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@pollyjs/persister": {
|
||||
"version": "6.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@pollyjs/persister/-/persister-6.0.6.tgz",
|
||||
"integrity": "sha512-9KB1p+frvYvFGur4ifzLnFKFLXAMXrhAhCnVhTnkG2WIqqQPT7y+mKBV/DKCmYFx8GPA9FiNGqt2pB53uJpIdw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@pollyjs/utils": "^6.0.6",
|
||||
"@types/set-cookie-parser": "^2.4.1",
|
||||
"bowser": "^2.4.0",
|
||||
"fast-json-stable-stringify": "^2.1.0",
|
||||
"lodash-es": "^4.17.21",
|
||||
"set-cookie-parser": "^2.4.8",
|
||||
"utf8-byte-length": "^1.0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@pollyjs/persister-fs": {
|
||||
"version": "6.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@pollyjs/persister-fs/-/persister-fs-6.0.6.tgz",
|
||||
"integrity": "sha512-/ALVgZiH2zGqwLkW0Mntc0Oq1v7tR8LS8JD2SAyIsHpnSXeBUnfPWwjAuYw0vqORHFVEbwned6MBRFfvU/3qng==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@pollyjs/node-server": "^6.0.6",
|
||||
"@pollyjs/persister": "^6.0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/@pollyjs/utils": {
|
||||
"version": "6.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@pollyjs/utils/-/utils-6.0.6.tgz",
|
||||
"integrity": "sha512-nhVJoI3nRgRimE0V2DVSvsXXNROUH6iyJbroDu4IdsOIOFC1Ds0w+ANMB4NMwFaqE+AisWOmXFzwAGdAfyiQVg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"qs": "^6.10.1",
|
||||
"url-parse": "^1.5.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@protobufjs/aspromise": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
|
||||
|
|
@ -2991,6 +3084,15 @@
|
|||
"integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@sindresorhus/fnv1a": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@sindresorhus/fnv1a/-/fnv1a-2.0.1.tgz",
|
||||
"integrity": "sha512-suq9tRQ6bkpMukTG5K5z0sPWB7t0zExMzZCdmYm6xTSSIm/yCKNm7VCL36wVeyTsFr597/UhU1OAYdHGMDiHrw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@sindresorhus/is": {
|
||||
"version": "4.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz",
|
||||
|
|
@ -3333,9 +3435,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "16.18.68",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.68.tgz",
|
||||
"integrity": "sha512-sG3hPIQwJLoewrN7cr0dwEy+yF5nD4D/4FxtQpFciRD/xwUzgD+G05uxZHv5mhfXo4F9Jkp13jjn0CC2q325sg=="
|
||||
"version": "16.18.101",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.101.tgz",
|
||||
"integrity": "sha512-AAsx9Rgz2IzG8KJ6tXd6ndNkVcu+GYB6U/SnFAaokSPNx2N7dcIIfnighYUNumvj6YS2q39Dejz5tT0NCV7CWA=="
|
||||
},
|
||||
"node_modules/@types/nodemailer": {
|
||||
"version": "6.4.14",
|
||||
|
|
@ -3490,6 +3592,15 @@
|
|||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/set-cookie-parser": {
|
||||
"version": "2.4.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/set-cookie-parser/-/set-cookie-parser-2.4.9.tgz",
|
||||
"integrity": "sha512-bCorlULvl0xTdjj4BPUHX4cqs9I+go2TfW/7Do1nnFYWS0CPP429Qr1AY42kiFhCwLpvAkWFr1XIBHd8j6/MCQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/stack-utils": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz",
|
||||
|
|
@ -4882,6 +4993,18 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"node_modules/basic-auth": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
|
||||
"integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"safe-buffer": "5.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/bcrypt": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.1.tgz",
|
||||
|
|
@ -4934,6 +5057,12 @@
|
|||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/blueimp-md5": {
|
||||
"version": "2.19.0",
|
||||
"resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.19.0.tgz",
|
||||
"integrity": "sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/body-parser": {
|
||||
"version": "1.20.0",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz",
|
||||
|
|
@ -4980,6 +5109,12 @@
|
|||
"resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz",
|
||||
"integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw=="
|
||||
},
|
||||
"node_modules/bowser": {
|
||||
"version": "2.11.0",
|
||||
"resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz",
|
||||
"integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
|
|
@ -8532,6 +8667,18 @@
|
|||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/http-graceful-shutdown": {
|
||||
"version": "3.1.13",
|
||||
"resolved": "https://registry.npmjs.org/http-graceful-shutdown/-/http-graceful-shutdown-3.1.13.tgz",
|
||||
"integrity": "sha512-Ci5LRufQ8AtrQ1U26AevS8QoMXDOhnAHCJI3eZu1com7mZGHxREmw3dNj85ftpQokQCvak8nI2pnFS8zyM1M+Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"debug": "^4.3.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/http2-wrapper": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz",
|
||||
|
|
@ -8719,6 +8866,15 @@
|
|||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/is-absolute-url": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz",
|
||||
"integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/is-arrayish": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
|
||||
|
|
@ -10653,6 +10809,12 @@
|
|||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||
},
|
||||
"node_modules/lodash-es": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
|
||||
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/lodash.debounce": {
|
||||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
|
||||
|
|
@ -10761,6 +10923,19 @@
|
|||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/loglevel": {
|
||||
"version": "1.9.1",
|
||||
"resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.1.tgz",
|
||||
"integrity": "sha512-hP3I3kCrDIMuRwAwHltphhDM1r8i55H33GgqjXbrisuJhF4kRhW1dNuxsRklp4bXl8DSdLaNLuiL4A/LWRfxvg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 0.6.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "tidelift",
|
||||
"url": "https://tidelift.com/funding/github/npm/loglevel"
|
||||
}
|
||||
},
|
||||
"node_modules/long": {
|
||||
"version": "5.2.3",
|
||||
"resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz",
|
||||
|
|
@ -11574,6 +11749,49 @@
|
|||
"node": ">=12.20.0"
|
||||
}
|
||||
},
|
||||
"node_modules/morgan": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz",
|
||||
"integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"basic-auth": "~2.0.1",
|
||||
"debug": "2.6.9",
|
||||
"depd": "~2.0.0",
|
||||
"on-finished": "~2.3.0",
|
||||
"on-headers": "~1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/morgan/node_modules/debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/morgan/node_modules/ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/morgan/node_modules/on-finished": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
|
||||
"integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ee-first": "1.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/mri": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/mri/-/mri-1.1.4.tgz",
|
||||
|
|
@ -11688,6 +11906,29 @@
|
|||
"lower-case": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"node_modules/nocache": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/nocache/-/nocache-3.0.4.tgz",
|
||||
"integrity": "sha512-WDD0bdg9mbq6F4mRxEYcPWwfA1vxd0mrvKOyxI7Xj/atfRHVeutzuWByG//jfm4uPzp0y4Kj051EORCBSQMycw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/nock": {
|
||||
"version": "13.5.4",
|
||||
"resolved": "https://registry.npmjs.org/nock/-/nock-13.5.4.tgz",
|
||||
"integrity": "sha512-yAyTfdeNJGGBFxWdzSKCBYxs5FxLbCg5X5Q4ets974hcQzG1+qCxvIyOo4j2Ry6MUlhWVMX4OoYDefAIIwupjw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"debug": "^4.1.0",
|
||||
"json-stringify-safe": "^5.0.1",
|
||||
"propagate": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.13"
|
||||
}
|
||||
},
|
||||
"node_modules/node-abort-controller": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz",
|
||||
|
|
@ -12745,6 +12986,15 @@
|
|||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/propagate": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz",
|
||||
"integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/proto-list": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
|
||||
|
|
@ -12947,6 +13197,12 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/querystringify": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
|
||||
"integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/queue-microtask": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
||||
|
|
@ -13130,6 +13386,12 @@
|
|||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/requires-port": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
||||
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/resolve": {
|
||||
"version": "1.22.8",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
|
||||
|
|
@ -13262,6 +13524,12 @@
|
|||
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz",
|
||||
"integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA=="
|
||||
},
|
||||
"node_modules/route-recognizer": {
|
||||
"version": "0.3.4",
|
||||
"resolved": "https://registry.npmjs.org/route-recognizer/-/route-recognizer-0.3.4.tgz",
|
||||
"integrity": "sha512-2+MhsfPhvauN1O8KaXpXAOfR/fwe8dnUXVM+xw7yt40lJRfPVQxV6yryZm0cgRvAj5fMF/mdRZbL2ptwbs5i2g==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/run-applescript": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-3.2.0.tgz",
|
||||
|
|
@ -13619,6 +13887,12 @@
|
|||
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
||||
"integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="
|
||||
},
|
||||
"node_modules/set-cookie-parser": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.6.0.tgz",
|
||||
"integrity": "sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/set-function-length": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz",
|
||||
|
|
@ -13643,6 +13917,15 @@
|
|||
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
|
||||
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
|
||||
},
|
||||
"node_modules/setup-polly-jest": {
|
||||
"version": "0.11.0",
|
||||
"resolved": "https://registry.npmjs.org/setup-polly-jest/-/setup-polly-jest-0.11.0.tgz",
|
||||
"integrity": "sha512-3ywsCFGfCvfi3ZpwYyDc4YDPNiB70QtjODoKFD5hbhza1GMOh0ZzAYUZO9OBmo/1isasynxcS5WzKYMyDJUeZw==",
|
||||
"dev": true,
|
||||
"peerDependencies": {
|
||||
"@pollyjs/core": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/sha.js": {
|
||||
"version": "2.4.11",
|
||||
"resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
|
||||
|
|
@ -13754,6 +14037,15 @@
|
|||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/slugify": {
|
||||
"version": "1.6.6",
|
||||
"resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.6.tgz",
|
||||
"integrity": "sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/sonic-boom": {
|
||||
"version": "2.8.0",
|
||||
"resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-2.8.0.tgz",
|
||||
|
|
@ -14353,9 +14645,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/ts-jest": {
|
||||
"version": "29.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.1.tgz",
|
||||
"integrity": "sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA==",
|
||||
"version": "29.1.5",
|
||||
"resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.5.tgz",
|
||||
"integrity": "sha512-UuClSYxM7byvvYfyWdFI+/2UxMmwNyJb0NPkZPQE2hew3RurV7l7zURgOHAd/1I1ZdPpe3GUsXNXAcN8TFKSIg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"bs-logger": "0.x",
|
||||
|
|
@ -14371,10 +14663,11 @@
|
|||
"ts-jest": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
"node": "^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": ">=7.0.0-beta.0 <8",
|
||||
"@jest/transform": "^29.0.0",
|
||||
"@jest/types": "^29.0.0",
|
||||
"babel-jest": "^29.0.0",
|
||||
"jest": "^29.0.0",
|
||||
|
|
@ -14384,6 +14677,9 @@
|
|||
"@babel/core": {
|
||||
"optional": true
|
||||
},
|
||||
"@jest/transform": {
|
||||
"optional": true
|
||||
},
|
||||
"@jest/types": {
|
||||
"optional": true
|
||||
},
|
||||
|
|
@ -14857,6 +15153,22 @@
|
|||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/url-parse": {
|
||||
"version": "1.5.10",
|
||||
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
|
||||
"integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"querystringify": "^2.1.1",
|
||||
"requires-port": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/utf8-byte-length": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.5.tgz",
|
||||
"integrity": "sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
|
|
|
|||
|
|
@ -13,11 +13,13 @@
|
|||
"start:dev": "NODE_ENV=development nest start --watch",
|
||||
"start:debug": "nest start --debug --watch",
|
||||
"start:prod": "NODE_ENV=production node dist/src/main",
|
||||
"test": "NODE_ENV=test jest --config jest.config.ts",
|
||||
"test:record": "NODE_ENV=test POLLY_MODE=record jest --config jest.config.ts --detectOpenHandles",
|
||||
"test": "NODE_ENV=test jest --config jest.config.ts --detectOpenHandles",
|
||||
"test:watch": "NODE_ENV=test jest --watch",
|
||||
"test:cov": "NODE_ENV=test jest --coverage",
|
||||
"test:debug": "NODE_ENV=test node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
|
||||
"test:e2e": "NODE_ENV=test jest --runInBand --config ./test/jest-e2e.json --detectOpenHandles",
|
||||
"test:e2e:record": "NODE_ENV=test POLLY_MODE=record jest --runInBand --config ./test/jest-e2e.json --detectOpenHandles",
|
||||
"db:create": "ts-node ./scripts/create-database.ts",
|
||||
"db:create:prod": "node dist/scripts/create-database.js ",
|
||||
"db:drop": "ts-node ./scripts/drop-database.ts",
|
||||
|
|
@ -95,13 +97,16 @@
|
|||
"@golevelup/ts-jest": "^0.3.2",
|
||||
"@nestjs/schematics": "^8.0.0",
|
||||
"@nestjs/testing": "^8.0.0",
|
||||
"@pollyjs/adapter-node-http": "^6.0.6",
|
||||
"@pollyjs/core": "^6.0.6",
|
||||
"@pollyjs/persister-fs": "^6.0.6",
|
||||
"@types/compression": "^1.7.2",
|
||||
"@types/cookie-parser": "^1.4.3",
|
||||
"@types/express": "^4.17.13",
|
||||
"@types/express-http-proxy": "^1.6.3",
|
||||
"@types/got": "^9.6.12",
|
||||
"@types/humps": "^2.0.1",
|
||||
"@types/jest": "^27.0.0",
|
||||
"@types/jest": "^27.5.2",
|
||||
"@types/multer": "^1.4.7",
|
||||
"@types/node": "^16.0.0",
|
||||
"@types/nodemailer": "^6.4.4",
|
||||
|
|
@ -121,8 +126,9 @@
|
|||
"prettier": "^2.3.2",
|
||||
"preview-email": "^3.0.19",
|
||||
"rimraf": "^3.0.2",
|
||||
"setup-polly-jest": "^0.11.0",
|
||||
"supertest": "^6.1.3",
|
||||
"ts-jest": "^29.1.1",
|
||||
"ts-jest": "^29.1.5",
|
||||
"ts-loader": "^9.2.3",
|
||||
"typescript": "^4.3.5"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -2,6 +2,50 @@ import { QueryFailedError } from 'typeorm';
|
|||
import { InternalTable } from 'src/entities/internal_table.entity';
|
||||
import { capitalize } from 'lodash';
|
||||
|
||||
export const TJDB = {
|
||||
character_varying: 'character varying' as const,
|
||||
integer: 'integer' as const,
|
||||
bigint: 'bigint' as const,
|
||||
serial: 'serial' as const,
|
||||
double_precision: 'double precision' as const,
|
||||
boolean: 'boolean' as const,
|
||||
};
|
||||
|
||||
export type TooljetDatabaseDataTypes = (typeof TJDB)[keyof typeof TJDB];
|
||||
|
||||
export type TooljetDatabaseColumn = {
|
||||
column_name: string;
|
||||
data_type: TooljetDatabaseDataTypes;
|
||||
column_default: string | null;
|
||||
character_maximum_length: number | null;
|
||||
numeric_precision: number | null;
|
||||
constraints_type: {
|
||||
is_not_null: boolean;
|
||||
is_primary_key: boolean;
|
||||
is_unique: boolean;
|
||||
};
|
||||
keytype: string | null;
|
||||
};
|
||||
|
||||
export type TooljetDatabaseForeignKey = {
|
||||
column_names: string[];
|
||||
referenced_table_name: string;
|
||||
referenced_column_names: string[];
|
||||
on_update: string;
|
||||
on_delete: string;
|
||||
constraint_name: string;
|
||||
referenced_table_id: string;
|
||||
};
|
||||
|
||||
export type TooljetDatabaseTable = {
|
||||
id: string;
|
||||
table_name: string;
|
||||
schema: {
|
||||
columns: TooljetDatabaseColumn[];
|
||||
foreign_keys: TooljetDatabaseForeignKey[];
|
||||
};
|
||||
};
|
||||
|
||||
enum PostgresErrorCode {
|
||||
UniqueViolation = '23505',
|
||||
CheckViolation = '23514',
|
||||
|
|
|
|||
|
|
@ -3,28 +3,14 @@ import { EntityManager, In, ObjectLiteral, SelectQueryBuilder, Table, TableColum
|
|||
import { InjectEntityManager } from '@nestjs/typeorm';
|
||||
import { InternalTable } from 'src/entities/internal_table.entity';
|
||||
import { isString, isEmpty, camelCase } from 'lodash';
|
||||
import { TooljetDatabaseError, TooljetDbActions } from 'src/modules/tooljet_db/tooljet-db.types';
|
||||
|
||||
export type TableColumnSchema = {
|
||||
column_name: string;
|
||||
data_type: SupportedDataTypes;
|
||||
column_default: string | null;
|
||||
character_maximum_length: number | null;
|
||||
numeric_precision: number | null;
|
||||
is_nullable: 'YES' | 'NO';
|
||||
constraint_type: string | null;
|
||||
keytype: string | null;
|
||||
};
|
||||
|
||||
export type ForeignKeyDetails = {
|
||||
column_names: Array<string>;
|
||||
referenced_table_name: string;
|
||||
referenced_column_names: Array<string>;
|
||||
on_delete: string;
|
||||
on_update: string;
|
||||
};
|
||||
|
||||
export type SupportedDataTypes = 'character varying' | 'integer' | 'bigint' | 'serial' | 'double precision' | 'boolean';
|
||||
import {
|
||||
TooljetDatabaseColumn,
|
||||
TooljetDatabaseDataTypes,
|
||||
TooljetDatabaseError,
|
||||
TooljetDatabaseForeignKey,
|
||||
TooljetDbActions,
|
||||
TJDB,
|
||||
} from 'src/modules/tooljet_db/tooljet-db.types';
|
||||
|
||||
// Patching TypeORM SelectQueryBuilder to handle for right and full outer joins
|
||||
declare module 'typeorm' {
|
||||
|
|
@ -91,7 +77,7 @@ export class TooljetDbService {
|
|||
organizationId: string,
|
||||
params,
|
||||
connectionManagers: Record<string, EntityManager> = { appManager: this.manager, tjdbManager: this.tooljetDbManager }
|
||||
): Promise<{ foreign_keys: ForeignKeyDetails[]; columns: TableColumnSchema[] }> {
|
||||
): Promise<{ foreign_keys: TooljetDatabaseForeignKey[]; columns: TooljetDatabaseColumn[] }> {
|
||||
const { table_name: tableName, id: id } = params;
|
||||
const { appManager, tjdbManager } = connectionManagers;
|
||||
|
||||
|
|
@ -667,7 +653,7 @@ export class TooljetDbService {
|
|||
if (!tables?.length) throw new BadRequestException('Tables are not chosen');
|
||||
|
||||
const tableIdList: Array<string> = tables
|
||||
.filter((table) => table.type === 'Table')
|
||||
.filter((table) => table.type === 'Table' && !isEmpty(table.name))
|
||||
.map((filteredTable) => filteredTable.name);
|
||||
|
||||
const internalTables = await this.findOrFailInternalTableFromTableId(tableIdList, organizationId);
|
||||
|
|
@ -847,17 +833,17 @@ export class TooljetDbService {
|
|||
}
|
||||
}
|
||||
|
||||
private prepareColumnListForCreateTable(columns) {
|
||||
private prepareColumnListForCreateTable(columns: TooljetDatabaseColumn[]) {
|
||||
const columnList = columns.map((column) => {
|
||||
const { column_name, constraints_type = {} } = column;
|
||||
const { column_name, constraints_type = {} as any } = column;
|
||||
const is_primary_key_column = constraints_type?.is_primary_key || false;
|
||||
|
||||
const prepareDataTypeAndDefault = (column): { data_type: SupportedDataTypes; column_default: unknown } => {
|
||||
const prepareDataTypeAndDefault = (column): { data_type: TooljetDatabaseDataTypes; column_default: unknown } => {
|
||||
const { data_type, column_default = undefined } = column;
|
||||
const isSerial = () => data_type === 'integer' && /^nextval\(/.test(column_default);
|
||||
const isCharacterVarying = () => data_type === 'character varying';
|
||||
const isSerial = () => data_type === TJDB.integer && /^nextval\(/.test(column_default);
|
||||
const isCharacterVarying = () => data_type === TJDB.character_varying;
|
||||
|
||||
if (isSerial()) return { data_type: 'serial', column_default: undefined };
|
||||
if (isSerial()) return { data_type: TJDB.serial, column_default: undefined };
|
||||
if (isCharacterVarying()) return { data_type, column_default: this.addQuotesIfString(column_default) };
|
||||
|
||||
return { data_type, column_default };
|
||||
|
|
@ -876,7 +862,7 @@ export class TooljetDbService {
|
|||
return columnList;
|
||||
}
|
||||
|
||||
private prepareForeignKeyDetailsJSON(foreign_keys, referenced_tables_info) {
|
||||
private prepareForeignKeyDetailsJSON(foreign_keys: TooljetDatabaseForeignKey[], referenced_tables_info) {
|
||||
if (!foreign_keys.length) return [];
|
||||
const foreignKeyList = foreign_keys.map((foreignKeyDetail) => {
|
||||
const {
|
||||
|
|
|
|||
|
|
@ -2,12 +2,13 @@ import { BadRequestException, Injectable, NotFoundException, Optional } from '@n
|
|||
import { EntityManager } from 'typeorm';
|
||||
import { InternalTable } from 'src/entities/internal_table.entity';
|
||||
import * as csv from 'fast-csv';
|
||||
import { SupportedDataTypes, TableColumnSchema, TooljetDbService } from './tooljet_db.service';
|
||||
import { TooljetDbService } from './tooljet_db.service';
|
||||
import { InjectEntityManager } from '@nestjs/typeorm';
|
||||
import { isEmpty } from 'lodash';
|
||||
import { pipeline } from 'stream/promises';
|
||||
import { PassThrough } from 'stream';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import { TJDB, TooljetDatabaseColumn, TooljetDatabaseDataTypes } from 'src/modules/tooljet_db/tooljet-db.types';
|
||||
|
||||
const MAX_ROW_COUNT = 1000;
|
||||
|
||||
|
|
@ -33,17 +34,17 @@ export class TooljetDbBulkUploadService {
|
|||
throw new NotFoundException(`Table ${tableName} not found`);
|
||||
}
|
||||
|
||||
const { columns: internalTableColumnSchema }: { columns: TableColumnSchema[] } =
|
||||
const { columns: internalTableDatabaseColumn }: { columns: TooljetDatabaseColumn[] } =
|
||||
await this.tooljetDbService.perform(organizationId, 'view_table', {
|
||||
table_name: tableName,
|
||||
});
|
||||
|
||||
return await this.bulkUploadCsv(internalTable.id, internalTableColumnSchema, fileBuffer);
|
||||
return await this.bulkUploadCsv(internalTable.id, internalTableDatabaseColumn, fileBuffer);
|
||||
}
|
||||
|
||||
async bulkUploadCsv(
|
||||
internalTableId: string,
|
||||
internalTableColumnSchema: TableColumnSchema[],
|
||||
internalTableDatabaseColumn: TooljetDatabaseColumn[],
|
||||
fileBuffer: Buffer
|
||||
): Promise<{ processedRows: number }> {
|
||||
const rowsToUpsert = [];
|
||||
|
|
@ -53,17 +54,17 @@ export class TooljetDbBulkUploadService {
|
|||
strictColumnHandling: true,
|
||||
discardUnmappedColumns: true,
|
||||
});
|
||||
const primaryKeyColumnSchema = internalTableColumnSchema.filter(
|
||||
const primaryKeyColumnSchema = internalTableDatabaseColumn.filter(
|
||||
(colDetails) => colDetails.keytype === 'PRIMARY KEY'
|
||||
);
|
||||
const primaryKeyValuesToUpsert = new Set();
|
||||
let rowsProcessed = 0;
|
||||
|
||||
csvStream
|
||||
.on('headers', (headers) => this.validateHeadersAsColumnSubset(internalTableColumnSchema, headers, csvStream))
|
||||
.on('headers', (headers) => this.validateHeadersAsColumnSubset(internalTableDatabaseColumn, headers, csvStream))
|
||||
.transform((row) =>
|
||||
this.validateAndParseColumnDataType(
|
||||
internalTableColumnSchema,
|
||||
internalTableDatabaseColumn,
|
||||
primaryKeyColumnSchema,
|
||||
row,
|
||||
rowsProcessed,
|
||||
|
|
@ -102,7 +103,7 @@ export class TooljetDbBulkUploadService {
|
|||
await pipeline(passThrough, csvStream);
|
||||
|
||||
await this.tooljetDbManager.transaction(async (tooljetDbManager) => {
|
||||
await this.bulkUpsertRows(tooljetDbManager, rowsToUpsert, internalTableId, internalTableColumnSchema);
|
||||
await this.bulkUpsertRows(tooljetDbManager, rowsToUpsert, internalTableId, internalTableDatabaseColumn);
|
||||
});
|
||||
|
||||
return { processedRows: rowsProcessed };
|
||||
|
|
@ -112,15 +113,15 @@ export class TooljetDbBulkUploadService {
|
|||
tooljetDbManager: EntityManager,
|
||||
rowsToUpsert: unknown[],
|
||||
internalTableId: string,
|
||||
internalTableColumnSchema: TableColumnSchema[]
|
||||
internalTableDatabaseColumn: TooljetDatabaseColumn[]
|
||||
) {
|
||||
if (isEmpty(rowsToUpsert)) return;
|
||||
|
||||
const primaryKeyColumns = internalTableColumnSchema
|
||||
const primaryKeyColumns = internalTableDatabaseColumn
|
||||
.filter((colDetails) => colDetails.keytype === 'PRIMARY KEY')
|
||||
.map((colDetails) => colDetails.column_name);
|
||||
|
||||
const serialTypeColumns = internalTableColumnSchema
|
||||
const serialTypeColumns = internalTableDatabaseColumn
|
||||
.filter((colDetails) => colDetails.data_type === 'integer' && /^nextval\(/.test(colDetails.column_default))
|
||||
.map((colDetails) => colDetails.column_name);
|
||||
|
||||
|
|
@ -164,11 +165,11 @@ export class TooljetDbBulkUploadService {
|
|||
}
|
||||
|
||||
async validateHeadersAsColumnSubset(
|
||||
internalTableColumnSchema: TableColumnSchema[],
|
||||
internalTableDatabaseColumn: TooljetDatabaseColumn[],
|
||||
headers: string[],
|
||||
csvStream: csv.CsvParserStream<csv.ParserRow<any>, csv.ParserRow<any>>
|
||||
) {
|
||||
const internalTableColumns = new Set<string>(internalTableColumnSchema.map((c) => c.column_name));
|
||||
const internalTableColumns = new Set<string>(internalTableDatabaseColumn.map((c) => c.column_name));
|
||||
const columnsInCsv = new Set<string>(headers);
|
||||
const isSubset = (subset: Set<string>, superset: Set<string>) => [...subset].every((item) => superset.has(item));
|
||||
|
||||
|
|
@ -179,15 +180,15 @@ export class TooljetDbBulkUploadService {
|
|||
}
|
||||
}
|
||||
|
||||
findPrimaryKey(columnName: string, primaryKeyColumns: TableColumnSchema[]) {
|
||||
findPrimaryKey(columnName: string, primaryKeyColumns: TooljetDatabaseColumn[]) {
|
||||
return primaryKeyColumns.find(
|
||||
(colDetails) => colDetails.column_name === columnName && colDetails.keytype === 'PRIMARY KEY'
|
||||
);
|
||||
}
|
||||
|
||||
validateAndParseColumnDataType(
|
||||
internalTableColumnSchema: TableColumnSchema[],
|
||||
primaryKeyColumnSchema: TableColumnSchema[],
|
||||
internalTableDatabaseColumn: TooljetDatabaseColumn[],
|
||||
primaryKeyColumnSchema: TooljetDatabaseColumn[],
|
||||
row: unknown,
|
||||
rowsProcessed: number,
|
||||
csvStream: csv.CsvParserStream<csv.ParserRow<any>, csv.ParserRow<any>>
|
||||
|
|
@ -197,7 +198,7 @@ export class TooljetDbBulkUploadService {
|
|||
try {
|
||||
const columnsInCsv = Object.keys(row);
|
||||
const transformedRow = columnsInCsv.reduce((result, columnInCsv) => {
|
||||
const columnDetails = internalTableColumnSchema.find((colDetails) => colDetails.column_name === columnInCsv);
|
||||
const columnDetails = internalTableDatabaseColumn.find((colDetails) => colDetails.column_name === columnInCsv);
|
||||
const primaryKey = this.findPrimaryKey(columnInCsv, primaryKeyColumnSchema);
|
||||
|
||||
if (!isEmpty(primaryKey) && isEmpty(primaryKey.column_default) && isEmpty(row[columnInCsv]))
|
||||
|
|
@ -213,15 +214,15 @@ export class TooljetDbBulkUploadService {
|
|||
}
|
||||
}
|
||||
|
||||
convertToDataType(columnValue: string, supportedDataType: SupportedDataTypes) {
|
||||
convertToDataType(columnValue: string, supportedDataType: TooljetDatabaseDataTypes) {
|
||||
if (!columnValue) return null;
|
||||
|
||||
switch (supportedDataType) {
|
||||
case 'boolean':
|
||||
case TJDB.boolean:
|
||||
return this.convertBoolean(columnValue);
|
||||
case 'integer':
|
||||
case 'double precision':
|
||||
case 'bigint':
|
||||
case TJDB.integer:
|
||||
case TJDB.double_precision:
|
||||
case TJDB.bigint:
|
||||
return this.convertNumber(columnValue, supportedDataType);
|
||||
default:
|
||||
return columnValue;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,128 @@
|
|||
{
|
||||
"log": {
|
||||
"_recordingName": "TooljetDbOperationsService/.createRow/should create a new row and verify its content",
|
||||
"creator": {
|
||||
"comment": "persister:fs",
|
||||
"name": "Polly.JS",
|
||||
"version": "6.0.6"
|
||||
},
|
||||
"entries": [
|
||||
{
|
||||
"_id": "197a6feb7e633d071ca275fc502d5b6f",
|
||||
"_order": 0,
|
||||
"cache": {},
|
||||
"request": {
|
||||
"bodySize": 46,
|
||||
"cookies": [],
|
||||
"headers": [
|
||||
{
|
||||
"name": "user-agent",
|
||||
"value": "got (https://github.com/sindresorhus/got)"
|
||||
},
|
||||
{
|
||||
"name": "data-query-id",
|
||||
"value": "query-id"
|
||||
},
|
||||
{
|
||||
"name": "tj-workspace-id",
|
||||
"value": "b17c6d5a-93b6-4eee-8420-4c19b9bf3ddf"
|
||||
},
|
||||
{
|
||||
"name": "tableinfo",
|
||||
"value": {
|
||||
"9a26655a-3afb-410f-8dd1-13f0787255b4": "users"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "authorization",
|
||||
"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoicG9zdGdyZXMiLCJpYXQiOjE3MjAxMjY3NTUsImV4cCI6MTcyMDEyNjgxNX0.rcfp0ZwfIdJ8fIkpb1ZBvOdyQLF9KtKdQJXc8F7gtX4"
|
||||
},
|
||||
{
|
||||
"name": "prefer",
|
||||
"value": "count=exact, return=representation"
|
||||
},
|
||||
{
|
||||
"name": "accept",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"name": "content-length",
|
||||
"value": "46"
|
||||
},
|
||||
{
|
||||
"name": "accept-encoding",
|
||||
"value": "gzip, deflate, br"
|
||||
},
|
||||
{
|
||||
"name": "host",
|
||||
"value": "localhost:3001"
|
||||
}
|
||||
],
|
||||
"headersSize": 563,
|
||||
"httpVersion": "HTTP/1.1",
|
||||
"method": "POST",
|
||||
"postData": {
|
||||
"mimeType": "text/plain",
|
||||
"params": [],
|
||||
"text": "{\"name\":\"John Doe\",\"email\":\"john@example.com\"}"
|
||||
},
|
||||
"queryString": [],
|
||||
"url": "http://localhost:3001/9a26655a-3afb-410f-8dd1-13f0787255b4"
|
||||
},
|
||||
"response": {
|
||||
"bodySize": 55,
|
||||
"content": {
|
||||
"mimeType": "application/json; charset=utf-8",
|
||||
"size": 55,
|
||||
"text": "[{\"id\":1,\"name\":\"John Doe\",\"email\":\"john@example.com\"}]"
|
||||
},
|
||||
"cookies": [],
|
||||
"headers": [
|
||||
{
|
||||
"name": "transfer-encoding",
|
||||
"value": "chunked"
|
||||
},
|
||||
{
|
||||
"name": "date",
|
||||
"value": "Thu, 04 Jul 2024 20:59:15 GMT"
|
||||
},
|
||||
{
|
||||
"name": "server",
|
||||
"value": "postgrest/12.0.3 (6a506d1)"
|
||||
},
|
||||
{
|
||||
"name": "content-range",
|
||||
"value": "*/1"
|
||||
},
|
||||
{
|
||||
"name": "preference-applied",
|
||||
"value": "return=representation, count=exact"
|
||||
},
|
||||
{
|
||||
"name": "content-type",
|
||||
"value": "application/json; charset=utf-8"
|
||||
}
|
||||
],
|
||||
"headersSize": 226,
|
||||
"httpVersion": "HTTP/1.1",
|
||||
"redirectURL": "",
|
||||
"status": 201,
|
||||
"statusText": "Created"
|
||||
},
|
||||
"startedDateTime": "2024-07-04T20:59:15.597Z",
|
||||
"time": 78,
|
||||
"timings": {
|
||||
"blocked": -1,
|
||||
"connect": -1,
|
||||
"dns": -1,
|
||||
"receive": 0,
|
||||
"send": 0,
|
||||
"ssl": -1,
|
||||
"wait": 78
|
||||
}
|
||||
}
|
||||
],
|
||||
"pages": [],
|
||||
"version": "1.2"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,246 @@
|
|||
{
|
||||
"log": {
|
||||
"_recordingName": "TooljetDbOperationsService/.deleteRows/should delete rows and verify the deletion",
|
||||
"creator": {
|
||||
"comment": "persister:fs",
|
||||
"name": "Polly.JS",
|
||||
"version": "6.0.6"
|
||||
},
|
||||
"entries": [
|
||||
{
|
||||
"_id": "197a6feb7e633d071ca275fc502d5b6f",
|
||||
"_order": 0,
|
||||
"cache": {},
|
||||
"request": {
|
||||
"bodySize": 46,
|
||||
"cookies": [],
|
||||
"headers": [
|
||||
{
|
||||
"name": "user-agent",
|
||||
"value": "got (https://github.com/sindresorhus/got)"
|
||||
},
|
||||
{
|
||||
"name": "data-query-id",
|
||||
"value": "query-id"
|
||||
},
|
||||
{
|
||||
"name": "tj-workspace-id",
|
||||
"value": "d029ddeb-e4c5-46ed-aa23-bbd58fbb445b"
|
||||
},
|
||||
{
|
||||
"name": "tableinfo",
|
||||
"value": {
|
||||
"d4dbdb73-e3fd-4cb8-8fd0-a8540f38267d": "users"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "authorization",
|
||||
"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoicG9zdGdyZXMiLCJpYXQiOjE3MjAxMjY3ODAsImV4cCI6MTcyMDEyNjg0MH0.oSaB7oSG8LYnxHs_CbaiBd7ZZXasu--TZuqo9nwohZY"
|
||||
},
|
||||
{
|
||||
"name": "prefer",
|
||||
"value": "count=exact, return=representation"
|
||||
},
|
||||
{
|
||||
"name": "accept",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"name": "content-length",
|
||||
"value": "46"
|
||||
},
|
||||
{
|
||||
"name": "accept-encoding",
|
||||
"value": "gzip, deflate, br"
|
||||
},
|
||||
{
|
||||
"name": "host",
|
||||
"value": "localhost:3001"
|
||||
}
|
||||
],
|
||||
"headersSize": 563,
|
||||
"httpVersion": "HTTP/1.1",
|
||||
"method": "POST",
|
||||
"postData": {
|
||||
"mimeType": "text/plain",
|
||||
"params": [],
|
||||
"text": "{\"name\":\"John Doe\",\"email\":\"john@example.com\"}"
|
||||
},
|
||||
"queryString": [],
|
||||
"url": "http://localhost:3001/d4dbdb73-e3fd-4cb8-8fd0-a8540f38267d"
|
||||
},
|
||||
"response": {
|
||||
"bodySize": 55,
|
||||
"content": {
|
||||
"mimeType": "application/json; charset=utf-8",
|
||||
"size": 55,
|
||||
"text": "[{\"id\":1,\"name\":\"John Doe\",\"email\":\"john@example.com\"}]"
|
||||
},
|
||||
"cookies": [],
|
||||
"headers": [
|
||||
{
|
||||
"name": "transfer-encoding",
|
||||
"value": "chunked"
|
||||
},
|
||||
{
|
||||
"name": "date",
|
||||
"value": "Thu, 04 Jul 2024 20:59:40 GMT"
|
||||
},
|
||||
{
|
||||
"name": "server",
|
||||
"value": "postgrest/12.0.3 (6a506d1)"
|
||||
},
|
||||
{
|
||||
"name": "content-range",
|
||||
"value": "*/1"
|
||||
},
|
||||
{
|
||||
"name": "preference-applied",
|
||||
"value": "return=representation, count=exact"
|
||||
},
|
||||
{
|
||||
"name": "content-type",
|
||||
"value": "application/json; charset=utf-8"
|
||||
}
|
||||
],
|
||||
"headersSize": 226,
|
||||
"httpVersion": "HTTP/1.1",
|
||||
"redirectURL": "",
|
||||
"status": 201,
|
||||
"statusText": "Created"
|
||||
},
|
||||
"startedDateTime": "2024-07-04T20:59:40.142Z",
|
||||
"time": 34,
|
||||
"timings": {
|
||||
"blocked": -1,
|
||||
"connect": -1,
|
||||
"dns": -1,
|
||||
"receive": 0,
|
||||
"send": 0,
|
||||
"ssl": -1,
|
||||
"wait": 34
|
||||
}
|
||||
},
|
||||
{
|
||||
"_id": "025d1c262b73f8739031fa6b0b522c67",
|
||||
"_order": 0,
|
||||
"cache": {},
|
||||
"request": {
|
||||
"bodySize": 0,
|
||||
"cookies": [],
|
||||
"headers": [
|
||||
{
|
||||
"name": "user-agent",
|
||||
"value": "got (https://github.com/sindresorhus/got)"
|
||||
},
|
||||
{
|
||||
"name": "data-query-id",
|
||||
"value": "query-id"
|
||||
},
|
||||
{
|
||||
"name": "tj-workspace-id",
|
||||
"value": "d029ddeb-e4c5-46ed-aa23-bbd58fbb445b"
|
||||
},
|
||||
{
|
||||
"name": "tableinfo",
|
||||
"value": {
|
||||
"d4dbdb73-e3fd-4cb8-8fd0-a8540f38267d": "users"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "authorization",
|
||||
"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoicG9zdGdyZXMiLCJpYXQiOjE3MjAxMjY3ODAsImV4cCI6MTcyMDEyNjg0MH0.oSaB7oSG8LYnxHs_CbaiBd7ZZXasu--TZuqo9nwohZY"
|
||||
},
|
||||
{
|
||||
"name": "prefer",
|
||||
"value": "count=exact, return=representation"
|
||||
},
|
||||
{
|
||||
"name": "accept",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"name": "accept-encoding",
|
||||
"value": "gzip, deflate, br"
|
||||
},
|
||||
{
|
||||
"name": "host",
|
||||
"value": "localhost:3001"
|
||||
}
|
||||
],
|
||||
"headersSize": 581,
|
||||
"httpVersion": "HTTP/1.1",
|
||||
"method": "DELETE",
|
||||
"queryString": [
|
||||
{
|
||||
"name": "name",
|
||||
"value": "eq.John Doe"
|
||||
},
|
||||
{
|
||||
"name": "limit",
|
||||
"value": "1"
|
||||
},
|
||||
{
|
||||
"name": "order",
|
||||
"value": "id"
|
||||
}
|
||||
],
|
||||
"url": "http://localhost:3001/d4dbdb73-e3fd-4cb8-8fd0-a8540f38267d?name=eq.John%20Doe&limit=1&order=id"
|
||||
},
|
||||
"response": {
|
||||
"bodySize": 55,
|
||||
"content": {
|
||||
"mimeType": "application/json; charset=utf-8",
|
||||
"size": 55,
|
||||
"text": "[{\"id\":1,\"name\":\"John Doe\",\"email\":\"john@example.com\"}]"
|
||||
},
|
||||
"cookies": [],
|
||||
"headers": [
|
||||
{
|
||||
"name": "transfer-encoding",
|
||||
"value": "chunked"
|
||||
},
|
||||
{
|
||||
"name": "date",
|
||||
"value": "Thu, 04 Jul 2024 20:59:40 GMT"
|
||||
},
|
||||
{
|
||||
"name": "server",
|
||||
"value": "postgrest/12.0.3 (6a506d1)"
|
||||
},
|
||||
{
|
||||
"name": "content-range",
|
||||
"value": "*/1"
|
||||
},
|
||||
{
|
||||
"name": "preference-applied",
|
||||
"value": "return=representation, count=exact"
|
||||
},
|
||||
{
|
||||
"name": "content-type",
|
||||
"value": "application/json; charset=utf-8"
|
||||
}
|
||||
],
|
||||
"headersSize": 226,
|
||||
"httpVersion": "HTTP/1.1",
|
||||
"redirectURL": "",
|
||||
"status": 200,
|
||||
"statusText": "OK"
|
||||
},
|
||||
"startedDateTime": "2024-07-04T20:59:40.235Z",
|
||||
"time": 25,
|
||||
"timings": {
|
||||
"blocked": -1,
|
||||
"connect": -1,
|
||||
"dns": -1,
|
||||
"receive": 0,
|
||||
"send": 0,
|
||||
"ssl": -1,
|
||||
"wait": 25
|
||||
}
|
||||
}
|
||||
],
|
||||
"pages": [],
|
||||
"version": "1.2"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,242 @@
|
|||
{
|
||||
"log": {
|
||||
"_recordingName": "TooljetDbOperationsService/.joinTables/should join tables and verify the result",
|
||||
"creator": {
|
||||
"comment": "persister:fs",
|
||||
"name": "Polly.JS",
|
||||
"version": "6.0.6"
|
||||
},
|
||||
"entries": [
|
||||
{
|
||||
"_id": "197a6feb7e633d071ca275fc502d5b6f",
|
||||
"_order": 0,
|
||||
"cache": {},
|
||||
"request": {
|
||||
"bodySize": 46,
|
||||
"cookies": [],
|
||||
"headers": [
|
||||
{
|
||||
"name": "user-agent",
|
||||
"value": "got (https://github.com/sindresorhus/got)"
|
||||
},
|
||||
{
|
||||
"name": "data-query-id",
|
||||
"value": "query-id"
|
||||
},
|
||||
{
|
||||
"name": "tj-workspace-id",
|
||||
"value": "14ff6b2c-18b9-45d5-8098-cbb2d3faa8d8"
|
||||
},
|
||||
{
|
||||
"name": "tableinfo",
|
||||
"value": {
|
||||
"0d81d897-f3f7-4616-afcb-a7873a6fdbd0": "users"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "authorization",
|
||||
"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoicG9zdGdyZXMiLCJpYXQiOjE3MjAxMjY3ODcsImV4cCI6MTcyMDEyNjg0N30.zMLW2N6-FhzS7zgwBgQM6fAPjI4rxqfAhum_izOLpDA"
|
||||
},
|
||||
{
|
||||
"name": "prefer",
|
||||
"value": "count=exact, return=representation"
|
||||
},
|
||||
{
|
||||
"name": "accept",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"name": "content-length",
|
||||
"value": "46"
|
||||
},
|
||||
{
|
||||
"name": "accept-encoding",
|
||||
"value": "gzip, deflate, br"
|
||||
},
|
||||
{
|
||||
"name": "host",
|
||||
"value": "localhost:3001"
|
||||
}
|
||||
],
|
||||
"headersSize": 563,
|
||||
"httpVersion": "HTTP/1.1",
|
||||
"method": "POST",
|
||||
"postData": {
|
||||
"mimeType": "text/plain",
|
||||
"params": [],
|
||||
"text": "{\"name\":\"John Doe\",\"email\":\"john@example.com\"}"
|
||||
},
|
||||
"queryString": [],
|
||||
"url": "http://localhost:3001/0d81d897-f3f7-4616-afcb-a7873a6fdbd0"
|
||||
},
|
||||
"response": {
|
||||
"bodySize": 55,
|
||||
"content": {
|
||||
"mimeType": "application/json; charset=utf-8",
|
||||
"size": 55,
|
||||
"text": "[{\"id\":1,\"name\":\"John Doe\",\"email\":\"john@example.com\"}]"
|
||||
},
|
||||
"cookies": [],
|
||||
"headers": [
|
||||
{
|
||||
"name": "transfer-encoding",
|
||||
"value": "chunked"
|
||||
},
|
||||
{
|
||||
"name": "date",
|
||||
"value": "Thu, 04 Jul 2024 20:59:47 GMT"
|
||||
},
|
||||
{
|
||||
"name": "server",
|
||||
"value": "postgrest/12.0.3 (6a506d1)"
|
||||
},
|
||||
{
|
||||
"name": "content-range",
|
||||
"value": "*/1"
|
||||
},
|
||||
{
|
||||
"name": "preference-applied",
|
||||
"value": "return=representation, count=exact"
|
||||
},
|
||||
{
|
||||
"name": "content-type",
|
||||
"value": "application/json; charset=utf-8"
|
||||
}
|
||||
],
|
||||
"headersSize": 226,
|
||||
"httpVersion": "HTTP/1.1",
|
||||
"redirectURL": "",
|
||||
"status": 201,
|
||||
"statusText": "Created"
|
||||
},
|
||||
"startedDateTime": "2024-07-04T20:59:47.938Z",
|
||||
"time": 34,
|
||||
"timings": {
|
||||
"blocked": -1,
|
||||
"connect": -1,
|
||||
"dns": -1,
|
||||
"receive": 0,
|
||||
"send": 0,
|
||||
"ssl": -1,
|
||||
"wait": 34
|
||||
}
|
||||
},
|
||||
{
|
||||
"_id": "11ab62f4916d91ebf3464b4d366801f1",
|
||||
"_order": 0,
|
||||
"cache": {},
|
||||
"request": {
|
||||
"bodySize": 27,
|
||||
"cookies": [],
|
||||
"headers": [
|
||||
{
|
||||
"name": "user-agent",
|
||||
"value": "got (https://github.com/sindresorhus/got)"
|
||||
},
|
||||
{
|
||||
"name": "data-query-id",
|
||||
"value": "query-id"
|
||||
},
|
||||
{
|
||||
"name": "tj-workspace-id",
|
||||
"value": "14ff6b2c-18b9-45d5-8098-cbb2d3faa8d8"
|
||||
},
|
||||
{
|
||||
"name": "tableinfo",
|
||||
"value": {
|
||||
"b8e3bafa-fa05-4bbc-8e3f-5af967405d30": "orders"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "authorization",
|
||||
"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoicG9zdGdyZXMiLCJpYXQiOjE3MjAxMjY3ODcsImV4cCI6MTcyMDEyNjg0N30.zMLW2N6-FhzS7zgwBgQM6fAPjI4rxqfAhum_izOLpDA"
|
||||
},
|
||||
{
|
||||
"name": "prefer",
|
||||
"value": "count=exact, return=representation"
|
||||
},
|
||||
{
|
||||
"name": "accept",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"name": "content-length",
|
||||
"value": "27"
|
||||
},
|
||||
{
|
||||
"name": "accept-encoding",
|
||||
"value": "gzip, deflate, br"
|
||||
},
|
||||
{
|
||||
"name": "host",
|
||||
"value": "localhost:3001"
|
||||
}
|
||||
],
|
||||
"headersSize": 563,
|
||||
"httpVersion": "HTTP/1.1",
|
||||
"method": "POST",
|
||||
"postData": {
|
||||
"mimeType": "text/plain",
|
||||
"params": [],
|
||||
"text": "{\"user_id\":1,\"total\":100.5}"
|
||||
},
|
||||
"queryString": [],
|
||||
"url": "http://localhost:3001/b8e3bafa-fa05-4bbc-8e3f-5af967405d30"
|
||||
},
|
||||
"response": {
|
||||
"bodySize": 36,
|
||||
"content": {
|
||||
"mimeType": "application/json; charset=utf-8",
|
||||
"size": 36,
|
||||
"text": "[{\"id\":1,\"user_id\":1,\"total\":100.5}]"
|
||||
},
|
||||
"cookies": [],
|
||||
"headers": [
|
||||
{
|
||||
"name": "transfer-encoding",
|
||||
"value": "chunked"
|
||||
},
|
||||
{
|
||||
"name": "date",
|
||||
"value": "Thu, 04 Jul 2024 20:59:47 GMT"
|
||||
},
|
||||
{
|
||||
"name": "server",
|
||||
"value": "postgrest/12.0.3 (6a506d1)"
|
||||
},
|
||||
{
|
||||
"name": "content-range",
|
||||
"value": "*/1"
|
||||
},
|
||||
{
|
||||
"name": "preference-applied",
|
||||
"value": "return=representation, count=exact"
|
||||
},
|
||||
{
|
||||
"name": "content-type",
|
||||
"value": "application/json; charset=utf-8"
|
||||
}
|
||||
],
|
||||
"headersSize": 226,
|
||||
"httpVersion": "HTTP/1.1",
|
||||
"redirectURL": "",
|
||||
"status": 201,
|
||||
"statusText": "Created"
|
||||
},
|
||||
"startedDateTime": "2024-07-04T20:59:47.999Z",
|
||||
"time": 14,
|
||||
"timings": {
|
||||
"blocked": -1,
|
||||
"connect": -1,
|
||||
"dns": -1,
|
||||
"receive": 0,
|
||||
"send": 0,
|
||||
"ssl": -1,
|
||||
"wait": 14
|
||||
}
|
||||
}
|
||||
],
|
||||
"pages": [],
|
||||
"version": "1.2"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,237 @@
|
|||
{
|
||||
"log": {
|
||||
"_recordingName": "TooljetDbOperationsService/.listRows/should list rows correctly",
|
||||
"creator": {
|
||||
"comment": "persister:fs",
|
||||
"name": "Polly.JS",
|
||||
"version": "6.0.6"
|
||||
},
|
||||
"entries": [
|
||||
{
|
||||
"_id": "197a6feb7e633d071ca275fc502d5b6f",
|
||||
"_order": 0,
|
||||
"cache": {},
|
||||
"request": {
|
||||
"bodySize": 46,
|
||||
"cookies": [],
|
||||
"headers": [
|
||||
{
|
||||
"name": "user-agent",
|
||||
"value": "got (https://github.com/sindresorhus/got)"
|
||||
},
|
||||
{
|
||||
"name": "data-query-id",
|
||||
"value": "query-id"
|
||||
},
|
||||
{
|
||||
"name": "tj-workspace-id",
|
||||
"value": "08eae723-42ac-4fd5-a7dc-3db4f0a1ba9c"
|
||||
},
|
||||
{
|
||||
"name": "tableinfo",
|
||||
"value": {
|
||||
"291dda09-4ca4-48cd-b62c-cf0e325c65ae": "users"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "authorization",
|
||||
"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoicG9zdGdyZXMiLCJpYXQiOjE3MjAxMjY3NjMsImV4cCI6MTcyMDEyNjgyM30.dlBsKWsPZMxNr3fGSL0-bi8x-viUGYpTScCU0YS8CQg"
|
||||
},
|
||||
{
|
||||
"name": "prefer",
|
||||
"value": "count=exact, return=representation"
|
||||
},
|
||||
{
|
||||
"name": "accept",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"name": "content-length",
|
||||
"value": "46"
|
||||
},
|
||||
{
|
||||
"name": "accept-encoding",
|
||||
"value": "gzip, deflate, br"
|
||||
},
|
||||
{
|
||||
"name": "host",
|
||||
"value": "localhost:3001"
|
||||
}
|
||||
],
|
||||
"headersSize": 563,
|
||||
"httpVersion": "HTTP/1.1",
|
||||
"method": "POST",
|
||||
"postData": {
|
||||
"mimeType": "text/plain",
|
||||
"params": [],
|
||||
"text": "{\"name\":\"John Doe\",\"email\":\"john@example.com\"}"
|
||||
},
|
||||
"queryString": [],
|
||||
"url": "http://localhost:3001/291dda09-4ca4-48cd-b62c-cf0e325c65ae"
|
||||
},
|
||||
"response": {
|
||||
"bodySize": 55,
|
||||
"content": {
|
||||
"mimeType": "application/json; charset=utf-8",
|
||||
"size": 55,
|
||||
"text": "[{\"id\":1,\"name\":\"John Doe\",\"email\":\"john@example.com\"}]"
|
||||
},
|
||||
"cookies": [],
|
||||
"headers": [
|
||||
{
|
||||
"name": "transfer-encoding",
|
||||
"value": "chunked"
|
||||
},
|
||||
{
|
||||
"name": "date",
|
||||
"value": "Thu, 04 Jul 2024 20:59:23 GMT"
|
||||
},
|
||||
{
|
||||
"name": "server",
|
||||
"value": "postgrest/12.0.3 (6a506d1)"
|
||||
},
|
||||
{
|
||||
"name": "content-range",
|
||||
"value": "*/1"
|
||||
},
|
||||
{
|
||||
"name": "preference-applied",
|
||||
"value": "return=representation, count=exact"
|
||||
},
|
||||
{
|
||||
"name": "content-type",
|
||||
"value": "application/json; charset=utf-8"
|
||||
}
|
||||
],
|
||||
"headersSize": 226,
|
||||
"httpVersion": "HTTP/1.1",
|
||||
"redirectURL": "",
|
||||
"status": 201,
|
||||
"statusText": "Created"
|
||||
},
|
||||
"startedDateTime": "2024-07-04T20:59:23.808Z",
|
||||
"time": 59,
|
||||
"timings": {
|
||||
"blocked": -1,
|
||||
"connect": -1,
|
||||
"dns": -1,
|
||||
"receive": 0,
|
||||
"send": 0,
|
||||
"ssl": -1,
|
||||
"wait": 59
|
||||
}
|
||||
},
|
||||
{
|
||||
"_id": "a201948f8b1cb6b14aa3987eeb19b1f5",
|
||||
"_order": 0,
|
||||
"cache": {},
|
||||
"request": {
|
||||
"bodySize": 0,
|
||||
"cookies": [],
|
||||
"headers": [
|
||||
{
|
||||
"name": "user-agent",
|
||||
"value": "got (https://github.com/sindresorhus/got)"
|
||||
},
|
||||
{
|
||||
"name": "data-query-id",
|
||||
"value": "query-id"
|
||||
},
|
||||
{
|
||||
"name": "tj-workspace-id",
|
||||
"value": "08eae723-42ac-4fd5-a7dc-3db4f0a1ba9c"
|
||||
},
|
||||
{
|
||||
"name": "tableinfo",
|
||||
"value": {
|
||||
"291dda09-4ca4-48cd-b62c-cf0e325c65ae": "users"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "authorization",
|
||||
"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoicG9zdGdyZXMiLCJpYXQiOjE3MjAxMjY3NjMsImV4cCI6MTcyMDEyNjgyM30.dlBsKWsPZMxNr3fGSL0-bi8x-viUGYpTScCU0YS8CQg"
|
||||
},
|
||||
{
|
||||
"name": "prefer",
|
||||
"value": "count=exact, return=representation"
|
||||
},
|
||||
{
|
||||
"name": "accept",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"name": "accept-encoding",
|
||||
"value": "gzip, deflate, br"
|
||||
},
|
||||
{
|
||||
"name": "host",
|
||||
"value": "localhost:3001"
|
||||
}
|
||||
],
|
||||
"headersSize": 542,
|
||||
"httpVersion": "HTTP/1.1",
|
||||
"method": "GET",
|
||||
"queryString": [],
|
||||
"url": "http://localhost:3001/291dda09-4ca4-48cd-b62c-cf0e325c65ae"
|
||||
},
|
||||
"response": {
|
||||
"bodySize": 55,
|
||||
"content": {
|
||||
"mimeType": "application/json; charset=utf-8",
|
||||
"size": 55,
|
||||
"text": "[{\"id\":1,\"name\":\"John Doe\",\"email\":\"john@example.com\"}]"
|
||||
},
|
||||
"cookies": [],
|
||||
"headers": [
|
||||
{
|
||||
"name": "transfer-encoding",
|
||||
"value": "chunked"
|
||||
},
|
||||
{
|
||||
"name": "date",
|
||||
"value": "Thu, 04 Jul 2024 20:59:23 GMT"
|
||||
},
|
||||
{
|
||||
"name": "server",
|
||||
"value": "postgrest/12.0.3 (6a506d1)"
|
||||
},
|
||||
{
|
||||
"name": "content-range",
|
||||
"value": "0-0/1"
|
||||
},
|
||||
{
|
||||
"name": "content-location",
|
||||
"value": "/291dda09-4ca4-48cd-b62c-cf0e325c65ae"
|
||||
},
|
||||
{
|
||||
"name": "content-type",
|
||||
"value": "application/json; charset=utf-8"
|
||||
},
|
||||
{
|
||||
"name": "preference-applied",
|
||||
"value": "count=exact"
|
||||
}
|
||||
],
|
||||
"headersSize": 262,
|
||||
"httpVersion": "HTTP/1.1",
|
||||
"redirectURL": "",
|
||||
"status": 200,
|
||||
"statusText": "OK"
|
||||
},
|
||||
"startedDateTime": "2024-07-04T20:59:23.901Z",
|
||||
"time": 19,
|
||||
"timings": {
|
||||
"blocked": -1,
|
||||
"connect": -1,
|
||||
"dns": -1,
|
||||
"receive": 0,
|
||||
"send": 0,
|
||||
"ssl": -1,
|
||||
"wait": 19
|
||||
}
|
||||
}
|
||||
],
|
||||
"pages": [],
|
||||
"version": "1.2"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
{
|
||||
"log": {
|
||||
"_recordingName": "TooljetDbOperationsService",
|
||||
"creator": {
|
||||
"comment": "persister:fs",
|
||||
"name": "Polly.JS",
|
||||
"version": "6.0.6"
|
||||
},
|
||||
"entries": [
|
||||
{
|
||||
"_id": "bed7fb75983310f155c3e3b6b1ccc6d8",
|
||||
"_order": 0,
|
||||
"cache": {},
|
||||
"request": {
|
||||
"bodySize": 46,
|
||||
"cookies": [],
|
||||
"headers": [
|
||||
{
|
||||
"name": "user-agent",
|
||||
"value": "got (https://github.com/sindresorhus/got)"
|
||||
},
|
||||
{
|
||||
"name": "data-query-id",
|
||||
"value": "query-id"
|
||||
},
|
||||
{
|
||||
"name": "tj-workspace-id",
|
||||
"value": "5e724498-ae98-42bc-bb3d-b7d255b1d2c5"
|
||||
},
|
||||
{
|
||||
"name": "tableinfo",
|
||||
"value": {
|
||||
"96732d2a-9d32-409e-b34f-4cf6a99ef342": "users"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "authorization",
|
||||
"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoicG9zdGdyZXMiLCJpYXQiOjE3MjAxMTY0MDAsImV4cCI6MTcyMDExNjQ2MH0.nQu4YxlacdZMYi0ssTe7MIWWU61rQNKe7xZc0GeGTXQ"
|
||||
},
|
||||
{
|
||||
"name": "prefer",
|
||||
"value": "count=exact, return=representation"
|
||||
},
|
||||
{
|
||||
"name": "accept",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"name": "content-length",
|
||||
"value": "46"
|
||||
},
|
||||
{
|
||||
"name": "accept-encoding",
|
||||
"value": "gzip, deflate, br"
|
||||
},
|
||||
{
|
||||
"name": "host",
|
||||
"value": "localhost:3001"
|
||||
}
|
||||
],
|
||||
"headersSize": 563,
|
||||
"httpVersion": "HTTP/1.1",
|
||||
"method": "POST",
|
||||
"postData": {
|
||||
"mimeType": "text/plain",
|
||||
"params": [],
|
||||
"text": "{\"name\":\"John Doe\",\"email\":\"john@example.com\"}"
|
||||
},
|
||||
"queryString": [],
|
||||
"url": "http://localhost:3001/96732d2a-9d32-409e-b34f-4cf6a99ef342"
|
||||
},
|
||||
"response": {
|
||||
"bodySize": 2,
|
||||
"content": {
|
||||
"mimeType": "application/json; charset=utf-8",
|
||||
"size": 2,
|
||||
"text": "{}"
|
||||
},
|
||||
"cookies": [],
|
||||
"headers": [
|
||||
{
|
||||
"name": "transfer-encoding",
|
||||
"value": "chunked"
|
||||
},
|
||||
{
|
||||
"name": "date",
|
||||
"value": "Thu, 04 Jul 2024 18:06:40 GMT"
|
||||
},
|
||||
{
|
||||
"name": "server",
|
||||
"value": "postgrest/12.0.3 (6a506d1)"
|
||||
},
|
||||
{
|
||||
"name": "content-type",
|
||||
"value": "application/json; charset=utf-8"
|
||||
}
|
||||
],
|
||||
"headersSize": 150,
|
||||
"httpVersion": "HTTP/1.1",
|
||||
"redirectURL": "",
|
||||
"status": 404,
|
||||
"statusText": "Not Found"
|
||||
},
|
||||
"startedDateTime": "2024-07-04T18:06:40.291Z",
|
||||
"time": 13,
|
||||
"timings": {
|
||||
"blocked": -1,
|
||||
"connect": -1,
|
||||
"dns": -1,
|
||||
"receive": 0,
|
||||
"send": 0,
|
||||
"ssl": -1,
|
||||
"wait": 13
|
||||
}
|
||||
}
|
||||
],
|
||||
"pages": [],
|
||||
"version": "1.2"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,360 @@
|
|||
{
|
||||
"log": {
|
||||
"_recordingName": "TooljetDbOperationsService/.updateRows/should update rows and verify the changes",
|
||||
"creator": {
|
||||
"comment": "persister:fs",
|
||||
"name": "Polly.JS",
|
||||
"version": "6.0.6"
|
||||
},
|
||||
"entries": [
|
||||
{
|
||||
"_id": "197a6feb7e633d071ca275fc502d5b6f",
|
||||
"_order": 0,
|
||||
"cache": {},
|
||||
"request": {
|
||||
"bodySize": 46,
|
||||
"cookies": [],
|
||||
"headers": [
|
||||
{
|
||||
"name": "user-agent",
|
||||
"value": "got (https://github.com/sindresorhus/got)"
|
||||
},
|
||||
{
|
||||
"name": "data-query-id",
|
||||
"value": "query-id"
|
||||
},
|
||||
{
|
||||
"name": "tj-workspace-id",
|
||||
"value": "577ed2e5-3243-432a-8084-c90bf85a6afc"
|
||||
},
|
||||
{
|
||||
"name": "tableinfo",
|
||||
"value": {
|
||||
"e3f89568-858d-4d4b-a443-d863ad392e7f": "users"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "authorization",
|
||||
"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoicG9zdGdyZXMiLCJpYXQiOjE3MjAxMjY3NzEsImV4cCI6MTcyMDEyNjgzMX0.-LwnMhI-S-rWKIFXWAqURKY7qGVsMTV5eAoP6vLe9_k"
|
||||
},
|
||||
{
|
||||
"name": "prefer",
|
||||
"value": "count=exact, return=representation"
|
||||
},
|
||||
{
|
||||
"name": "accept",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"name": "content-length",
|
||||
"value": "46"
|
||||
},
|
||||
{
|
||||
"name": "accept-encoding",
|
||||
"value": "gzip, deflate, br"
|
||||
},
|
||||
{
|
||||
"name": "host",
|
||||
"value": "localhost:3001"
|
||||
}
|
||||
],
|
||||
"headersSize": 563,
|
||||
"httpVersion": "HTTP/1.1",
|
||||
"method": "POST",
|
||||
"postData": {
|
||||
"mimeType": "text/plain",
|
||||
"params": [],
|
||||
"text": "{\"name\":\"John Doe\",\"email\":\"john@example.com\"}"
|
||||
},
|
||||
"queryString": [],
|
||||
"url": "http://localhost:3001/e3f89568-858d-4d4b-a443-d863ad392e7f"
|
||||
},
|
||||
"response": {
|
||||
"bodySize": 55,
|
||||
"content": {
|
||||
"mimeType": "application/json; charset=utf-8",
|
||||
"size": 55,
|
||||
"text": "[{\"id\":1,\"name\":\"John Doe\",\"email\":\"john@example.com\"}]"
|
||||
},
|
||||
"cookies": [],
|
||||
"headers": [
|
||||
{
|
||||
"name": "transfer-encoding",
|
||||
"value": "chunked"
|
||||
},
|
||||
{
|
||||
"name": "date",
|
||||
"value": "Thu, 04 Jul 2024 20:59:31 GMT"
|
||||
},
|
||||
{
|
||||
"name": "server",
|
||||
"value": "postgrest/12.0.3 (6a506d1)"
|
||||
},
|
||||
{
|
||||
"name": "content-range",
|
||||
"value": "*/1"
|
||||
},
|
||||
{
|
||||
"name": "preference-applied",
|
||||
"value": "return=representation, count=exact"
|
||||
},
|
||||
{
|
||||
"name": "content-type",
|
||||
"value": "application/json; charset=utf-8"
|
||||
}
|
||||
],
|
||||
"headersSize": 226,
|
||||
"httpVersion": "HTTP/1.1",
|
||||
"redirectURL": "",
|
||||
"status": 201,
|
||||
"statusText": "Created"
|
||||
},
|
||||
"startedDateTime": "2024-07-04T20:59:31.529Z",
|
||||
"time": 25,
|
||||
"timings": {
|
||||
"blocked": -1,
|
||||
"connect": -1,
|
||||
"dns": -1,
|
||||
"receive": 0,
|
||||
"send": 0,
|
||||
"ssl": -1,
|
||||
"wait": 25
|
||||
}
|
||||
},
|
||||
{
|
||||
"_id": "e671061f70ab82499db975c0d090cc9a",
|
||||
"_order": 0,
|
||||
"cache": {},
|
||||
"request": {
|
||||
"bodySize": 19,
|
||||
"cookies": [],
|
||||
"headers": [
|
||||
{
|
||||
"name": "user-agent",
|
||||
"value": "got (https://github.com/sindresorhus/got)"
|
||||
},
|
||||
{
|
||||
"name": "data-query-id",
|
||||
"value": "query-id"
|
||||
},
|
||||
{
|
||||
"name": "tj-workspace-id",
|
||||
"value": "577ed2e5-3243-432a-8084-c90bf85a6afc"
|
||||
},
|
||||
{
|
||||
"name": "tableinfo",
|
||||
"value": {
|
||||
"e3f89568-858d-4d4b-a443-d863ad392e7f": "users"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "authorization",
|
||||
"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoicG9zdGdyZXMiLCJpYXQiOjE3MjAxMjY3NzEsImV4cCI6MTcyMDEyNjgzMX0.-LwnMhI-S-rWKIFXWAqURKY7qGVsMTV5eAoP6vLe9_k"
|
||||
},
|
||||
{
|
||||
"name": "prefer",
|
||||
"value": "count=exact, return=representation"
|
||||
},
|
||||
{
|
||||
"name": "accept",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"name": "content-length",
|
||||
"value": "19"
|
||||
},
|
||||
{
|
||||
"name": "accept-encoding",
|
||||
"value": "gzip, deflate, br"
|
||||
},
|
||||
{
|
||||
"name": "host",
|
||||
"value": "localhost:3001"
|
||||
}
|
||||
],
|
||||
"headersSize": 592,
|
||||
"httpVersion": "HTTP/1.1",
|
||||
"method": "PATCH",
|
||||
"postData": {
|
||||
"mimeType": "text/plain",
|
||||
"params": [],
|
||||
"text": "{\"name\":\"Jane Doe\"}"
|
||||
},
|
||||
"queryString": [
|
||||
{
|
||||
"name": "name",
|
||||
"value": "eq.John Doe"
|
||||
},
|
||||
{
|
||||
"name": "order",
|
||||
"value": "id"
|
||||
}
|
||||
],
|
||||
"url": "http://localhost:3001/e3f89568-858d-4d4b-a443-d863ad392e7f?name=eq.John%20Doe&order=id"
|
||||
},
|
||||
"response": {
|
||||
"bodySize": 55,
|
||||
"content": {
|
||||
"mimeType": "application/json; charset=utf-8",
|
||||
"size": 55,
|
||||
"text": "[{\"id\":1,\"name\":\"Jane Doe\",\"email\":\"john@example.com\"}]"
|
||||
},
|
||||
"cookies": [],
|
||||
"headers": [
|
||||
{
|
||||
"name": "transfer-encoding",
|
||||
"value": "chunked"
|
||||
},
|
||||
{
|
||||
"name": "date",
|
||||
"value": "Thu, 04 Jul 2024 20:59:31 GMT"
|
||||
},
|
||||
{
|
||||
"name": "server",
|
||||
"value": "postgrest/12.0.3 (6a506d1)"
|
||||
},
|
||||
{
|
||||
"name": "content-range",
|
||||
"value": "0-0/1"
|
||||
},
|
||||
{
|
||||
"name": "preference-applied",
|
||||
"value": "return=representation, count=exact"
|
||||
},
|
||||
{
|
||||
"name": "content-type",
|
||||
"value": "application/json; charset=utf-8"
|
||||
}
|
||||
],
|
||||
"headersSize": 228,
|
||||
"httpVersion": "HTTP/1.1",
|
||||
"redirectURL": "",
|
||||
"status": 200,
|
||||
"statusText": "OK"
|
||||
},
|
||||
"startedDateTime": "2024-07-04T20:59:31.599Z",
|
||||
"time": 30,
|
||||
"timings": {
|
||||
"blocked": -1,
|
||||
"connect": -1,
|
||||
"dns": -1,
|
||||
"receive": 0,
|
||||
"send": 0,
|
||||
"ssl": -1,
|
||||
"wait": 30
|
||||
}
|
||||
},
|
||||
{
|
||||
"_id": "a201948f8b1cb6b14aa3987eeb19b1f5",
|
||||
"_order": 0,
|
||||
"cache": {},
|
||||
"request": {
|
||||
"bodySize": 0,
|
||||
"cookies": [],
|
||||
"headers": [
|
||||
{
|
||||
"name": "user-agent",
|
||||
"value": "got (https://github.com/sindresorhus/got)"
|
||||
},
|
||||
{
|
||||
"name": "data-query-id",
|
||||
"value": "query-id"
|
||||
},
|
||||
{
|
||||
"name": "tj-workspace-id",
|
||||
"value": "577ed2e5-3243-432a-8084-c90bf85a6afc"
|
||||
},
|
||||
{
|
||||
"name": "tableinfo",
|
||||
"value": {
|
||||
"e3f89568-858d-4d4b-a443-d863ad392e7f": "users"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "authorization",
|
||||
"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoicG9zdGdyZXMiLCJpYXQiOjE3MjAxMjY3NzEsImV4cCI6MTcyMDEyNjgzMX0.-LwnMhI-S-rWKIFXWAqURKY7qGVsMTV5eAoP6vLe9_k"
|
||||
},
|
||||
{
|
||||
"name": "prefer",
|
||||
"value": "count=exact, return=representation"
|
||||
},
|
||||
{
|
||||
"name": "accept",
|
||||
"value": "application/json"
|
||||
},
|
||||
{
|
||||
"name": "accept-encoding",
|
||||
"value": "gzip, deflate, br"
|
||||
},
|
||||
{
|
||||
"name": "host",
|
||||
"value": "localhost:3001"
|
||||
}
|
||||
],
|
||||
"headersSize": 542,
|
||||
"httpVersion": "HTTP/1.1",
|
||||
"method": "GET",
|
||||
"queryString": [],
|
||||
"url": "http://localhost:3001/e3f89568-858d-4d4b-a443-d863ad392e7f"
|
||||
},
|
||||
"response": {
|
||||
"bodySize": 55,
|
||||
"content": {
|
||||
"mimeType": "application/json; charset=utf-8",
|
||||
"size": 55,
|
||||
"text": "[{\"id\":1,\"name\":\"Jane Doe\",\"email\":\"john@example.com\"}]"
|
||||
},
|
||||
"cookies": [],
|
||||
"headers": [
|
||||
{
|
||||
"name": "transfer-encoding",
|
||||
"value": "chunked"
|
||||
},
|
||||
{
|
||||
"name": "date",
|
||||
"value": "Thu, 04 Jul 2024 20:59:31 GMT"
|
||||
},
|
||||
{
|
||||
"name": "server",
|
||||
"value": "postgrest/12.0.3 (6a506d1)"
|
||||
},
|
||||
{
|
||||
"name": "content-range",
|
||||
"value": "0-0/1"
|
||||
},
|
||||
{
|
||||
"name": "content-location",
|
||||
"value": "/e3f89568-858d-4d4b-a443-d863ad392e7f"
|
||||
},
|
||||
{
|
||||
"name": "content-type",
|
||||
"value": "application/json; charset=utf-8"
|
||||
},
|
||||
{
|
||||
"name": "preference-applied",
|
||||
"value": "count=exact"
|
||||
}
|
||||
],
|
||||
"headersSize": 262,
|
||||
"httpVersion": "HTTP/1.1",
|
||||
"redirectURL": "",
|
||||
"status": 200,
|
||||
"statusText": "OK"
|
||||
},
|
||||
"startedDateTime": "2024-07-04T20:59:31.695Z",
|
||||
"time": 25,
|
||||
"timings": {
|
||||
"blocked": -1,
|
||||
"connect": -1,
|
||||
"dns": -1,
|
||||
"receive": 0,
|
||||
"send": 0,
|
||||
"ssl": -1,
|
||||
"wait": 25
|
||||
}
|
||||
}
|
||||
],
|
||||
"pages": [],
|
||||
"version": "1.2"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"moduleFileExtensions": ["js", "json", "ts"],
|
||||
"moduleFileExtensions": ["js", "json", "ts", "node"],
|
||||
"rootDir": ".",
|
||||
"testEnvironment": "node",
|
||||
"testRegex": ".e2e-spec.ts$",
|
||||
|
|
@ -11,6 +11,7 @@
|
|||
"@plugins/(.*)": "<rootDir>/../plugins/$1",
|
||||
"@dto/(.*)": "<rootDir>/../src/dto/$1",
|
||||
"@services/(.*)": "<rootDir>/../src/services/$1",
|
||||
"@entities/(.*)": "<rootDir>/src/entities/$1",
|
||||
"@controllers/(.*)": "<rootDir>/../src/controllers/$1",
|
||||
"@ee/(.*)": "<rootDir>/../ee/$1"
|
||||
}
|
||||
|
|
|
|||
377
server/test/services/tooljet_db_operations.service.spec.ts
Normal file
377
server/test/services/tooljet_db_operations.service.spec.ts
Normal file
|
|
@ -0,0 +1,377 @@
|
|||
/** @jest-environment setup-polly-jest/jest-environment-node */
|
||||
|
||||
import { INestApplication } from '@nestjs/common';
|
||||
import { getManager, getConnection, EntityManager } from 'typeorm';
|
||||
import { TooljetDbOperationsService } from '../../src/services/tooljet_db_operations.service';
|
||||
import { TooljetDbService } from '../../src/services/tooljet_db.service';
|
||||
import { setupPolly } from 'setup-polly-jest';
|
||||
import * as NodeHttpAdapter from '@pollyjs/adapter-node-http';
|
||||
import * as FSPersister from '@pollyjs/persister-fs';
|
||||
import * as path from 'path';
|
||||
import { clearDB, createUser } from '../test.helper';
|
||||
import { setupTestTables } from '../tooljet-db-test.helper';
|
||||
import { InternalTable } from '@entities/internal_table.entity';
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { ConfigModule } from '@nestjs/config';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { ormconfig, tooljetDbOrmconfig } from '../../ormconfig';
|
||||
import { PostgrestProxyService } from '@services/postgrest_proxy.service';
|
||||
import { getEnvVars } from '../../scripts/database-config-utils';
|
||||
import { User } from '@entities/user.entity';
|
||||
import { Organization } from '@entities/organization.entity';
|
||||
import { OrganizationUser } from '@entities/organization_user.entity';
|
||||
import { AppVersion } from '@entities/app_version.entity';
|
||||
import { GroupPermission } from '@entities/group_permission.entity';
|
||||
import { UserGroupPermission } from '@entities/user_group_permission.entity';
|
||||
import { App } from '@entities/app.entity';
|
||||
|
||||
describe('TooljetDbOperationsService', () => {
|
||||
let app: INestApplication;
|
||||
let appManager: EntityManager;
|
||||
let tjDbManager: EntityManager;
|
||||
let service: TooljetDbOperationsService;
|
||||
let tooljetDbService: TooljetDbService;
|
||||
let organizationId: string;
|
||||
let usersTableId: string;
|
||||
|
||||
const context = setupPolly({
|
||||
adapters: [NodeHttpAdapter],
|
||||
persister: FSPersister,
|
||||
recordFailedRequests: true,
|
||||
matchRequestsBy: {
|
||||
method: true,
|
||||
headers: {
|
||||
exclude: ['tj-workspace-id', 'authorization', 'tableinfo'], // Exclude headers as they contain dynamic information
|
||||
},
|
||||
body: true,
|
||||
url: {
|
||||
protocol: true,
|
||||
username: true,
|
||||
password: true,
|
||||
hostname: true,
|
||||
port: true,
|
||||
pathname: false, // Don't match by pathname as it contains the dynamic table ID
|
||||
query: true,
|
||||
},
|
||||
},
|
||||
persisterOptions: {
|
||||
fs: {
|
||||
recordingsDir: path.resolve(__dirname, '../__fixtures__'),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
beforeAll(async () => {
|
||||
const moduleFixture: TestingModule = await Test.createTestingModule({
|
||||
imports: [
|
||||
ConfigModule.forRoot({
|
||||
isGlobal: true,
|
||||
envFilePath: ['../.env.test'],
|
||||
load: [() => getEnvVars()],
|
||||
}),
|
||||
TypeOrmModule.forRoot(ormconfig),
|
||||
TypeOrmModule.forRoot(tooljetDbOrmconfig),
|
||||
TypeOrmModule.forFeature([
|
||||
User,
|
||||
Organization,
|
||||
OrganizationUser,
|
||||
App,
|
||||
AppVersion,
|
||||
GroupPermission,
|
||||
UserGroupPermission,
|
||||
InternalTable,
|
||||
]),
|
||||
],
|
||||
providers: [TooljetDbOperationsService, TooljetDbService, PostgrestProxyService],
|
||||
}).compile();
|
||||
|
||||
app = moduleFixture.createNestApplication();
|
||||
await app.init();
|
||||
|
||||
appManager = getManager();
|
||||
tjDbManager = getConnection('tooljetDb').manager;
|
||||
|
||||
service = moduleFixture.get<TooljetDbOperationsService>(TooljetDbOperationsService);
|
||||
tooljetDbService = moduleFixture.get<TooljetDbService>(TooljetDbService);
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await clearDB();
|
||||
|
||||
const adminUserData = await createUser(app, {
|
||||
email: 'admin@tooljet.io',
|
||||
groups: ['all_users', 'admin'],
|
||||
});
|
||||
organizationId = adminUserData.organization.id;
|
||||
|
||||
await setupTestTables(appManager, tjDbManager, tooljetDbService, organizationId);
|
||||
const usersTable = await appManager.findOneOrFail(InternalTable, { organizationId, tableName: 'users' });
|
||||
usersTableId = usersTable.id;
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
context.polly.stop();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await app.close();
|
||||
await clearDB();
|
||||
});
|
||||
|
||||
describe('.createRow', () => {
|
||||
it('should create a new row and verify its content', async () => {
|
||||
const queryOptions = {
|
||||
table_id: usersTableId,
|
||||
create_row: {
|
||||
name: { column: 'name', value: 'John Doe' },
|
||||
email: { column: 'email', value: 'john@example.com' },
|
||||
},
|
||||
id: 'query-id',
|
||||
organization_id: organizationId,
|
||||
};
|
||||
|
||||
const result = await service.createRow(queryOptions);
|
||||
|
||||
expect(result).toBeDefined();
|
||||
expect(result.status).toBe('ok');
|
||||
expect(Array.isArray(result.data)).toBe(true);
|
||||
|
||||
const data = result.data as Array<Record<string, unknown>>;
|
||||
|
||||
expect(data.length).toBeGreaterThan(0);
|
||||
expect(data[0]).toEqual(
|
||||
expect.objectContaining({
|
||||
id: expect.any(Number),
|
||||
name: 'John Doe',
|
||||
email: 'john@example.com',
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('.listRows', () => {
|
||||
it('should list rows correctly', async () => {
|
||||
// Create a test row
|
||||
await service.createRow({
|
||||
table_id: usersTableId,
|
||||
create_row: {
|
||||
name: { column: 'name', value: 'John Doe' },
|
||||
email: { column: 'email', value: 'john@example.com' },
|
||||
},
|
||||
id: 'query-id',
|
||||
organization_id: organizationId,
|
||||
});
|
||||
|
||||
const queryOptions = {
|
||||
table_id: usersTableId,
|
||||
list_rows: {
|
||||
limit: 10,
|
||||
offset: 0,
|
||||
},
|
||||
id: 'query-id',
|
||||
organization_id: organizationId,
|
||||
};
|
||||
|
||||
const result = await service.listRows(queryOptions);
|
||||
|
||||
expect(result).toBeDefined();
|
||||
expect(result.status).toBe('ok');
|
||||
|
||||
const data = result.data as Array<Record<string, unknown>>;
|
||||
|
||||
expect(Array.isArray(data)).toBe(true);
|
||||
expect(data.length).toBe(1);
|
||||
expect(data[0]).toEqual(
|
||||
expect.objectContaining({
|
||||
name: 'John Doe',
|
||||
email: 'john@example.com',
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('.updateRows', () => {
|
||||
it('should update rows and verify the changes', async () => {
|
||||
// Create a test row
|
||||
await service.createRow({
|
||||
table_id: usersTableId,
|
||||
create_row: {
|
||||
name: { column: 'name', value: 'John Doe' },
|
||||
email: { column: 'email', value: 'john@example.com' },
|
||||
},
|
||||
id: 'query-id',
|
||||
organization_id: organizationId,
|
||||
});
|
||||
|
||||
const queryOptions = {
|
||||
table_id: usersTableId,
|
||||
update_rows: {
|
||||
where_filters: {
|
||||
filter1: { column: 'name', operator: 'eq', value: 'John Doe' },
|
||||
},
|
||||
columns: {
|
||||
name: { column: 'name', value: 'Jane Doe' },
|
||||
},
|
||||
},
|
||||
id: 'query-id',
|
||||
organization_id: organizationId,
|
||||
};
|
||||
|
||||
const result = await service.updateRows(queryOptions);
|
||||
|
||||
expect(result).toBeDefined();
|
||||
expect(result.status).toBe('ok');
|
||||
|
||||
// Verify the update
|
||||
const listResult = await service.listRows({
|
||||
table_id: usersTableId,
|
||||
list_rows: { limit: 1 },
|
||||
id: 'query-id',
|
||||
organization_id: organizationId,
|
||||
});
|
||||
|
||||
const data = listResult.data as Array<Record<string, unknown>>;
|
||||
|
||||
expect(Array.isArray(data)).toBe(true);
|
||||
expect(data).toEqual([
|
||||
{
|
||||
id: 1,
|
||||
name: 'Jane Doe',
|
||||
email: 'john@example.com',
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('.deleteRows', () => {
|
||||
it('should delete rows and verify the deletion', async () => {
|
||||
await service.createRow({
|
||||
table_id: usersTableId,
|
||||
create_row: {
|
||||
name: { column: 'name', value: 'John Doe' },
|
||||
email: { column: 'email', value: 'john@example.com' },
|
||||
},
|
||||
id: 'query-id',
|
||||
organization_id: organizationId,
|
||||
});
|
||||
|
||||
const queryOptions = {
|
||||
table_id: usersTableId,
|
||||
delete_rows: {
|
||||
where_filters: {
|
||||
filter1: { column: 'name', operator: 'eq', value: 'John Doe' },
|
||||
},
|
||||
},
|
||||
id: 'query-id',
|
||||
organization_id: organizationId,
|
||||
};
|
||||
|
||||
const result = await service.deleteRows(queryOptions);
|
||||
|
||||
expect(result).toBeDefined();
|
||||
expect(result.status).toBe('ok');
|
||||
});
|
||||
});
|
||||
|
||||
describe('.joinTables', () => {
|
||||
it('should join tables and verify the result', async () => {
|
||||
// Check if tables exist
|
||||
const usersTable = await appManager.findOne(InternalTable, { organizationId, tableName: 'users' });
|
||||
const ordersTable = await appManager.findOne(InternalTable, { organizationId, tableName: 'orders' });
|
||||
|
||||
expect(usersTable).toBeDefined();
|
||||
expect(ordersTable).toBeDefined();
|
||||
|
||||
const insertUserResult = await tjDbManager
|
||||
.createQueryBuilder()
|
||||
.insert()
|
||||
.into(usersTable.id)
|
||||
.values({
|
||||
name: 'John Doe',
|
||||
email: 'john@example.com',
|
||||
})
|
||||
.returning('id')
|
||||
.execute();
|
||||
|
||||
const userId = insertUserResult.raw[0].id;
|
||||
|
||||
await tjDbManager
|
||||
.createQueryBuilder()
|
||||
.insert()
|
||||
.into(ordersTable.id)
|
||||
.values({
|
||||
user_id: userId,
|
||||
total: 100.5,
|
||||
})
|
||||
.execute();
|
||||
|
||||
// Perform join
|
||||
const queryOptions = {
|
||||
join_table: {
|
||||
joins: [
|
||||
{
|
||||
id: Date.now(), // unique ID
|
||||
conditions: {
|
||||
operator: 'AND',
|
||||
conditionsList: [
|
||||
{
|
||||
operator: '=',
|
||||
leftField: {
|
||||
table: usersTable.id,
|
||||
columnName: 'id',
|
||||
type: 'Column',
|
||||
},
|
||||
rightField: {
|
||||
table: ordersTable.id,
|
||||
columnName: 'user_id',
|
||||
type: 'Column',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
joinType: 'INNER',
|
||||
table: ordersTable.id,
|
||||
},
|
||||
],
|
||||
from: {
|
||||
name: usersTable.id,
|
||||
type: 'Table',
|
||||
},
|
||||
fields: [
|
||||
{ name: 'id', table: usersTable.id },
|
||||
{ name: 'name', table: usersTable.id },
|
||||
{ name: 'email', table: usersTable.id },
|
||||
{ name: 'id', table: ordersTable.id },
|
||||
{ name: 'user_id', table: ordersTable.id },
|
||||
{ name: 'total', table: ordersTable.id },
|
||||
],
|
||||
conditions: {
|
||||
conditionsList: [],
|
||||
},
|
||||
order_by: [],
|
||||
},
|
||||
organization_id: organizationId,
|
||||
};
|
||||
|
||||
const joinResult = await service.joinTables(queryOptions);
|
||||
|
||||
const expectedResponse = {
|
||||
status: 'ok',
|
||||
data: {
|
||||
result: [
|
||||
{
|
||||
users_id: expect.any(Number),
|
||||
users_name: 'John Doe',
|
||||
users_email: 'john@example.com',
|
||||
orders_id: expect.any(Number),
|
||||
orders_user_id: expect.any(Number),
|
||||
orders_total: 100.5,
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
expect(joinResult).toEqual(expectedResponse);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -36,6 +36,7 @@ import { AppEnvironment } from 'src/entities/app_environments.entity';
|
|||
import { defaultAppEnvironments } from 'src/helpers/utils.helper';
|
||||
import { DataSourceOptions } from 'src/entities/data_source_options.entity';
|
||||
import * as cookieParser from 'cookie-parser';
|
||||
import { InternalTable } from '@entities/internal_table.entity';
|
||||
|
||||
export async function createNestAppInstance(): Promise<INestApplication> {
|
||||
let app: INestApplication;
|
||||
|
|
@ -103,13 +104,27 @@ export function authHeaderForUser(user: User, organizationId?: string, isPasswor
|
|||
}
|
||||
|
||||
export async function clearDB() {
|
||||
const entities = getConnection().entityMetadatas;
|
||||
for (const entity of entities) {
|
||||
const repository = getConnection().getRepository(entity.name);
|
||||
if (process.env.NODE_ENV !== 'test') return;
|
||||
if (process.env.ENABLE_TOOLJET_DB === 'true') await dropTooljetDbTables();
|
||||
|
||||
const connection = getConnection();
|
||||
for (const entity of connection.entityMetadatas) {
|
||||
const repository = connection.getRepository(entity.name);
|
||||
await repository.query(`TRUNCATE ${entity.tableName} RESTART IDENTITY CASCADE;`);
|
||||
}
|
||||
}
|
||||
|
||||
async function dropTooljetDbTables() {
|
||||
const connection = getConnection();
|
||||
const tooljetDbConnection = getConnection('tooljetDb');
|
||||
|
||||
const internalTables = (await connection.manager.find(InternalTable, { select: ['id'] })) as InternalTable[];
|
||||
|
||||
for (const table of internalTables) {
|
||||
await tooljetDbConnection.query(`DROP TABLE IF EXISTS "${table.id}" CASCADE`);
|
||||
}
|
||||
}
|
||||
|
||||
export async function createApplication(nestApp, { name, user, isPublic, slug }: any, shouldCreateEnvs = true) {
|
||||
let appRepository: Repository<App>;
|
||||
appRepository = nestApp.get('AppRepository');
|
||||
|
|
|
|||
159
server/test/tooljet-db-test.helper.ts
Normal file
159
server/test/tooljet-db-test.helper.ts
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
import { EntityManager } from 'typeorm';
|
||||
import { TooljetDbService } from '@services/tooljet_db.service';
|
||||
import { InternalTable } from '@entities/internal_table.entity';
|
||||
import {
|
||||
TooljetDatabaseColumn,
|
||||
TooljetDatabaseForeignKey,
|
||||
TooljetDatabaseTable,
|
||||
} from 'src/modules/tooljet_db/tooljet-db.types';
|
||||
|
||||
const mockTableSchemas: Array<TooljetDatabaseTable> = [
|
||||
{
|
||||
id: 'user_table_uuid',
|
||||
table_name: 'users',
|
||||
schema: {
|
||||
columns: [
|
||||
{
|
||||
column_name: 'id',
|
||||
data_type: 'integer',
|
||||
column_default: "nextval('users_id_seq'::regclass)",
|
||||
character_maximum_length: null,
|
||||
numeric_precision: 32,
|
||||
constraints_type: {
|
||||
is_not_null: true,
|
||||
is_primary_key: true,
|
||||
is_unique: true,
|
||||
},
|
||||
keytype: 'PRIMARY KEY',
|
||||
},
|
||||
{
|
||||
column_name: 'name',
|
||||
data_type: 'character varying',
|
||||
column_default: null,
|
||||
character_maximum_length: null,
|
||||
numeric_precision: null,
|
||||
constraints_type: {
|
||||
is_not_null: true,
|
||||
is_primary_key: false,
|
||||
is_unique: false,
|
||||
},
|
||||
keytype: '',
|
||||
},
|
||||
{
|
||||
column_name: 'email',
|
||||
data_type: 'character varying',
|
||||
column_default: null,
|
||||
character_maximum_length: null,
|
||||
numeric_precision: null,
|
||||
constraints_type: {
|
||||
is_not_null: true,
|
||||
is_primary_key: false,
|
||||
is_unique: true,
|
||||
},
|
||||
keytype: '',
|
||||
},
|
||||
],
|
||||
foreign_keys: [],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'orders_table_uuid',
|
||||
table_name: 'orders',
|
||||
schema: {
|
||||
columns: [
|
||||
{
|
||||
column_name: 'id',
|
||||
data_type: 'integer',
|
||||
column_default: "nextval('orders_id_seq'::regclass)",
|
||||
character_maximum_length: null,
|
||||
numeric_precision: 32,
|
||||
constraints_type: {
|
||||
is_not_null: true,
|
||||
is_primary_key: true,
|
||||
is_unique: true,
|
||||
},
|
||||
keytype: 'PRIMARY KEY',
|
||||
},
|
||||
{
|
||||
column_name: 'user_id',
|
||||
data_type: 'integer',
|
||||
column_default: null,
|
||||
character_maximum_length: null,
|
||||
numeric_precision: 32,
|
||||
constraints_type: {
|
||||
is_not_null: true,
|
||||
is_primary_key: false,
|
||||
is_unique: false,
|
||||
},
|
||||
keytype: '',
|
||||
},
|
||||
{
|
||||
column_name: 'total',
|
||||
data_type: 'double precision',
|
||||
column_default: null,
|
||||
character_maximum_length: null,
|
||||
numeric_precision: null,
|
||||
constraints_type: {
|
||||
is_not_null: true,
|
||||
is_primary_key: false,
|
||||
is_unique: false,
|
||||
},
|
||||
keytype: '',
|
||||
},
|
||||
],
|
||||
foreign_keys: [
|
||||
{
|
||||
referenced_table_name: 'users',
|
||||
constraint_name: 'fk_orders_user_id',
|
||||
column_names: ['user_id'],
|
||||
referenced_column_names: ['id'],
|
||||
on_update: 'NO ACTION',
|
||||
on_delete: 'CASCADE',
|
||||
referenced_table_id: 'user_table_id',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export async function setupTestTables(
|
||||
appManager: EntityManager,
|
||||
tjdbManager: EntityManager,
|
||||
tooljetDbService: TooljetDbService,
|
||||
organizationId: string,
|
||||
tableSchemas: Array<TooljetDatabaseTable> = mockTableSchemas
|
||||
): Promise<void> {
|
||||
const createTableParams = tableSchemas.map((table) => ({ ...table.schema, table_name: table.table_name }));
|
||||
|
||||
for (const params of createTableParams) {
|
||||
await createTable(appManager, tjdbManager, tooljetDbService, organizationId, params);
|
||||
}
|
||||
|
||||
// Wait for the tables to be created and postgrest to reload the schema
|
||||
// when running tests in record mode
|
||||
if (process.env.POLLY_MODE === 'record') {
|
||||
await new Promise((resolve) => setTimeout(resolve, 2000));
|
||||
}
|
||||
}
|
||||
|
||||
async function createTable(
|
||||
appManager: EntityManager,
|
||||
tjdbManager: EntityManager,
|
||||
tooljetDbService: TooljetDbService,
|
||||
organizationId: string,
|
||||
params: { table_name: string; columns: TooljetDatabaseColumn[]; foreign_keys: TooljetDatabaseForeignKey[] }
|
||||
) {
|
||||
await tooljetDbService.perform(organizationId, 'create_table', params, { appManager, tjdbManager });
|
||||
}
|
||||
|
||||
export async function dropTable(
|
||||
appManager: EntityManager,
|
||||
tjdbManager: EntityManager,
|
||||
tooljetDbService: TooljetDbService,
|
||||
organizationId: string,
|
||||
tableName: string
|
||||
) {
|
||||
await tooljetDbService.perform(organizationId, 'drop_table', { table_name: tableName }, { appManager, tjdbManager });
|
||||
|
||||
await appManager.delete(InternalTable, { organizationId, tableName });
|
||||
}
|
||||
|
|
@ -14,6 +14,7 @@
|
|||
"incremental": true,
|
||||
"paths": {
|
||||
"@ee/*": ["ee/*"],
|
||||
"@entities/*": ["src/entities/*"],
|
||||
"@services/*": ["src/services/*"],
|
||||
"@controllers/*": ["src/controllers/*"],
|
||||
"@repositories/*": ["src/repositories/*"],
|
||||
|
|
|
|||
Loading…
Reference in a new issue