firebase-admin-edge 1.1.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +103 -260
- package/dist/app-check/app-check-endpoints.d.ts +31 -0
- package/dist/app-check/app-check-endpoints.d.ts.map +1 -0
- package/dist/app-check/app-check-endpoints.js +75 -0
- package/dist/app-check/app-check-endpoints.js.map +1 -0
- package/dist/app-check/app-check-jwt.d.ts +16 -0
- package/dist/app-check/app-check-jwt.d.ts.map +1 -0
- package/dist/app-check/app-check-jwt.js +59 -0
- package/dist/app-check/app-check-jwt.js.map +1 -0
- package/dist/app-check/app-check.d.ts +48 -0
- package/dist/app-check/app-check.d.ts.map +1 -0
- package/dist/app-check/app-check.js +142 -0
- package/dist/app-check/app-check.js.map +1 -0
- package/dist/auth/auth-blocking-types.d.ts +44 -0
- package/dist/auth/auth-blocking-types.d.ts.map +1 -0
- package/dist/auth/auth-blocking-types.js +2 -0
- package/dist/auth/auth-blocking-types.js.map +1 -0
- package/dist/auth/auth-config-types.d.ts +146 -0
- package/dist/auth/auth-config-types.d.ts.map +1 -0
- package/dist/auth/auth-config-types.js +2 -0
- package/dist/auth/auth-config-types.js.map +1 -0
- package/dist/auth/auth-config.d.ts +15 -0
- package/dist/auth/auth-config.d.ts.map +1 -0
- package/dist/auth/auth-config.js +413 -0
- package/dist/auth/auth-config.js.map +1 -0
- package/dist/auth/auth-emulator.d.ts +7 -0
- package/dist/auth/auth-emulator.d.ts.map +1 -0
- package/dist/auth/auth-emulator.js +24 -0
- package/dist/auth/auth-emulator.js.map +1 -0
- package/dist/auth/auth-endpoint-errors.d.ts +2 -0
- package/dist/auth/auth-endpoint-errors.d.ts.map +1 -1
- package/dist/auth/auth-endpoint-errors.js +20 -1
- package/dist/auth/auth-endpoint-errors.js.map +1 -1
- package/dist/auth/email-link.d.ts +24 -0
- package/dist/auth/email-link.d.ts.map +1 -0
- package/dist/auth/email-link.js +103 -0
- package/dist/auth/email-link.js.map +1 -0
- package/dist/auth/firebase-admin-auth.d.ts +56 -8
- package/dist/auth/firebase-admin-auth.d.ts.map +1 -1
- package/dist/auth/firebase-admin-auth.js +323 -63
- package/dist/auth/firebase-admin-auth.js.map +1 -1
- package/dist/auth/firebase-auth-endpoints.d.ts +93 -5
- package/dist/auth/firebase-auth-endpoints.d.ts.map +1 -1
- package/dist/auth/firebase-auth-endpoints.js +342 -73
- package/dist/auth/firebase-auth-endpoints.js.map +1 -1
- package/dist/auth/firebase-auth.d.ts +82 -6
- package/dist/auth/firebase-auth.d.ts.map +1 -1
- package/dist/auth/firebase-auth.js +103 -10
- package/dist/auth/firebase-auth.js.map +1 -1
- package/dist/auth/firebase-jwt.d.ts +19 -10
- package/dist/auth/firebase-jwt.d.ts.map +1 -1
- package/dist/auth/firebase-jwt.js +176 -39
- package/dist/auth/firebase-jwt.js.map +1 -1
- package/dist/auth/firebase-types.d.ts +3 -0
- package/dist/auth/firebase-types.d.ts.map +1 -1
- package/dist/auth/google-oauth.d.ts +0 -1
- package/dist/auth/google-oauth.d.ts.map +1 -1
- package/dist/auth/google-oauth.js +16 -86
- package/dist/auth/google-oauth.js.map +1 -1
- package/dist/auth/identity-builder-types.d.ts +36 -0
- package/dist/auth/identity-builder-types.d.ts.map +1 -0
- package/dist/auth/identity-builder-types.js +2 -0
- package/dist/auth/identity-builder-types.js.map +1 -0
- package/dist/auth/identity-count-query.d.ts +17 -0
- package/dist/auth/identity-count-query.d.ts.map +1 -0
- package/dist/auth/identity-count-query.js +51 -0
- package/dist/auth/identity-count-query.js.map +1 -0
- package/dist/auth/identity-filter.d.ts +9 -0
- package/dist/auth/identity-filter.d.ts.map +1 -0
- package/dist/auth/identity-filter.js +129 -0
- package/dist/auth/identity-filter.js.map +1 -0
- package/dist/auth/identity-query.d.ts +11 -0
- package/dist/auth/identity-query.d.ts.map +1 -0
- package/dist/auth/identity-query.js +122 -0
- package/dist/auth/identity-query.js.map +1 -0
- package/dist/auth/identity-reference.d.ts +131 -0
- package/dist/auth/identity-reference.d.ts.map +1 -0
- package/dist/auth/identity-reference.js +293 -0
- package/dist/auth/identity-reference.js.map +1 -0
- package/dist/auth/identity-types.d.ts +44 -0
- package/dist/auth/identity-types.d.ts.map +1 -0
- package/dist/auth/identity-types.js +2 -0
- package/dist/auth/identity-types.js.map +1 -0
- package/dist/auth/identity-write.d.ts +41 -0
- package/dist/auth/identity-write.d.ts.map +1 -0
- package/dist/auth/identity-write.js +146 -0
- package/dist/auth/identity-write.js.map +1 -0
- package/dist/auth/identity.d.ts +84 -0
- package/dist/auth/identity.d.ts.map +1 -0
- package/dist/auth/identity.js +319 -0
- package/dist/auth/identity.js.map +1 -0
- package/dist/auth/project-config-manager.d.ts +10 -0
- package/dist/auth/project-config-manager.d.ts.map +1 -0
- package/dist/auth/project-config-manager.js +22 -0
- package/dist/auth/project-config-manager.js.map +1 -0
- package/dist/auth/provider-credential.d.ts +43 -0
- package/dist/auth/provider-credential.d.ts.map +1 -0
- package/dist/auth/provider-credential.js +107 -0
- package/dist/auth/provider-credential.js.map +1 -0
- package/dist/auth/provider-session.d.ts +10 -0
- package/dist/auth/provider-session.d.ts.map +1 -0
- package/dist/auth/provider-session.js +28 -0
- package/dist/auth/provider-session.js.map +1 -0
- package/dist/auth/tenant-manager.d.ts +17 -0
- package/dist/auth/tenant-manager.d.ts.map +1 -0
- package/dist/auth/tenant-manager.js +59 -0
- package/dist/auth/tenant-manager.js.map +1 -0
- package/dist/auth/user-import.d.ts +7 -1
- package/dist/auth/user-import.d.ts.map +1 -1
- package/dist/auth/user-import.js +53 -15
- package/dist/auth/user-import.js.map +1 -1
- package/dist/auth/user-record.d.ts +1 -0
- package/dist/auth/user-record.d.ts.map +1 -1
- package/dist/auth/user-record.js +5 -0
- package/dist/auth/user-record.js.map +1 -1
- package/dist/auth/user-request.d.ts +4 -1
- package/dist/auth/user-request.d.ts.map +1 -1
- package/dist/auth/user-request.js +7 -4
- package/dist/auth/user-request.js.map +1 -1
- package/dist/db/aggregate.d.ts +49 -0
- package/dist/db/aggregate.d.ts.map +1 -0
- package/dist/db/aggregate.js +115 -0
- package/dist/db/aggregate.js.map +1 -0
- package/dist/db/bulk-writer.d.ts +55 -0
- package/dist/db/bulk-writer.d.ts.map +1 -0
- package/dist/db/bulk-writer.js +257 -0
- package/dist/db/bulk-writer.js.map +1 -0
- package/dist/db/bundle-builder.d.ts +17 -0
- package/dist/db/bundle-builder.d.ts.map +1 -0
- package/dist/db/bundle-builder.js +118 -0
- package/dist/db/bundle-builder.js.map +1 -0
- package/dist/db/bytes.d.ts +12 -0
- package/dist/db/bytes.d.ts.map +1 -0
- package/dist/db/bytes.js +49 -0
- package/dist/db/bytes.js.map +1 -0
- package/dist/db/collection-group.d.ts +14 -0
- package/dist/db/collection-group.d.ts.map +1 -0
- package/dist/db/collection-group.js +43 -0
- package/dist/db/collection-group.js.map +1 -0
- package/dist/db/collection-reference.d.ts +21 -0
- package/dist/db/collection-reference.d.ts.map +1 -0
- package/dist/db/collection-reference.js +46 -0
- package/dist/db/collection-reference.js.map +1 -0
- package/dist/db/document-reference.d.ts +41 -0
- package/dist/db/document-reference.d.ts.map +1 -0
- package/dist/db/document-reference.js +125 -0
- package/dist/db/document-reference.js.map +1 -0
- package/dist/db/document-snapshot.d.ts +31 -0
- package/dist/db/document-snapshot.d.ts.map +1 -0
- package/dist/db/document-snapshot.js +103 -0
- package/dist/db/document-snapshot.js.map +1 -0
- package/dist/db/explain.d.ts +28 -0
- package/dist/db/explain.d.ts.map +1 -0
- package/dist/db/explain.js +61 -0
- package/dist/db/explain.js.map +1 -0
- package/dist/db/field-path.d.ts +10 -0
- package/dist/db/field-path.d.ts.map +1 -0
- package/dist/db/field-path.js +65 -0
- package/dist/db/field-path.js.map +1 -0
- package/dist/db/field-value.d.ts +17 -0
- package/dist/db/field-value.d.ts.map +1 -0
- package/dist/db/field-value.js +57 -0
- package/dist/db/field-value.js.map +1 -0
- package/dist/db/filter.d.ts +20 -0
- package/dist/db/filter.d.ts.map +1 -0
- package/dist/db/filter.js +48 -0
- package/dist/db/filter.js.map +1 -0
- package/dist/db/firestore-converter.d.ts +11 -0
- package/dist/db/firestore-converter.d.ts.map +1 -0
- package/dist/db/firestore-converter.js +14 -0
- package/dist/db/firestore-converter.js.map +1 -0
- package/dist/db/firestore-document.d.ts +62 -0
- package/dist/db/firestore-document.d.ts.map +1 -0
- package/dist/db/firestore-document.js +238 -0
- package/dist/db/firestore-document.js.map +1 -0
- package/dist/db/firestore-endpoints.d.ts +41 -0
- package/dist/db/firestore-endpoints.d.ts.map +1 -0
- package/dist/db/firestore-endpoints.js +735 -0
- package/dist/db/firestore-endpoints.js.map +1 -0
- package/dist/db/firestore-error-codes.d.ts +24 -0
- package/dist/db/firestore-error-codes.d.ts.map +1 -0
- package/dist/db/firestore-error-codes.js +24 -0
- package/dist/db/firestore-error-codes.js.map +1 -0
- package/dist/db/firestore-logging.d.ts +23 -0
- package/dist/db/firestore-logging.d.ts.map +1 -0
- package/dist/db/firestore-logging.js +41 -0
- package/dist/db/firestore-logging.js.map +1 -0
- package/dist/db/firestore-path.d.ts +4 -0
- package/dist/db/firestore-path.d.ts.map +1 -0
- package/dist/db/firestore-path.js +37 -0
- package/dist/db/firestore-path.js.map +1 -0
- package/dist/db/firestore-results.d.ts +12 -0
- package/dist/db/firestore-results.d.ts.map +1 -0
- package/dist/db/firestore-results.js +19 -0
- package/dist/db/firestore-results.js.map +1 -0
- package/dist/db/firestore-settings.d.ts +22 -0
- package/dist/db/firestore-settings.d.ts.map +1 -0
- package/dist/db/firestore-settings.js +83 -0
- package/dist/db/firestore-settings.js.map +1 -0
- package/dist/db/firestore-telemetry.d.ts +21 -0
- package/dist/db/firestore-telemetry.d.ts.map +1 -0
- package/dist/db/firestore-telemetry.js +84 -0
- package/dist/db/firestore-telemetry.js.map +1 -0
- package/dist/db/firestore-types.d.ts +25 -0
- package/dist/db/firestore-types.d.ts.map +1 -0
- package/dist/db/firestore-types.js +2 -0
- package/dist/db/firestore-types.js.map +1 -0
- package/dist/db/firestore.d.ts +157 -0
- package/dist/db/firestore.d.ts.map +1 -0
- package/dist/db/firestore.js +513 -0
- package/dist/db/firestore.js.map +1 -0
- package/dist/db/geo-point.d.ts +11 -0
- package/dist/db/geo-point.d.ts.map +1 -0
- package/dist/db/geo-point.js +29 -0
- package/dist/db/geo-point.js.map +1 -0
- package/dist/db/json-stream.d.ts +3 -0
- package/dist/db/json-stream.d.ts.map +1 -0
- package/dist/db/json-stream.js +117 -0
- package/dist/db/json-stream.js.map +1 -0
- package/dist/db/pipeline-expression.d.ts +293 -0
- package/dist/db/pipeline-expression.d.ts.map +1 -0
- package/dist/db/pipeline-expression.js +1436 -0
- package/dist/db/pipeline-expression.js.map +1 -0
- package/dist/db/pipeline-query.d.ts +6 -0
- package/dist/db/pipeline-query.d.ts.map +1 -0
- package/dist/db/pipeline-query.js +91 -0
- package/dist/db/pipeline-query.js.map +1 -0
- package/dist/db/pipeline.d.ts +120 -0
- package/dist/db/pipeline.d.ts.map +1 -0
- package/dist/db/pipeline.js +396 -0
- package/dist/db/pipeline.js.map +1 -0
- package/dist/db/query-document-snapshot.d.ts +2 -0
- package/dist/db/query-document-snapshot.d.ts.map +1 -0
- package/dist/db/query-document-snapshot.js +2 -0
- package/dist/db/query-document-snapshot.js.map +1 -0
- package/dist/db/query-partition.d.ts +14 -0
- package/dist/db/query-partition.d.ts.map +1 -0
- package/dist/db/query-partition.js +32 -0
- package/dist/db/query-partition.js.map +1 -0
- package/dist/db/query-request.d.ts +96 -0
- package/dist/db/query-request.d.ts.map +1 -0
- package/dist/db/query-request.js +283 -0
- package/dist/db/query-request.js.map +1 -0
- package/dist/db/query.d.ts +129 -0
- package/dist/db/query.d.ts.map +1 -0
- package/dist/db/query.js +468 -0
- package/dist/db/query.js.map +1 -0
- package/dist/db/recursive-delete.d.ts +6 -0
- package/dist/db/recursive-delete.d.ts.map +1 -0
- package/dist/db/recursive-delete.js +38 -0
- package/dist/db/recursive-delete.js.map +1 -0
- package/dist/db/snapshot-listener.d.ts +10 -0
- package/dist/db/snapshot-listener.d.ts.map +1 -0
- package/dist/db/snapshot-listener.js +71 -0
- package/dist/db/snapshot-listener.js.map +1 -0
- package/dist/db/timestamp.d.ts +29 -0
- package/dist/db/timestamp.d.ts.map +1 -0
- package/dist/db/timestamp.js +98 -0
- package/dist/db/timestamp.js.map +1 -0
- package/dist/db/transaction.d.ts +44 -0
- package/dist/db/transaction.d.ts.map +1 -0
- package/dist/db/transaction.js +177 -0
- package/dist/db/transaction.js.map +1 -0
- package/dist/db/value-equality.d.ts +3 -0
- package/dist/db/value-equality.d.ts.map +1 -0
- package/dist/db/value-equality.js +29 -0
- package/dist/db/value-equality.js.map +1 -0
- package/dist/db/vector-query.d.ts +38 -0
- package/dist/db/vector-query.d.ts.map +1 -0
- package/dist/db/vector-query.js +110 -0
- package/dist/db/vector-query.js.map +1 -0
- package/dist/db/vector-value.d.ts +8 -0
- package/dist/db/vector-value.d.ts.map +1 -0
- package/dist/db/vector-value.js +25 -0
- package/dist/db/vector-value.js.map +1 -0
- package/dist/db/write-batch.d.ts +25 -0
- package/dist/db/write-batch.d.ts.map +1 -0
- package/dist/db/write-batch.js +72 -0
- package/dist/db/write-batch.js.map +1 -0
- package/dist/db/write-request.d.ts +36 -0
- package/dist/db/write-request.d.ts.map +1 -0
- package/dist/db/write-request.js +257 -0
- package/dist/db/write-request.js.map +1 -0
- package/dist/firebase-edge-server.d.ts +145 -36
- package/dist/firebase-edge-server.d.ts.map +1 -1
- package/dist/firebase-edge-server.js +495 -258
- package/dist/firebase-edge-server.js.map +1 -1
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/rest-fetch.d.ts +1 -1
- package/dist/rest-fetch.d.ts.map +1 -1
- package/dist/storage/storage-acl.d.ts +48 -0
- package/dist/storage/storage-acl.d.ts.map +1 -0
- package/dist/storage/storage-acl.js +101 -0
- package/dist/storage/storage-acl.js.map +1 -0
- package/dist/storage/storage-bucket-endpoints.d.ts +10 -0
- package/dist/storage/storage-bucket-endpoints.d.ts.map +1 -0
- package/dist/storage/storage-bucket-endpoints.js +514 -0
- package/dist/storage/storage-bucket-endpoints.js.map +1 -0
- package/dist/storage/storage-bucket-types.d.ts +183 -0
- package/dist/storage/storage-bucket-types.d.ts.map +1 -0
- package/dist/storage/storage-bucket-types.js +2 -0
- package/dist/storage/storage-bucket-types.js.map +1 -0
- package/dist/storage/storage-bucket.d.ts +122 -0
- package/dist/storage/storage-bucket.d.ts.map +1 -0
- package/dist/storage/storage-bucket.js +544 -0
- package/dist/storage/storage-bucket.js.map +1 -0
- package/dist/storage/storage-channel.d.ts +10 -0
- package/dist/storage/storage-channel.d.ts.map +1 -0
- package/dist/storage/storage-channel.js +15 -0
- package/dist/storage/storage-channel.js.map +1 -0
- package/dist/storage/storage-checksum.d.ts +35 -0
- package/dist/storage/storage-checksum.d.ts.map +1 -0
- package/dist/storage/storage-checksum.js +312 -0
- package/dist/storage/storage-checksum.js.map +1 -0
- package/dist/storage/storage-endpoints.d.ts +14 -0
- package/dist/storage/storage-endpoints.d.ts.map +1 -0
- package/dist/storage/storage-endpoints.js +721 -0
- package/dist/storage/storage-endpoints.js.map +1 -0
- package/dist/storage/storage-file.d.ts +126 -0
- package/dist/storage/storage-file.d.ts.map +1 -0
- package/dist/storage/storage-file.js +604 -0
- package/dist/storage/storage-file.js.map +1 -0
- package/dist/storage/storage-hmac-key.d.ts +26 -0
- package/dist/storage/storage-hmac-key.d.ts.map +1 -0
- package/dist/storage/storage-hmac-key.js +45 -0
- package/dist/storage/storage-hmac-key.js.map +1 -0
- package/dist/storage/storage-iam.d.ts +20 -0
- package/dist/storage/storage-iam.d.ts.map +1 -0
- package/dist/storage/storage-iam.js +43 -0
- package/dist/storage/storage-iam.js.map +1 -0
- package/dist/storage/storage-md5.d.ts +11 -0
- package/dist/storage/storage-md5.d.ts.map +1 -0
- package/dist/storage/storage-md5.js +96 -0
- package/dist/storage/storage-md5.js.map +1 -0
- package/dist/storage/storage-notification.d.ts +24 -0
- package/dist/storage/storage-notification.d.ts.map +1 -0
- package/dist/storage/storage-notification.js +40 -0
- package/dist/storage/storage-notification.js.map +1 -0
- package/dist/storage/storage-progress.d.ts +4 -0
- package/dist/storage/storage-progress.d.ts.map +1 -0
- package/dist/storage/storage-progress.js +17 -0
- package/dist/storage/storage-progress.js.map +1 -0
- package/dist/storage/storage-reference-endpoints.d.ts +63 -0
- package/dist/storage/storage-reference-endpoints.d.ts.map +1 -0
- package/dist/storage/storage-reference-endpoints.js +276 -0
- package/dist/storage/storage-reference-endpoints.js.map +1 -0
- package/dist/storage/storage-reference-helpers.d.ts +12 -0
- package/dist/storage/storage-reference-helpers.d.ts.map +1 -0
- package/dist/storage/storage-reference-helpers.js +72 -0
- package/dist/storage/storage-reference-helpers.js.map +1 -0
- package/dist/storage/storage-reference-signing.d.ts +40 -0
- package/dist/storage/storage-reference-signing.d.ts.map +1 -0
- package/dist/storage/storage-reference-signing.js +289 -0
- package/dist/storage/storage-reference-signing.js.map +1 -0
- package/dist/storage/storage-reference-types.d.ts +76 -0
- package/dist/storage/storage-reference-types.d.ts.map +1 -0
- package/dist/storage/storage-reference-types.js +2 -0
- package/dist/storage/storage-reference-types.js.map +1 -0
- package/dist/storage/storage-results.d.ts +8 -0
- package/dist/storage/storage-results.d.ts.map +1 -0
- package/dist/storage/storage-results.js +32 -0
- package/dist/storage/storage-results.js.map +1 -0
- package/dist/storage/storage-resumable.d.ts +18 -0
- package/dist/storage/storage-resumable.d.ts.map +1 -0
- package/dist/storage/storage-resumable.js +166 -0
- package/dist/storage/storage-resumable.js.map +1 -0
- package/dist/storage/storage-retry.d.ts +9 -0
- package/dist/storage/storage-retry.d.ts.map +1 -0
- package/dist/storage/storage-retry.js +104 -0
- package/dist/storage/storage-retry.js.map +1 -0
- package/dist/storage/storage-signed-url.d.ts +9 -0
- package/dist/storage/storage-signed-url.d.ts.map +1 -0
- package/dist/storage/storage-signed-url.js +96 -0
- package/dist/storage/storage-signed-url.js.map +1 -0
- package/dist/storage/storage-special-endpoints.d.ts +10 -0
- package/dist/storage/storage-special-endpoints.d.ts.map +1 -0
- package/dist/storage/storage-special-endpoints.js +394 -0
- package/dist/storage/storage-special-endpoints.js.map +1 -0
- package/dist/storage/storage-special-types.d.ts +154 -0
- package/dist/storage/storage-special-types.d.ts.map +1 -0
- package/dist/storage/storage-special-types.js +2 -0
- package/dist/storage/storage-special-types.js.map +1 -0
- package/dist/storage/storage-types.d.ts +251 -0
- package/dist/storage/storage-types.d.ts.map +1 -0
- package/dist/storage/storage-types.js +2 -0
- package/dist/storage/storage-types.js.map +1 -0
- package/dist/storage/storage-upload-stream.d.ts +41 -0
- package/dist/storage/storage-upload-stream.d.ts.map +1 -0
- package/dist/storage/storage-upload-stream.js +335 -0
- package/dist/storage/storage-upload-stream.js.map +1 -0
- package/dist/storage/storage-xml-signing.d.ts +17 -0
- package/dist/storage/storage-xml-signing.d.ts.map +1 -0
- package/dist/storage/storage-xml-signing.js +144 -0
- package/dist/storage/storage-xml-signing.js.map +1 -0
- package/dist/storage/storage.d.ts +159 -0
- package/dist/storage/storage.d.ts.map +1 -0
- package/dist/storage/storage.js +545 -0
- package/dist/storage/storage.js.map +1 -0
- package/dist/utils/token-cache.d.ts.map +1 -1
- package/dist/utils/token-cache.js +3 -2
- package/dist/utils/token-cache.js.map +1 -1
- package/package.json +24 -8
- package/dist/auth/auth-endpoint-errors.test.d.ts +0 -2
- package/dist/auth/auth-endpoint-errors.test.d.ts.map +0 -1
- package/dist/auth/auth-endpoint-errors.test.js +0 -411
- package/dist/auth/auth-endpoint-errors.test.js.map +0 -1
- package/dist/auth/email-action-request.test.d.ts +0 -2
- package/dist/auth/email-action-request.test.d.ts.map +0 -1
- package/dist/auth/email-action-request.test.js +0 -128
- package/dist/auth/email-action-request.test.js.map +0 -1
- package/dist/auth/errors.test.d.ts +0 -2
- package/dist/auth/errors.test.d.ts.map +0 -1
- package/dist/auth/errors.test.js +0 -123
- package/dist/auth/errors.test.js.map +0 -1
- package/dist/auth/firebase-admin-auth.test.d.ts +0 -2
- package/dist/auth/firebase-admin-auth.test.d.ts.map +0 -1
- package/dist/auth/firebase-admin-auth.test.js +0 -1542
- package/dist/auth/firebase-admin-auth.test.js.map +0 -1
- package/dist/auth/firebase-auth-endpoints.test.d.ts +0 -2
- package/dist/auth/firebase-auth-endpoints.test.d.ts.map +0 -1
- package/dist/auth/firebase-auth-endpoints.test.js +0 -1082
- package/dist/auth/firebase-auth-endpoints.test.js.map +0 -1
- package/dist/auth/firebase-auth.test.d.ts +0 -2
- package/dist/auth/firebase-auth.test.d.ts.map +0 -1
- package/dist/auth/firebase-auth.test.js +0 -167
- package/dist/auth/firebase-auth.test.js.map +0 -1
- package/dist/auth/firebase-jwt.test.d.ts +0 -2
- package/dist/auth/firebase-jwt.test.d.ts.map +0 -1
- package/dist/auth/firebase-jwt.test.js +0 -164
- package/dist/auth/firebase-jwt.test.js.map +0 -1
- package/dist/auth/github-oauth.d.ts +0 -19
- package/dist/auth/github-oauth.d.ts.map +0 -1
- package/dist/auth/github-oauth.js +0 -145
- package/dist/auth/github-oauth.js.map +0 -1
- package/dist/auth/github-oauth.test.d.ts +0 -2
- package/dist/auth/github-oauth.test.d.ts.map +0 -1
- package/dist/auth/github-oauth.test.js +0 -202
- package/dist/auth/github-oauth.test.js.map +0 -1
- package/dist/auth/google-oauth.test.d.ts +0 -2
- package/dist/auth/google-oauth.test.d.ts.map +0 -1
- package/dist/auth/google-oauth.test.js +0 -200
- package/dist/auth/google-oauth.test.js.map +0 -1
- package/dist/auth/oauth.d.ts +0 -3
- package/dist/auth/oauth.d.ts.map +0 -1
- package/dist/auth/oauth.js +0 -48
- package/dist/auth/oauth.js.map +0 -1
- package/dist/auth/oauth.test.d.ts +0 -2
- package/dist/auth/oauth.test.d.ts.map +0 -1
- package/dist/auth/oauth.test.js +0 -109
- package/dist/auth/oauth.test.js.map +0 -1
- package/dist/auth/user-batch.test.d.ts +0 -2
- package/dist/auth/user-batch.test.d.ts.map +0 -1
- package/dist/auth/user-batch.test.js +0 -73
- package/dist/auth/user-batch.test.js.map +0 -1
- package/dist/auth/user-import.test.d.ts +0 -2
- package/dist/auth/user-import.test.d.ts.map +0 -1
- package/dist/auth/user-import.test.js +0 -217
- package/dist/auth/user-import.test.js.map +0 -1
- package/dist/auth/user-record.test.d.ts +0 -2
- package/dist/auth/user-record.test.d.ts.map +0 -1
- package/dist/auth/user-record.test.js +0 -198
- package/dist/auth/user-record.test.js.map +0 -1
- package/dist/auth/user-request.test.d.ts +0 -2
- package/dist/auth/user-request.test.d.ts.map +0 -1
- package/dist/auth/user-request.test.js +0 -327
- package/dist/auth/user-request.test.js.map +0 -1
- package/dist/firebase-edge-errors.test.d.ts +0 -2
- package/dist/firebase-edge-errors.test.d.ts.map +0 -1
- package/dist/firebase-edge-errors.test.js +0 -72
- package/dist/firebase-edge-errors.test.js.map +0 -1
- package/dist/firebase-edge-server.test.d.ts +0 -2
- package/dist/firebase-edge-server.test.d.ts.map +0 -1
- package/dist/firebase-edge-server.test.js +0 -293
- package/dist/firebase-edge-server.test.js.map +0 -1
- package/dist/rest-fetch.test.d.ts +0 -2
- package/dist/rest-fetch.test.d.ts.map +0 -1
- package/dist/rest-fetch.test.js +0 -164
- package/dist/rest-fetch.test.js.map +0 -1
|
@@ -0,0 +1,735 @@
|
|
|
1
|
+
import { traceFirestoreOperation } from './firestore-telemetry.js';
|
|
2
|
+
import { logFirestore } from './firestore-logging.js';
|
|
3
|
+
import { FirestoreErrorInfo } from './firestore-error-codes.js';
|
|
4
|
+
import { restFetch } from '../rest-fetch.js';
|
|
5
|
+
import { FirebaseEdgeError, ensureError } from '../auth/errors.js';
|
|
6
|
+
import { buildStructuredQuery } from './query-request.js';
|
|
7
|
+
import { WriteResult } from './write-request.js';
|
|
8
|
+
import { aggregateReadTime, aggregateMetrics } from './aggregate.js';
|
|
9
|
+
import { decodeFields } from './firestore-document.js';
|
|
10
|
+
import { Timestamp } from './timestamp.js';
|
|
11
|
+
import { readJsonArray } from './json-stream.js';
|
|
12
|
+
import { parseExplainMetrics } from './explain.js';
|
|
13
|
+
export async function batchGetDocuments(projectId, databaseId, paths, token, fetchFn, fieldMask, transaction) {
|
|
14
|
+
const names = paths.map((path) => createDocumentName(projectId, databaseId, path));
|
|
15
|
+
const requestedNames = new Set(names);
|
|
16
|
+
const rows = await firestorePost(projectId, databaseId, '', 'batchGet', {
|
|
17
|
+
documents: [...requestedNames],
|
|
18
|
+
...(transaction ? { transaction } : {}),
|
|
19
|
+
...(fieldMask ? { mask: { fieldPaths: fieldMask } } : {})
|
|
20
|
+
}, token, fetchFn);
|
|
21
|
+
if (!Array.isArray(rows))
|
|
22
|
+
throw new FirebaseEdgeError({
|
|
23
|
+
...FirestoreErrorInfo.INVALID_RESPONSE,
|
|
24
|
+
message: 'Invalid batchGet response.'
|
|
25
|
+
});
|
|
26
|
+
const documents = new Map();
|
|
27
|
+
const readTimes = new Map();
|
|
28
|
+
for (const row of rows) {
|
|
29
|
+
if (row?.error)
|
|
30
|
+
throw mapFirestoreError(row);
|
|
31
|
+
const name = row?.found?.name ?? row?.missing;
|
|
32
|
+
if (!name || !requestedNames.has(name))
|
|
33
|
+
throw new FirebaseEdgeError({
|
|
34
|
+
...FirestoreErrorInfo.INVALID_RESPONSE,
|
|
35
|
+
message: 'Unexpected batchGet document.'
|
|
36
|
+
});
|
|
37
|
+
const readTime = row.readTime;
|
|
38
|
+
if (readTime)
|
|
39
|
+
readTimes.set(name, Timestamp.fromString(readTime));
|
|
40
|
+
documents.set(name, row.found && readTime ? { ...row.found, readTime } : row.found);
|
|
41
|
+
}
|
|
42
|
+
if (names.some((name) => !documents.has(name)))
|
|
43
|
+
throw new FirebaseEdgeError({
|
|
44
|
+
...FirestoreErrorInfo.INVALID_RESPONSE,
|
|
45
|
+
message: 'Incomplete batchGet response.'
|
|
46
|
+
});
|
|
47
|
+
const ordered = names.map((name) => documents.get(name));
|
|
48
|
+
Object.defineProperty(ordered, 'readTimes', {
|
|
49
|
+
value: names.map((name) => readTimes.get(name))
|
|
50
|
+
});
|
|
51
|
+
return ordered;
|
|
52
|
+
}
|
|
53
|
+
export async function listCollectionIds(projectId, databaseId, parent, token, fetchFn) {
|
|
54
|
+
const ids = [];
|
|
55
|
+
let pageToken;
|
|
56
|
+
const seen = new Set();
|
|
57
|
+
do {
|
|
58
|
+
const page = await firestorePost(projectId, databaseId, parent, 'listCollectionIds', { pageSize: 1000, ...(pageToken ? { pageToken } : {}) }, token, fetchFn);
|
|
59
|
+
if (!page ||
|
|
60
|
+
typeof page !== 'object' ||
|
|
61
|
+
Array.isArray(page) ||
|
|
62
|
+
(page.nextPageToken !== undefined &&
|
|
63
|
+
typeof page.nextPageToken !== 'string') ||
|
|
64
|
+
(page.collectionIds !== undefined &&
|
|
65
|
+
(!Array.isArray(page.collectionIds) ||
|
|
66
|
+
page.collectionIds.some((id) => typeof id !== 'string' || !id || id.includes('/')))))
|
|
67
|
+
throw new FirebaseEdgeError({
|
|
68
|
+
...FirestoreErrorInfo.INVALID_RESPONSE,
|
|
69
|
+
message: 'Invalid collection list response.'
|
|
70
|
+
});
|
|
71
|
+
ids.push(...(page.collectionIds ?? []));
|
|
72
|
+
pageToken = page.nextPageToken;
|
|
73
|
+
if (pageToken && seen.has(pageToken))
|
|
74
|
+
throw new FirebaseEdgeError({
|
|
75
|
+
...FirestoreErrorInfo.INVALID_RESPONSE,
|
|
76
|
+
message: 'Repeated collection page token.'
|
|
77
|
+
});
|
|
78
|
+
if (pageToken)
|
|
79
|
+
seen.add(pageToken);
|
|
80
|
+
} while (pageToken);
|
|
81
|
+
return ids;
|
|
82
|
+
}
|
|
83
|
+
export async function listDocumentPaths(projectId, databaseId, path, token, fetchFn) {
|
|
84
|
+
const paths = [];
|
|
85
|
+
let pageToken;
|
|
86
|
+
const seen = new Set();
|
|
87
|
+
do {
|
|
88
|
+
const { data, error } = await restFetch(createDocumentsURL(projectId, databaseId, path), {
|
|
89
|
+
method: 'GET',
|
|
90
|
+
bearerToken: token,
|
|
91
|
+
global: { fetch: fetchFn },
|
|
92
|
+
params: {
|
|
93
|
+
pageSize: '1000',
|
|
94
|
+
showMissing: 'true',
|
|
95
|
+
...(pageToken ? { pageToken } : {})
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
if (error)
|
|
99
|
+
throw mapFirestoreError(error);
|
|
100
|
+
if (!data ||
|
|
101
|
+
typeof data !== 'object' ||
|
|
102
|
+
Array.isArray(data) ||
|
|
103
|
+
(data.nextPageToken !== undefined &&
|
|
104
|
+
typeof data.nextPageToken !== 'string') ||
|
|
105
|
+
(data.documents !== undefined && !Array.isArray(data.documents)))
|
|
106
|
+
throw new FirebaseEdgeError({
|
|
107
|
+
...FirestoreErrorInfo.INVALID_RESPONSE,
|
|
108
|
+
message: 'Invalid document list response.'
|
|
109
|
+
});
|
|
110
|
+
const prefix = `${createDocumentName(projectId, databaseId, '')}/`;
|
|
111
|
+
for (const document of data.documents ?? []) {
|
|
112
|
+
if (typeof document?.name !== 'string' ||
|
|
113
|
+
!document.name.startsWith(`${prefix}${path}/`) ||
|
|
114
|
+
document.name.length === prefix.length + path.length + 1 ||
|
|
115
|
+
document.name
|
|
116
|
+
.slice(prefix.length + path.length + 1)
|
|
117
|
+
.includes('/'))
|
|
118
|
+
throw new FirebaseEdgeError({
|
|
119
|
+
...FirestoreErrorInfo.INVALID_RESPONSE,
|
|
120
|
+
message: 'Invalid listed document name.'
|
|
121
|
+
});
|
|
122
|
+
paths.push(document.name.slice(prefix.length));
|
|
123
|
+
}
|
|
124
|
+
pageToken = data.nextPageToken;
|
|
125
|
+
if (pageToken && seen.has(pageToken))
|
|
126
|
+
throw new FirebaseEdgeError({
|
|
127
|
+
...FirestoreErrorInfo.INVALID_RESPONSE,
|
|
128
|
+
message: 'Repeated document page token.'
|
|
129
|
+
});
|
|
130
|
+
if (pageToken)
|
|
131
|
+
seen.add(pageToken);
|
|
132
|
+
} while (pageToken);
|
|
133
|
+
return paths;
|
|
134
|
+
}
|
|
135
|
+
export async function* streamQuery(projectId, databaseId, collectionPath, options, token, fetchFn, signal) {
|
|
136
|
+
for await (const row of streamQueryRows(projectId, databaseId, collectionPath, options, token, fetchFn, signal))
|
|
137
|
+
if (row.document)
|
|
138
|
+
yield row.document;
|
|
139
|
+
}
|
|
140
|
+
/** @internal Streaming transport shared by ordinary queries and query explain. */
|
|
141
|
+
export async function* streamQueryRows(projectId, databaseId, collectionPath, options, token, fetchFn = globalThis.fetch, signal, explainOptions) {
|
|
142
|
+
const segments = collectionPath.split('/');
|
|
143
|
+
const collectionId = segments.pop();
|
|
144
|
+
const parent = segments.join('/');
|
|
145
|
+
const response = await fetchFn(`${createDocumentsURL(projectId, databaseId, parent)}:runQuery`, {
|
|
146
|
+
method: 'POST',
|
|
147
|
+
headers: {
|
|
148
|
+
Authorization: `Bearer ${token}`,
|
|
149
|
+
'Content-Type': 'application/json',
|
|
150
|
+
Accept: 'application/json'
|
|
151
|
+
},
|
|
152
|
+
body: JSON.stringify({
|
|
153
|
+
...(explainOptions ? { explainOptions } : {}),
|
|
154
|
+
structuredQuery: buildStructuredQuery(collectionId, options, createDocumentName(projectId, databaseId, parent))
|
|
155
|
+
}),
|
|
156
|
+
signal
|
|
157
|
+
});
|
|
158
|
+
if (!response.ok) {
|
|
159
|
+
const message = await response.text();
|
|
160
|
+
let error;
|
|
161
|
+
try {
|
|
162
|
+
error = JSON.parse(message);
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
error = { error: { message } };
|
|
166
|
+
}
|
|
167
|
+
throw mapFirestoreError(error);
|
|
168
|
+
}
|
|
169
|
+
if (!response.body)
|
|
170
|
+
throw new FirebaseEdgeError({
|
|
171
|
+
...FirestoreErrorInfo.INVALID_RESPONSE,
|
|
172
|
+
message: 'Firestore returned no query stream.'
|
|
173
|
+
});
|
|
174
|
+
for await (const value of readJsonArray(response.body)) {
|
|
175
|
+
const row = value;
|
|
176
|
+
if (!row || typeof row !== 'object')
|
|
177
|
+
throw new FirebaseEdgeError({
|
|
178
|
+
...FirestoreErrorInfo.INVALID_RESPONSE,
|
|
179
|
+
message: 'Invalid query stream row.'
|
|
180
|
+
});
|
|
181
|
+
if (row.error)
|
|
182
|
+
throw mapFirestoreError(row);
|
|
183
|
+
if (!row.document) {
|
|
184
|
+
if (row.explainMetrics)
|
|
185
|
+
yield {
|
|
186
|
+
metrics: parseExplainMetrics(row.explainMetrics),
|
|
187
|
+
readTime: row.readTime
|
|
188
|
+
};
|
|
189
|
+
else if (row.readTime)
|
|
190
|
+
yield { readTime: row.readTime };
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
if (typeof row.document.name !== 'string' ||
|
|
194
|
+
!row.document.name.startsWith(`${createDocumentName(projectId, databaseId, '')}/`))
|
|
195
|
+
throw new FirebaseEdgeError({
|
|
196
|
+
...FirestoreErrorInfo.INVALID_RESPONSE,
|
|
197
|
+
message: 'Invalid query stream document.'
|
|
198
|
+
});
|
|
199
|
+
const readTime = row.readTime;
|
|
200
|
+
yield {
|
|
201
|
+
document: readTime ? { ...row.document, readTime } : row.document,
|
|
202
|
+
readTime
|
|
203
|
+
};
|
|
204
|
+
if (row.explainMetrics)
|
|
205
|
+
yield {
|
|
206
|
+
metrics: parseExplainMetrics(row.explainMetrics),
|
|
207
|
+
readTime: row.readTime
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
export function createDocumentName(projectId, databaseId, path) {
|
|
212
|
+
return `projects/${projectId}/databases/${databaseId}/documents${path ? `/${path}` : ''}`;
|
|
213
|
+
}
|
|
214
|
+
function serializeWrites(projectId, databaseId, operations) {
|
|
215
|
+
return operations.map((operation) => {
|
|
216
|
+
const name = createDocumentName(projectId, databaseId, operation.path);
|
|
217
|
+
return {
|
|
218
|
+
...(operation.kind === 'delete'
|
|
219
|
+
? { delete: name }
|
|
220
|
+
: {
|
|
221
|
+
update: { name, fields: operation.fields },
|
|
222
|
+
...(operation.mask
|
|
223
|
+
? { updateMask: { fieldPaths: operation.mask } }
|
|
224
|
+
: {}),
|
|
225
|
+
...(operation.transforms?.length
|
|
226
|
+
? { updateTransforms: operation.transforms }
|
|
227
|
+
: {})
|
|
228
|
+
}),
|
|
229
|
+
...(operation.precondition
|
|
230
|
+
? { currentDocument: operation.precondition }
|
|
231
|
+
: {})
|
|
232
|
+
};
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
/** @internal Independent REST writes, with one result or error per operation. */
|
|
236
|
+
export async function batchWrite(projectId, databaseId, operations, token, fetchFn) {
|
|
237
|
+
if (!operations.length)
|
|
238
|
+
return [];
|
|
239
|
+
if (new Set(operations.map((operation) => operation.path)).size !==
|
|
240
|
+
operations.length)
|
|
241
|
+
throw new FirebaseEdgeError({
|
|
242
|
+
...FirestoreErrorInfo.INVALID_ARGUMENT,
|
|
243
|
+
message: 'batchWrite requires distinct document paths.'
|
|
244
|
+
});
|
|
245
|
+
const writes = serializeWrites(projectId, databaseId, operations);
|
|
246
|
+
// Leave headroom below the service request limit, including UTF-8 expansion.
|
|
247
|
+
if (new TextEncoder().encode(JSON.stringify({ writes })).byteLength >
|
|
248
|
+
9 * 1024 * 1024) {
|
|
249
|
+
if (operations.length === 1)
|
|
250
|
+
throw new FirebaseEdgeError({
|
|
251
|
+
...FirestoreErrorInfo.INVALID_ARGUMENT,
|
|
252
|
+
message: 'Write exceeds the bulk request size limit.'
|
|
253
|
+
});
|
|
254
|
+
const middle = Math.ceil(operations.length / 2);
|
|
255
|
+
const outcomes = [];
|
|
256
|
+
for (const part of [
|
|
257
|
+
operations.slice(0, middle),
|
|
258
|
+
operations.slice(middle)
|
|
259
|
+
]) {
|
|
260
|
+
try {
|
|
261
|
+
const results = await batchWrite(projectId, databaseId, part, token, fetchFn);
|
|
262
|
+
outcomes.push(...results);
|
|
263
|
+
}
|
|
264
|
+
catch (error) {
|
|
265
|
+
const failure = error instanceof FirebaseEdgeError
|
|
266
|
+
? error
|
|
267
|
+
: mapFirestoreError({
|
|
268
|
+
error: { message: ensureError(error).message }
|
|
269
|
+
});
|
|
270
|
+
outcomes.push(...part.map(() => failure));
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
return outcomes;
|
|
274
|
+
}
|
|
275
|
+
const response = await firestorePost(projectId, databaseId, '', 'batchWrite', { writes }, token, fetchFn);
|
|
276
|
+
if (!Array.isArray(response?.writeResults) ||
|
|
277
|
+
!Array.isArray(response?.status) ||
|
|
278
|
+
response.writeResults.length !== operations.length ||
|
|
279
|
+
response.status.length !== operations.length)
|
|
280
|
+
throw new FirebaseEdgeError({
|
|
281
|
+
...FirestoreErrorInfo.INVALID_RESPONSE,
|
|
282
|
+
message: 'Invalid batchWrite response.'
|
|
283
|
+
});
|
|
284
|
+
return response.status.map((status, index) => {
|
|
285
|
+
if (!status ||
|
|
286
|
+
typeof status !== 'object' ||
|
|
287
|
+
(status.code !== undefined &&
|
|
288
|
+
(!Number.isInteger(status.code) ||
|
|
289
|
+
status.code < 0 ||
|
|
290
|
+
status.code > 16)))
|
|
291
|
+
return new FirebaseEdgeError({
|
|
292
|
+
...FirestoreErrorInfo.INVALID_RESPONSE,
|
|
293
|
+
message: 'Invalid batchWrite status.'
|
|
294
|
+
});
|
|
295
|
+
if (status.code) {
|
|
296
|
+
const names = [
|
|
297
|
+
'OK',
|
|
298
|
+
'CANCELLED',
|
|
299
|
+
'UNKNOWN',
|
|
300
|
+
'INVALID_ARGUMENT',
|
|
301
|
+
'DEADLINE_EXCEEDED',
|
|
302
|
+
'NOT_FOUND',
|
|
303
|
+
'ALREADY_EXISTS',
|
|
304
|
+
'PERMISSION_DENIED',
|
|
305
|
+
'RESOURCE_EXHAUSTED',
|
|
306
|
+
'FAILED_PRECONDITION',
|
|
307
|
+
'ABORTED',
|
|
308
|
+
'OUT_OF_RANGE',
|
|
309
|
+
'UNIMPLEMENTED',
|
|
310
|
+
'INTERNAL',
|
|
311
|
+
'UNAVAILABLE',
|
|
312
|
+
'DATA_LOSS',
|
|
313
|
+
'UNAUTHENTICATED'
|
|
314
|
+
];
|
|
315
|
+
return mapFirestoreError({
|
|
316
|
+
error: { status: names[status.code], message: status.message }
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
const write = response.writeResults[index];
|
|
320
|
+
if (!write ||
|
|
321
|
+
typeof write !== 'object' ||
|
|
322
|
+
(!write.updateTime && operations[index].kind !== 'delete'))
|
|
323
|
+
return new FirebaseEdgeError({
|
|
324
|
+
...FirestoreErrorInfo.INVALID_RESPONSE,
|
|
325
|
+
message: 'Invalid batchWrite result.'
|
|
326
|
+
});
|
|
327
|
+
try {
|
|
328
|
+
// Match Admin BulkWriter's epoch sentinel for deletes, which lack updateTime.
|
|
329
|
+
return new WriteResult(write.updateTime
|
|
330
|
+
? Timestamp.fromString(write.updateTime)
|
|
331
|
+
: new Timestamp(0, 0));
|
|
332
|
+
}
|
|
333
|
+
catch {
|
|
334
|
+
return new FirebaseEdgeError({
|
|
335
|
+
...FirestoreErrorInfo.INVALID_RESPONSE,
|
|
336
|
+
message: 'Invalid batchWrite timestamp.'
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
export async function commitWrites(projectId, databaseId, operations, token, fetchFn, transaction) {
|
|
342
|
+
const writes = serializeWrites(projectId, databaseId, operations);
|
|
343
|
+
const result = await firestorePost(projectId, databaseId, '', 'commit', { writes, ...(transaction ? { transaction } : {}) }, token, fetchFn);
|
|
344
|
+
if (!result ||
|
|
345
|
+
!Array.isArray(result.writeResults) ||
|
|
346
|
+
result.writeResults.length !== operations.length ||
|
|
347
|
+
!result.commitTime) {
|
|
348
|
+
// The API may omit writeResults for a read-only transaction commit.
|
|
349
|
+
if (!operations.length && result?.commitTime)
|
|
350
|
+
return [];
|
|
351
|
+
throw new FirebaseEdgeError({
|
|
352
|
+
...FirestoreErrorInfo.INVALID_RESPONSE,
|
|
353
|
+
message: 'Firestore returned an invalid commit response.'
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
return result.writeResults.map((write) => new WriteResult(Timestamp.fromString(write.updateTime ?? result.commitTime)));
|
|
357
|
+
}
|
|
358
|
+
export async function beginTransaction(projectId, databaseId, token, fetchFn, options) {
|
|
359
|
+
const result = await firestorePost(projectId, databaseId, '', 'beginTransaction', {
|
|
360
|
+
options: options
|
|
361
|
+
? {
|
|
362
|
+
readOnly: {
|
|
363
|
+
...(options.readTime
|
|
364
|
+
? { readTime: options.readTime.toString() }
|
|
365
|
+
: {})
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
: { readWrite: {} }
|
|
369
|
+
}, token, fetchFn);
|
|
370
|
+
if (!result?.transaction)
|
|
371
|
+
throw new FirebaseEdgeError({
|
|
372
|
+
...FirestoreErrorInfo.INVALID_RESPONSE,
|
|
373
|
+
message: 'Firestore returned no transaction ID.'
|
|
374
|
+
});
|
|
375
|
+
return result.transaction;
|
|
376
|
+
}
|
|
377
|
+
export async function rollbackTransaction(projectId, databaseId, transaction, token, fetchFn) {
|
|
378
|
+
await firestorePost(projectId, databaseId, '', 'rollback', { transaction }, token, fetchFn);
|
|
379
|
+
}
|
|
380
|
+
export async function runAggregate(projectId, databaseId, collectionPath, options, spec, token, fetchFn, transaction, explainOptions) {
|
|
381
|
+
const segments = collectionPath.split('/');
|
|
382
|
+
const collectionId = segments.pop();
|
|
383
|
+
const parent = segments.join('/');
|
|
384
|
+
const entries = Object.entries(spec);
|
|
385
|
+
const aggregations = entries.map(([, field], index) => ({
|
|
386
|
+
alias: `agg_${index}`,
|
|
387
|
+
...(field.aggregateType === 'count'
|
|
388
|
+
? { count: {} }
|
|
389
|
+
: {
|
|
390
|
+
[field.aggregateType === 'avg' ? 'avg' : 'sum']: {
|
|
391
|
+
field: { fieldPath: field.field }
|
|
392
|
+
}
|
|
393
|
+
})
|
|
394
|
+
}));
|
|
395
|
+
const result = await firestorePost(projectId, databaseId, parent, 'runAggregationQuery', {
|
|
396
|
+
structuredAggregationQuery: {
|
|
397
|
+
structuredQuery: buildStructuredQuery(collectionId, options, createDocumentName(projectId, databaseId, parent)),
|
|
398
|
+
aggregations
|
|
399
|
+
},
|
|
400
|
+
...(transaction ? { transaction } : {}),
|
|
401
|
+
...(explainOptions ? { explainOptions } : {})
|
|
402
|
+
}, token, fetchFn);
|
|
403
|
+
if (!Array.isArray(result))
|
|
404
|
+
throw new FirebaseEdgeError({
|
|
405
|
+
...FirestoreErrorInfo.INVALID_RESPONSE,
|
|
406
|
+
message: 'Invalid aggregate response.'
|
|
407
|
+
});
|
|
408
|
+
for (const row of result) {
|
|
409
|
+
if (!row || typeof row !== 'object')
|
|
410
|
+
throw new FirebaseEdgeError({
|
|
411
|
+
...FirestoreErrorInfo.INVALID_RESPONSE,
|
|
412
|
+
message: 'Invalid aggregate response row.'
|
|
413
|
+
});
|
|
414
|
+
if (row.error)
|
|
415
|
+
throw mapFirestoreError(row);
|
|
416
|
+
}
|
|
417
|
+
const metricsRow = result.find((row) => row.explainMetrics);
|
|
418
|
+
const metrics = metricsRow
|
|
419
|
+
? parseExplainMetrics(metricsRow.explainMetrics)
|
|
420
|
+
: undefined;
|
|
421
|
+
const fields = result.find((row) => row?.result)?.result?.aggregateFields;
|
|
422
|
+
if (!fields && explainOptions && !explainOptions.analyze && metrics) {
|
|
423
|
+
const data = {};
|
|
424
|
+
Object.defineProperty(data, aggregateMetrics, { value: metrics });
|
|
425
|
+
return data;
|
|
426
|
+
}
|
|
427
|
+
if (!fields)
|
|
428
|
+
throw new FirebaseEdgeError({
|
|
429
|
+
...FirestoreErrorInfo.INVALID_RESPONSE,
|
|
430
|
+
message: 'No aggregate result returned.'
|
|
431
|
+
});
|
|
432
|
+
const decoded = decodeFields(fields);
|
|
433
|
+
const values = Object.fromEntries(entries.map(([alias], index) => {
|
|
434
|
+
const value = decoded[`agg_${index}`];
|
|
435
|
+
if (value !== null && typeof value !== 'number')
|
|
436
|
+
throw new FirebaseEdgeError({
|
|
437
|
+
...FirestoreErrorInfo.INVALID_RESPONSE,
|
|
438
|
+
message: 'Invalid aggregate field returned.'
|
|
439
|
+
});
|
|
440
|
+
return [alias, value];
|
|
441
|
+
}));
|
|
442
|
+
const readTime = result.find((row) => row.readTime)?.readTime;
|
|
443
|
+
if (readTime)
|
|
444
|
+
Object.defineProperty(values, aggregateReadTime, {
|
|
445
|
+
value: Timestamp.fromString(readTime)
|
|
446
|
+
});
|
|
447
|
+
if (metrics)
|
|
448
|
+
Object.defineProperty(values, aggregateMetrics, { value: metrics });
|
|
449
|
+
return values;
|
|
450
|
+
}
|
|
451
|
+
async function firestorePost(projectId, databaseId, parent, method, body, token, fetchFn) {
|
|
452
|
+
const { data, error } = await restFetch(`${createDocumentsURL(projectId, databaseId, parent)}:${method}`, {
|
|
453
|
+
method: 'POST',
|
|
454
|
+
body,
|
|
455
|
+
bearerToken: token,
|
|
456
|
+
global: { fetch: fetchFn }
|
|
457
|
+
});
|
|
458
|
+
logFirestore(`Firestore REST ${method}: ${error ? 'error' : 'success'}`);
|
|
459
|
+
if (error)
|
|
460
|
+
throw mapFirestoreError(error);
|
|
461
|
+
return data;
|
|
462
|
+
}
|
|
463
|
+
/** @internal Fetch and sort all split points; REST pages are not globally ordered. */
|
|
464
|
+
export async function partitionQuery(projectId, databaseId, collectionId, count, token, fetchFn) {
|
|
465
|
+
const names = new Set();
|
|
466
|
+
const seen = new Set();
|
|
467
|
+
let pageToken;
|
|
468
|
+
const prefix = `${createDocumentName(projectId, databaseId, '')}/`;
|
|
469
|
+
do {
|
|
470
|
+
const page = await firestorePost(projectId, databaseId, '', 'partitionQuery', {
|
|
471
|
+
structuredQuery: buildStructuredQuery(collectionId, {
|
|
472
|
+
allDescendants: true,
|
|
473
|
+
orders: [{ field: '__name__', direction: 'asc' }]
|
|
474
|
+
}),
|
|
475
|
+
partitionCount: String(count - 1),
|
|
476
|
+
pageSize: 1000,
|
|
477
|
+
...(pageToken ? { pageToken } : {})
|
|
478
|
+
}, token, fetchFn);
|
|
479
|
+
if (!page ||
|
|
480
|
+
(page.partitions !== undefined &&
|
|
481
|
+
!Array.isArray(page.partitions)) ||
|
|
482
|
+
(page.nextPageToken !== undefined &&
|
|
483
|
+
typeof page.nextPageToken !== 'string'))
|
|
484
|
+
throw new FirebaseEdgeError({
|
|
485
|
+
...FirestoreErrorInfo.INVALID_RESPONSE,
|
|
486
|
+
message: 'Invalid partition response.'
|
|
487
|
+
});
|
|
488
|
+
for (const cursor of page.partitions ?? []) {
|
|
489
|
+
const name = cursor?.values?.[0]?.referenceValue;
|
|
490
|
+
const path = typeof name === 'string' && name.startsWith(prefix)
|
|
491
|
+
? name.slice(prefix.length)
|
|
492
|
+
: '';
|
|
493
|
+
const segments = path.split('/');
|
|
494
|
+
if (cursor?.values?.length !== 1 ||
|
|
495
|
+
!path ||
|
|
496
|
+
segments.length % 2 !== 0 ||
|
|
497
|
+
segments.some((segment) => !segment || segment === '.' || segment === '..') ||
|
|
498
|
+
segments.at(-2) !== collectionId)
|
|
499
|
+
throw new FirebaseEdgeError({
|
|
500
|
+
...FirestoreErrorInfo.INVALID_RESPONSE,
|
|
501
|
+
message: 'Invalid partition cursor.'
|
|
502
|
+
});
|
|
503
|
+
names.add(path);
|
|
504
|
+
}
|
|
505
|
+
pageToken = page.nextPageToken;
|
|
506
|
+
if (pageToken && seen.has(pageToken))
|
|
507
|
+
throw new FirebaseEdgeError({
|
|
508
|
+
...FirestoreErrorInfo.INVALID_RESPONSE,
|
|
509
|
+
message: 'Repeated partition page token.'
|
|
510
|
+
});
|
|
511
|
+
if (pageToken)
|
|
512
|
+
seen.add(pageToken);
|
|
513
|
+
} while (pageToken);
|
|
514
|
+
const encoder = new TextEncoder();
|
|
515
|
+
return [...names]
|
|
516
|
+
.map((path) => ({ path, bytes: encoder.encode(path) }))
|
|
517
|
+
.sort((left, right) => {
|
|
518
|
+
for (let index = 0; index < Math.min(left.bytes.length, right.bytes.length); index++) {
|
|
519
|
+
const difference = left.bytes[index] - right.bytes[index];
|
|
520
|
+
if (difference)
|
|
521
|
+
return difference;
|
|
522
|
+
}
|
|
523
|
+
return left.bytes.length - right.bytes.length;
|
|
524
|
+
})
|
|
525
|
+
.map((entry) => entry.path);
|
|
526
|
+
}
|
|
527
|
+
/** @internal Configure the REST destination. */
|
|
528
|
+
export function configureFirestoreFetch(fetchFn, host, ssl = true, port, telemetry) {
|
|
529
|
+
if (typeof host !== 'string' ||
|
|
530
|
+
!host ||
|
|
531
|
+
/[\s/?#@]/.test(host) ||
|
|
532
|
+
host.includes('://'))
|
|
533
|
+
throw new FirebaseEdgeError({
|
|
534
|
+
...FirestoreErrorInfo.INVALID_ARGUMENT,
|
|
535
|
+
message: 'host must be a hostname with an optional port.'
|
|
536
|
+
});
|
|
537
|
+
const url = new URL(`${ssl ? 'https' : 'http'}://${host}`);
|
|
538
|
+
if (port !== undefined)
|
|
539
|
+
url.port = String(port);
|
|
540
|
+
const origin = url.origin;
|
|
541
|
+
return (input, init) => {
|
|
542
|
+
const url = new URL(input instanceof Request ? input.url : String(input));
|
|
543
|
+
if (url.origin !== 'https://firestore.googleapis.com')
|
|
544
|
+
return fetchFn(input, init);
|
|
545
|
+
const destination = `${origin}${url.pathname}${url.search}`;
|
|
546
|
+
return traceFirestoreOperation('firestore.rest', telemetry, () => fetchFn(input instanceof Request
|
|
547
|
+
? new Request(destination, input)
|
|
548
|
+
: destination, init));
|
|
549
|
+
};
|
|
550
|
+
}
|
|
551
|
+
function createDocumentsURL(projectId, databaseId, path) {
|
|
552
|
+
const parts = ['projects', projectId, 'databases', databaseId, 'documents'];
|
|
553
|
+
if (path)
|
|
554
|
+
parts.push(...path.split('/'));
|
|
555
|
+
return `https://firestore.googleapis.com/v1/${parts.map(encodeURIComponent).join('/')}`;
|
|
556
|
+
}
|
|
557
|
+
function mapFirestoreError(error) {
|
|
558
|
+
const details = Array.isArray(error)
|
|
559
|
+
? error.find((row) => row?.error)?.error
|
|
560
|
+
: error && typeof error === 'object'
|
|
561
|
+
? error.error
|
|
562
|
+
: undefined;
|
|
563
|
+
return new FirebaseEdgeError({
|
|
564
|
+
...FirestoreErrorInfo.UNKNOWN,
|
|
565
|
+
...(typeof details?.status === 'string' && details.status
|
|
566
|
+
? {
|
|
567
|
+
code: `firestore/${details.status.toLowerCase().replaceAll('_', '-')}`
|
|
568
|
+
}
|
|
569
|
+
: {}),
|
|
570
|
+
message: typeof details?.message === 'string'
|
|
571
|
+
? details.message
|
|
572
|
+
: FirestoreErrorInfo.UNKNOWN.message
|
|
573
|
+
}, { cause: ensureError(error) });
|
|
574
|
+
}
|
|
575
|
+
export async function runQuery(projectId, databaseId, collectionPath, options, token, fetchFn, transaction) {
|
|
576
|
+
const segments = collectionPath.split('/');
|
|
577
|
+
const collectionId = segments.pop();
|
|
578
|
+
const data = await firestorePost(projectId, databaseId, segments.join('/'), 'runQuery', {
|
|
579
|
+
...(transaction ? { transaction } : {}),
|
|
580
|
+
structuredQuery: buildStructuredQuery(collectionId, options, createDocumentName(projectId, databaseId, segments.join('/')))
|
|
581
|
+
}, token, fetchFn);
|
|
582
|
+
if (!Array.isArray(data))
|
|
583
|
+
throw new FirebaseEdgeError({
|
|
584
|
+
...FirestoreErrorInfo.INVALID_RESPONSE,
|
|
585
|
+
message: 'Firestore returned an invalid query response.'
|
|
586
|
+
});
|
|
587
|
+
const documents = [];
|
|
588
|
+
for (const row of data) {
|
|
589
|
+
if (!row || typeof row !== 'object')
|
|
590
|
+
throw new FirebaseEdgeError({
|
|
591
|
+
...FirestoreErrorInfo.INVALID_RESPONSE,
|
|
592
|
+
message: 'Firestore returned an invalid query row.'
|
|
593
|
+
});
|
|
594
|
+
if (row.error)
|
|
595
|
+
throw mapFirestoreError(row);
|
|
596
|
+
if (!row.document)
|
|
597
|
+
continue;
|
|
598
|
+
if (typeof row.document.name !== 'string' ||
|
|
599
|
+
!row.document.name.startsWith(`projects/${projectId}/databases/${databaseId}/documents/`))
|
|
600
|
+
throw new FirebaseEdgeError({
|
|
601
|
+
...FirestoreErrorInfo.INVALID_RESPONSE,
|
|
602
|
+
message: 'Firestore returned an invalid query document.'
|
|
603
|
+
});
|
|
604
|
+
const readTime = row.readTime;
|
|
605
|
+
documents.push(readTime ? { ...row.document, readTime } : row.document);
|
|
606
|
+
}
|
|
607
|
+
const readTime = data.at(-1)
|
|
608
|
+
?.readTime;
|
|
609
|
+
if (readTime)
|
|
610
|
+
Object.defineProperty(documents, 'readTime', { value: readTime });
|
|
611
|
+
return documents;
|
|
612
|
+
}
|
|
613
|
+
/** Read via batchGet so found and missing documents both retain server read times. */
|
|
614
|
+
export async function getDocument(projectId, databaseId, path, token, fetchFn, transaction) {
|
|
615
|
+
const documents = await batchGetDocuments(projectId, databaseId, [path], token, fetchFn, undefined, transaction);
|
|
616
|
+
if (documents[0])
|
|
617
|
+
return documents[0];
|
|
618
|
+
const readTime = documents.readTimes?.[0];
|
|
619
|
+
if (!readTime)
|
|
620
|
+
return undefined;
|
|
621
|
+
return {
|
|
622
|
+
name: createDocumentName(projectId, databaseId, path),
|
|
623
|
+
missing: true,
|
|
624
|
+
readTime: readTime.toString()
|
|
625
|
+
};
|
|
626
|
+
}
|
|
627
|
+
/** Execute REST pipeline stages, preserving errors from streamed response rows. */
|
|
628
|
+
export async function executePipeline(projectId, databaseId, structuredPipeline, token, fetchFn, transaction, readTime) {
|
|
629
|
+
if (transaction && readTime)
|
|
630
|
+
throw new FirebaseEdgeError({
|
|
631
|
+
...FirestoreErrorInfo.INVALID_ARGUMENT,
|
|
632
|
+
message: 'Choose a transaction or readTime.'
|
|
633
|
+
});
|
|
634
|
+
const rows = await firestorePost(projectId, databaseId, '', 'executePipeline', {
|
|
635
|
+
structuredPipeline,
|
|
636
|
+
...(transaction ? { transaction } : {}),
|
|
637
|
+
...(readTime ? { readTime: readTime.toString() } : {})
|
|
638
|
+
}, token, fetchFn);
|
|
639
|
+
if (!Array.isArray(rows))
|
|
640
|
+
throw new FirebaseEdgeError({
|
|
641
|
+
...FirestoreErrorInfo.INVALID_RESPONSE,
|
|
642
|
+
message: 'Invalid pipeline response.'
|
|
643
|
+
});
|
|
644
|
+
const result = {
|
|
645
|
+
results: [],
|
|
646
|
+
executionTime: ''
|
|
647
|
+
};
|
|
648
|
+
for (const row of rows) {
|
|
649
|
+
if (!row || typeof row !== 'object')
|
|
650
|
+
throw new FirebaseEdgeError({
|
|
651
|
+
...FirestoreErrorInfo.INVALID_RESPONSE,
|
|
652
|
+
message: 'Invalid pipeline row.'
|
|
653
|
+
});
|
|
654
|
+
if (row.error)
|
|
655
|
+
throw mapFirestoreError(row);
|
|
656
|
+
if (row.results !== undefined &&
|
|
657
|
+
(!Array.isArray(row.results) ||
|
|
658
|
+
row.results.some((document) => !document ||
|
|
659
|
+
typeof document !== 'object' ||
|
|
660
|
+
Array.isArray(document))))
|
|
661
|
+
throw new FirebaseEdgeError({
|
|
662
|
+
...FirestoreErrorInfo.INVALID_RESPONSE,
|
|
663
|
+
message: 'Invalid pipeline results.'
|
|
664
|
+
});
|
|
665
|
+
result.results.push(...(row.results ?? []));
|
|
666
|
+
if (row.executionTime)
|
|
667
|
+
result.executionTime = row.executionTime;
|
|
668
|
+
if (row.explainStats)
|
|
669
|
+
result.explainStats = row.explainStats;
|
|
670
|
+
}
|
|
671
|
+
if (!result.executionTime)
|
|
672
|
+
throw new FirebaseEdgeError({
|
|
673
|
+
...FirestoreErrorInfo.INVALID_RESPONSE,
|
|
674
|
+
message: 'Missing pipeline execution time.'
|
|
675
|
+
});
|
|
676
|
+
Timestamp.fromString(result.executionTime);
|
|
677
|
+
return result;
|
|
678
|
+
}
|
|
679
|
+
/** @internal Stream pipeline document batches with fetch cancellation and bounded buffering. */
|
|
680
|
+
export async function* streamPipeline(projectId, databaseId, structuredPipeline, token, fetchFn = globalThis.fetch, signal, readTime) {
|
|
681
|
+
signal?.throwIfAborted();
|
|
682
|
+
const response = await fetchFn(`${createDocumentsURL(projectId, databaseId, '')}:executePipeline`, {
|
|
683
|
+
method: 'POST',
|
|
684
|
+
headers: {
|
|
685
|
+
Authorization: `Bearer ${token}`,
|
|
686
|
+
'Content-Type': 'application/json',
|
|
687
|
+
Accept: 'application/json'
|
|
688
|
+
},
|
|
689
|
+
body: JSON.stringify({
|
|
690
|
+
structuredPipeline,
|
|
691
|
+
...(readTime ? { readTime: readTime.toString() } : {})
|
|
692
|
+
}),
|
|
693
|
+
signal
|
|
694
|
+
});
|
|
695
|
+
if (!response.ok) {
|
|
696
|
+
const text = await response.text();
|
|
697
|
+
let error;
|
|
698
|
+
try {
|
|
699
|
+
error = JSON.parse(text);
|
|
700
|
+
}
|
|
701
|
+
catch {
|
|
702
|
+
error = { error: { message: text } };
|
|
703
|
+
}
|
|
704
|
+
throw mapFirestoreError(error);
|
|
705
|
+
}
|
|
706
|
+
if (!response.body)
|
|
707
|
+
throw new FirebaseEdgeError({
|
|
708
|
+
...FirestoreErrorInfo.INVALID_RESPONSE,
|
|
709
|
+
message: 'Missing pipeline stream.'
|
|
710
|
+
});
|
|
711
|
+
for await (const value of readJsonArray(response.body)) {
|
|
712
|
+
const row = value;
|
|
713
|
+
if (!row || typeof row !== 'object')
|
|
714
|
+
throw new FirebaseEdgeError({
|
|
715
|
+
...FirestoreErrorInfo.INVALID_RESPONSE,
|
|
716
|
+
message: 'Invalid pipeline row.'
|
|
717
|
+
});
|
|
718
|
+
if (row.error)
|
|
719
|
+
throw mapFirestoreError(row);
|
|
720
|
+
if (row.results !== undefined &&
|
|
721
|
+
(!Array.isArray(row.results) ||
|
|
722
|
+
row.results.some((document) => !document ||
|
|
723
|
+
typeof document !== 'object' ||
|
|
724
|
+
Array.isArray(document))))
|
|
725
|
+
throw new FirebaseEdgeError({
|
|
726
|
+
...FirestoreErrorInfo.INVALID_RESPONSE,
|
|
727
|
+
message: 'Invalid pipeline results.'
|
|
728
|
+
});
|
|
729
|
+
for (const document of row.results ?? []) {
|
|
730
|
+
signal?.throwIfAborted();
|
|
731
|
+
yield document;
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
//# sourceMappingURL=firestore-endpoints.js.map
|