Merge pull request #4864 from mslourens/google_firebase_integration
Google firebase integration
This commit is contained in:
commit
2d011bce0d
|
@ -0,0 +1,54 @@
|
||||||
|
<script>
|
||||||
|
export let width = "100"
|
||||||
|
export let height = "100"
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
viewBox="23 6 469 132"
|
||||||
|
{width}
|
||||||
|
{height}
|
||||||
|
>
|
||||||
|
<defs id="defs202">
|
||||||
|
<linearGradient id="a" x1="-3.49%" x2="100.83%" y1="17.02%" y2="92.9%">
|
||||||
|
<stop offset="0%" stop-color="#fff" stop-opacity=".1" id="stop192" />
|
||||||
|
<stop offset="14%" stop-color="#fff" stop-opacity=".08" id="stop194" />
|
||||||
|
<stop offset="61%" stop-color="#fff" stop-opacity=".02" id="stop196" />
|
||||||
|
<stop offset="100%" stop-color="#fff" stop-opacity="0" id="stop198" />
|
||||||
|
</linearGradient>
|
||||||
|
<path
|
||||||
|
id="b"
|
||||||
|
d="M106.687 35.2742c-.186-1.0977-.967-2-2.0244-2.338s-2.2148-.057-3.0002.73L86.2473 49.166l-12.12-23.1455c-.5133-.9786-1.525-1.5914-2.6273-1.5914s-2.114.6128-2.6273 1.5914l-6.6277 12.656L45.62 7.5726c-.603-1.1297-1.8588-1.746-3.118-1.5297s-2.2394 1.216-2.4335 2.4827L24 111.701l42.9727 24.1654c2.6985 1.5113 5.985 1.5113 8.6836 0L119 111.701l-12.313-76.427z"
|
||||||
|
/>
|
||||||
|
</defs>
|
||||||
|
<g id="g305" transform="matrix(2.9011579,0,0,2.9011579,43.533284,-135.93685)">
|
||||||
|
<path
|
||||||
|
fill="#ffa000"
|
||||||
|
d="M 23.8266,111.7182 39.9588,8.4901 c 0.1972,-1.266 1.1818,-2.264 2.445,-2.4786 1.2632,-0.2146 2.522,0.4028 3.126,1.5327 L 62.2133,38.6615 68.8633,26 c 0.515,-0.979 1.5303,-1.592 2.6366,-1.592 1.1063,0 2.1215,0.613 2.6366,1.592 l 45.0227,85.718 H 23.8266 Z"
|
||||||
|
id="path204"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill="#f57c00"
|
||||||
|
d="M 79.566,71.5074 62.2124,38.6472 23.8334,111.7187 Z"
|
||||||
|
id="path206"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill="#ffca28"
|
||||||
|
d="m 119.1666,111.7187 -12.356,-76.4603 c -0.1867,-1.098 -0.9703,-2 -2.0315,-2.34 -1.0612,-0.34 -2.2226,-0.057 -3.0107,0.7302 l -77.935,78.069 43.1234,24.1834 c 2.708,1.512 6.006,1.512 8.714,0 l 43.4958,-24.1834 z"
|
||||||
|
id="path208"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill="#ffffff"
|
||||||
|
fill-opacity="0.2"
|
||||||
|
d="m 106.8105,35.2584 c -0.1867,-1.098 -0.9703,-2 -2.0315,-2.34 -1.0612,-0.34 -2.2226,-0.057 -3.0107,0.7302 L 86.3,49.1562 74.1365,26 c -0.515,-0.979 -1.5303,-1.592 -2.6366,-1.592 -1.1063,0 -2.1215,0.613 -2.6366,1.592 L 62.2133,38.6615 45.529,7.5447 C 44.924,6.4145 43.6637,5.7981 42.399,6.0143 41.1343,6.2305 40.153,7.231 39.958,8.498 L 23.8333,111.7187 h -0.052 l 0.052,0.0596 0.4245,0.2085 77.488,-77.5775 c 0.7877,-0.7915 1.952,-1.076 3.016,-0.737 1.064,0.339 1.849,1.2445 2.0338,2.3457 l 12.2518,75.775 0.1192,-0.0745 -12.356,-76.4603 z M 23.9748,111.5772 39.9655,9.228 c 0.1948,-1.267 1.1784,-2.2675 2.442,-2.4837 1.2636,-0.2162 2.524,0.4 3.13,1.5304 L 62.22,39.392 68.87,26.7305 c 0.515,-0.979 1.5303,-1.592 2.6366,-1.592 1.1063,0 2.1215,0.613 2.6366,1.592 l 11.9167,22.664 -62.0858,62.1827 z"
|
||||||
|
id="path210"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill="#a52714"
|
||||||
|
opacity="0.2"
|
||||||
|
d="m 75.6708,135.1722 c -2.708,1.512 -6.006,1.512 -8.714,0 l -43.0192,-24.1162 -0.1043,0.663 43.1234,24.176 c 2.708,1.512 6.006,1.512 8.714,0 l 43.4958,-24.176 -0.1117,-0.6852 -43.384,24.1387 z"
|
||||||
|
id="path212"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
|
@ -0,0 +1,67 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
viewBox="23 6 469 132"
|
||||||
|
width="100"
|
||||||
|
height="100"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<defs
|
||||||
|
id="defs202">
|
||||||
|
<linearGradient
|
||||||
|
id="a"
|
||||||
|
x1="-3.49%"
|
||||||
|
x2="100.83%"
|
||||||
|
y1="17.02%"
|
||||||
|
y2="92.9%">
|
||||||
|
<stop
|
||||||
|
offset="0%"
|
||||||
|
stop-color="#fff"
|
||||||
|
stop-opacity=".1"
|
||||||
|
id="stop192" />
|
||||||
|
<stop
|
||||||
|
offset="14%"
|
||||||
|
stop-color="#fff"
|
||||||
|
stop-opacity=".08"
|
||||||
|
id="stop194" />
|
||||||
|
<stop
|
||||||
|
offset="61%"
|
||||||
|
stop-color="#fff"
|
||||||
|
stop-opacity=".02"
|
||||||
|
id="stop196" />
|
||||||
|
<stop
|
||||||
|
offset="100%"
|
||||||
|
stop-color="#fff"
|
||||||
|
stop-opacity="0"
|
||||||
|
id="stop198" />
|
||||||
|
</linearGradient>
|
||||||
|
<path
|
||||||
|
id="b"
|
||||||
|
d="M106.687 35.2742c-.186-1.0977-.967-2-2.0244-2.338s-2.2148-.057-3.0002.73L86.2473 49.166l-12.12-23.1455c-.5133-.9786-1.525-1.5914-2.6273-1.5914s-2.114.6128-2.6273 1.5914l-6.6277 12.656L45.62 7.5726c-.603-1.1297-1.8588-1.746-3.118-1.5297s-2.2394 1.216-2.4335 2.4827L24 111.701l42.9727 24.1654c2.6985 1.5113 5.985 1.5113 8.6836 0L119 111.701l-12.313-76.427z" />
|
||||||
|
</defs>
|
||||||
|
<g
|
||||||
|
id="g305"
|
||||||
|
transform="matrix(2.9011579,0,0,2.9011579,43.533284,-135.93685)">
|
||||||
|
<path
|
||||||
|
fill="#ffa000"
|
||||||
|
d="M 23.8266,111.7182 39.9588,8.4901 c 0.1972,-1.266 1.1818,-2.264 2.445,-2.4786 1.2632,-0.2146 2.522,0.4028 3.126,1.5327 L 62.2133,38.6615 68.8633,26 c 0.515,-0.979 1.5303,-1.592 2.6366,-1.592 1.1063,0 2.1215,0.613 2.6366,1.592 l 45.0227,85.718 H 23.8266 Z"
|
||||||
|
id="path204" />
|
||||||
|
<path
|
||||||
|
fill="#f57c00"
|
||||||
|
d="M 79.566,71.5074 62.2124,38.6472 23.8334,111.7187 Z"
|
||||||
|
id="path206" />
|
||||||
|
<path
|
||||||
|
fill="#ffca28"
|
||||||
|
d="m 119.1666,111.7187 -12.356,-76.4603 c -0.1867,-1.098 -0.9703,-2 -2.0315,-2.34 -1.0612,-0.34 -2.2226,-0.057 -3.0107,0.7302 l -77.935,78.069 43.1234,24.1834 c 2.708,1.512 6.006,1.512 8.714,0 l 43.4958,-24.1834 z"
|
||||||
|
id="path208" />
|
||||||
|
<path
|
||||||
|
fill="#ffffff"
|
||||||
|
fill-opacity="0.2"
|
||||||
|
d="m 106.8105,35.2584 c -0.1867,-1.098 -0.9703,-2 -2.0315,-2.34 -1.0612,-0.34 -2.2226,-0.057 -3.0107,0.7302 L 86.3,49.1562 74.1365,26 c -0.515,-0.979 -1.5303,-1.592 -2.6366,-1.592 -1.1063,0 -2.1215,0.613 -2.6366,1.592 L 62.2133,38.6615 45.529,7.5447 C 44.924,6.4145 43.6637,5.7981 42.399,6.0143 41.1343,6.2305 40.153,7.231 39.958,8.498 L 23.8333,111.7187 h -0.052 l 0.052,0.0596 0.4245,0.2085 77.488,-77.5775 c 0.7877,-0.7915 1.952,-1.076 3.016,-0.737 1.064,0.339 1.849,1.2445 2.0338,2.3457 l 12.2518,75.775 0.1192,-0.0745 -12.356,-76.4603 z M 23.9748,111.5772 39.9655,9.228 c 0.1948,-1.267 1.1784,-2.2675 2.442,-2.4837 1.2636,-0.2162 2.524,0.4 3.13,1.5304 L 62.22,39.392 68.87,26.7305 c 0.515,-0.979 1.5303,-1.592 2.6366,-1.592 1.1063,0 2.1215,0.613 2.6366,1.592 l 11.9167,22.664 -62.0858,62.1827 z"
|
||||||
|
id="path210" />
|
||||||
|
<path
|
||||||
|
fill="#a52714"
|
||||||
|
opacity="0.2"
|
||||||
|
d="m 75.6708,135.1722 c -2.708,1.512 -6.006,1.512 -8.714,0 l -43.0192,-24.1162 -0.1043,0.663 43.1234,24.176 c 2.708,1.512 6.006,1.512 8.714,0 l 43.4958,-24.176 -0.1117,-0.6852 -43.384,24.1387 z"
|
||||||
|
id="path212" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.1 KiB |
|
@ -12,6 +12,7 @@ import Rest from "./Rest.svelte"
|
||||||
import Budibase from "./Budibase.svelte"
|
import Budibase from "./Budibase.svelte"
|
||||||
import Oracle from "./Oracle.svelte"
|
import Oracle from "./Oracle.svelte"
|
||||||
import GoogleSheets from "./GoogleSheets.svelte"
|
import GoogleSheets from "./GoogleSheets.svelte"
|
||||||
|
import Firebase from "./Firebase.svelte"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
BUDIBASE: Budibase,
|
BUDIBASE: Budibase,
|
||||||
|
@ -28,4 +29,5 @@ export default {
|
||||||
REST: Rest,
|
REST: Rest,
|
||||||
ORACLE: Oracle,
|
ORACLE: Oracle,
|
||||||
GOOGLE_SHEETS: GoogleSheets,
|
GOOGLE_SHEETS: GoogleSheets,
|
||||||
|
FIREBASE: Firebase,
|
||||||
}
|
}
|
||||||
|
|
|
@ -178,6 +178,7 @@ export const IntegrationTypes = {
|
||||||
ORACLE: "ORACLE",
|
ORACLE: "ORACLE",
|
||||||
INTERNAL: "INTERNAL",
|
INTERNAL: "INTERNAL",
|
||||||
GOOGLE_SHEETS: "GOOGLE_SHEETS",
|
GOOGLE_SHEETS: "GOOGLE_SHEETS",
|
||||||
|
FIREBASE: "FIREBASE",
|
||||||
}
|
}
|
||||||
|
|
||||||
export const IntegrationNames = {
|
export const IntegrationNames = {
|
||||||
|
@ -195,6 +196,7 @@ export const IntegrationNames = {
|
||||||
[IntegrationTypes.ORACLE]: "Oracle",
|
[IntegrationTypes.ORACLE]: "Oracle",
|
||||||
[IntegrationTypes.INTERNAL]: "Internal",
|
[IntegrationTypes.INTERNAL]: "Internal",
|
||||||
[IntegrationTypes.GOOGLE_SHEETS]: "Google Sheets",
|
[IntegrationTypes.GOOGLE_SHEETS]: "Google Sheets",
|
||||||
|
[IntegrationTypes.FIREBASE]: "Firebase",
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SchemaTypeOptions = [
|
export const SchemaTypeOptions = [
|
||||||
|
|
|
@ -77,6 +77,7 @@
|
||||||
"@bull-board/api": "^3.7.0",
|
"@bull-board/api": "^3.7.0",
|
||||||
"@bull-board/koa": "^3.7.0",
|
"@bull-board/koa": "^3.7.0",
|
||||||
"@elastic/elasticsearch": "7.10.0",
|
"@elastic/elasticsearch": "7.10.0",
|
||||||
|
"@google-cloud/firestore": "^5.0.2",
|
||||||
"@koa/router": "8.0.0",
|
"@koa/router": "8.0.0",
|
||||||
"@sendgrid/mail": "7.1.1",
|
"@sendgrid/mail": "7.1.1",
|
||||||
"@sentry/node": "^6.0.0",
|
"@sentry/node": "^6.0.0",
|
||||||
|
|
|
@ -48,6 +48,7 @@ export enum SourceNames {
|
||||||
REST = "REST",
|
REST = "REST",
|
||||||
ORACLE = "ORACLE",
|
ORACLE = "ORACLE",
|
||||||
GOOGLE_SHEETS = "GOOGLE_SHEETS",
|
GOOGLE_SHEETS = "GOOGLE_SHEETS",
|
||||||
|
FIREBASE = "FIREBASE",
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum IncludeRelationships {
|
export enum IncludeRelationships {
|
||||||
|
|
|
@ -0,0 +1,205 @@
|
||||||
|
import {
|
||||||
|
DatasourceFieldTypes,
|
||||||
|
Integration,
|
||||||
|
QueryTypes,
|
||||||
|
} from "../definitions/datasource"
|
||||||
|
import { IntegrationBase } from "./base/IntegrationBase"
|
||||||
|
import { Firestore, WhereFilterOp } from "@google-cloud/firestore"
|
||||||
|
|
||||||
|
module Firebase {
|
||||||
|
interface FirebaseConfig {
|
||||||
|
email: string
|
||||||
|
privateKey: string
|
||||||
|
projectId: string
|
||||||
|
serviceAccount?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const SCHEMA: Integration = {
|
||||||
|
docs: "https://firebase.google.com/docs/firestore/quickstart",
|
||||||
|
friendlyName: "Firestore",
|
||||||
|
description:
|
||||||
|
"Cloud Firestore is a flexible, scalable database for mobile, web, and server development from Firebase and Google Cloud.",
|
||||||
|
datasource: {
|
||||||
|
email: {
|
||||||
|
type: DatasourceFieldTypes.STRING,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
privateKey: {
|
||||||
|
type: DatasourceFieldTypes.STRING,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
projectId: {
|
||||||
|
type: DatasourceFieldTypes.STRING,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
serviceAccount: {
|
||||||
|
type: DatasourceFieldTypes.JSON,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
query: {
|
||||||
|
create: {
|
||||||
|
type: QueryTypes.JSON,
|
||||||
|
},
|
||||||
|
read: {
|
||||||
|
type: QueryTypes.JSON,
|
||||||
|
},
|
||||||
|
update: {
|
||||||
|
type: QueryTypes.JSON,
|
||||||
|
},
|
||||||
|
delete: {
|
||||||
|
type: QueryTypes.JSON,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
extra: {
|
||||||
|
collection: {
|
||||||
|
displayName: "Collection",
|
||||||
|
type: DatasourceFieldTypes.STRING,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
filterField: {
|
||||||
|
displayName: "Filter field",
|
||||||
|
type: DatasourceFieldTypes.STRING,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
filter: {
|
||||||
|
displayName: "Filter comparison",
|
||||||
|
type: DatasourceFieldTypes.LIST,
|
||||||
|
required: false,
|
||||||
|
data: {
|
||||||
|
read: [
|
||||||
|
"==",
|
||||||
|
"<",
|
||||||
|
"<=",
|
||||||
|
"==",
|
||||||
|
"!=",
|
||||||
|
">=",
|
||||||
|
">",
|
||||||
|
"array-contains",
|
||||||
|
"in",
|
||||||
|
"not-in",
|
||||||
|
"array-contains-any",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
filterValue: {
|
||||||
|
displayName: "Filter value",
|
||||||
|
type: DatasourceFieldTypes.STRING,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
class FirebaseIntegration implements IntegrationBase {
|
||||||
|
private config: FirebaseConfig
|
||||||
|
private db: Firestore
|
||||||
|
|
||||||
|
constructor(config: FirebaseConfig) {
|
||||||
|
this.config = config
|
||||||
|
if (config.serviceAccount) {
|
||||||
|
const serviceAccount = JSON.parse(config.serviceAccount)
|
||||||
|
this.db = new Firestore({
|
||||||
|
projectId: serviceAccount.project_id,
|
||||||
|
credentials: {
|
||||||
|
client_email: serviceAccount.client_email,
|
||||||
|
private_key: serviceAccount.private_key,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.db = new Firestore({
|
||||||
|
projectId: config.projectId,
|
||||||
|
credentials: {
|
||||||
|
client_email: config.email,
|
||||||
|
private_key: config.privateKey,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async create(query: { json: object; extra: { [key: string]: string } }) {
|
||||||
|
try {
|
||||||
|
const documentReference = this.db
|
||||||
|
.collection(query.extra.collection)
|
||||||
|
.doc()
|
||||||
|
await documentReference.set({ ...query.json, id: documentReference.id })
|
||||||
|
const snapshot = await documentReference.get()
|
||||||
|
return snapshot.data()
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Error writing to Firestore", err)
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async read(query: { json: object; extra: { [key: string]: string } }) {
|
||||||
|
try {
|
||||||
|
let snapshot
|
||||||
|
const collectionRef = this.db.collection(query.extra.collection)
|
||||||
|
if (
|
||||||
|
query.extra.filterField &&
|
||||||
|
query.extra.filter &&
|
||||||
|
query.extra.filterValue
|
||||||
|
) {
|
||||||
|
snapshot = await collectionRef
|
||||||
|
.where(
|
||||||
|
query.extra.filterField,
|
||||||
|
query.extra.filter as WhereFilterOp,
|
||||||
|
query.extra.filterValue
|
||||||
|
)
|
||||||
|
.get()
|
||||||
|
} else {
|
||||||
|
snapshot = await collectionRef.get()
|
||||||
|
}
|
||||||
|
const result: any[] = []
|
||||||
|
snapshot.forEach(doc => result.push(doc.data()))
|
||||||
|
|
||||||
|
return result
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Error querying Firestore", err)
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async update(query: {
|
||||||
|
json: Record<string, any>
|
||||||
|
extra: { [key: string]: string }
|
||||||
|
}) {
|
||||||
|
try {
|
||||||
|
await this.db
|
||||||
|
.collection(query.extra.collection)
|
||||||
|
.doc(query.json.id)
|
||||||
|
.update(query.json)
|
||||||
|
|
||||||
|
return (
|
||||||
|
await this.db
|
||||||
|
.collection(query.extra.collection)
|
||||||
|
.doc(query.json.id)
|
||||||
|
.get()
|
||||||
|
).data()
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Error writing to firebase", err)
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async delete(query: {
|
||||||
|
json: { id: string }
|
||||||
|
extra: { [key: string]: string }
|
||||||
|
}) {
|
||||||
|
try {
|
||||||
|
await this.db
|
||||||
|
.collection(query.extra.collection)
|
||||||
|
.doc(query.json.id)
|
||||||
|
.delete()
|
||||||
|
return true
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Error writing to mongodb", err)
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
schema: SCHEMA,
|
||||||
|
integration: FirebaseIntegration,
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,6 +10,7 @@ const mysql = require("./mysql")
|
||||||
const arangodb = require("./arangodb")
|
const arangodb = require("./arangodb")
|
||||||
const rest = require("./rest")
|
const rest = require("./rest")
|
||||||
const googlesheets = require("./googlesheets")
|
const googlesheets = require("./googlesheets")
|
||||||
|
const firebase = require("./firebase")
|
||||||
const { SourceNames } = require("../definitions/datasource")
|
const { SourceNames } = require("../definitions/datasource")
|
||||||
const environment = require("../environment")
|
const environment = require("../environment")
|
||||||
|
|
||||||
|
@ -25,6 +26,7 @@ const DEFINITIONS = {
|
||||||
[SourceNames.MYSQL]: mysql.schema,
|
[SourceNames.MYSQL]: mysql.schema,
|
||||||
[SourceNames.ARANGODB]: arangodb.schema,
|
[SourceNames.ARANGODB]: arangodb.schema,
|
||||||
[SourceNames.REST]: rest.schema,
|
[SourceNames.REST]: rest.schema,
|
||||||
|
[SourceNames.FIREBASE]: firebase.schema,
|
||||||
}
|
}
|
||||||
|
|
||||||
const INTEGRATIONS = {
|
const INTEGRATIONS = {
|
||||||
|
@ -39,6 +41,7 @@ const INTEGRATIONS = {
|
||||||
[SourceNames.MYSQL]: mysql.integration,
|
[SourceNames.MYSQL]: mysql.integration,
|
||||||
[SourceNames.ARANGODB]: arangodb.integration,
|
[SourceNames.ARANGODB]: arangodb.integration,
|
||||||
[SourceNames.REST]: rest.integration,
|
[SourceNames.REST]: rest.integration,
|
||||||
|
[SourceNames.FIREBASE]: firebase.integration,
|
||||||
}
|
}
|
||||||
|
|
||||||
// optionally add oracle integration if the oracle binary can be installed
|
// optionally add oracle integration if the oracle binary can be installed
|
||||||
|
|
Loading…
Reference in New Issue