123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349 |
- "use strict";
- Object.defineProperty(exports, "__esModule", { value: true });
- exports.toSerializedDate = exports.CloudStorageObjectMetadata = exports.CloudStorageObjectAccessControlMetadata = exports.CloudStorageBucketMetadata = exports.OutgoingFirebaseMetadata = exports.StoredFileMetadata = void 0;
- const uuid = require("uuid");
- const crypto = require("crypto");
- const registry_1 = require("../registry");
- const types_1 = require("../types");
- const crc_1 = require("./crc");
- class StoredFileMetadata {
- constructor(opts, _cloudFunctions, bytes) {
- this._cloudFunctions = _cloudFunctions;
- this.name = opts.name;
- this.bucket = opts.bucket;
- this.metageneration = opts.metageneration || 1;
- this.generation = opts.generation || Date.now();
- this.contentType = opts.contentType || "application/octet-stream";
- this.storageClass = opts.storageClass || "STANDARD";
- this.contentDisposition = opts.contentDisposition;
- this.cacheControl = opts.cacheControl;
- this.contentLanguage = opts.contentLanguage;
- this.customTime = opts.customTime;
- this.contentEncoding = opts.contentEncoding;
- this.downloadTokens = opts.downloadTokens || [];
- if (opts.etag) {
- this.etag = opts.etag;
- }
- else {
- this.etag = generateETag(this.generation, this.metageneration);
- }
- if (opts.customMetadata) {
- this.customMetadata = {};
- for (const [k, v] of Object.entries(opts.customMetadata)) {
- let stringVal = v;
- if (typeof stringVal !== "string") {
- stringVal = JSON.stringify(v);
- }
- this.customMetadata[k] = stringVal || "";
- }
- }
- this.timeCreated = opts.timeCreated ? new Date(opts.timeCreated) : new Date();
- this.updated = opts.updated ? new Date(opts.updated) : this.timeCreated;
- if (bytes) {
- this.size = bytes.byteLength;
- this.md5Hash = generateMd5Hash(bytes);
- this.crc32c = `${(0, crc_1.crc32c)(bytes)}`;
- }
- else if (opts.size !== undefined && opts.md5Hash && opts.crc32c) {
- this.size = opts.size;
- this.md5Hash = opts.md5Hash;
- this.crc32c = opts.crc32c;
- }
- else {
- throw new Error("Must pass bytes array or opts object with size, md5hash, and crc32c");
- }
- this.deleteFieldsSetAsNull();
- this.setDownloadTokensFromCustomMetadata();
- }
- clone() {
- const clone = new StoredFileMetadata({
- name: this.name,
- bucket: this.bucket,
- generation: this.generation,
- metageneration: this.metageneration,
- contentType: this.contentType,
- storageClass: this.storageClass,
- size: this.size,
- md5Hash: this.md5Hash,
- contentEncoding: this.contentEncoding,
- contentDisposition: this.contentDisposition,
- contentLanguage: this.contentLanguage,
- cacheControl: this.cacheControl,
- customTime: this.customTime,
- crc32c: this.crc32c,
- etag: this.etag,
- downloadTokens: this.downloadTokens,
- customMetadata: this.customMetadata,
- }, this._cloudFunctions);
- clone.timeCreated = this.timeCreated;
- clone.updated = this.updated;
- return clone;
- }
- asRulesResource(proposedChanges) {
- const proposedMetadata = this.clone();
- if (proposedChanges) {
- proposedMetadata.update(proposedChanges, false);
- }
- return {
- name: proposedMetadata.name,
- bucket: proposedMetadata.bucket,
- generation: proposedMetadata.generation,
- metageneration: proposedMetadata.metageneration,
- size: proposedMetadata.size,
- timeCreated: proposedMetadata.timeCreated,
- updated: proposedMetadata.updated,
- md5Hash: proposedMetadata.md5Hash,
- crc32c: proposedMetadata.crc32c,
- etag: proposedMetadata.etag,
- contentDisposition: proposedMetadata.contentDisposition,
- contentEncoding: proposedMetadata.contentEncoding,
- contentType: proposedMetadata.contentType,
- metadata: proposedMetadata.customMetadata || {},
- };
- }
- setDownloadTokensFromCustomMetadata() {
- if (!this.customMetadata) {
- return;
- }
- if (this.customMetadata.firebaseStorageDownloadTokens) {
- this.downloadTokens = [
- ...new Set([
- ...this.downloadTokens,
- ...this.customMetadata.firebaseStorageDownloadTokens.split(","),
- ]),
- ];
- delete this.customMetadata.firebaseStorageDownloadTokens;
- }
- }
- deleteFieldsSetAsNull() {
- const deletableFields = [
- "contentDisposition",
- "contentType",
- "contentLanguage",
- "contentEncoding",
- "cacheControl",
- ];
- deletableFields.map((field) => {
- if (this[field] === null) {
- delete this[field];
- }
- });
- if (this.customMetadata) {
- Object.keys(this.customMetadata).map((key) => {
- if (!this.customMetadata)
- return;
- if (this.customMetadata[key] === null) {
- delete this.customMetadata[key];
- }
- });
- }
- }
- update(incoming, shouldTrigger = true) {
- if (incoming.contentDisposition !== undefined) {
- this.contentDisposition =
- incoming.contentDisposition === null ? undefined : incoming.contentDisposition;
- }
- if (incoming.contentType !== undefined) {
- this.contentType = incoming.contentType === null ? undefined : incoming.contentType;
- }
- if (incoming.contentLanguage !== undefined) {
- this.contentLanguage =
- incoming.contentLanguage === null ? undefined : incoming.contentLanguage;
- }
- if (incoming.contentEncoding !== undefined) {
- this.contentEncoding =
- incoming.contentEncoding === null ? undefined : incoming.contentEncoding;
- }
- if (incoming.cacheControl !== undefined) {
- this.cacheControl = incoming.cacheControl === null ? undefined : incoming.cacheControl;
- }
- if (incoming.metadata !== undefined) {
- if (incoming.metadata === null) {
- this.customMetadata = undefined;
- }
- else {
- this.customMetadata = this.customMetadata || {};
- for (const [k, v] of Object.entries(incoming.metadata)) {
- if (v === null) {
- delete this.customMetadata[k];
- }
- else {
- this.customMetadata[k] = String(v);
- }
- }
- if (Object.keys(this.customMetadata).length === 0) {
- this.customMetadata = undefined;
- }
- }
- }
- this.metageneration++;
- this.updated = new Date();
- this.setDownloadTokensFromCustomMetadata();
- if (shouldTrigger) {
- this._cloudFunctions.dispatch("metadataUpdate", new CloudStorageObjectMetadata(this));
- }
- }
- addDownloadToken(shouldTrigger = true) {
- this.downloadTokens = [...(this.downloadTokens || []), uuid.v4()];
- this.update({}, shouldTrigger);
- }
- deleteDownloadToken(token) {
- if (!this.downloadTokens.length) {
- return;
- }
- const remainingTokens = this.downloadTokens.filter((t) => t !== token);
- this.downloadTokens = remainingTokens;
- if (remainingTokens.length === 0) {
- this.addDownloadToken(false);
- }
- this.update({});
- }
- static fromJSON(data, cloudFunctions) {
- const opts = JSON.parse(data);
- return new StoredFileMetadata(opts, cloudFunctions);
- }
- static toJSON(metadata) {
- return JSON.stringify(metadata, (key, value) => {
- if (key.startsWith("_")) {
- return undefined;
- }
- return value;
- }, 2);
- }
- }
- exports.StoredFileMetadata = StoredFileMetadata;
- class OutgoingFirebaseMetadata {
- constructor(metadata) {
- this.name = metadata.name;
- this.bucket = metadata.bucket;
- this.generation = metadata.generation.toString();
- this.metageneration = metadata.metageneration.toString();
- this.contentType = metadata.contentType;
- this.timeCreated = toSerializedDate(metadata.timeCreated);
- this.updated = toSerializedDate(metadata.updated);
- this.storageClass = metadata.storageClass;
- this.size = metadata.size.toString();
- this.md5Hash = metadata.md5Hash;
- this.crc32c = metadata.crc32c;
- this.etag = metadata.etag;
- this.downloadTokens = metadata.downloadTokens.join(",");
- this.contentEncoding = metadata.contentEncoding || "identity";
- this.contentDisposition = metadata.contentDisposition;
- this.metadata = metadata.customMetadata;
- this.contentLanguage = metadata.contentLanguage;
- this.cacheControl = metadata.cacheControl;
- }
- }
- exports.OutgoingFirebaseMetadata = OutgoingFirebaseMetadata;
- class CloudStorageBucketMetadata {
- constructor(id) {
- this.kind = "storage#bucket";
- this.name = id;
- this.id = id;
- const selfLink = registry_1.EmulatorRegistry.url(types_1.Emulators.STORAGE);
- selfLink.pathname = `/v1/b/${this.id}`;
- this.selfLink = selfLink.toString();
- this.timeCreated = toSerializedDate(new Date());
- this.updated = this.timeCreated;
- this.projectNumber = "000000000000";
- this.metageneration = "1";
- this.location = "US";
- this.storageClass = "STANDARD";
- this.etag = "====";
- this.locationType = "mutli-region";
- }
- }
- exports.CloudStorageBucketMetadata = CloudStorageBucketMetadata;
- class CloudStorageObjectAccessControlMetadata {
- constructor(object, generation, selfLink, id, role, entity, bucket, etag) {
- this.object = object;
- this.generation = generation;
- this.selfLink = selfLink;
- this.id = id;
- this.role = role;
- this.entity = entity;
- this.bucket = bucket;
- this.etag = etag;
- this.kind = "storage#objectAccessControl";
- }
- }
- exports.CloudStorageObjectAccessControlMetadata = CloudStorageObjectAccessControlMetadata;
- class CloudStorageObjectMetadata {
- constructor(metadata) {
- this.kind = "storage#object";
- this.name = metadata.name;
- this.bucket = metadata.bucket;
- this.generation = metadata.generation.toString();
- this.metageneration = metadata.metageneration.toString();
- this.contentType = metadata.contentType;
- this.contentDisposition = metadata.contentDisposition;
- this.timeCreated = toSerializedDate(metadata.timeCreated);
- this.updated = toSerializedDate(metadata.updated);
- this.storageClass = metadata.storageClass;
- this.size = metadata.size.toString();
- this.md5Hash = metadata.md5Hash;
- this.etag = metadata.etag;
- this.metadata = {};
- if (Object.keys(metadata.customMetadata || {})) {
- this.metadata = Object.assign(Object.assign({}, this.metadata), metadata.customMetadata);
- }
- if (metadata.downloadTokens.length) {
- this.metadata = Object.assign(Object.assign({}, this.metadata), { firebaseStorageDownloadTokens: metadata.downloadTokens.join(",") });
- }
- if (!Object.keys(this.metadata).length) {
- delete this.metadata;
- }
- if (metadata.contentLanguage) {
- this.contentLanguage = metadata.contentLanguage;
- }
- if (metadata.cacheControl) {
- this.cacheControl = metadata.cacheControl;
- }
- if (metadata.contentDisposition) {
- this.contentDisposition = metadata.contentDisposition;
- }
- if (metadata.contentEncoding) {
- this.contentEncoding = metadata.contentEncoding;
- }
- if (metadata.customTime) {
- this.customTime = toSerializedDate(metadata.customTime);
- }
- this.crc32c = (0, crc_1.crc32cToString)(metadata.crc32c);
- this.timeStorageClassUpdated = toSerializedDate(metadata.timeCreated);
- this.id = `${metadata.bucket}/${metadata.name}/${metadata.generation}`;
- const selfLink = registry_1.EmulatorRegistry.url(types_1.Emulators.STORAGE);
- selfLink.pathname = `/storage/v1/b/${metadata.bucket}/o/${encodeURIComponent(metadata.name)}`;
- this.selfLink = selfLink.toString();
- const mediaLink = registry_1.EmulatorRegistry.url(types_1.Emulators.STORAGE);
- mediaLink.pathname = `/download/storage/v1/b/${metadata.bucket}/o/${encodeURIComponent(metadata.name)}`;
- mediaLink.searchParams.set("generation", metadata.generation.toString());
- mediaLink.searchParams.set("alt", "media");
- this.mediaLink = mediaLink.toString();
- }
- }
- exports.CloudStorageObjectMetadata = CloudStorageObjectMetadata;
- function toSerializedDate(d) {
- const day = `${d.getUTCFullYear()}-${(d.getUTCMonth() + 1).toString().padStart(2, "0")}-${d
- .getUTCDate()
- .toString()
- .padStart(2, "0")}`;
- const time = `${d.getUTCHours().toString().padStart(2, "0")}:${d
- .getUTCMinutes()
- .toString()
- .padStart(2, "0")}:${d.getUTCSeconds().toString().padStart(2, "0")}.${d
- .getUTCMilliseconds()
- .toString()
- .padStart(3, "0")}`;
- return `${day}T${time}Z`;
- }
- exports.toSerializedDate = toSerializedDate;
- function generateMd5Hash(bytes) {
- const hash = crypto.createHash("md5");
- hash.update(bytes);
- return hash.digest("base64");
- }
- function generateETag(generation, metadatageneration) {
- const hash = crypto.createHash("sha1");
- hash.update(`${generation}/${metadatageneration}`);
- return hash.digest("base64").slice(0, -1);
- }
|