Compare commits

...
36 Commits
Author SHA1 Message Date
Florent Vilmart 2d7b9923ef ⚡ Release 3.1.3 (#5267)
* ⚡ Release 3.1.3

* Update CHANGELOG.md
2018-12-30 09:45:19 -05:00
dependabot[bot] d11e93c36c Bump eslint from 5.10.0 to 5.11.1 (#5261)
Bumps [eslint](https://github.com/eslint/eslint) from 5.10.0 to 5.11.1.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v5.10.0...v5.11.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-29 12:35:04 -05:00
dependabot[bot] d04a7b5a77 Bump husky from 1.2.1 to 1.3.1 (#5263)
Bumps [husky](https://github.com/typicode/husky) from 1.2.1 to 1.3.1.
- [Release notes](https://github.com/typicode/husky/releases)
- [Changelog](https://github.com/typicode/husky/blob/master/CHANGELOG.md)
- [Commits](https://github.com/typicode/husky/compare/v1.2.1...v1.3.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-29 12:34:51 -05:00
Diamond Lewis ce7ff2ca44 Add original object to LiveQuery Events (#5265)
* Add original object to LiveQuery Events

* change response original
2018-12-28 17:56:08 -05:00
Benjamin Simonsson de92ce5c49 Fix for count being very slow on large Parse Classes' collections (#5264)
* * Added fix for MongoCollection's count function, so that it uses the much more effecient estimatedDocumentCount if no queries were specified

* * Added missing options when running estimatedDocumentCount for Mongo Collections

* * Fixed issue with checking for zero query for Mongo Collections count
2018-12-28 09:45:36 -05:00
Diamond Lewis 66f594342e Update CHANGELOG.md 2018-12-27 09:06:37 -06:00
greenkeeper[bot] 3a6505a32d Update follow-redirects to the latest version 🚀 (#5260)
* fix(package): update follow-redirects to version 1.6.0

* chore(package): update lockfile package-lock.json
2018-12-25 22:46:16 +00:00
greenkeeper[bot] acf205cd7f Update bcrypt to the latest version 🚀 (#5258)
* chore(package): update bcrypt to version 3.0.3

* chore(package): update lockfile package-lock.json
2018-12-24 04:16:59 +00:00
Diamond Lewis 99698928af Fix for #5207 (#5257) 2018-12-23 19:40:59 -06:00
Florent Vilmart a9aff79cc6 docker: slim docker image to 154Mb (#5248)
* Better dockerfile

* nits

* proper VOLUMES
2018-12-22 11:33:41 -05:00
greenkeeper[bot] df109c0023 Update supports-color to the latest version 🚀 (#5256)
* chore(package): update supports-color to version 6.0.0

* chore(package): update lockfile package-lock.json
2018-12-21 16:02:18 +00:00
greenkeeper[bot] 1d8bcb22bd Update babel7 to the latest version 🚀 (#5255)
* chore(package): update @babel/cli to version 7.2.3

* chore(package): update @babel/plugin-transform-flow-strip-types to version 7.2.3

* chore(package): update @babel/preset-env to version 7.2.3

* chore(package): update lockfile package-lock.json
2018-12-20 13:41:28 +00:00
Diamond Lewis ab32dbc9a2 PG: Fix containedIn query on empty array (#5254)
* PG: Fix containedIn query on empty array

* improve logic
2018-12-19 17:57:55 -06:00
Diamond Lewis 631b1684e2 PG: Updating mixed array test (#5252)
* PG: Updating mixed array test

Currently we can save a mixed array but not update

* build array instead of casting

* fix test

* add recursion
2018-12-18 17:38:05 -06:00
Diamond Lewis 7b3da8b744 PG: Fix updating numeric array (#5251)
* PG: Fix updating numeric array

* lint
2018-12-18 12:11:24 -06:00
Florent Vilmart c762ee4b43 run tests against mongodb 4.0 (#5250)
* run tests against mongodb 4.0

* Adds compatibility shields
2018-12-18 11:41:18 -05:00
Florent Vilmart 315d3bfee8 Use current LTS 10.14.2 for dev and ci (#5249) 2018-12-18 11:21:33 -05:00
dependabot[bot] 980c2cda3a ⬆️ Bump eslint from 5.9.0 to 5.10.0 (#5247)
Bumps [eslint](https://github.com/eslint/eslint) from 5.9.0 to 5.10.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v5.9.0...v5.10.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-17 07:32:44 -05:00
dependabot[bot] 3ea632fa1b Bump winston from 2.4.1 to 2.4.4 (#5203)
Bumps [winston](https://github.com/winstonjs/winston) from 2.4.1 to 2.4.4.
- [Release notes](https://github.com/winstonjs/winston/releases)
- [Changelog](https://github.com/winstonjs/winston/blob/2.4.4/CHANGELOG.md)
- [Commits](https://github.com/winstonjs/winston/compare/2.4.1...2.4.4)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-15 08:07:44 -05:00
dependabot[bot] f08ca7b9cc Bump follow-redirects from 1.5.9 to 1.5.10 (#5204)
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.5.9 to 1.5.10.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.5.9...v1.5.10)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-15 08:07:26 -05:00
greenkeeper[bot] 4b8dc9409f Update babel7 to the latest version 🚀 (#5243)
* chore(package): update @babel/core to version 7.2.2

* chore(package): update @babel/plugin-transform-flow-strip-types to version 7.2.0

* chore(package): update @babel/preset-env to version 7.2.0

* chore(package): update lockfile package-lock.json
2018-12-15 11:42:07 +00:00
Diamond Lewis d478e001b5 PG: Support multiple global config (#5242)
* PG: Support Multiple Configs

* rename test

* refactor
2018-12-14 17:39:07 -06:00
Diamond Lewis 8c419ec52a Update CONTRIBUTING.md (#5241) 2018-12-14 10:46:37 -05:00
dependabot[bot] 9470dfc88a Bump @babel/plugin-proposal-object-rest-spread from 7.0.0 to 7.2.0 (#5221)
Bumps [@babel/plugin-proposal-object-rest-spread](https://github.com/babel/babel) from 7.0.0 to 7.2.0.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.0.0...v7.2.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-14 10:46:10 -05:00
dependabot[bot] 13626290c0 Bump express from 4.16.2 to 4.16.4 (#5202)
Bumps [express](https://github.com/expressjs/express) from 4.16.2 to 4.16.4.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.16.2...4.16.4)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-14 10:44:27 -05:00
dependabot[bot] cbd31d513e Bump nyc from 12.0.2 to 13.1.0 (#5206)
Bumps [nyc](https://github.com/istanbuljs/nyc) from 12.0.2 to 13.1.0.
- [Release notes](https://github.com/istanbuljs/nyc/releases)
- [Changelog](https://github.com/istanbuljs/nyc/blob/master/CHANGELOG.md)
- [Commits](https://github.com/istanbuljs/nyc/compare/v12.0.2...v13.1.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-14 10:44:11 -05:00
dependabot[bot] 3e414a8c60 Bump lint-staged from 7.3.0 to 8.1.0 (#5211)
Bumps [lint-staged](https://github.com/okonet/lint-staged) from 7.3.0 to 8.1.0.
- [Release notes](https://github.com/okonet/lint-staged/releases)
- [Commits](https://github.com/okonet/lint-staged/compare/v7.3.0...v8.1.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-14 10:43:55 -05:00
dependabot[bot] 38482cf0fe Bump lru-cache from 5.0.0 to 5.1.1 (#5213)
Bumps [lru-cache](https://github.com/isaacs/node-lru-cache) from 5.0.0 to 5.1.1.
- [Release notes](https://github.com/isaacs/node-lru-cache/releases)
- [Commits](https://github.com/isaacs/node-lru-cache/compare/v5.0.0...v5.1.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-14 10:43:34 -05:00
dependabot[bot] 8c044ab85b Bump @babel/cli from 7.1.5 to 7.2.0 (#5222)
Bumps [@babel/cli](https://github.com/babel/babel) from 7.1.5 to 7.2.0.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/compare/v7.1.5...v7.2.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-14 10:43:16 -05:00
dependabot[bot] 208f92160d Bump husky from 1.0.0-rc.15 to 1.2.1 (#5237)
Bumps [husky](https://github.com/typicode/husky) from 1.0.0-rc.15 to 1.2.1.
- [Release notes](https://github.com/typicode/husky/releases)
- [Changelog](https://github.com/typicode/husky/blob/master/CHANGELOG.md)
- [Commits](https://github.com/typicode/husky/compare/v1.0.0-rc.15...v1.2.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-12-14 10:42:07 -05:00
greenkeeper[bot] e28770e744 Update pg-promise to the latest version 🚀 (#5234)
* fix(package): update pg-promise to version 8.5.4

* chore(package): update lockfile package-lock.json
2018-12-14 01:29:47 +00:00
greenkeeper[bot] a4b592a355 Update pg-promise to the latest version 🚀 (#5217)
* fix(package): update pg-promise to version 8.5.3

* chore(package): update lockfile package-lock.json
2018-11-30 04:54:59 +00:00
greenkeeper[bot] f0626508d3 Update prettier to the latest version 🚀 (#5216)
* chore(package): update prettier to version 1.15.3

* chore(package): update lockfile package-lock.json
2018-11-30 03:28:53 +00:00
dependabot[bot] bc12b1496a Bump babel-eslint from 10.0.0 to 10.0.1 (#5200)
Bumps [babel-eslint](https://github.com/babel/babel-eslint) from 10.0.0 to 10.0.1.
- [Release notes](https://github.com/babel/babel-eslint/releases)
- [Commits](https://github.com/babel/babel-eslint/compare/v10.0.0...v10.0.1)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-11-27 21:01:40 -05:00
dependabot[bot] 80a9b70253 Bump eslint-plugin-flowtype from 3.0.0 to 3.2.0 (#5197)
Bumps [eslint-plugin-flowtype](https://github.com/gajus/eslint-plugin-flowtype) from 3.0.0 to 3.2.0.
- [Release notes](https://github.com/gajus/eslint-plugin-flowtype/releases)
- [Commits](https://github.com/gajus/eslint-plugin-flowtype/compare/v3.0.0...v3.2.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-11-27 20:58:37 -05:00
dependabot[bot] 5d9d7601a9 Bump eslint from 5.6.0 to 5.9.0 (#5199)
Bumps [eslint](https://github.com/eslint/eslint) from 5.6.0 to 5.9.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v5.6.0...v5.9.0)

Signed-off-by: dependabot[bot] <support@dependabot.com>
2018-11-27 20:58:21 -05:00
14 changed files with 1601 additions and 2067 deletions
+2 -1
View File
@@ -1 +1,2 @@
8.10
10.14.2
+6 -7
View File
@@ -26,16 +26,15 @@ stage: test
env:
global:
- COVERAGE_OPTION='./node_modules/.bin/nyc'
- NODE_VERSION=8.11.2
matrix:
- MONGODB_VERSION=3.2.13
- MONGODB_VERSION=3.4.4
- MONGODB_VERSION=4.0.4
- MONGODB_VERSION=3.6.9
- PARSE_SERVER_TEST_DB=postgres
- PARSE_SERVER_TEST_CACHE=redis
- NODE_VERSION=stable
- NODE_VERSION=11.4.0
matrix:
allow_failures:
- env: NODE_VERSION=stable
- env: NODE_VERSION=11.4.0
before_install:
- nvm install $NODE_VERSION
- nvm use $NODE_VERSION
@@ -74,9 +73,9 @@ jobs:
- provider: npm
skip_cleanup: true
email:
secure: "YweTGc22uqFWpzbfiUa5ptBLRAy6tt6d9TZLwEkPtmnsWzN9dguGyKWmXiw0qL+848FWQ5PWzUgBn5XdigV9tF3rJY6RGs8i38WulNjwSoGuRZa3AChsQHAb1KenANcJybzhnwgEj9gRsrGZPEsyI2whfake/xLDtG91kHjpJANsd4gseOh6fdS4FIYCbyXvSbC7S0yZzIJkgSkMqJO7RJ8r0HYQ7srYIw31dM3ZXSmUYu+GaMDUUu3RLAGYoKaROxhDRnzkjdeLLiwZH8hQ/6CaqwqX54iJ6OS+MOQU3fi5ZXalA7RZvtC4RmrcCkaTf3i0f+5xejYIFgzXdYGMVm8DUc82tDw1s4b6Pb19bgi1xXOQ0IKzRmZuGxnvkRN61dnYdnpnnNuG97HXgVjiOigZXVLZkWazUdnf9zXqmkC+KxPfa4Ldqg0TMjQ9J14n6TXxRti8Tt0xMa1Uzho7VdsxdJy35Bghy398O6X8VdX6parfzEkX7c/JzcA3TIMJ9+S1dy3J4Tb2URB5367W6h7cDeXtGmwLTFu75Q1CNqRJkUGbSrX2NyMqG5tc8oaTM+OWvLxcbKPRy9T6qN7x2JmCHHaapf8/8VR9wCy2PwE5j+KWhmctEHqqOgrtG5gsjC0eCPJsposxZWyM7M6aUpXe3w+olBfKq9apUGStUSU="
secure: $NPM_EMAIL
api_key:
secure: "QprkaqQ+WCvZQR4qIEs5iS6peMCbRd8Hgt0s6HfdmhavNXwDFY8Bkdf6zJwWHLiqs4pyClXDZ2f6QiOs7y9IvJZ+wOIbsf4N5V6s06zOxJ0NAOwhe0mgWS3Us0zgXIfmW4BpmGnU4ql/qGL+9vNfyQJ7wxEJxVK7hiYh9Epu49E2jmefDqTX+SNSrDCg4HkRcxerxYGnAJDCP50QaNlyLSciODD6wHaddrSYkdvmISLMnLHug61OkE4OBIOWXfYV+e31kDj+zgczAfVQgekDKtaimCQclHFrmaEPl0KIm6wsDQAw5HWkepA/WZfv4SbCrDaKJDZw+LBI7dR0ezmiOH/zmWWrRW7D4wjkDGiumWjA8etuf8I4GRyC/d1RS+hnlvPr0Bu+WljuVxLoK3nhZOdiK5t4QlVDoGankkRjLylwFQgo8tzu5N0dc26z3ClowTwcKsjStmFr53gjCD7l3qoFjyPot1JlW3LPhG9Nch7rK33/7ONqVai3zxb1xB9ynd8TSzKi4/66LeYEDcGVM5A9Vmkp+egCnOhkOAXdI8O4jid98NANir+U4xmUYZ2PAMNmSeHlpSpwH2pC1/BHpDKA9RZEuEdr3sgmtuXXwwOCp+xvuVwxZZ6+gVEjG4nGTqSNxUIq1fzjGih8ElJtbM1Uhh2dVE9uxW7EC/oCuuk="
secure: $NPM_TOKEN
on:
tags: true
all_branches: true
+13 -2
View File
@@ -1,7 +1,18 @@
## Parse Server Changelog
### master
[Full Changelog](https://github.com/parse-community/parse-server/compare/3.1.2...master)
[Full Changelog](https://github.com/parse-community/parse-server/compare/3.1.3...master)
### 3.1.3
[Full Changelog](https://github.com/parse-community/parse-server/compare/3.1.2...3.1.3)
- Postgres: Fixes support for global configuration
- Postgres: Fixes support for numeric arrays
- Postgres: Fixes issue affecting queries on emtpy arrays
- LiveQuery: Adds support for transmitting the original object
- Queries: Use estimated count if queyr is empty
- Docker: Reduces the size of the docker image to 154Mb
### 3.1.2
[Full Changelog](https://github.com/parse-community/parse-server/compare/3.1.1...3.1.2)
@@ -46,7 +57,7 @@ For more informations, visit the v3.0.0 [migration guide](https://github.com/par
* Cloud Code handlers have a new interface based on promises.
* response.success / response.error are removed in Cloud Code
* Cloud Code runs with Parse-SDK 2.0
* The aggregate now require aggregates to be passed in the form: `{"pipeline": [...]}`
* The aggregate now require aggregates to be passed in the form: `{"pipeline": [...]}` (REST Only)
#### Improvements:
* Adds Pipeline Operator to Aggregate Router.
+1
View File
@@ -61,6 +61,7 @@ Once you have babel running in watch mode, you can start making changes to parse
If your pull request introduces a change that may affect the storage or retrieval of objects, you may want to make sure it plays nice with Postgres.
* Run the tests against the postgres database with `PARSE_SERVER_TEST_DB=postgres npm test`. You'll need to have postgres running on your machine and setup [appropriately](https://github.com/parse-community/parse-server/blob/master/.travis.yml#L37)
* The Postgres adapter has a special debugger that traces all the sql commands. You can enable it with setting the environment variable `PARSE_SERVER_LOG_LEVEL=debug`
* If your feature is intended to only work with MongoDB, you should disable PostgreSQL-specific tests with:
- `describe_only_db('mongo')` // will create a `describe` that runs only on mongoDB
+22 -12
View File
@@ -1,21 +1,31 @@
FROM node:carbon
# Build stage
FROM node:lts-alpine as build
RUN mkdir -p /parse-server
COPY ./ /parse-server/
RUN apk update; \
apk add git;
WORKDIR /tmp
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
RUN mkdir -p /parse-server/config
VOLUME /parse-server/config
RUN mkdir -p /parse-server/cloud
VOLUME /parse-server/cloud
# Release stage
FROM node:lts-alpine as release
VOLUME /parse-server/cloud /parse-server/config
WORKDIR /parse-server
RUN npm install && \
npm run build
COPY package*.json ./
RUN npm ci --production
COPY bin bin
COPY public_html public_html
COPY views views
COPY --from=build /tmp/lib lib
RUN mkdir -p logs && chown -R node: logs
ENV PORT=1337
USER node
EXPOSE $PORT
ENTRYPOINT ["npm", "start", "--"]
ENTRYPOINT ["node", "./bin/parse-server"]
+6
View File
@@ -7,6 +7,12 @@
[![Join Chat](https://img.shields.io/badge/gitter-join%20chat%20%E2%86%92-brightgreen.svg)](https://gitter.im/ParsePlatform/Chat)
[![Greenkeeper badge](https://badges.greenkeeper.io/parse-community/parse-server.svg)](https://greenkeeper.io/)
[![](https://img.shields.io/badge/mongodb-3.2-green.svg?logo=mongodb&style=flat)]()
[![](https://img.shields.io/badge/mongodb-3.4-green.svg?logo=mongodb&style=flat)]()
[![](https://img.shields.io/badge/mongodb-3.6-green.svg?logo=mongodb&style=flat)]()
[![](https://img.shields.io/badge/mongodb-4.0-green.svg?logo=mongodb&style=flat)]()
Parse Server is an [open source version of the Parse backend](http://blog.parseplatform.org/announcements/introducing-parse-server-and-the-database-migration-tool/) that can be deployed to any infrastructure that can run Node.js.
Parse Server works with the Express web application framework. It can be added to existing web applications, or run by itself.
+1224 -2010
View File
File diff suppressed because it is too large Load Diff
+18 -18
View File
@@ -1,6 +1,6 @@
{
"name": "parse-server",
"version": "3.1.2",
"version": "3.1.3",
"description": "An express module providing a Parse-compatible API server",
"main": "lib/index.js",
"repository": {
@@ -27,29 +27,29 @@
"body-parser": "1.18.3",
"commander": "2.19.0",
"deepcopy": "1.0.0",
"express": "4.16.2",
"follow-redirects": "1.5.9",
"express": "4.16.4",
"follow-redirects": "1.6.0",
"intersect": "1.0.1",
"lodash": "4.17.11",
"lru-cache": "5.0.0",
"lru-cache": "5.1.1",
"mime": "2.4.0",
"mongodb": "3.1.10",
"parse": "2.1.0",
"pg-promise": "8.5.2",
"pg-promise": "8.5.4",
"redis": "2.8.0",
"semver": "5.6.0",
"tv4": "1.3.0",
"uuid": "^3.1.0",
"winston": "2.4.1",
"winston": "2.4.4",
"winston-daily-rotate-file": "1.7.2",
"ws": "6.1.2"
},
"devDependencies": {
"@babel/cli": "7.1.5",
"@babel/core": "7.1.6",
"@babel/plugin-transform-flow-strip-types": "7.1.6",
"@babel/plugin-proposal-object-rest-spread": "7.0.0",
"@babel/preset-env": "7.1.6",
"@babel/cli": "7.2.3",
"@babel/core": "7.2.2",
"@babel/plugin-transform-flow-strip-types": "7.2.3",
"@babel/plugin-proposal-object-rest-spread": "7.2.0",
"@babel/preset-env": "7.2.3",
"@parse/minami": "^1.0.0",
"babel-eslint": "^10.0.0",
"bcrypt-nodejs": "0.0.3",
@@ -64,11 +64,11 @@
"jasmine-spec-reporter": "^4.1.0",
"jsdoc": "^3.5.5",
"jsdoc-babel": "^0.5.0",
"lint-staged": "^7.2.2",
"lint-staged": "^8.1.0",
"mongodb-runner": "4.3.2",
"nyc": "^12.0.2",
"prettier": "1.15.2",
"supports-color": "^5.4.0"
"nyc": "^13.1.0",
"prettier": "1.15.3",
"supports-color": "^6.0.0"
},
"scripts": {
"docs": "jsdoc -c ./jsdoc-conf.json",
@@ -76,8 +76,8 @@
"lint": "flow && eslint --cache ./",
"build": "babel src/ -d lib/ --copy-files",
"watch": "babel --watch src/ -d lib/ --copy-files",
"test": "cross-env MONGODB_VERSION=${MONGODB_VERSION:=3.2.6} MONGODB_STORAGE_ENGINE=mmapv1 TESTING=1 jasmine",
"coverage": "cross-env MONGODB_VERSION=${MONGODB_VERSION:=3.2.6} MONGODB_STORAGE_ENGINE=mmapv1 TESTING=1 nyc jasmine",
"test": "cross-env MONGODB_VERSION=${MONGODB_VERSION:=4.0.4} MONGODB_STORAGE_ENGINE=mmapv1 TESTING=1 jasmine",
"coverage": "cross-env MONGODB_VERSION=${MONGODB_VERSION:=4.0.4} MONGODB_STORAGE_ENGINE=mmapv1 TESTING=1 nyc jasmine",
"start": "node ./bin/parse-server",
"prepare": "npm run build",
"postinstall": "node -p 'require(\"./postinstall.js\")()'"
@@ -89,7 +89,7 @@
"parse-server": "./bin/parse-server"
},
"optionalDependencies": {
"bcrypt": "3.0.2",
"bcrypt": "3.0.3",
"uws": "10.148.1"
},
"collective": {
+104 -1
View File
@@ -899,6 +899,56 @@ describe('ParseLiveQueryServer', function() {
}, jasmine.ASYNC_TEST_WAIT_TIME);
});
it('can handle update command with original object', function(done) {
jasmine.restoreLibrary('../lib/LiveQuery/Client', 'Client');
const Client = require('../lib/LiveQuery/Client').Client;
const parseLiveQueryServer = new ParseLiveQueryServer({});
// Make mock request message
const message = generateMockMessage(true);
const clientId = 1;
const parseWebSocket = {
clientId,
send: jasmine.createSpy('send'),
};
const client = new Client(clientId, parseWebSocket);
spyOn(client, 'pushUpdate').and.callThrough();
parseLiveQueryServer.clients.set(clientId, client);
// Add mock subscription
const requestId = 2;
addMockSubscription(
parseLiveQueryServer,
clientId,
requestId,
parseWebSocket
);
// Mock _matchesSubscription to return matching
parseLiveQueryServer._matchesSubscription = function(parseObject) {
if (!parseObject) {
return false;
}
return true;
};
parseLiveQueryServer._matchesACL = function() {
return Promise.resolve(true);
};
parseLiveQueryServer._onAfterSave(message);
// Make sure we send update command to client
setTimeout(function() {
expect(client.pushUpdate).toHaveBeenCalled();
const args = parseWebSocket.send.calls.mostRecent().args;
const toSend = JSON.parse(args[0]);
expect(toSend.object).toBeDefined();
expect(toSend.original).toBeDefined();
done();
}, jasmine.ASYNC_TEST_WAIT_TIME);
});
it('can handle object create command which matches some subscriptions', function(done) {
const parseLiveQueryServer = new ParseLiveQueryServer({});
// Make mock request message
@@ -1006,6 +1056,59 @@ describe('ParseLiveQueryServer', function() {
expect(originalObject.updatedAt).not.toBeUndefined();
});
it('can inflate user object', async () => {
const parseLiveQueryServer = new ParseLiveQueryServer({});
const userJSON = {
username: 'test',
ACL: {},
createdAt: '2018-12-21T23:09:51.784Z',
sessionToken: 'r:1234',
updatedAt: '2018-12-21T23:09:51.784Z',
objectId: 'NhF2u9n72W',
__type: 'Object',
className: '_User',
_hashed_password: '1234',
_email_verify_token: '1234',
};
const originalUserJSON = {
username: 'test',
ACL: {},
createdAt: '2018-12-21T23:09:51.784Z',
sessionToken: 'r:1234',
updatedAt: '2018-12-21T23:09:51.784Z',
objectId: 'NhF2u9n72W',
__type: 'Object',
className: '_User',
_hashed_password: '12345',
_email_verify_token: '12345',
};
const message = {
currentParseObject: userJSON,
originalParseObject: originalUserJSON,
};
parseLiveQueryServer._inflateParseObject(message);
const object = message.currentParseObject;
expect(object instanceof Parse.Object).toBeTruthy();
expect(object.get('_hashed_password')).toBeUndefined();
expect(object.get('_email_verify_token')).toBeUndefined();
expect(object.className).toEqual('_User');
expect(object.id).toBe('NhF2u9n72W');
expect(object.createdAt).not.toBeUndefined();
expect(object.updatedAt).not.toBeUndefined();
const originalObject = message.originalParseObject;
expect(originalObject instanceof Parse.Object).toBeTruthy();
expect(originalObject.get('_hashed_password')).toBeUndefined();
expect(originalObject.get('_email_verify_token')).toBeUndefined();
expect(originalObject.className).toEqual('_User');
expect(originalObject.id).toBe('NhF2u9n72W');
expect(originalObject.createdAt).not.toBeUndefined();
expect(originalObject.updatedAt).not.toBeUndefined();
});
it('can match undefined ACL', function(done) {
const parseLiveQueryServer = new ParseLiveQueryServer({});
const client = {};
@@ -1314,7 +1417,7 @@ describe('ParseLiveQueryServer', function() {
new Parse.ACL()
);
liveQueryRole.id = 'abcdef1234';
callback(liveQueryRole)
callback(liveQueryRole);
return Promise.resolve();
},
};
+120
View File
@@ -238,6 +238,30 @@ describe('Parse.Query testing', () => {
});
});
it('query notContainedIn on empty array', async () => {
const object = new TestObject();
object.set('value', 100);
await object.save();
const query = new Parse.Query(TestObject);
query.notContainedIn('value', []);
const results = await query.find();
equal(results.length, 1);
});
it('query containedIn on empty array', async () => {
const object = new TestObject();
object.set('value', 100);
await object.save();
const query = new Parse.Query(TestObject);
query.containedIn('value', []);
const results = await query.find();
equal(results.length, 0);
});
it('query with limit', function(done) {
const baz = new TestObject({ foo: 'baz' });
const qux = new TestObject({ foo: 'qux' });
@@ -4517,4 +4541,100 @@ describe('Parse.Query testing', () => {
.then(done.fail)
.catch(() => done());
});
it('can add new config to existing config', async () => {
await request({
method: 'PUT',
url: 'http://localhost:8378/1/config',
json: true,
body: {
params: {
files: [{ __type: 'File', name: 'name', url: 'http://url' }],
},
},
headers: masterKeyHeaders,
});
await request({
method: 'PUT',
url: 'http://localhost:8378/1/config',
json: true,
body: {
params: { newConfig: 'good' },
},
headers: masterKeyHeaders,
});
const result = await Parse.Config.get();
equal(result.get('files')[0].toJSON(), {
__type: 'File',
name: 'name',
url: 'http://url',
});
equal(result.get('newConfig'), 'good');
});
it('can set object type key', async () => {
const data = { bar: true, baz: 100 };
const object = new TestObject();
object.set('objectField', data);
await object.save();
const query = new Parse.Query(TestObject);
let result = await query.get(object.id);
equal(result.get('objectField'), data);
object.set('objectField.baz', 50, { ignoreValidation: true });
await object.save();
result = await query.get(object.id);
equal(result.get('objectField'), { bar: true, baz: 50 });
});
it('can update numeric array', async () => {
const data1 = [0, 1.1, 1, -2, 3];
const data2 = [0, 1.1, 1, -2, 3, 4];
const obj1 = new TestObject();
obj1.set('array', data1);
await obj1.save();
equal(obj1.get('array'), data1);
const query = new Parse.Query(TestObject);
query.equalTo('objectId', obj1.id);
const result = await query.first();
equal(result.get('array'), data1);
result.set('array', data2);
equal(result.get('array'), data2);
await result.save();
equal(result.get('array'), data2);
const results = await query.find();
equal(results[0].get('array'), data2);
});
it('can update mixed array', async () => {
const data1 = [0, 1.1, 'hello world', { foo: 'bar' }];
const data2 = [0, 1, { foo: 'bar' }, [], [1, 2, 'bar']];
const obj1 = new TestObject();
obj1.set('array', data1);
await obj1.save();
equal(obj1.get('array'), data1);
const query = new Parse.Query(TestObject);
query.equalTo('objectId', obj1.id);
const result = await query.first();
equal(result.get('array'), data1);
result.set('array', data2);
equal(result.get('array'), data2);
await result.save();
equal(result.get('array'), data2);
const results = await query.find();
equal(results[0].get('array'), data2);
});
});
@@ -80,6 +80,16 @@ export default class MongoCollection {
}
count(query, { skip, limit, sort, maxTimeMS, readPreference } = {}) {
// If query is empty, then use estimatedDocumentCount instead.
// This is due to countDocuments performing a scan,
// which greatly increases execution time when being run on large collections.
// See https://github.com/Automattic/mongoose/issues/6713 for more info regarding this problem.
if (typeof query !== 'object' || !Object.keys(query).length) {
return this._mongoCollection.estimatedDocumentCount({
maxTimeMS,
});
}
const countOperation = this._mongoCollection.countDocuments(query, {
skip,
limit,
@@ -402,8 +402,8 @@ const buildWhereClause = ({ schema, query, index }): WhereClause => {
index = index + 1 + inPatterns.length;
} else if (isInOrNin) {
var createConstraint = (baseArray, notIn) => {
const not = notIn ? ' NOT ' : '';
if (baseArray.length > 0) {
const not = notIn ? ' NOT ' : '';
if (isArrayField) {
patterns.push(
`${not} array_contains($${index}:name, $${index + 1})`
@@ -430,6 +430,13 @@ const buildWhereClause = ({ schema, query, index }): WhereClause => {
values.push(fieldName);
patterns.push(`$${index}:name IS NULL`);
index = index + 1;
} else {
// Handle empty array
if (notIn) {
patterns.push('1 = 1'); // Return all values
} else {
patterns.push('1 = 2'); // Return no values
}
}
};
if (fieldValue.$in) {
@@ -969,6 +976,7 @@ export class PostgresStorageAdapter implements StorageAdapter {
const qs = `CREATE TABLE IF NOT EXISTS $1:name (${patternsArray.join()})`;
const values = [className, ...valuesArray];
debug(qs, values);
return conn.task('create-table', function*(t) {
try {
yield self._ensureSchemaCollectionExists(t);
@@ -1426,6 +1434,18 @@ export class PostgresStorageAdapter implements StorageAdapter {
schema = toPostgresSchema(schema);
const originalUpdate = { ...update };
// Set flag for dot notation fields
const dotNotationOptions = {};
Object.keys(update).forEach(fieldName => {
if (fieldName.indexOf('.') > -1) {
const components = fieldName.split('.');
const first = components.shift();
dotNotationOptions[first] = true;
} else {
dotNotationOptions[fieldName] = false;
}
});
update = handleDotFields(update);
// Resolve authData first,
// So we don't end up with multiple key updates
@@ -1615,13 +1635,18 @@ export class PostgresStorageAdapter implements StorageAdapter {
},
''
);
// Override Object
let updateObject = "'{}'::jsonb";
if (dotNotationOptions[fieldName]) {
// Merge Object
updateObject = `COALESCE($${index}:name, '{}'::jsonb)`;
}
updatePatterns.push(
`$${index}:name = ('{}'::jsonb ${deletePatterns} ${incrementPatterns} || $${index +
`$${index}:name = (${updateObject} ${deletePatterns} ${incrementPatterns} || $${index +
1 +
keysToDelete.length}::jsonb )`
);
values.push(fieldName, ...keysToDelete, JSON.stringify(fieldValue));
index += 2 + keysToDelete.length;
} else if (
@@ -1632,20 +1657,37 @@ export class PostgresStorageAdapter implements StorageAdapter {
const expectedType = parseTypeToPostgresType(schema.fields[fieldName]);
if (expectedType === 'text[]') {
updatePatterns.push(`$${index}:name = $${index + 1}::text[]`);
values.push(fieldName, fieldValue);
index += 2;
} else {
let type = 'text';
for (const elt of fieldValue) {
if (typeof elt == 'object') {
type = 'json';
break;
values.push(fieldName);
const buildSQLArray = fieldValue => {
let pattern = 'json_build_array(';
for (let i = 0; i < fieldValue.length; i += 1) {
const element = fieldValue[i];
let type = '';
if (Array.isArray(element)) {
pattern += buildSQLArray(element) + ',';
continue;
} else if (typeof element == 'object') {
type = '::json';
}
values.push(element);
pattern += `$${index + 1}${type},`;
index += 1;
}
}
updatePatterns.push(
`$${index}:name = array_to_json($${index + 1}::${type}[])::jsonb`
);
// remove last comma
if (fieldValue.length > 0) {
pattern = pattern.slice(0, -1);
}
pattern += ')';
return pattern;
};
const sql = `$${index}:name = ${buildSQLArray(fieldValue)}`;
updatePatterns.push(sql);
index += 1;
}
values.push(fieldName, fieldValue);
index += 2;
} else {
debug('Not supported update', fieldName, fieldValue);
return Promise.reject(
+11 -1
View File
@@ -78,7 +78,11 @@ class Client {
}
_pushEvent(type: string): Function {
return function(subscriptionId: number, parseObjectJSON: any): void {
return function(
subscriptionId: number,
parseObjectJSON: any,
parseOriginalObjectJSON: any
): void {
const response: Message = {
op: type,
clientId: this.id,
@@ -92,6 +96,12 @@ class Client {
fields = this.subscriptionInfos.get(subscriptionId).fields;
}
response['object'] = this._toJSONWithFields(parseObjectJSON, fields);
if (typeof parseOriginalObjectJSON !== 'undefined') {
response['original'] = this._toJSONWithFields(
parseOriginalObjectJSON,
fields
);
}
}
Client.pushResponse(this.parseWebSocket, JSON.stringify(response));
};
+8 -1
View File
@@ -14,6 +14,7 @@ import { runLiveQueryEventHandlers } from '../triggers';
import { getAuthForSessionToken, Auth } from '../Auth';
import { getCacheController } from '../Controllers';
import LRU from 'lru-cache';
import UserRouter from '../Routers/UsersRouter';
class ParseLiveQueryServer {
clients: Map;
@@ -98,6 +99,7 @@ class ParseLiveQueryServer {
_inflateParseObject(message: any): void {
// Inflate merged object
const currentParseObject = message.currentParseObject;
UserRouter.removeHiddenProperties(currentParseObject);
let className = currentParseObject.className;
let parseObject = new Parse.Object(className);
parseObject._finishFetch(currentParseObject);
@@ -105,6 +107,7 @@ class ParseLiveQueryServer {
// Inflate original object
const originalParseObject = message.originalParseObject;
if (originalParseObject) {
UserRouter.removeHiddenProperties(originalParseObject);
className = originalParseObject.className;
parseObject = new Parse.Object(className);
parseObject._finishFetch(originalParseObject);
@@ -289,7 +292,11 @@ class ParseLiveQueryServer {
return null;
}
const functionName = 'push' + type;
client[functionName](requestId, currentParseObject);
client[functionName](
requestId,
currentParseObject,
originalParseObject
);
},
error => {
logger.error('Matching ACL error : ', error);