diff --git a/.gitignore b/.gitignore index c141039..eb7f69c 100644 --- a/.gitignore +++ b/.gitignore @@ -7,7 +7,6 @@ /.pnp .pnp.js .cache -package-lock.json # testing /coverage diff --git a/README.md b/README.md index 461305a..038f06f 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # The Baby Equipment Exchange -## Introduction +## Introduction... -This project assists the collection and distribution of unused and gently used baby and child equipment. Over twenty different organizations are served by this exchange. +This project assists the collection and distribution of unused and gently used baby and child equipment. Over twenty dif.ferent organizations are served by this exchange. ## Dev remote Setup (Recommended for consistency, you can dev local if you don't want to work with docker) @@ -26,11 +26,12 @@ docker run -dit -p 3000:3000 -p 4000:4000 -p 5000:5000 -p 4400:4400 -p 4500:4500 12. open folder and navigate to /home/user/projects/baby-equipment-exchange/ 13. open a new terminal in VScode (verify that it's connected to the container not your host machine) the following command should start the emulators and the app: ``` + export FIREBASE_CONFIG="$(cat /home/user/projects/baby-equipment-exchange/firebaseConfig.json)" -export NEXT_PUBLIC_FIREBASE_CONFIG="$(cat /home/user/projects/baby-equipment-exchange/firebaseConfig.json)" npm run dev + ``` -13. see the output you can run in your host machine browser http://localhost:3000 +14. see the output you can run in your host machine browser http://localhost:3000 ## Dev Local Setup @@ -73,12 +74,9 @@ sudo echo 'GOOGLE_APPLICATION_CREDENTIALS="/home/user/projects/baby-equipment-ex sudo echo 'FIREBASE_EMULATORS_IMPORT_DIRECTORY="./data_directory"' >> /home/user/projects/baby-equipment-exchange/.env.local sudo apt-get install jq echo FIREBASE_CONFIG=\"$(jq -c . < firebaseConfig.json)\" >> .env.local -sudo echo NEXT_PUBLIC_FIREBASE_CONFIG=\"$(jq -c . < firebaseConfig.json)\" >> .env.local - export FIREBASE_EMULATORS_IMPORT_DIRECTORY="./data_directory" export GOOGLE_APPLICATION_CREDENTIALS="/home/user/projects/baby-equipment-exchange/serviceAccount.json" -export FIREBASE_CONFIG="$(cat /home/user/projects/baby-equipment-exchange/firebaseConfig.json)" -export NEXT_PUBLIC_FIREBASE_CONFIG="$(cat /home/user/projects/baby-equipment-exchange/firebaseConfig.json)" +export FIREBASE_CONFIG="$(cat /home/user/projects/baby-equipment-exchange/firebaseConfig.json)" ``` 3. install npm requirments and build project @@ -168,7 +166,7 @@ Scroll to Custom claims. Claims should already be present. If the text field is ![Firebase Emulator Auth edit existing user](https://raw.githubusercontent.com/codeforbtv/baby-equipment-exchange/main/docs/images/account_creation_3.png) -(Clicking outside the Edit user pop-up closes it) Scroll the slider down and select the **\*\*\*\***Save**\*\*\*\*** button: +(Clicking outside the Edit user pop-up closes it) Scroll the slider down and select the **Save** button: ![Firebase Emulator Auth save button](https://raw.githubusercontent.com/codeforbtv/baby-equipment-exchange/main/docs/images/account_creation_3_5.png) diff --git a/docker_image_build_files/Dockerfile b/docker_image_build_files/Dockerfile index a4a2721..16853a3 100644 --- a/docker_image_build_files/Dockerfile +++ b/docker_image_build_files/Dockerfile @@ -38,9 +38,7 @@ COPY firebase_emulator_files/ ${REPO_DIR}/ WORKDIR ${REPO_DIR} # Set default environment variables (these will be overwritten before build with terraform) ARG FIREBASE_CONFIG -ARG NEXT_PUBLIC_FIREBASE_CONFIG ENV FIREBASE_CONFIG=$FIREBASE_CONFIG -ENV NEXT_PUBLIC_FIREBASE_CONFIG=$NEXT_PUBLIC_FIREBASE_CONFIG RUN chmod +x /home/user/projects/baby-equipment-exchange/ @@ -49,15 +47,13 @@ RUN touch /home/user/projects/baby-equipment-exchange/.env.local # the below envinroment variables should be passed through terraform RUN echo 'GOOGLE_APPLICATION_CREDENTIALS="/home/user/projects/baby-equipment-exchange/serviceAccount.json"' >> /home/user/projects/baby-equipment-exchange/.env.local RUN echo 'FIREBASE_EMULATORS_IMPORT_DIRECTORY="./data_directory"' >> /home/user/projects/baby-equipment-exchange/.env.local -RUN echo FIREBASE_CONFIG=\"$(jq -c . < firebaseConfig.json)\" >> .env.local && \ - echo NEXT_PUBLIC_FIREBASE_CONFIG=\"$(jq -c . < firebaseConfig.json)\" >> .env.local +RUN echo FIREBASE_CONFIG=\"$(jq -c . < firebaseConfig.json)\" >> .env.local ENV FIREBASE_EMULATORS_IMPORT_DIRECTORY="./data_directory" ENV GOOGLE_APPLICATION_CREDENTIALS="/home/user/projects/baby-equipment-exchange/serviceAccount.json" ENV CYPRESS_INSTALL_BINARY=0 # Use a RUN command to export the environment variables RUN export FIREBASE_CONFIG="$(cat /home/user/projects/baby-equipment-exchange/firebaseConfig.json | jq -c .)" && \ - export NEXT_PUBLIC_FIREBASE_CONFIG="$(cat /home/user/projects/baby-equipment-exchange/firebaseConfig.json | jq -c .)" && \ npm install && \ cd /home/user/projects/baby-equipment-exchange/functions && \ npm install && \ diff --git a/docker_image_build_files/firebase_emulator_files/entrypoint.sh b/docker_image_build_files/firebase_emulator_files/entrypoint.sh index 9a343a6..05318e8 100644 --- a/docker_image_build_files/firebase_emulator_files/entrypoint.sh +++ b/docker_image_build_files/firebase_emulator_files/entrypoint.sh @@ -1,6 +1,5 @@ #!/bin/sh export FIREBASE_CONFIG="$(cat /home/user/projects/baby-equipment-exchange/firebaseConfig.json)" -export NEXT_PUBLIC_FIREBASE_CONFIG="$(cat /home/user/projects/baby-equipment-exchange/firebaseConfig.json)" # Execute the Docker CMD exec "$@" # Then open a new shell diff --git a/functions/src/index.ts b/functions/src/index.ts index e69c5c9..43a91e6 100644 --- a/functions/src/index.ts +++ b/functions/src/index.ts @@ -29,7 +29,7 @@ type Event = { modifiedAt: string; }; -const firebaseConfig = JSON.parse(process.env.NEXT_PUBLIC_FIREBASE_CONFIG ?? process.env.FIREBASE_CONFIG ?? '{}'); +const firebaseConfig = JSON.parse(process.env.FIREBASE_CONFIG ?? '{}'); const app: App = admin.initializeApp({ credential: applicationDefault(), diff --git a/next.config.js b/next.config.js index 86e899d..fbd4e4c 100644 --- a/next.config.js +++ b/next.config.js @@ -1,5 +1,11 @@ + +const FIREBASE_CONFIG = process.env.FIREBASE_CONFIG; + /** @type {import('next').NextConfig} */ const nextConfig = { + env: { + FIREBASE_CONFIG + }, experimental: { serverActions: true } diff --git a/package.json b/package.json index 5399244..ff5bbce 100644 --- a/package.json +++ b/package.json @@ -3,9 +3,9 @@ "version": "0.1.0", "private": true, "scripts": { - "dev": "node ./src/utils/setup.cjs --cmd=\"next dev\"", + "dev": "node ./src/utils/setup.cjs --cmd=0", "test:cypress": "npx cypress run --headless --component", - "test:unit": "node ./src/utils/setup.cjs --cmd=\"node ./node_modules/jest/bin/jest.js .*/.*\\.unit\\.test\\.ts.*\"", + "test:unit": "node ./src/utils/setup.cjs --cmd=1", "build": "next build", "start": "next start", "lint": "next lint", @@ -37,19 +37,20 @@ "@types/react-burger-menu": "^2.8.4", "@types/react-dom": "18.2.8", "autoprefixer": "10.4.16", + "dexie": "3.2.4", + "dexie-react-hooks": "^1.1.7", "eslint": "8.51.0", - "dexie": "^3.2.4", - "dexie-react-hooks": "1.1.7", "firebase": "^10.6.0", "firebase-admin": "^11.11.0", "firebase-functions": "^4.3.1", + "indexeddbshim": "13.0.0", "next": "^13.5.0", "postcss": "8.4.31", "react": "18.2.0", "react-burger-menu": "^3.0.9", "react-dom": "18.2.0", "sass": "1.69.5", - "tailwindcss": "3.3.3", + "tailwindcss": "3.4.1", "typescript": "5.2.2", "uuid": "^9.0.1" }, @@ -59,9 +60,9 @@ "@testing-library/jest-dom": "^6.1.3", "@testing-library/react": "^14.0.0", "@types/jest": "^29.5.5", - "@types/node": "^20.8.2", - "@types/react": "^18.2.24", - "@types/react-dom": "^18.2.8", + "@types/node": "^20.11.6", + "@types/react": "^18.2.51", + "@types/react-dom": "^18.2.18", "@types/react-redux": "^7.1.27", "@types/uuid": "^9.0.4", "@typescript-eslint/eslint-plugin": "^6.7.4", @@ -80,6 +81,6 @@ "prettier": "^3.0.0", "puppeteer": "^21.3.8", "ts-node": "^10.9.1", - "typescript": "^5.2.2" + "typescript": "^5.3.3" } } diff --git a/src/api/firebase-donations.ts b/src/api/firebase-donations.ts index 6c1c392..282026a 100644 --- a/src/api/firebase-donations.ts +++ b/src/api/firebase-donations.ts @@ -33,6 +33,7 @@ export const DONATION_DETAILS_COLLECTION = 'DonationDetails'; const donationConverter = { toFirestore(donation: Donation): DocumentData { const donationData: IDonation = { + id: donation.getId(), category: donation.getCategory(), brand: donation.getBrand(), model: donation.getModel(), @@ -52,6 +53,7 @@ const donationConverter = { fromFirestore(snapshot: QueryDocumentSnapshot, options: SnapshotOptions): Donation { const data = snapshot.data(options); const donationData: IDonation = { + id: data.id, category: data.category, brand: data.brand, model: data.model, @@ -175,80 +177,54 @@ export async function getDonations(filter: null | undefined): Promise { - const donations: Donation[] = []; - for (const donationDetail of donationDetails) { - const donationRef = donationDetail.getDonation().withConverter(donationConverter); - const donationSnapshot = await getDoc(donationRef); - if (donationSnapshot.exists()) { - const donation = donationSnapshot.data(); - const imagesRef: DocumentReference[] = donation.getImages() as DocumentReference[]; - imagesRef.push(...(donationDetail.getImages() as DocumentReference[])); - donation.images = await imageReferenceConverter(...imagesRef); - donations.push(donation); - } - } - return donations; -} - export async function addDonation(newDonation: DonationBody) { try { - const userId: string = await getUserId(); - const donationParams: IDonation = { - category: newDonation.category, - brand: newDonation.brand, - model: newDonation.model, - description: newDonation.description, - active: false, - images: [], // Only approved images display here. - createdAt: serverTimestamp() as Timestamp, - modifiedAt: serverTimestamp() as Timestamp - }; - - const donationDetailParams: IDonationDetail = { - donation: doc(db, `${DONATIONS_COLLECTION}/${userId}`), - availability: undefined, - donor: doc(db, `${USERS_COLLECTION}/${userId}`), - tagNumber: undefined, - tagNumberForItemDelivered: undefined, - sku: undefined, - recipientOrganization: undefined, - images: newDonation.images, - recipientContact: undefined, - recipientAddress: undefined, - requestor: undefined, - storage: undefined, - dateReceived: undefined, - dateDistributed: undefined, - scheduledPickupDate: undefined, - dateOrderFulfilled: undefined, - createdAt: serverTimestamp() as Timestamp, - modifiedAt: serverTimestamp() as Timestamp - }; - - const donation = new Donation(donationParams); - const donationDetail = new DonationDetail(donationDetailParams); - - try { - await runTransaction(db, async (transaction) => { - // Generate document references with firebase-generated IDs - const donationRef = doc(collection(db, DONATIONS_COLLECTION)); - const donationDetailRef = doc(collection(db, DONATION_DETAILS_COLLECTION)); - // Assign donation reference to donation detail - donationDetail.setDonation(donationRef); - - transaction.set(donationRef, donationConverter.toFirestore(donation)); - - transaction.set(donationDetailRef, donationDetailsConverter.toFirestore(donationDetail)); - }); - } catch (error: any) { - const keys: any[] = []; - for (const key in error) { - keys.push(key); - } - addEvent({ location: 'addDonation', keys: keys }); + await runTransaction(db, async (transaction) => { + // Generate document references with firebase-generated IDs + const donationRef = doc(collection(db, DONATIONS_COLLECTION)); + const donationDetailRef = doc(collection(db, DONATION_DETAILS_COLLECTION)); + const userId: string = await getUserId(); + const donationParams: IDonation = { + id: donationRef.id, + category: newDonation.category, + brand: newDonation.brand, + model: newDonation.model, + description: newDonation.description, + active: false, + images: [], // Only approved images display here. + createdAt: serverTimestamp() as Timestamp, + modifiedAt: serverTimestamp() as Timestamp + }; + const donationDetailParams: IDonationDetail = { + donation: donationRef, + availability: undefined, + donor: doc(db, `${USERS_COLLECTION}/${userId}`), + tagNumber: undefined, + tagNumberForItemDelivered: undefined, + sku: undefined, + recipientOrganization: undefined, + images: newDonation.images, + recipientContact: undefined, + recipientAddress: undefined, + requestor: undefined, + storage: undefined, + dateReceived: undefined, + dateDistributed: undefined, + scheduledPickupDate: undefined, + dateOrderFulfilled: undefined, + createdAt: serverTimestamp() as Timestamp, + modifiedAt: serverTimestamp() as Timestamp + }; + const donation = new Donation(donationParams); + const donationDetail = new DonationDetail(donationDetailParams); + transaction.set(donationRef, donationConverter.toFirestore(donation)); + transaction.set(donationDetailRef, donationDetailsConverter.toFirestore(donationDetail)); + }); + } catch (error: any) { + const keys: any[] = []; + for (const key in error) { + keys.push(key); } - } catch (error) { - addEvent(newDonation); + addEvent({ location: 'addDonation', keys: keys }); } } diff --git a/src/api/firebase.ts b/src/api/firebase.ts index 0411144..58105ac 100644 --- a/src/api/firebase.ts +++ b/src/api/firebase.ts @@ -15,7 +15,7 @@ import { } from 'firebase/auth'; import { AccountInformation, UserBody } from '@/types/post-data'; -const firebaseConfig = JSON.parse(process.env.NEXT_PUBLIC_FIREBASE_CONFIG ?? '{}'); +const firebaseConfig = JSON.parse(process.env.FIREBASE_CONFIG ?? '{}'); export const app: FirebaseApp = initializeApp(firebaseConfig); export const db: Firestore = initDb(); @@ -25,10 +25,7 @@ const functions = initFunctions(); function initDb(): Firestore { let _db: Firestore; - if ( - (process?.env?.NODE_ENV === 'test' || process?.env?.NODE_ENV === 'development') && - process?.env?.NEXT_PUBLIC_FIREBASE_EMULATORS_IMPORT_DIRECTORY !== undefined - ) { + if ((process?.env?.NODE_ENV === 'test' || process?.env?.NODE_ENV === 'development') && process?.env?.NEXT_PUBLIC_IMPORT_DIRECTORY != null) { const FIREBASE_EMULATORS_FIRESTORE_PORT = Number.parseInt(process.env.NEXT_PUBLIC_FIREBASE_EMULATORS_FIRESTORE_PORT ?? '8080'); _db = getFirestore(app); connectFirestoreEmulator(_db, '127.0.0.1', FIREBASE_EMULATORS_FIRESTORE_PORT); @@ -40,10 +37,7 @@ function initDb(): Firestore { function initFirebaseAuth() { let _auth: Auth; - if ( - (process?.env?.NODE_ENV === 'test' || process?.env?.NODE_ENV === 'development') && - process.env.NEXT_PUBLIC_FIREBASE_EMULATORS_IMPORT_DIRECTORY !== undefined - ) { + if ((process?.env?.NODE_ENV === 'test' || process?.env?.NODE_ENV === 'development') && process.env.NEXT_PUBLIC_IMPORT_DIRECTORY != null) { const FIREBASE_EMULATORS_AUTH_PORT = Number.parseInt(process.env.NEXT_PUBLIC_FIREBASE_EMULATORS_AUTH_PORT ?? '9099'); _auth = getAuth(app); connectAuthEmulator(_auth, `http://127.0.0.1:${FIREBASE_EMULATORS_AUTH_PORT}`); @@ -55,10 +49,7 @@ function initFirebaseAuth() { function initFirebaseStorage() { let _storage: FirebaseStorage; - if ( - (process?.env?.NODE_ENV === 'test' || process?.env?.NODE_ENV === 'development') && - process?.env?.NEXT_PUBLIC_FIREBASE_EMULATORS_IMPORT_DIRECTORY !== undefined - ) { + if ((process?.env?.NODE_ENV === 'test' || process?.env?.NODE_ENV === 'development') && process?.env?.NEXT_PUBLIC_IMPORT_DIRECTORY != null) { const FIREBASE_EMULATORS_STORAGE_PORT = Number.parseInt(process.env.NEXT_PUBLIC_FIREBASE_EMULATORS_STORAGE_PORT ?? '9199'); _storage = getStorage(app); connectStorageEmulator(_storage, '127.0.0.1', FIREBASE_EMULATORS_STORAGE_PORT); @@ -70,10 +61,7 @@ function initFirebaseStorage() { function initFunctions() { let _functions: Functions; - if ( - (process?.env?.NODE_ENV === 'test' || process?.env?.NODE_ENV === 'development') && - process?.env?.NEXT_PUBLIC_FIREBASE_EMULATORS_IMPORT_DIRECTORY !== undefined - ) { + if ((process?.env?.NODE_ENV === 'test' || process?.env?.NODE_ENV === 'development') && process?.env?.NEXT_PUBLIC_IMPORT_DIRECTORY != null) { const FIREBASE_EMULATORS_FUNCTIONS_PORT = Number.parseInt(process.env.NEXT_PUBLIC_FIREBASE_EMULATORS_FUNCTIONS_PORT ?? '5001'); _functions = getFunctions(app, 'us-east1'); connectFunctionsEmulator(_functions, '127.0.0.1', FIREBASE_EMULATORS_FUNCTIONS_PORT); diff --git a/src/models/donation.ts b/src/models/donation.ts index 33c2b1f..9439f7c 100644 --- a/src/models/donation.ts +++ b/src/models/donation.ts @@ -1,6 +1,12 @@ //Firebase types import { DocumentReference, Timestamp } from 'firebase/firestore'; +export interface IDonationCache { + [key: string]: string | number; + id: string; + modifiedAt: number; +} + export interface IDonation { [key: string]: | boolean @@ -15,6 +21,7 @@ export interface IDonation { | (() => boolean | null | undefined) | (() => string | null | undefined) | (() => Timestamp); + id: string; category: string | null | undefined; brand: string | null | undefined; model: string | null | undefined; @@ -39,6 +46,7 @@ export class Donation implements IDonation { | (() => boolean | null | undefined) | (() => string | null | undefined) | (() => Timestamp); + id: string; category: string | null | undefined; brand: string | null | undefined; model: string | null | undefined; @@ -49,6 +57,7 @@ export class Donation implements IDonation { modifiedAt: Timestamp; constructor(args: IDonation) { + this.id = args.id; this.category = args.category; this.brand = args.brand; this.model = args.model; @@ -59,6 +68,10 @@ export class Donation implements IDonation { this.modifiedAt = args.modifiedAt as Timestamp; } + getId(): string { + return this.id; + } + getCategory(): string | null | undefined { return this.category; } diff --git a/src/utils/setup.cjs b/src/utils/setup.cjs index 3434ae8..10aa662 100644 --- a/src/utils/setup.cjs +++ b/src/utils/setup.cjs @@ -1,9 +1,24 @@ +function _sanitize(text) { + if (text == null) { + return text; + } + return text.replace(/[^\d]/g, ''); +} + // eslint-disable-next-line @typescript-eslint/no-var-requires require('dotenv').config({ path: '.env.local' // Suppress the @typescript-eslint/no-var-requires rule. }); (() => { - let cmd = process.argv.splice(2).join(' ').slice(6); + const CMD_RAW = parseInt(_sanitize(process.argv.splice(2).join(' ').slice(6))); + let cmd = 'next dev'; + switch (CMD_RAW) { + case 1: + cmd = 'node ./node_modules/jest/bin/jest.js .*/.*.unit.test.ts.*'; + break; + default: + break; + } // eslint-disable-next-line @typescript-eslint/no-var-requires const execSync = require('child_process').execSync; // Suppress the @typescript-eslint/no-var-requires rule. // eslint-disable-next-line @typescript-eslint/no-var-requires @@ -12,16 +27,19 @@ require('dotenv').config({ if (firebaseJSON === undefined || process.env.FIREBASE_EMULATORS_IMPORT_DIRECTORY === undefined) { execSync(`${cmd}`, { stdio: 'inherit' }); } else { - const FIREBASE_EMULATORS_FIRESTORE_PORT = firebaseJSON.emulators?.firestore?.port ?? 8080; - const FIREBASE_EMULATORS_FUNCTIONS_PORT = firebaseJSON.emulators?.functions?.port ?? 5001; - const FIREBASE_EMULATORS_AUTH_PORT = firebaseJSON.emulators?.auth?.port ?? 9099; - const FIREBASE_EMULATORS_STORAGE_PORT = firebaseJSON.emulators?.storage?.port ?? 9199; + const FIREBASE_EMULATORS_FIRESTORE_PORT = _sanitize(firebaseJSON.emulators?.firestore?.port) ?? 8080; + const FIREBASE_EMULATORS_FUNCTIONS_PORT = _sanitize(firebaseJSON.emulators?.functions?.port) ?? 5001; + const FIREBASE_EMULATORS_AUTH_PORT = _sanitize(firebaseJSON.emulators?.auth?.port) ?? 9099; + const FIREBASE_EMULATORS_STORAGE_PORT = _sanitize(firebaseJSON.emulators?.storage?.port) ?? 9199; const TIMESTAMP = Date.now(); + const DATA_DIRECTORY_STATS = fs.lstatSync(process.env.FIREBASE_EMULATORS_IMPORT_DIRECTORY, { throwIfNoEntry: false }); + const SHOULD_IMPORT_DIRECTORY = DATA_DIRECTORY_STATS.isDirectory() ? 1 : null; + const DATA_DIRECTORY = DATA_DIRECTORY_STATS.isDirectory() ? fs.realpathSync(process.env.FIREBASE_EMULATORS_IMPORT_DIRECTORY) : 'data'; const DATA_DIRECTORY_CMD = fs.existsSync(process.env.FIREBASE_EMULATORS_IMPORT_DIRECTORY) - ? `--export-on-exit="${process.env.FIREBASE_EMULATORS_IMPORT_DIRECTORY}-${TIMESTAMP}" --import="${process.env.FIREBASE_EMULATORS_IMPORT_DIRECTORY}"` - : `--export-on-exit=${process.env.FIREBASE_EMULATORS_IMPORT_DIRECTORY}`; + ? `--export-on-exit="${DATA_DIRECTORY}-${TIMESTAMP}" --import="${DATA_DIRECTORY}"` + : `--export-on-exit=${DATA_DIRECTORY}`; execSync( - `node ./node_modules/dotenv-cli/cli.js -v NEXT_PUBLIC_FIREBASE_EMULATORS_IMPORT_DIRECTORY=${process.env.FIREBASE_EMULATORS_IMPORT_DIRECTORY} -v NEXT_PUBLIC_FIREBASE_EMULATORS_FIRESTORE_PORT=${FIREBASE_EMULATORS_FIRESTORE_PORT} -v NEXT_PUBLIC_FIREBASE_EMULATORS_FUNCTIONS_PORT=${FIREBASE_EMULATORS_FUNCTIONS_PORT} -v NEXT_PUBLIC_FIREBASE_EMULATORS_AUTH_PORT=${FIREBASE_EMULATORS_AUTH_PORT} -v NEXT_PUBLIC_FIREBASE_EMULATORS_STORAGE_PORT=${FIREBASE_EMULATORS_STORAGE_PORT} -- firebase --ui ${DATA_DIRECTORY_CMD} emulators:exec "${cmd}"`, + `node ./node_modules/dotenv-cli/cli.js -v NEXT_PUBLIC_IMPORT_DIRECTORY=${SHOULD_IMPORT_DIRECTORY} -v NEXT_PUBLIC_FIREBASE_EMULATORS_FIRESTORE_PORT=${FIREBASE_EMULATORS_FIRESTORE_PORT} -v NEXT_PUBLIC_FIREBASE_EMULATORS_FUNCTIONS_PORT=${FIREBASE_EMULATORS_FUNCTIONS_PORT} -v NEXT_PUBLIC_FIREBASE_EMULATORS_AUTH_PORT=${FIREBASE_EMULATORS_AUTH_PORT} -v NEXT_PUBLIC_FIREBASE_EMULATORS_STORAGE_PORT=${FIREBASE_EMULATORS_STORAGE_PORT} -- firebase --ui ${DATA_DIRECTORY_CMD} emulators:exec "${cmd}"`, { stdio: 'inherit' } ); } diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 264b3b0..ac48494 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -1,10 +1,20 @@ export function base64ToBlob(base64: string, contentType: string): Blob { const byteArray: Uint8Array = new Uint8Array(Array.from(atob(base64)).map((elem) => elem.charCodeAt(0))); const blob = new Blob([byteArray], { type: contentType }); - return blob; } +export async function blobToArrayBuffer(blob: Blob): Promise<{ arrayBuffer: ArrayBuffer; type: string }> { + try { + const arrayBuffer: ArrayBuffer = await blob.arrayBuffer(); + const type: string = blob.type; + return { arrayBuffer, type }; + } catch (error: any) { + // eslint-disable-line no-empty + } + return Promise.reject(); +} + export function contains(object: object, objects: object[]) { const objectString: string = JSON.stringify(object); for (let index = 0; index < objects.length; index++) {