Support analytics data in user export bundle

GitOrigin-RevId: 49739297f40831cf035e2a9d4f3343a8cb2d7fdb
This commit is contained in:
John Lees-Miller
2025-11-19 14:29:07 +00:00
committed by Copybot
parent 241a4b6b03
commit b514ebcc8e
4 changed files with 39 additions and 6 deletions

View File

@@ -160,4 +160,21 @@ module.exports = class AbstractPersistor {
name,
})
}
/**
* List objects in a directory, returning the full keys.
*
* Suitable only for directories where the number of keys is known to be small.
*
* @param {string} location
* @param {string} prefix
* @returns {Promise<Array<string>>}
*/
async listDirectoryKeys(location, prefix) {
throw new NotImplementedError('method not implemented in persistor', {
method: 'listDirectoryKeys',
location,
prefix,
})
}
}

View File

@@ -194,6 +194,11 @@ module.exports = class FSPersistor extends AbstractPersistor {
}
}
async listDirectoryKeys(location, name) {
const fsPath = this._getFsPath(location, name)
return await this._listDirectory(fsPath)
}
async checkIfObjectExists(location, name) {
const fsPath = this._getFsPath(location, name)
try {

View File

@@ -288,23 +288,25 @@ module.exports = class GcsPersistor extends AbstractPersistor {
} while (query)
}
async directorySize(bucketName, key) {
let files
const prefix = ensurePrefixIsDirectory(key)
async #listDirectory(bucketName, prefix) {
try {
const [response] = await this.storage
.bucket(bucketName)
.getFiles({ prefix })
files = response
return response
} catch (err) {
throw PersistorHelper.wrapError(
err,
'failed to list objects in GCS',
{ bucketName, key },
{ bucketName, prefix },
ReadError
)
}
}
async directorySize(bucketName, key) {
const prefix = ensurePrefixIsDirectory(key)
const files = await this.#listDirectory(bucketName, prefix)
return files.reduce(
(acc, file) => parseInt(file.metadata.size, 10) + acc,
@@ -312,6 +314,14 @@ module.exports = class GcsPersistor extends AbstractPersistor {
)
}
async listDirectoryKeys(bucketName, prefix) {
const files = await this.#listDirectory(
bucketName,
ensurePrefixIsDirectory(prefix)
)
return files.map(file => file.name)
}
async checkIfObjectExists(bucketName, key) {
try {
const [response] = await this.storage

View File

@@ -353,6 +353,7 @@ module.exports = {
'scripts/suspend_users.mjs',
'scripts/sync-user-entitlements/sync-user-entitlements.mjs',
'scripts/update_project_image_name.mjs',
'scripts/user-export/analytics.mjs',
'scripts/user-export/fs.mjs',
'scripts/user-export/http.mjs',
'scripts/user-export/observer.mjs',