├── .editorconfig ├── .eslintrc.js ├── .github └── workflows │ └── ci.yml ├── .gitignore ├── .jsdocrc.json ├── .npmignore ├── .travis.yml ├── LICENSE ├── README.md ├── babel.config.json ├── browserslist ├── changelog.md ├── core.d.ts ├── core.js ├── demo ├── leaderboard │ ├── index.html │ ├── leaderboard.css │ └── leaderboard.js ├── live-query │ ├── app.js │ └── index.html └── settings │ └── index.html ├── live-query-core.d.ts ├── live-query-core.js ├── live-query.d.ts ├── live-query.js ├── package-lock.json ├── package.json ├── recordings ├── AV-Cloud_4059047921 │ ├── -getServerDate_3861860821 │ │ └── should-return-a-date-_3033254009 │ │ │ └── recording.har │ └── -rpc_2399869033 │ │ ├── receive-array-of-AVObjects_3617734733 │ │ └── recording.har │ │ ├── receive-bare-AVObject_2209367706 │ │ └── recording.har │ │ ├── receive-complex-object_427351593 │ │ └── recording.har │ │ ├── send-AVObject_366179365 │ │ └── recording.har │ │ └── send-bare-AVObject_2666081587 │ │ └── recording.har ├── AV-Status_182513154 │ ├── Query-statuses-_3829896703 │ │ ├── should-not-cause-URI-too-long_857544070 │ │ │ └── recording.har │ │ ├── should-reset-unread-statuses-_3611373772 │ │ │ └── recording.har │ │ ├── should-return-private-statuses-_654498159 │ │ │ └── recording.har │ │ ├── should-return-published-statuses-_2464967190 │ │ │ └── recording.har │ │ ├── should-return-unread-count-_2709918790 │ │ │ └── recording.har │ │ └── should-return-unread-count-that-is-greater-than-zero-_1427996684 │ │ │ └── recording.har │ ├── Send-status-_3868217483 │ │ ├── should-send-private-status-to-an-user-_2182658328 │ │ │ └── recording.har │ │ ├── should-send-status-to-a-female-user-_4070335779 │ │ │ └── recording.har │ │ └── should-send-status-to-followers-_1653702374 │ │ │ └── recording.har │ └── Status-guide-test-_197092205 │ │ └── should-follow_20583307 │ │ └── unfollow-successfully-_2639136222 │ │ └── recording.har ├── Conversation_2640583206 │ ├── -broadcast_4209827445 │ │ └── should-broadcast-a-message-to-all-clients-with-current-conversation_3412507037 │ │ │ └── recording.har │ ├── -save_2867845407 │ │ └── should-create-a-realtime-conversation_2600615093 │ │ │ └── recording.har │ └── -send_1543326976 │ │ ├── should-send-a-realtime-message-to-the-conversation_3245344578 │ │ └── recording.har │ │ └── should-send-a-realtime-message-to-the-system-conversation_1406045071 │ │ └── recording.har ├── Geopoints_1459669221 │ ├── near_1425233679 │ │ └── recording.har │ └── save-object-with-geopoints_2892866483 │ │ └── recording.har ├── Leaderboard_3275071436 │ ├── Statistics_2658119722 │ │ ├── count_967958004 │ │ │ └── recording.har │ │ ├── delete-statistics_147177321 │ │ │ └── recording.har │ │ ├── get-results-around-a-specified-user_3745100926 │ │ │ └── recording.har │ │ ├── get-results-around-user_2016320561 │ │ │ └── recording.har │ │ ├── get-statistics_1972767578 │ │ │ └── recording.har │ │ ├── getResults_1632843303 │ │ │ └── recording.har │ │ ├── include-a-non-exist-statistic-should-throw_1253811762 │ │ │ └── recording.har │ │ └── shoud-have-properties_2344979797 │ │ │ └── recording.har │ ├── getArchives_881889484 │ │ └── recording.har │ ├── mutation-1-with-masterKey_1386815290 │ │ └── recording.har │ ├── mutation-2-with-masterKey_2430815065 │ │ └── recording.har │ ├── mutation-by-client-should-be-rejected_2328768432 │ │ └── recording.har │ ├── query_4174280163 │ │ └── recording.har │ └── shoud-have-properties_2344979797 │ │ └── recording.har ├── ObjectACL_686985374 │ └── set-and-fetch-acl_477705090 │ │ └── recording.har ├── Objects_136869387 │ ├── -Saving-Objects_734425844 │ │ ├── should-crate-a-Object_1252906117 │ │ │ └── recording.har │ │ ├── should-create-a-User_2344521204 │ │ │ └── recording.har │ │ └── should-create-another-Object_3488117680 │ │ │ └── recording.har │ ├── Array-Data_43804130 │ │ ├── accept-array-param_460166929 │ │ │ └── recording.har │ │ ├── addUnique_624757339 │ │ │ └── recording.har │ │ ├── add_993596020 │ │ │ └── recording.har │ │ └── remove_3683784189 │ │ │ └── recording.har │ ├── Bit-operations_633833390 │ │ ├── bit-and_1788825609 │ │ │ └── recording.har │ │ ├── bit-or_2656474989 │ │ │ └── recording.har │ │ └── bit-xor_2267708325 │ │ │ └── recording.har │ ├── Deleting-Objects_1626626437 │ │ └── should-delete-object_1537042592 │ │ │ └── recording.har │ ├── Fetching-Objects_1241673741 │ │ ├── fetch-should-remove-deleted-keys_1235015609 │ │ │ └── recording.har │ │ ├── fetchAll-with-non-existed-Class_1732774206 │ │ │ └── object-should-fail_3925781535 │ │ │ │ └── recording.har │ │ ├── fetchAll_2292446774 │ │ │ └── recording.har │ │ └── fetch_2910765027 │ │ │ └── recording.har │ ├── Relational-Data_1128359924 │ │ ├── fetchOptions-keys_2424158557 │ │ │ └── recording.har │ │ ├── should-compatible-with-previous-include-option-of-fetch_3234965851 │ │ │ └── recording.har │ │ ├── should-create-a-Person_3530769578 │ │ │ └── recording.har │ │ ├── should-create-many-to-many-relations_1407352012 │ │ │ └── recording.har │ │ ├── should-fetch-include-authors-successfully_548451651 │ │ │ └── recording.har │ │ ├── should-fetch-when-save-when-creating-new-object-_2919684681 │ │ │ └── recording.har │ │ ├── should-fetch-when-save_592982047 │ │ │ └── recording.har │ │ ├── should-query-relational-data_3369127417 │ │ │ └── recording.har │ │ ├── should-save-all-partially_2114313946 │ │ │ └── recording.har │ │ ├── should-save-all-successfully_2711275917 │ │ │ └── recording.har │ │ └── should-set-relation-_570108726 │ │ │ └── recording.har │ ├── Retrieving-Objects_2244900730 │ │ └── should-be-the-just-save-Object_3889513002 │ │ │ └── recording.har │ └── Updating-Objects_3413221323 │ │ ├── should-not-update-prop-when-query-not-match_211364035 │ │ └── recording.har │ │ ├── should-update-prop-when-query-match_1479817141 │ │ └── recording.har │ │ └── should-update-prop_1422992344 │ │ └── recording.har ├── Queries_842530531 │ ├── -Basic-Queries_2120137160 │ │ ├── should-return-Class-Array_2034830301 │ │ │ └── recording.har │ │ ├── should-return-TestClass_3615366676 │ │ │ └── recording.har │ │ └── should-throw-when-object-not-exists_3742366688 │ │ │ └── recording.har │ ├── -File-Query_3474564568 │ │ └── recording.har │ ├── -cloudQuery_1998416685 │ │ ├── should-return-count-value-_1336084012 │ │ │ └── recording.har │ │ ├── should-return-count-value-too-_2597229118 │ │ │ └── recording.har │ │ ├── should-return-limited-results-_4046762198 │ │ │ └── recording.har │ │ ├── should-return-results-_1029991224 │ │ │ └── recording.har │ │ └── should-return-syntax-error-_1626848969 │ │ │ └── recording.har │ ├── All-Files_3339381387 │ │ └── should-return-AV-File-Object-list_834687804 │ │ │ └── recording.har │ ├── All-User_2070679183 │ │ └── should-return-AV-User-Object-list_1328405593 │ │ │ └── recording.har │ ├── Compound-Query_632679536 │ │ ├── should-satisfy-on-and-conditions_1689265471 │ │ │ └── recording.har │ │ └── should-satisfy-on-or-conditions_2078682385 │ │ │ └── recording.har │ ├── Counts_2261259173 │ │ └── should-return-num_2552064632 │ │ │ └── recording.har │ ├── Query-Constraints_3042071231 │ │ ├── basic_87360061 │ │ │ └── recording.har │ │ ├── containsAll-with-an-large-array-should-not-cause-URI-too-long_1886922003 │ │ │ └── recording.har │ │ ├── include-with-multi-params_3387938594 │ │ │ └── recording.har │ │ ├── includeACL_153220253 │ │ │ └── recording.har │ │ ├── include_1968798311 │ │ │ └── recording.har │ │ ├── param-check_3351637078 │ │ │ └── recording.har │ │ ├── select-with-multi-params_3146310132 │ │ │ └── recording.har │ │ ├── select_297952813 │ │ │ └── recording.har │ │ └── sizeEqualTo_1056335421 │ │ │ └── recording.har │ ├── Query-with-different-condtions_1390618707 │ │ └── query-doncition-with-array_1620466613 │ │ │ └── recording.har │ ├── Relational-Queries_3507322460 │ │ └── should-return-relation-count_2835530171 │ │ │ └── recording.har │ ├── destroyAll_418999268 │ │ └── should-be-deleted_943263470 │ │ │ └── recording.har │ └── scan_3974641896 │ │ └── should-works_2009598512 │ │ └── recording.har ├── Role_2418769465 │ └── constructor_4066221903 │ │ └── acl-is-required_3763596966 │ │ └── recording.har ├── User_3768991250 │ ├── Associations_1760271453 │ │ └── return-post-relation-to-user_948600757 │ │ │ └── recording.har │ ├── Current-User_1380399265 │ │ ├── current-_4079961613 │ │ │ └── recording.har │ │ └── currentAsync-_4006155249 │ │ │ └── recording.har │ ├── User-getRoles_2840946038 │ │ └── Should-get-the-current-user-s-role_30030259 │ │ │ └── recording.har │ ├── User-logIn-and-User-become_1707829842 │ │ ├── should-fail-with-wrong-password_995446848 │ │ │ └── recording.har │ │ ├── should-loginWithEmail_2640516273 │ │ │ └── recording.har │ │ └── should-login_817989515 │ │ │ └── recording.har │ ├── User-loginAnonymously_1844780739 │ │ ├── create-an-anonymous-user-and-then-associateWithAuthData_411731184 │ │ │ └── recording.har │ │ └── create-an-anonymous-user-and-then-signup_4063588952 │ │ │ └── recording.har │ ├── User-signUp_2418928912 │ │ ├── should-sign-up_2537997332 │ │ │ └── recording.har │ │ └── should-throw-when-required-field-missing_2393193183 │ │ │ └── recording.har │ ├── associate-with-authData_3638344631 │ │ └── logIn-an-user-and-associate-with-authData_2872736161 │ │ │ └── recording.har │ ├── authData-and-unionId_3520550132 │ │ ├── failOnNotExist_3834259720 │ │ │ └── recording.har │ │ └── should-login-as-the-same-user_1314336463 │ │ │ └── recording.har │ ├── authenticated_3520222456 │ │ ├── authenticated-_3192898843 │ │ │ └── recording.har │ │ └── isAuthenticated_2942338952 │ │ │ ├── currentUser-isAuthenticated-_625895223 │ │ │ └── recording.har │ │ │ ├── outdated-sessionToken_2526954518 │ │ │ └── recording.har │ │ │ └── user-isAuthenticated-_3902894676 │ │ │ └── recording.har │ ├── currentUser-disabled_1568416055 │ │ └── User_3768991250 │ │ │ └── recording.har │ ├── existing-user_3495910359 │ │ ├── Update-user-password_3119043600 │ │ │ └── should-update-password_2946486776 │ │ │ │ └── recording.har │ │ ├── User-query_1077910714 │ │ │ └── should-return-conditoinal-users_3844284628 │ │ │ │ └── recording.har │ │ ├── User-update_226365055 │ │ │ └── shoud-update-name_2931045486 │ │ │ │ └── recording.har │ │ └── fetch-User_3200994950 │ │ │ └── should-resolve-promise_2205418555 │ │ │ └── recording.har │ └── refreshSessionToken_403527525 │ │ └── User-refreshSessionToken_2206618895 │ │ └── recording.har └── hooks_2679941595 │ ├── Object-destroyAll_2713433654 │ └── recording.har │ ├── Object-destroy_3257794531 │ └── recording.har │ ├── Object-save-modify-children-_395790374 │ └── recording.har │ ├── Object-save-new-object-_4054548722 │ └── recording.har │ ├── Object-save-new-object-disableBeforeHook_1351232110 │ └── recording.har │ ├── Object-save-new-object-ignore-afterSave_3895694271 │ └── recording.har │ ├── Object-save-update-object-_2416096873 │ └── recording.har │ ├── Object-save-update-object-disableAfterHook_1726024070 │ └── recording.har │ └── Object-saveAll_4023780288 │ └── recording.har ├── script ├── check-version.js ├── deploy.sh ├── gh-deploy.sh ├── gh-release.sh └── release.sh ├── src ├── acl.js ├── adapter.js ├── app-router.js ├── av.js ├── cache.js ├── captcha.js ├── cloudfunction.js ├── conversation.js ├── entry │ ├── core-live-query.js │ ├── core.js │ ├── index-live-query.js │ ├── index.js │ ├── use-adapters.js │ └── use-live-query.js ├── error.js ├── event.js ├── file.js ├── friendship.js ├── geopoint.js ├── index.js ├── init.js ├── insight.js ├── leaderboard.js ├── live-query.js ├── localstorage.js ├── object.js ├── op.js ├── push.js ├── query.js ├── relation.js ├── request.js ├── role.js ├── search.js ├── status.js ├── uploader │ ├── cos.js │ ├── qiniu.js │ └── s3.js ├── user.js ├── utils │ ├── ajax.js │ ├── btoa.js │ ├── index.js │ ├── parse-base64-browser.js │ └── parse-base64.js └── version.js ├── storage.d.ts ├── test ├── acl.js ├── av.js ├── cache.js ├── captcha.js ├── cloud.js ├── conversation.js ├── error.js ├── file.js ├── geopoints.js ├── hooks.js ├── index.js ├── leaderboard.js ├── object.js ├── polly.js ├── query.js ├── role.js ├── search.js ├── sms.js ├── status.js ├── storage.js ├── test.html ├── test.js ├── user.js └── util.js └── webpack ├── browser.js ├── common.js ├── core.js └── weapp.js /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | insert_final_newline = true 8 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: 'airbnb', 3 | env: { 4 | node: true, 5 | mocha: true, 6 | browser: true, 7 | }, 8 | rules: { 9 | 'no-param-reassign': 0, 10 | 'no-underscore-dangle': 0, 11 | 'consistent-return': 0, 12 | 'no-else-return': 0, 13 | 'max-len': 0, 14 | 'no-console': [ 2, { allow: ['warn', 'trace'] } ], 15 | 'no-restricted-syntax': [ 0, 'ForInStatement' ], 16 | 'no-new': 0, 17 | 'new-cap': 0, 18 | 'default-case': 0, 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | push: 4 | branches: [master] 5 | pull_request: 6 | branches: [master] 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v3 12 | - uses: actions/setup-node@v3 13 | with: 14 | node-version: 16 15 | - run: npm ci 16 | - run: npm test 17 | env: 18 | SERVER_URL: https://qvnm6ag2.api.lncldglobal.com 19 | APPID: QvNM6AG2khJtBQo6WRMWqfLV-gzGzoHsz 20 | APPKEY: be2YmUduiuEnCB2VR9bLRnnV 21 | MASTERKEY: ${{ secrets.MASTER_KEY }} 22 | HOOKKEY: ${{ secrets.HOOK_KEY }} 23 | - uses: codecov/codecov-action@v3 24 | - run: npm run build 25 | - if: github.ref_name == 'master' 26 | run: | 27 | ./script/gh-release.sh 28 | ./script/gh-deploy.sh 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | package/ 3 | *tgz 4 | *.tar.gz 5 | coverage 6 | *.swp 7 | dist/js-sdk-api-docs 8 | npm-debug.log 9 | .nyc_output 10 | dist 11 | docs 12 | -------------------------------------------------------------------------------- /.jsdocrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "opts": { 3 | "template": "node_modules/docdash", 4 | "recurse": true 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | coverage 2 | demo 3 | docs 4 | node_modules 5 | src 6 | test 7 | webpack 8 | script 9 | recordings 10 | babel.config.json 11 | browserslist 12 | .gitignore 13 | .travis.yml 14 | gulpfile.babel.js 15 | readme.txt 16 | .nyc_output 17 | .editorconfig 18 | .eslintrc.js 19 | .jsdocrc.json 20 | .github 21 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | 3 | node_js: 4 | - '10' 5 | 6 | sudo: false 7 | install: 8 | - npm install -g codecov 9 | - npm install 10 | script: 11 | - npm test && codecov 12 | - npm run build 13 | after_success: 14 | - if [[ "$TRAVIS_BRANCH" == "master" ]] && [[ "${TRAVIS_PULL_REQUEST}" = "false" ]]; then 15 | ./script/release.sh; 16 | ./script/deploy.sh; 17 | fi 18 | - if [[ "$TRAVIS_BRANCH" == "next" ]] && [[ "${TRAVIS_PULL_REQUEST}" = "false" ]]; then 19 | ./script/release.sh next-dist; 20 | fi 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 LeanCloud 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LeanCloud JavaScript SDK 2 | 3 | [![npm](https://img.shields.io/npm/v/leancloud-storage.svg?style=flat-square)](https://www.npmjs.com/package/leancloud-storage) 4 | ![gzip size](http://img.badgesize.io/leancloud/javascript-sdk/dist/dist/av-min.js.svg?compression=gzip&style=flat-square) 5 | [![Build Status](https://img.shields.io/travis/leancloud/javascript-sdk.svg?style=flat-square)](https://travis-ci.org/leancloud/javascript-sdk) 6 | [![Codecov](https://img.shields.io/codecov/c/github/leancloud/javascript-sdk.svg?style=flat-square)](https://codecov.io/github/leancloud/javascript-sdk) 7 | [![Known Vulnerabilities](https://snyk.io/test/github/leancloud/javascript-sdk/badge.svg?style=flat-square)](https://snyk.io/test/github/leancloud/javascript-sdk) 8 | 9 | JavaScript SDK for [LeanCloud](http://leancloud.cn/). 10 | 11 | ## 安装 12 | 13 | ``` 14 | // npm 安装 15 | npm install leancloud-storage --save 16 | // npm 安装 2.x 版本 17 | npm install leancloud-storage@2 --save 18 | ``` 19 | 20 | ## 文档 21 | 22 | - [安装文档](https://leancloud.cn/docs/sdk_setup-js.html) 23 | - [使用文档](https://leancloud.cn/docs/leanstorage_guide-js.html) 24 | - [API 文档](https://leancloud.github.io/javascript-sdk/docs/) 25 | 26 | ## 支持 27 | 28 | - 如果你发现了新的 bug,或者有新的 feature request,请新建一个 issue 29 | - 在使用过程中遇到了问题时 30 | - 如果你是商用版用户,请新建一个工单。 31 | - 也可以在 [论坛](https://forum.leancloud.cn/) 提问、讨论。 32 | 33 | ## 贡献 34 | 35 | 如果你希望为这个项目贡献代码,请按以下步骤进行: 36 | 37 | - `fork` 这个项目 38 | - `npm install` 安装相关依赖 39 | - 开发和调试 40 | - 确保测试全部通过 `npm run test`,浏览器环境打开 `test/test.html` 41 | - 提交并发起 `Pull Request` 42 | 43 | 项目的目录结构说明如下: 44 | 45 | ``` 46 | ├── dist // 编译之后生成的文件将会在此目录下 47 | │ ├── av.js // 浏览器版本 48 | │ ├── av-min.js 49 | │ ├── av-weapp.js // 小程序版本 50 | │ ├── av-weapp-min.js 51 | │ ├── node // 目录中为生成的 nodejs 版本代码 52 | │ └── ... 53 | ├── src 54 | │ ├── index.js // node.js 环境入口文件 55 | │ └── ... 56 | └── test // 单元测试 57 | ``` 58 | 59 | ## 发布流程 60 | 61 | 1. 遵循 semver 提升版本号 62 | - src/version.js 63 | - package.json 64 | 2. 对照 commit 历史写 changelog 65 | 3. 提交当前所有改动 66 | 4. 等待持续集成 pass 67 | 5. 使用 GitHub 基于 dist 分支发布一个 release 68 | 6. Fetch and checkout remote `dist` branch 并确认该提交的内容是即将发布的版本 69 | 7. npm publish(`npm publish`,需 npm 协作者身份),如果是 pre-release 版本需要带 next tag 70 | -------------------------------------------------------------------------------- /babel.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | "modules": "commonjs" 7 | } 8 | ] 9 | ], 10 | "plugins": [ 11 | [ 12 | "@babel/plugin-transform-runtime", 13 | { 14 | "corejs": 3 15 | } 16 | ], 17 | [ 18 | "transform-inline-environment-variables", 19 | { 20 | "include": ["PLATFORM"] 21 | } 22 | ] 23 | ], 24 | "env": { 25 | "test": { 26 | "plugins": ["istanbul"] 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /browserslist: -------------------------------------------------------------------------------- 1 | > 0.25% 2 | not dead -------------------------------------------------------------------------------- /core.d.ts: -------------------------------------------------------------------------------- 1 | export * from './storage'; 2 | -------------------------------------------------------------------------------- /core.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./dist/av-core'); 2 | -------------------------------------------------------------------------------- /demo/leaderboard/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | LeanCloud Leaderboard Demo 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 |
15 |
16 | 17 | 18 |
19 |   20 | 21 |
22 |
23 |
24 |
25 |
26 | 27 | {{ score || '🎲' }} 28 | 29 | 30 | 新纪录 31 | 32 |
33 |
34 | 35 |
  • 36 | {{ranking.rank + 1}}.  37 | {{ranking.user.username}} 38 | (你) 39 | 40 | 41 | 42 | 43 |
  • 44 |
    45 | 46 |
    47 |
    下次重置时间:{{ nextResetAt }} 48 | 49 | 50 |
    51 |
    52 | Powered by LeanCloud 53 | 54 | 源码 55 | 56 | {{user.username}}(注销 57 |
    58 |
    59 | 60 |
    61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /demo/leaderboard/leaderboard.css: -------------------------------------------------------------------------------- 1 | body, 2 | html { 3 | background: linear-gradient(320deg, #581b98, #9c1de7); 4 | height: 100vh; 5 | width: 100vw; 6 | margin: 0; 7 | color: white; 8 | font-family: radikal, sans-serif; 9 | } 10 | 11 | a, 12 | a:active, 13 | a:visited { 14 | color: white; 15 | text-decoration: none; 16 | } 17 | 18 | #app { 19 | height: 100%; 20 | display: flex; 21 | flex-direction: column; 22 | } 23 | 24 | [v-cloak] { 25 | display: none; 26 | } 27 | 28 | .center { 29 | top: 50%; 30 | left: 50%; 31 | transform: translate(-50%, -50%); 32 | position: fixed; 33 | z-index: 1000; 34 | } 35 | 36 | #dice-wrapper { 37 | height: 8.5rem; 38 | width: 8.5rem; 39 | } 40 | 41 | .dice { 42 | background: #fefefe; 43 | border-radius: 10px; 44 | box-shadow: 4px 3px 12px 2px #333; 45 | height: 100%; 46 | width: 100%; 47 | cursor: pointer; 48 | display: inline-block; 49 | text-align: center; 50 | } 51 | 52 | .dice .score { 53 | color: black; 54 | line-height: 8.5rem; 55 | font-size: 4rem; 56 | } 57 | 58 | .new-high-score { 59 | position: absolute; 60 | top: -2em; 61 | width: 100%; 62 | left: 0; 63 | } 64 | 65 | .ranking-list { 66 | height: 100%; 67 | flex: 1; 68 | margin: 0; 69 | padding: 0; 70 | list-style: none; 71 | display: flex; 72 | flex-direction: column; 73 | font-size: 1.4em; 74 | overflow: auto; 75 | } 76 | 77 | .ranking { 78 | background: linear-gradient(320deg, #581b98, #9c1de7); 79 | height: 100%; 80 | max-height: 8.333%; 81 | min-height: 44px; 82 | flex: 1; 83 | display: flex; 84 | align-items: center; 85 | padding: 0 10px; 86 | transition: all 1s; 87 | position: relative; 88 | } 89 | 90 | .ranking-list-move { 91 | transition: transform 1s; 92 | } 93 | 94 | .ranking-list-enter, 95 | .ranking-list-leave-to { 96 | opacity: 0; 97 | transform: translateY(-30px); 98 | } 99 | .ranking-list-leave-active { 100 | position: absolute; 101 | } 102 | 103 | .ranking:nth-child(1) { 104 | color: gold; 105 | } 106 | .ranking:nth-child(2) { 107 | color: lightgray; 108 | } 109 | .ranking:nth-child(3) { 110 | color: sandybrown; 111 | } 112 | 113 | .username { 114 | width: 100%; 115 | flex: 1; 116 | } 117 | .ranking .score { 118 | max-width: 44px; 119 | overflow: hidden; 120 | } 121 | 122 | .operations { 123 | padding: 6px 0; 124 | text-align: center; 125 | color: #ddd; 126 | } 127 | 128 | .operations .separator { 129 | display: inline-block; 130 | margin: 0 0.4em; 131 | } 132 | 133 | #overlay { 134 | width: 100%; 135 | background: rgba(0, 0, 0, 0.8); 136 | } 137 | #login { 138 | width: 300px; 139 | margin: 0 auto; 140 | padding: 14px 0 18px; 141 | display: flex; 142 | flex-direction: column; 143 | } 144 | 145 | #login input { 146 | box-sizing: border-box; 147 | width: 100%; 148 | background: transparent; 149 | border: 1px solid #ffffff99; 150 | border-width: 0 0 2px 0; 151 | border-radius: 0; 152 | color: white; 153 | font-size: 20px; 154 | text-align: center; 155 | padding: 10px 6px 14px; 156 | margin: 0 0 4px; 157 | } 158 | #login input:hover { 159 | background: #ffffff18; 160 | } 161 | #login input:focus { 162 | background: #ffffff28; 163 | } 164 | 165 | .control { 166 | display: flex; 167 | } 168 | -------------------------------------------------------------------------------- /demo/settings/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
    8 |
    9 |
    10 | 11 |
    12 |
    13 | 14 |
    15 |
    16 | 17 |
    18 |
    19 | Presets: 20 |
    21 | 25 |
    26 |
    27 |
    28 | 29 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /live-query-core.d.ts: -------------------------------------------------------------------------------- 1 | export * from './storage'; 2 | -------------------------------------------------------------------------------- /live-query-core.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./dist/av-live-query-core'); 2 | -------------------------------------------------------------------------------- /live-query.d.ts: -------------------------------------------------------------------------------- 1 | export * from './storage'; 2 | -------------------------------------------------------------------------------- /live-query.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./dist/node/entry/index-live-query'); 2 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "leancloud-storage", 3 | "version": "4.15.3", 4 | "main": "./dist/node/entry/index.js", 5 | "description": "LeanCloud JavaScript SDK.", 6 | "repository": { 7 | "type": "git", 8 | "url": "https://github.com/leancloud/javascript-sdk" 9 | }, 10 | "scripts": { 11 | "precommit": "pretty-quick --staged", 12 | "lint": "tsc storage.d.ts --strict", 13 | "test": "npm run lint && npm run test:node", 14 | "test:node": "cross-env NODE_ENV=test PLATFORM=NODE_JS nyc mocha --timeout 300000 test/index.js", 15 | "test:real": "cross-env REAL_BACKEND=1 npm run test:node", 16 | "docs": "jsdoc src README.md package.json -d docs -c .jsdocrc.json", 17 | "build:node": "cross-env PLATFORM=NODE_JS babel src --out-dir dist/node", 18 | "build:core": "cross-env webpack --config webpack/core.js", 19 | "build:browser": "cross-env PLATFORM=Browser webpack --config webpack/browser.js", 20 | "build:weapp": "cross-env PLATFORM=Weapp webpack --config webpack/weapp.js", 21 | "build:platforms": "npm run build:core && npm run build:browser && npm run build:weapp", 22 | "build": "rimraf dist && npm run build:node && npm run build:platforms && cross-env LIVE_QUERY=1 npm run build:platforms", 23 | "prepublishOnly": "./script/check-version.js" 24 | }, 25 | "dependencies": { 26 | "@babel/runtime-corejs3": "^7.18.6", 27 | "@leancloud/adapter-types": "^5.0.0", 28 | "@leancloud/platform-adapters-browser": "^1.5.3", 29 | "@leancloud/platform-adapters-node": "^1.6.0", 30 | "@leancloud/platform-adapters-weapp": "^1.6.3", 31 | "debug": "^3.1.0", 32 | "eventemitter3": "^2.0.3", 33 | "leancloud-realtime": "^5.0.0-rc.8", 34 | "leancloud-realtime-plugin-live-query": "^1.2.0", 35 | "md5": "^2.0.0", 36 | "promise-timeout": "^1.3.0", 37 | "underscore": "^1.8.3", 38 | "uuid": "^3.3.2" 39 | }, 40 | "devDependencies": { 41 | "@babel/cli": "^7.18.6", 42 | "@babel/core": "^7.18.6", 43 | "@babel/plugin-transform-runtime": "^7.18.6", 44 | "@babel/preset-env": "^7.18.6", 45 | "@babel/register": "^7.18.6", 46 | "@pollyjs/adapter-node-http": "^2.6.2", 47 | "@pollyjs/core": "^2.6.2", 48 | "@pollyjs/persister-fs": "^2.6.2", 49 | "babel-loader": "^8.2.5", 50 | "babel-plugin-istanbul": "^6.1.1", 51 | "babel-plugin-transform-inline-environment-variables": "^0.4.4", 52 | "cross-env": "^5.1.3", 53 | "docdash": "git+https://github.com/leeyeh/docdash.git#leancloud", 54 | "eslint": "^2.8.0", 55 | "eslint-config-airbnb": "^8.0.0", 56 | "eslint-plugin-import": "^1.6.0", 57 | "eslint-plugin-jsx-a11y": "^1.0.3", 58 | "eslint-plugin-react": "^5.0.1", 59 | "expect.js": "^0.3.0", 60 | "husky": "^0.14.3", 61 | "jsdoc": "^3.5.5", 62 | "mocha": "^3.0.0", 63 | "nyc": "^15.1.0", 64 | "prettier": "^1.11.1", 65 | "pretty-quick": "^1.4.1", 66 | "rimraf": "^3.0.2", 67 | "should": "^11.1.0", 68 | "typescript": "^3.8.3", 69 | "webpack": "^3.11.0", 70 | "webpack-strip-block": "^0.2.0" 71 | }, 72 | "license": "MIT", 73 | "author": { 74 | "name": "LeanCloud", 75 | "email": "support@leancloud.rocks" 76 | }, 77 | "browser": { 78 | "@leancloud/platform-adapters-node": "@leancloud/platform-adapters-browser", 79 | "./src/utils/parse-base64.js": "./src/utils/parse-base64-browser.js", 80 | "./dist/node/entry/index.js": "./dist/av.js" 81 | }, 82 | "react-native": { 83 | "./dist/node/entry/index.js": "./dist/av-core.js" 84 | }, 85 | "weapp": { 86 | "@leancloud/platform-adapters-node": "@leancloud/platform-adapters-weapp", 87 | "./dist/node/entry/index.js": "./dist/av-weapp.js" 88 | }, 89 | "typings": "./storage.d.ts", 90 | "types": "./storage.d.ts", 91 | "prettier": { 92 | "singleQuote": true, 93 | "trailingComma": "es5" 94 | }, 95 | "nyc": { 96 | "require": [ 97 | "@babel/register" 98 | ], 99 | "reporter": [ 100 | "lcov", 101 | "text" 102 | ], 103 | "sourceMap": false, 104 | "instrument": false 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /recordings/AV-Cloud_4059047921/-getServerDate_3861860821/should-return-a-date-_3033254009/recording.har: -------------------------------------------------------------------------------- 1 | { 2 | "log": { 3 | "_recordingName": "AV.Cloud/#getServerDate/should return a date.", 4 | "creator": { 5 | "comment": "persister:fs", 6 | "name": "Polly.JS", 7 | "version": "2.6.2" 8 | }, 9 | "entries": [ 10 | { 11 | "_id": "8155709efbda6b6b32cde46b6ec2d7c6", 12 | "_order": 0, 13 | "cache": {}, 14 | "request": { 15 | "bodySize": 4, 16 | "cookies": [], 17 | "headers": [ 18 | { 19 | "name": "accept-encoding", 20 | "value": "gzip, deflate" 21 | }, 22 | { 23 | "name": "user-agent", 24 | "value": "LeanCloud-JS-SDK/3.15.0 (Node.js; Node.js/v12.10.0)" 25 | }, 26 | { 27 | "name": "x-lc-id", 28 | "value": "4h2h4okwiyn8b6cle0oig00vitayum8ephrlsvg7xo8o19ne" 29 | }, 30 | { 31 | "name": "content-type", 32 | "value": "application/json;charset=UTF-8" 33 | }, 34 | { 35 | "name": "x-lc-sign", 36 | "value": "67204e7642ff21c258fe4ad334dfc0eb,1568868348587" 37 | }, 38 | { 39 | "name": "x-lc-hook-key", 40 | "value": "2iCbUZDgEF0siKxmCn2kVQXV" 41 | }, 42 | { 43 | "name": "x-lc-prod", 44 | "value": "1" 45 | }, 46 | { 47 | "name": "content-length", 48 | "value": 4 49 | }, 50 | { 51 | "name": "host", 52 | "value": "api.leancloud.cn" 53 | } 54 | ], 55 | "headersSize": 409, 56 | "httpVersion": "HTTP/1.1", 57 | "method": "GET", 58 | "postData": { 59 | "mimeType": "application/json;charset=UTF-8", 60 | "params": [], 61 | "text": "null" 62 | }, 63 | "queryString": [], 64 | "url": "https://api.leancloud.cn/1.1/date" 65 | }, 66 | "response": { 67 | "bodySize": 140, 68 | "content": { 69 | "mimeType": "application/json;charset=utf-8", 70 | "size": 140, 71 | "text": "[\"1f8b0800000000000003ab568a8f2fa92c4855b25272492c4955d251ca2cce07728c0c0c2d750d2c750d2d430c4cac4c4cad4c2cf4cc8ccca2946a016b66a42232000000\"]" 72 | }, 73 | "cookies": [], 74 | "headers": [ 75 | { 76 | "name": "server", 77 | "value": "openresty" 78 | }, 79 | { 80 | "name": "date", 81 | "value": "Thu, 19 Sep 2019 04:45:48 GMT" 82 | }, 83 | { 84 | "name": "content-type", 85 | "value": "application/json;charset=utf-8" 86 | }, 87 | { 88 | "name": "transfer-encoding", 89 | "value": "chunked" 90 | }, 91 | { 92 | "name": "connection", 93 | "value": "close" 94 | }, 95 | { 96 | "name": "vary", 97 | "value": "Accept-Encoding" 98 | }, 99 | { 100 | "name": "cache-control", 101 | "value": "no-cache,no-store" 102 | }, 103 | { 104 | "name": "pragma", 105 | "value": "no-cache" 106 | }, 107 | { 108 | "name": "strict-transport-security", 109 | "value": "max-age=31536000" 110 | }, 111 | { 112 | "name": "content-encoding", 113 | "value": "gzip" 114 | } 115 | ], 116 | "headersSize": 295, 117 | "httpVersion": "HTTP/1.1", 118 | "redirectURL": "", 119 | "status": 200, 120 | "statusText": "OK" 121 | }, 122 | "startedDateTime": "2019-09-19T04:45:48.589Z", 123 | "time": 39, 124 | "timings": { 125 | "blocked": -1, 126 | "connect": -1, 127 | "dns": -1, 128 | "receive": 0, 129 | "send": 0, 130 | "ssl": -1, 131 | "wait": 39 132 | } 133 | } 134 | ], 135 | "pages": [], 136 | "version": "1.2" 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /recordings/AV-Cloud_4059047921/-rpc_2399869033/send-bare-AVObject_2666081587/recording.har: -------------------------------------------------------------------------------- 1 | { 2 | "log": { 3 | "_recordingName": "AV.Cloud/#rpc/send bare AVObject", 4 | "creator": { 5 | "comment": "persister:fs", 6 | "name": "Polly.JS", 7 | "version": "2.6.2" 8 | }, 9 | "entries": [ 10 | { 11 | "_id": "260af08bb560f57392d7e98658891595", 12 | "_order": 0, 13 | "cache": {}, 14 | "request": { 15 | "bodySize": 269, 16 | "cookies": [], 17 | "headers": [ 18 | { 19 | "name": "accept-encoding", 20 | "value": "gzip, deflate" 21 | }, 22 | { 23 | "name": "x-lc-id", 24 | "value": "4h2h4okwiyn8b6cle0oig00vitayum8ephrlsvg7xo8o19ne" 25 | }, 26 | { 27 | "name": "content-type", 28 | "value": "application/json;charset=UTF-8" 29 | }, 30 | { 31 | "name": "x-lc-sign", 32 | "value": "798d11503491db6eebb68324fb4e8cd0,1608272583725" 33 | }, 34 | { 35 | "name": "x-lc-hook-key", 36 | "value": "2iCbUZDgEF0siKxmCn2kVQXV" 37 | }, 38 | { 39 | "name": "x-lc-prod", 40 | "value": "1" 41 | }, 42 | { 43 | "name": "user-agent", 44 | "value": "LeanCloud-JS-SDK/4.8.3 (Node.js/14.15.0)" 45 | }, 46 | { 47 | "name": "content-length", 48 | "value": 269 49 | }, 50 | { 51 | "name": "host", 52 | "value": "api.leancloud.cn" 53 | } 54 | ], 55 | "headersSize": 424, 56 | "httpVersion": "HTTP/1.1", 57 | "method": "POST", 58 | "postData": { 59 | "mimeType": "application/json;charset=UTF-8", 60 | "params": [], 61 | "text": "{\"name\":\"avObject\",\"avFile\":{\"name\":\"hello.txt\",\"url\":\"http://ac-1qdney6b.qiniudn.com/3zLG4o0d27MsCQ0qHGRg4JUKbaXU2fiE35HdhC8j.txt\",\"metaData\":{\"owner\":\"unknown\",\"__source\":\"external\",\"size\":0},\"base64\":\"\",\"__type\":\"File\"},\"__type\":\"Object\",\"className\":\"ComplexObject\"}" 62 | }, 63 | "queryString": [], 64 | "url": "https://api.leancloud.cn/1.1/call/testBareAVObjectParams" 65 | }, 66 | "response": { 67 | "bodySize": 13, 68 | "content": { 69 | "mimeType": "application/json; charset=UTF-8", 70 | "size": 13, 71 | "text": "{\"result\":{}}" 72 | }, 73 | "cookies": [], 74 | "headers": [ 75 | { 76 | "name": "server", 77 | "value": "openresty" 78 | }, 79 | { 80 | "name": "date", 81 | "value": "Fri, 18 Dec 2020 06:23:03 GMT" 82 | }, 83 | { 84 | "name": "content-type", 85 | "value": "application/json; charset=UTF-8" 86 | }, 87 | { 88 | "name": "content-length", 89 | "value": "13" 90 | }, 91 | { 92 | "name": "connection", 93 | "value": "close" 94 | }, 95 | { 96 | "name": "x-request-biztype", 97 | "value": "unknown" 98 | }, 99 | { 100 | "name": "x-powered-by", 101 | "value": "Express" 102 | }, 103 | { 104 | "name": "access-control-allow-origin", 105 | "value": "*" 106 | }, 107 | { 108 | "name": "access-control-request-headers", 109 | "value": "Content-Type, X-LC-Id, X-LC-Prod, X-LC-Session, X-LC-Sign, X-LC-UA" 110 | }, 111 | { 112 | "name": "access-control-request-method", 113 | "value": "POST" 114 | } 115 | ], 116 | "headersSize": 364, 117 | "httpVersion": "HTTP/1.1", 118 | "redirectURL": "", 119 | "status": 200, 120 | "statusText": "OK" 121 | }, 122 | "startedDateTime": "2020-12-18T06:23:03.727Z", 123 | "time": 42, 124 | "timings": { 125 | "blocked": -1, 126 | "connect": -1, 127 | "dns": -1, 128 | "receive": 0, 129 | "send": 0, 130 | "ssl": -1, 131 | "wait": 42 132 | } 133 | } 134 | ], 135 | "pages": [], 136 | "version": "1.2" 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /recordings/Conversation_2640583206/-save_2867845407/should-create-a-realtime-conversation_2600615093/recording.har: -------------------------------------------------------------------------------- 1 | { 2 | "log": { 3 | "_recordingName": "Conversation/#save/should create a realtime conversation", 4 | "creator": { 5 | "comment": "persister:fs", 6 | "name": "Polly.JS", 7 | "version": "2.6.2" 8 | }, 9 | "entries": [ 10 | { 11 | "_id": "96bb83faae305051090bdd7504d681b1", 12 | "_order": 0, 13 | "cache": {}, 14 | "request": { 15 | "bodySize": 62, 16 | "cookies": [], 17 | "headers": [ 18 | { 19 | "name": "accept-encoding", 20 | "value": "gzip, deflate" 21 | }, 22 | { 23 | "name": "user-agent", 24 | "value": "LeanCloud-JS-SDK/3.15.0 (Node.js; Node.js/v12.10.0)" 25 | }, 26 | { 27 | "name": "x-lc-id", 28 | "value": "95TNUaOSUd8IpKNW0RSqSEOm-9Nh9j0Va" 29 | }, 30 | { 31 | "name": "content-type", 32 | "value": "application/json;charset=UTF-8" 33 | }, 34 | { 35 | "name": "x-lc-sign", 36 | "value": "185cb5e09a5990209b80a9f4e08a1a08,1569224674526" 37 | }, 38 | { 39 | "name": "x-lc-hook-key", 40 | "value": "2iCbUZDgEF0siKxmCn2kVQXV" 41 | }, 42 | { 43 | "name": "x-lc-prod", 44 | "value": "1" 45 | }, 46 | { 47 | "name": "content-length", 48 | "value": 62 49 | }, 50 | { 51 | "name": "host", 52 | "value": "95tnuaos.api.lncldapi.com" 53 | } 54 | ], 55 | "headersSize": 431, 56 | "httpVersion": "HTTP/1.1", 57 | "method": "POST", 58 | "postData": { 59 | "mimeType": "application/json;charset=UTF-8", 60 | "params": [], 61 | "text": "{\"name\":\"test\",\"m\":{\"__op\":\"Add\",\"objects\":[\"test1\",\"test2\"]}}" 62 | }, 63 | "queryString": [], 64 | "url": "https://95tnuaos.api.lncldapi.com/1.1/classes/_Conversation" 65 | }, 66 | "response": { 67 | "bodySize": 78, 68 | "content": { 69 | "mimeType": "application/json;charset=utf-8", 70 | "size": 78, 71 | "text": "{\"objectId\":\"5d8877e253b36f00083ce254\",\"createdAt\":\"2019-09-23T07:44:34.665Z\"}" 72 | }, 73 | "cookies": [], 74 | "headers": [ 75 | { 76 | "name": "server", 77 | "value": "openresty" 78 | }, 79 | { 80 | "name": "date", 81 | "value": "Mon, 23 Sep 2019 07:44:34 GMT" 82 | }, 83 | { 84 | "name": "content-type", 85 | "value": "application/json;charset=utf-8" 86 | }, 87 | { 88 | "name": "transfer-encoding", 89 | "value": "chunked" 90 | }, 91 | { 92 | "name": "connection", 93 | "value": "close" 94 | }, 95 | { 96 | "name": "cache-control", 97 | "value": "no-cache,no-store" 98 | }, 99 | { 100 | "name": "pragma", 101 | "value": "no-cache" 102 | }, 103 | { 104 | "name": "location", 105 | "value": "/1.1/classes/_Conversation/5d8877e253b36f00083ce254" 106 | } 107 | ], 108 | "headersSize": 266, 109 | "httpVersion": "HTTP/1.1", 110 | "redirectURL": "/1.1/classes/_Conversation/5d8877e253b36f00083ce254", 111 | "status": 201, 112 | "statusText": "Created" 113 | }, 114 | "startedDateTime": "2019-09-23T07:44:34.527Z", 115 | "time": 161, 116 | "timings": { 117 | "blocked": -1, 118 | "connect": -1, 119 | "dns": -1, 120 | "receive": 0, 121 | "send": 0, 122 | "ssl": -1, 123 | "wait": 161 124 | } 125 | } 126 | ], 127 | "pages": [], 128 | "version": "1.2" 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /recordings/Geopoints_1459669221/save-object-with-geopoints_2892866483/recording.har: -------------------------------------------------------------------------------- 1 | { 2 | "log": { 3 | "_recordingName": "Geopoints/save object with geopoints", 4 | "creator": { 5 | "comment": "persister:fs", 6 | "name": "Polly.JS", 7 | "version": "2.6.2" 8 | }, 9 | "entries": [ 10 | { 11 | "_id": "1c281391ca6fd690f4cd993db0cbd20f", 12 | "_order": 0, 13 | "cache": {}, 14 | "request": { 15 | "bodySize": 118, 16 | "cookies": [], 17 | "headers": [ 18 | { 19 | "name": "accept-encoding", 20 | "value": "gzip, deflate" 21 | }, 22 | { 23 | "name": "user-agent", 24 | "value": "LeanCloud-JS-SDK/3.15.0 (Node.js; Node.js/v12.10.0)" 25 | }, 26 | { 27 | "name": "x-lc-id", 28 | "value": "95TNUaOSUd8IpKNW0RSqSEOm-9Nh9j0Va" 29 | }, 30 | { 31 | "name": "content-type", 32 | "value": "application/json;charset=UTF-8" 33 | }, 34 | { 35 | "name": "x-lc-sign", 36 | "value": "cccc1865d4c18d5cb3afd65dbe0de37e,1568868348166" 37 | }, 38 | { 39 | "name": "x-lc-hook-key", 40 | "value": "2iCbUZDgEF0siKxmCn2kVQXV" 41 | }, 42 | { 43 | "name": "x-lc-prod", 44 | "value": "1" 45 | }, 46 | { 47 | "name": "content-length", 48 | "value": 118 49 | }, 50 | { 51 | "name": "host", 52 | "value": "95tnuaos.api.lncldapi.com" 53 | } 54 | ], 55 | "headersSize": 423, 56 | "httpVersion": "HTTP/1.1", 57 | "method": "POST", 58 | "postData": { 59 | "mimeType": "application/json;charset=UTF-8", 60 | "params": [], 61 | "text": "{\"title\":\"Post Geopoints\",\"body\":\" Geopoints content.\",\"location\":{\"__type\":\"GeoPoint\",\"latitude\":40,\"longitude\":-30}}" 62 | }, 63 | "queryString": [], 64 | "url": "https://95tnuaos.api.lncldapi.com/1.1/classes/Post" 65 | }, 66 | "response": { 67 | "bodySize": 78, 68 | "content": { 69 | "mimeType": "application/json;charset=utf-8", 70 | "size": 78, 71 | "text": "{\"objectId\":\"5d8307fc9c9235000886c4bf\",\"createdAt\":\"2019-09-19T04:45:48.354Z\"}" 72 | }, 73 | "cookies": [], 74 | "headers": [ 75 | { 76 | "name": "server", 77 | "value": "openresty" 78 | }, 79 | { 80 | "name": "date", 81 | "value": "Thu, 19 Sep 2019 04:45:48 GMT" 82 | }, 83 | { 84 | "name": "content-type", 85 | "value": "application/json;charset=utf-8" 86 | }, 87 | { 88 | "name": "transfer-encoding", 89 | "value": "chunked" 90 | }, 91 | { 92 | "name": "connection", 93 | "value": "close" 94 | }, 95 | { 96 | "name": "cache-control", 97 | "value": "no-cache,no-store" 98 | }, 99 | { 100 | "name": "pragma", 101 | "value": "no-cache" 102 | }, 103 | { 104 | "name": "location", 105 | "value": "/1.1/classes/Post/5d8307fc9c9235000886c4bf" 106 | } 107 | ], 108 | "headersSize": 257, 109 | "httpVersion": "HTTP/1.1", 110 | "redirectURL": "/1.1/classes/Post/5d8307fc9c9235000886c4bf", 111 | "status": 201, 112 | "statusText": "Created" 113 | }, 114 | "startedDateTime": "2019-09-19T04:45:48.171Z", 115 | "time": 209, 116 | "timings": { 117 | "blocked": -1, 118 | "connect": -1, 119 | "dns": -1, 120 | "receive": 0, 121 | "send": 0, 122 | "ssl": -1, 123 | "wait": 209 124 | } 125 | } 126 | ], 127 | "pages": [], 128 | "version": "1.2" 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /recordings/Objects_136869387/-Saving-Objects_734425844/should-crate-a-Object_1252906117/recording.har: -------------------------------------------------------------------------------- 1 | { 2 | "log": { 3 | "_recordingName": "Objects/#Saving Objects/should crate a Object", 4 | "creator": { 5 | "comment": "persister:fs", 6 | "name": "Polly.JS", 7 | "version": "2.6.2" 8 | }, 9 | "entries": [ 10 | { 11 | "_id": "c538ec0217226d447b662077c6343183", 12 | "_order": 0, 13 | "cache": {}, 14 | "request": { 15 | "bodySize": 123, 16 | "cookies": [], 17 | "headers": [ 18 | { 19 | "name": "accept-encoding", 20 | "value": "gzip, deflate" 21 | }, 22 | { 23 | "name": "user-agent", 24 | "value": "LeanCloud-JS-SDK/3.15.0 (Node.js; Node.js/v12.10.0)" 25 | }, 26 | { 27 | "name": "x-lc-id", 28 | "value": "95TNUaOSUd8IpKNW0RSqSEOm-9Nh9j0Va" 29 | }, 30 | { 31 | "name": "content-type", 32 | "value": "application/json;charset=UTF-8" 33 | }, 34 | { 35 | "name": "x-lc-sign", 36 | "value": "f5228a4138fe55516c167a2378c1ba33,1568868353756" 37 | }, 38 | { 39 | "name": "x-lc-hook-key", 40 | "value": "2iCbUZDgEF0siKxmCn2kVQXV" 41 | }, 42 | { 43 | "name": "x-lc-prod", 44 | "value": "1" 45 | }, 46 | { 47 | "name": "content-length", 48 | "value": 123 49 | }, 50 | { 51 | "name": "host", 52 | "value": "95tnuaos.api.lncldapi.com" 53 | } 54 | ], 55 | "headersSize": 423, 56 | "httpVersion": "HTTP/1.1", 57 | "method": "POST", 58 | "postData": { 59 | "mimeType": "application/json;charset=UTF-8", 60 | "params": [], 61 | "text": "{\"title\":\"post1\",\"content\":\"Where should we go for lunch?\",\"geo\":{\"__type\":\"GeoPoint\",\"latitude\":80.01,\"longitude\":-30.01}}" 62 | }, 63 | "queryString": [], 64 | "url": "https://95tnuaos.api.lncldapi.com/1.1/classes/Post" 65 | }, 66 | "response": { 67 | "bodySize": 78, 68 | "content": { 69 | "mimeType": "application/json;charset=utf-8", 70 | "size": 78, 71 | "text": "{\"objectId\":\"5d8308019c9235000886c4ce\",\"createdAt\":\"2019-09-19T04:45:53.884Z\"}" 72 | }, 73 | "cookies": [], 74 | "headers": [ 75 | { 76 | "name": "server", 77 | "value": "openresty" 78 | }, 79 | { 80 | "name": "date", 81 | "value": "Thu, 19 Sep 2019 04:45:53 GMT" 82 | }, 83 | { 84 | "name": "content-type", 85 | "value": "application/json;charset=utf-8" 86 | }, 87 | { 88 | "name": "transfer-encoding", 89 | "value": "chunked" 90 | }, 91 | { 92 | "name": "connection", 93 | "value": "close" 94 | }, 95 | { 96 | "name": "cache-control", 97 | "value": "no-cache,no-store" 98 | }, 99 | { 100 | "name": "pragma", 101 | "value": "no-cache" 102 | }, 103 | { 104 | "name": "location", 105 | "value": "/1.1/classes/Post/5d8308019c9235000886c4ce" 106 | } 107 | ], 108 | "headersSize": 257, 109 | "httpVersion": "HTTP/1.1", 110 | "redirectURL": "/1.1/classes/Post/5d8308019c9235000886c4ce", 111 | "status": 201, 112 | "statusText": "Created" 113 | }, 114 | "startedDateTime": "2019-09-19T04:45:53.756Z", 115 | "time": 149, 116 | "timings": { 117 | "blocked": -1, 118 | "connect": -1, 119 | "dns": -1, 120 | "receive": 0, 121 | "send": 0, 122 | "ssl": -1, 123 | "wait": 149 124 | } 125 | } 126 | ], 127 | "pages": [], 128 | "version": "1.2" 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /recordings/Objects_136869387/-Saving-Objects_734425844/should-create-another-Object_3488117680/recording.har: -------------------------------------------------------------------------------- 1 | { 2 | "log": { 3 | "_recordingName": "Objects/#Saving Objects/should create another Object", 4 | "creator": { 5 | "comment": "persister:fs", 6 | "name": "Polly.JS", 7 | "version": "2.6.2" 8 | }, 9 | "entries": [ 10 | { 11 | "_id": "0a735249d63b37423c94ca4ffc0d982e", 12 | "_order": 0, 13 | "cache": {}, 14 | "request": { 15 | "bodySize": 82, 16 | "cookies": [], 17 | "headers": [ 18 | { 19 | "name": "accept-encoding", 20 | "value": "gzip, deflate" 21 | }, 22 | { 23 | "name": "user-agent", 24 | "value": "LeanCloud-JS-SDK/3.15.0 (Node.js; Node.js/v12.10.0)" 25 | }, 26 | { 27 | "name": "x-lc-id", 28 | "value": "95TNUaOSUd8IpKNW0RSqSEOm-9Nh9j0Va" 29 | }, 30 | { 31 | "name": "content-type", 32 | "value": "application/json;charset=UTF-8" 33 | }, 34 | { 35 | "name": "x-lc-sign", 36 | "value": "fdb5b18493401bc1e3da54db7009945c,1568868353911" 37 | }, 38 | { 39 | "name": "x-lc-hook-key", 40 | "value": "2iCbUZDgEF0siKxmCn2kVQXV" 41 | }, 42 | { 43 | "name": "x-lc-prod", 44 | "value": "1" 45 | }, 46 | { 47 | "name": "content-length", 48 | "value": 82 49 | }, 50 | { 51 | "name": "host", 52 | "value": "95tnuaos.api.lncldapi.com" 53 | } 54 | ], 55 | "headersSize": 427, 56 | "httpVersion": "HTTP/1.1", 57 | "method": "POST", 58 | "postData": { 59 | "mimeType": "application/json;charset=UTF-8", 60 | "params": [], 61 | "text": "{\"score\":1111,\"playerName\":\"dd\",\"cheatMode\":false,\"arr\":[\"arr1\",\"arr2\"],\"id\":\"id\"}" 62 | }, 63 | "queryString": [], 64 | "url": "https://95tnuaos.api.lncldapi.com/1.1/classes/GameScore" 65 | }, 66 | "response": { 67 | "bodySize": 78, 68 | "content": { 69 | "mimeType": "application/json;charset=utf-8", 70 | "size": 78, 71 | "text": "{\"objectId\":\"5d8308029c9235000886c4cf\",\"createdAt\":\"2019-09-19T04:45:54.076Z\"}" 72 | }, 73 | "cookies": [], 74 | "headers": [ 75 | { 76 | "name": "server", 77 | "value": "openresty" 78 | }, 79 | { 80 | "name": "date", 81 | "value": "Thu, 19 Sep 2019 04:45:54 GMT" 82 | }, 83 | { 84 | "name": "content-type", 85 | "value": "application/json;charset=utf-8" 86 | }, 87 | { 88 | "name": "transfer-encoding", 89 | "value": "chunked" 90 | }, 91 | { 92 | "name": "connection", 93 | "value": "close" 94 | }, 95 | { 96 | "name": "cache-control", 97 | "value": "no-cache,no-store" 98 | }, 99 | { 100 | "name": "pragma", 101 | "value": "no-cache" 102 | }, 103 | { 104 | "name": "location", 105 | "value": "/1.1/classes/GameScore/5d8308029c9235000886c4cf" 106 | } 107 | ], 108 | "headersSize": 262, 109 | "httpVersion": "HTTP/1.1", 110 | "redirectURL": "/1.1/classes/GameScore/5d8308029c9235000886c4cf", 111 | "status": 201, 112 | "statusText": "Created" 113 | }, 114 | "startedDateTime": "2019-09-19T04:45:53.914Z", 115 | "time": 183, 116 | "timings": { 117 | "blocked": -1, 118 | "connect": -1, 119 | "dns": -1, 120 | "receive": 0, 121 | "send": 0, 122 | "ssl": -1, 123 | "wait": 183 124 | } 125 | } 126 | ], 127 | "pages": [], 128 | "version": "1.2" 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /recordings/Objects_136869387/Fetching-Objects_1241673741/fetchAll-with-non-existed-Class_1732774206/object-should-fail_3925781535/recording.har: -------------------------------------------------------------------------------- 1 | { 2 | "log": { 3 | "_recordingName": "Objects/Fetching Objects/fetchAll with non-existed Class/object should fail", 4 | "creator": { 5 | "comment": "persister:fs", 6 | "name": "Polly.JS", 7 | "version": "2.6.2" 8 | }, 9 | "entries": [ 10 | { 11 | "_id": "a3a356130c62d7c0a2149850beb35169", 12 | "_order": 0, 13 | "cache": {}, 14 | "request": { 15 | "bodySize": 218, 16 | "cookies": [], 17 | "headers": [ 18 | { 19 | "name": "accept-encoding", 20 | "value": "gzip, deflate" 21 | }, 22 | { 23 | "name": "user-agent", 24 | "value": "LeanCloud-JS-SDK/3.15.0 (Node.js; Node.js/v12.10.0)" 25 | }, 26 | { 27 | "name": "x-lc-id", 28 | "value": "95TNUaOSUd8IpKNW0RSqSEOm-9Nh9j0Va" 29 | }, 30 | { 31 | "name": "content-type", 32 | "value": "application/json;charset=UTF-8" 33 | }, 34 | { 35 | "name": "x-lc-sign", 36 | "value": "b5b89f3bf6c25029b6f0063f1daa7f26,1568868356247" 37 | }, 38 | { 39 | "name": "x-lc-hook-key", 40 | "value": "2iCbUZDgEF0siKxmCn2kVQXV" 41 | }, 42 | { 43 | "name": "x-lc-prod", 44 | "value": "1" 45 | }, 46 | { 47 | "name": "content-length", 48 | "value": 218 49 | }, 50 | { 51 | "name": "host", 52 | "value": "95tnuaos.api.lncldapi.com" 53 | } 54 | ], 55 | "headersSize": 416, 56 | "httpVersion": "HTTP/1.1", 57 | "method": "POST", 58 | "postData": { 59 | "mimeType": "application/json;charset=UTF-8", 60 | "params": [], 61 | "text": "{\"requests\":[{\"method\":\"GET\",\"path\":\"/1.1/classes/GameScore/5d8308029c9235000886c4cf\"},{\"method\":\"GET\",\"path\":\"/1.1/classes/GameScore/fakeId\"},{\"method\":\"GET\",\"path\":\"/1.1/classes/FakeClass/5d8308029c9235000886c4cf\"}]}" 62 | }, 63 | "queryString": [], 64 | "url": "https://95tnuaos.api.lncldapi.com/1.1/batch" 65 | }, 66 | "response": { 67 | "bodySize": 450, 68 | "content": { 69 | "mimeType": "application/json;charset=utf-8", 70 | "size": 450, 71 | "text": "[\"1f8b08000000000000037d8f316bc3301085ff8ab9a58b634e8ee54ada4aa60ccd94a921832a5da88b1a059d0c0dc1ff3d5243a153a7bbfb78f71eef70039e9d23663037982fde66f22f190cf428f40af54ae83d0e669046ca6e54f20d5ab0298139d4211e570fc716e2fb27b9bcf5e5577ab54685bd76ba5f4b44546a74833b15b54bf44fc4d0e1f358232ec15e29edec17159df7854cd578aa1bbb980a16c5178be147317c8dbe90930d4ccbd2fee9749e43a880528aa956743f4a81a2fd65b00996b989a97934687c243e3fe586be27cedcc1b21cefc6aadec027010000\"]" 72 | }, 73 | "cookies": [], 74 | "headers": [ 75 | { 76 | "name": "server", 77 | "value": "openresty" 78 | }, 79 | { 80 | "name": "date", 81 | "value": "Thu, 19 Sep 2019 04:45:56 GMT" 82 | }, 83 | { 84 | "name": "content-type", 85 | "value": "application/json;charset=utf-8" 86 | }, 87 | { 88 | "name": "transfer-encoding", 89 | "value": "chunked" 90 | }, 91 | { 92 | "name": "connection", 93 | "value": "close" 94 | }, 95 | { 96 | "name": "vary", 97 | "value": "Accept-Encoding" 98 | }, 99 | { 100 | "name": "cache-control", 101 | "value": "no-cache,no-store" 102 | }, 103 | { 104 | "name": "pragma", 105 | "value": "no-cache" 106 | }, 107 | { 108 | "name": "content-encoding", 109 | "value": "gzip" 110 | } 111 | ], 112 | "headersSize": 250, 113 | "httpVersion": "HTTP/1.1", 114 | "redirectURL": "", 115 | "status": 200, 116 | "statusText": "OK" 117 | }, 118 | "startedDateTime": "2019-09-19T04:45:56.249Z", 119 | "time": 166, 120 | "timings": { 121 | "blocked": -1, 122 | "connect": -1, 123 | "dns": -1, 124 | "receive": 0, 125 | "send": 0, 126 | "ssl": -1, 127 | "wait": 166 128 | } 129 | } 130 | ], 131 | "pages": [], 132 | "version": "1.2" 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /recordings/Objects_136869387/Fetching-Objects_1241673741/fetchAll_2292446774/recording.har: -------------------------------------------------------------------------------- 1 | { 2 | "log": { 3 | "_recordingName": "Objects/Fetching Objects/fetchAll", 4 | "creator": { 5 | "comment": "persister:fs", 6 | "name": "Polly.JS", 7 | "version": "2.6.2" 8 | }, 9 | "entries": [ 10 | { 11 | "_id": "0f5cb4ef586413c16b77498be2403824", 12 | "_order": 0, 13 | "cache": {}, 14 | "request": { 15 | "bodySize": 162, 16 | "cookies": [], 17 | "headers": [ 18 | { 19 | "name": "accept-encoding", 20 | "value": "gzip, deflate" 21 | }, 22 | { 23 | "name": "user-agent", 24 | "value": "LeanCloud-JS-SDK/3.15.0 (Node.js; Node.js/v12.10.0)" 25 | }, 26 | { 27 | "name": "x-lc-id", 28 | "value": "95TNUaOSUd8IpKNW0RSqSEOm-9Nh9j0Va" 29 | }, 30 | { 31 | "name": "content-type", 32 | "value": "application/json;charset=UTF-8" 33 | }, 34 | { 35 | "name": "x-lc-sign", 36 | "value": "908ae94c2d32798d328d1286191e2a66,1568868356064" 37 | }, 38 | { 39 | "name": "x-lc-hook-key", 40 | "value": "2iCbUZDgEF0siKxmCn2kVQXV" 41 | }, 42 | { 43 | "name": "x-lc-prod", 44 | "value": "1" 45 | }, 46 | { 47 | "name": "content-length", 48 | "value": 162 49 | }, 50 | { 51 | "name": "host", 52 | "value": "95tnuaos.api.lncldapi.com" 53 | } 54 | ], 55 | "headersSize": 416, 56 | "httpVersion": "HTTP/1.1", 57 | "method": "POST", 58 | "postData": { 59 | "mimeType": "application/json;charset=UTF-8", 60 | "params": [], 61 | "text": "{\"requests\":[{\"method\":\"GET\",\"path\":\"/1.1/classes/GameScore/5d8308029c9235000886c4cf\"},{\"method\":\"GET\",\"path\":\"/1.1/classes/GameScore/5d8308029c9235000886c4cf\"}]}" 62 | }, 63 | "queryString": [], 64 | "url": "https://95tnuaos.api.lncldapi.com/1.1/batch" 65 | }, 66 | "response": { 67 | "bodySize": 362, 68 | "content": { 69 | "mimeType": "application/json;charset=utf-8", 70 | "size": 362, 71 | "text": "[\"1f8b0800000000000003dd8f310f82301085ffcbcd40aea5c5b69ba3834e4e1286da9688c1405a180ce1bf7b8dbb3fc0e9ee5ede7d2fafdd20adce8594c06cb0cede2ec11f1730c091e91275c9f4158511d24859354adea0001b2398360ff6bd3874054cf76770cbc9d3aff4aa46855c3bcd6b89884a354eb89edc2e861f11a2c2439323e6d1be43bcd857209ff7a40c193ce42db92992cc888b047c10f03c79527a3ba6b0efc51f76ea3e2830ee1ea9010000\"]" 72 | }, 73 | "cookies": [], 74 | "headers": [ 75 | { 76 | "name": "server", 77 | "value": "openresty" 78 | }, 79 | { 80 | "name": "date", 81 | "value": "Thu, 19 Sep 2019 04:45:56 GMT" 82 | }, 83 | { 84 | "name": "content-type", 85 | "value": "application/json;charset=utf-8" 86 | }, 87 | { 88 | "name": "transfer-encoding", 89 | "value": "chunked" 90 | }, 91 | { 92 | "name": "connection", 93 | "value": "close" 94 | }, 95 | { 96 | "name": "vary", 97 | "value": "Accept-Encoding" 98 | }, 99 | { 100 | "name": "cache-control", 101 | "value": "no-cache,no-store" 102 | }, 103 | { 104 | "name": "pragma", 105 | "value": "no-cache" 106 | }, 107 | { 108 | "name": "content-encoding", 109 | "value": "gzip" 110 | } 111 | ], 112 | "headersSize": 250, 113 | "httpVersion": "HTTP/1.1", 114 | "redirectURL": "", 115 | "status": 200, 116 | "statusText": "OK" 117 | }, 118 | "startedDateTime": "2019-09-19T04:45:56.066Z", 119 | "time": 172, 120 | "timings": { 121 | "blocked": -1, 122 | "connect": -1, 123 | "dns": -1, 124 | "receive": 0, 125 | "send": 0, 126 | "ssl": -1, 127 | "wait": 172 128 | } 129 | } 130 | ], 131 | "pages": [], 132 | "version": "1.2" 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /recordings/Objects_136869387/Fetching-Objects_1241673741/fetch_2910765027/recording.har: -------------------------------------------------------------------------------- 1 | { 2 | "log": { 3 | "_recordingName": "Objects/Fetching Objects/fetch", 4 | "creator": { 5 | "comment": "persister:fs", 6 | "name": "Polly.JS", 7 | "version": "2.6.2" 8 | }, 9 | "entries": [ 10 | { 11 | "_id": "a54a79dc2b720a740328a56c3d840384", 12 | "_order": 0, 13 | "cache": {}, 14 | "request": { 15 | "bodySize": 4, 16 | "cookies": [], 17 | "headers": [ 18 | { 19 | "name": "accept-encoding", 20 | "value": "gzip, deflate" 21 | }, 22 | { 23 | "name": "user-agent", 24 | "value": "LeanCloud-JS-SDK/3.15.0 (Node.js; Node.js/v12.10.0)" 25 | }, 26 | { 27 | "name": "x-lc-id", 28 | "value": "95TNUaOSUd8IpKNW0RSqSEOm-9Nh9j0Va" 29 | }, 30 | { 31 | "name": "content-type", 32 | "value": "application/json;charset=UTF-8" 33 | }, 34 | { 35 | "name": "x-lc-sign", 36 | "value": "a708a5920dbd36aa68c910f52036695d,1568868355718" 37 | }, 38 | { 39 | "name": "x-lc-hook-key", 40 | "value": "2iCbUZDgEF0siKxmCn2kVQXV" 41 | }, 42 | { 43 | "name": "x-lc-prod", 44 | "value": "1" 45 | }, 46 | { 47 | "name": "content-length", 48 | "value": 4 49 | }, 50 | { 51 | "name": "host", 52 | "value": "95tnuaos.api.lncldapi.com" 53 | } 54 | ], 55 | "headersSize": 450, 56 | "httpVersion": "HTTP/1.1", 57 | "method": "GET", 58 | "postData": { 59 | "mimeType": "application/json;charset=UTF-8", 60 | "params": [], 61 | "text": "null" 62 | }, 63 | "queryString": [], 64 | "url": "https://95tnuaos.api.lncldapi.com/1.1/classes/GameScore/5d8308029c9235000886c4cf" 65 | }, 66 | "response": { 67 | "bodySize": 330, 68 | "content": { 69 | "mimeType": "application/json;charset=utf-8", 70 | "size": 330, 71 | "text": "[\"1f8b08000000000000037d8d310ec2300c45efe2b9ad9c3429493646069898400c214e455151aa340c0871771cb133d97efa7eff0dcf857c89b42de040a2b02dda56d8232aa7b4d3ba1b8c3e41033e6770e73ac4ef927069205def31941df1af26d3a341698395bd46446386a0c2c8e990e39f0ad5e166a815cbec5f311ffc23728e88c954c553ddd6903263c15e64e18d85fb444c463faff1f3055ae47c6ac7000000\"]" 72 | }, 73 | "cookies": [], 74 | "headers": [ 75 | { 76 | "name": "server", 77 | "value": "openresty" 78 | }, 79 | { 80 | "name": "date", 81 | "value": "Thu, 19 Sep 2019 04:45:55 GMT" 82 | }, 83 | { 84 | "name": "content-type", 85 | "value": "application/json;charset=utf-8" 86 | }, 87 | { 88 | "name": "transfer-encoding", 89 | "value": "chunked" 90 | }, 91 | { 92 | "name": "connection", 93 | "value": "close" 94 | }, 95 | { 96 | "name": "vary", 97 | "value": "Accept-Encoding" 98 | }, 99 | { 100 | "name": "cache-control", 101 | "value": "no-cache,no-store" 102 | }, 103 | { 104 | "name": "pragma", 105 | "value": "no-cache" 106 | }, 107 | { 108 | "name": "last-modified", 109 | "value": "Thu, 19 Sep 2019 04:45:55.685 GMT" 110 | }, 111 | { 112 | "name": "content-encoding", 113 | "value": "gzip" 114 | } 115 | ], 116 | "headersSize": 300, 117 | "httpVersion": "HTTP/1.1", 118 | "redirectURL": "", 119 | "status": 200, 120 | "statusText": "OK" 121 | }, 122 | "startedDateTime": "2019-09-19T04:45:55.720Z", 123 | "time": 162, 124 | "timings": { 125 | "blocked": -1, 126 | "connect": -1, 127 | "dns": -1, 128 | "receive": 0, 129 | "send": 0, 130 | "ssl": -1, 131 | "wait": 162 132 | } 133 | } 134 | ], 135 | "pages": [], 136 | "version": "1.2" 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /recordings/Objects_136869387/Relational-Data_1128359924/should-create-a-Person_3530769578/recording.har: -------------------------------------------------------------------------------- 1 | { 2 | "log": { 3 | "_recordingName": "Objects/Relational Data/should create a Person", 4 | "creator": { 5 | "comment": "persister:fs", 6 | "name": "Polly.JS", 7 | "version": "2.6.2" 8 | }, 9 | "entries": [ 10 | { 11 | "_id": "b4bfb4e942a448496740353b5c83f718", 12 | "_order": 0, 13 | "cache": {}, 14 | "request": { 15 | "bodySize": 19, 16 | "cookies": [], 17 | "headers": [ 18 | { 19 | "name": "accept-encoding", 20 | "value": "gzip, deflate" 21 | }, 22 | { 23 | "name": "user-agent", 24 | "value": "LeanCloud-JS-SDK/3.15.0 (Node.js; Node.js/v12.10.0)" 25 | }, 26 | { 27 | "name": "x-lc-id", 28 | "value": "95TNUaOSUd8IpKNW0RSqSEOm-9Nh9j0Va" 29 | }, 30 | { 31 | "name": "content-type", 32 | "value": "application/json;charset=UTF-8" 33 | }, 34 | { 35 | "name": "x-lc-sign", 36 | "value": "140ab2acbcf587d14ad1834378ce24d1,1568868360027" 37 | }, 38 | { 39 | "name": "x-lc-hook-key", 40 | "value": "2iCbUZDgEF0siKxmCn2kVQXV" 41 | }, 42 | { 43 | "name": "x-lc-prod", 44 | "value": "1" 45 | }, 46 | { 47 | "name": "content-length", 48 | "value": 19 49 | }, 50 | { 51 | "name": "host", 52 | "value": "95tnuaos.api.lncldapi.com" 53 | } 54 | ], 55 | "headersSize": 424, 56 | "httpVersion": "HTTP/1.1", 57 | "method": "POST", 58 | "postData": { 59 | "mimeType": "application/json;charset=UTF-8", 60 | "params": [], 61 | "text": "{\"pname\":\"person1\"}" 62 | }, 63 | "queryString": [], 64 | "url": "https://95tnuaos.api.lncldapi.com/1.1/classes/Person" 65 | }, 66 | "response": { 67 | "bodySize": 78, 68 | "content": { 69 | "mimeType": "application/json;charset=utf-8", 70 | "size": 78, 71 | "text": "{\"objectId\":\"5d830808f40d3a0007541daa\",\"createdAt\":\"2019-09-19T04:46:00.151Z\"}" 72 | }, 73 | "cookies": [], 74 | "headers": [ 75 | { 76 | "name": "server", 77 | "value": "openresty" 78 | }, 79 | { 80 | "name": "date", 81 | "value": "Thu, 19 Sep 2019 04:46:00 GMT" 82 | }, 83 | { 84 | "name": "content-type", 85 | "value": "application/json;charset=utf-8" 86 | }, 87 | { 88 | "name": "transfer-encoding", 89 | "value": "chunked" 90 | }, 91 | { 92 | "name": "connection", 93 | "value": "close" 94 | }, 95 | { 96 | "name": "cache-control", 97 | "value": "no-cache,no-store" 98 | }, 99 | { 100 | "name": "pragma", 101 | "value": "no-cache" 102 | }, 103 | { 104 | "name": "location", 105 | "value": "/1.1/classes/Person/5d830808f40d3a0007541daa" 106 | } 107 | ], 108 | "headersSize": 259, 109 | "httpVersion": "HTTP/1.1", 110 | "redirectURL": "/1.1/classes/Person/5d830808f40d3a0007541daa", 111 | "status": 201, 112 | "statusText": "Created" 113 | }, 114 | "startedDateTime": "2019-09-19T04:46:00.029Z", 115 | "time": 146, 116 | "timings": { 117 | "blocked": -1, 118 | "connect": -1, 119 | "dns": -1, 120 | "receive": 0, 121 | "send": 0, 122 | "ssl": -1, 123 | "wait": 146 124 | } 125 | } 126 | ], 127 | "pages": [], 128 | "version": "1.2" 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /recordings/Objects_136869387/Relational-Data_1128359924/should-fetch-when-save-when-creating-new-object-_2919684681/recording.har: -------------------------------------------------------------------------------- 1 | { 2 | "log": { 3 | "_recordingName": "Objects/Relational Data/should fetch when save when creating new object.", 4 | "creator": { 5 | "comment": "persister:fs", 6 | "name": "Polly.JS", 7 | "version": "2.6.2" 8 | }, 9 | "entries": [ 10 | { 11 | "_id": "16ee56ceb06b374040ef900a70e83432", 12 | "_order": 0, 13 | "cache": {}, 14 | "request": { 15 | "bodySize": 18, 16 | "cookies": [], 17 | "headers": [ 18 | { 19 | "name": "accept-encoding", 20 | "value": "gzip, deflate" 21 | }, 22 | { 23 | "name": "user-agent", 24 | "value": "LeanCloud-JS-SDK/3.15.0 (Node.js; Node.js/v12.10.0)" 25 | }, 26 | { 27 | "name": "x-lc-id", 28 | "value": "95TNUaOSUd8IpKNW0RSqSEOm-9Nh9j0Va" 29 | }, 30 | { 31 | "name": "content-type", 32 | "value": "application/json;charset=UTF-8" 33 | }, 34 | { 35 | "name": "x-lc-sign", 36 | "value": "f8797fdf2dca553d223334a11d874e22,1568868361856" 37 | }, 38 | { 39 | "name": "x-lc-hook-key", 40 | "value": "2iCbUZDgEF0siKxmCn2kVQXV" 41 | }, 42 | { 43 | "name": "x-lc-prod", 44 | "value": "1" 45 | }, 46 | { 47 | "name": "content-length", 48 | "value": 18 49 | }, 50 | { 51 | "name": "host", 52 | "value": "95tnuaos.api.lncldapi.com" 53 | } 54 | ], 55 | "headersSize": 433, 56 | "httpVersion": "HTTP/1.1", 57 | "method": "POST", 58 | "postData": { 59 | "mimeType": "application/json;charset=UTF-8", 60 | "params": [], 61 | "text": "{\"pname\":\"dennis\"}" 62 | }, 63 | "queryString": [ 64 | { 65 | "name": "new", 66 | "value": "true" 67 | } 68 | ], 69 | "url": "https://95tnuaos.api.lncldapi.com/1.1/classes/Person?new=true" 70 | }, 71 | "response": { 72 | "bodySize": 205, 73 | "content": { 74 | "mimeType": "application/json;charset=utf-8", 75 | "size": 205, 76 | "text": "{\"company\":\"leancloud\",\"pname\":\"dennis\",\"createdAt\":\"2019-09-19T04:46:01.983Z\",\"updatedAt\":\"2019-09-19T04:46:01.983Z\",\"objectId\":\"5d8308099c9235000886c4d4\",\"likes\":{\"__type\":\"Relation\",\"className\":\"Post\"}}" 77 | }, 78 | "cookies": [], 79 | "headers": [ 80 | { 81 | "name": "server", 82 | "value": "openresty" 83 | }, 84 | { 85 | "name": "date", 86 | "value": "Thu, 19 Sep 2019 04:46:01 GMT" 87 | }, 88 | { 89 | "name": "content-type", 90 | "value": "application/json;charset=utf-8" 91 | }, 92 | { 93 | "name": "transfer-encoding", 94 | "value": "chunked" 95 | }, 96 | { 97 | "name": "connection", 98 | "value": "close" 99 | }, 100 | { 101 | "name": "cache-control", 102 | "value": "no-cache,no-store" 103 | }, 104 | { 105 | "name": "pragma", 106 | "value": "no-cache" 107 | }, 108 | { 109 | "name": "location", 110 | "value": "/1.1/classes/Person/5d8308099c9235000886c4d4" 111 | } 112 | ], 113 | "headersSize": 259, 114 | "httpVersion": "HTTP/1.1", 115 | "redirectURL": "/1.1/classes/Person/5d8308099c9235000886c4d4", 116 | "status": 201, 117 | "statusText": "Created" 118 | }, 119 | "startedDateTime": "2019-09-19T04:46:01.858Z", 120 | "time": 150, 121 | "timings": { 122 | "blocked": -1, 123 | "connect": -1, 124 | "dns": -1, 125 | "receive": 0, 126 | "send": 0, 127 | "ssl": -1, 128 | "wait": 150 129 | } 130 | } 131 | ], 132 | "pages": [], 133 | "version": "1.2" 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /recordings/Objects_136869387/Relational-Data_1128359924/should-save-all-partially_2114313946/recording.har: -------------------------------------------------------------------------------- 1 | { 2 | "log": { 3 | "_recordingName": "Objects/Relational Data/should save all partially", 4 | "creator": { 5 | "comment": "persister:fs", 6 | "name": "Polly.JS", 7 | "version": "2.6.2" 8 | }, 9 | "entries": [ 10 | { 11 | "_id": "9fb6131c17f01a755c875bf9af9d1080", 12 | "_order": 0, 13 | "cache": {}, 14 | "request": { 15 | "bodySize": 150, 16 | "cookies": [], 17 | "headers": [ 18 | { 19 | "name": "accept-encoding", 20 | "value": "gzip, deflate" 21 | }, 22 | { 23 | "name": "user-agent", 24 | "value": "LeanCloud-JS-SDK/3.15.0 (Node.js; Node.js/v12.10.0)" 25 | }, 26 | { 27 | "name": "x-lc-id", 28 | "value": "95TNUaOSUd8IpKNW0RSqSEOm-9Nh9j0Va" 29 | }, 30 | { 31 | "name": "content-type", 32 | "value": "application/json;charset=UTF-8" 33 | }, 34 | { 35 | "name": "x-lc-sign", 36 | "value": "8164310ee456858f548063eaa483ce4b,1568868360864" 37 | }, 38 | { 39 | "name": "x-lc-hook-key", 40 | "value": "2iCbUZDgEF0siKxmCn2kVQXV" 41 | }, 42 | { 43 | "name": "x-lc-prod", 44 | "value": "1" 45 | }, 46 | { 47 | "name": "content-length", 48 | "value": 150 49 | }, 50 | { 51 | "name": "host", 52 | "value": "95tnuaos.api.lncldapi.com" 53 | } 54 | ], 55 | "headersSize": 416, 56 | "httpVersion": "HTTP/1.1", 57 | "method": "POST", 58 | "postData": { 59 | "mimeType": "application/json;charset=UTF-8", 60 | "params": [], 61 | "text": "{\"requests\":[{\"method\":\"PUT\",\"path\":\"/1.1/classes/Person/fakeid\",\"body\":{\"age\":30}},{\"method\":\"POST\",\"path\":\"/1.1/classes/Person\",\"body\":{\"age\":40}}]}" 62 | }, 63 | "queryString": [], 64 | "url": "https://95tnuaos.api.lncldapi.com/1.1/batch" 65 | }, 66 | "response": { 67 | "bodySize": 344, 68 | "content": { 69 | "mimeType": "application/json;charset=utf-8", 70 | "size": 344, 71 | "text": "[\"1f8b080000000000000335ccb10e82301485e157b9b90b0b905b294abb19273707278d43e96d1394d0a42d8321bcbb18e37af29fefbea08b3144d40bdac00eb528ff0b9ec23c324c21831f2686d03f9dcdd0bf616028bc79b9810bf021821d4d4a505c5c4c612a6a5cd772c1345beb52facabfe79937b3e5aea18e3a2f891b434487560a363d9668a333d9f1316fd98e84aa4855425d496ab9d744b552cd6da31f1f7d66030cb4000000\"]" 72 | }, 73 | "cookies": [], 74 | "headers": [ 75 | { 76 | "name": "server", 77 | "value": "openresty" 78 | }, 79 | { 80 | "name": "date", 81 | "value": "Thu, 19 Sep 2019 04:46:00 GMT" 82 | }, 83 | { 84 | "name": "content-type", 85 | "value": "application/json;charset=utf-8" 86 | }, 87 | { 88 | "name": "transfer-encoding", 89 | "value": "chunked" 90 | }, 91 | { 92 | "name": "connection", 93 | "value": "close" 94 | }, 95 | { 96 | "name": "vary", 97 | "value": "Accept-Encoding" 98 | }, 99 | { 100 | "name": "cache-control", 101 | "value": "no-cache,no-store" 102 | }, 103 | { 104 | "name": "pragma", 105 | "value": "no-cache" 106 | }, 107 | { 108 | "name": "content-encoding", 109 | "value": "gzip" 110 | } 111 | ], 112 | "headersSize": 250, 113 | "httpVersion": "HTTP/1.1", 114 | "redirectURL": "", 115 | "status": 200, 116 | "statusText": "OK" 117 | }, 118 | "startedDateTime": "2019-09-19T04:46:00.866Z", 119 | "time": 147, 120 | "timings": { 121 | "blocked": -1, 122 | "connect": -1, 123 | "dns": -1, 124 | "receive": 0, 125 | "send": 0, 126 | "ssl": -1, 127 | "wait": 147 128 | } 129 | } 130 | ], 131 | "pages": [], 132 | "version": "1.2" 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /recordings/Objects_136869387/Retrieving-Objects_2244900730/should-be-the-just-save-Object_3889513002/recording.har: -------------------------------------------------------------------------------- 1 | { 2 | "log": { 3 | "_recordingName": "Objects/Retrieving Objects/should be the just save Object", 4 | "creator": { 5 | "comment": "persister:fs", 6 | "name": "Polly.JS", 7 | "version": "2.6.2" 8 | }, 9 | "entries": [ 10 | { 11 | "_id": "a54a79dc2b720a740328a56c3d840384", 12 | "_order": 0, 13 | "cache": {}, 14 | "request": { 15 | "bodySize": 4, 16 | "cookies": [], 17 | "headers": [ 18 | { 19 | "name": "accept-encoding", 20 | "value": "gzip, deflate" 21 | }, 22 | { 23 | "name": "user-agent", 24 | "value": "LeanCloud-JS-SDK/3.15.0 (Node.js; Node.js/v12.10.0)" 25 | }, 26 | { 27 | "name": "x-lc-id", 28 | "value": "95TNUaOSUd8IpKNW0RSqSEOm-9Nh9j0Va" 29 | }, 30 | { 31 | "name": "content-type", 32 | "value": "application/json;charset=UTF-8" 33 | }, 34 | { 35 | "name": "x-lc-sign", 36 | "value": "d731559c9d3562770330cfacd8f6db13,1568868354772" 37 | }, 38 | { 39 | "name": "x-lc-hook-key", 40 | "value": "2iCbUZDgEF0siKxmCn2kVQXV" 41 | }, 42 | { 43 | "name": "x-lc-prod", 44 | "value": "1" 45 | }, 46 | { 47 | "name": "content-length", 48 | "value": 4 49 | }, 50 | { 51 | "name": "host", 52 | "value": "95tnuaos.api.lncldapi.com" 53 | } 54 | ], 55 | "headersSize": 450, 56 | "httpVersion": "HTTP/1.1", 57 | "method": "GET", 58 | "postData": { 59 | "mimeType": "application/json;charset=UTF-8", 60 | "params": [], 61 | "text": "null" 62 | }, 63 | "queryString": [], 64 | "url": "https://95tnuaos.api.lncldapi.com/1.1/classes/GameScore/5d8308029c9235000886c4cf" 65 | }, 66 | "response": { 67 | "bodySize": 320, 68 | "content": { 69 | "mimeType": "application/json;charset=utf-8", 70 | "size": 320, 71 | "text": "[\"1f8b08000000000000038d8d310ec2300c45efe2b9454e9a94241b23034c4c208610a7a25551aa340c0871771c7101bcd87efa7e7ec373215f22ed0a3890286c8bb615f684ca29edb4dae0b63f43033e677097dac46f93706d20dda618ca9ef85693e9d0a0b4c1ca4e23a2317d5061e074c8f19f17cbec5f311ffd23728e88c958c5639dd6903263c1c5be3bfb0e89180c7e5ee3e70b36a18b50c6000000\"]" 72 | }, 73 | "cookies": [], 74 | "headers": [ 75 | { 76 | "name": "server", 77 | "value": "openresty" 78 | }, 79 | { 80 | "name": "date", 81 | "value": "Thu, 19 Sep 2019 04:45:55 GMT" 82 | }, 83 | { 84 | "name": "content-type", 85 | "value": "application/json;charset=utf-8" 86 | }, 87 | { 88 | "name": "transfer-encoding", 89 | "value": "chunked" 90 | }, 91 | { 92 | "name": "connection", 93 | "value": "close" 94 | }, 95 | { 96 | "name": "vary", 97 | "value": "Accept-Encoding" 98 | }, 99 | { 100 | "name": "cache-control", 101 | "value": "no-cache,no-store" 102 | }, 103 | { 104 | "name": "pragma", 105 | "value": "no-cache" 106 | }, 107 | { 108 | "name": "last-modified", 109 | "value": "Thu, 19 Sep 2019 04:45:54.076 GMT" 110 | }, 111 | { 112 | "name": "content-encoding", 113 | "value": "gzip" 114 | } 115 | ], 116 | "headersSize": 300, 117 | "httpVersion": "HTTP/1.1", 118 | "redirectURL": "", 119 | "status": 200, 120 | "statusText": "OK" 121 | }, 122 | "startedDateTime": "2019-09-19T04:45:54.773Z", 123 | "time": 252, 124 | "timings": { 125 | "blocked": -1, 126 | "connect": -1, 127 | "dns": -1, 128 | "receive": 0, 129 | "send": 0, 130 | "ssl": -1, 131 | "wait": 252 132 | } 133 | } 134 | ], 135 | "pages": [], 136 | "version": "1.2" 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /recordings/Objects_136869387/Updating-Objects_3413221323/should-not-update-prop-when-query-not-match_211364035/recording.har: -------------------------------------------------------------------------------- 1 | { 2 | "log": { 3 | "_recordingName": "Objects/Updating Objects/should not update prop when query not match", 4 | "creator": { 5 | "comment": "persister:fs", 6 | "name": "Polly.JS", 7 | "version": "2.6.2" 8 | }, 9 | "entries": [ 10 | { 11 | "_id": "eddc4281995c7b7d89adcfdcd1eef073", 12 | "_order": 0, 13 | "cache": {}, 14 | "request": { 15 | "bodySize": 15, 16 | "cookies": [], 17 | "headers": [ 18 | { 19 | "name": "accept-encoding", 20 | "value": "gzip, deflate" 21 | }, 22 | { 23 | "name": "user-agent", 24 | "value": "LeanCloud-JS-SDK/3.15.0 (Node.js; Node.js/v12.10.0)" 25 | }, 26 | { 27 | "name": "x-lc-id", 28 | "value": "95TNUaOSUd8IpKNW0RSqSEOm-9Nh9j0Va" 29 | }, 30 | { 31 | "name": "content-type", 32 | "value": "application/json;charset=UTF-8" 33 | }, 34 | { 35 | "name": "x-lc-sign", 36 | "value": "ca9020d8f225a120106f66bf478a0387,1568868355295" 37 | }, 38 | { 39 | "name": "x-lc-hook-key", 40 | "value": "2iCbUZDgEF0siKxmCn2kVQXV" 41 | }, 42 | { 43 | "name": "x-lc-prod", 44 | "value": "1" 45 | }, 46 | { 47 | "name": "content-length", 48 | "value": 15 49 | }, 50 | { 51 | "name": "host", 52 | "value": "95tnuaos.api.lncldapi.com" 53 | } 54 | ], 55 | "headersSize": 480, 56 | "httpVersion": "HTTP/1.1", 57 | "method": "PUT", 58 | "postData": { 59 | "mimeType": "application/json;charset=UTF-8", 60 | "params": [], 61 | "text": "{\"score\":10000}" 62 | }, 63 | "queryString": [ 64 | { 65 | "name": "where", 66 | "value": "{\"score\":-1}" 67 | } 68 | ], 69 | "url": "https://95tnuaos.api.lncldapi.com/1.1/classes/GameScore/5d8308029c9235000886c4cf?where=%7B%22score%22%3A-1%7D" 70 | }, 71 | "response": { 72 | "bodySize": 66, 73 | "content": { 74 | "mimeType": "application/json;charset=utf-8", 75 | "size": 66, 76 | "text": "{\"code\":305,\"error\":\"No effect on updating\\/deleting a document.\"}" 77 | }, 78 | "cookies": [], 79 | "headers": [ 80 | { 81 | "name": "server", 82 | "value": "openresty" 83 | }, 84 | { 85 | "name": "date", 86 | "value": "Thu, 19 Sep 2019 04:45:55 GMT" 87 | }, 88 | { 89 | "name": "content-type", 90 | "value": "application/json;charset=utf-8" 91 | }, 92 | { 93 | "name": "transfer-encoding", 94 | "value": "chunked" 95 | }, 96 | { 97 | "name": "connection", 98 | "value": "close" 99 | }, 100 | { 101 | "name": "cache-control", 102 | "value": "no-cache,no-store" 103 | }, 104 | { 105 | "name": "pragma", 106 | "value": "no-cache" 107 | } 108 | ], 109 | "headersSize": 203, 110 | "httpVersion": "HTTP/1.1", 111 | "redirectURL": "", 112 | "status": 400, 113 | "statusText": "Bad Request" 114 | }, 115 | "startedDateTime": "2019-09-19T04:45:55.298Z", 116 | "time": 223, 117 | "timings": { 118 | "blocked": -1, 119 | "connect": -1, 120 | "dns": -1, 121 | "receive": 0, 122 | "send": 0, 123 | "ssl": -1, 124 | "wait": 223 125 | } 126 | } 127 | ], 128 | "pages": [], 129 | "version": "1.2" 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /recordings/Objects_136869387/Updating-Objects_3413221323/should-update-prop-when-query-match_1479817141/recording.har: -------------------------------------------------------------------------------- 1 | { 2 | "log": { 3 | "_recordingName": "Objects/Updating Objects/should update prop when query match", 4 | "creator": { 5 | "comment": "persister:fs", 6 | "name": "Polly.JS", 7 | "version": "2.6.2" 8 | }, 9 | "entries": [ 10 | { 11 | "_id": "c35902b303b15f9fc4466ef483a98cee", 12 | "_order": 0, 13 | "cache": {}, 14 | "request": { 15 | "bodySize": 15, 16 | "cookies": [], 17 | "headers": [ 18 | { 19 | "name": "accept-encoding", 20 | "value": "gzip, deflate" 21 | }, 22 | { 23 | "name": "user-agent", 24 | "value": "LeanCloud-JS-SDK/3.15.0 (Node.js; Node.js/v12.10.0)" 25 | }, 26 | { 27 | "name": "x-lc-id", 28 | "value": "95TNUaOSUd8IpKNW0RSqSEOm-9Nh9j0Va" 29 | }, 30 | { 31 | "name": "content-type", 32 | "value": "application/json;charset=UTF-8" 33 | }, 34 | { 35 | "name": "x-lc-sign", 36 | "value": "be1fc8d5fd806734f6399fe7164f2d19,1568868355532" 37 | }, 38 | { 39 | "name": "x-lc-hook-key", 40 | "value": "2iCbUZDgEF0siKxmCn2kVQXV" 41 | }, 42 | { 43 | "name": "x-lc-prod", 44 | "value": "1" 45 | }, 46 | { 47 | "name": "content-length", 48 | "value": 15 49 | }, 50 | { 51 | "name": "host", 52 | "value": "95tnuaos.api.lncldapi.com" 53 | } 54 | ], 55 | "headersSize": 509, 56 | "httpVersion": "HTTP/1.1", 57 | "method": "PUT", 58 | "postData": { 59 | "mimeType": "application/json;charset=UTF-8", 60 | "params": [], 61 | "text": "{\"score\":10000}" 62 | }, 63 | "queryString": [ 64 | { 65 | "name": "new", 66 | "value": "true" 67 | }, 68 | { 69 | "name": "where", 70 | "value": "{\"score\":{\"$ne\":-1}}" 71 | } 72 | ], 73 | "url": "https://95tnuaos.api.lncldapi.com/1.1/classes/GameScore/5d8308029c9235000886c4cf?new=true&where=%7B%22score%22%3A%7B%22%24ne%22%3A-1%7D%7D" 74 | }, 75 | "response": { 76 | "bodySize": 214, 77 | "content": { 78 | "mimeType": "application/json;charset=utf-8", 79 | "size": 214, 80 | "text": "[\"1f8b08000000000000030dccab0e80300c40d17fa91ea47b7469e79078140eba213010188af0efecea93fbc2adc75520596c1978cebcd492870a091c5ae9503a2b1386142811f591690603c7ba17ad636e8a327b6474a2e23cb50973d4a01b7c3f54faf5735c000000\"]" 81 | }, 82 | "cookies": [], 83 | "headers": [ 84 | { 85 | "name": "server", 86 | "value": "openresty" 87 | }, 88 | { 89 | "name": "date", 90 | "value": "Thu, 19 Sep 2019 04:45:55 GMT" 91 | }, 92 | { 93 | "name": "content-type", 94 | "value": "application/json;charset=utf-8" 95 | }, 96 | { 97 | "name": "transfer-encoding", 98 | "value": "chunked" 99 | }, 100 | { 101 | "name": "connection", 102 | "value": "close" 103 | }, 104 | { 105 | "name": "vary", 106 | "value": "Accept-Encoding" 107 | }, 108 | { 109 | "name": "cache-control", 110 | "value": "no-cache,no-store" 111 | }, 112 | { 113 | "name": "pragma", 114 | "value": "no-cache" 115 | }, 116 | { 117 | "name": "content-encoding", 118 | "value": "gzip" 119 | } 120 | ], 121 | "headersSize": 250, 122 | "httpVersion": "HTTP/1.1", 123 | "redirectURL": "", 124 | "status": 200, 125 | "statusText": "OK" 126 | }, 127 | "startedDateTime": "2019-09-19T04:45:55.534Z", 128 | "time": 177, 129 | "timings": { 130 | "blocked": -1, 131 | "connect": -1, 132 | "dns": -1, 133 | "receive": 0, 134 | "send": 0, 135 | "ssl": -1, 136 | "wait": 177 137 | } 138 | } 139 | ], 140 | "pages": [], 141 | "version": "1.2" 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /recordings/Objects_136869387/Updating-Objects_3413221323/should-update-prop_1422992344/recording.har: -------------------------------------------------------------------------------- 1 | { 2 | "log": { 3 | "_recordingName": "Objects/Updating Objects/should update prop", 4 | "creator": { 5 | "comment": "persister:fs", 6 | "name": "Polly.JS", 7 | "version": "2.6.2" 8 | }, 9 | "entries": [ 10 | { 11 | "_id": "4ebed9ff5596e91f644aabe339290877", 12 | "_order": 0, 13 | "cache": {}, 14 | "request": { 15 | "bodySize": 15, 16 | "cookies": [], 17 | "headers": [ 18 | { 19 | "name": "accept-encoding", 20 | "value": "gzip, deflate" 21 | }, 22 | { 23 | "name": "user-agent", 24 | "value": "LeanCloud-JS-SDK/3.15.0 (Node.js; Node.js/v12.10.0)" 25 | }, 26 | { 27 | "name": "x-lc-id", 28 | "value": "95TNUaOSUd8IpKNW0RSqSEOm-9Nh9j0Va" 29 | }, 30 | { 31 | "name": "content-type", 32 | "value": "application/json;charset=UTF-8" 33 | }, 34 | { 35 | "name": "x-lc-sign", 36 | "value": "bc55a8a2545f9a2e3cc3a85359b46b62,1568868355033" 37 | }, 38 | { 39 | "name": "x-lc-hook-key", 40 | "value": "2iCbUZDgEF0siKxmCn2kVQXV" 41 | }, 42 | { 43 | "name": "x-lc-prod", 44 | "value": "1" 45 | }, 46 | { 47 | "name": "content-length", 48 | "value": 15 49 | }, 50 | { 51 | "name": "host", 52 | "value": "95tnuaos.api.lncldapi.com" 53 | } 54 | ], 55 | "headersSize": 451, 56 | "httpVersion": "HTTP/1.1", 57 | "method": "PUT", 58 | "postData": { 59 | "mimeType": "application/json;charset=UTF-8", 60 | "params": [], 61 | "text": "{\"score\":10000}" 62 | }, 63 | "queryString": [], 64 | "url": "https://95tnuaos.api.lncldapi.com/1.1/classes/GameScore/5d8308029c9235000886c4cf" 65 | }, 66 | "response": { 67 | "bodySize": 194, 68 | "content": { 69 | "mimeType": "application/json;charset=utf-8", 70 | "size": 194, 71 | "text": "[\"1f8b08000000000000030dcaa11280300800d07f21abc718ecc69ad16eb229cc60d13093e7bfebcbef81fbf2b5551f1b14200cdaa3f64167e4c25244064abc4007e776546b93ff4b3c47cc486a4a511031e7646c3bbc1fbf36a8994e000000\"]" 72 | }, 73 | "cookies": [], 74 | "headers": [ 75 | { 76 | "name": "server", 77 | "value": "openresty" 78 | }, 79 | { 80 | "name": "date", 81 | "value": "Thu, 19 Sep 2019 04:45:55 GMT" 82 | }, 83 | { 84 | "name": "content-type", 85 | "value": "application/json;charset=utf-8" 86 | }, 87 | { 88 | "name": "transfer-encoding", 89 | "value": "chunked" 90 | }, 91 | { 92 | "name": "connection", 93 | "value": "close" 94 | }, 95 | { 96 | "name": "vary", 97 | "value": "Accept-Encoding" 98 | }, 99 | { 100 | "name": "cache-control", 101 | "value": "no-cache,no-store" 102 | }, 103 | { 104 | "name": "pragma", 105 | "value": "no-cache" 106 | }, 107 | { 108 | "name": "content-encoding", 109 | "value": "gzip" 110 | } 111 | ], 112 | "headersSize": 250, 113 | "httpVersion": "HTTP/1.1", 114 | "redirectURL": "", 115 | "status": 200, 116 | "statusText": "OK" 117 | }, 118 | "startedDateTime": "2019-09-19T04:45:55.035Z", 119 | "time": 253, 120 | "timings": { 121 | "blocked": -1, 122 | "connect": -1, 123 | "dns": -1, 124 | "receive": 0, 125 | "send": 0, 126 | "ssl": -1, 127 | "wait": 253 128 | } 129 | } 130 | ], 131 | "pages": [], 132 | "version": "1.2" 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /recordings/Queries_842530531/-Basic-Queries_2120137160/should-throw-when-object-not-exists_3742366688/recording.har: -------------------------------------------------------------------------------- 1 | { 2 | "log": { 3 | "_recordingName": "Queries/#Basic Queries/should throw when object not exists", 4 | "creator": { 5 | "comment": "persister:fs", 6 | "name": "Polly.JS", 7 | "version": "2.6.2" 8 | }, 9 | "entries": [ 10 | { 11 | "_id": "fbb833524bc1694e7544b5725531581a", 12 | "_order": 0, 13 | "cache": {}, 14 | "request": { 15 | "bodySize": 4, 16 | "cookies": [], 17 | "headers": [ 18 | { 19 | "name": "accept-encoding", 20 | "value": "gzip, deflate" 21 | }, 22 | { 23 | "name": "user-agent", 24 | "value": "LeanCloud-JS-SDK/3.15.0 (Node.js; Node.js/v12.10.0)" 25 | }, 26 | { 27 | "name": "x-lc-id", 28 | "value": "95TNUaOSUd8IpKNW0RSqSEOm-9Nh9j0Va" 29 | }, 30 | { 31 | "name": "content-type", 32 | "value": "application/json;charset=UTF-8" 33 | }, 34 | { 35 | "name": "x-lc-sign", 36 | "value": "dad6e7269bdfb44f8cac14272a45a351,1568868365232" 37 | }, 38 | { 39 | "name": "x-lc-hook-key", 40 | "value": "2iCbUZDgEF0siKxmCn2kVQXV" 41 | }, 42 | { 43 | "name": "x-lc-prod", 44 | "value": "1" 45 | }, 46 | { 47 | "name": "content-length", 48 | "value": 4 49 | }, 50 | { 51 | "name": "host", 52 | "value": "95tnuaos.api.lncldapi.com" 53 | } 54 | ], 55 | "headersSize": 429, 56 | "httpVersion": "HTTP/1.1", 57 | "method": "GET", 58 | "postData": { 59 | "mimeType": "application/json;charset=UTF-8", 60 | "params": [], 61 | "text": "null" 62 | }, 63 | "queryString": [], 64 | "url": "https://95tnuaos.api.lncldapi.com/1.1/classes/GameScore/123" 65 | }, 66 | "response": { 67 | "bodySize": 48, 68 | "content": { 69 | "mimeType": "application/json;charset=utf-8", 70 | "size": 48, 71 | "text": "[\"1f8b0800000000000003abae050043bfa6a302000000\"]" 72 | }, 73 | "cookies": [], 74 | "headers": [ 75 | { 76 | "name": "server", 77 | "value": "openresty" 78 | }, 79 | { 80 | "name": "date", 81 | "value": "Thu, 19 Sep 2019 04:46:05 GMT" 82 | }, 83 | { 84 | "name": "content-type", 85 | "value": "application/json;charset=utf-8" 86 | }, 87 | { 88 | "name": "transfer-encoding", 89 | "value": "chunked" 90 | }, 91 | { 92 | "name": "connection", 93 | "value": "close" 94 | }, 95 | { 96 | "name": "vary", 97 | "value": "Accept-Encoding" 98 | }, 99 | { 100 | "name": "cache-control", 101 | "value": "no-cache,no-store" 102 | }, 103 | { 104 | "name": "pragma", 105 | "value": "no-cache" 106 | }, 107 | { 108 | "name": "content-encoding", 109 | "value": "gzip" 110 | } 111 | ], 112 | "headersSize": 250, 113 | "httpVersion": "HTTP/1.1", 114 | "redirectURL": "", 115 | "status": 200, 116 | "statusText": "OK" 117 | }, 118 | "startedDateTime": "2019-09-19T04:46:05.234Z", 119 | "time": 166, 120 | "timings": { 121 | "blocked": -1, 122 | "connect": -1, 123 | "dns": -1, 124 | "receive": 0, 125 | "send": 0, 126 | "ssl": -1, 127 | "wait": 166 128 | } 129 | } 130 | ], 131 | "pages": [], 132 | "version": "1.2" 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /recordings/Queries_842530531/-File-Query_3474564568/recording.har: -------------------------------------------------------------------------------- 1 | { 2 | "log": { 3 | "_recordingName": "Queries/#File Query", 4 | "creator": { 5 | "comment": "persister:fs", 6 | "name": "Polly.JS", 7 | "version": "2.6.2" 8 | }, 9 | "entries": [ 10 | { 11 | "_id": "cf349f0e40932816611b1c591f320a58", 12 | "_order": 0, 13 | "cache": {}, 14 | "request": { 15 | "bodySize": 0, 16 | "cookies": [], 17 | "headers": [ 18 | { 19 | "name": "accept-encoding", 20 | "value": "gzip, deflate" 21 | }, 22 | { 23 | "name": "user-agent", 24 | "value": "LeanCloud-JS-SDK/3.15.0 (Node.js; Node.js/v12.10.0)" 25 | }, 26 | { 27 | "name": "x-lc-id", 28 | "value": "95TNUaOSUd8IpKNW0RSqSEOm-9Nh9j0Va" 29 | }, 30 | { 31 | "name": "content-type", 32 | "value": "application/json;charset=UTF-8" 33 | }, 34 | { 35 | "name": "x-lc-sign", 36 | "value": "91a5dce8e93c8633709d1fc98ea994c7,1568868364504" 37 | }, 38 | { 39 | "name": "x-lc-hook-key", 40 | "value": "2iCbUZDgEF0siKxmCn2kVQXV" 41 | }, 42 | { 43 | "name": "x-lc-prod", 44 | "value": "1" 45 | }, 46 | { 47 | "name": "host", 48 | "value": "95tnuaos.api.lncldapi.com" 49 | } 50 | ], 51 | "headersSize": 462, 52 | "httpVersion": "HTTP/1.1", 53 | "method": "GET", 54 | "queryString": [ 55 | { 56 | "name": "where", 57 | "value": "{\"objectId\":\"52f9dd5ae4b019816c865985\"}" 58 | } 59 | ], 60 | "url": "https://95tnuaos.api.lncldapi.com/1.1/classes/_File?where=%7B%22objectId%22%3A%2252f9dd5ae4b019816c865985%22%7D" 61 | }, 62 | "response": { 63 | "bodySize": 558, 64 | "content": { 65 | "mimeType": "application/json;charset=utf-8", 66 | "size": 558, 67 | "text": "[\"1f8b0800000000000003958fcb6e83301045ffc5ebf0300564b38b9445bba0956822f54115f93134140c08061582f2ef35513e20ddde3957f7cc427a18c61a07927c2ec494068e38774012823061ee75b5281bb22163a70582dea2bd043e0d1d3f7028ddfb2c09fc240c5ccaf987c52a982d20cdf6d9c4a7729a1fbfd3c359bc654c4f55961ef6d9ae0f63fdce53f6f2caa88b13da5223cc3a68e6a2ace196b5f207143e699b4741c1b58e0484d2a79cd158b138e22cb294eae11eabb1af2d7042ec92dccbbd5a399d1083b3ce0dae6a9c86bab5ba8eabd6e4de3ff50da0d80914245948fbdb407f739610b2d5f921d2200bc6640cdae24379b6df86970d91a3aa60555f6d8e571b72f9bafc016c53208793010000\"]" 68 | }, 69 | "cookies": [], 70 | "headers": [ 71 | { 72 | "name": "server", 73 | "value": "openresty" 74 | }, 75 | { 76 | "name": "date", 77 | "value": "Thu, 19 Sep 2019 04:46:04 GMT" 78 | }, 79 | { 80 | "name": "content-type", 81 | "value": "application/json;charset=utf-8" 82 | }, 83 | { 84 | "name": "transfer-encoding", 85 | "value": "chunked" 86 | }, 87 | { 88 | "name": "connection", 89 | "value": "close" 90 | }, 91 | { 92 | "name": "vary", 93 | "value": "Accept-Encoding" 94 | }, 95 | { 96 | "name": "cache-control", 97 | "value": "no-cache,no-store" 98 | }, 99 | { 100 | "name": "pragma", 101 | "value": "no-cache" 102 | }, 103 | { 104 | "name": "last-modified", 105 | "value": "Thu, 19 Sep 2019 04:11:53.859 GMT" 106 | }, 107 | { 108 | "name": "content-encoding", 109 | "value": "gzip" 110 | } 111 | ], 112 | "headersSize": 300, 113 | "httpVersion": "HTTP/1.1", 114 | "redirectURL": "", 115 | "status": 200, 116 | "statusText": "OK" 117 | }, 118 | "startedDateTime": "2019-09-19T04:46:04.507Z", 119 | "time": 148, 120 | "timings": { 121 | "blocked": -1, 122 | "connect": -1, 123 | "dns": -1, 124 | "receive": 0, 125 | "send": 0, 126 | "ssl": -1, 127 | "wait": 148 128 | } 129 | } 130 | ], 131 | "pages": [], 132 | "version": "1.2" 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /recordings/Queries_842530531/-cloudQuery_1998416685/should-return-count-value-_1336084012/recording.har: -------------------------------------------------------------------------------- 1 | { 2 | "log": { 3 | "_recordingName": "Queries/#cloudQuery/should return count value.", 4 | "creator": { 5 | "comment": "persister:fs", 6 | "name": "Polly.JS", 7 | "version": "2.6.2" 8 | }, 9 | "entries": [ 10 | { 11 | "_id": "6eb5784c3b95b302192d01ed702efed8", 12 | "_order": 0, 13 | "cache": {}, 14 | "request": { 15 | "bodySize": 4, 16 | "cookies": [], 17 | "headers": [ 18 | { 19 | "name": "accept-encoding", 20 | "value": "gzip, deflate" 21 | }, 22 | { 23 | "name": "user-agent", 24 | "value": "LeanCloud-JS-SDK/3.15.0 (Node.js; Node.js/v12.10.0)" 25 | }, 26 | { 27 | "name": "x-lc-id", 28 | "value": "95TNUaOSUd8IpKNW0RSqSEOm-9Nh9j0Va" 29 | }, 30 | { 31 | "name": "content-type", 32 | "value": "application/json;charset=UTF-8" 33 | }, 34 | { 35 | "name": "x-lc-sign", 36 | "value": "ca09b22319d834490a6ae31bde8d5e01,1568868365772" 37 | }, 38 | { 39 | "name": "x-lc-hook-key", 40 | "value": "2iCbUZDgEF0siKxmCn2kVQXV" 41 | }, 42 | { 43 | "name": "x-lc-prod", 44 | "value": "1" 45 | }, 46 | { 47 | "name": "content-length", 48 | "value": 4 49 | }, 50 | { 51 | "name": "host", 52 | "value": "95tnuaos.api.lncldapi.com" 53 | } 54 | ], 55 | "headersSize": 489, 56 | "httpVersion": "HTTP/1.1", 57 | "method": "GET", 58 | "postData": { 59 | "mimeType": "application/json;charset=UTF-8", 60 | "params": [], 61 | "text": "null" 62 | }, 63 | "queryString": [ 64 | { 65 | "name": "cql", 66 | "value": "select *,count(objectId) from GameScore limit 10" 67 | } 68 | ], 69 | "url": "https://95tnuaos.api.lncldapi.com/1.1/cloudQuery?cql=select%20%2A%2Ccount%28objectId%29%20from%20GameScore%20limit%2010" 70 | }, 71 | "response": { 72 | "bodySize": 792, 73 | "content": { 74 | "mimeType": "application/json;charset=utf-8", 75 | "size": 792, 76 | "text": "[\"1f8b0800000000000003a5933b6f02311084ff8b6b38ad77fd38bb4b15a5489a50254ae1f343514402e2a08810ff3dcbab38c08094eab4d6c8dfdc78762d16b95f4d97bdf0ef6bb19aa7b0cce96129bc40907a2c618c3891e4013cd94649fd2646222ef23db259f795e3f229b14a1b6c532ada4087988b8bcaa80c9ac466749b4ac6dd433dc86e5255b98f6ae92eea5e7693aaa14eb513293d394fd038b255eab96c3e0dbf79f112be33ebfa54f8a88fb3054fc8777cf21dcfb3c45309d33e9f9a2c062d6e4d06138b0344db255337692612bc541e5d834e564d9ecbf626b7051381c74e7c9c3a4925811e3821b41527722c6902d62353a83158717251f69fb8946e0ba6ad496d5248362970588beb4827e395e28ae0759303d909d511c42135a6ab8fa43c10ff768350dfd573d97fa2c14c18dac1fb6988f568da5d8fdbedc338a8acf645d9309a680877add159d9a83138956bd4e3f628f4928b09edf5251bc84eb7866437dc9acc35e04ec769e8fb43828ffc79dde5c7e7b3d50f2324a2defc01cea05e046f050000\"]" 77 | }, 78 | "cookies": [], 79 | "headers": [ 80 | { 81 | "name": "server", 82 | "value": "openresty" 83 | }, 84 | { 85 | "name": "date", 86 | "value": "Thu, 19 Sep 2019 04:46:05 GMT" 87 | }, 88 | { 89 | "name": "content-type", 90 | "value": "application/json;charset=utf-8" 91 | }, 92 | { 93 | "name": "transfer-encoding", 94 | "value": "chunked" 95 | }, 96 | { 97 | "name": "connection", 98 | "value": "close" 99 | }, 100 | { 101 | "name": "vary", 102 | "value": "Accept-Encoding" 103 | }, 104 | { 105 | "name": "cache-control", 106 | "value": "no-cache,no-store" 107 | }, 108 | { 109 | "name": "pragma", 110 | "value": "no-cache" 111 | }, 112 | { 113 | "name": "content-encoding", 114 | "value": "gzip" 115 | } 116 | ], 117 | "headersSize": 250, 118 | "httpVersion": "HTTP/1.1", 119 | "redirectURL": "", 120 | "status": 200, 121 | "statusText": "OK" 122 | }, 123 | "startedDateTime": "2019-09-19T04:46:05.775Z", 124 | "time": 171, 125 | "timings": { 126 | "blocked": -1, 127 | "connect": -1, 128 | "dns": -1, 129 | "receive": 0, 130 | "send": 0, 131 | "ssl": -1, 132 | "wait": 171 133 | } 134 | } 135 | ], 136 | "pages": [], 137 | "version": "1.2" 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /recordings/Queries_842530531/-cloudQuery_1998416685/should-return-count-value-too-_2597229118/recording.har: -------------------------------------------------------------------------------- 1 | { 2 | "log": { 3 | "_recordingName": "Queries/#cloudQuery/should return count value too.", 4 | "creator": { 5 | "comment": "persister:fs", 6 | "name": "Polly.JS", 7 | "version": "2.6.2" 8 | }, 9 | "entries": [ 10 | { 11 | "_id": "f7352fd6c99a99615277d9d38addabce", 12 | "_order": 0, 13 | "cache": {}, 14 | "request": { 15 | "bodySize": 4, 16 | "cookies": [], 17 | "headers": [ 18 | { 19 | "name": "accept-encoding", 20 | "value": "gzip, deflate" 21 | }, 22 | { 23 | "name": "user-agent", 24 | "value": "LeanCloud-JS-SDK/3.15.0 (Node.js; Node.js/v12.10.0)" 25 | }, 26 | { 27 | "name": "x-lc-id", 28 | "value": "95TNUaOSUd8IpKNW0RSqSEOm-9Nh9j0Va" 29 | }, 30 | { 31 | "name": "content-type", 32 | "value": "application/json;charset=UTF-8" 33 | }, 34 | { 35 | "name": "x-lc-sign", 36 | "value": "bd87559c2557da7d553eae20038a41ca,1568868365955" 37 | }, 38 | { 39 | "name": "x-lc-hook-key", 40 | "value": "2iCbUZDgEF0siKxmCn2kVQXV" 41 | }, 42 | { 43 | "name": "x-lc-prod", 44 | "value": "1" 45 | }, 46 | { 47 | "name": "content-length", 48 | "value": 4 49 | }, 50 | { 51 | "name": "host", 52 | "value": "95tnuaos.api.lncldapi.com" 53 | } 54 | ], 55 | "headersSize": 506, 56 | "httpVersion": "HTTP/1.1", 57 | "method": "GET", 58 | "postData": { 59 | "mimeType": "application/json;charset=UTF-8", 60 | "params": [], 61 | "text": "null" 62 | }, 63 | "queryString": [ 64 | { 65 | "name": "cql", 66 | "value": "select *,count(objectId) from GameScore limit ?" 67 | }, 68 | { 69 | "name": "pvalues", 70 | "value": "[5]" 71 | } 72 | ], 73 | "url": "https://95tnuaos.api.lncldapi.com/1.1/cloudQuery?cql=select%20%2A%2Ccount%28objectId%29%20from%20GameScore%20limit%20%3F&pvalues=%5B5%5D" 74 | }, 75 | "response": { 76 | "bodySize": 532, 77 | "content": { 78 | "mimeType": "application/json;charset=utf-8", 79 | "size": 532, 80 | "text": "[\"1f8b08000000000000038d923d4fc3301086ffcbcd6d743ec736f6c6841860211388c1f187100aa48a930155f9ef5c69175a45c964bda747f7bc27f908432a533716706f47980ed18f29de8fe08050a8bdc03d5123a44374d254b550afb08330a42d58df7ea6303e46a694a6bb18b3d2d812a56c43adeb844ac2bc5bb74a6db7582fd8aab5cedbac466eb29eb155abc265ab698470d23a89959566d17a8b1d3aff938667ff95982b31f3a8847ee044bce383773cf59153f65d49d725b32643a7925e876c91c8b4512f97d48d40276a47b6222b164bde62e792a70f069e630befd74d628ea8fe35916460662e74be94cb7d0ffcbcfc5dc7f37efa66ad2052f32f69f5bb3bc3020000\"]" 81 | }, 82 | "cookies": [], 83 | "headers": [ 84 | { 85 | "name": "server", 86 | "value": "openresty" 87 | }, 88 | { 89 | "name": "date", 90 | "value": "Thu, 19 Sep 2019 04:46:06 GMT" 91 | }, 92 | { 93 | "name": "content-type", 94 | "value": "application/json;charset=utf-8" 95 | }, 96 | { 97 | "name": "transfer-encoding", 98 | "value": "chunked" 99 | }, 100 | { 101 | "name": "connection", 102 | "value": "close" 103 | }, 104 | { 105 | "name": "vary", 106 | "value": "Accept-Encoding" 107 | }, 108 | { 109 | "name": "cache-control", 110 | "value": "no-cache,no-store" 111 | }, 112 | { 113 | "name": "pragma", 114 | "value": "no-cache" 115 | }, 116 | { 117 | "name": "content-encoding", 118 | "value": "gzip" 119 | } 120 | ], 121 | "headersSize": 250, 122 | "httpVersion": "HTTP/1.1", 123 | "redirectURL": "", 124 | "status": 200, 125 | "statusText": "OK" 126 | }, 127 | "startedDateTime": "2019-09-19T04:46:05.957Z", 128 | "time": 159, 129 | "timings": { 130 | "blocked": -1, 131 | "connect": -1, 132 | "dns": -1, 133 | "receive": 0, 134 | "send": 0, 135 | "ssl": -1, 136 | "wait": 159 137 | } 138 | } 139 | ], 140 | "pages": [], 141 | "version": "1.2" 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /recordings/Queries_842530531/-cloudQuery_1998416685/should-return-limited-results-_4046762198/recording.har: -------------------------------------------------------------------------------- 1 | { 2 | "log": { 3 | "_recordingName": "Queries/#cloudQuery/should return limited results.", 4 | "creator": { 5 | "comment": "persister:fs", 6 | "name": "Polly.JS", 7 | "version": "2.6.2" 8 | }, 9 | "entries": [ 10 | { 11 | "_id": "fb0ff608218bb6c0ac38c94ecd90067b", 12 | "_order": 0, 13 | "cache": {}, 14 | "request": { 15 | "bodySize": 4, 16 | "cookies": [], 17 | "headers": [ 18 | { 19 | "name": "accept-encoding", 20 | "value": "gzip, deflate" 21 | }, 22 | { 23 | "name": "user-agent", 24 | "value": "LeanCloud-JS-SDK/3.15.0 (Node.js; Node.js/v12.10.0)" 25 | }, 26 | { 27 | "name": "x-lc-id", 28 | "value": "95TNUaOSUd8IpKNW0RSqSEOm-9Nh9j0Va" 29 | }, 30 | { 31 | "name": "content-type", 32 | "value": "application/json;charset=UTF-8" 33 | }, 34 | { 35 | "name": "x-lc-sign", 36 | "value": "4eb3182cf9bc1aef3e387d9382bb0907,1568868365599" 37 | }, 38 | { 39 | "name": "x-lc-hook-key", 40 | "value": "2iCbUZDgEF0siKxmCn2kVQXV" 41 | }, 42 | { 43 | "name": "x-lc-prod", 44 | "value": "1" 45 | }, 46 | { 47 | "name": "content-length", 48 | "value": 4 49 | }, 50 | { 51 | "name": "host", 52 | "value": "95tnuaos.api.lncldapi.com" 53 | } 54 | ], 55 | "headersSize": 467, 56 | "httpVersion": "HTTP/1.1", 57 | "method": "GET", 58 | "postData": { 59 | "mimeType": "application/json;charset=UTF-8", 60 | "params": [], 61 | "text": "null" 62 | }, 63 | "queryString": [ 64 | { 65 | "name": "cql", 66 | "value": "select * from GameScore limit 10" 67 | } 68 | ], 69 | "url": "https://95tnuaos.api.lncldapi.com/1.1/cloudQuery?cql=select%20%2A%20from%20GameScore%20limit%2010" 70 | }, 71 | "response": { 72 | "bodySize": 776, 73 | "content": { 74 | "mimeType": "application/json;charset=utf-8", 75 | "size": 776, 76 | "text": "[\"1f8b0800000000000003a5933b6fc2301485ff8b6788aeeff523f6d6a9ead02ecdd4aa83e387aa8a0a44c25021fe7b1d1e43020624a6e84647fe8e8fcfddb275ec368bbe63f673cb36abe0fa189e7a66190297730e73c4869305b0a42bc1e5079b31bf8ef7c896ed4ff4fd4bc82aa9b00e2149052d624cc60b25224862bbd96d2a29730ff528bb4915e93eaaa6bba807d94daa843255379c5b3296a032a48bd473d96ae1fee2facdfdc6aceb42cabf3abf5ce709f319dff98cd765c853728b2e4e4d26851a07934ef9640051b741954daa8683e5c2a2a9d0f0a2c973d9c1e45030e6f2d8b2afa9939002c89113425d70c2e79c1ad01633852a85052717658fc425649d300c26a50a2ee820c06029ae139d9415225704af9b1cc9265443e0c7541fae3e92b040f9da15427957cf658f448391d0d5a3f793e0cbd1d4fb1ed7c3c31828acf645d9381aaf08f7ad9151682fd119114bd4d3f608b43c1713eaeb4b36924db786783bde9a986b903bed17aeeb8e093ee7cffb3ebfdd3f670ae6bc62050000\"]" 77 | }, 78 | "cookies": [], 79 | "headers": [ 80 | { 81 | "name": "server", 82 | "value": "openresty" 83 | }, 84 | { 85 | "name": "date", 86 | "value": "Thu, 19 Sep 2019 04:46:05 GMT" 87 | }, 88 | { 89 | "name": "content-type", 90 | "value": "application/json;charset=utf-8" 91 | }, 92 | { 93 | "name": "transfer-encoding", 94 | "value": "chunked" 95 | }, 96 | { 97 | "name": "connection", 98 | "value": "close" 99 | }, 100 | { 101 | "name": "vary", 102 | "value": "Accept-Encoding" 103 | }, 104 | { 105 | "name": "cache-control", 106 | "value": "no-cache,no-store" 107 | }, 108 | { 109 | "name": "pragma", 110 | "value": "no-cache" 111 | }, 112 | { 113 | "name": "content-encoding", 114 | "value": "gzip" 115 | } 116 | ], 117 | "headersSize": 250, 118 | "httpVersion": "HTTP/1.1", 119 | "redirectURL": "", 120 | "status": 200, 121 | "statusText": "OK" 122 | }, 123 | "startedDateTime": "2019-09-19T04:46:05.601Z", 124 | "time": 161, 125 | "timings": { 126 | "blocked": -1, 127 | "connect": -1, 128 | "dns": -1, 129 | "receive": 0, 130 | "send": 0, 131 | "ssl": -1, 132 | "wait": 161 133 | } 134 | } 135 | ], 136 | "pages": [], 137 | "version": "1.2" 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /recordings/Queries_842530531/-cloudQuery_1998416685/should-return-syntax-error-_1626848969/recording.har: -------------------------------------------------------------------------------- 1 | { 2 | "log": { 3 | "_recordingName": "Queries/#cloudQuery/should return syntax error.", 4 | "creator": { 5 | "comment": "persister:fs", 6 | "name": "Polly.JS", 7 | "version": "2.6.2" 8 | }, 9 | "entries": [ 10 | { 11 | "_id": "84ac89d73d1e41ed2f56fb8da0078bd3", 12 | "_order": 0, 13 | "cache": {}, 14 | "request": { 15 | "bodySize": 4, 16 | "cookies": [], 17 | "headers": [ 18 | { 19 | "name": "accept-encoding", 20 | "value": "gzip, deflate" 21 | }, 22 | { 23 | "name": "user-agent", 24 | "value": "LeanCloud-JS-SDK/3.15.0 (Node.js; Node.js/v12.10.0)" 25 | }, 26 | { 27 | "name": "x-lc-id", 28 | "value": "95TNUaOSUd8IpKNW0RSqSEOm-9Nh9j0Va" 29 | }, 30 | { 31 | "name": "content-type", 32 | "value": "application/json;charset=UTF-8" 33 | }, 34 | { 35 | "name": "x-lc-sign", 36 | "value": "7aa175ea960a50883ba947cd889bea08,1568868366122" 37 | }, 38 | { 39 | "name": "x-lc-hook-key", 40 | "value": "2iCbUZDgEF0siKxmCn2kVQXV" 41 | }, 42 | { 43 | "name": "x-lc-prod", 44 | "value": "1" 45 | }, 46 | { 47 | "name": "content-length", 48 | "value": 4 49 | }, 50 | { 51 | "name": "host", 52 | "value": "95tnuaos.api.lncldapi.com" 53 | } 54 | ], 55 | "headersSize": 460, 56 | "httpVersion": "HTTP/1.1", 57 | "method": "GET", 58 | "postData": { 59 | "mimeType": "application/json;charset=UTF-8", 60 | "params": [], 61 | "text": "null" 62 | }, 63 | "queryString": [ 64 | { 65 | "name": "cql", 66 | "value": "select * GameScore limit 10" 67 | } 68 | ], 69 | "url": "https://95tnuaos.api.lncldapi.com/1.1/cloudQuery?cql=select%20%2A%20GameScore%20limit%2010" 70 | }, 71 | "response": { 72 | "bodySize": 164, 73 | "content": { 74 | "mimeType": "application/json;charset=utf-8", 75 | "size": 164, 76 | "text": "{\"code\":300,\"error\":\"CQL syntax error.Detail: Parse error at line 1, column 10:\\nselect * GameScore limit 10\\n ^\\nExpected one of:\\nfrom\\n#\\\"\\\\s+\\\"\\n,\\n\\n\"}" 77 | }, 78 | "cookies": [], 79 | "headers": [ 80 | { 81 | "name": "server", 82 | "value": "openresty" 83 | }, 84 | { 85 | "name": "date", 86 | "value": "Thu, 19 Sep 2019 04:46:06 GMT" 87 | }, 88 | { 89 | "name": "content-type", 90 | "value": "application/json;charset=utf-8" 91 | }, 92 | { 93 | "name": "transfer-encoding", 94 | "value": "chunked" 95 | }, 96 | { 97 | "name": "connection", 98 | "value": "close" 99 | }, 100 | { 101 | "name": "cache-control", 102 | "value": "no-cache,no-store" 103 | }, 104 | { 105 | "name": "pragma", 106 | "value": "no-cache" 107 | } 108 | ], 109 | "headersSize": 203, 110 | "httpVersion": "HTTP/1.1", 111 | "redirectURL": "", 112 | "status": 400, 113 | "statusText": "Bad Request" 114 | }, 115 | "startedDateTime": "2019-09-19T04:46:06.125Z", 116 | "time": 147, 117 | "timings": { 118 | "blocked": -1, 119 | "connect": -1, 120 | "dns": -1, 121 | "receive": 0, 122 | "send": 0, 123 | "ssl": -1, 124 | "wait": 147 125 | } 126 | } 127 | ], 128 | "pages": [], 129 | "version": "1.2" 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /recordings/Queries_842530531/Compound-Query_632679536/should-satisfy-on-and-conditions_1689265471/recording.har: -------------------------------------------------------------------------------- 1 | { 2 | "log": { 3 | "_recordingName": "Queries/Compound Query/should satisfy on 'and' conditions", 4 | "creator": { 5 | "comment": "persister:fs", 6 | "name": "Polly.JS", 7 | "version": "2.6.2" 8 | }, 9 | "entries": [ 10 | { 11 | "_id": "47a5a97780cb563cb103a7280a4caad1", 12 | "_order": 0, 13 | "cache": {}, 14 | "request": { 15 | "bodySize": 0, 16 | "cookies": [], 17 | "headers": [ 18 | { 19 | "name": "accept-encoding", 20 | "value": "gzip, deflate" 21 | }, 22 | { 23 | "name": "user-agent", 24 | "value": "LeanCloud-JS-SDK/3.15.0 (Node.js; Node.js/v12.10.0)" 25 | }, 26 | { 27 | "name": "x-lc-id", 28 | "value": "95TNUaOSUd8IpKNW0RSqSEOm-9Nh9j0Va" 29 | }, 30 | { 31 | "name": "content-type", 32 | "value": "application/json;charset=UTF-8" 33 | }, 34 | { 35 | "name": "x-lc-sign", 36 | "value": "4a7d5036c006c0a0a9b0b9a0a53787b9,1568868373907" 37 | }, 38 | { 39 | "name": "x-lc-hook-key", 40 | "value": "2iCbUZDgEF0siKxmCn2kVQXV" 41 | }, 42 | { 43 | "name": "x-lc-prod", 44 | "value": "1" 45 | }, 46 | { 47 | "name": "host", 48 | "value": "95tnuaos.api.lncldapi.com" 49 | } 50 | ], 51 | "headersSize": 514, 52 | "httpVersion": "HTTP/1.1", 53 | "method": "GET", 54 | "queryString": [ 55 | { 56 | "name": "where", 57 | "value": "{\"$and\":[{\"score\":{\"$gt\":150}},{\"cheatMode\":true}]}" 58 | } 59 | ], 60 | "url": "https://95tnuaos.api.lncldapi.com/1.1/classes/GameScore?where=%7B%22%24and%22%3A%5B%7B%22score%22%3A%7B%22%24gt%22%3A150%7D%7D%2C%7B%22cheatMode%22%3Atrue%7D%5D%7D" 61 | }, 62 | "response": { 63 | "bodySize": 72, 64 | "content": { 65 | "mimeType": "application/json;charset=utf-8", 66 | "size": 72, 67 | "text": "[\"1f8b0800000000000003ab562a4a2d2ecd292956b28a8ead05000a277c9e0e000000\"]" 68 | }, 69 | "cookies": [], 70 | "headers": [ 71 | { 72 | "name": "server", 73 | "value": "openresty" 74 | }, 75 | { 76 | "name": "date", 77 | "value": "Thu, 19 Sep 2019 04:46:14 GMT" 78 | }, 79 | { 80 | "name": "content-type", 81 | "value": "application/json;charset=utf-8" 82 | }, 83 | { 84 | "name": "transfer-encoding", 85 | "value": "chunked" 86 | }, 87 | { 88 | "name": "connection", 89 | "value": "close" 90 | }, 91 | { 92 | "name": "vary", 93 | "value": "Accept-Encoding" 94 | }, 95 | { 96 | "name": "cache-control", 97 | "value": "no-cache,no-store" 98 | }, 99 | { 100 | "name": "pragma", 101 | "value": "no-cache" 102 | }, 103 | { 104 | "name": "last-modified", 105 | "value": "Thu, 19 Sep 2019 04:46:12.153 GMT" 106 | }, 107 | { 108 | "name": "content-encoding", 109 | "value": "gzip" 110 | } 111 | ], 112 | "headersSize": 300, 113 | "httpVersion": "HTTP/1.1", 114 | "redirectURL": "", 115 | "status": 200, 116 | "statusText": "OK" 117 | }, 118 | "startedDateTime": "2019-09-19T04:46:13.908Z", 119 | "time": 159, 120 | "timings": { 121 | "blocked": -1, 122 | "connect": -1, 123 | "dns": -1, 124 | "receive": 0, 125 | "send": 0, 126 | "ssl": -1, 127 | "wait": 159 128 | } 129 | } 130 | ], 131 | "pages": [], 132 | "version": "1.2" 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /recordings/Queries_842530531/Counts_2261259173/should-return-num_2552064632/recording.har: -------------------------------------------------------------------------------- 1 | { 2 | "log": { 3 | "_recordingName": "Queries/Counts/should return num", 4 | "creator": { 5 | "comment": "persister:fs", 6 | "name": "Polly.JS", 7 | "version": "2.6.2" 8 | }, 9 | "entries": [ 10 | { 11 | "_id": "1a6fd0fb298682b52858e9ce37173fc5", 12 | "_order": 0, 13 | "cache": {}, 14 | "request": { 15 | "bodySize": 0, 16 | "cookies": [], 17 | "headers": [ 18 | { 19 | "name": "accept-encoding", 20 | "value": "gzip, deflate" 21 | }, 22 | { 23 | "name": "user-agent", 24 | "value": "LeanCloud-JS-SDK/3.15.0 (Node.js; Node.js/v12.10.0)" 25 | }, 26 | { 27 | "name": "x-lc-id", 28 | "value": "95TNUaOSUd8IpKNW0RSqSEOm-9Nh9j0Va" 29 | }, 30 | { 31 | "name": "content-type", 32 | "value": "application/json;charset=UTF-8" 33 | }, 34 | { 35 | "name": "x-lc-sign", 36 | "value": "9c670aa3b1fb48c6e3a177d242d3138e,1568868373517" 37 | }, 38 | { 39 | "name": "x-lc-hook-key", 40 | "value": "2iCbUZDgEF0siKxmCn2kVQXV" 41 | }, 42 | { 43 | "name": "x-lc-prod", 44 | "value": "1" 45 | }, 46 | { 47 | "name": "host", 48 | "value": "95tnuaos.api.lncldapi.com" 49 | } 50 | ], 51 | "headersSize": 493, 52 | "httpVersion": "HTTP/1.1", 53 | "method": "GET", 54 | "queryString": [ 55 | { 56 | "name": "where", 57 | "value": "{\"pname\":{\"$regex\":\"^\\\\Qp\\\\E\"}}" 58 | }, 59 | { 60 | "name": "limit", 61 | "value": "0" 62 | }, 63 | { 64 | "name": "count", 65 | "value": "1" 66 | } 67 | ], 68 | "url": "https://95tnuaos.api.lncldapi.com/1.1/classes/Person?where=%7B%22pname%22%3A%7B%22%24regex%22%3A%22%5E%5C%5CQp%5C%5CE%22%7D%7D&limit=0&count=1" 69 | }, 70 | "response": { 71 | "bodySize": 98, 72 | "content": { 73 | "mimeType": "application/json;charset=utf-8", 74 | "size": 98, 75 | "text": "[\"1f8b0800000000000003ab562a4a2d2ecd292956b28a8ed5514ace2fcd2b51b23236b730ae0500c73bdcad1b000000\"]" 76 | }, 77 | "cookies": [], 78 | "headers": [ 79 | { 80 | "name": "server", 81 | "value": "openresty" 82 | }, 83 | { 84 | "name": "date", 85 | "value": "Thu, 19 Sep 2019 04:46:13 GMT" 86 | }, 87 | { 88 | "name": "content-type", 89 | "value": "application/json;charset=utf-8" 90 | }, 91 | { 92 | "name": "transfer-encoding", 93 | "value": "chunked" 94 | }, 95 | { 96 | "name": "connection", 97 | "value": "close" 98 | }, 99 | { 100 | "name": "vary", 101 | "value": "Accept-Encoding" 102 | }, 103 | { 104 | "name": "cache-control", 105 | "value": "no-cache,no-store" 106 | }, 107 | { 108 | "name": "pragma", 109 | "value": "no-cache" 110 | }, 111 | { 112 | "name": "last-modified", 113 | "value": "Thu, 19 Sep 2019 04:46:03.141 GMT" 114 | }, 115 | { 116 | "name": "content-encoding", 117 | "value": "gzip" 118 | } 119 | ], 120 | "headersSize": 300, 121 | "httpVersion": "HTTP/1.1", 122 | "redirectURL": "", 123 | "status": 200, 124 | "statusText": "OK" 125 | }, 126 | "startedDateTime": "2019-09-19T04:46:13.519Z", 127 | "time": 176, 128 | "timings": { 129 | "blocked": -1, 130 | "connect": -1, 131 | "dns": -1, 132 | "receive": 0, 133 | "send": 0, 134 | "ssl": -1, 135 | "wait": 176 136 | } 137 | } 138 | ], 139 | "pages": [], 140 | "version": "1.2" 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /recordings/Queries_842530531/Query-with-different-condtions_1390618707/query-doncition-with-array_1620466613/recording.har: -------------------------------------------------------------------------------- 1 | { 2 | "log": { 3 | "_recordingName": "Queries/Query with different condtions/query doncition with array", 4 | "creator": { 5 | "comment": "persister:fs", 6 | "name": "Polly.JS", 7 | "version": "2.6.2" 8 | }, 9 | "entries": [ 10 | { 11 | "_id": "b24fc436e6b45f23525f8e4b4d4c1826", 12 | "_order": 0, 13 | "cache": {}, 14 | "request": { 15 | "bodySize": 0, 16 | "cookies": [], 17 | "headers": [ 18 | { 19 | "name": "accept-encoding", 20 | "value": "gzip, deflate" 21 | }, 22 | { 23 | "name": "user-agent", 24 | "value": "LeanCloud-JS-SDK/3.15.0 (Node.js; Node.js/v12.10.0)" 25 | }, 26 | { 27 | "name": "x-lc-id", 28 | "value": "95TNUaOSUd8IpKNW0RSqSEOm-9Nh9j0Va" 29 | }, 30 | { 31 | "name": "content-type", 32 | "value": "application/json;charset=UTF-8" 33 | }, 34 | { 35 | "name": "x-lc-sign", 36 | "value": "7d4399309322a0c9b5ed033c09811498,1568868372177" 37 | }, 38 | { 39 | "name": "x-lc-hook-key", 40 | "value": "2iCbUZDgEF0siKxmCn2kVQXV" 41 | }, 42 | { 43 | "name": "x-lc-prod", 44 | "value": "1" 45 | }, 46 | { 47 | "name": "host", 48 | "value": "95tnuaos.api.lncldapi.com" 49 | } 50 | ], 51 | "headersSize": 449, 52 | "httpVersion": "HTTP/1.1", 53 | "method": "GET", 54 | "queryString": [ 55 | { 56 | "name": "where", 57 | "value": "{\"arr\":\"arr1\"}" 58 | }, 59 | { 60 | "name": "limit", 61 | "value": "1" 62 | } 63 | ], 64 | "url": "https://95tnuaos.api.lncldapi.com/1.1/classes/GameScore?where=%7B%22arr%22%3A%22arr1%22%7D&limit=1" 65 | }, 66 | "response": { 67 | "bodySize": 352, 68 | "content": { 69 | "mimeType": "application/json;charset=utf-8", 70 | "size": 352, 71 | "text": "[\"1f8b0800000000000003758dbd0ec2300c84dfc5735b394ddba4dd181960620275c88f11a0a256493aa0aaef8e2366bcd8773a7fb741a0b84e29c270db605dbc49e40f0906a851a8528852a80baa41f6438355abf10a059810389e97f8a91ac60266fb22978e9e7f5b83d4d7d20a6cc86a44a9bd6bacea38ed02fdaf907dd569912b96c97c289ccd9b38e73d3bcf0c7ee62bba39b02d9087810f069e66cfcedd4c91f671ff02481ee643d5000000\"]" 72 | }, 73 | "cookies": [], 74 | "headers": [ 75 | { 76 | "name": "server", 77 | "value": "openresty" 78 | }, 79 | { 80 | "name": "date", 81 | "value": "Thu, 19 Sep 2019 04:46:12 GMT" 82 | }, 83 | { 84 | "name": "content-type", 85 | "value": "application/json;charset=utf-8" 86 | }, 87 | { 88 | "name": "transfer-encoding", 89 | "value": "chunked" 90 | }, 91 | { 92 | "name": "connection", 93 | "value": "close" 94 | }, 95 | { 96 | "name": "vary", 97 | "value": "Accept-Encoding" 98 | }, 99 | { 100 | "name": "cache-control", 101 | "value": "no-cache,no-store" 102 | }, 103 | { 104 | "name": "pragma", 105 | "value": "no-cache" 106 | }, 107 | { 108 | "name": "last-modified", 109 | "value": "Thu, 19 Sep 2019 04:46:12.153 GMT" 110 | }, 111 | { 112 | "name": "content-encoding", 113 | "value": "gzip" 114 | } 115 | ], 116 | "headersSize": 300, 117 | "httpVersion": "HTTP/1.1", 118 | "redirectURL": "", 119 | "status": 200, 120 | "statusText": "OK" 121 | }, 122 | "startedDateTime": "2019-09-19T04:46:12.179Z", 123 | "time": 149, 124 | "timings": { 125 | "blocked": -1, 126 | "connect": -1, 127 | "dns": -1, 128 | "receive": 0, 129 | "send": 0, 130 | "ssl": -1, 131 | "wait": 149 132 | } 133 | } 134 | ], 135 | "pages": [], 136 | "version": "1.2" 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /recordings/Role_2418769465/constructor_4066221903/acl-is-required_3763596966/recording.har: -------------------------------------------------------------------------------- 1 | { 2 | "log": { 3 | "_recordingName": "Role/constructor/acl is required", 4 | "creator": { 5 | "comment": "persister:fs", 6 | "name": "Polly.JS", 7 | "version": "2.6.2" 8 | }, 9 | "entries": [ 10 | { 11 | "_id": "db635d151ade7aa27abbd3d9fdecff6e", 12 | "_order": 0, 13 | "cache": {}, 14 | "request": { 15 | "bodySize": 14, 16 | "cookies": [], 17 | "headers": [ 18 | { 19 | "name": "accept-encoding", 20 | "value": "gzip, deflate" 21 | }, 22 | { 23 | "name": "user-agent", 24 | "value": "LeanCloud-JS-SDK/3.15.0 (Node.js; Node.js/v12.10.0)" 25 | }, 26 | { 27 | "name": "x-lc-id", 28 | "value": "95TNUaOSUd8IpKNW0RSqSEOm-9Nh9j0Va" 29 | }, 30 | { 31 | "name": "content-type", 32 | "value": "application/json;charset=UTF-8" 33 | }, 34 | { 35 | "name": "x-lc-sign", 36 | "value": "feea05a17865905ffc40b3f04b302ab5,1569224366878" 37 | }, 38 | { 39 | "name": "x-lc-hook-key", 40 | "value": "2iCbUZDgEF0siKxmCn2kVQXV" 41 | }, 42 | { 43 | "name": "x-lc-prod", 44 | "value": "1" 45 | }, 46 | { 47 | "name": "x-lc-session", 48 | "value": "nrivwzkwe7fwcnyxcmqdcaryu" 49 | }, 50 | { 51 | "name": "content-length", 52 | "value": 14 53 | }, 54 | { 55 | "name": "host", 56 | "value": "95tnuaos.api.lncldapi.com" 57 | } 58 | ], 59 | "headersSize": 464, 60 | "httpVersion": "HTTP/1.1", 61 | "method": "POST", 62 | "postData": { 63 | "mimeType": "application/json;charset=UTF-8", 64 | "params": [], 65 | "text": "{\"name\":\"foo\"}" 66 | }, 67 | "queryString": [], 68 | "url": "https://95tnuaos.api.lncldapi.com/1.1/classes/_Role" 69 | }, 70 | "response": { 71 | "bodySize": 42, 72 | "content": { 73 | "mimeType": "application/json;charset=utf-8", 74 | "size": 42, 75 | "text": "{\"code\":1,\"error\":\"Role ACL is required.\"}" 76 | }, 77 | "cookies": [], 78 | "headers": [ 79 | { 80 | "name": "server", 81 | "value": "openresty" 82 | }, 83 | { 84 | "name": "date", 85 | "value": "Mon, 23 Sep 2019 07:39:27 GMT" 86 | }, 87 | { 88 | "name": "content-type", 89 | "value": "application/json;charset=utf-8" 90 | }, 91 | { 92 | "name": "transfer-encoding", 93 | "value": "chunked" 94 | }, 95 | { 96 | "name": "connection", 97 | "value": "close" 98 | }, 99 | { 100 | "name": "cache-control", 101 | "value": "no-cache,no-store" 102 | }, 103 | { 104 | "name": "pragma", 105 | "value": "no-cache" 106 | } 107 | ], 108 | "headersSize": 203, 109 | "httpVersion": "HTTP/1.1", 110 | "redirectURL": "", 111 | "status": 400, 112 | "statusText": "Bad Request" 113 | }, 114 | "startedDateTime": "2019-09-23T07:39:26.880Z", 115 | "time": 162, 116 | "timings": { 117 | "blocked": -1, 118 | "connect": -1, 119 | "dns": -1, 120 | "receive": 0, 121 | "send": 0, 122 | "ssl": -1, 123 | "wait": 162 124 | } 125 | } 126 | ], 127 | "pages": [], 128 | "version": "1.2" 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /recordings/User_3768991250/Current-User_1380399265/currentAsync-_4006155249/recording.har: -------------------------------------------------------------------------------- 1 | { 2 | "log": { 3 | "_recordingName": "User/Current User/currentAsync()", 4 | "creator": { 5 | "comment": "persister:fs", 6 | "name": "Polly.JS", 7 | "version": "2.6.2" 8 | }, 9 | "entries": [ 10 | { 11 | "_id": "f083b232583ad8178f9737c3a080464a", 12 | "_order": 0, 13 | "cache": {}, 14 | "request": { 15 | "bodySize": 0, 16 | "cookies": [], 17 | "headers": [ 18 | { 19 | "name": "accept-encoding", 20 | "value": "gzip, deflate" 21 | }, 22 | { 23 | "name": "user-agent", 24 | "value": "LeanCloud-JS-SDK/3.15.0 (Node.js; Node.js/v12.10.0)" 25 | }, 26 | { 27 | "name": "x-lc-id", 28 | "value": "95TNUaOSUd8IpKNW0RSqSEOm-9Nh9j0Va" 29 | }, 30 | { 31 | "name": "content-type", 32 | "value": "application/json;charset=UTF-8" 33 | }, 34 | { 35 | "name": "x-lc-sign", 36 | "value": "79b4d3c5ae754ccbfde8b9a29c765dbf,1568873164662,master" 37 | }, 38 | { 39 | "name": "x-lc-hook-key", 40 | "value": "2iCbUZDgEF0siKxmCn2kVQXV" 41 | }, 42 | { 43 | "name": "x-lc-prod", 44 | "value": "1" 45 | }, 46 | { 47 | "name": "x-lc-session", 48 | "value": "47vn9wub7mqe5piw9ktd6d8tx" 49 | }, 50 | { 51 | "name": "host", 52 | "value": "95tnuaos.api.lncldapi.com" 53 | } 54 | ], 55 | "headersSize": 501, 56 | "httpVersion": "HTTP/1.1", 57 | "method": "GET", 58 | "queryString": [ 59 | { 60 | "name": "where", 61 | "value": "{\"username\":\"tester1\"}" 62 | }, 63 | { 64 | "name": "limit", 65 | "value": "1" 66 | } 67 | ], 68 | "url": "https://95tnuaos.api.lncldapi.com/1.1/classes/_User?where=%7B%22username%22%3A%22tester1%22%7D&limit=1" 69 | }, 70 | "response": { 71 | "bodySize": 72, 72 | "content": { 73 | "mimeType": "application/json;charset=utf-8", 74 | "size": 72, 75 | "text": "[\"1f8b0800000000000003ab562a4a2d2ecd292956b28a8ead05000a277c9e0e000000\"]" 76 | }, 77 | "cookies": [], 78 | "headers": [ 79 | { 80 | "name": "server", 81 | "value": "openresty" 82 | }, 83 | { 84 | "name": "date", 85 | "value": "Thu, 19 Sep 2019 06:06:04 GMT" 86 | }, 87 | { 88 | "name": "content-type", 89 | "value": "application/json;charset=utf-8" 90 | }, 91 | { 92 | "name": "transfer-encoding", 93 | "value": "chunked" 94 | }, 95 | { 96 | "name": "connection", 97 | "value": "close" 98 | }, 99 | { 100 | "name": "vary", 101 | "value": "Accept-Encoding" 102 | }, 103 | { 104 | "name": "cache-control", 105 | "value": "no-cache,no-store" 106 | }, 107 | { 108 | "name": "pragma", 109 | "value": "no-cache" 110 | }, 111 | { 112 | "name": "last-modified", 113 | "value": "Thu, 19 Sep 2019 06:06:04.626 GMT" 114 | }, 115 | { 116 | "name": "content-encoding", 117 | "value": "gzip" 118 | } 119 | ], 120 | "headersSize": 300, 121 | "httpVersion": "HTTP/1.1", 122 | "redirectURL": "", 123 | "status": 200, 124 | "statusText": "OK" 125 | }, 126 | "startedDateTime": "2019-09-19T06:06:04.664Z", 127 | "time": 164, 128 | "timings": { 129 | "blocked": -1, 130 | "connect": -1, 131 | "dns": -1, 132 | "receive": 0, 133 | "send": 0, 134 | "ssl": -1, 135 | "wait": 164 136 | } 137 | } 138 | ], 139 | "pages": [], 140 | "version": "1.2" 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /script/check-version.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | const assert = require('assert'); 3 | assert.equal(require('../').version, require('../package.json').version); 4 | assert.equal( 5 | require('../package.json').version, 6 | require('../package-lock.json').version 7 | ); 8 | -------------------------------------------------------------------------------- /script/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | echo "Deploy docs to github pages."; 3 | npm run docs; 4 | mkdir gh_pages; 5 | cp -r docs gh_pages/; 6 | mkdir gh_pages/dist; 7 | cp -r dist/av* gh_pages/dist/; 8 | cp -r demo gh_pages/; 9 | cd gh_pages && git init; 10 | git config user.name "leancloud-bot"; 11 | git config user.email "ci@leancloud.cn"; 12 | git add .; 13 | git commit -m "Deploy docs and demos to Github Pages [skip ci]"; 14 | git push -qf https://${TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git master:gh-pages; 15 | echo "done."; 16 | cd .. 17 | -------------------------------------------------------------------------------- /script/gh-deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | echo "Deploy docs to github pages."; 3 | git checkout --orphan gh-pages; 4 | git reset HEAD -- .; 5 | npm run docs; 6 | git add -f dist/av* docs demo 7 | git config user.name "leancloud-bot"; 8 | git config user.email "ci@leancloud.cn"; 9 | git commit -m "Deploy docs and demos to Github Pages [skip ci]"; 10 | git push -qf origin gh-pages; 11 | echo "done."; 12 | -------------------------------------------------------------------------------- /script/gh-release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "Deploy dist to dist branch."; 3 | REV=`git rev-parse HEAD`; 4 | BRANCH=`git rev-parse --abbrev-ref HEAD`; 5 | DIST_BRANCH=${1:-dist}; 6 | test "$(git config user.name)" = '' && ( 7 | git config user.name "leancloud-bot"; 8 | git config user.email "ci@leancloud.cn"; 9 | ) 10 | git add dist -f; 11 | git commit -m "chore(build): build ${REV} [skip ci]"; 12 | git push -qf origin ${BRANCH}:${DIST_BRANCH} > /dev/null 2>&1; 13 | git reset HEAD~1; 14 | echo "done."; 15 | -------------------------------------------------------------------------------- /script/release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "Deploy dist to dist branch."; 3 | REV=`git rev-parse HEAD`; 4 | BRANCH=`git rev-parse --abbrev-ref HEAD`; 5 | DIST_BRANCH=${1:-dist}; 6 | test "$(git config user.name)" = '' && ( 7 | git config user.name "leancloud-bot"; 8 | git config user.email "ci@leancloud.cn"; 9 | ) 10 | git add dist -f; 11 | git commit -m "chore(build): build ${REV} [skip ci]"; 12 | git push -qf https://${TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git ${BRANCH}:${DIST_BRANCH} > /dev/null 2>&1; 13 | git reset HEAD~1; 14 | echo "done."; 15 | -------------------------------------------------------------------------------- /src/adapter.js: -------------------------------------------------------------------------------- 1 | const _ = require('underscore'); 2 | const EventEmitter = require('eventemitter3'); 3 | const { inherits } = require('./utils'); 4 | 5 | const AdapterManager = inherits(EventEmitter, { 6 | constructor() { 7 | EventEmitter.apply(this); 8 | this._adapters = {}; 9 | }, 10 | getAdapter(name) { 11 | const adapter = this._adapters[name]; 12 | if (adapter === undefined) { 13 | throw new Error(`${name} adapter is not configured`); 14 | } 15 | return adapter; 16 | }, 17 | setAdapters(newAdapters) { 18 | _.extend(this._adapters, newAdapters); 19 | _.keys(newAdapters).forEach(name => this.emit(name, newAdapters[name])); 20 | }, 21 | }); 22 | 23 | const adapterManager = new AdapterManager(); 24 | 25 | module.exports = { 26 | getAdapter: adapterManager.getAdapter.bind(adapterManager), 27 | setAdapters: adapterManager.setAdapters.bind(adapterManager), 28 | adapterManager, 29 | }; 30 | -------------------------------------------------------------------------------- /src/app-router.js: -------------------------------------------------------------------------------- 1 | const ajax = require('./utils/ajax'); 2 | const Cache = require('./cache'); 3 | 4 | function AppRouter(AV) { 5 | this.AV = AV; 6 | this.lockedUntil = 0; 7 | Cache.getAsync('serverURLs') 8 | .then(data => { 9 | if (this.disabled) return; 10 | if (!data) return this.lock(0); 11 | const { serverURLs, lockedUntil } = data; 12 | this.AV._setServerURLs(serverURLs, false); 13 | this.lockedUntil = lockedUntil; 14 | }) 15 | .catch(() => this.lock(0)); 16 | } 17 | 18 | AppRouter.prototype.disable = function disable() { 19 | this.disabled = true; 20 | }; 21 | AppRouter.prototype.lock = function lock(ttl) { 22 | this.lockedUntil = Date.now() + ttl; 23 | }; 24 | AppRouter.prototype.refresh = function refresh() { 25 | if (this.disabled) return; 26 | if (Date.now() < this.lockedUntil) return; 27 | this.lock(10); 28 | const url = 'https://app-router.com/2/route'; 29 | return ajax({ 30 | method: 'get', 31 | url, 32 | query: { 33 | appId: this.AV.applicationId, 34 | }, 35 | }) 36 | .then(servers => { 37 | if (this.disabled) return; 38 | let ttl = servers.ttl; 39 | if (!ttl) throw new Error('missing ttl'); 40 | ttl = ttl * 1000; 41 | const protocal = 'https://'; 42 | const serverURLs = { 43 | push: protocal + servers.push_server, 44 | stats: protocal + servers.stats_server, 45 | engine: protocal + servers.engine_server, 46 | api: protocal + servers.api_server, 47 | }; 48 | this.AV._setServerURLs(serverURLs, false); 49 | this.lock(ttl); 50 | return Cache.setAsync( 51 | 'serverURLs', 52 | { 53 | serverURLs, 54 | lockedUntil: this.lockedUntil, 55 | }, 56 | ttl 57 | ); 58 | }) 59 | .catch(error => { 60 | // bypass all errors 61 | console.warn(`refresh server URLs failed: ${error.message}`); 62 | this.lock(600); 63 | }); 64 | }; 65 | 66 | module.exports = AppRouter; 67 | -------------------------------------------------------------------------------- /src/cache.js: -------------------------------------------------------------------------------- 1 | const storage = require('./localstorage'); 2 | const AV = require('./av'); 3 | 4 | const removeAsync = (exports.removeAsync = storage.removeItemAsync.bind( 5 | storage 6 | )); 7 | 8 | const getCacheData = (cacheData, key) => { 9 | try { 10 | cacheData = JSON.parse(cacheData); 11 | } catch (e) { 12 | return null; 13 | } 14 | if (cacheData) { 15 | const expired = cacheData.expiredAt && cacheData.expiredAt < Date.now(); 16 | if (!expired) { 17 | return cacheData.value; 18 | } 19 | return removeAsync(key).then(() => null); 20 | } 21 | return null; 22 | }; 23 | 24 | exports.getAsync = key => { 25 | key = `AV/${AV.applicationId}/${key}`; 26 | return storage.getItemAsync(key).then(cache => getCacheData(cache, key)); 27 | }; 28 | 29 | exports.setAsync = (key, value, ttl) => { 30 | const cache = { value }; 31 | if (typeof ttl === 'number') { 32 | cache.expiredAt = Date.now() + ttl; 33 | } 34 | return storage.setItemAsync( 35 | `AV/${AV.applicationId}/${key}`, 36 | JSON.stringify(cache) 37 | ); 38 | }; 39 | -------------------------------------------------------------------------------- /src/entry/core-live-query.js: -------------------------------------------------------------------------------- 1 | const AV = require('./core'); 2 | const useLiveQuery = require('./use-live-query'); 3 | 4 | module.exports = useLiveQuery(AV); 5 | -------------------------------------------------------------------------------- /src/entry/core.js: -------------------------------------------------------------------------------- 1 | module.exports = require('../index'); 2 | -------------------------------------------------------------------------------- /src/entry/index-live-query.js: -------------------------------------------------------------------------------- 1 | const AV = require('./index'); 2 | const useLiveQuery = require('./use-live-query'); 3 | const useAdatpers = require('./use-adapters'); 4 | 5 | module.exports = useAdatpers(useLiveQuery(AV)); 6 | -------------------------------------------------------------------------------- /src/entry/index.js: -------------------------------------------------------------------------------- 1 | const AV = require('./core'); 2 | const useAdatpers = require('./use-adapters'); 3 | 4 | module.exports = useAdatpers(AV); 5 | -------------------------------------------------------------------------------- /src/entry/use-adapters.js: -------------------------------------------------------------------------------- 1 | const adapters = require('@leancloud/platform-adapters-node'); 2 | 3 | module.exports = AV => { 4 | AV.setAdapters(adapters); 5 | return AV; 6 | }; 7 | -------------------------------------------------------------------------------- /src/entry/use-live-query.js: -------------------------------------------------------------------------------- 1 | const { 2 | Realtime, 3 | setAdapters: setRTMAdapters, 4 | } = require('leancloud-realtime/core'); 5 | const { LiveQueryPlugin } = require('leancloud-realtime-plugin-live-query'); 6 | Realtime.__preRegisteredPlugins = [LiveQueryPlugin]; 7 | 8 | module.exports = AV => { 9 | AV._sharedConfig.liveQueryRealtime = Realtime; 10 | 11 | const { setAdapters } = AV; 12 | AV.setAdapters = adapters => { 13 | setAdapters(adapters); 14 | setRTMAdapters(adapters); 15 | }; 16 | 17 | return AV; 18 | }; 19 | -------------------------------------------------------------------------------- /src/event.js: -------------------------------------------------------------------------------- 1 | var _ = require('underscore'); 2 | 3 | module.exports = function(AV) { 4 | var eventSplitter = /\s+/; 5 | var slice = Array.prototype.slice; 6 | 7 | /** 8 | * @class 9 | * 10 | *

    AV.Events is a fork of Backbone's Events module, provided for your 11 | * convenience.

    12 | * 13 | *

    A module that can be mixed in to any object in order to provide 14 | * it with custom events. You may bind callback functions to an event 15 | * with `on`, or remove these functions with `off`. 16 | * Triggering an event fires all callbacks in the order that `on` was 17 | * called. 18 | * 19 | * @private 20 | * @example 21 | * var object = {}; 22 | * _.extend(object, AV.Events); 23 | * object.on('expand', function(){ alert('expanded'); }); 24 | * object.trigger('expand');

    25 | * 26 | */ 27 | AV.Events = { 28 | /** 29 | * Bind one or more space separated events, `events`, to a `callback` 30 | * function. Passing `"all"` will bind the callback to all events fired. 31 | */ 32 | on: function(events, callback, context) { 33 | var calls, event, node, tail, list; 34 | if (!callback) { 35 | return this; 36 | } 37 | events = events.split(eventSplitter); 38 | calls = this._callbacks || (this._callbacks = {}); 39 | 40 | // Create an immutable callback list, allowing traversal during 41 | // modification. The tail is an empty object that will always be used 42 | // as the next node. 43 | event = events.shift(); 44 | while (event) { 45 | list = calls[event]; 46 | node = list ? list.tail : {}; 47 | node.next = tail = {}; 48 | node.context = context; 49 | node.callback = callback; 50 | calls[event] = { tail: tail, next: list ? list.next : node }; 51 | event = events.shift(); 52 | } 53 | 54 | return this; 55 | }, 56 | 57 | /** 58 | * Remove one or many callbacks. If `context` is null, removes all callbacks 59 | * with that function. If `callback` is null, removes all callbacks for the 60 | * event. If `events` is null, removes all bound callbacks for all events. 61 | */ 62 | off: function(events, callback, context) { 63 | var event, calls, node, tail, cb, ctx; 64 | 65 | // No events, or removing *all* events. 66 | if (!(calls = this._callbacks)) { 67 | return; 68 | } 69 | if (!(events || callback || context)) { 70 | delete this._callbacks; 71 | return this; 72 | } 73 | 74 | // Loop through the listed events and contexts, splicing them out of the 75 | // linked list of callbacks if appropriate. 76 | events = events ? events.split(eventSplitter) : _.keys(calls); 77 | event = events.shift(); 78 | while (event) { 79 | node = calls[event]; 80 | delete calls[event]; 81 | if (!node || !(callback || context)) { 82 | continue; 83 | } 84 | // Create a new list, omitting the indicated callbacks. 85 | tail = node.tail; 86 | node = node.next; 87 | while (node !== tail) { 88 | cb = node.callback; 89 | ctx = node.context; 90 | if ((callback && cb !== callback) || (context && ctx !== context)) { 91 | this.on(event, cb, ctx); 92 | } 93 | node = node.next; 94 | } 95 | event = events.shift(); 96 | } 97 | 98 | return this; 99 | }, 100 | 101 | /** 102 | * Trigger one or many events, firing all bound callbacks. Callbacks are 103 | * passed the same arguments as `trigger` is, apart from the event name 104 | * (unless you're listening on `"all"`, which will cause your callback to 105 | * receive the true name of the event as the first argument). 106 | */ 107 | trigger: function(events) { 108 | var event, node, calls, tail, args, all, rest; 109 | if (!(calls = this._callbacks)) { 110 | return this; 111 | } 112 | all = calls.all; 113 | events = events.split(eventSplitter); 114 | rest = slice.call(arguments, 1); 115 | 116 | // For each event, walk through the linked list of callbacks twice, 117 | // first to trigger the event, then to trigger any `"all"` callbacks. 118 | event = events.shift(); 119 | while (event) { 120 | node = calls[event]; 121 | if (node) { 122 | tail = node.tail; 123 | while ((node = node.next) !== tail) { 124 | node.callback.apply(node.context || this, rest); 125 | } 126 | } 127 | node = all; 128 | if (node) { 129 | tail = node.tail; 130 | args = [event].concat(rest); 131 | while ((node = node.next) !== tail) { 132 | node.callback.apply(node.context || this, args); 133 | } 134 | } 135 | event = events.shift(); 136 | } 137 | 138 | return this; 139 | }, 140 | }; 141 | 142 | /** 143 | * @function 144 | */ 145 | AV.Events.bind = AV.Events.on; 146 | 147 | /** 148 | * @function 149 | */ 150 | AV.Events.unbind = AV.Events.off; 151 | }; 152 | -------------------------------------------------------------------------------- /src/friendship.js: -------------------------------------------------------------------------------- 1 | const _ = require('underscore'); 2 | const { request: LCRequest } = require('./request'); 3 | const { getSessionToken } = require('./utils'); 4 | 5 | module.exports = function(AV) { 6 | const getUserWithSessionToken = authOptions => { 7 | if (authOptions.user) { 8 | if (!authOptions.user._sessionToken) { 9 | throw new Error('authOptions.user is not signed in.'); 10 | } 11 | return Promise.resolve(authOptions.user); 12 | } 13 | if (authOptions.sessionToken) { 14 | return AV.User._fetchUserBySessionToken(authOptions.sessionToken); 15 | } 16 | return AV.User.currentAsync(); 17 | }; 18 | 19 | const getSessionTokenAsync = authOptions => { 20 | const sessionToken = getSessionToken(authOptions); 21 | if (sessionToken) { 22 | return Promise.resolve(sessionToken); 23 | } 24 | return AV.User.currentAsync().then(user => { 25 | if (user) { 26 | return user.getSessionToken(); 27 | } 28 | }); 29 | }; 30 | 31 | /** 32 | * Contains functions to deal with Friendship in LeanCloud. 33 | * @class 34 | */ 35 | AV.Friendship = { 36 | /** 37 | * Request friendship. 38 | * @since 4.8.0 39 | * @param {String | AV.User | Object} options if an AV.User or string is given, it will be used as the friend. 40 | * @param {AV.User | string} options.friend The friend (or friend's objectId) to follow. 41 | * @param {Object} [options.attributes] key-value attributes dictionary to be used as conditions of followeeQuery. 42 | * @param {AuthOptions} [authOptions] 43 | * @return {Promise} 44 | */ 45 | request: function(options, authOptions = {}) { 46 | let friend; 47 | let attributes; 48 | 49 | if (options.friend) { 50 | friend = options.friend; 51 | attributes = options.attributes; 52 | } else { 53 | friend = options; 54 | } 55 | 56 | const friendObj = _.isString(friend) 57 | ? AV.Object.createWithoutData('_User', friend) 58 | : friend; 59 | 60 | return getUserWithSessionToken(authOptions).then(userObj => { 61 | if (!userObj) { 62 | throw new Error('Please signin an user.'); 63 | } 64 | return LCRequest({ 65 | method: 'POST', 66 | path: '/users/friendshipRequests', 67 | data: { 68 | user: userObj._toPointer(), 69 | friend: friendObj._toPointer(), 70 | friendship: attributes, 71 | }, 72 | authOptions, 73 | }); 74 | }); 75 | }, 76 | 77 | /** 78 | * Accept a friendship request. 79 | * @since 4.8.0 80 | * @param {AV.Object | string | Object} options if an AV.Object or string is given, it will be used as the request in _FriendshipRequest. 81 | * @param {AV.Object} options.request The request (or it's objectId) to be accepted. 82 | * @param {Object} [options.attributes] key-value attributes dictionary to be used as conditions of {@link AV#followeeQuery}. 83 | * @param {AuthOptions} [authOptions] 84 | * @return {Promise} 85 | */ 86 | acceptRequest: function(options, authOptions = {}) { 87 | let request; 88 | let attributes; 89 | if (options.request) { 90 | request = options.request; 91 | attributes = options.attributes; 92 | } else { 93 | request = options; 94 | } 95 | const requestId = _.isString(request) ? request : request.id; 96 | return getSessionTokenAsync(authOptions).then(sessionToken => { 97 | if (!sessionToken) { 98 | throw new Error('Please signin an user.'); 99 | } 100 | return LCRequest({ 101 | method: 'PUT', 102 | path: '/users/friendshipRequests/' + requestId + '/accept', 103 | data: { 104 | friendship: AV._encode(attributes), 105 | }, 106 | authOptions, 107 | }); 108 | }); 109 | }, 110 | 111 | /** 112 | * Decline a friendship request. 113 | * @param {AV.Object | string} request The request (or it's objectId) to be declined. 114 | * @param {AuthOptions} [authOptions] 115 | * @return {Promise} 116 | */ 117 | declineRequest: function(request, authOptions = {}) { 118 | const requestId = _.isString(request) ? request : request.id; 119 | return getSessionTokenAsync(authOptions).then(sessionToken => { 120 | if (!sessionToken) { 121 | throw new Error('Please signin an user.'); 122 | } 123 | return LCRequest({ 124 | method: 'PUT', 125 | path: '/users/friendshipRequests/' + requestId + '/decline', 126 | authOptions, 127 | }); 128 | }); 129 | }, 130 | }; 131 | }; 132 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * LeanCloud JavaScript SDK 3 | * https://leancloud.cn 4 | * 5 | * Copyright 2016 LeanCloud.cn, Inc. 6 | * The LeanCloud JavaScript SDK is freely distributable under the MIT license. 7 | */ 8 | const _ = require('underscore'); 9 | 10 | const AV = require('./av'); 11 | 12 | AV._ = _; 13 | AV.version = require('./version'); 14 | AV.Promise = Promise; 15 | AV.localStorage = require('./localstorage'); 16 | AV.Cache = require('./cache'); 17 | AV.Error = require('./error'); 18 | 19 | require('./init'); 20 | require('./event')(AV); 21 | require('./geopoint')(AV); 22 | require('./acl')(AV); 23 | require('./op')(AV); 24 | require('./relation')(AV); 25 | require('./file')(AV); 26 | require('./object')(AV); 27 | require('./role')(AV); 28 | require('./user')(AV); 29 | require('./query')(AV); 30 | require('./live-query')(AV); 31 | require('./captcha')(AV); 32 | require('./cloudfunction')(AV); 33 | require('./push')(AV); 34 | require('./status')(AV); 35 | require('./search')(AV); 36 | require('./insight')(AV); 37 | require('./friendship')(AV); 38 | 39 | AV.Conversation = require('./conversation'); 40 | require('./leaderboard'); 41 | module.exports = AV; 42 | 43 | /** 44 | * Options to controll the authentication for an operation 45 | * @typedef {Object} AuthOptions 46 | * @property {String} [sessionToken] Specify a user to excute the operation as. 47 | * @property {AV.User} [user] Specify a user to excute the operation as. The user must have _sessionToken. This option will be ignored if sessionToken option provided. 48 | * @property {Boolean} [useMasterKey] Indicates whether masterKey is used for this operation. Only valid when masterKey is set. 49 | */ 50 | 51 | /** 52 | * Options to controll the authentication for an SMS operation 53 | * @typedef {Object} SMSAuthOptions 54 | * @property {String} [sessionToken] Specify a user to excute the operation as. 55 | * @property {AV.User} [user] Specify a user to excute the operation as. The user must have _sessionToken. This option will be ignored if sessionToken option provided. 56 | * @property {Boolean} [useMasterKey] Indicates whether masterKey is used for this operation. Only valid when masterKey is set. 57 | * @property {String} [validateToken] a validate token returned by {@link AV.Cloud.verifyCaptcha} 58 | */ 59 | -------------------------------------------------------------------------------- /src/insight.js: -------------------------------------------------------------------------------- 1 | const _ = require('underscore'); 2 | const AVError = require('./error'); 3 | const { request } = require('./request'); 4 | 5 | module.exports = function(AV) { 6 | /** 7 | * 包含了使用了 LeanCloud 8 | * 离线数据分析功能的函数。 9 | *

    10 | * 仅在云引擎运行环境下有效。 11 | *

    12 | * @namespace 13 | */ 14 | AV.Insight = AV.Insight || {}; 15 | 16 | _.extend( 17 | AV.Insight, 18 | /** @lends AV.Insight */ { 19 | /** 20 | * 开始一个 Insight 任务。结果里将返回 Job id,你可以拿得到的 id 使用 21 | * AV.Insight.JobQuery 查询任务状态和结果。 22 | * @param {Object} jobConfig 任务配置的 JSON 对象,例如:
     23 |        *                   { "sql" : "select count(*) as c,gender from _User group by gender",
     24 |        *                     "saveAs": {
     25 |        *                         "className" : "UserGender",
     26 |        *                         "limit": 1
     27 |        *                      }
     28 |        *                   }
     29 |        *                  
    30 | * sql 指定任务执行的 SQL 语句, saveAs(可选) 指定将结果保存在哪张表里,limit 最大 1000。 31 | * @param {AuthOptions} [options] 32 | * @return {Promise} A promise that will be resolved with the result 33 | * of the function. 34 | */ 35 | startJob: function(jobConfig, options) { 36 | if (!jobConfig || !jobConfig.sql) { 37 | throw new Error('Please provide the sql to run the job.'); 38 | } 39 | var data = { 40 | jobConfig: jobConfig, 41 | appId: AV.applicationId, 42 | }; 43 | return request({ 44 | path: '/bigquery/jobs', 45 | method: 'POST', 46 | data: AV._encode(data, null, true), 47 | authOptions: options, 48 | signKey: false, 49 | }).then(resp => AV._decode(resp).id); 50 | }, 51 | 52 | /** 53 | * 监听 Insight 任务事件(未来推出独立部署的离线分析服务后开放) 54 | *

    55 | * 仅在云引擎运行环境下有效。 56 | *

    57 | * @param {String} event 监听的事件,目前尚不支持。 58 | * @param {Function} 监听回调函数,接收 (err, id) 两个参数,err 表示错误信息, 59 | * id 表示任务 id。接下来你可以拿这个 id 使用AV.Insight.JobQuery 查询任务状态和结果。 60 | * 61 | */ 62 | on: function(event, cb) {}, 63 | } 64 | ); 65 | 66 | /** 67 | * 创建一个对象,用于查询 Insight 任务状态和结果。 68 | * @class 69 | * @param {String} id 任务 id 70 | * @since 0.5.5 71 | */ 72 | AV.Insight.JobQuery = function(id, className) { 73 | if (!id) { 74 | throw new Error('Please provide the job id.'); 75 | } 76 | this.id = id; 77 | this.className = className; 78 | this._skip = 0; 79 | this._limit = 100; 80 | }; 81 | 82 | _.extend( 83 | AV.Insight.JobQuery.prototype, 84 | /** @lends AV.Insight.JobQuery.prototype */ { 85 | /** 86 | * Sets the number of results to skip before returning any results. 87 | * This is useful for pagination. 88 | * Default is to skip zero results. 89 | * @param {Number} n the number of results to skip. 90 | * @return {AV.Query} Returns the query, so you can chain this call. 91 | */ 92 | skip: function(n) { 93 | this._skip = n; 94 | return this; 95 | }, 96 | 97 | /** 98 | * Sets the limit of the number of results to return. The default limit is 99 | * 100, with a maximum of 1000 results being returned at a time. 100 | * @param {Number} n the number of results to limit to. 101 | * @return {AV.Query} Returns the query, so you can chain this call. 102 | */ 103 | limit: function(n) { 104 | this._limit = n; 105 | return this; 106 | }, 107 | 108 | /** 109 | * 查询任务状态和结果,任务结果为一个 JSON 对象,包括 status 表示任务状态, totalCount 表示总数, 110 | * results 数组表示任务结果数组,previewCount 表示可以返回的结果总数,任务的开始和截止时间 111 | * startTime、endTime 等信息。 112 | * 113 | * @param {AuthOptions} [options] 114 | * @return {Promise} A promise that will be resolved with the result 115 | * of the function. 116 | * 117 | */ 118 | find: function(options) { 119 | var params = { 120 | skip: this._skip, 121 | limit: this._limit, 122 | }; 123 | 124 | return request({ 125 | path: `/bigquery/jobs/${this.id}`, 126 | method: 'GET', 127 | query: params, 128 | authOptions: options, 129 | signKey: false, 130 | }).then(function(response) { 131 | if (response.error) { 132 | return Promise.reject(new AVError(response.code, response.error)); 133 | } 134 | return Promise.resolve(response); 135 | }); 136 | }, 137 | } 138 | ); 139 | }; 140 | -------------------------------------------------------------------------------- /src/localstorage.js: -------------------------------------------------------------------------------- 1 | var { getAdapter } = require('./adapter'); 2 | 3 | var syncApiNames = ['getItem', 'setItem', 'removeItem', 'clear']; 4 | 5 | const localStorage = { 6 | get async() { 7 | return getAdapter('storage').async; 8 | }, 9 | }; 10 | 11 | // wrap sync apis with async ones. 12 | syncApiNames.forEach(function(apiName) { 13 | localStorage[apiName + 'Async'] = function() { 14 | const storage = getAdapter('storage'); 15 | return Promise.resolve(storage[apiName].apply(storage, arguments)); 16 | }; 17 | 18 | localStorage[apiName] = function() { 19 | const storage = getAdapter('storage'); 20 | if (!storage.async) { 21 | return storage[apiName].apply(storage, arguments); 22 | } 23 | const error = new Error( 24 | 'Synchronous API [' + apiName + '] is not available in this runtime.' 25 | ); 26 | error.code = 'SYNC_API_NOT_AVAILABLE'; 27 | throw error; 28 | }; 29 | }); 30 | 31 | module.exports = localStorage; 32 | -------------------------------------------------------------------------------- /src/push.js: -------------------------------------------------------------------------------- 1 | const request = require('./request').request; 2 | 3 | module.exports = function(AV) { 4 | AV.Installation = AV.Object.extend('_Installation'); 5 | 6 | /** 7 | * @namespace 8 | */ 9 | AV.Push = AV.Push || {}; 10 | 11 | /** 12 | * Sends a push notification. 13 | * @param {Object} data The data of the push notification. 14 | * @param {String[]} [data.channels] An Array of channels to push to. 15 | * @param {Date} [data.push_time] A Date object for when to send the push. 16 | * @param {Date} [data.expiration_time] A Date object for when to expire 17 | * the push. 18 | * @param {Number} [data.expiration_interval] The seconds from now to expire the push. 19 | * @param {Number} [data.flow_control] The clients to notify per second 20 | * @param {AV.Query} [data.where] An AV.Query over AV.Installation that is used to match 21 | * a set of installations to push to. 22 | * @param {String} [data.cql] A CQL statement over AV.Installation that is used to match 23 | * a set of installations to push to. 24 | * @param {Object} data.data The data to send as part of the push. 25 | More details: https://url.leanapp.cn/pushData 26 | * @param {AuthOptions} [options] 27 | * @return {Promise} 28 | */ 29 | AV.Push.send = function(data, options) { 30 | if (data.where) { 31 | data.where = data.where._getParams().where; 32 | } 33 | 34 | if (data.where && data.cql) { 35 | throw new Error("Both where and cql can't be set"); 36 | } 37 | 38 | if (data.push_time) { 39 | data.push_time = data.push_time.toJSON(); 40 | } 41 | 42 | if (data.expiration_time) { 43 | data.expiration_time = data.expiration_time.toJSON(); 44 | } 45 | 46 | if (data.expiration_time && data.expiration_interval) { 47 | throw new Error( 48 | "Both expiration_time and expiration_interval can't be set" 49 | ); 50 | } 51 | 52 | return request({ 53 | service: 'push', 54 | method: 'POST', 55 | path: '/push', 56 | data, 57 | authOptions: options, 58 | }); 59 | }; 60 | }; 61 | -------------------------------------------------------------------------------- /src/relation.js: -------------------------------------------------------------------------------- 1 | var _ = require('underscore'); 2 | 3 | module.exports = function(AV) { 4 | /** 5 | * Creates a new Relation for the given parent object and key. This 6 | * constructor should rarely be used directly, but rather created by 7 | * {@link AV.Object#relation}. 8 | * @param {AV.Object} parent The parent of this relation. 9 | * @param {String} key The key for this relation on the parent. 10 | * @see AV.Object#relation 11 | * @class 12 | * 13 | *

    14 | * A class that is used to access all of the children of a many-to-many 15 | * relationship. Each instance of AV.Relation is associated with a 16 | * particular parent object and key. 17 | *

    18 | */ 19 | AV.Relation = function(parent, key) { 20 | if (!_.isString(key)) { 21 | throw new TypeError('key must be a string'); 22 | } 23 | this.parent = parent; 24 | this.key = key; 25 | this.targetClassName = null; 26 | }; 27 | 28 | /** 29 | * Creates a query that can be used to query the parent objects in this relation. 30 | * @param {String} parentClass The parent class or name. 31 | * @param {String} relationKey The relation field key in parent. 32 | * @param {AV.Object} child The child object. 33 | * @return {AV.Query} 34 | */ 35 | AV.Relation.reverseQuery = function(parentClass, relationKey, child) { 36 | var query = new AV.Query(parentClass); 37 | query.equalTo(relationKey, child._toPointer()); 38 | return query; 39 | }; 40 | 41 | _.extend( 42 | AV.Relation.prototype, 43 | /** @lends AV.Relation.prototype */ { 44 | /** 45 | * Makes sure that this relation has the right parent and key. 46 | * @private 47 | */ 48 | _ensureParentAndKey: function(parent, key) { 49 | this.parent = this.parent || parent; 50 | this.key = this.key || key; 51 | if (this.parent !== parent) { 52 | throw new Error( 53 | 'Internal Error. Relation retrieved from two different Objects.' 54 | ); 55 | } 56 | if (this.key !== key) { 57 | throw new Error( 58 | 'Internal Error. Relation retrieved from two different keys.' 59 | ); 60 | } 61 | }, 62 | 63 | /** 64 | * Adds a AV.Object or an array of AV.Objects to the relation. 65 | * @param {AV.Object|AV.Object[]} objects The item or items to add. 66 | */ 67 | add: function(objects) { 68 | if (!_.isArray(objects)) { 69 | objects = [objects]; 70 | } 71 | 72 | var change = new AV.Op.Relation(objects, []); 73 | this.parent.set(this.key, change); 74 | this.targetClassName = change._targetClassName; 75 | }, 76 | 77 | /** 78 | * Removes a AV.Object or an array of AV.Objects from this relation. 79 | * @param {AV.Object|AV.Object[]} objects The item or items to remove. 80 | */ 81 | remove: function(objects) { 82 | if (!_.isArray(objects)) { 83 | objects = [objects]; 84 | } 85 | 86 | var change = new AV.Op.Relation([], objects); 87 | this.parent.set(this.key, change); 88 | this.targetClassName = change._targetClassName; 89 | }, 90 | 91 | /** 92 | * Returns a JSON version of the object suitable for saving to disk. 93 | * @return {Object} 94 | */ 95 | toJSON: function() { 96 | return { __type: 'Relation', className: this.targetClassName }; 97 | }, 98 | 99 | /** 100 | * Returns a AV.Query that is limited to objects in this 101 | * relation. 102 | * @return {AV.Query} 103 | */ 104 | query: function() { 105 | var targetClass; 106 | var query; 107 | if (!this.targetClassName) { 108 | targetClass = AV.Object._getSubclass(this.parent.className); 109 | query = new AV.Query(targetClass); 110 | query._defaultParams.redirectClassNameForKey = this.key; 111 | } else { 112 | targetClass = AV.Object._getSubclass(this.targetClassName); 113 | query = new AV.Query(targetClass); 114 | } 115 | query._addCondition('$relatedTo', 'object', this.parent._toPointer()); 116 | query._addCondition('$relatedTo', 'key', this.key); 117 | 118 | return query; 119 | }, 120 | } 121 | ); 122 | }; 123 | -------------------------------------------------------------------------------- /src/role.js: -------------------------------------------------------------------------------- 1 | const _ = require('underscore'); 2 | const AVError = require('./error'); 3 | 4 | module.exports = function(AV) { 5 | AV.Role = AV.Object.extend( 6 | '_Role', 7 | /** @lends AV.Role.prototype */ { 8 | // Instance Methods 9 | 10 | /** 11 | * Represents a Role on the AV server. Roles represent groupings of 12 | * Users for the purposes of granting permissions (e.g. specifying an ACL 13 | * for an Object). Roles are specified by their sets of child users and 14 | * child roles, all of which are granted any permissions that the parent 15 | * role has. 16 | * 17 | *

    Roles must have a name (which cannot be changed after creation of the 18 | * role), and must specify an ACL.

    19 | * An AV.Role is a local representation of a role persisted to the AV 20 | * cloud. 21 | * @class AV.Role 22 | * @param {String} name The name of the Role to create. 23 | * @param {AV.ACL} acl The ACL for this role. 24 | */ 25 | constructor: function(name, acl) { 26 | if (_.isString(name)) { 27 | AV.Object.prototype.constructor.call(this, null, null); 28 | this.setName(name); 29 | } else { 30 | AV.Object.prototype.constructor.call(this, name, acl); 31 | } 32 | if (acl) { 33 | if (!(acl instanceof AV.ACL)) { 34 | throw new TypeError('acl must be an instance of AV.ACL'); 35 | } else { 36 | this.setACL(acl); 37 | } 38 | } 39 | }, 40 | 41 | /** 42 | * Gets the name of the role. You can alternatively call role.get("name") 43 | * 44 | * @return {String} the name of the role. 45 | */ 46 | getName: function() { 47 | return this.get('name'); 48 | }, 49 | 50 | /** 51 | * Sets the name for a role. This value must be set before the role has 52 | * been saved to the server, and cannot be set once the role has been 53 | * saved. 54 | * 55 | *

    56 | * A role's name can only contain alphanumeric characters, _, -, and 57 | * spaces. 58 | *

    59 | * 60 | *

    This is equivalent to calling role.set("name", name)

    61 | * 62 | * @param {String} name The name of the role. 63 | */ 64 | setName: function(name, options) { 65 | return this.set('name', name, options); 66 | }, 67 | 68 | /** 69 | * Gets the AV.Relation for the AV.Users that are direct 70 | * children of this role. These users are granted any privileges that this 71 | * role has been granted (e.g. read or write access through ACLs). You can 72 | * add or remove users from the role through this relation. 73 | * 74 | *

    This is equivalent to calling role.relation("users")

    75 | * 76 | * @return {AV.Relation} the relation for the users belonging to this 77 | * role. 78 | */ 79 | getUsers: function() { 80 | return this.relation('users'); 81 | }, 82 | 83 | /** 84 | * Gets the AV.Relation for the AV.Roles that are direct 85 | * children of this role. These roles' users are granted any privileges that 86 | * this role has been granted (e.g. read or write access through ACLs). You 87 | * can add or remove child roles from this role through this relation. 88 | * 89 | *

    This is equivalent to calling role.relation("roles")

    90 | * 91 | * @return {AV.Relation} the relation for the roles belonging to this 92 | * role. 93 | */ 94 | getRoles: function() { 95 | return this.relation('roles'); 96 | }, 97 | 98 | /** 99 | * @ignore 100 | */ 101 | validate: function(attrs, options) { 102 | if ('name' in attrs && attrs.name !== this.getName()) { 103 | var newName = attrs.name; 104 | if (this.id && this.id !== attrs.objectId) { 105 | // Check to see if the objectId being set matches this.id. 106 | // This happens during a fetch -- the id is set before calling fetch. 107 | // Let the name be set in this case. 108 | return new AVError( 109 | AVError.OTHER_CAUSE, 110 | "A role's name can only be set before it has been saved." 111 | ); 112 | } 113 | if (!_.isString(newName)) { 114 | return new AVError( 115 | AVError.OTHER_CAUSE, 116 | "A role's name must be a String." 117 | ); 118 | } 119 | if (!/^[0-9a-zA-Z\-_ ]+$/.test(newName)) { 120 | return new AVError( 121 | AVError.OTHER_CAUSE, 122 | "A role's name can only contain alphanumeric characters, _," + 123 | ' -, and spaces.' 124 | ); 125 | } 126 | } 127 | if (AV.Object.prototype.validate) { 128 | return AV.Object.prototype.validate.call(this, attrs, options); 129 | } 130 | return false; 131 | }, 132 | } 133 | ); 134 | }; 135 | -------------------------------------------------------------------------------- /src/uploader/cos.js: -------------------------------------------------------------------------------- 1 | const { getAdapter } = require('../adapter'); 2 | const debug = require('debug')('cos'); 3 | 4 | module.exports = function(uploadInfo, data, file, saveOptions = {}) { 5 | const url = 6 | uploadInfo.upload_url + '?sign=' + encodeURIComponent(uploadInfo.token); 7 | const fileFormData = { 8 | field: 'fileContent', 9 | data, 10 | name: file.attributes.name, 11 | }; 12 | const options = { 13 | headers: file._uploadHeaders, 14 | data: { 15 | op: 'upload', 16 | }, 17 | onprogress: saveOptions.onprogress, 18 | }; 19 | debug('url: %s, file: %o, options: %o', url, fileFormData, options); 20 | const upload = getAdapter('upload'); 21 | return upload(url, fileFormData, options).then( 22 | response => { 23 | debug(response.status, response.data); 24 | if (response.ok === false) { 25 | const error = new Error(response.status); 26 | error.response = response; 27 | throw error; 28 | } 29 | file.attributes.url = uploadInfo.url; 30 | file._bucket = uploadInfo.bucket; 31 | file.id = uploadInfo.objectId; 32 | return file; 33 | }, 34 | error => { 35 | const { response } = error; 36 | if (response) { 37 | debug(response.status, response.data); 38 | error.statusCode = response.status; 39 | error.response = response.data; 40 | } 41 | throw error; 42 | } 43 | ); 44 | }; 45 | -------------------------------------------------------------------------------- /src/uploader/s3.js: -------------------------------------------------------------------------------- 1 | const _ = require('underscore'); 2 | const ajax = require('../utils/ajax'); 3 | 4 | module.exports = function upload(uploadInfo, data, file, saveOptions = {}) { 5 | /* NODE-ONLY:start */ 6 | if (data instanceof require('stream')) { 7 | const size = file.metaData('size'); 8 | if (typeof size !== 'number') { 9 | throw new Error( 10 | 'Saving an AV.File from a Stream to S3 need metaData.size to be set' 11 | ); 12 | } 13 | file.setUploadHeader('Content-Length', size.toString()); 14 | } 15 | /* NODE-ONLY:end */ 16 | 17 | return ajax({ 18 | url: uploadInfo.upload_url, 19 | method: 'PUT', 20 | data, 21 | headers: _.extend( 22 | { 23 | 'Content-Type': file.get('mime_type'), 24 | 'Cache-Control': 'public, max-age=31536000', 25 | }, 26 | file._uploadHeaders 27 | ), 28 | onprogress: saveOptions.onprogress, 29 | }).then(() => { 30 | file.attributes.url = uploadInfo.url; 31 | file._bucket = uploadInfo.bucket; 32 | file.id = uploadInfo.objectId; 33 | return file; 34 | }); 35 | }; 36 | -------------------------------------------------------------------------------- /src/utils/ajax.js: -------------------------------------------------------------------------------- 1 | const _ = require('underscore'); 2 | const { timeout } = require('promise-timeout'); 3 | const debug = require('debug'); 4 | const debugRequest = debug('leancloud:request'); 5 | const debugRequestError = debug('leancloud:request:error'); 6 | const { getAdapter } = require('../adapter'); 7 | 8 | let requestsCount = 0; 9 | 10 | const ajax = ({ 11 | method, 12 | url, 13 | query, 14 | data, 15 | headers = {}, 16 | timeout: time, 17 | onprogress, 18 | }) => { 19 | if (query) { 20 | const queryString = Object.keys(query) 21 | .map(key => { 22 | const value = query[key]; 23 | if (value === undefined) return undefined; 24 | const v = typeof value === 'object' ? JSON.stringify(value) : value; 25 | return `${encodeURIComponent(key)}=${encodeURIComponent(v)}`; 26 | }) 27 | .filter(qs => qs) 28 | .join('&'); 29 | url = `${url}?${queryString}`; 30 | } 31 | 32 | const count = requestsCount++; 33 | debugRequest( 34 | 'request(%d) %s %s %o %o %o', 35 | count, 36 | method, 37 | url, 38 | query, 39 | data, 40 | headers 41 | ); 42 | 43 | const request = getAdapter('request'); 44 | const promise = request(url, { method, headers, data, onprogress }) 45 | .then(response => { 46 | debugRequest( 47 | 'response(%d) %d %O %o', 48 | count, 49 | response.status, 50 | response.data || response.text, 51 | response.header 52 | ); 53 | if (response.ok === false) { 54 | const error = new Error(); 55 | error.response = response; 56 | throw error; 57 | } 58 | return response.data; 59 | }) 60 | .catch(error => { 61 | if (error.response) { 62 | if (!debug.enabled('leancloud:request')) { 63 | debugRequestError( 64 | 'request(%d) %s %s %o %o %o', 65 | count, 66 | method, 67 | url, 68 | query, 69 | data, 70 | headers 71 | ); 72 | } 73 | debugRequestError( 74 | 'response(%d) %d %O %o', 75 | count, 76 | error.response.status, 77 | error.response.data || error.response.text, 78 | error.response.header 79 | ); 80 | error.statusCode = error.response.status; 81 | error.responseText = error.response.text; 82 | error.response = error.response.data; 83 | } 84 | throw error; 85 | }); 86 | return time ? timeout(promise, time) : promise; 87 | }; 88 | 89 | module.exports = ajax; 90 | -------------------------------------------------------------------------------- /src/utils/btoa.js: -------------------------------------------------------------------------------- 1 | // base64 character set, plus padding character (=) 2 | const b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; 3 | 4 | module.exports = string => { 5 | let result = ''; 6 | 7 | for (let i = 0; i < string.length; ) { 8 | const a = string.charCodeAt(i++); 9 | const b = string.charCodeAt(i++); 10 | const c = string.charCodeAt(i++); 11 | if (a > 255 || b > 255 || c > 255) { 12 | throw new TypeError( 13 | 'Failed to encode base64: The string to be encoded contains characters outside of the Latin1 range.' 14 | ); 15 | } 16 | 17 | const bitmap = (a << 16) | (b << 8) | c; 18 | result += 19 | b64.charAt((bitmap >> 18) & 63) + 20 | b64.charAt((bitmap >> 12) & 63) + 21 | b64.charAt((bitmap >> 6) & 63) + 22 | b64.charAt(bitmap & 63); 23 | } 24 | 25 | // To determine the final padding 26 | const rest = string.length % 3; 27 | // If there's need of padding, replace the last 'A's with equal signs 28 | return rest ? result.slice(0, rest - 3) + '==='.substring(rest) : result; 29 | }; 30 | -------------------------------------------------------------------------------- /src/utils/index.js: -------------------------------------------------------------------------------- 1 | const _ = require('underscore'); 2 | 3 | // Helper function to check null or undefined. 4 | const isNullOrUndefined = x => _.isNull(x) || _.isUndefined(x); 5 | 6 | const ensureArray = target => { 7 | if (_.isArray(target)) { 8 | return target; 9 | } 10 | if (target === undefined || target === null) { 11 | return []; 12 | } 13 | return [target]; 14 | }; 15 | 16 | const transformFetchOptions = ({ keys, include, includeACL } = {}) => { 17 | const fetchOptions = {}; 18 | if (keys) { 19 | fetchOptions.keys = ensureArray(keys).join(','); 20 | } 21 | if (include) { 22 | fetchOptions.include = ensureArray(include).join(','); 23 | } 24 | if (includeACL) { 25 | fetchOptions.returnACL = includeACL; 26 | } 27 | return fetchOptions; 28 | }; 29 | 30 | const getSessionToken = authOptions => { 31 | if (authOptions.sessionToken) { 32 | return authOptions.sessionToken; 33 | } 34 | if ( 35 | authOptions.user && 36 | typeof authOptions.user.getSessionToken === 'function' 37 | ) { 38 | return authOptions.user.getSessionToken(); 39 | } 40 | }; 41 | 42 | const tap = interceptor => value => (interceptor(value), value); 43 | 44 | // Shared empty constructor function to aid in prototype-chain creation. 45 | const EmptyConstructor = function() {}; 46 | 47 | // Helper function to correctly set up the prototype chain, for subclasses. 48 | // Similar to `goog.inherits`, but uses a hash of prototype properties and 49 | // class properties to be extended. 50 | const inherits = function inherits(parent, protoProps, staticProps) { 51 | var child; 52 | 53 | // The constructor function for the new subclass is either defined by you 54 | // (the "constructor" property in your `extend` definition), or defaulted 55 | // by us to simply call the parent's constructor. 56 | if (protoProps && protoProps.hasOwnProperty('constructor')) { 57 | child = protoProps.constructor; 58 | } else { 59 | /** @ignore */ 60 | child = function() { 61 | parent.apply(this, arguments); 62 | }; 63 | } 64 | 65 | // Inherit class (static) properties from parent. 66 | _.extend(child, parent); 67 | 68 | // Set the prototype chain to inherit from `parent`, without calling 69 | // `parent`'s constructor function. 70 | EmptyConstructor.prototype = parent.prototype; 71 | child.prototype = new EmptyConstructor(); 72 | 73 | // Add prototype properties (instance properties) to the subclass, 74 | // if supplied. 75 | if (protoProps) { 76 | _.extend(child.prototype, protoProps); 77 | } 78 | 79 | // Add static properties to the constructor function, if supplied. 80 | if (staticProps) { 81 | _.extend(child, staticProps); 82 | } 83 | 84 | // Correctly set child's `prototype.constructor`. 85 | child.prototype.constructor = child; 86 | 87 | // Set a convenience property in case the parent's prototype is 88 | // needed later. 89 | child.__super__ = parent.prototype; 90 | 91 | return child; 92 | }; 93 | 94 | // Suppress the date string format warning in Weixin DevTools 95 | // Link: https://developers.weixin.qq.com/community/minihome/doc/00080c6f244718053550067736b401 96 | const parseDate = 97 | typeof wx === 'undefined' 98 | ? iso8601 => new Date(iso8601) 99 | : iso8601 => new Date(Date.parse(iso8601)); 100 | 101 | const setValue = (target, key, value) => { 102 | // '.' is not allowed in Class keys, escaping is not in concern now. 103 | const segs = key.split('.'); 104 | const lastSeg = segs.pop(); 105 | let currentTarget = target; 106 | segs.forEach(seg => { 107 | if (currentTarget[seg] === undefined) currentTarget[seg] = {}; 108 | currentTarget = currentTarget[seg]; 109 | }); 110 | currentTarget[lastSeg] = value; 111 | return target; 112 | }; 113 | 114 | const findValue = (target, key) => { 115 | const segs = key.split('.'); 116 | const firstSeg = segs[0]; 117 | const lastSeg = segs.pop(); 118 | let currentTarget = target; 119 | for (let i = 0; i < segs.length; i++) { 120 | currentTarget = currentTarget[segs[i]]; 121 | if (currentTarget === undefined) { 122 | return [undefined, undefined, lastSeg]; 123 | } 124 | } 125 | const value = currentTarget[lastSeg]; 126 | return [value, currentTarget, lastSeg, firstSeg]; 127 | }; 128 | 129 | const isPlainObject = obj => 130 | _.isObject(obj) && Object.getPrototypeOf(obj) === Object.prototype; 131 | 132 | const continueWhile = function(predicate, asyncFunction) { 133 | if (predicate()) { 134 | return asyncFunction().then(function() { 135 | return continueWhile(predicate, asyncFunction); 136 | }); 137 | } 138 | return Promise.resolve(); 139 | }; 140 | 141 | module.exports = { 142 | isNullOrUndefined, 143 | ensureArray, 144 | transformFetchOptions, 145 | getSessionToken, 146 | tap, 147 | inherits, 148 | parseDate, 149 | setValue, 150 | findValue, 151 | isPlainObject, 152 | continueWhile, 153 | }; 154 | -------------------------------------------------------------------------------- /src/utils/parse-base64-browser.js: -------------------------------------------------------------------------------- 1 | var dataURItoBlob = function(dataURI, type) { 2 | var byteString; 3 | 4 | // 传入的 base64,不是 dataURL 5 | if (dataURI.indexOf('base64') < 0) { 6 | byteString = atob(dataURI); 7 | } else if (dataURI.split(',')[0].indexOf('base64') >= 0) { 8 | type = 9 | type || 10 | dataURI 11 | .split(',')[0] 12 | .split(':')[1] 13 | .split(';')[0]; 14 | byteString = atob(dataURI.split(',')[1]); 15 | } else { 16 | byteString = unescape(dataURI.split(',')[1]); 17 | } 18 | var ia = new Uint8Array(byteString.length); 19 | for (var i = 0; i < byteString.length; i++) { 20 | ia[i] = byteString.charCodeAt(i); 21 | } 22 | return new Blob([ia], { type }); 23 | }; 24 | 25 | module.exports = dataURItoBlob; 26 | -------------------------------------------------------------------------------- /src/utils/parse-base64.js: -------------------------------------------------------------------------------- 1 | var dataURLToBlob = function(base64) { 2 | // 兼容 dataURL 3 | if (base64.split(',')[0] && base64.split(',')[0].indexOf('base64') >= 0) { 4 | base64 = base64.split(',')[1]; 5 | } 6 | return Buffer.from(base64, 'base64'); 7 | }; 8 | 9 | module.exports = dataURLToBlob; 10 | -------------------------------------------------------------------------------- /src/version.js: -------------------------------------------------------------------------------- 1 | module.exports = '4.15.3'; 2 | -------------------------------------------------------------------------------- /test/acl.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import { setupPolly } from './polly'; 4 | 5 | var GameScore = AV.Object.extend('GameScore'); 6 | describe('ObjectACL', function() { 7 | setupPolly(); 8 | 9 | it('set and fetch acl', function() { 10 | var gameScore = new GameScore(); 11 | gameScore.set('score', 2); 12 | gameScore.set('playerName', 'sdf'); 13 | gameScore.set('cheatMode', false); 14 | 15 | var postACL = new AV.ACL(); 16 | postACL.setPublicReadAccess(true); 17 | postACL.setPublicWriteAccess(true); 18 | 19 | postACL.setReadAccess('read-only', true); 20 | postACL.setWriteAccess('write-only', true); 21 | postACL.setRoleWriteAccess('write-only-role', true); 22 | gameScore.setACL(postACL); 23 | return gameScore 24 | .save() 25 | .then(result => { 26 | result.id.should.be.ok(); 27 | return AV.Object.createWithoutData('GameScore', result.id).fetch({ 28 | includeACL: true, 29 | }); 30 | }) 31 | .then(fetchedGameScore => { 32 | const acl = fetchedGameScore.getACL(); 33 | acl.should.be.instanceOf(AV.ACL); 34 | acl.getPublicReadAccess().should.eql(true); 35 | acl.getPublicWriteAccess().should.eql(true); 36 | acl.getReadAccess('read-only').should.eql(true); 37 | acl.getWriteAccess('read-only').should.eql(false); 38 | acl.getReadAccess('write-only').should.eql(false); 39 | acl.getWriteAccess('write-only').should.eql(true); 40 | acl.getRoleReadAccess('write-only-role').should.eql(false); 41 | acl.getRoleWriteAccess('write-only-role').should.eql(true); 42 | }) 43 | .then( 44 | () => gameScore.destroy(), 45 | error => { 46 | gameScore.destroy(); 47 | throw error; 48 | } 49 | ); 50 | }); 51 | }); 52 | -------------------------------------------------------------------------------- /test/av.js: -------------------------------------------------------------------------------- 1 | describe('AV.init', () => { 2 | before(function() { 3 | this.originalAppId = AV.applicationId; 4 | AV.applicationId = undefined; 5 | }); 6 | 7 | after(function() { 8 | AV.applicationId = this.originalAppId; 9 | }); 10 | 11 | it('param check', () => { 12 | (() => AV.init()).should.throw(/must be a string/); 13 | (() => AV.init('aaa')).should.throw(/must be a string/); 14 | (() => AV.init('', '')).should.throw(/must be a string/); 15 | }); 16 | }); 17 | 18 | describe('AV utils', () => { 19 | describe('_encode', () => { 20 | it('should be pure', () => { 21 | const date = new Date(); 22 | const object = { date }; 23 | const array = [date]; 24 | AV._encode(object); 25 | AV._encode(array); 26 | object.date.should.be.a.Date(); 27 | object.date.should.be.exactly(date); 28 | array[0].should.be.a.Date(); 29 | array[0].should.be.exactly(date); 30 | }); 31 | }); 32 | 33 | describe('_decode', () => { 34 | it('should be pure', () => { 35 | const value = '1970-01-01 08:00:00.000 +0800'; 36 | const object = { date: value }; 37 | const array = [value]; 38 | AV._decode(object); 39 | AV._decode(array); 40 | object.date.should.be.a.String(); 41 | object.date.should.be.exactly(value); 42 | array[0].should.be.a.String(); 43 | array[0].should.be.exactly(value); 44 | }); 45 | 46 | it('should bypass with non-plain object', () => { 47 | const now = new Date(); 48 | AV._decode(now).should.be.exactly(now); 49 | AV._decode(3.14).should.be.exactly(3.14); 50 | AV._decode(false).should.be.exactly(false); 51 | AV._decode('false').should.be.exactly('false'); 52 | }); 53 | 54 | it('should decode ACL', () => { 55 | AV._decode(new AV.ACL(), 'ACL').should.be.instanceof(AV.ACL); 56 | AV._decode( 57 | { '*': { read: true, write: true } }, 58 | 'ACL' 59 | ).should.be.instanceof(AV.ACL); 60 | AV._decode({ '*': { read: true, write: true } }).should.not.be.instanceof( 61 | AV.ACL 62 | ); 63 | }); 64 | 65 | it('should decode File', () => { 66 | const fileId = '1111111'; 67 | const json = { 68 | mime_type: 'image/png', 69 | updatedAt: '2016-12-30T06:55:43.561Z', 70 | key: 'd7aaab5c477b289980fc.png', 71 | name: 'lc.png', 72 | objectId: fileId, 73 | createdAt: '2016-12-30T06:55:43.561Z', 74 | __type: 'File', 75 | url: '', 76 | bucket: 'rYAutyUJ', 77 | }; 78 | const file = AV._decode(json); 79 | expect(file).to.be.a(AV.File); 80 | expect(file.id).to.be(fileId); 81 | expect(file.name()).to.be('lc.png'); 82 | expect(file.get('mime_type')).to.be('image/png'); 83 | expect(typeof file.url()).to.be('string'); 84 | expect(file.createdAt).to.be.a(Date); 85 | }); 86 | }); 87 | }); 88 | -------------------------------------------------------------------------------- /test/cache.js: -------------------------------------------------------------------------------- 1 | var Cache = AV.Cache; 2 | var wait = function wait(time) { 3 | return new Promise(function(resolve) { 4 | return setTimeout(resolve, time); 5 | }); 6 | }; 7 | 8 | describe('Cache async', function() { 9 | var getValue = function getValue() { 10 | return Cache.getAsync('__test'); 11 | }; 12 | it('get/set async', function() { 13 | return Cache.setAsync('__test', 1) 14 | .then(getValue) 15 | .then(function(value) { 16 | expect(value).to.be(1); 17 | return Cache.setAsync('__test', '1', 10).then(getValue); 18 | }) 19 | .then(function(value) { 20 | expect(value).to.be('1'); 21 | return wait(11).then(getValue); 22 | }) 23 | .then(function(value) { 24 | expect(value).to.be(null); 25 | }); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /test/captcha.js: -------------------------------------------------------------------------------- 1 | describe('Captcha', () => { 2 | before(function() { 3 | return AV.Captcha.request().then(captcha => { 4 | this.captcha = captcha; 5 | }); 6 | }); 7 | it('.request', function() { 8 | this.captcha.should.be.instanceof(AV.Captcha); 9 | this.captcha.url.should.be.a.String(); 10 | this.captcha.captchaToken.should.be.a.String(); 11 | }); 12 | it('.refresh', function() { 13 | const currentUrl = this.captcha.url; 14 | return this.captcha.refresh().then(() => { 15 | this.captcha.url.should.not.equalTo(currentUrl); 16 | }); 17 | }); 18 | it('.refresh', function() { 19 | return this.captcha.verify('fakecode').should.be.rejected(); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /test/conversation.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import { setupPolly } from './polly'; 4 | 5 | describe('Conversation', () => { 6 | setupPolly(); 7 | 8 | describe('.constructor', () => { 9 | const conv = new AV.Conversation('test', { 10 | isSystem: true, 11 | isTransient: false, 12 | }); 13 | expect(conv.isTransient()).to.be(false); 14 | expect(conv.isSystem()).to.be(true); 15 | expect(conv.getName()).to.be('test'); 16 | }); 17 | describe('#save', () => { 18 | it('should create a realtime conversation', () => { 19 | const conv = new AV.Conversation('test'); 20 | conv.addMember('test1'); 21 | conv.addMember('test2'); 22 | return conv.save(); 23 | }); 24 | }); 25 | describe('#send', () => { 26 | it('should send a realtime message to the conversation', () => { 27 | const conv = new AV.Conversation('test'); 28 | conv.addMember('test1'); 29 | conv.addMember('test2'); 30 | return conv.save().then(() => { 31 | return conv.send( 32 | 'admin', 33 | 'test test test!', 34 | {}, 35 | { useMasterKey: true } 36 | ); 37 | }); 38 | }); 39 | 40 | it('should send a realtime message to the system conversation', () => { 41 | const conv = new AV.Conversation('system', { isSystem: true }); 42 | return conv.save().then(() => { 43 | return conv.send( 44 | 'admin', 45 | 'test system conversation !', 46 | { 47 | toClients: ['user1', 'user2'], 48 | }, 49 | { 50 | useMasterKey: true, 51 | } 52 | ); 53 | }); 54 | }); 55 | }); 56 | describe('#broadcast', () => { 57 | it('should broadcast a message to all clients with current conversation', () => { 58 | const conv = new AV.Conversation('test', { isSystem: true }); 59 | return conv.save().then(() => { 60 | const authOptions = { 61 | useMasterKey: true, 62 | }; 63 | return conv.broadcast('admin', 'test broadcast!', {}, authOptions); 64 | }); 65 | }); 66 | }); 67 | }); 68 | -------------------------------------------------------------------------------- /test/error.js: -------------------------------------------------------------------------------- 1 | describe('AVError', () => { 2 | it('should be an Error', () => { 3 | try { 4 | throw AV.Error(-1, 'error message'); 5 | } catch (error) { 6 | expect(error).to.be.an(Error); 7 | expect(error.stack).to.be.ok(); 8 | expect(error.code).to.equal(-1); 9 | expect(error.message).to.equal('error message'); 10 | expect(error.toString()).to.contain('error message'); 11 | } 12 | }); 13 | 14 | it('should be a constructor', () => { 15 | const error = new AV.Error(-1, 'error message'); 16 | expect(error).to.be.an(AV.Error); 17 | expect(error).to.be.an(Error); 18 | expect(error.stack).to.be.ok(); 19 | expect(error.code).to.equal(-1); 20 | expect(error.message).to.equal('error message'); 21 | expect(error.toString()).to.contain('error message'); 22 | }); 23 | 24 | it('should be inheritable', () => { 25 | class UnknownError extends AV.Error { 26 | constructor() { 27 | super(-1, 'unknown error'); 28 | } 29 | } 30 | const error = new UnknownError(); 31 | expect(error).to.be.an(UnknownError); 32 | expect(error).to.be.an(AV.Error); 33 | expect(error).to.be.an(Error); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /test/geopoints.js: -------------------------------------------------------------------------------- 1 | import { setupPolly } from './polly'; 2 | 3 | var Post = AV.Object.extend('Post'); 4 | describe('Geopoints', () => { 5 | setupPolly(); 6 | 7 | before(function() { 8 | const post = new Post(); 9 | post.set('title', 'Post Geopoints'); 10 | post.set('body', ' Geopoints content.'); 11 | this.post = post; 12 | }); 13 | 14 | it('save object with geopoints', function() { 15 | const point = new AV.GeoPoint({ latitude: 40.0, longitude: -30.0 }); 16 | this.post.set('location', point); 17 | return this.post.save(); 18 | }); 19 | 20 | it('near', function() { 21 | const postGeoPoint = this.post.get('location'); 22 | // Create a query for places 23 | const query = new AV.Query(Post); 24 | // Interested in locations near user. 25 | query.near('location', postGeoPoint); 26 | // Limit what could be a lot of points. 27 | query.limit(10); 28 | // Final list of objects 29 | return query.find(); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | require('should'); 2 | require('./test.js'); 3 | require('./av.js'); 4 | 5 | require('./acl.js'); 6 | require('./cache'); 7 | require('./cloud.js'); 8 | require('./conversation.js'); 9 | require('./error.js'); 10 | require('./geopoints.js'); 11 | require('./hooks.js'); 12 | require('./leaderboard.js'); 13 | require('./object.js'); 14 | require('./query.js'); 15 | require('./role.js'); 16 | require('./search.js'); 17 | require('./sms.js'); 18 | require('./status.js'); 19 | require('./user.js'); 20 | 21 | if (process.env.REAL_BACKEND !== undefined) { 22 | require('./file.js'); 23 | } 24 | 25 | // require('./captcha.js'); 26 | -------------------------------------------------------------------------------- /test/polly.js: -------------------------------------------------------------------------------- 1 | import { Polly, setupMocha } from '@pollyjs/core'; 2 | import NodeHttpAdapter from '@pollyjs/adapter-node-http'; 3 | import FSPersister from '@pollyjs/persister-fs'; 4 | 5 | Polly.register(NodeHttpAdapter); 6 | Polly.register(FSPersister); 7 | 8 | const pollyOpt = { 9 | adapters: ['node-http'], 10 | persister: 'fs', 11 | recordFailedRequests: true, 12 | matchRequestsBy: { 13 | headers: false, 14 | url: { 15 | protocol: false, 16 | username: false, 17 | password: false, 18 | hostname: false, 19 | port: false, 20 | pathname: true, 21 | query: true, 22 | hash: false, 23 | }, 24 | }, 25 | }; 26 | 27 | const pollyEnabled = () => { 28 | return ( 29 | typeof process !== 'undefined' && 30 | process && 31 | process.env && 32 | process.env.REAL_BACKEND === undefined && 33 | process.env.NODE_ENV !== undefined 34 | ); 35 | }; 36 | 37 | export const setupPolly = () => { 38 | return pollyEnabled() && setupMocha(pollyOpt); 39 | }; 40 | 41 | const beforeEach = () => { 42 | return pollyEnabled() && setupMocha.beforeEach(pollyOpt); 43 | }; 44 | 45 | const afterEach = () => { 46 | return pollyEnabled() && setupMocha.afterEach(); 47 | }; 48 | 49 | export default { beforeEach, afterEach }; 50 | -------------------------------------------------------------------------------- /test/role.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import { setupPolly } from './polly'; 4 | 5 | describe('Role', function() { 6 | setupPolly(); 7 | describe('constructor', function() { 8 | it('normal usage', function() { 9 | var acl = new AV.ACL(); 10 | var role = new AV.Role('foo', acl); 11 | expect(role.getName()).to.be('foo'); 12 | expect(role.getACL()).to.be(acl); 13 | }); 14 | it('acl is required', function() { 15 | var role = new AV.Role('foo'); 16 | return role.save().should.be.rejected(); 17 | }); 18 | it('type check', function() { 19 | expect(function() { 20 | new AV.Role('foo', {}); 21 | }).to.throwError(); 22 | }); 23 | it('no argument', function() { 24 | expect(function() { 25 | new AV.Role(); 26 | }).not.to.throwError(); 27 | }); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /test/search.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe.skip('App Searching', function() { 4 | describe('#AV.SearchSortBuilder', function() { 5 | it('should build sort string.', function() { 6 | var builder = new AV.SearchSortBuilder(); 7 | var s = builder 8 | .ascending('a') 9 | .descending('b', 'max') 10 | .whereNear('location', new AV.GeoPoint(10, 20), { 11 | order: 'desc', 12 | }) 13 | .build(); 14 | expect(s).to.be( 15 | '[{"a":{"order":"asc","mode":"avg","missing":"_last"}},{"b":{"order":"desc","mode":"max","missing":"_last"}},{"_geo_distance":{"order":"desc","mode":"avg","unit":"km","location":{"lat":10,"lon":20}}}]' 16 | ); 17 | }); 18 | }); 19 | 20 | describe('#AV.SearchQuery', function() { 21 | it('should find something.', function() { 22 | var q = new AV.SearchQuery('GameScore'); 23 | q.queryString('*'); 24 | return q.find().then(function(results) { 25 | expect(q.hits()).to.be.greaterThan(0); 26 | expect(results[0]).to.be.an(AV.Object); 27 | }); 28 | }); 29 | 30 | it('should sort by score.', function() { 31 | var q = new AV.SearchQuery('GameScore'); 32 | q.descending('score'); 33 | q.queryString('*'); 34 | return q.find().then(function(results) { 35 | expect(q.hits()).to.be.greaterThan(0); 36 | console.dir(results); 37 | expect(results[0].appURL).to.be.ok(); 38 | expect(results[0].get('score') >= results[1].get('score')).to.be.ok(); 39 | }); 40 | }); 41 | 42 | it('should sort by score with sort builder.', function() { 43 | var q = new AV.SearchQuery('GameScore'); 44 | q.sortBy(new AV.SearchSortBuilder().descending('score')); 45 | q.queryString('*'); 46 | return q.find().then(function(results) { 47 | expect(q.hits()).to.be.greaterThan(0); 48 | console.dir(results); 49 | expect(results[0].get('score') >= results[1].get('score')).to.be.ok(); 50 | }); 51 | }); 52 | }); 53 | }); 54 | -------------------------------------------------------------------------------- /test/sms.js: -------------------------------------------------------------------------------- 1 | // 'use strict'; 2 | 3 | // describe("sms", function() { 4 | // var phoneNumber = '18668012283'; 5 | // describe("#verifyUserMobilePhone", function(){ 6 | 7 | // it("should be verified", function(done){ 8 | // var user = new AV.User(); 9 | // user.set("username", "dennis"); 10 | // user.set("password", "123456"); 11 | // user.setMobilePhoneNumber(phoneNumber); 12 | 13 | // user.signUp(null, { 14 | // success: function(user) { 15 | // AV.User.requestMobilePhoneVerify(phoneNumber).then(function() { 16 | // AV.User.logInWithMobilePhone(phoneNumber, '123456').then(function(user){ 17 | // debug(user); 18 | // expect(user.get('mobilePhoneVerified')).to.be(false); 19 | // AV.User.requestLoginSmsCode(phoneNumber).then(function(){ 20 | // throw "Unverfied."; 21 | // }, function(err){ 22 | // user.destroy().then(function(){ 23 | // done(); 24 | // }); 25 | // }); 26 | // }, function(err){ 27 | // throw err; 28 | // }); 29 | 30 | // },function(err){ 31 | // throw err; 32 | // }); 33 | // }, 34 | // error: function(user, error) { 35 | // throw error; 36 | // } 37 | // }); 38 | // }); 39 | // }); 40 | 41 | // describe("#requestSmsCode", function(){ 42 | // it("should send sms code.", function(done){ 43 | // AV.Cloud.requestSmsCode(phoneNumber).then(function(){ 44 | // AV.Cloud.requestSmsCode({ 45 | // mobilePhoneNumber: phoneNumber, 46 | // name: '测试啊', 47 | // op: '测试操作', 48 | // ttl: 5 49 | // }).then(function(){ 50 | // done(); 51 | // }, function(err){ 52 | // done(err); 53 | // }); 54 | // }, function(err){ 55 | // done(err); 56 | // }); 57 | // }); 58 | // }); 59 | // }); 60 | -------------------------------------------------------------------------------- /test/storage.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var Storage = AV.localStorage; 4 | var testKey = '__test__'; 5 | 6 | describe('Storage', function() { 7 | describe('sync', function() { 8 | it('set, get', function() { 9 | Storage.setItem(testKey, testKey); 10 | var result = Storage.getItem(testKey); 11 | expect(result).to.be(testKey); 12 | }); 13 | it('remove', function() { 14 | Storage.setItem(testKey, testKey); 15 | Storage.removeItem(testKey); 16 | var result = Storage.getItem(testKey); 17 | expect(result).to.be(null); 18 | }); 19 | it('clear', function() { 20 | Storage.setItem(testKey, testKey); 21 | Storage.clear(); 22 | var result = Storage.getItem(testKey); 23 | expect(result).to.be(null); 24 | }); 25 | }); 26 | 27 | describe('async', function() { 28 | it('set, get', function(done) { 29 | Storage.setItemAsync(testKey, testKey) 30 | .then(function() { 31 | return Storage.getItem(testKey); 32 | }) 33 | .then(function(result) { 34 | expect(result).to.be(testKey); 35 | done(); 36 | }); 37 | }); 38 | it('remove', function(done) { 39 | Storage.setItemAsync(testKey, testKey) 40 | .then(function() { 41 | return Storage.removeItemAsync(testKey); 42 | }) 43 | .then(function() { 44 | return Storage.getItemAsync(testKey); 45 | }) 46 | .then(function(result) { 47 | expect(result).to.be(null); 48 | done(); 49 | }); 50 | }); 51 | it('clear', function(done) { 52 | Storage.setItemAsync(testKey, testKey) 53 | .then(function() { 54 | return Storage.clearAsync(testKey); 55 | }) 56 | .then(function() { 57 | return Storage.getItemAsync(testKey); 58 | }) 59 | .then(function(result) { 60 | expect(result).to.be(null); 61 | done(); 62 | }); 63 | }); 64 | }); 65 | }); 66 | -------------------------------------------------------------------------------- /test/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Test 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 55 | 56 | 57 | 58 |
    59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | if (typeof process === 'undefined') process = { env: {} }; 2 | 3 | if (typeof require !== 'undefined') { 4 | global.debug = require('debug')('test'); 5 | global.expect = require('expect.js'); 6 | global.AV = require('../src/entry'); 7 | } 8 | 9 | AV.init({ 10 | appId: process.env.APPID, 11 | appKey: process.env.APPKEY, 12 | masterKey: process.env.MASTERKEY, 13 | hookKey: process.env.HOOKKEY, 14 | serverURLs: process.env.SERVER_URL, 15 | }); 16 | AV.setProduction(true); 17 | -------------------------------------------------------------------------------- /test/util.js: -------------------------------------------------------------------------------- 1 | export const forceDeleteUser = username => { 2 | const userQuery = new AV.Query('_User'); 3 | userQuery.equalTo('username', username); 4 | return userQuery 5 | .first({ useMasterKey: true }) 6 | .then(user => user && user.destroy({ useMasterKey: true })) 7 | .catch(); 8 | }; 9 | -------------------------------------------------------------------------------- /webpack/browser.js: -------------------------------------------------------------------------------- 1 | const { create, entry, name } = require('./common'); 2 | 3 | const config = create(); 4 | 5 | config.entry = { 6 | [`${name}`]: entry, 7 | [`${name}-min`]: entry, 8 | }; 9 | 10 | module.exports = config; 11 | -------------------------------------------------------------------------------- /webpack/common.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const webpack = require('webpack'); 3 | 4 | const entry = (exports.entry = process.env.LIVE_QUERY 5 | ? './src/entry/index-live-query.js' 6 | : './src/entry/index.js'); 7 | exports.name = process.env.LIVE_QUERY ? 'av-live-query' : 'av'; 8 | 9 | exports.create = () => ({ 10 | entry: { 11 | av: entry, 12 | }, 13 | output: { 14 | filename: '[name].js', 15 | libraryTarget: 'umd2', 16 | library: 'AV', 17 | path: path.resolve(__dirname, '../dist'), 18 | }, 19 | resolve: {}, 20 | devtool: 'source-map', 21 | node: { 22 | // do not polyfill Buffer 23 | Buffer: false, 24 | stream: false, 25 | process: false, 26 | }, 27 | module: { 28 | loaders: [ 29 | { 30 | test: /\.js$/, 31 | include: [ 32 | path.resolve(__dirname, '../src'), 33 | /node_modules\/leancloud-realtime/, 34 | /node_modules\/event-target-shim/, 35 | /node_modules\/superagent/, 36 | /node_modules\/@leancloud\/platform-adapters-/, 37 | ], 38 | loader: 'babel-loader', 39 | }, 40 | { 41 | test: /\.js$/, 42 | enforce: 'pre', 43 | include: [path.resolve(__dirname, '../src')], 44 | use: [ 45 | { 46 | loader: 'webpack-strip-block', 47 | options: { 48 | start: 'NODE-ONLY:start', 49 | end: 'NODE-ONLY:end', 50 | }, 51 | }, 52 | ], 53 | }, 54 | ], 55 | }, 56 | plugins: [ 57 | new webpack.EnvironmentPlugin(['PLATFORM']), 58 | new webpack.optimize.UglifyJsPlugin({ 59 | include: /-min\.js$/, 60 | sourceMap: true, 61 | }), 62 | ], 63 | }); 64 | -------------------------------------------------------------------------------- /webpack/core.js: -------------------------------------------------------------------------------- 1 | const { create, name } = require('./common'); 2 | 3 | const config = create(); 4 | 5 | const entry = process.env.LIVE_QUERY 6 | ? './src/entry/core-live-query.js' 7 | : './src/entry/core.js'; 8 | 9 | config.entry = { 10 | [`${name}-core`]: entry, 11 | [`${name}-core-min`]: entry, 12 | }; 13 | 14 | module.exports = config; 15 | -------------------------------------------------------------------------------- /webpack/weapp.js: -------------------------------------------------------------------------------- 1 | const { create, entry, name } = require('./common'); 2 | 3 | const config = create(); 4 | 5 | config.entry = { 6 | [`${name}-weapp`]: entry, 7 | [`${name}-weapp-min`]: entry, 8 | }; 9 | config.resolve.aliasFields = ['weapp', 'browser']; 10 | 11 | module.exports = config; 12 | --------------------------------------------------------------------------------