-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
24 changed files
with
655 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
name: CI | ||
|
||
on: | ||
push: | ||
branches: | ||
- main | ||
|
||
pull_request: | ||
branches: | ||
- main | ||
|
||
jobs: | ||
test: | ||
runs-on: ${{ matrix.os }} | ||
|
||
strategy: | ||
matrix: | ||
os: [ubuntu-latest, macos-latest] | ||
fail-fast: false | ||
|
||
steps: | ||
- id: checkout | ||
name: Checkout | ||
uses: actions/checkout@v3 | ||
- id: setup-bun | ||
name: Setup Bun | ||
uses: oven-sh/setup-bun@v1 | ||
with: | ||
bun-version: latest | ||
- id: install-deps | ||
name: Install dependencies | ||
run: | | ||
bun install | ||
- id: test | ||
name: Run test | ||
run: | | ||
bun test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
name: Release | ||
|
||
on: | ||
push: | ||
tags: | ||
- 'v*' | ||
|
||
jobs: | ||
release: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v3 | ||
with: | ||
fetch-depth: 0 | ||
|
||
- uses: actions/setup-node@v3 | ||
with: | ||
node-version: 16.x | ||
|
||
- run: npx changelogithub | ||
env: | ||
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
node_modules | ||
dist |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,26 @@ | ||
# firebase-admin-rest | ||
Firebase admin wrapper on REST apis works on Vercel edge functions, cloudflare workers, bun, deno or any js runtime. | ||
# bun starter | ||
|
||
## Getting Started | ||
|
||
Click the [Use this template](https://github.com/wobsoriano/bun-lib-starter/generate) button to create a new repository with the contents starter. | ||
|
||
OR | ||
|
||
Run `bun create wobsoriano/bun-lib-starter ./my-lib`. | ||
|
||
## Setup | ||
|
||
```bash | ||
# install dependencies | ||
bun install | ||
|
||
# test the app | ||
bun test | ||
|
||
# build the app, available under dist | ||
bun run build | ||
``` | ||
|
||
## License | ||
|
||
MIT |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import dts from 'bun-plugin-dts' | ||
|
||
await Bun.build({ | ||
entrypoints: ['./src/index.ts'], | ||
outdir: './dist', | ||
minify: true, | ||
plugins: [dts()] | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
{ | ||
"name": "firebase-edge", | ||
"version": "0.0.0", | ||
"main": "dist/index.js", | ||
"types": "dist/index.d.ts", | ||
"description": "", | ||
"scripts": { | ||
"build": "bun run build.mjs", | ||
"prepublishOnly": "bun run build", | ||
"dev-test": "bun run src/tests/index.ts" | ||
}, | ||
"files": [ | ||
"dist" | ||
], | ||
"keywords": [ | ||
"bun" | ||
], | ||
"license": "MIT", | ||
"homepage": "https://github.com/wobsoriano/pkg-name#readme", | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/wobsoriano/pkg-name.git" | ||
}, | ||
"bugs": "https://github.com/wobsoriano/pkg-name/issues", | ||
"author": "Robert Soriano <[email protected]>", | ||
"devDependencies": { | ||
"bun-plugin-dts": "^0.2.1", | ||
"@types/bun": "^1.0.0", | ||
"typescript": "^5.2.2" | ||
}, | ||
"dependencies": { | ||
"@tsndr/cloudflare-worker-jwt": "^2.5.3", | ||
"dotenv": "^16.4.5" | ||
} | ||
} |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
|
||
|
||
import * as jwt from '@tsndr/cloudflare-worker-jwt' | ||
import { FirebaseAdminConfig, FirestoreDatabase } from '../types'; | ||
|
||
export async function generateJWT(input?: { | ||
service?: string, | ||
serviceAccount?: { | ||
client_email: string; | ||
private_key: string; | ||
private_key_id: string; | ||
} | ||
}) { | ||
const serviceAccount = input?.serviceAccount || JSON.parse(process.env.GCLOUD_SERVICE_ACCOUNT || '{}'); | ||
// const serviceAccount: { | ||
// client_email: string; | ||
// private_key: string; | ||
// private_key_id: string; | ||
// } | undefined = JSON.parse(process.env.SERVICE_ACCOUNT || '{}'); | ||
if (!serviceAccount) throw new Error('SERVICE_ACCOUNT not found in environment variables'); | ||
const privateKey = serviceAccount.private_key; | ||
const signedJwt = await jwt.sign( | ||
{ | ||
iss: serviceAccount.client_email, | ||
sub: serviceAccount.client_email, | ||
// scope: 'https://www.googleapis.com/auth/datastore', | ||
aud: `https://${input?.service || 'firestore'}.googleapis.com/`, | ||
iat: Math.floor(Date.now() / 1000), | ||
exp: Math.floor(Date.now() / 1000) + 3600, // Expires in 1 hour | ||
}, | ||
privateKey, | ||
{ | ||
algorithm: 'RS256', | ||
header: { | ||
'kid': serviceAccount.private_key_id, | ||
'typ': 'JWT', | ||
'alg': 'RS256', | ||
}, | ||
}); | ||
|
||
return signedJwt; | ||
} | ||
|
||
export async function initEdgeFirebase(options: { | ||
serviceAccount: FirebaseAdminConfig | ||
databaseId?: string; | ||
}): Promise<FirestoreDatabase> { | ||
if (options.serviceAccount.project_id === undefined) throw new Error('project_id is required in serviceAccount.'); | ||
const accessToken = await generateJWT({ serviceAccount: options.serviceAccount }); | ||
process.env.FIREBASE_REST_ACCESS_TOKEN = accessToken; | ||
process.env.FIREBASE_REST_PROJECT_ID = options.serviceAccount.project_id; | ||
process.env.FIREBASE_REST_DATABASE_ID = options.databaseId || '(default)'; | ||
return { | ||
name: options.databaseId || '(default)', | ||
projectId: options.serviceAccount?.project_id, | ||
accessToken: accessToken | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import { typedEnv } from ".."; | ||
import { generateFirebaseReqHeaders } from "./utils"; | ||
|
||
/** | ||
* Fetches documents from Firestore. | ||
* @param {string} collectionPath - The path to the Firestore collection. | ||
* @param {Object} options - Additional options for fetching documents. | ||
* @param {number | undefined} options.limit - Optional. The maximum number of documents to fetch defaults to 100. | ||
* @param {string | undefined} options.nextPageToken - The token for fetching the next page of documents. | ||
* @template T - The type of the documents being fetched. Defaults to 'any'. | ||
* @returns {Promise<RestDocuments<T>>} A Promise that resolves to a response object containing fetched Firestore documents. | ||
*/ | ||
export async function deleteDocEdge( | ||
docPath: string, | ||
options?: { | ||
limit?: number, | ||
nextPageToken?: string | ||
}): Promise<{ | ||
response?: Response, | ||
error?: any, | ||
}> { | ||
|
||
try { | ||
let qs = new URLSearchParams({ | ||
fields: 'documents(fields,name),nextPageToken', | ||
}); | ||
|
||
if (options?.nextPageToken) { | ||
qs.append('pageToken', options.nextPageToken); | ||
} | ||
|
||
const deleteResponse = await fetch(`https://firestore.googleapis.com/v1beta1/projects/speakwiz-app/databases/${typedEnv.FIREBASE_REST_DATABASE_ID}/documents/${docPath}`, { | ||
method: 'DELETE', | ||
headers: { | ||
...generateFirebaseReqHeaders() | ||
}, | ||
}) | ||
return { | ||
response: deleteResponse | ||
} | ||
} catch (error) { | ||
return { | ||
error: error | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import { typedEnv } from ".."; | ||
import { CompatibleDocument } from "../types"; | ||
import { formatValuesWithType, generateFirebaseReqHeaders } from "./utils"; | ||
|
||
/** | ||
* Fetches documents from Firestore. | ||
* @param {string} docPath - The path to the Firestore document. | ||
* @param {Object | undefined} options - Additional options for fetching documents. | ||
* @param {number | undefined} options.db - Optional. database-id instead of the default one. | ||
* @template T - The type of the document being fetched. Defaults to 'any'. | ||
* @returns {Promise<CompatibleDocument<T>>} A Promise that resolves to a response object containing fetched Firestore document. | ||
*/ | ||
export async function getDocEdge( | ||
docPath: string, | ||
options?: { | ||
db?: string | ||
}): Promise<CompatibleDocument> { | ||
try { | ||
const response: any = await fetch(`https://firestore.googleapis.com/v1beta1/projects/speakwiz-app/databases/${typedEnv.FIREBASE_REST_PROJECT_ID}/documents/${docPath}`, { | ||
method: 'GET', | ||
headers: generateFirebaseReqHeaders(options?.db || typedEnv.FIREBASE_REST_DATABASE_ID) | ||
} | ||
).then((res) => res.json()); | ||
// console.log(response) | ||
|
||
if (response?.fields) { | ||
return { | ||
id: docPath.includes(`/`) ? (docPath.split('/').pop() || docPath) : docPath, | ||
exists: () => true, | ||
data: () => formatValuesWithType(response) | ||
} | ||
} else { | ||
return { | ||
id: docPath.includes(`/`) ? (docPath.split('/').pop() || docPath) : docPath, | ||
exists: () => false, | ||
data: () => undefined, | ||
} | ||
} | ||
} catch (error) { | ||
console.error(error) | ||
return { | ||
id: docPath.includes(`/`) ? (docPath.split('/').pop() || docPath) : docPath, | ||
exists: () => false, | ||
data: () => undefined, | ||
error: error, | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
|
||
import { typedEnv } from ".."; | ||
import { FirestoreDocument, RestDocuments } from "../types"; | ||
import { formatValuesWithType, generateFirebaseReqHeaders } from "./utils"; | ||
|
||
/** | ||
* Fetches documents from Firestore. | ||
* @param {string} collectionPath - The path to the Firestore collection. | ||
* @param {Object| undefined} options - Additional options for fetching documents. | ||
* @param {number | undefined} options.limit - Optional. The maximum number of documents to fetch defaults to 100. | ||
* @param {string | undefined} options.nextPageToken - The token for fetching the next page of documents. | ||
* @template T - The type of the documents being fetched. Defaults to 'any'. | ||
* @returns {Promise<RestDocuments<T>>} A Promise that resolves to a response object containing fetched Firestore documents. | ||
*/ | ||
export async function getDocsEdge<T = any>( | ||
collectionPath: string, | ||
options?: { | ||
limit?: number, | ||
nextPageToken?: string | ||
}): Promise<RestDocuments<T>> { | ||
try { | ||
|
||
let qs = new URLSearchParams({ | ||
fields: 'documents(fields,name),nextPageToken', | ||
}); | ||
|
||
if (options?.nextPageToken) { | ||
qs.append('pageToken', options.nextPageToken); | ||
} | ||
|
||
const res: any = await fetch(`https://firestore.googleapis.com/v1beta1/projects/speakwiz-app/databases/${typedEnv.FIREBASE_REST_DATABASE_ID}/documents/${collectionPath}?${qs.toString()}&pageSize=${options?.limit || 100}`, { | ||
method: 'GET', | ||
headers: { | ||
...generateFirebaseReqHeaders(typedEnv.FIREBASE_REST_DATABASE_ID) | ||
// "Authorization": "Bearer " + accessToken, | ||
// "x-goog-request-params": `project_id=speakwiz-app&database_id=${options.bucket}` | ||
}, | ||
}).then((res) => res.json()); | ||
|
||
const rawDocs = res?.documents || []; | ||
|
||
if (rawDocs?.length > 0) { | ||
const docs = rawDocs.map((docRef: { | ||
name: string, | ||
fields: { | ||
[key: string]: FirestoreDocument | ||
} | ||
}) => { | ||
return formatValuesWithType(docRef); | ||
}); | ||
|
||
return { | ||
size: docs?.length, | ||
empty: docs?.length === 0, | ||
docs: docs | ||
}; | ||
} else { | ||
return { | ||
size: 0, | ||
empty: true, | ||
docs: [] | ||
}; | ||
} | ||
} catch (error) { | ||
console.error(error); | ||
return { | ||
size: 0, | ||
empty: true, | ||
docs: [], | ||
error: error | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { initEdgeFirebase } from "../firebase-auth-utils/initFirebase"; | ||
import { deleteDocEdge } from "./deleteDoc"; | ||
import { getDocEdge } from "./getDoc"; | ||
import { getDocsEdge } from "./getDocs"; | ||
|
||
export { | ||
initEdgeFirebase, | ||
getDocEdge, | ||
getDocsEdge, | ||
deleteDocEdge | ||
} |
Empty file.
Empty file.
Empty file.
Oops, something went wrong.