@prmichaelsen/firebase-admin-sdk-v8 2.4.2 → 2.5.1
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/AGENT.md +224 -21
- package/CHANGELOG.md +33 -1
- package/README.md +93 -1
- package/dist/index.d.mts +125 -1
- package/dist/index.d.ts +125 -1
- package/dist/index.js +251 -3
- package/dist/index.mjs +242 -3
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -183,6 +183,81 @@ interface BatchWriteResult {
|
|
|
183
183
|
updateTime: string;
|
|
184
184
|
}>;
|
|
185
185
|
}
|
|
186
|
+
/**
|
|
187
|
+
* Firebase user record
|
|
188
|
+
*/
|
|
189
|
+
interface UserRecord {
|
|
190
|
+
/** User's unique ID */
|
|
191
|
+
uid: string;
|
|
192
|
+
/** User's email address */
|
|
193
|
+
email?: string;
|
|
194
|
+
/** Whether the email is verified */
|
|
195
|
+
emailVerified: boolean;
|
|
196
|
+
/** User's display name */
|
|
197
|
+
displayName?: string;
|
|
198
|
+
/** User's photo URL */
|
|
199
|
+
photoURL?: string;
|
|
200
|
+
/** User's phone number */
|
|
201
|
+
phoneNumber?: string;
|
|
202
|
+
/** Whether the user is disabled */
|
|
203
|
+
disabled: boolean;
|
|
204
|
+
/** User metadata (creation and last sign-in times) */
|
|
205
|
+
metadata: {
|
|
206
|
+
creationTime: string;
|
|
207
|
+
lastSignInTime: string;
|
|
208
|
+
};
|
|
209
|
+
/** Provider-specific user information */
|
|
210
|
+
providerData: UserInfo[];
|
|
211
|
+
/** Custom claims set on the user */
|
|
212
|
+
customClaims?: Record<string, any>;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Request to create a new user
|
|
216
|
+
*/
|
|
217
|
+
interface CreateUserRequest {
|
|
218
|
+
/** User's email address */
|
|
219
|
+
email?: string;
|
|
220
|
+
/** Whether the email should be marked as verified */
|
|
221
|
+
emailVerified?: boolean;
|
|
222
|
+
/** User's phone number */
|
|
223
|
+
phoneNumber?: string;
|
|
224
|
+
/** User's password */
|
|
225
|
+
password?: string;
|
|
226
|
+
/** User's display name */
|
|
227
|
+
displayName?: string;
|
|
228
|
+
/** User's photo URL */
|
|
229
|
+
photoURL?: string;
|
|
230
|
+
/** Whether the user should be disabled */
|
|
231
|
+
disabled?: boolean;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Request to update an existing user
|
|
235
|
+
*/
|
|
236
|
+
interface UpdateUserRequest {
|
|
237
|
+
/** User's email address */
|
|
238
|
+
email?: string;
|
|
239
|
+
/** Whether the email should be marked as verified */
|
|
240
|
+
emailVerified?: boolean;
|
|
241
|
+
/** User's phone number */
|
|
242
|
+
phoneNumber?: string;
|
|
243
|
+
/** User's password */
|
|
244
|
+
password?: string;
|
|
245
|
+
/** User's display name */
|
|
246
|
+
displayName?: string;
|
|
247
|
+
/** User's photo URL */
|
|
248
|
+
photoURL?: string;
|
|
249
|
+
/** Whether the user should be disabled */
|
|
250
|
+
disabled?: boolean;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Result of listing users
|
|
254
|
+
*/
|
|
255
|
+
interface ListUsersResult {
|
|
256
|
+
/** Array of user records */
|
|
257
|
+
users: UserRecord[];
|
|
258
|
+
/** Token for fetching the next page (if available) */
|
|
259
|
+
pageToken?: string;
|
|
260
|
+
}
|
|
186
261
|
|
|
187
262
|
/**
|
|
188
263
|
* Firebase Admin SDK v8 - Configuration
|
|
@@ -395,6 +470,55 @@ declare function verifySessionCookie(sessionCookie: string, checkRevoked?: boole
|
|
|
395
470
|
*/
|
|
396
471
|
declare function getAuth(): any;
|
|
397
472
|
|
|
473
|
+
/**
|
|
474
|
+
* Firebase User Management APIs
|
|
475
|
+
* Provides user management operations using Firebase Identity Toolkit REST API
|
|
476
|
+
*/
|
|
477
|
+
|
|
478
|
+
/**
|
|
479
|
+
* Look up a Firebase user by email address
|
|
480
|
+
* @param email - User's email address
|
|
481
|
+
* @returns User record or null if not found
|
|
482
|
+
*/
|
|
483
|
+
declare function getUserByEmail(email: string): Promise<UserRecord | null>;
|
|
484
|
+
/**
|
|
485
|
+
* Look up a Firebase user by UID
|
|
486
|
+
* @param uid - User's unique ID
|
|
487
|
+
* @returns User record or null if not found
|
|
488
|
+
*/
|
|
489
|
+
declare function getUserByUid(uid: string): Promise<UserRecord | null>;
|
|
490
|
+
/**
|
|
491
|
+
* Create a new Firebase user
|
|
492
|
+
* @param properties - User properties (email, password, displayName, etc.)
|
|
493
|
+
* @returns Created user record
|
|
494
|
+
*/
|
|
495
|
+
declare function createUser(properties: CreateUserRequest): Promise<UserRecord>;
|
|
496
|
+
/**
|
|
497
|
+
* Update an existing Firebase user
|
|
498
|
+
* @param uid - User's unique ID
|
|
499
|
+
* @param properties - Properties to update (email, password, displayName, etc.)
|
|
500
|
+
* @returns Updated user record
|
|
501
|
+
*/
|
|
502
|
+
declare function updateUser(uid: string, properties: UpdateUserRequest): Promise<UserRecord>;
|
|
503
|
+
/**
|
|
504
|
+
* Delete a Firebase user
|
|
505
|
+
* @param uid - User's unique ID
|
|
506
|
+
*/
|
|
507
|
+
declare function deleteUser(uid: string): Promise<void>;
|
|
508
|
+
/**
|
|
509
|
+
* List all users with pagination
|
|
510
|
+
* @param maxResults - Maximum number of users to return (default: 1000, max: 1000)
|
|
511
|
+
* @param pageToken - Token for next page
|
|
512
|
+
* @returns List of users and next page token
|
|
513
|
+
*/
|
|
514
|
+
declare function listUsers(maxResults?: number, pageToken?: string): Promise<ListUsersResult>;
|
|
515
|
+
/**
|
|
516
|
+
* Set custom claims on a user's ID token
|
|
517
|
+
* @param uid - User's unique ID
|
|
518
|
+
* @param customClaims - Custom claims object (max 1000 bytes when serialized)
|
|
519
|
+
*/
|
|
520
|
+
declare function setCustomUserClaims(uid: string, customClaims: Record<string, any> | null): Promise<void>;
|
|
521
|
+
|
|
398
522
|
/**
|
|
399
523
|
* Firebase Admin SDK v8 - Firestore CRUD Operations
|
|
400
524
|
* All Firestore document operations using REST API
|
|
@@ -979,4 +1103,4 @@ declare function getAdminAccessToken(): Promise<string>;
|
|
|
979
1103
|
*/
|
|
980
1104
|
declare function clearTokenCache(): void;
|
|
981
1105
|
|
|
982
|
-
export { type BatchWrite, type BatchWriteResult, type CustomClaims, type CustomTokenSignInResponse, type DataObject, type DecodedIdToken, type DocumentReference, type DownloadOptions, FieldValue, type FieldValue$1 as FieldValueSentinel, FieldValueType, type FileMetadata, type FirestoreDocument, type FirestoreValue, type ListFilesResult, type ListOptions, type QueryFilter, type QueryOptions, type QueryOrder, type ResumableUploadOptions, type ServiceAccount, type SessionCookieOptions, type SetOptions, type SignedUrlOptions, type TokenResponse, type UpdateOptions, type UploadOptions, type UserInfo, type WhereFilterOp, addDocument, batchWrite, clearConfig, clearTokenCache, countDocuments, createCustomToken, createSessionCookie, deleteDocument, deleteFile, downloadFile, fileExists, generateSignedUrl, getAdminAccessToken, getAuth, getConfig, getDocument, getFileMetadata, getProjectId, getServiceAccount, getUserFromToken, initializeApp, iterateCollection, listDocuments, listFiles, queryDocuments, setDocument, signInWithCustomToken, updateDocument, uploadFile, uploadFileResumable, verifyIdToken, verifySessionCookie };
|
|
1106
|
+
export { type BatchWrite, type BatchWriteResult, type CreateUserRequest, type CustomClaims, type CustomTokenSignInResponse, type DataObject, type DecodedIdToken, type DocumentReference, type DownloadOptions, FieldValue, type FieldValue$1 as FieldValueSentinel, FieldValueType, type FileMetadata, type FirestoreDocument, type FirestoreValue, type ListFilesResult, type ListOptions, type ListUsersResult, type QueryFilter, type QueryOptions, type QueryOrder, type ResumableUploadOptions, type ServiceAccount, type SessionCookieOptions, type SetOptions, type SignedUrlOptions, type TokenResponse, type UpdateOptions, type UpdateUserRequest, type UploadOptions, type UserInfo, type UserRecord, type WhereFilterOp, addDocument, batchWrite, clearConfig, clearTokenCache, countDocuments, createCustomToken, createSessionCookie, createUser, deleteDocument, deleteFile, deleteUser, downloadFile, fileExists, generateSignedUrl, getAdminAccessToken, getAuth, getConfig, getDocument, getFileMetadata, getProjectId, getServiceAccount, getUserByEmail, getUserByUid, getUserFromToken, initializeApp, iterateCollection, listDocuments, listFiles, listUsers, queryDocuments, setCustomUserClaims, setDocument, signInWithCustomToken, updateDocument, updateUser, uploadFile, uploadFileResumable, verifyIdToken, verifySessionCookie };
|
package/dist/index.js
CHANGED
|
@@ -208,8 +208,10 @@ __export(index_exports, {
|
|
|
208
208
|
countDocuments: () => countDocuments,
|
|
209
209
|
createCustomToken: () => createCustomToken,
|
|
210
210
|
createSessionCookie: () => createSessionCookie,
|
|
211
|
+
createUser: () => createUser,
|
|
211
212
|
deleteDocument: () => deleteDocument,
|
|
212
213
|
deleteFile: () => deleteFile,
|
|
214
|
+
deleteUser: () => deleteUser,
|
|
213
215
|
downloadFile: () => downloadFile,
|
|
214
216
|
fileExists: () => fileExists,
|
|
215
217
|
generateSignedUrl: () => generateSignedUrl,
|
|
@@ -220,15 +222,20 @@ __export(index_exports, {
|
|
|
220
222
|
getFileMetadata: () => getFileMetadata,
|
|
221
223
|
getProjectId: () => getProjectId,
|
|
222
224
|
getServiceAccount: () => getServiceAccount,
|
|
225
|
+
getUserByEmail: () => getUserByEmail,
|
|
226
|
+
getUserByUid: () => getUserByUid,
|
|
223
227
|
getUserFromToken: () => getUserFromToken,
|
|
224
228
|
initializeApp: () => initializeApp,
|
|
225
229
|
iterateCollection: () => iterateCollection,
|
|
226
230
|
listDocuments: () => listDocuments,
|
|
227
231
|
listFiles: () => listFiles,
|
|
232
|
+
listUsers: () => listUsers,
|
|
228
233
|
queryDocuments: () => queryDocuments,
|
|
234
|
+
setCustomUserClaims: () => setCustomUserClaims,
|
|
229
235
|
setDocument: () => setDocument,
|
|
230
236
|
signInWithCustomToken: () => signInWithCustomToken,
|
|
231
237
|
updateDocument: () => updateDocument,
|
|
238
|
+
updateUser: () => updateUser,
|
|
232
239
|
uploadFile: () => uploadFile,
|
|
233
240
|
uploadFileResumable: () => uploadFileResumable,
|
|
234
241
|
verifyIdToken: () => verifyIdToken,
|
|
@@ -716,6 +723,233 @@ function getAuth() {
|
|
|
716
723
|
};
|
|
717
724
|
}
|
|
718
725
|
|
|
726
|
+
// src/user-management.ts
|
|
727
|
+
init_token_generation();
|
|
728
|
+
init_service_account();
|
|
729
|
+
var IDENTITY_TOOLKIT_API = "https://identitytoolkit.googleapis.com/v1";
|
|
730
|
+
function convertToUserRecord(user) {
|
|
731
|
+
return {
|
|
732
|
+
uid: user.localId,
|
|
733
|
+
email: user.email || void 0,
|
|
734
|
+
emailVerified: user.emailVerified || false,
|
|
735
|
+
displayName: user.displayName || void 0,
|
|
736
|
+
photoURL: user.photoUrl || void 0,
|
|
737
|
+
phoneNumber: user.phoneNumber || void 0,
|
|
738
|
+
disabled: user.disabled || false,
|
|
739
|
+
metadata: {
|
|
740
|
+
creationTime: user.createdAt ? new Date(parseInt(user.createdAt)).toISOString() : (/* @__PURE__ */ new Date()).toISOString(),
|
|
741
|
+
lastSignInTime: user.lastLoginAt ? new Date(parseInt(user.lastLoginAt)).toISOString() : (/* @__PURE__ */ new Date()).toISOString()
|
|
742
|
+
},
|
|
743
|
+
providerData: user.providerUserInfo || [],
|
|
744
|
+
customClaims: user.customAttributes ? JSON.parse(user.customAttributes) : void 0
|
|
745
|
+
};
|
|
746
|
+
}
|
|
747
|
+
async function getUserByEmail(email) {
|
|
748
|
+
if (!email || typeof email !== "string") {
|
|
749
|
+
throw new Error("email must be a non-empty string");
|
|
750
|
+
}
|
|
751
|
+
const projectId = getProjectId();
|
|
752
|
+
const accessToken = await getAdminAccessToken();
|
|
753
|
+
const response = await fetch(
|
|
754
|
+
`${IDENTITY_TOOLKIT_API}/projects/${projectId}/accounts:lookup`,
|
|
755
|
+
{
|
|
756
|
+
method: "POST",
|
|
757
|
+
headers: {
|
|
758
|
+
"Authorization": `Bearer ${accessToken}`,
|
|
759
|
+
"Content-Type": "application/json"
|
|
760
|
+
},
|
|
761
|
+
body: JSON.stringify({ email: [email] })
|
|
762
|
+
}
|
|
763
|
+
);
|
|
764
|
+
if (!response.ok) {
|
|
765
|
+
const errorText = await response.text();
|
|
766
|
+
throw new Error(`Failed to get user by email: ${response.status} ${errorText}`);
|
|
767
|
+
}
|
|
768
|
+
const data = await response.json();
|
|
769
|
+
if (!data.users || data.users.length === 0) {
|
|
770
|
+
return null;
|
|
771
|
+
}
|
|
772
|
+
return convertToUserRecord(data.users[0]);
|
|
773
|
+
}
|
|
774
|
+
async function getUserByUid(uid) {
|
|
775
|
+
if (!uid || typeof uid !== "string") {
|
|
776
|
+
throw new Error("uid must be a non-empty string");
|
|
777
|
+
}
|
|
778
|
+
const projectId = getProjectId();
|
|
779
|
+
const accessToken = await getAdminAccessToken();
|
|
780
|
+
const response = await fetch(
|
|
781
|
+
`${IDENTITY_TOOLKIT_API}/projects/${projectId}/accounts:lookup`,
|
|
782
|
+
{
|
|
783
|
+
method: "POST",
|
|
784
|
+
headers: {
|
|
785
|
+
"Authorization": `Bearer ${accessToken}`,
|
|
786
|
+
"Content-Type": "application/json"
|
|
787
|
+
},
|
|
788
|
+
body: JSON.stringify({ localId: [uid] })
|
|
789
|
+
}
|
|
790
|
+
);
|
|
791
|
+
if (!response.ok) {
|
|
792
|
+
const errorText = await response.text();
|
|
793
|
+
throw new Error(`Failed to get user by UID: ${response.status} ${errorText}`);
|
|
794
|
+
}
|
|
795
|
+
const data = await response.json();
|
|
796
|
+
if (!data.users || data.users.length === 0) {
|
|
797
|
+
return null;
|
|
798
|
+
}
|
|
799
|
+
return convertToUserRecord(data.users[0]);
|
|
800
|
+
}
|
|
801
|
+
async function createUser(properties) {
|
|
802
|
+
if (!properties || typeof properties !== "object") {
|
|
803
|
+
throw new Error("properties must be an object");
|
|
804
|
+
}
|
|
805
|
+
const projectId = getProjectId();
|
|
806
|
+
const accessToken = await getAdminAccessToken();
|
|
807
|
+
const requestBody = {};
|
|
808
|
+
if (properties.email) requestBody.email = properties.email;
|
|
809
|
+
if (properties.password) requestBody.password = properties.password;
|
|
810
|
+
if (properties.displayName) requestBody.displayName = properties.displayName;
|
|
811
|
+
if (properties.photoURL) requestBody.photoUrl = properties.photoURL;
|
|
812
|
+
if (properties.phoneNumber) requestBody.phoneNumber = properties.phoneNumber;
|
|
813
|
+
if (typeof properties.emailVerified === "boolean") requestBody.emailVerified = properties.emailVerified;
|
|
814
|
+
if (typeof properties.disabled === "boolean") requestBody.disabled = properties.disabled;
|
|
815
|
+
const response = await fetch(
|
|
816
|
+
`${IDENTITY_TOOLKIT_API}/projects/${projectId}/accounts`,
|
|
817
|
+
{
|
|
818
|
+
method: "POST",
|
|
819
|
+
headers: {
|
|
820
|
+
"Authorization": `Bearer ${accessToken}`,
|
|
821
|
+
"Content-Type": "application/json"
|
|
822
|
+
},
|
|
823
|
+
body: JSON.stringify(requestBody)
|
|
824
|
+
}
|
|
825
|
+
);
|
|
826
|
+
if (!response.ok) {
|
|
827
|
+
const errorText = await response.text();
|
|
828
|
+
throw new Error(`Failed to create user: ${response.status} ${errorText}`);
|
|
829
|
+
}
|
|
830
|
+
const data = await response.json();
|
|
831
|
+
return getUserByUid(data.localId);
|
|
832
|
+
}
|
|
833
|
+
async function updateUser(uid, properties) {
|
|
834
|
+
if (!uid || typeof uid !== "string") {
|
|
835
|
+
throw new Error("uid must be a non-empty string");
|
|
836
|
+
}
|
|
837
|
+
if (!properties || typeof properties !== "object") {
|
|
838
|
+
throw new Error("properties must be an object");
|
|
839
|
+
}
|
|
840
|
+
const projectId = getProjectId();
|
|
841
|
+
const accessToken = await getAdminAccessToken();
|
|
842
|
+
const requestBody = { localId: uid };
|
|
843
|
+
if (properties.email) requestBody.email = properties.email;
|
|
844
|
+
if (properties.password) requestBody.password = properties.password;
|
|
845
|
+
if (properties.displayName !== void 0) requestBody.displayName = properties.displayName;
|
|
846
|
+
if (properties.photoURL !== void 0) requestBody.photoUrl = properties.photoURL;
|
|
847
|
+
if (properties.phoneNumber !== void 0) requestBody.phoneNumber = properties.phoneNumber;
|
|
848
|
+
if (typeof properties.emailVerified === "boolean") requestBody.emailVerified = properties.emailVerified;
|
|
849
|
+
if (typeof properties.disabled === "boolean") requestBody.disableUser = properties.disabled;
|
|
850
|
+
const response = await fetch(
|
|
851
|
+
`${IDENTITY_TOOLKIT_API}/projects/${projectId}/accounts:update`,
|
|
852
|
+
{
|
|
853
|
+
method: "POST",
|
|
854
|
+
headers: {
|
|
855
|
+
"Authorization": `Bearer ${accessToken}`,
|
|
856
|
+
"Content-Type": "application/json"
|
|
857
|
+
},
|
|
858
|
+
body: JSON.stringify(requestBody)
|
|
859
|
+
}
|
|
860
|
+
);
|
|
861
|
+
if (!response.ok) {
|
|
862
|
+
const errorText = await response.text();
|
|
863
|
+
throw new Error(`Failed to update user: ${response.status} ${errorText}`);
|
|
864
|
+
}
|
|
865
|
+
return getUserByUid(uid);
|
|
866
|
+
}
|
|
867
|
+
async function deleteUser(uid) {
|
|
868
|
+
if (!uid || typeof uid !== "string") {
|
|
869
|
+
throw new Error("uid must be a non-empty string");
|
|
870
|
+
}
|
|
871
|
+
const projectId = getProjectId();
|
|
872
|
+
const accessToken = await getAdminAccessToken();
|
|
873
|
+
const response = await fetch(
|
|
874
|
+
`${IDENTITY_TOOLKIT_API}/projects/${projectId}/accounts:delete`,
|
|
875
|
+
{
|
|
876
|
+
method: "POST",
|
|
877
|
+
headers: {
|
|
878
|
+
"Authorization": `Bearer ${accessToken}`,
|
|
879
|
+
"Content-Type": "application/json"
|
|
880
|
+
},
|
|
881
|
+
body: JSON.stringify({ localId: uid })
|
|
882
|
+
}
|
|
883
|
+
);
|
|
884
|
+
if (!response.ok) {
|
|
885
|
+
const errorText = await response.text();
|
|
886
|
+
throw new Error(`Failed to delete user: ${response.status} ${errorText}`);
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
async function listUsers(maxResults = 1e3, pageToken) {
|
|
890
|
+
if (typeof maxResults !== "number" || maxResults < 1 || maxResults > 1e3) {
|
|
891
|
+
throw new Error("maxResults must be a number between 1 and 1000");
|
|
892
|
+
}
|
|
893
|
+
const projectId = getProjectId();
|
|
894
|
+
const accessToken = await getAdminAccessToken();
|
|
895
|
+
const params = new URLSearchParams({
|
|
896
|
+
maxResults: maxResults.toString()
|
|
897
|
+
});
|
|
898
|
+
if (pageToken) {
|
|
899
|
+
params.append("nextPageToken", pageToken);
|
|
900
|
+
}
|
|
901
|
+
const response = await fetch(
|
|
902
|
+
`${IDENTITY_TOOLKIT_API}/projects/${projectId}/accounts:query?${params.toString()}`,
|
|
903
|
+
{
|
|
904
|
+
method: "GET",
|
|
905
|
+
headers: {
|
|
906
|
+
"Authorization": `Bearer ${accessToken}`
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
);
|
|
910
|
+
if (!response.ok) {
|
|
911
|
+
const errorText = await response.text();
|
|
912
|
+
throw new Error(`Failed to list users: ${response.status} ${errorText}`);
|
|
913
|
+
}
|
|
914
|
+
const data = await response.json();
|
|
915
|
+
return {
|
|
916
|
+
users: (data.users || []).map(convertToUserRecord),
|
|
917
|
+
pageToken: data.nextPageToken
|
|
918
|
+
};
|
|
919
|
+
}
|
|
920
|
+
async function setCustomUserClaims(uid, customClaims) {
|
|
921
|
+
if (!uid || typeof uid !== "string") {
|
|
922
|
+
throw new Error("uid must be a non-empty string");
|
|
923
|
+
}
|
|
924
|
+
if (customClaims !== null) {
|
|
925
|
+
const serialized = JSON.stringify(customClaims);
|
|
926
|
+
if (new TextEncoder().encode(serialized).length > 1e3) {
|
|
927
|
+
throw new Error("customClaims must be less than 1000 bytes when serialized");
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
const projectId = getProjectId();
|
|
931
|
+
const accessToken = await getAdminAccessToken();
|
|
932
|
+
const requestBody = {
|
|
933
|
+
localId: uid,
|
|
934
|
+
customAttributes: customClaims ? JSON.stringify(customClaims) : "{}"
|
|
935
|
+
};
|
|
936
|
+
const response = await fetch(
|
|
937
|
+
`${IDENTITY_TOOLKIT_API}/projects/${projectId}/accounts:update`,
|
|
938
|
+
{
|
|
939
|
+
method: "POST",
|
|
940
|
+
headers: {
|
|
941
|
+
"Authorization": `Bearer ${accessToken}`,
|
|
942
|
+
"Content-Type": "application/json"
|
|
943
|
+
},
|
|
944
|
+
body: JSON.stringify(requestBody)
|
|
945
|
+
}
|
|
946
|
+
);
|
|
947
|
+
if (!response.ok) {
|
|
948
|
+
const errorText = await response.text();
|
|
949
|
+
throw new Error(`Failed to set custom claims: ${response.status} ${errorText}`);
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
|
|
719
953
|
// src/field-value.ts
|
|
720
954
|
function serverTimestamp() {
|
|
721
955
|
return {
|
|
@@ -1053,7 +1287,7 @@ async function setDocument(collectionPath, documentId, data, options) {
|
|
|
1053
1287
|
const nonTransformFields = Object.keys(cleanData);
|
|
1054
1288
|
if (nonTransformFields.length > 0) {
|
|
1055
1289
|
if (options?.merge) {
|
|
1056
|
-
updateWrite.updateMask = { fieldPaths:
|
|
1290
|
+
updateWrite.updateMask = { fieldPaths: nonTransformFields };
|
|
1057
1291
|
} else if (options?.mergeFields && options.mergeFields.length > 0) {
|
|
1058
1292
|
updateWrite.updateMask = { fieldPaths: options.mergeFields };
|
|
1059
1293
|
} else {
|
|
@@ -1067,7 +1301,11 @@ async function setDocument(collectionPath, documentId, data, options) {
|
|
|
1067
1301
|
const url = `${FIRESTORE_API}/${documentPath}`;
|
|
1068
1302
|
let queryParams = "";
|
|
1069
1303
|
if (options?.merge) {
|
|
1070
|
-
|
|
1304
|
+
const allFields = Object.keys(cleanData);
|
|
1305
|
+
if (allFields.length > 0) {
|
|
1306
|
+
const fieldPaths = allFields.join("&updateMask.fieldPaths=");
|
|
1307
|
+
queryParams = `?updateMask.fieldPaths=${fieldPaths}`;
|
|
1308
|
+
}
|
|
1071
1309
|
} else if (options?.mergeFields && options.mergeFields.length > 0) {
|
|
1072
1310
|
const fieldPaths = options.mergeFields.join("&updateMask.fieldPaths=");
|
|
1073
1311
|
queryParams = `?updateMask.fieldPaths=${fieldPaths}`;
|
|
@@ -1273,7 +1511,10 @@ async function batchWrite(operations) {
|
|
|
1273
1511
|
}
|
|
1274
1512
|
};
|
|
1275
1513
|
if (op.options?.merge) {
|
|
1276
|
-
|
|
1514
|
+
const nonTransformFields = Object.keys(cleanData);
|
|
1515
|
+
if (nonTransformFields.length > 0) {
|
|
1516
|
+
write.updateMask = { fieldPaths: nonTransformFields };
|
|
1517
|
+
}
|
|
1277
1518
|
} else if (op.options?.mergeFields) {
|
|
1278
1519
|
write.updateMask = { fieldPaths: op.options.mergeFields };
|
|
1279
1520
|
}
|
|
@@ -1896,8 +2137,10 @@ init_service_account();
|
|
|
1896
2137
|
countDocuments,
|
|
1897
2138
|
createCustomToken,
|
|
1898
2139
|
createSessionCookie,
|
|
2140
|
+
createUser,
|
|
1899
2141
|
deleteDocument,
|
|
1900
2142
|
deleteFile,
|
|
2143
|
+
deleteUser,
|
|
1901
2144
|
downloadFile,
|
|
1902
2145
|
fileExists,
|
|
1903
2146
|
generateSignedUrl,
|
|
@@ -1908,15 +2151,20 @@ init_service_account();
|
|
|
1908
2151
|
getFileMetadata,
|
|
1909
2152
|
getProjectId,
|
|
1910
2153
|
getServiceAccount,
|
|
2154
|
+
getUserByEmail,
|
|
2155
|
+
getUserByUid,
|
|
1911
2156
|
getUserFromToken,
|
|
1912
2157
|
initializeApp,
|
|
1913
2158
|
iterateCollection,
|
|
1914
2159
|
listDocuments,
|
|
1915
2160
|
listFiles,
|
|
2161
|
+
listUsers,
|
|
1916
2162
|
queryDocuments,
|
|
2163
|
+
setCustomUserClaims,
|
|
1917
2164
|
setDocument,
|
|
1918
2165
|
signInWithCustomToken,
|
|
1919
2166
|
updateDocument,
|
|
2167
|
+
updateUser,
|
|
1920
2168
|
uploadFile,
|
|
1921
2169
|
uploadFileResumable,
|
|
1922
2170
|
verifyIdToken,
|