├── .eslintignore ├── .eslintrc.json ├── .gitattributes ├── .github ├── .OwlBot.lock.yaml ├── .OwlBot.yaml ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── bug_report.yml │ ├── config.yml │ ├── documentation_request.yml │ ├── feature_request.md │ ├── feature_request.yml │ ├── processs_request.md │ ├── question.md │ ├── questions.md │ └── support_request.md ├── PULL_REQUEST_TEMPLATE.md ├── auto-approve.yml ├── auto-label.yaml ├── flakybot.yaml ├── generated-files-bot.yml ├── release-please.yml ├── release-trigger.yml ├── scripts │ ├── close-invalid-link.cjs │ ├── close-unresponsive.cjs │ └── remove-response-label.cjs ├── sync-repo-settings.yaml └── workflows │ ├── ci.yaml │ ├── issues-no-repro.yaml │ └── response.yaml ├── .gitignore ├── .idea └── runConfigurations │ ├── Conformance_Tests.xml │ ├── System_Test.xml │ └── Unit_Tests.xml ├── .jsdoc.js ├── .kokoro ├── .gitattributes ├── common.cfg ├── continuous │ └── node14 │ │ ├── common.cfg │ │ ├── lint.cfg │ │ ├── samples-test.cfg │ │ ├── system-test.cfg │ │ └── test.cfg ├── docs.sh ├── lint.sh ├── populate-secrets.sh ├── pre-samples-test.sh ├── pre-system-test.sh ├── presubmit │ ├── node14 │ │ ├── common.cfg │ │ ├── samples-test.cfg │ │ ├── system-test.cfg │ │ └── test.cfg │ └── windows │ │ ├── common.cfg │ │ └── test.cfg ├── publish.sh ├── release │ ├── common.cfg │ ├── docs-devsite.cfg │ ├── docs-devsite.sh │ ├── docs.cfg │ ├── docs.sh │ └── publish.cfg ├── samples-test.sh ├── system-test.sh ├── test.bat ├── test.sh └── trampoline.sh ├── .mocharc.js ├── .nycrc ├── .prettierignore ├── .prettierrc.js ├── .readme-partials.yaml ├── .repo-metadata.json ├── .trampolinerc ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── SECURITY.md ├── api-report └── firestore.api.md ├── dev ├── conformance │ ├── conformance-tests │ │ ├── create-all-transforms.json │ │ ├── create-arrayremove-multi.json │ │ ├── create-arrayremove-nested.json │ │ ├── create-arrayremove-noarray-nested.json │ │ ├── create-arrayremove-noarray.json │ │ ├── create-arrayremove-with-st.json │ │ ├── create-arrayremove.json │ │ ├── create-arrayunion-multi.json │ │ ├── create-arrayunion-nested.json │ │ ├── create-arrayunion-noarray-nested.json │ │ ├── create-arrayunion-noarray.json │ │ ├── create-arrayunion-with-st.json │ │ ├── create-arrayunion.json │ │ ├── create-basic.json │ │ ├── create-complex.json │ │ ├── create-del-noarray-nested.json │ │ ├── create-del-noarray.json │ │ ├── create-empty.json │ │ ├── create-nodel.json │ │ ├── create-nosplit.json │ │ ├── create-special-chars.json │ │ ├── create-st-alone.json │ │ ├── create-st-multi.json │ │ ├── create-st-nested.json │ │ ├── create-st-noarray-nested.json │ │ ├── create-st-noarray.json │ │ ├── create-st-with-empty-map.json │ │ ├── create-st.json │ │ ├── delete-exists-precond.json │ │ ├── delete-no-precond.json │ │ ├── delete-time-precond.json │ │ ├── get-basic.json │ │ ├── listen-add-mod-del-add.json │ │ ├── listen-add-one.json │ │ ├── listen-add-three.json │ │ ├── listen-doc-remove.json │ │ ├── listen-empty.json │ │ ├── listen-filter-nop.json │ │ ├── listen-multi-docs.json │ │ ├── listen-nocurrent.json │ │ ├── listen-nomod.json │ │ ├── listen-removed-target-ids.json │ │ ├── listen-reset.json │ │ ├── listen-target-add-nop.json │ │ ├── listen-target-add-wrong-id.json │ │ ├── listen-target-remove.json │ │ ├── query-arrayremove-cursor.json │ │ ├── query-arrayremove-where.json │ │ ├── query-arrayunion-cursor.json │ │ ├── query-arrayunion-where.json │ │ ├── query-bad-NaN.json │ │ ├── query-bad-null.json │ │ ├── query-cursor-docsnap-order.json │ │ ├── query-cursor-docsnap-orderby-name.json │ │ ├── query-cursor-docsnap-where-eq.json │ │ ├── query-cursor-docsnap-where-neq-orderby.json │ │ ├── query-cursor-docsnap-where-neq.json │ │ ├── query-cursor-docsnap.json │ │ ├── query-cursor-endbefore-empty-map.json │ │ ├── query-cursor-endbefore-empty.json │ │ ├── query-cursor-no-order.json │ │ ├── query-cursor-startafter-docsnap.json │ │ ├── query-cursor-startat-empty-map.json │ │ ├── query-cursor-startat-empty.json │ │ ├── query-cursor-vals-1a.json │ │ ├── query-cursor-vals-1b.json │ │ ├── query-cursor-vals-2.json │ │ ├── query-cursor-vals-docid.json │ │ ├── query-cursor-vals-last-wins.json │ │ ├── query-del-cursor.json │ │ ├── query-del-where.json │ │ ├── query-invalid-operator.json │ │ ├── query-invalid-path-order.json │ │ ├── query-invalid-path-select.json │ │ ├── query-invalid-path-where.json │ │ ├── query-offset-limit-last-wins.json │ │ ├── query-offset-limit.json │ │ ├── query-order.json │ │ ├── query-select-empty.json │ │ ├── query-select-last-wins.json │ │ ├── query-select.json │ │ ├── query-st-cursor.json │ │ ├── query-st-where.json │ │ ├── query-where-2.json │ │ ├── query-where-NaN.json │ │ ├── query-where-null.json │ │ ├── query-where.json │ │ ├── query-wrong-collection.json │ │ ├── set-all-transforms.json │ │ ├── set-arrayremove-multi.json │ │ ├── set-arrayremove-nested.json │ │ ├── set-arrayremove-noarray-nested.json │ │ ├── set-arrayremove-noarray.json │ │ ├── set-arrayremove-with-st.json │ │ ├── set-arrayremove.json │ │ ├── set-arrayunion-merge.json │ │ ├── set-arrayunion-multi.json │ │ ├── set-arrayunion-nested.json │ │ ├── set-arrayunion-noarray-nested.json │ │ ├── set-arrayunion-noarray.json │ │ ├── set-arrayunion-with-st.json │ │ ├── set-arrayunion.json │ │ ├── set-basic.json │ │ ├── set-complex.json │ │ ├── set-del-merge-alone.json │ │ ├── set-del-merge.json │ │ ├── set-del-mergeall.json │ │ ├── set-del-noarray-nested.json │ │ ├── set-del-noarray.json │ │ ├── set-del-nomerge.json │ │ ├── set-del-nonleaf.json │ │ ├── set-del-wo-merge.json │ │ ├── set-empty.json │ │ ├── set-merge-fp.json │ │ ├── set-merge-nested.json │ │ ├── set-merge-nonleaf.json │ │ ├── set-merge-prefix.json │ │ ├── set-merge-present.json │ │ ├── set-merge.json │ │ ├── set-mergeall-empty.json │ │ ├── set-mergeall-nested.json │ │ ├── set-mergeall.json │ │ ├── set-nodel.json │ │ ├── set-nosplit.json │ │ ├── set-special-chars.json │ │ ├── set-st-alone-mergeall.json │ │ ├── set-st-alone.json │ │ ├── set-st-merge-both.json │ │ ├── set-st-merge-nonleaf-alone.json │ │ ├── set-st-merge-nonleaf.json │ │ ├── set-st-merge-nowrite.json │ │ ├── set-st-mergeall.json │ │ ├── set-st-multi.json │ │ ├── set-st-nested.json │ │ ├── set-st-noarray-nested.json │ │ ├── set-st-noarray.json │ │ ├── set-st-nomerge.json │ │ ├── set-st-with-empty-map.json │ │ ├── set-st.json │ │ ├── update-all-transforms.json │ │ ├── update-arrayremove-alone.json │ │ ├── update-arrayremove-multi.json │ │ ├── update-arrayremove-nested.json │ │ ├── update-arrayremove-noarray-nested.json │ │ ├── update-arrayremove-noarray.json │ │ ├── update-arrayremove-with-st.json │ │ ├── update-arrayremove.json │ │ ├── update-arrayunion-alone.json │ │ ├── update-arrayunion-multi.json │ │ ├── update-arrayunion-nested.json │ │ ├── update-arrayunion-noarray-nested.json │ │ ├── update-arrayunion-noarray.json │ │ ├── update-arrayunion-with-st.json │ │ ├── update-arrayunion.json │ │ ├── update-badchar.json │ │ ├── update-basic.json │ │ ├── update-complex.json │ │ ├── update-del-alone.json │ │ ├── update-del-dot.json │ │ ├── update-del-nested.json │ │ ├── update-del-noarray-nested.json │ │ ├── update-del-noarray.json │ │ ├── update-del.json │ │ ├── update-exists-false-precond.json │ │ ├── update-exists-true-precond.json │ │ ├── update-fp-empty-component.json │ │ ├── update-nested-transform-and-nested-value.json │ │ ├── update-no-paths.json │ │ ├── update-paths-all-transforms.json │ │ ├── update-paths-arrayremove-alone.json │ │ ├── update-paths-arrayremove-multi.json │ │ ├── update-paths-arrayremove-nested.json │ │ ├── update-paths-arrayremove-noarray-nested.json │ │ ├── update-paths-arrayremove-noarray.json │ │ ├── update-paths-arrayremove-with-st.json │ │ ├── update-paths-arrayremove.json │ │ ├── update-paths-arrayunion-alone.json │ │ ├── update-paths-arrayunion-multi.json │ │ ├── update-paths-arrayunion-nested.json │ │ ├── update-paths-arrayunion-noarray-nested.json │ │ ├── update-paths-arrayunion-noarray.json │ │ ├── update-paths-arrayunion-with-st.json │ │ ├── update-paths-arrayunion.json │ │ ├── update-paths-basic.json │ │ ├── update-paths-complex.json │ │ ├── update-paths-del-alone.json │ │ ├── update-paths-del-nested.json │ │ ├── update-paths-del-noarray-nested.json │ │ ├── update-paths-del-noarray.json │ │ ├── update-paths-del.json │ │ ├── update-paths-exists-false-precond.json │ │ ├── update-paths-exists-true-precond.json │ │ ├── update-paths-fp-del.json │ │ ├── update-paths-fp-dup-transforms.json │ │ ├── update-paths-fp-dup.json │ │ ├── update-paths-fp-empty-component.json │ │ ├── update-paths-fp-empty.json │ │ ├── update-paths-fp-multi.json │ │ ├── update-paths-fp-nosplit.json │ │ ├── update-paths-nested-transform-and-nested-value.json │ │ ├── update-paths-no-paths.json │ │ ├── update-paths-prefix-1.json │ │ ├── update-paths-prefix-2.json │ │ ├── update-paths-prefix-3.json │ │ ├── update-paths-special-chars.json │ │ ├── update-paths-st-alone.json │ │ ├── update-paths-st-multi.json │ │ ├── update-paths-st-nested.json │ │ ├── update-paths-st-noarray-nested.json │ │ ├── update-paths-st-noarray.json │ │ ├── update-paths-st-with-empty-map.json │ │ ├── update-paths-st.json │ │ ├── update-paths-uptime.json │ │ ├── update-prefix-1.json │ │ ├── update-prefix-2.json │ │ ├── update-prefix-3.json │ │ ├── update-quoting.json │ │ ├── update-split-top-level.json │ │ ├── update-split.json │ │ ├── update-st-alone.json │ │ ├── update-st-dot.json │ │ ├── update-st-multi.json │ │ ├── update-st-nested.json │ │ ├── update-st-noarray-nested.json │ │ ├── update-st-noarray.json │ │ ├── update-st-with-empty-map.json │ │ ├── update-st.json │ │ └── update-uptime.json │ ├── runner.ts │ └── test-definition.proto ├── protos │ ├── admin_v1.json │ ├── firestore │ │ └── bundle.proto │ ├── firestore_admin_v1_proto_api.d.ts │ ├── firestore_admin_v1_proto_api.js │ ├── firestore_v1_proto_api.d.ts │ ├── firestore_v1_proto_api.js │ ├── firestore_v1beta1_proto_api.d.ts │ ├── firestore_v1beta1_proto_api.js │ ├── google │ │ ├── api │ │ │ ├── annotations.proto │ │ │ ├── client.proto │ │ │ ├── field_behavior.proto │ │ │ ├── http.proto │ │ │ ├── launch_stage.proto │ │ │ └── resource.proto │ │ ├── firestore │ │ │ ├── admin │ │ │ │ └── v1 │ │ │ │ │ ├── backup.proto │ │ │ │ │ ├── database.proto │ │ │ │ │ ├── field.proto │ │ │ │ │ ├── firestore_admin.proto │ │ │ │ │ ├── index.proto │ │ │ │ │ ├── location.proto │ │ │ │ │ ├── operation.proto │ │ │ │ │ └── schedule.proto │ │ │ ├── v1 │ │ │ │ ├── aggregation_result.proto │ │ │ │ ├── bloom_filter.proto │ │ │ │ ├── common.proto │ │ │ │ ├── document.proto │ │ │ │ ├── firestore.proto │ │ │ │ ├── query.proto │ │ │ │ ├── query_profile.proto │ │ │ │ └── write.proto │ │ │ └── v1beta1 │ │ │ │ ├── common.proto │ │ │ │ ├── document.proto │ │ │ │ ├── firestore.proto │ │ │ │ ├── query.proto │ │ │ │ ├── undeliverable_first_gen_event.proto │ │ │ │ └── write.proto │ │ ├── longrunning │ │ │ └── operations.proto │ │ ├── protobuf │ │ │ ├── any.proto │ │ │ ├── descriptor.proto │ │ │ ├── duration.proto │ │ │ ├── empty.proto │ │ │ ├── field_mask.proto │ │ │ ├── struct.proto │ │ │ ├── timestamp.proto │ │ │ └── wrappers.proto │ │ ├── rpc │ │ │ └── status.proto │ │ └── type │ │ │ ├── dayofweek.proto │ │ │ └── latlng.proto │ ├── update.sh │ ├── v1.json │ └── v1beta1.json ├── src │ ├── aggregate.ts │ ├── backoff.ts │ ├── bulk-writer.ts │ ├── bundle.ts │ ├── collection-group.ts │ ├── convert.ts │ ├── document-change.ts │ ├── document-reader.ts │ ├── document.ts │ ├── external-modules.d.ts │ ├── field-value.ts │ ├── filter.ts │ ├── geo-point.ts │ ├── index.ts │ ├── logger.ts │ ├── map-type.ts │ ├── order.ts │ ├── path.ts │ ├── pool.ts │ ├── query-partition.ts │ ├── query-profile.ts │ ├── rate-limiter.ts │ ├── recursive-delete.ts │ ├── reference │ │ ├── aggregate-query-snapshot.ts │ │ ├── aggregate-query.ts │ │ ├── collection-reference.ts │ │ ├── composite-filter-internal.ts │ │ ├── constants.ts │ │ ├── document-reference.ts │ │ ├── field-filter-internal.ts │ │ ├── field-order.ts │ │ ├── filter-internal.ts │ │ ├── helpers.ts │ │ ├── query-options.ts │ │ ├── query-snapshot.ts │ │ ├── query-util.ts │ │ ├── query.ts │ │ ├── types.ts │ │ ├── vector-query-options.ts │ │ ├── vector-query-snapshot.ts │ │ └── vector-query.ts │ ├── serializer.ts │ ├── status-code.ts │ ├── telemetry │ │ ├── disabled-trace-util.ts │ │ ├── enabled-trace-util.ts │ │ ├── span.ts │ │ └── trace-util.ts │ ├── timestamp.ts │ ├── transaction.ts │ ├── types.ts │ ├── util.ts │ ├── v1 │ │ ├── firestore_admin_client.ts │ │ ├── firestore_admin_client_config.json │ │ ├── firestore_admin_proto_list.json │ │ ├── firestore_client.ts │ │ ├── firestore_client_config.json │ │ ├── firestore_proto_list.json │ │ ├── gapic_metadata.json │ │ └── index.ts │ ├── v1beta1 │ │ ├── firestore_client.ts │ │ ├── firestore_client_config.json │ │ ├── firestore_proto_list.json │ │ ├── gapic_metadata.json │ │ └── index.ts │ ├── validate.ts │ ├── watch.ts │ └── write-batch.ts ├── system-test │ ├── firestore.ts │ ├── index_test_helper.ts │ └── tracing.ts └── test │ ├── aggregate.ts │ ├── aggregateQuery.ts │ ├── backoff.ts │ ├── bulk-writer.ts │ ├── bundle.ts │ ├── collection.ts │ ├── document.ts │ ├── field-value.ts │ ├── gapic_firestore_admin_v1.ts │ ├── gapic_firestore_v1.ts │ ├── gapic_firestore_v1beta1.ts │ ├── ignore-undefined.ts │ ├── index.ts │ ├── lazy-load.ts │ ├── mocha.opts │ ├── order.ts │ ├── partition-query.ts │ ├── path.ts │ ├── pool.ts │ ├── query.ts │ ├── rate-limiter.ts │ ├── recursive-delete.ts │ ├── serializer.ts │ ├── timestamp.ts │ ├── tracing.ts │ ├── transaction.ts │ ├── types.ts │ ├── util.ts │ ├── util │ └── helpers.ts │ ├── vector-query.ts │ ├── watch.ts │ └── write-batch.ts ├── docfx.json ├── linkinator.config.json ├── owlbot.py ├── package.json ├── renovate.json ├── samples ├── .eslintrc.yml ├── README.md ├── limit-to-last-query.js ├── package.json ├── quickstart.js ├── solution-counters.js └── test │ ├── limit-to-last-query.test.js │ ├── quickstart.test.js │ └── solution-counters.test.js ├── scripts ├── .eslintrc.yml ├── api-report.js ├── init-directories.js └── license.js ├── tsconfig.json └── types ├── firestore.d.ts ├── protos ├── firestore_admin_v1_proto_api.d.ts ├── firestore_v1_proto_api.d.ts └── firestore_v1beta1_proto_api.d.ts ├── v1 ├── firestore_admin_client.d.ts └── firestore_client.d.ts └── v1beta1 └── firestore_client.d.ts /.eslintignore: -------------------------------------------------------------------------------- 1 | **/node_modules 2 | **/coverage 3 | test/fixtures 4 | build/ 5 | docs/ 6 | protos/ 7 | samples/generated/ 8 | system-test/**/fixtures 9 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./node_modules/gts", 3 | "overrides": [ 4 | { 5 | "files": [ 6 | "dev/src/*.ts" 7 | ], 8 | "parser": "@typescript-eslint/parser", 9 | "rules": { 10 | "@typescript-eslint/explicit-function-return-type": [ 11 | "error", 12 | { 13 | "allowExpressions": true, 14 | "allowTypedFunctionExpressions": true 15 | } 16 | ], 17 | "no-console": ["error", {"allow": ["error"]}] 18 | } 19 | }, 20 | { 21 | "files": [ 22 | "dev/test/*.ts", 23 | "dev/system-test/*.ts" 24 | ], 25 | "parser": "@typescript-eslint/parser", 26 | "rules": { 27 | "no-restricted-properties": [ 28 | "error", 29 | { 30 | "object": "describe", 31 | "property": "only" 32 | }, 33 | { 34 | "object": "it", 35 | "property": "only" 36 | } 37 | ] 38 | } 39 | } 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.ts text eol=lf 2 | *.js text eol=lf 3 | protos/* linguist-generated 4 | **/api-extractor.json linguist-language=JSON-with-Comments 5 | -------------------------------------------------------------------------------- /.github/.OwlBot.lock.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2024 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | docker: 15 | image: gcr.io/cloud-devrel-public-resources/owlbot-nodejs:latest 16 | digest: sha256:0d39e59663287ae929c1d4ccf8ebf7cef9946826c9b86eda7e85d8d752dbb584 17 | # created: 2024-11-21T22:39:44.342569463Z 18 | -------------------------------------------------------------------------------- /.github/.OwlBot.yaml: -------------------------------------------------------------------------------- 1 | # Copyright 2021 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | docker: 15 | image: gcr.io/cloud-devrel-public-resources/owlbot-nodejs:latest 16 | 17 | 18 | deep-remove-regex: 19 | - /owl-bot-staging 20 | 21 | deep-copy-regex: 22 | - source: /google/firestore/(v.*)/.*-nodejs/(.*) 23 | dest: /owl-bot-staging/$1/$2 24 | - source: /google/firestore/admin/(v.*)/.*-nodejs/(.*) 25 | dest: /owl-bot-staging/admin/$1/$2 26 | 27 | begin-after-commit-hash: d3509d2520fb8db862129633f1cf8406d17454e1 28 | 29 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Code owners file. 2 | # This file controls who is tagged for review for any given pull request. 3 | # 4 | # For syntax help see: 5 | # https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners#codeowners-syntax 6 | 7 | 8 | # The yoshi-nodejs team is the default owner for nodejs repositories. 9 | * @googleapis/yoshi-nodejs @googleapis/firestore-dpe @googleapis/api-firestore 10 | .github/auto-approve.yml @googleapis/github-automation/ -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | contact_links: 2 | - name: Google Cloud Support 3 | url: https://cloud.google.com/support/ 4 | about: If you have a support contract with Google, please use the Google Cloud Support portal. 5 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this library 4 | labels: 'type: feature request, priority: p3' 5 | --- 6 | 7 | Thanks for stopping by to let us know something could be better! 8 | 9 | **PLEASE READ**: If you have a support contract with Google, please create an issue in the [support console](https://cloud.google.com/support/) instead of filing on GitHub. This will ensure a timely response. 10 | 11 | **Is your feature request related to a problem? Please describe.** 12 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | **Describe alternatives you've considered** 16 | A clear and concise description of any alternative solutions or features you've considered. 17 | **Additional context** 18 | Add any other context or screenshots about the feature request here. 19 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/processs_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Process Request 3 | about: Submit a process request to the library. Process requests are any requests related to library infrastructure, for example CI/CD, publishing, releasing, broken links. 4 | --- 5 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Question 3 | about: Ask a question 4 | labels: 'type: question, priority: p3' 5 | --- 6 | 7 | Thanks for stopping by to ask us a question! Please make sure to include: 8 | - What you're trying to do 9 | - What code you've already tried 10 | - Any error messages you're getting 11 | 12 | **PLEASE READ**: If you have a support contract with Google, please create an issue in the [support console](https://cloud.google.com/support/) instead of filing on GitHub. This will ensure a timely response. 13 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/questions.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Question 3 | about: If you have a question, please use Discussions 4 | 5 | --- 6 | 7 | If you have a general question that goes beyond the library itself, we encourage you to use [Discussions](https://github.com//discussions) 8 | to engage with fellow community members! 9 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/support_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Support request 3 | about: If you have a support contract with Google, please create an issue in the Google Cloud Support console. 4 | 5 | --- 6 | 7 | **PLEASE READ**: If you have a support contract with Google, please create an issue in the [support console](https://cloud.google.com/support/) instead of filing on GitHub. This will ensure a timely response. 8 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Thank you for opening a Pull Request! Before submitting your PR, there are a few things you can do to make sure it goes smoothly: 2 | - [ ] Make sure to open an issue as a [bug/issue](https://github.com/googleapis/nodejs-firestore/issues/new/choose) before writing your code! That way we can discuss the change, evaluate designs, and agree on the general idea 3 | - [ ] Ensure the tests and linter pass 4 | - [ ] Code coverage does not decrease (if any source code was changed) 5 | - [ ] Appropriate docs were updated (if necessary) 6 | 7 | Fixes # 🦕 8 | -------------------------------------------------------------------------------- /.github/auto-approve.yml: -------------------------------------------------------------------------------- 1 | processes: 2 | - "NodeDependency" -------------------------------------------------------------------------------- /.github/auto-label.yaml: -------------------------------------------------------------------------------- 1 | requestsize: 2 | enabled: true 3 | -------------------------------------------------------------------------------- /.github/flakybot.yaml: -------------------------------------------------------------------------------- 1 | issuePriority: p2 2 | 3 | 4 | -------------------------------------------------------------------------------- /.github/generated-files-bot.yml: -------------------------------------------------------------------------------- 1 | generatedFiles: 2 | - path: '.kokoro/**' 3 | message: '`.kokoro` files are templated and should be updated in [`synthtool`](https://github.com/googleapis/synthtool)' 4 | - path: '.github/CODEOWNERS' 5 | message: 'CODEOWNERS should instead be modified via the `codeowner_team` property in .repo-metadata.json' 6 | - path: '.github/workflows/ci.yaml' 7 | message: '`.github/workflows/ci.yaml` (GitHub Actions) should be updated in [`synthtool`](https://github.com/googleapis/synthtool)' 8 | - path: '.github/generated-files-bot.+(yml|yaml)' 9 | message: '`.github/generated-files-bot.(yml|yaml)` should be updated in [`synthtool`](https://github.com/googleapis/synthtool)' 10 | - path: 'README.md' 11 | message: '`README.md` is managed by [`synthtool`](https://github.com/googleapis/synthtool). However, a partials file can be used to update the README, e.g.: https://github.com/googleapis/nodejs-storage/blob/main/.readme-partials.yaml' 12 | - path: 'samples/README.md' 13 | message: '`samples/README.md` is managed by [`synthtool`](https://github.com/googleapis/synthtool). However, a partials file can be used to update the README, e.g.: https://github.com/googleapis/nodejs-storage/blob/main/.readme-partials.yaml' 14 | ignoreAuthors: 15 | - 'gcf-owl-bot[bot]' 16 | - 'yoshi-automation' 17 | -------------------------------------------------------------------------------- /.github/release-please.yml: -------------------------------------------------------------------------------- 1 | handleGHRelease: true 2 | releaseType: node 3 | -------------------------------------------------------------------------------- /.github/release-trigger.yml: -------------------------------------------------------------------------------- 1 | enabled: true 2 | multiScmName: nodejs-firestore -------------------------------------------------------------------------------- /.github/scripts/remove-response-label.cjs: -------------------------------------------------------------------------------- 1 | // Copyright 2024 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | module.exports = async ({ github, context }) => { 16 | const commenter = context.actor; 17 | const issue = await github.rest.issues.get({ 18 | owner: context.repo.owner, 19 | repo: context.repo.repo, 20 | issue_number: context.issue.number, 21 | }); 22 | const author = issue.data.user.login; 23 | const labels = issue.data.labels.map((e) => e.name); 24 | 25 | if (author === commenter && labels.includes('needs more info')) { 26 | await github.rest.issues.removeLabel({ 27 | owner: context.repo.owner, 28 | repo: context.repo.repo, 29 | issue_number: context.issue.number, 30 | name: 'needs more info', 31 | }); 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /.github/sync-repo-settings.yaml: -------------------------------------------------------------------------------- 1 | branchProtectionRules: 2 | - pattern: main 3 | isAdminEnforced: true 4 | requiredApprovingReviewCount: 1 5 | requiresCodeOwnerReviews: true 6 | requiresStrictStatusChecks: true 7 | requiredStatusCheckContexts: 8 | - "ci/kokoro: Samples test" 9 | - "ci/kokoro: System test" 10 | - lint 11 | - test (14) 12 | - test (16) 13 | - test (18) 14 | - cla/google 15 | - windows 16 | - OwlBot Post Processor 17 | permissionRules: 18 | - team: yoshi-admins 19 | permission: admin 20 | - team: jsteam-admins 21 | permission: admin 22 | - team: jsteam 23 | permission: push 24 | -------------------------------------------------------------------------------- /.github/workflows/issues-no-repro.yaml: -------------------------------------------------------------------------------- 1 | name: invalid_link 2 | on: 3 | issues: 4 | types: [opened, reopened] 5 | 6 | jobs: 7 | close: 8 | runs-on: ubuntu-latest 9 | permissions: 10 | issues: write 11 | pull-requests: write 12 | steps: 13 | - uses: actions/checkout@v4 14 | - uses: actions/github-script@v7 15 | with: 16 | script: | 17 | const script = require('./.github/scripts/close-invalid-link.cjs') 18 | await script({github, context}) 19 | -------------------------------------------------------------------------------- /.github/workflows/response.yaml: -------------------------------------------------------------------------------- 1 | name: no_response 2 | on: 3 | schedule: 4 | - cron: '30 1 * * *' # Run every day at 01:30 5 | workflow_dispatch: 6 | issue_comment: 7 | 8 | jobs: 9 | close: 10 | if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' 11 | runs-on: ubuntu-latest 12 | permissions: 13 | issues: write 14 | pull-requests: write 15 | steps: 16 | - uses: actions/checkout@v4 17 | - uses: actions/github-script@v7 18 | with: 19 | script: | 20 | const script = require('./.github/scripts/close-unresponsive.cjs') 21 | await script({github, context}) 22 | 23 | remove_label: 24 | if: github.event_name == 'issue_comment' 25 | runs-on: ubuntu-latest 26 | permissions: 27 | issues: write 28 | pull-requests: write 29 | steps: 30 | - uses: actions/checkout@v4 31 | - uses: actions/github-script@v7 32 | with: 33 | script: | 34 | const script = require('./.github/scripts/remove-response-label.cjs') 35 | await script({github, context}) 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/*.log 2 | **/node_modules 3 | /.coverage 4 | /coverage 5 | /.nyc_output 6 | /docs/ 7 | /out/ 8 | /build/ 9 | system-test/secrets.js 10 | system-test/*key.json 11 | *.lock 12 | .DS_Store 13 | package-lock.json 14 | __pycache__ 15 | -------------------------------------------------------------------------------- /.idea/runConfigurations/Conformance_Tests.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | node 4 | 5 | $PROJECT_DIR$/node_modules/mocha 6 | $PROJECT_DIR$ 7 | true 8 | 9 | 10 | 11 | bdd 12 | --require ts-node/register/type-check --no-cache --no-timeout 13 | TEST_FILE 14 | $PROJECT_DIR$/dev/conformance/runner.ts 15 | 16 | 17 | -------------------------------------------------------------------------------- /.idea/runConfigurations/System_Test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | node 4 | 5 | $PROJECT_DIR$/node_modules/mocha 6 | $PROJECT_DIR$ 7 | true 8 | 9 | 10 | 11 | bdd 12 | --require ts-node/register/type-check --no-cache --timeout 60000 13 | PATTERN 14 | $PROJECT_DIR$/dev/system-test/*.js $PROJECT_DIR$/dev/system-test/*.ts 15 | 16 | 17 | -------------------------------------------------------------------------------- /.idea/runConfigurations/Unit_Tests.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | node 4 | 5 | $PROJECT_DIR$/node_modules/mocha 6 | $PROJECT_DIR$/dev 7 | true 8 | 9 | 10 | 11 | bdd 12 | --require ts-node/register/type-check --no-cache --no-timeout 13 | PATTERN 14 | $PROJECT_DIR$/dev/test/*.js $PROJECT_DIR$/dev/test/*.ts 15 | 16 | 17 | -------------------------------------------------------------------------------- /.kokoro/.gitattributes: -------------------------------------------------------------------------------- 1 | * linguist-generated=true 2 | -------------------------------------------------------------------------------- /.kokoro/common.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Build logs will be here 4 | action { 5 | define_artifacts { 6 | regex: "**/*sponge_log.xml" 7 | } 8 | } 9 | 10 | # Download trampoline resources. 11 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" 12 | 13 | # Use the trampoline script to run in docker. 14 | build_file: "nodejs-firestore/.kokoro/trampoline.sh" 15 | 16 | # Configure the docker image for kokoro-trampoline. 17 | env_vars: { 18 | key: "TRAMPOLINE_IMAGE" 19 | value: "gcr.io/cloud-devrel-kokoro-resources/node:14-user" 20 | } 21 | env_vars: { 22 | key: "TRAMPOLINE_BUILD_FILE" 23 | value: "github/nodejs-firestore/.kokoro/test.sh" 24 | } 25 | -------------------------------------------------------------------------------- /.kokoro/continuous/node14/common.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Build logs will be here 4 | action { 5 | define_artifacts { 6 | regex: "**/*sponge_log.xml" 7 | } 8 | } 9 | 10 | # Download trampoline resources. 11 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" 12 | 13 | # Use the trampoline script to run in docker. 14 | build_file: "nodejs-firestore/.kokoro/trampoline.sh" 15 | 16 | # Configure the docker image for kokoro-trampoline. 17 | env_vars: { 18 | key: "TRAMPOLINE_IMAGE" 19 | value: "gcr.io/cloud-devrel-kokoro-resources/node:14-user" 20 | } 21 | env_vars: { 22 | key: "TRAMPOLINE_BUILD_FILE" 23 | value: "github/nodejs-firestore/.kokoro/test.sh" 24 | } 25 | -------------------------------------------------------------------------------- /.kokoro/continuous/node14/lint.cfg: -------------------------------------------------------------------------------- 1 | env_vars: { 2 | key: "TRAMPOLINE_BUILD_FILE" 3 | value: "github/nodejs-firestore/.kokoro/lint.sh" 4 | } 5 | -------------------------------------------------------------------------------- /.kokoro/continuous/node14/samples-test.cfg: -------------------------------------------------------------------------------- 1 | # Download resources for system tests (service account key, etc.) 2 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/google-cloud-nodejs" 3 | 4 | env_vars: { 5 | key: "TRAMPOLINE_BUILD_FILE" 6 | value: "github/nodejs-firestore/.kokoro/samples-test.sh" 7 | } 8 | 9 | env_vars: { 10 | key: "SECRET_MANAGER_KEYS" 11 | value: "nodejs-firestore-ci-samples-71b5f8aee66e" 12 | } 13 | -------------------------------------------------------------------------------- /.kokoro/continuous/node14/system-test.cfg: -------------------------------------------------------------------------------- 1 | # Download resources for system tests (service account key, etc.) 2 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/google-cloud-nodejs" 3 | 4 | env_vars: { 5 | key: "TRAMPOLINE_BUILD_FILE" 6 | value: "github/nodejs-firestore/.kokoro/system-test.sh" 7 | } 8 | 9 | env_vars: { 10 | key: "SECRET_MANAGER_KEYS" 11 | value: "java-review_firestore-nodejs-it-6d41b624fec9" 12 | } 13 | -------------------------------------------------------------------------------- /.kokoro/continuous/node14/test.cfg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/googleapis/nodejs-firestore/3955811061106db04f56919262b3f97408296592/.kokoro/continuous/node14/test.cfg -------------------------------------------------------------------------------- /.kokoro/docs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2018 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -eo pipefail 18 | 19 | export NPM_CONFIG_PREFIX=/home/node/.npm-global 20 | 21 | cd $(dirname $0)/.. 22 | 23 | npm install 24 | 25 | npm run docs-test 26 | -------------------------------------------------------------------------------- /.kokoro/lint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2018 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -eo pipefail 18 | 19 | export NPM_CONFIG_PREFIX=/home/node/.npm-global 20 | 21 | cd $(dirname $0)/.. 22 | 23 | npm install 24 | 25 | # Install and link samples 26 | if [ -f samples/package.json ]; then 27 | cd samples/ 28 | npm link ../ 29 | npm install 30 | cd .. 31 | fi 32 | 33 | npm run lint 34 | -------------------------------------------------------------------------------- /.kokoro/pre-samples-test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2018 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | export GCLOUD_PROJECT=nodejs-firestore-ci 18 | export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/secret_manager/nodejs-firestore-ci-samples-71b5f8aee66e 19 | -------------------------------------------------------------------------------- /.kokoro/pre-system-test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2018 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | export GCLOUD_PROJECT=java-review 18 | export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/secret_manager/java-review_firestore-nodejs-it-6d41b624fec9 19 | -------------------------------------------------------------------------------- /.kokoro/presubmit/node14/common.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Build logs will be here 4 | action { 5 | define_artifacts { 6 | regex: "**/*sponge_log.xml" 7 | } 8 | } 9 | 10 | # Download trampoline resources. 11 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" 12 | 13 | # Use the trampoline script to run in docker. 14 | build_file: "nodejs-firestore/.kokoro/trampoline.sh" 15 | 16 | # Configure the docker image for kokoro-trampoline. 17 | env_vars: { 18 | key: "TRAMPOLINE_IMAGE" 19 | value: "gcr.io/cloud-devrel-kokoro-resources/node:14-user" 20 | } 21 | env_vars: { 22 | key: "TRAMPOLINE_BUILD_FILE" 23 | value: "github/nodejs-firestore/.kokoro/test.sh" 24 | } 25 | -------------------------------------------------------------------------------- /.kokoro/presubmit/node14/samples-test.cfg: -------------------------------------------------------------------------------- 1 | # Download resources for system tests (service account key, etc.) 2 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/google-cloud-nodejs" 3 | 4 | env_vars: { 5 | key: "TRAMPOLINE_BUILD_FILE" 6 | value: "github/nodejs-firestore/.kokoro/samples-test.sh" 7 | } 8 | 9 | env_vars: { 10 | key: "SECRET_MANAGER_KEYS" 11 | value: "nodejs-firestore-ci-samples-71b5f8aee66e" 12 | } 13 | -------------------------------------------------------------------------------- /.kokoro/presubmit/node14/system-test.cfg: -------------------------------------------------------------------------------- 1 | # Download resources for system tests (service account key, etc.) 2 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/google-cloud-nodejs" 3 | 4 | env_vars: { 5 | key: "TRAMPOLINE_BUILD_FILE" 6 | value: "github/nodejs-firestore/.kokoro/system-test.sh" 7 | } 8 | 9 | env_vars: { 10 | key: "SECRET_MANAGER_KEYS" 11 | value: "java-review_firestore-nodejs-it-6d41b624fec9" 12 | } 13 | -------------------------------------------------------------------------------- /.kokoro/presubmit/node14/test.cfg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/googleapis/nodejs-firestore/3955811061106db04f56919262b3f97408296592/.kokoro/presubmit/node14/test.cfg -------------------------------------------------------------------------------- /.kokoro/presubmit/windows/common.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | -------------------------------------------------------------------------------- /.kokoro/presubmit/windows/test.cfg: -------------------------------------------------------------------------------- 1 | # Use the test file directly 2 | build_file: "nodejs-firestore/.kokoro/test.bat" 3 | -------------------------------------------------------------------------------- /.kokoro/publish.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2018 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -eo pipefail 18 | 19 | export NPM_CONFIG_PREFIX=/home/node/.npm-global 20 | 21 | # Start the releasetool reporter 22 | python3 -m pip install gcp-releasetool 23 | python3 -m releasetool publish-reporter-script > /tmp/publisher-script; source /tmp/publisher-script 24 | 25 | cd $(dirname $0)/.. 26 | 27 | NPM_TOKEN=$(cat $KOKORO_KEYSTORE_DIR/73713_google-cloud-npm-token-1) 28 | echo "//wombat-dressing-room.appspot.com/:_authToken=${NPM_TOKEN}" > ~/.npmrc 29 | 30 | npm install 31 | npm publish --access=public --registry=https://wombat-dressing-room.appspot.com 32 | -------------------------------------------------------------------------------- /.kokoro/release/common.cfg: -------------------------------------------------------------------------------- 1 | before_action { 2 | fetch_keystore { 3 | keystore_resource { 4 | keystore_config_id: 73713 5 | keyname: "yoshi-automation-github-key" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /.kokoro/release/docs-devsite.cfg: -------------------------------------------------------------------------------- 1 | # service account used to publish up-to-date docs. 2 | before_action { 3 | fetch_keystore { 4 | keystore_resource { 5 | keystore_config_id: 73713 6 | keyname: "docuploader_service_account" 7 | } 8 | } 9 | } 10 | 11 | # doc publications use a Python image. 12 | env_vars: { 13 | key: "TRAMPOLINE_IMAGE" 14 | value: "gcr.io/cloud-devrel-kokoro-resources/node:14-user" 15 | } 16 | 17 | # Download trampoline resources. 18 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" 19 | 20 | # Use the trampoline script to run in docker. 21 | build_file: "nodejs-firestore/.kokoro/trampoline.sh" 22 | 23 | env_vars: { 24 | key: "TRAMPOLINE_BUILD_FILE" 25 | value: "github/nodejs-firestore/.kokoro/release/docs-devsite.sh" 26 | } 27 | -------------------------------------------------------------------------------- /.kokoro/release/docs-devsite.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2021 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -eo pipefail 18 | 19 | if [[ -z "$CREDENTIALS" ]]; then 20 | # if CREDENTIALS are explicitly set, assume we're testing locally 21 | # and don't set NPM_CONFIG_PREFIX. 22 | export NPM_CONFIG_PREFIX=${HOME}/.npm-global 23 | export PATH="$PATH:${NPM_CONFIG_PREFIX}/bin" 24 | cd $(dirname $0)/../.. 25 | fi 26 | 27 | npm install 28 | npm install --no-save @google-cloud/cloud-rad@^0.4.0 29 | npx @google-cloud/cloud-rad 30 | -------------------------------------------------------------------------------- /.kokoro/release/docs.cfg: -------------------------------------------------------------------------------- 1 | # service account used to publish up-to-date docs. 2 | before_action { 3 | fetch_keystore { 4 | keystore_resource { 5 | keystore_config_id: 73713 6 | keyname: "docuploader_service_account" 7 | } 8 | } 9 | } 10 | 11 | # doc publications use a Python image. 12 | env_vars: { 13 | key: "TRAMPOLINE_IMAGE" 14 | value: "gcr.io/cloud-devrel-kokoro-resources/node:14-user" 15 | } 16 | 17 | # Download trampoline resources. 18 | gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" 19 | 20 | # Use the trampoline script to run in docker. 21 | build_file: "nodejs-firestore/.kokoro/trampoline.sh" 22 | 23 | env_vars: { 24 | key: "TRAMPOLINE_BUILD_FILE" 25 | value: "github/nodejs-firestore/.kokoro/release/docs.sh" 26 | } 27 | -------------------------------------------------------------------------------- /.kokoro/test.bat: -------------------------------------------------------------------------------- 1 | @rem Copyright 2018 Google LLC. All rights reserved. 2 | @rem 3 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 4 | @rem you may not use this file except in compliance with the License. 5 | @rem You may obtain a copy of the License at 6 | @rem 7 | @rem http://www.apache.org/licenses/LICENSE-2.0 8 | @rem 9 | @rem Unless required by applicable law or agreed to in writing, software 10 | @rem distributed under the License is distributed on an "AS IS" BASIS, 11 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | @rem See the License for the specific language governing permissions and 13 | @rem limitations under the License. 14 | 15 | @echo "Starting Windows build" 16 | 17 | cd /d %~dp0 18 | cd .. 19 | 20 | @rem npm path is not currently set in our image, we should fix this next time 21 | @rem we upgrade Node.js in the image: 22 | SET PATH=%PATH%;/cygdrive/c/Program Files/nodejs/npm 23 | 24 | call nvm use v12.14.1 25 | call which node 26 | 27 | call npm install || goto :error 28 | call npm run test || goto :error 29 | 30 | goto :EOF 31 | 32 | :error 33 | exit /b 1 34 | -------------------------------------------------------------------------------- /.kokoro/trampoline.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2017 Google Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | set -eo pipefail 17 | 18 | # Always run the cleanup script, regardless of the success of bouncing into 19 | # the container. 20 | function cleanup() { 21 | chmod +x ${KOKORO_GFILE_DIR}/trampoline_cleanup.sh 22 | ${KOKORO_GFILE_DIR}/trampoline_cleanup.sh 23 | echo "cleanup"; 24 | } 25 | trap cleanup EXIT 26 | 27 | $(dirname $0)/populate-secrets.sh # Secret Manager secrets. 28 | python3 "${KOKORO_GFILE_DIR}/trampoline_v1.py" 29 | -------------------------------------------------------------------------------- /.mocharc.js: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | const config = { 15 | "enable-source-maps": true, 16 | "throw-deprecation": true, 17 | "timeout": 10000, 18 | "recursive": true 19 | } 20 | if (process.env.MOCHA_THROW_DEPRECATION === 'false') { 21 | delete config['throw-deprecation']; 22 | } 23 | if (process.env.MOCHA_REPORTER) { 24 | config.reporter = process.env.MOCHA_REPORTER; 25 | } 26 | if (process.env.MOCHA_REPORTER_OUTPUT) { 27 | config['reporter-option'] = `output=${process.env.MOCHA_REPORTER_OUTPUT}`; 28 | } 29 | module.exports = config 30 | -------------------------------------------------------------------------------- /.nycrc: -------------------------------------------------------------------------------- 1 | { 2 | "report-dir": "./.coverage", 3 | "reporter": ["text", "lcov"], 4 | "exclude": [ 5 | "**/*-test", 6 | "**/.coverage", 7 | "**/apis", 8 | "**/benchmark", 9 | "**/conformance", 10 | "**/docs", 11 | "**/samples", 12 | "**/scripts", 13 | "**/protos", 14 | "**/test", 15 | "**/*.d.ts", 16 | ".jsdoc.js", 17 | "**/.jsdoc.js", 18 | "karma.conf.js", 19 | "webpack-tests.config.js", 20 | "webpack.config.js" 21 | ], 22 | "exclude-after-remap": false, 23 | "all": true 24 | } 25 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | **/node_modules 2 | **/coverage 3 | test/fixtures 4 | build/ 5 | docs/ 6 | protos/ 7 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | module.exports = { 16 | ...require('gts/.prettierrc.json') 17 | } 18 | -------------------------------------------------------------------------------- /.readme-partials.yaml: -------------------------------------------------------------------------------- 1 | introduction: |- 2 | This is the Node.js Server SDK for [Google Cloud Firestore](https://firebase.google.com/docs/firestore/). Google Cloud Firestore is a NoSQL document database built for automatic scaling, high performance, and ease of application development. 3 | 4 | This Cloud Firestore Server SDK uses Google’s Cloud Identity and Access Management for authentication and should only be used in trusted environments. Your Cloud Identity credentials allow you bypass all access restrictions and provide read and write access to all data in your Cloud Firestore project. 5 | 6 | The Cloud Firestore Server SDKs are designed to manage the full set of data in your Cloud Firestore project and work best with reliable network connectivity. Data operations performed via these SDKs directly access the Cloud Firestore backend and all document reads and writes are optimized for high throughput. 7 | 8 | Applications that use Google's Server SDKs should not be used in end-user environments, such as on phones or on publicly hosted websites. If you are developing a Web or Node.js application that accesses Cloud Firestore on behalf of end users, use the firebase Client SDK. 9 | 10 | **Note:** This Cloud Firestore Server SDK does not support Firestore databases created in [Datastore mode](https://cloud.google.com/datastore/docs/firestore-or-datastore#in_datastore_mode). To access these databases, use the [Datastore SDK](https://www.npmjs.com/package/@google-cloud/datastore). 11 | -------------------------------------------------------------------------------- /.repo-metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "codeowner_team": "@googleapis/firestore-dpe", 3 | "language": "nodejs", 4 | "api_id": "firestore.googleapis.com", 5 | "name_pretty": "Cloud Firestore", 6 | "requires_billing ": false, 7 | "default_version": "v1", 8 | "product_documentation": "https://cloud.google.com/firestore", 9 | "name": "firestore", 10 | "issue_tracker": "https://issuetracker.google.com/savedsearches/5337669", 11 | "distribution_name": "@google-cloud/firestore", 12 | "repo": "googleapis/nodejs-firestore", 13 | "client_documentation": "https://cloud.google.com/nodejs/docs/reference/firestore/latest", 14 | "release_level": "stable", 15 | "api_shortname": "firestore", 16 | "library_type": "GAPIC_COMBO" 17 | } 18 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | To report a security issue, please use [g.co/vulnz](https://g.co/vulnz). 4 | 5 | The Google Security Team will respond within 5 working days of your report on g.co/vulnz. 6 | 7 | We use g.co/vulnz for our intake, and do coordination and disclosure here using GitHub Security Advisory to privately discuss and fix the issue. 8 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/create-arrayremove-noarray-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "create: ArrayRemove cannot be anywhere inside an array value", 5 | "comment": "There cannot be an array value anywhere on the path from the document\nroot to the ArrayRemove. Firestore transforms don't support array indexing.", 6 | "create": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, {\"b\": [\"ArrayRemove\", 1, 2, 3]}]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/create-arrayremove-noarray.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "create: ArrayRemove cannot be in an array value", 5 | "comment": "ArrayRemove must be the value of a field. Firestore\ntransforms don't support array indexing.", 6 | "create": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, 2, [\"ArrayRemove\", 1, 2, 3]]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/create-arrayremove-with-st.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "create: The ServerTimestamp sentinel cannot be in an ArrayUnion", 5 | "comment": "The ServerTimestamp sentinel must be the value of a field. It may\nnot appear in an ArrayUnion.", 6 | "create": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [\"ArrayRemove\", 1, \"ServerTimestamp\", 3]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/create-arrayunion-noarray-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "create: ArrayUnion cannot be anywhere inside an array value", 5 | "comment": "There cannot be an array value anywhere on the path from the document\nroot to the ArrayUnion. Firestore transforms don't support array indexing.", 6 | "create": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, {\"b\": [\"ArrayUnion\", 1, 2, 3]}]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/create-arrayunion-noarray.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "create: ArrayUnion cannot be in an array value", 5 | "comment": "ArrayUnion must be the value of a field. Firestore\ntransforms don't support array indexing.", 6 | "create": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, 2, [\"ArrayRemove\", 1, 2, 3]]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/create-arrayunion-with-st.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "create: The ServerTimestamp sentinel cannot be in an ArrayUnion", 5 | "comment": "The ServerTimestamp sentinel must be the value of a field. It may\nnot appear in an ArrayUnion.", 6 | "create": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [\"ArrayUnion\", 1, \"ServerTimestamp\", 3]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/create-basic.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "create: basic", 5 | "comment": "A simple call, resulting in a single update operation.", 6 | "create": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": 1}", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "update": { 14 | "name": "projects/projectID/databases/(default)/documents/C/d", 15 | "fields": { 16 | "a": { 17 | "integerValue": "1" 18 | } 19 | } 20 | }, 21 | "currentDocument": { 22 | "exists": false 23 | } 24 | } 25 | ] 26 | } 27 | } 28 | } 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/create-del-noarray-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "create: Delete cannot be anywhere inside an array value", 5 | "comment": "The Delete sentinel must be the value of a field. Deletes are implemented\nby turning the path to the Delete sentinel into a FieldPath, and FieldPaths do not support\narray indexing.", 6 | "create": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, {\"b\": \"Delete\"}]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/create-del-noarray.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "create: Delete cannot be in an array value", 5 | "comment": "The Delete sentinel must be the value of a field. Deletes are\nimplemented by turning the path to the Delete sentinel into a FieldPath, and FieldPaths\ndo not support array indexing.", 6 | "create": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, 2, \"Delete\"]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/create-empty.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "create: creating or setting an empty map", 5 | "create": { 6 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 7 | "jsonData": "{}", 8 | "request": { 9 | "database": "projects/projectID/databases/(default)", 10 | "writes": [ 11 | { 12 | "update": { 13 | "name": "projects/projectID/databases/(default)/documents/C/d", 14 | "fields": {} 15 | }, 16 | "currentDocument": { 17 | "exists": false 18 | } 19 | } 20 | ] 21 | } 22 | } 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/create-nodel.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "create: Delete cannot appear in data", 5 | "comment": "The Delete sentinel cannot be used in Create, or in Set without a Merge option.", 6 | "create": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": 1, \"b\": \"Delete\"}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/create-nosplit.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "create: don’t split on dots", 5 | "comment": "Create and Set treat their map keys literally. They do not split on dots.", 6 | "create": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{ \"a.b\": { \"c.d\": 1 }, \"e\": 2 }", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "update": { 14 | "name": "projects/projectID/databases/(default)/documents/C/d", 15 | "fields": { 16 | "a.b": { 17 | "mapValue": { 18 | "fields": { 19 | "c.d": { 20 | "integerValue": "1" 21 | } 22 | } 23 | } 24 | }, 25 | "e": { 26 | "integerValue": "2" 27 | } 28 | } 29 | }, 30 | "currentDocument": { 31 | "exists": false 32 | } 33 | } 34 | ] 35 | } 36 | } 37 | } 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/create-special-chars.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "create: non-alpha characters in map keys", 5 | "comment": "Create and Set treat their map keys literally. They do not escape special characters.", 6 | "create": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{ \"*\": { \".\": 1 }, \"~\": 2 }", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "update": { 14 | "name": "projects/projectID/databases/(default)/documents/C/d", 15 | "fields": { 16 | "*": { 17 | "mapValue": { 18 | "fields": { 19 | ".": { 20 | "integerValue": "1" 21 | } 22 | } 23 | } 24 | }, 25 | "~": { 26 | "integerValue": "2" 27 | } 28 | } 29 | }, 30 | "currentDocument": { 31 | "exists": false 32 | } 33 | } 34 | ] 35 | } 36 | } 37 | } 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/create-st-alone.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "create: ServerTimestamp alone", 5 | "comment": "If the only values in the input are ServerTimestamps, then no\nupdate operation should be produced.", 6 | "create": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": \"ServerTimestamp\"}", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "currentDocument": { 14 | "exists": false 15 | }, 16 | "update": { 17 | "fields": {}, 18 | "name": "projects/projectID/databases/(default)/documents/C/d" 19 | }, 20 | "updateTransforms": [ 21 | { 22 | "fieldPath": "a", 23 | "setToServerValue": "REQUEST_TIME" 24 | } 25 | ] 26 | } 27 | ] 28 | } 29 | } 30 | } 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/create-st-multi.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "create: multiple ServerTimestamp fields", 5 | "comment": "A document can have more than one ServerTimestamp field.\nSince all the ServerTimestamp fields are removed, the only field in the update is \"a\".", 6 | "create": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": 1, \"b\": \"ServerTimestamp\", \"c\": {\"d\": \"ServerTimestamp\"}}", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "update": { 14 | "name": "projects/projectID/databases/(default)/documents/C/d", 15 | "fields": { 16 | "a": { 17 | "integerValue": "1" 18 | } 19 | } 20 | }, 21 | "currentDocument": { 22 | "exists": false 23 | }, 24 | "updateTransforms": [ 25 | { 26 | "fieldPath": "b", 27 | "setToServerValue": "REQUEST_TIME" 28 | }, 29 | { 30 | "fieldPath": "c.d", 31 | "setToServerValue": "REQUEST_TIME" 32 | } 33 | ] 34 | } 35 | ] 36 | } 37 | } 38 | } 39 | ] 40 | } 41 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/create-st-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "create: nested ServerTimestamp field", 5 | "comment": "A ServerTimestamp value can occur at any depth. In this case,\nthe transform applies to the field path \"b.c\". Since \"c\" is removed from the update,\n\"b\" becomes empty, so it is also removed from the update.", 6 | "create": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": 1, \"b\": {\"c\": \"ServerTimestamp\"}}", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "update": { 14 | "name": "projects/projectID/databases/(default)/documents/C/d", 15 | "fields": { 16 | "a": { 17 | "integerValue": "1" 18 | } 19 | } 20 | }, 21 | "currentDocument": { 22 | "exists": false 23 | }, 24 | "updateTransforms": [ 25 | { 26 | "fieldPath": "b.c", 27 | "setToServerValue": "REQUEST_TIME" 28 | } 29 | ] 30 | } 31 | ] 32 | } 33 | } 34 | } 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/create-st-noarray-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "create: ServerTimestamp cannot be anywhere inside an array value", 5 | "comment": "There cannot be an array value anywhere on the path from the document\nroot to the ServerTimestamp sentinel. Firestore transforms don't support array indexing.", 6 | "create": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, {\"b\": \"ServerTimestamp\"}]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/create-st-noarray.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "create: ServerTimestamp cannot be in an array value", 5 | "comment": "The ServerTimestamp sentinel must be the value of a field. Firestore\ntransforms don't support array indexing.", 6 | "create": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, 2, \"ServerTimestamp\"]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/create-st-with-empty-map.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "create: ServerTimestamp beside an empty map", 5 | "comment": "When a ServerTimestamp and a map both reside inside a map, the\nServerTimestamp should be stripped out but the empty map should remain.", 6 | "create": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": {\"b\": {}, \"c\": \"ServerTimestamp\"}}", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "update": { 14 | "name": "projects/projectID/databases/(default)/documents/C/d", 15 | "fields": { 16 | "a": { 17 | "mapValue": { 18 | "fields": { 19 | "b": { 20 | "mapValue": { 21 | "fields": {} 22 | } 23 | } 24 | } 25 | } 26 | } 27 | } 28 | }, 29 | "currentDocument": { 30 | "exists": false 31 | }, 32 | "updateTransforms": [ 33 | { 34 | "fieldPath": "a.c", 35 | "setToServerValue": "REQUEST_TIME" 36 | } 37 | ] 38 | } 39 | ] 40 | } 41 | } 42 | } 43 | ] 44 | } 45 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/create-st.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "create: ServerTimestamp with data", 5 | "comment": "A key with the special ServerTimestamp sentinel is removed from\nthe data in the update operation. Instead it appears in a separate Transform operation.\nNote that in these tests, the string \"ServerTimestamp\" should be replaced with the\nspecial ServerTimestamp value.", 6 | "create": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": 1, \"b\": \"ServerTimestamp\"}", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "update": { 14 | "name": "projects/projectID/databases/(default)/documents/C/d", 15 | "fields": { 16 | "a": { 17 | "integerValue": "1" 18 | } 19 | } 20 | }, 21 | "currentDocument": { 22 | "exists": false 23 | }, 24 | "updateTransforms": [ 25 | { 26 | "fieldPath": "b", 27 | "setToServerValue": "REQUEST_TIME" 28 | } 29 | ] 30 | } 31 | ] 32 | } 33 | } 34 | } 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/delete-exists-precond.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "delete: delete with exists precondition", 5 | "comment": "Delete supports an exists precondition.", 6 | "delete": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "precondition": { 9 | "exists": true 10 | }, 11 | "request": { 12 | "database": "projects/projectID/databases/(default)", 13 | "writes": [ 14 | { 15 | "delete": "projects/projectID/databases/(default)/documents/C/d", 16 | "currentDocument": { 17 | "exists": true 18 | } 19 | } 20 | ] 21 | } 22 | } 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/delete-no-precond.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "delete: delete without precondition", 5 | "comment": "An ordinary Delete call.", 6 | "delete": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "request": { 9 | "database": "projects/projectID/databases/(default)", 10 | "writes": [ 11 | { 12 | "delete": "projects/projectID/databases/(default)/documents/C/d" 13 | } 14 | ] 15 | } 16 | } 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/delete-time-precond.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "delete: delete with last-update-time precondition", 5 | "comment": "Delete supports a last-update-time precondition.", 6 | "delete": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "precondition": { 9 | "updateTime": "1970-01-01T00:00:42Z" 10 | }, 11 | "request": { 12 | "database": "projects/projectID/databases/(default)", 13 | "writes": [ 14 | { 15 | "delete": "projects/projectID/databases/(default)/documents/C/d", 16 | "currentDocument": { 17 | "updateTime": "1970-01-01T00:00:42Z" 18 | } 19 | } 20 | ] 21 | } 22 | } 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/get-basic.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "get: get a document", 5 | "comment": "A call to DocumentRef.Get", 6 | "get": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "request": { 9 | "name": "projects/projectID/databases/(default)/documents/C/d" 10 | } 11 | } 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/listen-empty.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "listen: no changes; empty snapshot", 5 | "comment": "There are no changes, so the snapshot should be empty.", 6 | "listen": { 7 | "responses": [ 8 | { 9 | "targetChange": { 10 | "targetChangeType": "CURRENT" 11 | } 12 | }, 13 | { 14 | "targetChange": { 15 | "readTime": "1970-01-01T00:00:01Z" 16 | } 17 | } 18 | ], 19 | "snapshots": [ 20 | { 21 | "readTime": "1970-01-01T00:00:01Z" 22 | } 23 | ] 24 | } 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/listen-target-add-wrong-id.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "listen: TargetChange_ADD is an error if it has a different target ID", 5 | "comment": "A TargetChange_ADD response must have the same watch target ID.", 6 | "listen": { 7 | "responses": [ 8 | { 9 | "documentChange": { 10 | "document": { 11 | "name": "projects/projectID/databases/(default)/documents/C/d1", 12 | "fields": { 13 | "a": { 14 | "integerValue": "3" 15 | } 16 | }, 17 | "createTime": "1970-01-01T00:00:01Z", 18 | "updateTime": "1970-01-01T00:00:01Z" 19 | }, 20 | "targetIds": [ 21 | 1 22 | ] 23 | } 24 | }, 25 | { 26 | "targetChange": { 27 | "targetChangeType": "CURRENT" 28 | } 29 | }, 30 | { 31 | "targetChange": { 32 | "targetChangeType": "ADD", 33 | "targetIds": [ 34 | 2 35 | ], 36 | "readTime": "1970-01-01T00:00:02Z" 37 | } 38 | }, 39 | { 40 | "targetChange": { 41 | "readTime": "1970-01-01T00:00:01Z" 42 | } 43 | } 44 | ], 45 | "isError": true 46 | } 47 | } 48 | ] 49 | } 50 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/listen-target-remove.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "listen: TargetChange_REMOVE should not appear", 5 | "comment": "A TargetChange_REMOVE response should never be sent.", 6 | "listen": { 7 | "responses": [ 8 | { 9 | "documentChange": { 10 | "document": { 11 | "name": "projects/projectID/databases/(default)/documents/C/d1", 12 | "fields": { 13 | "a": { 14 | "integerValue": "3" 15 | } 16 | }, 17 | "createTime": "1970-01-01T00:00:01Z", 18 | "updateTime": "1970-01-01T00:00:01Z" 19 | }, 20 | "targetIds": [ 21 | 1 22 | ] 23 | } 24 | }, 25 | { 26 | "targetChange": { 27 | "targetChangeType": "CURRENT" 28 | } 29 | }, 30 | { 31 | "targetChange": { 32 | "targetChangeType": "REMOVE" 33 | } 34 | }, 35 | { 36 | "targetChange": { 37 | "readTime": "1970-01-01T00:00:01Z" 38 | } 39 | } 40 | ], 41 | "isError": true 42 | } 43 | } 44 | ] 45 | } 46 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/query-arrayremove-cursor.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: ArrayRemove in cursor method", 5 | "comment": "ArrayRemove is not permitted in queries.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "orderBy": { 11 | "path": { 12 | "field": [ 13 | "a" 14 | ] 15 | }, 16 | "direction": "asc" 17 | } 18 | }, 19 | { 20 | "endBefore": { 21 | "jsonValues": [ 22 | "[\"ArrayRemove\", 1, 2, 3]" 23 | ] 24 | } 25 | } 26 | ], 27 | "isError": true 28 | } 29 | } 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/query-arrayremove-where.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: ArrayRemove in Where", 5 | "comment": "ArrayRemove is not permitted in queries.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "where": { 11 | "path": { 12 | "field": [ 13 | "a" 14 | ] 15 | }, 16 | "op": "==", 17 | "jsonValue": "[\"ArrayRemove\", 1, 2, 3]" 18 | } 19 | } 20 | ], 21 | "isError": true 22 | } 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/query-arrayunion-cursor.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: ArrayUnion in cursor method", 5 | "comment": "ArrayUnion is not permitted in queries.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "orderBy": { 11 | "path": { 12 | "field": [ 13 | "a" 14 | ] 15 | }, 16 | "direction": "asc" 17 | } 18 | }, 19 | { 20 | "endBefore": { 21 | "jsonValues": [ 22 | "[\"ArrayUnion\", 1, 2, 3]" 23 | ] 24 | } 25 | } 26 | ], 27 | "isError": true 28 | } 29 | } 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/query-arrayunion-where.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: ArrayUnion in Where", 5 | "comment": "ArrayUnion is not permitted in queries.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "where": { 11 | "path": { 12 | "field": [ 13 | "a" 14 | ] 15 | }, 16 | "op": "==", 17 | "jsonValue": "[\"ArrayUnion\", 1, 2, 3]" 18 | } 19 | } 20 | ], 21 | "isError": true 22 | } 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/query-bad-NaN.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: where clause with non-== comparison with NaN", 5 | "comment": "You can only compare NaN for equality.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "where": { 11 | "path": { 12 | "field": [ 13 | "a" 14 | ] 15 | }, 16 | "op": "\u003c", 17 | "jsonValue": "\"NaN\"" 18 | } 19 | } 20 | ], 21 | "isError": true 22 | } 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/query-bad-null.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: where clause with non-== comparison with Null", 5 | "comment": "You can only compare Null for equality.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "where": { 11 | "path": { 12 | "field": [ 13 | "a" 14 | ] 15 | }, 16 | "op": "\u003e", 17 | "jsonValue": "null" 18 | } 19 | } 20 | ], 21 | "isError": true 22 | } 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/query-cursor-docsnap.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: cursor methods with a document snapshot", 5 | "comment": "When a document snapshot is used, the client appends a __name__ order-by clause.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "startAt": { 11 | "docSnapshot": { 12 | "path": "projects/projectID/databases/(default)/documents/C/D", 13 | "jsonData": "{\"a\": 7, \"b\": 8}" 14 | } 15 | } 16 | } 17 | ], 18 | "query": { 19 | "from": [ 20 | { 21 | "collectionId": "C" 22 | } 23 | ], 24 | "orderBy": [ 25 | { 26 | "field": { 27 | "fieldPath": "__name__" 28 | }, 29 | "direction": "ASCENDING" 30 | } 31 | ], 32 | "startAt": { 33 | "values": [ 34 | { 35 | "referenceValue": "projects/projectID/databases/(default)/documents/C/D" 36 | } 37 | ], 38 | "before": true 39 | } 40 | } 41 | } 42 | } 43 | ] 44 | } 45 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/query-cursor-endbefore-empty-map.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: EndBefore with explicit empty map", 5 | "comment": "Cursor methods are allowed to use empty maps with EndBefore. It should result in an empty map in the query.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "orderBy": { 11 | "path": { 12 | "field": [ 13 | "a" 14 | ] 15 | }, 16 | "direction": "asc" 17 | } 18 | }, 19 | { 20 | "endBefore": { 21 | "jsonValues": [ 22 | "{}" 23 | ] 24 | } 25 | } 26 | ], 27 | "query": { 28 | "from": [ 29 | { 30 | "collectionId": "C" 31 | } 32 | ], 33 | "orderBy": [ 34 | { 35 | "field": { 36 | "fieldPath": "a" 37 | }, 38 | "direction": "ASCENDING" 39 | } 40 | ], 41 | "endAt": { 42 | "values": [ 43 | { 44 | "mapValue": { 45 | "fields": {} 46 | } 47 | } 48 | ], 49 | "before": true 50 | } 51 | } 52 | } 53 | } 54 | ] 55 | } 56 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/query-cursor-endbefore-empty.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: EndBefore with empty values", 5 | "comment": "Cursor methods are not allowed to use empty values with EndBefore. It should result in an error.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "orderBy": { 11 | "path": { 12 | "field": [ 13 | "a" 14 | ] 15 | }, 16 | "direction": "asc" 17 | } 18 | }, 19 | { 20 | "endBefore": {} 21 | } 22 | ], 23 | "isError": true 24 | } 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/query-cursor-no-order.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: cursor method without orderBy", 5 | "comment": "If a cursor method with a list of values is provided, there must be at least as many\nexplicit orderBy clauses as values.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "startAt": { 11 | "jsonValues": [ 12 | "2" 13 | ] 14 | } 15 | } 16 | ], 17 | "isError": true 18 | } 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/query-cursor-startat-empty-map.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: StartAt with explicit empty map", 5 | "comment": "Cursor methods are allowed to use empty maps with StartAt. It should result in an empty map in the query.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "orderBy": { 11 | "path": { 12 | "field": [ 13 | "a" 14 | ] 15 | }, 16 | "direction": "asc" 17 | } 18 | }, 19 | { 20 | "startAt": { 21 | "jsonValues": [ 22 | "{}" 23 | ] 24 | } 25 | } 26 | ], 27 | "query": { 28 | "from": [ 29 | { 30 | "collectionId": "C" 31 | } 32 | ], 33 | "orderBy": [ 34 | { 35 | "field": { 36 | "fieldPath": "a" 37 | }, 38 | "direction": "ASCENDING" 39 | } 40 | ], 41 | "startAt": { 42 | "values": [ 43 | { 44 | "mapValue": { 45 | "fields": {} 46 | } 47 | } 48 | ], 49 | "before": true 50 | } 51 | } 52 | } 53 | } 54 | ] 55 | } 56 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/query-cursor-startat-empty.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: StartAt with empty values", 5 | "comment": "Cursor methods are not allowed to use empty values with StartAt. It should result in an error.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "orderBy": { 11 | "path": { 12 | "field": [ 13 | "a" 14 | ] 15 | }, 16 | "direction": "asc" 17 | } 18 | }, 19 | { 20 | "startAt": {} 21 | } 22 | ], 23 | "isError": true 24 | } 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/query-del-cursor.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: Delete in cursor method", 5 | "comment": "Sentinel values are not permitted in queries.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "orderBy": { 11 | "path": { 12 | "field": [ 13 | "a" 14 | ] 15 | }, 16 | "direction": "asc" 17 | } 18 | }, 19 | { 20 | "endBefore": { 21 | "jsonValues": [ 22 | "\"Delete\"" 23 | ] 24 | } 25 | } 26 | ], 27 | "isError": true 28 | } 29 | } 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/query-del-where.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: Delete in Where", 5 | "comment": "Sentinel values are not permitted in queries.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "where": { 11 | "path": { 12 | "field": [ 13 | "a" 14 | ] 15 | }, 16 | "op": "==", 17 | "jsonValue": "\"Delete\"" 18 | } 19 | } 20 | ], 21 | "isError": true 22 | } 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/query-invalid-operator.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: invalid operator in Where clause", 5 | "comment": "The |~| operator is not supported.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "where": { 11 | "path": { 12 | "field": [ 13 | "a" 14 | ] 15 | }, 16 | "op": "|~|", 17 | "jsonValue": "4" 18 | } 19 | } 20 | ], 21 | "isError": true 22 | } 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/query-invalid-path-order.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: invalid path in OrderBy clause", 5 | "comment": "The path has an empty component.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "orderBy": { 11 | "path": { 12 | "field": [ 13 | "*", 14 | "" 15 | ] 16 | }, 17 | "direction": "asc" 18 | } 19 | } 20 | ], 21 | "isError": true 22 | } 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/query-invalid-path-select.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: invalid path in Where clause", 5 | "comment": "The path has an empty component.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "select": { 11 | "fields": [ 12 | { 13 | "field": [ 14 | "*", 15 | "" 16 | ] 17 | } 18 | ] 19 | } 20 | } 21 | ], 22 | "isError": true 23 | } 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/query-invalid-path-where.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: invalid path in Where clause", 5 | "comment": "The path has an empty component.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "where": { 11 | "path": { 12 | "field": [ 13 | "*", 14 | "" 15 | ] 16 | }, 17 | "op": "==", 18 | "jsonValue": "4" 19 | } 20 | } 21 | ], 22 | "isError": true 23 | } 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/query-offset-limit-last-wins.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: multiple Offset and Limit clauses", 5 | "comment": "With multiple Offset or Limit clauses, the last one wins.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "offset": 2 11 | }, 12 | { 13 | "limit": 3 14 | }, 15 | { 16 | "limit": 4 17 | }, 18 | { 19 | "offset": 5 20 | } 21 | ], 22 | "query": { 23 | "from": [ 24 | { 25 | "collectionId": "C" 26 | } 27 | ], 28 | "offset": 5, 29 | "limit": 4 30 | } 31 | } 32 | } 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/query-offset-limit.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: Offset and Limit clauses", 5 | "comment": "Offset and Limit clauses.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "offset": 2 11 | }, 12 | { 13 | "limit": 3 14 | } 15 | ], 16 | "query": { 17 | "from": [ 18 | { 19 | "collectionId": "C" 20 | } 21 | ], 22 | "offset": 2, 23 | "limit": 3 24 | } 25 | } 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/query-order.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: basic OrderBy clauses", 5 | "comment": "Multiple OrderBy clauses combine.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "orderBy": { 11 | "path": { 12 | "field": [ 13 | "b" 14 | ] 15 | }, 16 | "direction": "asc" 17 | } 18 | }, 19 | { 20 | "orderBy": { 21 | "path": { 22 | "field": [ 23 | "a" 24 | ] 25 | }, 26 | "direction": "desc" 27 | } 28 | } 29 | ], 30 | "query": { 31 | "from": [ 32 | { 33 | "collectionId": "C" 34 | } 35 | ], 36 | "orderBy": [ 37 | { 38 | "field": { 39 | "fieldPath": "b" 40 | }, 41 | "direction": "ASCENDING" 42 | }, 43 | { 44 | "field": { 45 | "fieldPath": "a" 46 | }, 47 | "direction": "DESCENDING" 48 | } 49 | ] 50 | } 51 | } 52 | } 53 | ] 54 | } 55 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/query-select-empty.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: empty Select clause", 5 | "comment": "An empty Select clause selects just the document ID.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "select": { 11 | "fields": [] 12 | } 13 | } 14 | ], 15 | "query": { 16 | "select": { 17 | "fields": [ 18 | { 19 | "fieldPath": "__name__" 20 | } 21 | ] 22 | }, 23 | "from": [ 24 | { 25 | "collectionId": "C" 26 | } 27 | ] 28 | } 29 | } 30 | } 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/query-select-last-wins.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: two Select clauses", 5 | "comment": "The last Select clause is the only one used.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "select": { 11 | "fields": [ 12 | { 13 | "field": [ 14 | "a" 15 | ] 16 | }, 17 | { 18 | "field": [ 19 | "b" 20 | ] 21 | } 22 | ] 23 | } 24 | }, 25 | { 26 | "select": { 27 | "fields": [ 28 | { 29 | "field": [ 30 | "c" 31 | ] 32 | } 33 | ] 34 | } 35 | } 36 | ], 37 | "query": { 38 | "select": { 39 | "fields": [ 40 | { 41 | "fieldPath": "c" 42 | } 43 | ] 44 | }, 45 | "from": [ 46 | { 47 | "collectionId": "C" 48 | } 49 | ] 50 | } 51 | } 52 | } 53 | ] 54 | } 55 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/query-select.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: Select clause with some fields", 5 | "comment": "An ordinary Select clause.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "select": { 11 | "fields": [ 12 | { 13 | "field": [ 14 | "a" 15 | ] 16 | }, 17 | { 18 | "field": [ 19 | "b" 20 | ] 21 | } 22 | ] 23 | } 24 | } 25 | ], 26 | "query": { 27 | "select": { 28 | "fields": [ 29 | { 30 | "fieldPath": "a" 31 | }, 32 | { 33 | "fieldPath": "b" 34 | } 35 | ] 36 | }, 37 | "from": [ 38 | { 39 | "collectionId": "C" 40 | } 41 | ] 42 | } 43 | } 44 | } 45 | ] 46 | } 47 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/query-st-cursor.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: ServerTimestamp in cursor method", 5 | "comment": "Sentinel values are not permitted in queries.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "orderBy": { 11 | "path": { 12 | "field": [ 13 | "a" 14 | ] 15 | }, 16 | "direction": "asc" 17 | } 18 | }, 19 | { 20 | "endBefore": { 21 | "jsonValues": [ 22 | "\"ServerTimestamp\"" 23 | ] 24 | } 25 | } 26 | ], 27 | "isError": true 28 | } 29 | } 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/query-st-where.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: ServerTimestamp in Where", 5 | "comment": "Sentinel values are not permitted in queries.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "where": { 11 | "path": { 12 | "field": [ 13 | "a" 14 | ] 15 | }, 16 | "op": "==", 17 | "jsonValue": "\"ServerTimestamp\"" 18 | } 19 | } 20 | ], 21 | "isError": true 22 | } 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/query-where-NaN.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: a Where clause comparing to NaN", 5 | "comment": "A Where clause that tests for equality with NaN results in a unary filter.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "where": { 11 | "path": { 12 | "field": [ 13 | "a" 14 | ] 15 | }, 16 | "op": "==", 17 | "jsonValue": "\"NaN\"" 18 | } 19 | } 20 | ], 21 | "query": { 22 | "from": [ 23 | { 24 | "collectionId": "C" 25 | } 26 | ], 27 | "where": { 28 | "unaryFilter": { 29 | "op": "IS_NAN", 30 | "field": { 31 | "fieldPath": "a" 32 | } 33 | } 34 | } 35 | } 36 | } 37 | } 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/query-where-null.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: a Where clause comparing to null", 5 | "comment": "A Where clause that tests for equality with null results in a unary filter.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "where": { 11 | "path": { 12 | "field": [ 13 | "a" 14 | ] 15 | }, 16 | "op": "==", 17 | "jsonValue": "null" 18 | } 19 | } 20 | ], 21 | "query": { 22 | "from": [ 23 | { 24 | "collectionId": "C" 25 | } 26 | ], 27 | "where": { 28 | "unaryFilter": { 29 | "op": "IS_NULL", 30 | "field": { 31 | "fieldPath": "a" 32 | } 33 | } 34 | } 35 | } 36 | } 37 | } 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/query-where.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: Where clause", 5 | "comment": "A simple Where clause.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "where": { 11 | "path": { 12 | "field": [ 13 | "a" 14 | ] 15 | }, 16 | "op": "\u003e", 17 | "jsonValue": "5" 18 | } 19 | } 20 | ], 21 | "query": { 22 | "from": [ 23 | { 24 | "collectionId": "C" 25 | } 26 | ], 27 | "where": { 28 | "fieldFilter": { 29 | "field": { 30 | "fieldPath": "a" 31 | }, 32 | "op": "GREATER_THAN", 33 | "value": { 34 | "integerValue": "5" 35 | } 36 | } 37 | } 38 | } 39 | } 40 | } 41 | ] 42 | } 43 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/query-wrong-collection.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "query: doc snapshot with wrong collection in cursor method", 5 | "comment": "If a document snapshot is passed to a Start*/End* method, it must be in the\nsame collection as the query.", 6 | "query": { 7 | "collPath": "projects/projectID/databases/(default)/documents/C", 8 | "clauses": [ 9 | { 10 | "endBefore": { 11 | "docSnapshot": { 12 | "path": "projects/projectID/databases/(default)/documents/C2/D", 13 | "jsonData": "{\"a\": 7, \"b\": 8}" 14 | } 15 | } 16 | } 17 | ], 18 | "isError": true 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/set-arrayremove-noarray-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: ArrayRemove cannot be anywhere inside an array value", 5 | "comment": "There cannot be an array value anywhere on the path from the document\nroot to the ArrayRemove. Firestore transforms don't support array indexing.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, {\"b\": [\"ArrayRemove\", 1, 2, 3]}]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/set-arrayremove-noarray.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: ArrayRemove cannot be in an array value", 5 | "comment": "ArrayRemove must be the value of a field. Firestore\ntransforms don't support array indexing.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, 2, [\"ArrayRemove\", 1, 2, 3]]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/set-arrayremove-with-st.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: The ServerTimestamp sentinel cannot be in an ArrayUnion", 5 | "comment": "The ServerTimestamp sentinel must be the value of a field. It may\nnot appear in an ArrayUnion.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [\"ArrayRemove\", 1, \"ServerTimestamp\", 3]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/set-arrayremove.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: ArrayRemove with data", 5 | "comment": "A key with ArrayRemove is removed from the data in the update \noperation. Instead it appears in a separate Transform operation.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": 1, \"b\": [\"ArrayRemove\", 1, 2, 3]}", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "update": { 14 | "name": "projects/projectID/databases/(default)/documents/C/d", 15 | "fields": { 16 | "a": { 17 | "integerValue": "1" 18 | } 19 | } 20 | }, 21 | "updateTransforms": [ 22 | { 23 | "fieldPath": "b", 24 | "removeAllFromArray": { 25 | "values": [ 26 | { 27 | "integerValue": "1" 28 | }, 29 | { 30 | "integerValue": "2" 31 | }, 32 | { 33 | "integerValue": "3" 34 | } 35 | ] 36 | } 37 | } 38 | ] 39 | } 40 | ] 41 | } 42 | } 43 | } 44 | ] 45 | } 46 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/set-arrayunion-noarray-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: ArrayUnion cannot be anywhere inside an array value", 5 | "comment": "There cannot be an array value anywhere on the path from the document\nroot to the ArrayUnion. Firestore transforms don't support array indexing.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, {\"b\": [\"ArrayUnion\", 1, 2, 3]}]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/set-arrayunion-noarray.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: ArrayUnion cannot be in an array value", 5 | "comment": "ArrayUnion must be the value of a field. Firestore\ntransforms don't support array indexing.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, 2, [\"ArrayRemove\", 1, 2, 3]]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/set-arrayunion-with-st.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: The ServerTimestamp sentinel cannot be in an ArrayUnion", 5 | "comment": "The ServerTimestamp sentinel must be the value of a field. It may\nnot appear in an ArrayUnion.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [\"ArrayUnion\", 1, \"ServerTimestamp\", 3]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/set-arrayunion.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: ArrayUnion with data", 5 | "comment": "A key with ArrayUnion is removed from the data in the update \noperation. Instead it appears in a separate Transform operation.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": 1, \"b\": [\"ArrayUnion\", 1, 2, 3]}", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "update": { 14 | "name": "projects/projectID/databases/(default)/documents/C/d", 15 | "fields": { 16 | "a": { 17 | "integerValue": "1" 18 | } 19 | } 20 | }, 21 | "updateTransforms": [ 22 | { 23 | "fieldPath": "b", 24 | "appendMissingElements": { 25 | "values": [ 26 | { 27 | "integerValue": "1" 28 | }, 29 | { 30 | "integerValue": "2" 31 | }, 32 | { 33 | "integerValue": "3" 34 | } 35 | ] 36 | } 37 | } 38 | ] 39 | } 40 | ] 41 | } 42 | } 43 | } 44 | ] 45 | } 46 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/set-basic.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: basic", 5 | "comment": "A simple call, resulting in a single update operation.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": 1}", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "update": { 14 | "name": "projects/projectID/databases/(default)/documents/C/d", 15 | "fields": { 16 | "a": { 17 | "integerValue": "1" 18 | } 19 | } 20 | } 21 | } 22 | ] 23 | } 24 | } 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/set-del-merge-alone.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set-merge: Delete with merge", 5 | "comment": "A Delete sentinel can appear with a merge option. If the delete\npaths are the only ones to be merged, then no document is sent, just an update mask.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "option": { 9 | "fields": [ 10 | { 11 | "field": [ 12 | "b", 13 | "c" 14 | ] 15 | } 16 | ] 17 | }, 18 | "jsonData": "{\"a\": 1, \"b\": {\"c\": \"Delete\"}}", 19 | "request": { 20 | "database": "projects/projectID/databases/(default)", 21 | "writes": [ 22 | { 23 | "update": { 24 | "name": "projects/projectID/databases/(default)/documents/C/d" 25 | }, 26 | "updateMask": { 27 | "fieldPaths": [ 28 | "b.c" 29 | ] 30 | } 31 | } 32 | ] 33 | } 34 | } 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/set-del-merge.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set-merge: Delete with merge", 5 | "comment": "A Delete sentinel can appear with a merge option.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "option": { 9 | "fields": [ 10 | { 11 | "field": [ 12 | "a" 13 | ] 14 | }, 15 | { 16 | "field": [ 17 | "b", 18 | "c" 19 | ] 20 | } 21 | ] 22 | }, 23 | "jsonData": "{\"a\": 1, \"b\": {\"c\": \"Delete\"}}", 24 | "request": { 25 | "database": "projects/projectID/databases/(default)", 26 | "writes": [ 27 | { 28 | "update": { 29 | "name": "projects/projectID/databases/(default)/documents/C/d", 30 | "fields": { 31 | "a": { 32 | "integerValue": "1" 33 | } 34 | } 35 | }, 36 | "updateMask": { 37 | "fieldPaths": [ 38 | "a", 39 | "b.c" 40 | ] 41 | } 42 | } 43 | ] 44 | } 45 | } 46 | } 47 | ] 48 | } 49 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/set-del-mergeall.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: Delete with MergeAll", 5 | "comment": "A Delete sentinel can appear with a mergeAll option.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "option": { 9 | "all": true 10 | }, 11 | "jsonData": "{\"a\": 1, \"b\": {\"c\": \"Delete\"}}", 12 | "request": { 13 | "database": "projects/projectID/databases/(default)", 14 | "writes": [ 15 | { 16 | "update": { 17 | "name": "projects/projectID/databases/(default)/documents/C/d", 18 | "fields": { 19 | "a": { 20 | "integerValue": "1" 21 | } 22 | } 23 | }, 24 | "updateMask": { 25 | "fieldPaths": [ 26 | "a", 27 | "b.c" 28 | ] 29 | } 30 | } 31 | ] 32 | } 33 | } 34 | } 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/set-del-noarray-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: Delete cannot be anywhere inside an array value", 5 | "comment": "The Delete sentinel must be the value of a field. Deletes are implemented\nby turning the path to the Delete sentinel into a FieldPath, and FieldPaths do not support\narray indexing.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, {\"b\": \"Delete\"}]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/set-del-noarray.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: Delete cannot be in an array value", 5 | "comment": "The Delete sentinel must be the value of a field. Deletes are\nimplemented by turning the path to the Delete sentinel into a FieldPath, and FieldPaths\ndo not support array indexing.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, 2, \"Delete\"]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/set-del-nomerge.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set-merge: Delete cannot appear in an unmerged field", 5 | "comment": "The client signals an error if the Delete sentinel is in the\ninput data, but not selected by a merge option, because this is most likely a programming\nbug.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "option": { 9 | "fields": [ 10 | { 11 | "field": [ 12 | "a" 13 | ] 14 | } 15 | ] 16 | }, 17 | "jsonData": "{\"a\": 1, \"b\": \"Delete\"}", 18 | "isError": true 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/set-del-nonleaf.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set-merge: Delete cannot appear as part of a merge path", 5 | "comment": "If a Delete is part of the value at a merge path, then the user is\nconfused: their merge path says \"replace this entire value\" but their Delete says\n\"delete this part of the value\". This should be an error, just as if they specified Delete\nin a Set with no merge.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "option": { 9 | "fields": [ 10 | { 11 | "field": [ 12 | "h" 13 | ] 14 | } 15 | ] 16 | }, 17 | "jsonData": "{\"h\": {\"g\": \"Delete\"}}", 18 | "isError": true 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/set-del-wo-merge.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: Delete cannot appear unless a merge option is specified", 5 | "comment": "Without a merge option, Set replaces the document with the input\ndata. A Delete sentinel in the data makes no sense in this case.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": 1, \"b\": \"Delete\"}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/set-empty.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: creating or setting an empty map", 5 | "set": { 6 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 7 | "jsonData": "{}", 8 | "request": { 9 | "database": "projects/projectID/databases/(default)", 10 | "writes": [ 11 | { 12 | "update": { 13 | "name": "projects/projectID/databases/(default)/documents/C/d", 14 | "fields": {} 15 | } 16 | } 17 | ] 18 | } 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/set-merge-fp.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set-merge: Merge with FieldPaths", 5 | "comment": "A merge with fields that use special characters.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "option": { 9 | "fields": [ 10 | { 11 | "field": [ 12 | "*", 13 | "~" 14 | ] 15 | } 16 | ] 17 | }, 18 | "jsonData": "{\"*\": {\"~\": true}}", 19 | "request": { 20 | "database": "projects/projectID/databases/(default)", 21 | "writes": [ 22 | { 23 | "update": { 24 | "name": "projects/projectID/databases/(default)/documents/C/d", 25 | "fields": { 26 | "*": { 27 | "mapValue": { 28 | "fields": { 29 | "~": { 30 | "booleanValue": true 31 | } 32 | } 33 | } 34 | } 35 | } 36 | }, 37 | "updateMask": { 38 | "fieldPaths": [ 39 | "`*`.`~`" 40 | ] 41 | } 42 | } 43 | ] 44 | } 45 | } 46 | } 47 | ] 48 | } 49 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/set-merge-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set-merge: Merge with a nested field", 5 | "comment": "A merge option where the field is not at top level.\nOnly fields mentioned in the option are present in the update operation.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "option": { 9 | "fields": [ 10 | { 11 | "field": [ 12 | "h", 13 | "g" 14 | ] 15 | } 16 | ] 17 | }, 18 | "jsonData": "{\"h\": {\"g\": 4, \"f\": 5}}", 19 | "request": { 20 | "database": "projects/projectID/databases/(default)", 21 | "writes": [ 22 | { 23 | "update": { 24 | "name": "projects/projectID/databases/(default)/documents/C/d", 25 | "fields": { 26 | "h": { 27 | "mapValue": { 28 | "fields": { 29 | "g": { 30 | "integerValue": "4" 31 | } 32 | } 33 | } 34 | } 35 | } 36 | }, 37 | "updateMask": { 38 | "fieldPaths": [ 39 | "h.g" 40 | ] 41 | } 42 | } 43 | ] 44 | } 45 | } 46 | } 47 | ] 48 | } 49 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/set-merge-prefix.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set-merge: One merge path cannot be the prefix of another", 5 | "comment": "The prefix would make the other path meaningless, so this is\nprobably a programming error.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "option": { 9 | "fields": [ 10 | { 11 | "field": [ 12 | "a" 13 | ] 14 | }, 15 | { 16 | "field": [ 17 | "a", 18 | "b" 19 | ] 20 | } 21 | ] 22 | }, 23 | "jsonData": "{\"a\": {\"b\": 1}}", 24 | "isError": true 25 | } 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/set-merge-present.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set-merge: Merge fields must all be present in data", 5 | "comment": "The client signals an error if a merge option mentions a path\nthat is not in the input data.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "option": { 9 | "fields": [ 10 | { 11 | "field": [ 12 | "b" 13 | ] 14 | }, 15 | { 16 | "field": [ 17 | "a" 18 | ] 19 | } 20 | ] 21 | }, 22 | "jsonData": "{\"a\": 1}", 23 | "isError": true 24 | } 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/set-merge.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set-merge: Merge with a field", 5 | "comment": "Fields in the input data but not in a merge option are pruned.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "option": { 9 | "fields": [ 10 | { 11 | "field": [ 12 | "a" 13 | ] 14 | } 15 | ] 16 | }, 17 | "jsonData": "{\"a\": 1, \"b\": 2}", 18 | "request": { 19 | "database": "projects/projectID/databases/(default)", 20 | "writes": [ 21 | { 22 | "update": { 23 | "name": "projects/projectID/databases/(default)/documents/C/d", 24 | "fields": { 25 | "a": { 26 | "integerValue": "1" 27 | } 28 | } 29 | }, 30 | "updateMask": { 31 | "fieldPaths": [ 32 | "a" 33 | ] 34 | } 35 | } 36 | ] 37 | } 38 | } 39 | } 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/set-mergeall-empty.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: MergeAll can be specified with empty data.", 5 | "comment": "This is a valid call that can be used to ensure a document exists.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "option": { 9 | "all": true 10 | }, 11 | "jsonData": "{}", 12 | "request": { 13 | "database": "projects/projectID/databases/(default)", 14 | "writes": [ 15 | { 16 | "update": { 17 | "name": "projects/projectID/databases/(default)/documents/C/d", 18 | "fields": {} 19 | }, 20 | "updateMask": { 21 | "fieldPaths": [] 22 | } 23 | } 24 | ] 25 | } 26 | } 27 | } 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/set-mergeall-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: MergeAll with nested fields", 5 | "comment": "MergeAll with nested fields results in an update mask that\nincludes entries for all the leaf fields.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "option": { 9 | "all": true 10 | }, 11 | "jsonData": "{\"h\": { \"g\": 3, \"f\": 4 }}", 12 | "request": { 13 | "database": "projects/projectID/databases/(default)", 14 | "writes": [ 15 | { 16 | "update": { 17 | "name": "projects/projectID/databases/(default)/documents/C/d", 18 | "fields": { 19 | "h": { 20 | "mapValue": { 21 | "fields": { 22 | "f": { 23 | "integerValue": "4" 24 | }, 25 | "g": { 26 | "integerValue": "3" 27 | } 28 | } 29 | } 30 | } 31 | } 32 | }, 33 | "updateMask": { 34 | "fieldPaths": [ 35 | "h.f", 36 | "h.g" 37 | ] 38 | } 39 | } 40 | ] 41 | } 42 | } 43 | } 44 | ] 45 | } 46 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/set-mergeall.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: MergeAll", 5 | "comment": "The MergeAll option with a simple piece of data.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "option": { 9 | "all": true 10 | }, 11 | "jsonData": "{\"a\": 1, \"b\": 2}", 12 | "request": { 13 | "database": "projects/projectID/databases/(default)", 14 | "writes": [ 15 | { 16 | "update": { 17 | "name": "projects/projectID/databases/(default)/documents/C/d", 18 | "fields": { 19 | "a": { 20 | "integerValue": "1" 21 | }, 22 | "b": { 23 | "integerValue": "2" 24 | } 25 | } 26 | }, 27 | "updateMask": { 28 | "fieldPaths": [ 29 | "a", 30 | "b" 31 | ] 32 | } 33 | } 34 | ] 35 | } 36 | } 37 | } 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/set-nodel.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: Delete cannot appear in data", 5 | "comment": "The Delete sentinel cannot be used in Create, or in Set without a Merge option.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": 1, \"b\": \"Delete\"}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/set-nosplit.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: don’t split on dots", 5 | "comment": "Create and Set treat their map keys literally. They do not split on dots.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{ \"a.b\": { \"c.d\": 1 }, \"e\": 2 }", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "update": { 14 | "name": "projects/projectID/databases/(default)/documents/C/d", 15 | "fields": { 16 | "a.b": { 17 | "mapValue": { 18 | "fields": { 19 | "c.d": { 20 | "integerValue": "1" 21 | } 22 | } 23 | } 24 | }, 25 | "e": { 26 | "integerValue": "2" 27 | } 28 | } 29 | } 30 | } 31 | ] 32 | } 33 | } 34 | } 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/set-special-chars.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: non-alpha characters in map keys", 5 | "comment": "Create and Set treat their map keys literally. They do not escape special characters.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{ \"*\": { \".\": 1 }, \"~\": 2 }", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "update": { 14 | "name": "projects/projectID/databases/(default)/documents/C/d", 15 | "fields": { 16 | "*": { 17 | "mapValue": { 18 | "fields": { 19 | ".": { 20 | "integerValue": "1" 21 | } 22 | } 23 | } 24 | }, 25 | "~": { 26 | "integerValue": "2" 27 | } 28 | } 29 | } 30 | } 31 | ] 32 | } 33 | } 34 | } 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/set-st-alone-mergeall.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: ServerTimestamp alone with MergeAll", 5 | "comment": "If the only values in the input are ServerTimestamps, then no\nupdate operation should be produced.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "option": { 9 | "all": true 10 | }, 11 | "jsonData": "{\"a\": \"ServerTimestamp\"}", 12 | "request": { 13 | "database": "projects/projectID/databases/(default)", 14 | "writes": [ 15 | { 16 | "update": { 17 | "fields": {}, 18 | "name": "projects/projectID/databases/(default)/documents/C/d" 19 | }, 20 | "updateMask": { 21 | "fieldPaths": [] 22 | }, 23 | "updateTransforms": [ 24 | { 25 | "fieldPath": "a", 26 | "setToServerValue": "REQUEST_TIME" 27 | } 28 | ] 29 | } 30 | ] 31 | } 32 | } 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/set-st-alone.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: ServerTimestamp alone", 5 | "comment": "If the only values in the input are ServerTimestamps, then\nan update operation with an empty map should be produced.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": \"ServerTimestamp\"}", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "update": { 14 | "name": "projects/projectID/databases/(default)/documents/C/d", 15 | "fields": {} 16 | }, 17 | "updateTransforms": [ 18 | { 19 | "fieldPath": "a", 20 | "setToServerValue": "REQUEST_TIME" 21 | } 22 | ] 23 | } 24 | ] 25 | } 26 | } 27 | } 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/set-st-merge-nonleaf-alone.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set-merge: non-leaf merge field with ServerTimestamp alone", 5 | "comment": "If a field path is in a merge option, the value at that path\nreplaces the stored value. If the value has only ServerTimestamps, they become transforms\nand we clear the value by including the field path in the update mask.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "option": { 9 | "fields": [ 10 | { 11 | "field": [ 12 | "h" 13 | ] 14 | } 15 | ] 16 | }, 17 | "jsonData": "{\"h\": {\"g\": \"ServerTimestamp\"}, \"e\": 7}", 18 | "request": { 19 | "database": "projects/projectID/databases/(default)", 20 | "writes": [ 21 | { 22 | "update": { 23 | "name": "projects/projectID/databases/(default)/documents/C/d" 24 | }, 25 | "updateMask": { 26 | "fieldPaths": [ 27 | "h" 28 | ] 29 | }, 30 | "updateTransforms": [ 31 | { 32 | "fieldPath": "h.g", 33 | "setToServerValue": "REQUEST_TIME" 34 | } 35 | ] 36 | } 37 | ] 38 | } 39 | } 40 | } 41 | ] 42 | } 43 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/set-st-merge-nowrite.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set-merge: If no ordinary values in Merge, no write", 5 | "comment": "If all the fields in the merge option have ServerTimestamp\nvalues, then no update operation is produced, only a transform.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "option": { 9 | "fields": [ 10 | { 11 | "field": [ 12 | "b" 13 | ] 14 | } 15 | ] 16 | }, 17 | "jsonData": "{\"a\": 1, \"b\": \"ServerTimestamp\"}", 18 | "request": { 19 | "database": "projects/projectID/databases/(default)", 20 | "writes": [ 21 | { 22 | "update": { 23 | "fields": {}, 24 | "name": "projects/projectID/databases/(default)/documents/C/d" 25 | }, 26 | "updateMask": { 27 | "fieldPaths": [] 28 | }, 29 | "updateTransforms": [ 30 | { 31 | "fieldPath": "b", 32 | "setToServerValue": "REQUEST_TIME" 33 | } 34 | ] 35 | } 36 | ] 37 | } 38 | } 39 | } 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/set-st-mergeall.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: ServerTimestamp with MergeAll", 5 | "comment": "Just as when no merge option is specified, ServerTimestamp\nsentinel values are removed from the data in the update operation and become\ntransforms.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "option": { 9 | "all": true 10 | }, 11 | "jsonData": "{\"a\": 1, \"b\": \"ServerTimestamp\"}", 12 | "request": { 13 | "database": "projects/projectID/databases/(default)", 14 | "writes": [ 15 | { 16 | "update": { 17 | "name": "projects/projectID/databases/(default)/documents/C/d", 18 | "fields": { 19 | "a": { 20 | "integerValue": "1" 21 | } 22 | } 23 | }, 24 | "updateMask": { 25 | "fieldPaths": [ 26 | "a" 27 | ] 28 | }, 29 | "updateTransforms": [ 30 | { 31 | "fieldPath": "b", 32 | "setToServerValue": "REQUEST_TIME" 33 | } 34 | ] 35 | } 36 | ] 37 | } 38 | } 39 | } 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/set-st-multi.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: multiple ServerTimestamp fields", 5 | "comment": "A document can have more than one ServerTimestamp field.\nSince all the ServerTimestamp fields are removed, the only field in the update is \"a\".", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": 1, \"b\": \"ServerTimestamp\", \"c\": {\"d\": \"ServerTimestamp\"}}", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "update": { 14 | "name": "projects/projectID/databases/(default)/documents/C/d", 15 | "fields": { 16 | "a": { 17 | "integerValue": "1" 18 | } 19 | } 20 | }, 21 | "updateTransforms": [ 22 | { 23 | "fieldPath": "b", 24 | "setToServerValue": "REQUEST_TIME" 25 | }, 26 | { 27 | "fieldPath": "c.d", 28 | "setToServerValue": "REQUEST_TIME" 29 | } 30 | ] 31 | } 32 | ] 33 | } 34 | } 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/set-st-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: nested ServerTimestamp field", 5 | "comment": "A ServerTimestamp value can occur at any depth. In this case,\nthe transform applies to the field path \"b.c\". Since \"c\" is removed from the update,\n\"b\" becomes empty, so it is also removed from the update.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": 1, \"b\": {\"c\": \"ServerTimestamp\"}}", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "update": { 14 | "name": "projects/projectID/databases/(default)/documents/C/d", 15 | "fields": { 16 | "a": { 17 | "integerValue": "1" 18 | } 19 | } 20 | }, 21 | "updateTransforms": [ 22 | { 23 | "fieldPath": "b.c", 24 | "setToServerValue": "REQUEST_TIME" 25 | } 26 | ] 27 | } 28 | ] 29 | } 30 | } 31 | } 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/set-st-noarray-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: ServerTimestamp cannot be anywhere inside an array value", 5 | "comment": "There cannot be an array value anywhere on the path from the document\nroot to the ServerTimestamp sentinel. Firestore transforms don't support array indexing.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, {\"b\": \"ServerTimestamp\"}]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/set-st-noarray.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: ServerTimestamp cannot be in an array value", 5 | "comment": "The ServerTimestamp sentinel must be the value of a field. Firestore\ntransforms don't support array indexing.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, 2, \"ServerTimestamp\"]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/set-st-nomerge.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set-merge: If is ServerTimestamp not in Merge, no transform", 5 | "comment": "If the ServerTimestamp value is not mentioned in a merge option,\nthen it is pruned from the data but does not result in a transform.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "option": { 9 | "fields": [ 10 | { 11 | "field": [ 12 | "a" 13 | ] 14 | } 15 | ] 16 | }, 17 | "jsonData": "{\"a\": 1, \"b\": \"ServerTimestamp\"}", 18 | "request": { 19 | "database": "projects/projectID/databases/(default)", 20 | "writes": [ 21 | { 22 | "update": { 23 | "name": "projects/projectID/databases/(default)/documents/C/d", 24 | "fields": { 25 | "a": { 26 | "integerValue": "1" 27 | } 28 | } 29 | }, 30 | "updateMask": { 31 | "fieldPaths": [ 32 | "a" 33 | ] 34 | } 35 | } 36 | ] 37 | } 38 | } 39 | } 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/set-st-with-empty-map.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: ServerTimestamp beside an empty map", 5 | "comment": "When a ServerTimestamp and a map both reside inside a map, the\nServerTimestamp should be stripped out but the empty map should remain.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": {\"b\": {}, \"c\": \"ServerTimestamp\"}}", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "update": { 14 | "name": "projects/projectID/databases/(default)/documents/C/d", 15 | "fields": { 16 | "a": { 17 | "mapValue": { 18 | "fields": { 19 | "b": { 20 | "mapValue": { 21 | "fields": {} 22 | } 23 | } 24 | } 25 | } 26 | } 27 | } 28 | }, 29 | "updateTransforms": [ 30 | { 31 | "fieldPath": "a.c", 32 | "setToServerValue": "REQUEST_TIME" 33 | } 34 | ] 35 | } 36 | ] 37 | } 38 | } 39 | } 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/set-st.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "set: ServerTimestamp with data", 5 | "comment": "A key with the special ServerTimestamp sentinel is removed from\nthe data in the update operation. Instead it appears in a separate Transform operation.\nNote that in these tests, the string \"ServerTimestamp\" should be replaced with the\nspecial ServerTimestamp value.", 6 | "set": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": 1, \"b\": \"ServerTimestamp\"}", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "update": { 14 | "name": "projects/projectID/databases/(default)/documents/C/d", 15 | "fields": { 16 | "a": { 17 | "integerValue": "1" 18 | } 19 | } 20 | }, 21 | "updateTransforms": [ 22 | { 23 | "fieldPath": "b", 24 | "setToServerValue": "REQUEST_TIME" 25 | } 26 | ] 27 | } 28 | ] 29 | } 30 | } 31 | } 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-arrayremove-alone.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: ArrayRemove alone", 5 | "comment": "If the only values in the input are ArrayRemove, then no\nupdate operation should be produced.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [\"ArrayRemove\", 1, 2, 3]}", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "currentDocument": { 14 | "exists": true 15 | }, 16 | "update": { 17 | "fields": {}, 18 | "name": "projects/projectID/databases/(default)/documents/C/d" 19 | }, 20 | "updateMask": { 21 | "fieldPaths": [] 22 | }, 23 | "updateTransforms": [ 24 | { 25 | "fieldPath": "a", 26 | "removeAllFromArray": { 27 | "values": [ 28 | { 29 | "integerValue": "1" 30 | }, 31 | { 32 | "integerValue": "2" 33 | }, 34 | { 35 | "integerValue": "3" 36 | } 37 | ] 38 | } 39 | } 40 | ] 41 | } 42 | ] 43 | } 44 | } 45 | } 46 | ] 47 | } 48 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-arrayremove-noarray-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: ArrayRemove cannot be anywhere inside an array value", 5 | "comment": "There cannot be an array value anywhere on the path from the document\nroot to the ArrayRemove. Firestore transforms don't support array indexing.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, {\"b\": [\"ArrayRemove\", 1, 2, 3]}]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-arrayremove-noarray.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: ArrayRemove cannot be in an array value", 5 | "comment": "ArrayRemove must be the value of a field. Firestore\ntransforms don't support array indexing.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, 2, [\"ArrayRemove\", 1, 2, 3]]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-arrayremove-with-st.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: The ServerTimestamp sentinel cannot be in an ArrayUnion", 5 | "comment": "The ServerTimestamp sentinel must be the value of a field. It may\nnot appear in an ArrayUnion.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [\"ArrayRemove\", 1, \"ServerTimestamp\", 3]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-arrayunion-alone.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: ArrayUnion alone", 5 | "comment": "If the only values in the input are ArrayUnion, then no\nupdate operation should be produced.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [\"ArrayUnion\", 1, 2, 3]}", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "currentDocument": { 14 | "exists": true 15 | }, 16 | "update": { 17 | "fields": {}, 18 | "name": "projects/projectID/databases/(default)/documents/C/d" 19 | }, 20 | "updateMask": { 21 | "fieldPaths": [] 22 | }, 23 | "updateTransforms": [ 24 | { 25 | "appendMissingElements": { 26 | "values": [ 27 | { 28 | "integerValue": "1" 29 | }, 30 | { 31 | "integerValue": "2" 32 | }, 33 | { 34 | "integerValue": "3" 35 | } 36 | ] 37 | }, 38 | "fieldPath": "a" 39 | } 40 | ] 41 | } 42 | ] 43 | } 44 | } 45 | } 46 | ] 47 | } 48 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-arrayunion-noarray-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: ArrayUnion cannot be anywhere inside an array value", 5 | "comment": "There cannot be an array value anywhere on the path from the document\nroot to the ArrayUnion. Firestore transforms don't support array indexing.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, {\"b\": [\"ArrayUnion\", 1, 2, 3]}]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-arrayunion-noarray.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: ArrayUnion cannot be in an array value", 5 | "comment": "ArrayUnion must be the value of a field. Firestore\ntransforms don't support array indexing.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, 2, [\"ArrayRemove\", 1, 2, 3]]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-arrayunion-with-st.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: The ServerTimestamp sentinel cannot be in an ArrayUnion", 5 | "comment": "The ServerTimestamp sentinel must be the value of a field. It may\nnot appear in an ArrayUnion.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [\"ArrayUnion\", 1, \"ServerTimestamp\", 3]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-badchar.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: invalid character", 5 | "comment": "The keys of the data given to Update are interpreted, unlike those of Create and Set. They cannot contain special characters.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a~b\": 1}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-basic.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: basic", 5 | "comment": "A simple call, resulting in a single update operation.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": 1}", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "update": { 14 | "name": "projects/projectID/databases/(default)/documents/C/d", 15 | "fields": { 16 | "a": { 17 | "integerValue": "1" 18 | } 19 | } 20 | }, 21 | "updateMask": { 22 | "fieldPaths": [ 23 | "a" 24 | ] 25 | }, 26 | "currentDocument": { 27 | "exists": true 28 | } 29 | } 30 | ] 31 | } 32 | } 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-del-alone.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: Delete alone", 5 | "comment": "If the input data consists solely of Deletes, then the update\noperation has no map, just an update mask.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": \"Delete\"}", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "update": { 14 | "name": "projects/projectID/databases/(default)/documents/C/d" 15 | }, 16 | "updateMask": { 17 | "fieldPaths": [ 18 | "a" 19 | ] 20 | }, 21 | "currentDocument": { 22 | "exists": true 23 | } 24 | } 25 | ] 26 | } 27 | } 28 | } 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-del-dot.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: Delete with a dotted field", 5 | "comment": "After expanding top-level dotted fields, fields with Delete\nvalues are pruned from the output data, but appear in the update mask.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": 1, \"b.c\": \"Delete\", \"b.d\": 2}", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "update": { 14 | "name": "projects/projectID/databases/(default)/documents/C/d", 15 | "fields": { 16 | "a": { 17 | "integerValue": "1" 18 | }, 19 | "b": { 20 | "mapValue": { 21 | "fields": { 22 | "d": { 23 | "integerValue": "2" 24 | } 25 | } 26 | } 27 | } 28 | } 29 | }, 30 | "updateMask": { 31 | "fieldPaths": [ 32 | "a", 33 | "b.c", 34 | "b.d" 35 | ] 36 | }, 37 | "currentDocument": { 38 | "exists": true 39 | } 40 | } 41 | ] 42 | } 43 | } 44 | } 45 | ] 46 | } 47 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-del-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: Delete cannot be nested", 5 | "comment": "The Delete sentinel must be the value of a top-level key.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": {\"b\": \"Delete\"}}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-del-noarray-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: Delete cannot be anywhere inside an array value", 5 | "comment": "The Delete sentinel must be the value of a field. Deletes are implemented\nby turning the path to the Delete sentinel into a FieldPath, and FieldPaths do not support\narray indexing.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, {\"b\": \"Delete\"}]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-del-noarray.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: Delete cannot be in an array value", 5 | "comment": "The Delete sentinel must be the value of a field. Deletes are\nimplemented by turning the path to the Delete sentinel into a FieldPath, and FieldPaths\ndo not support array indexing.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, 2, \"Delete\"]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-del.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: Delete", 5 | "comment": "If a field's value is the Delete sentinel, then it doesn't appear\nin the update data, but does in the mask.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": 1, \"b\": \"Delete\"}", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "update": { 14 | "name": "projects/projectID/databases/(default)/documents/C/d", 15 | "fields": { 16 | "a": { 17 | "integerValue": "1" 18 | } 19 | } 20 | }, 21 | "updateMask": { 22 | "fieldPaths": [ 23 | "a", 24 | "b" 25 | ] 26 | }, 27 | "currentDocument": { 28 | "exists": true 29 | } 30 | } 31 | ] 32 | } 33 | } 34 | } 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-exists-false-precond.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: Exists=false precondition is invalid", 5 | "comment": "The Update method does not support an explicit exists=false precondition.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "precondition": { 9 | "exists": false 10 | }, 11 | "jsonData": "{\"a\": 1}", 12 | "isError": true 13 | } 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-exists-true-precond.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: Exists=true precondition is valid", 5 | "comment": "The Update method supports an explicit exists=true precondition.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "precondition": { 9 | "exists": true 10 | }, 11 | "jsonData": "{\"a\": 1}", 12 | "request": { 13 | "database": "projects/projectID/databases/(default)", 14 | "writes": [ 15 | { 16 | "update": { 17 | "name": "projects/projectID/databases/(default)/documents/C/d", 18 | "fields": { 19 | "a": { 20 | "integerValue": "1" 21 | } 22 | } 23 | }, 24 | "updateMask": { 25 | "fieldPaths": [ 26 | "a" 27 | ] 28 | }, 29 | "currentDocument": { 30 | "exists": true 31 | } 32 | } 33 | ] 34 | } 35 | } 36 | } 37 | ] 38 | } 39 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-fp-empty-component.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: empty field path component", 5 | "comment": "Empty fields are not allowed.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a..b\": 1}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-no-paths.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: no paths", 5 | "comment": "It is a client-side error to call Update with empty data.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-paths-arrayremove-noarray-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: ArrayRemove cannot be anywhere inside an array value", 5 | "comment": "There cannot be an array value anywhere on the path from the document\nroot to the ArrayRemove. Firestore transforms don't support array indexing.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "a" 12 | ] 13 | } 14 | ], 15 | "jsonValues": [ 16 | "[1, {\"b\": [\"ArrayRemove\", 1, 2, 3]}]" 17 | ], 18 | "isError": true 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-paths-arrayremove-noarray.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: ArrayRemove cannot be in an array value", 5 | "comment": "ArrayRemove must be the value of a field. Firestore\ntransforms don't support array indexing.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "a" 12 | ] 13 | } 14 | ], 15 | "jsonValues": [ 16 | "[1, 2, [\"ArrayRemove\", 1, 2, 3]]" 17 | ], 18 | "isError": true 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-paths-arrayremove-with-st.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: The ServerTimestamp sentinel cannot be in an ArrayUnion", 5 | "comment": "The ServerTimestamp sentinel must be the value of a field. It may\nnot appear in an ArrayUnion.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "a" 12 | ] 13 | } 14 | ], 15 | "jsonValues": [ 16 | "[\"ArrayRemove\", 1, \"ServerTimestamp\", 3]" 17 | ], 18 | "isError": true 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-paths-arrayunion-noarray-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: ArrayUnion cannot be anywhere inside an array value", 5 | "comment": "There cannot be an array value anywhere on the path from the document\nroot to the ArrayUnion. Firestore transforms don't support array indexing.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "a" 12 | ] 13 | } 14 | ], 15 | "jsonValues": [ 16 | "[1, {\"b\": [\"ArrayUnion\", 1, 2, 3]}]" 17 | ], 18 | "isError": true 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-paths-arrayunion-noarray.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: ArrayUnion cannot be in an array value", 5 | "comment": "ArrayUnion must be the value of a field. Firestore\ntransforms don't support array indexing.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "a" 12 | ] 13 | } 14 | ], 15 | "jsonValues": [ 16 | "[1, 2, [\"ArrayRemove\", 1, 2, 3]]" 17 | ], 18 | "isError": true 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-paths-arrayunion-with-st.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: The ServerTimestamp sentinel cannot be in an ArrayUnion", 5 | "comment": "The ServerTimestamp sentinel must be the value of a field. It may\nnot appear in an ArrayUnion.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "a" 12 | ] 13 | } 14 | ], 15 | "jsonValues": [ 16 | "[\"ArrayUnion\", 1, \"ServerTimestamp\", 3]" 17 | ], 18 | "isError": true 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-paths-basic.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: basic", 5 | "comment": "A simple call, resulting in a single update operation.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "a" 12 | ] 13 | } 14 | ], 15 | "jsonValues": [ 16 | "1" 17 | ], 18 | "request": { 19 | "database": "projects/projectID/databases/(default)", 20 | "writes": [ 21 | { 22 | "update": { 23 | "name": "projects/projectID/databases/(default)/documents/C/d", 24 | "fields": { 25 | "a": { 26 | "integerValue": "1" 27 | } 28 | } 29 | }, 30 | "updateMask": { 31 | "fieldPaths": [ 32 | "a" 33 | ] 34 | }, 35 | "currentDocument": { 36 | "exists": true 37 | } 38 | } 39 | ] 40 | } 41 | } 42 | } 43 | ] 44 | } 45 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-paths-del-alone.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: Delete alone", 5 | "comment": "If the input data consists solely of Deletes, then the update\noperation has no map, just an update mask.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "a" 12 | ] 13 | } 14 | ], 15 | "jsonValues": [ 16 | "\"Delete\"" 17 | ], 18 | "request": { 19 | "database": "projects/projectID/databases/(default)", 20 | "writes": [ 21 | { 22 | "update": { 23 | "name": "projects/projectID/databases/(default)/documents/C/d" 24 | }, 25 | "updateMask": { 26 | "fieldPaths": [ 27 | "a" 28 | ] 29 | }, 30 | "currentDocument": { 31 | "exists": true 32 | } 33 | } 34 | ] 35 | } 36 | } 37 | } 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-paths-del-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: Delete cannot be nested", 5 | "comment": "The Delete sentinel must be the value of a top-level key.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "a" 12 | ] 13 | } 14 | ], 15 | "jsonValues": [ 16 | "{\"b\": \"Delete\"}" 17 | ], 18 | "isError": true 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-paths-del-noarray-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: Delete cannot be anywhere inside an array value", 5 | "comment": "The Delete sentinel must be the value of a field. Deletes are implemented\nby turning the path to the Delete sentinel into a FieldPath, and FieldPaths do not support\narray indexing.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "a" 12 | ] 13 | } 14 | ], 15 | "jsonValues": [ 16 | "[1, {\"b\": \"Delete\"}]" 17 | ], 18 | "isError": true 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-paths-del-noarray.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: Delete cannot be in an array value", 5 | "comment": "The Delete sentinel must be the value of a field. Deletes are\nimplemented by turning the path to the Delete sentinel into a FieldPath, and FieldPaths\ndo not support array indexing.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "a" 12 | ] 13 | } 14 | ], 15 | "jsonValues": [ 16 | "[1, 2, \"Delete\"]" 17 | ], 18 | "isError": true 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-paths-del.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: Delete", 5 | "comment": "If a field's value is the Delete sentinel, then it doesn't appear\nin the update data, but does in the mask.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "a" 12 | ] 13 | }, 14 | { 15 | "field": [ 16 | "b" 17 | ] 18 | } 19 | ], 20 | "jsonValues": [ 21 | "1", 22 | "\"Delete\"" 23 | ], 24 | "request": { 25 | "database": "projects/projectID/databases/(default)", 26 | "writes": [ 27 | { 28 | "update": { 29 | "name": "projects/projectID/databases/(default)/documents/C/d", 30 | "fields": { 31 | "a": { 32 | "integerValue": "1" 33 | } 34 | } 35 | }, 36 | "updateMask": { 37 | "fieldPaths": [ 38 | "a", 39 | "b" 40 | ] 41 | }, 42 | "currentDocument": { 43 | "exists": true 44 | } 45 | } 46 | ] 47 | } 48 | } 49 | } 50 | ] 51 | } 52 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-paths-exists-false-precond.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: Exists=false precondition is invalid", 5 | "comment": "The Update method does not support an explicit exists=false precondition.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "precondition": { 9 | "exists": false 10 | }, 11 | "fieldPaths": [ 12 | { 13 | "field": [ 14 | "a" 15 | ] 16 | } 17 | ], 18 | "jsonValues": [ 19 | "1" 20 | ], 21 | "isError": true 22 | } 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-paths-exists-true-precond.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: Exists=true precondition is valid", 5 | "comment": "The Update method supports an explicit exists=true precondition.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "precondition": { 9 | "exists": true 10 | }, 11 | "fieldPaths": [ 12 | { 13 | "field": [ 14 | "a" 15 | ] 16 | } 17 | ], 18 | "jsonValues": [ 19 | "1" 20 | ], 21 | "request": { 22 | "database": "projects/projectID/databases/(default)", 23 | "writes": [ 24 | { 25 | "update": { 26 | "name": "projects/projectID/databases/(default)/documents/C/d", 27 | "fields": { 28 | "a": { 29 | "integerValue": "1" 30 | } 31 | } 32 | }, 33 | "updateMask": { 34 | "fieldPaths": [ 35 | "a" 36 | ] 37 | }, 38 | "currentDocument": { 39 | "exists": true 40 | } 41 | } 42 | ] 43 | } 44 | } 45 | } 46 | ] 47 | } 48 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-paths-fp-dup-transforms.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: duplicate field path with only transforms", 5 | "comment": "The same field cannot occur more than once, even if all the operations are transforms.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "a" 12 | ] 13 | }, 14 | { 15 | "field": [ 16 | "b" 17 | ] 18 | }, 19 | { 20 | "field": [ 21 | "a" 22 | ] 23 | } 24 | ], 25 | "jsonValues": [ 26 | "[\"ArrayUnion\", 1, 2, 3]", 27 | "\"ServerTimestamp\"", 28 | "[\"ArrayUnion\", 4, 5, 6]" 29 | ], 30 | "isError": true 31 | } 32 | } 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-paths-fp-dup.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: duplicate field path", 5 | "comment": "The same field cannot occur more than once.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "a" 12 | ] 13 | }, 14 | { 15 | "field": [ 16 | "b" 17 | ] 18 | }, 19 | { 20 | "field": [ 21 | "a" 22 | ] 23 | } 24 | ], 25 | "jsonValues": [ 26 | "1", 27 | "2", 28 | "3" 29 | ], 30 | "isError": true 31 | } 32 | } 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-paths-fp-empty-component.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: empty field path component", 5 | "comment": "Empty fields are not allowed.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "*", 12 | "" 13 | ] 14 | } 15 | ], 16 | "jsonValues": [ 17 | "1" 18 | ], 19 | "isError": true 20 | } 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-paths-fp-empty.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: empty field path", 5 | "comment": "A FieldPath of length zero is invalid.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [] 11 | } 12 | ], 13 | "jsonValues": [ 14 | "1" 15 | ], 16 | "isError": true 17 | } 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-paths-fp-multi.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: multiple-element field path", 5 | "comment": "The UpdatePaths or equivalent method takes a list of FieldPaths.\nEach FieldPath is a sequence of uninterpreted path components.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "a", 12 | "b" 13 | ] 14 | } 15 | ], 16 | "jsonValues": [ 17 | "1" 18 | ], 19 | "request": { 20 | "database": "projects/projectID/databases/(default)", 21 | "writes": [ 22 | { 23 | "update": { 24 | "name": "projects/projectID/databases/(default)/documents/C/d", 25 | "fields": { 26 | "a": { 27 | "mapValue": { 28 | "fields": { 29 | "b": { 30 | "integerValue": "1" 31 | } 32 | } 33 | } 34 | } 35 | } 36 | }, 37 | "updateMask": { 38 | "fieldPaths": [ 39 | "a.b" 40 | ] 41 | }, 42 | "currentDocument": { 43 | "exists": true 44 | } 45 | } 46 | ] 47 | } 48 | } 49 | } 50 | ] 51 | } 52 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-paths-no-paths.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: no paths", 5 | "comment": "It is a client-side error to call Update with empty data.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "isError": true 9 | } 10 | } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-paths-prefix-1.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: prefix #1", 5 | "comment": "In the input data, one field cannot be a prefix of another.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "a", 12 | "b" 13 | ] 14 | }, 15 | { 16 | "field": [ 17 | "a" 18 | ] 19 | } 20 | ], 21 | "jsonValues": [ 22 | "1", 23 | "2" 24 | ], 25 | "isError": true 26 | } 27 | } 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-paths-prefix-2.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: prefix #2", 5 | "comment": "In the input data, one field cannot be a prefix of another.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "a" 12 | ] 13 | }, 14 | { 15 | "field": [ 16 | "a", 17 | "b" 18 | ] 19 | } 20 | ], 21 | "jsonValues": [ 22 | "1", 23 | "2" 24 | ], 25 | "isError": true 26 | } 27 | } 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-paths-prefix-3.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: prefix #3", 5 | "comment": "In the input data, one field cannot be a prefix of another, even if the values could in principle be combined.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "a" 12 | ] 13 | }, 14 | { 15 | "field": [ 16 | "a", 17 | "d" 18 | ] 19 | } 20 | ], 21 | "jsonValues": [ 22 | "{\"b\": 1}", 23 | "2" 24 | ], 25 | "isError": true 26 | } 27 | } 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-paths-st-alone.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: ServerTimestamp alone", 5 | "comment": "If the only values in the input are ServerTimestamps, then no\nupdate operation should be produced.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "a" 12 | ] 13 | } 14 | ], 15 | "jsonValues": [ 16 | "\"ServerTimestamp\"" 17 | ], 18 | "request": { 19 | "database": "projects/projectID/databases/(default)", 20 | "writes": [ 21 | { 22 | "currentDocument": { 23 | "exists": true 24 | }, 25 | "update": { 26 | "fields": {}, 27 | "name": "projects/projectID/databases/(default)/documents/C/d" 28 | }, 29 | "updateMask": { 30 | "fieldPaths": [] 31 | }, 32 | "updateTransforms": [ 33 | { 34 | "fieldPath": "a", 35 | "setToServerValue": "REQUEST_TIME" 36 | } 37 | ] 38 | } 39 | ] 40 | } 41 | } 42 | } 43 | ] 44 | } 45 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-paths-st-noarray-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: ServerTimestamp cannot be anywhere inside an array value", 5 | "comment": "There cannot be an array value anywhere on the path from the document\nroot to the ServerTimestamp sentinel. Firestore transforms don't support array indexing.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "a" 12 | ] 13 | } 14 | ], 15 | "jsonValues": [ 16 | "[1, {\"b\": \"ServerTimestamp\"}]" 17 | ], 18 | "isError": true 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-paths-st-noarray.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: ServerTimestamp cannot be in an array value", 5 | "comment": "The ServerTimestamp sentinel must be the value of a field. Firestore\ntransforms don't support array indexing.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "fieldPaths": [ 9 | { 10 | "field": [ 11 | "a" 12 | ] 13 | } 14 | ], 15 | "jsonValues": [ 16 | "[1, 2, \"ServerTimestamp\"]" 17 | ], 18 | "isError": true 19 | } 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-paths-uptime.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update-paths: last-update-time precondition", 5 | "comment": "The Update call supports a last-update-time precondition.", 6 | "updatePaths": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "precondition": { 9 | "updateTime": "1970-01-01T00:00:42Z" 10 | }, 11 | "fieldPaths": [ 12 | { 13 | "field": [ 14 | "a" 15 | ] 16 | } 17 | ], 18 | "jsonValues": [ 19 | "1" 20 | ], 21 | "request": { 22 | "database": "projects/projectID/databases/(default)", 23 | "writes": [ 24 | { 25 | "update": { 26 | "name": "projects/projectID/databases/(default)/documents/C/d", 27 | "fields": { 28 | "a": { 29 | "integerValue": "1" 30 | } 31 | } 32 | }, 33 | "updateMask": { 34 | "fieldPaths": [ 35 | "a" 36 | ] 37 | }, 38 | "currentDocument": { 39 | "updateTime": "1970-01-01T00:00:42Z" 40 | } 41 | } 42 | ] 43 | } 44 | } 45 | } 46 | ] 47 | } 48 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-prefix-1.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: prefix #1", 5 | "comment": "In the input data, one field cannot be a prefix of another.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a.b\": 1, \"a\": 2}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-prefix-2.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: prefix #2", 5 | "comment": "In the input data, one field cannot be a prefix of another.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": 1, \"a.b\": 2}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-prefix-3.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: prefix #3", 5 | "comment": "In the input data, one field cannot be a prefix of another, even if the values could in principle be combined.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": {\"b\": 1}, \"a.d\": 2}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-split.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: split on dots", 5 | "comment": "The Update method splits top-level keys at dots.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a.b.c\": 1}", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "update": { 14 | "name": "projects/projectID/databases/(default)/documents/C/d", 15 | "fields": { 16 | "a": { 17 | "mapValue": { 18 | "fields": { 19 | "b": { 20 | "mapValue": { 21 | "fields": { 22 | "c": { 23 | "integerValue": "1" 24 | } 25 | } 26 | } 27 | } 28 | } 29 | } 30 | } 31 | } 32 | }, 33 | "updateMask": { 34 | "fieldPaths": [ 35 | "a.b.c" 36 | ] 37 | }, 38 | "currentDocument": { 39 | "exists": true 40 | } 41 | } 42 | ] 43 | } 44 | } 45 | } 46 | ] 47 | } 48 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-st-alone.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: ServerTimestamp alone", 5 | "comment": "If the only values in the input are ServerTimestamps, then no\nupdate operation should be produced.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": \"ServerTimestamp\"}", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "currentDocument": { 14 | "exists": true 15 | }, 16 | "update": { 17 | "fields": {}, 18 | "name": "projects/projectID/databases/(default)/documents/C/d" 19 | }, 20 | "updateMask": { 21 | "fieldPaths": [] 22 | }, 23 | "updateTransforms": [ 24 | { 25 | "fieldPath": "a", 26 | "setToServerValue": "REQUEST_TIME" 27 | } 28 | ] 29 | } 30 | ] 31 | } 32 | } 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-st-dot.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: ServerTimestamp with dotted field", 5 | "comment": "Like other uses of ServerTimestamp, the data is pruned and the\nfield does not appear in the update mask, because it is in the transform. In this case\nAn update operation is produced just to hold the precondition.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a.b.c\": \"ServerTimestamp\"}", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "currentDocument": { 14 | "exists": true 15 | }, 16 | "update": { 17 | "fields": {}, 18 | "name": "projects/projectID/databases/(default)/documents/C/d" 19 | }, 20 | "updateMask": { 21 | "fieldPaths": [] 22 | }, 23 | "updateTransforms": [ 24 | { 25 | "fieldPath": "a.b.c", 26 | "setToServerValue": "REQUEST_TIME" 27 | } 28 | ] 29 | } 30 | ] 31 | } 32 | } 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-st-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: nested ServerTimestamp field", 5 | "comment": "A ServerTimestamp value can occur at any depth. In this case,\nthe transform applies to the field path \"b.c\". Since \"c\" is removed from the update,\n\"b\" becomes empty, so it is also removed from the update.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": 1, \"b\": {\"c\": \"ServerTimestamp\"}}", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "update": { 14 | "name": "projects/projectID/databases/(default)/documents/C/d", 15 | "fields": { 16 | "a": { 17 | "integerValue": "1" 18 | } 19 | } 20 | }, 21 | "updateMask": { 22 | "fieldPaths": [ 23 | "a", 24 | "b" 25 | ] 26 | }, 27 | "currentDocument": { 28 | "exists": true 29 | }, 30 | "updateTransforms": [ 31 | { 32 | "fieldPath": "b.c", 33 | "setToServerValue": "REQUEST_TIME" 34 | } 35 | ] 36 | } 37 | ] 38 | } 39 | } 40 | } 41 | ] 42 | } 43 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-st-noarray-nested.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: ServerTimestamp cannot be anywhere inside an array value", 5 | "comment": "There cannot be an array value anywhere on the path from the document\nroot to the ServerTimestamp sentinel. Firestore transforms don't support array indexing.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, {\"b\": \"ServerTimestamp\"}]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-st-noarray.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: ServerTimestamp cannot be in an array value", 5 | "comment": "The ServerTimestamp sentinel must be the value of a field. Firestore\ntransforms don't support array indexing.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": [1, 2, \"ServerTimestamp\"]}", 9 | "isError": true 10 | } 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-st.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: ServerTimestamp with data", 5 | "comment": "A key with the special ServerTimestamp sentinel is removed from\nthe data in the update operation. Instead it appears in a separate Transform operation.\nNote that in these tests, the string \"ServerTimestamp\" should be replaced with the\nspecial ServerTimestamp value.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "jsonData": "{\"a\": 1, \"b\": \"ServerTimestamp\"}", 9 | "request": { 10 | "database": "projects/projectID/databases/(default)", 11 | "writes": [ 12 | { 13 | "update": { 14 | "name": "projects/projectID/databases/(default)/documents/C/d", 15 | "fields": { 16 | "a": { 17 | "integerValue": "1" 18 | } 19 | } 20 | }, 21 | "updateMask": { 22 | "fieldPaths": [ 23 | "a" 24 | ] 25 | }, 26 | "currentDocument": { 27 | "exists": true 28 | }, 29 | "updateTransforms": [ 30 | { 31 | "fieldPath": "b", 32 | "setToServerValue": "REQUEST_TIME" 33 | } 34 | ] 35 | } 36 | ] 37 | } 38 | } 39 | } 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /dev/conformance/conformance-tests/update-uptime.json: -------------------------------------------------------------------------------- 1 | { 2 | "tests": [ 3 | { 4 | "description": "update: last-update-time precondition", 5 | "comment": "The Update call supports a last-update-time precondition.", 6 | "update": { 7 | "docRefPath": "projects/projectID/databases/(default)/documents/C/d", 8 | "precondition": { 9 | "updateTime": "1970-01-01T00:00:42Z" 10 | }, 11 | "jsonData": "{\"a\": 1}", 12 | "request": { 13 | "database": "projects/projectID/databases/(default)", 14 | "writes": [ 15 | { 16 | "update": { 17 | "name": "projects/projectID/databases/(default)/documents/C/d", 18 | "fields": { 19 | "a": { 20 | "integerValue": "1" 21 | } 22 | } 23 | }, 24 | "updateMask": { 25 | "fieldPaths": [ 26 | "a" 27 | ] 28 | }, 29 | "currentDocument": { 30 | "updateTime": "1970-01-01T00:00:42Z" 31 | } 32 | } 33 | ] 34 | } 35 | } 36 | } 37 | ] 38 | } 39 | -------------------------------------------------------------------------------- /dev/protos/google/api/annotations.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2024 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api; 18 | 19 | import "google/api/http.proto"; 20 | import "google/protobuf/descriptor.proto"; 21 | 22 | option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; 23 | option java_multiple_files = true; 24 | option java_outer_classname = "AnnotationsProto"; 25 | option java_package = "com.google.api"; 26 | option objc_class_prefix = "GAPI"; 27 | 28 | extend google.protobuf.MethodOptions { 29 | // See `HttpRule`. 30 | HttpRule http = 72295728; 31 | } 32 | -------------------------------------------------------------------------------- /dev/protos/google/firestore/admin/v1/location.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2024 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.firestore.admin.v1; 18 | 19 | option csharp_namespace = "Google.Cloud.Firestore.Admin.V1"; 20 | option go_package = "cloud.google.com/go/firestore/apiv1/admin/adminpb;adminpb"; 21 | option java_multiple_files = true; 22 | option java_outer_classname = "LocationProto"; 23 | option java_package = "com.google.firestore.admin.v1"; 24 | option objc_class_prefix = "GCFS"; 25 | option php_namespace = "Google\\Cloud\\Firestore\\Admin\\V1"; 26 | option ruby_package = "Google::Cloud::Firestore::Admin::V1"; 27 | 28 | // The metadata message for 29 | // [google.cloud.location.Location.metadata][google.cloud.location.Location.metadata]. 30 | message LocationMetadata {} 31 | -------------------------------------------------------------------------------- /dev/protos/google/type/dayofweek.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2024 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.type; 18 | 19 | option go_package = "google.golang.org/genproto/googleapis/type/dayofweek;dayofweek"; 20 | option java_multiple_files = true; 21 | option java_outer_classname = "DayOfWeekProto"; 22 | option java_package = "com.google.type"; 23 | option objc_class_prefix = "GTP"; 24 | 25 | // Represents a day of the week. 26 | enum DayOfWeek { 27 | // The day of the week is unspecified. 28 | DAY_OF_WEEK_UNSPECIFIED = 0; 29 | 30 | // Monday 31 | MONDAY = 1; 32 | 33 | // Tuesday 34 | TUESDAY = 2; 35 | 36 | // Wednesday 37 | WEDNESDAY = 3; 38 | 39 | // Thursday 40 | THURSDAY = 4; 41 | 42 | // Friday 43 | FRIDAY = 5; 44 | 45 | // Saturday 46 | SATURDAY = 6; 47 | 48 | // Sunday 49 | SUNDAY = 7; 50 | } 51 | -------------------------------------------------------------------------------- /dev/src/external-modules.d.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright 2019 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // TODO(mrschmidt): Come up with actual definitions for these modules. 18 | declare module 'functional-red-black-tree'; 19 | declare module 'length-prefixed-json-stream'; 20 | -------------------------------------------------------------------------------- /dev/src/map-type.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright 2024 Google LLC. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | export const RESERVED_MAP_KEY = '__type__'; 18 | export const RESERVED_MAP_KEY_VECTOR_VALUE = '__vector__'; 19 | export const VECTOR_MAP_VECTORS_KEY = 'value'; 20 | -------------------------------------------------------------------------------- /dev/src/reference/filter-internal.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2024 Google LLC. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Filter} from '../filter'; 18 | import {FieldFilterInternal} from './field-filter-internal'; 19 | 20 | export abstract class FilterInternal { 21 | /** Returns a list of all field filters that are contained within this filter */ 22 | abstract getFlattenedFilters(): FieldFilterInternal[]; 23 | 24 | /** Returns a list of all filters that are contained within this filter */ 25 | abstract getFilters(): FilterInternal[]; 26 | 27 | /** Returns the proto representation of this filter */ 28 | abstract toProto(): Filter; 29 | 30 | abstract isEqual(other: FilterInternal): boolean; 31 | } 32 | -------------------------------------------------------------------------------- /dev/src/status-code.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2021 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Internal copy of GRPC status code. Copied to prevent loading of google-gax 19 | * at SDK startup. 20 | */ 21 | export const enum StatusCode { 22 | OK = 0, 23 | CANCELLED = 1, 24 | UNKNOWN = 2, 25 | INVALID_ARGUMENT = 3, 26 | DEADLINE_EXCEEDED = 4, 27 | NOT_FOUND = 5, 28 | ALREADY_EXISTS = 6, 29 | PERMISSION_DENIED = 7, 30 | RESOURCE_EXHAUSTED = 8, 31 | FAILED_PRECONDITION = 9, 32 | ABORTED = 10, 33 | OUT_OF_RANGE = 11, 34 | UNIMPLEMENTED = 12, 35 | INTERNAL = 13, 36 | UNAVAILABLE = 14, 37 | DATA_LOSS = 15, 38 | UNAUTHENTICATED = 16, 39 | } 40 | -------------------------------------------------------------------------------- /dev/src/telemetry/span.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2024 Google LLC. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {Span as OpenTelemetrySpan} from '@opentelemetry/api'; 18 | import {Attributes} from './trace-util'; 19 | 20 | /** 21 | * @private 22 | * @internal 23 | */ 24 | export class Span { 25 | constructor(private span?: OpenTelemetrySpan) {} 26 | 27 | end(): void { 28 | this.span?.end(); 29 | } 30 | 31 | addEvent(name: string, attributes?: Attributes): this { 32 | this.span = this.span?.addEvent(name, attributes); 33 | return this; 34 | } 35 | 36 | setAttributes(attributes: Attributes): this { 37 | this.span = this.span?.setAttributes(attributes); 38 | return this; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /dev/src/v1/firestore_admin_proto_list.json: -------------------------------------------------------------------------------- 1 | [ 2 | "../../protos/google/firestore/admin/v1/backup.proto", 3 | "../../protos/google/firestore/admin/v1/database.proto", 4 | "../../protos/google/firestore/admin/v1/field.proto", 5 | "../../protos/google/firestore/admin/v1/firestore_admin.proto", 6 | "../../protos/google/firestore/admin/v1/index.proto", 7 | "../../protos/google/firestore/admin/v1/location.proto", 8 | "../../protos/google/firestore/admin/v1/operation.proto", 9 | "../../protos/google/firestore/admin/v1/schedule.proto" 10 | ] 11 | -------------------------------------------------------------------------------- /dev/src/v1/firestore_proto_list.json: -------------------------------------------------------------------------------- 1 | [ 2 | "../../protos/google/firestore/v1/aggregation_result.proto", 3 | "../../protos/google/firestore/v1/bloom_filter.proto", 4 | "../../protos/google/firestore/v1/common.proto", 5 | "../../protos/google/firestore/v1/document.proto", 6 | "../../protos/google/firestore/v1/firestore.proto", 7 | "../../protos/google/firestore/v1/query.proto", 8 | "../../protos/google/firestore/v1/query_profile.proto", 9 | "../../protos/google/firestore/v1/write.proto" 10 | ] 11 | -------------------------------------------------------------------------------- /dev/src/v1/index.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import {FirestoreAdminClient} from './firestore_admin_client'; 16 | import {FirestoreClient} from './firestore_client'; 17 | 18 | export {FirestoreClient, FirestoreAdminClient}; 19 | 20 | // Doing something really horrible for reverse compatibility with original JavaScript exports 21 | const existingExports = module.exports; 22 | module.exports = FirestoreClient; 23 | module.exports = Object.assign(module.exports, existingExports); 24 | -------------------------------------------------------------------------------- /dev/src/v1beta1/firestore_proto_list.json: -------------------------------------------------------------------------------- 1 | [ 2 | "../../protos/google/firestore/v1beta1/common.proto", 3 | "../../protos/google/firestore/v1beta1/document.proto", 4 | "../../protos/google/firestore/v1beta1/firestore.proto", 5 | "../../protos/google/firestore/v1beta1/query.proto", 6 | "../../protos/google/firestore/v1beta1/undeliverable_first_gen_event.proto", 7 | "../../protos/google/firestore/v1beta1/write.proto" 8 | ] 9 | -------------------------------------------------------------------------------- /dev/src/v1beta1/index.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // https://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | // 15 | // ** This file is automatically generated by gapic-generator-typescript. ** 16 | // ** https://github.com/googleapis/gapic-generator-typescript ** 17 | // ** All changes to this file may be overwritten. ** 18 | 19 | // tslint:disable deprecation 20 | 21 | import {FirestoreClient} from './firestore_client'; 22 | export {FirestoreClient}; 23 | 24 | // Doing something really horrible for reverse compatibility with original JavaScript exports 25 | const existingExports = module.exports; 26 | module.exports = FirestoreClient; 27 | module.exports = Object.assign(module.exports, existingExports); 28 | -------------------------------------------------------------------------------- /dev/test/lazy-load.ts: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | import {describe, it} from 'mocha'; 16 | import {expect} from 'chai'; 17 | 18 | function isModuleLoaded(moduleName: string) { 19 | return !!Object.keys(require.cache).find( 20 | path => path.indexOf(`node_modules/${moduleName}`) !== -1 21 | ); 22 | } 23 | 24 | describe('Index.js', () => { 25 | (isModuleLoaded('google-gax') ? it.skip : it)( 26 | 'does not load google-gax', 27 | () => { 28 | require('../src/index'); 29 | expect(isModuleLoaded('google-gax')).to.be.false; 30 | } 31 | ); 32 | 33 | (isModuleLoaded('protobufjs') ? it.skip : it)( 34 | 'does not load protobufjs', 35 | () => { 36 | require('../src/index'); 37 | expect(isModuleLoaded('protobufjs')).to.be.false; 38 | } 39 | ); 40 | }); 41 | -------------------------------------------------------------------------------- /dev/test/mocha.opts: -------------------------------------------------------------------------------- 1 | --enable-source-maps 2 | --timeout 2000 3 | --throw-deprecation 4 | -------------------------------------------------------------------------------- /docfx.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/googleapis/nodejs-firestore/3955811061106db04f56919262b3f97408296592/docfx.json -------------------------------------------------------------------------------- /linkinator.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "recurse": true, 3 | "skip": [ 4 | "https://codecov.io/gh/googleapis/", 5 | "www.googleapis.com", 6 | "img.shields.io" 7 | ], 8 | "silent": true, 9 | "concurrency": 10 10 | } 11 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "config:base", 4 | "docker:disable", 5 | ":disableDependencyDashboard" 6 | ], 7 | "constraintsFiltering": "strict", 8 | "pinVersions": false, 9 | "rebaseStalePrs": true, 10 | "schedule": [ 11 | "after 9am and before 3pm" 12 | ], 13 | "gitAuthor": null, 14 | "packageRules": [ 15 | { 16 | "extends": "packages:linters", 17 | "groupName": "linters" 18 | } 19 | ], 20 | "ignoreDeps": ["typescript"] 21 | } 22 | -------------------------------------------------------------------------------- /samples/.eslintrc.yml: -------------------------------------------------------------------------------- 1 | --- 2 | rules: 3 | no-console: off 4 | no-unused-vars: off 5 | node/no-unpublished-require: off 6 | -------------------------------------------------------------------------------- /samples/limit-to-last-query.js: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 'use strict'; 16 | 17 | // [START firestore_limit_to_last_query] 18 | const {Firestore} = require('@google-cloud/firestore'); 19 | 20 | // Create a new client 21 | const firestore = new Firestore(); 22 | 23 | async function limitToLastQuery() { 24 | const collectionReference = firestore.collection('cities'); 25 | const cityDocuments = await collectionReference 26 | .orderBy('name') 27 | .limitToLast(2) 28 | .get(); 29 | const cityDocumentData = cityDocuments.docs.map(d => d.data()); 30 | cityDocumentData.forEach(doc => { 31 | console.log(doc.name); 32 | }); 33 | } 34 | limitToLastQuery(); 35 | // [END firestore_limit_to_last_query] 36 | -------------------------------------------------------------------------------- /samples/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@google-cloud/firestore-samples", 3 | "private": true, 4 | "license": "Apache-2.0", 5 | "author": "Google Inc.", 6 | "repository": "googleapis/nodejs-firestore", 7 | "engines": { 8 | "node": ">=12.0.0" 9 | }, 10 | "scripts": { 11 | "test": "mocha --timeout 600000" 12 | }, 13 | "dependencies": { 14 | "@google-cloud/firestore": "^7.11.1" 15 | }, 16 | "devDependencies": { 17 | "chai": "^4.2.0", 18 | "mocha": "^7.0.0" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /samples/test/quickstart.test.js: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 'use strict'; 16 | 17 | const {execSync} = require('child_process'); 18 | const {assert} = require('chai'); 19 | const {describe, it} = require('mocha'); 20 | const exec = cmd => execSync(cmd, {encoding: 'utf8'}); 21 | 22 | describe('should make some API calls', () => { 23 | it('should run quickstart', () => { 24 | const output = exec('node quickstart.js'); 25 | assert.include(output, 'Entered new data into the document'); 26 | assert.include(output, 'Updated an existing document'); 27 | assert.include(output, 'Read the document'); 28 | assert.include(output, 'Deleted the document'); 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /samples/test/solution-counters.test.js: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 'use strict'; 16 | 17 | const {execSync} = require('child_process'); 18 | const {assert} = require('chai'); 19 | const {describe, it} = require('mocha'); 20 | const exec = cmd => execSync(cmd, {encoding: 'utf8'}); 21 | 22 | describe('distributed counter', () => { 23 | it('should increase, get counter and delete the docs', () => { 24 | const output = exec('node solution-counters.js'); 25 | assert.include(output, 'counter increased'); 26 | assert.include(output, 'new count is : 1'); 27 | assert.include(output, 'Deleted the document'); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /scripts/.eslintrc.yml: -------------------------------------------------------------------------------- 1 | --- 2 | rules: 3 | no-console: off 4 | no-unused-vars: off 5 | node/no-unpublished-require: off 6 | node/no-extraneous-require: off 7 | 8 | -------------------------------------------------------------------------------- /scripts/init-directories.js: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Google LLC 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | const mkdirp = require('mkdirp'); 16 | 17 | // We have to manually add the directory here because the docker image that 18 | // runs CI does not have this directory. We also can't use `mkdir -p` in the 19 | // package.json file because CI is also run on Windows, which does not support 20 | // the `-p` flag. 21 | mkdirp.sync('build/conformance/conformance-tests'); 22 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./node_modules/gts/tsconfig-google.json", 3 | "compilerOptions": { 4 | "resolveJsonModule": true, 5 | "outDir": "build", 6 | "lib": [ 7 | "es2016", 8 | "dom" 9 | ], 10 | "useUnknownInCatchVariables": false, 11 | }, 12 | "include": [ 13 | "dev/src/*.d.ts", 14 | "dev/src/*.ts", 15 | "dev/src/**/*.ts", 16 | "dev/test/*.ts", 17 | "dev/test/**/*.ts", 18 | "dev/system-test/*.ts", 19 | "dev/conformance/*.ts", 20 | "types/*.d.ts" 21 | ] 22 | } 23 | --------------------------------------------------------------------------------