Created
November 5, 2020 08:06
-
-
Save K3TH3R/f10f37a38b7f13c7412fb3a21ad089d6 to your computer and use it in GitHub Desktop.
Loads/updates the schema in a Fauna database.
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
// Required packages: faunadb, dotenv. | |
// FAUNA_SECRET: should be the secret of an admin key in the target DB. | |
const fs = require("fs"); | |
const https = require("https"); | |
const path = require("path"); | |
const { Client, query: q } = require("faunadb"); | |
require('dotenv').config({ path: path.join(__dirname, '.env') }); | |
const { FAUNA_SECRET, UPD_FUN, UPD_GQL, UPD_KEY, UPD_ROLE } = process.env; | |
function schemaGql() { | |
return new Promise((resolve, reject) => { | |
const data = fs.readFileSync(path.join(__dirname, "schema.gql")); | |
const req = https.request({ | |
hostname: "graphql.fauna.com", | |
port: 443, | |
path: "/import", | |
method: "POST", | |
headers: { | |
Authorization: `Bearer ${FAUNA_SECRET}` | |
} | |
}, res => { | |
console.debug(`GQL imported, status: ${res.statusCode}`); | |
res.on("data", b => console.log(b.toString())); | |
res.on("end", resolve); | |
}); | |
req.on("error", reject); | |
req.end(data); | |
}); | |
} | |
function unlessExists(label, upd, ref, then, otherwise) { | |
return { | |
label, | |
query: q.If( | |
// false disables check and assumes it exists: | |
ref ? q.Exists(ref) : true, | |
(upd && otherwise) || "exists", | |
then | |
), | |
} | |
} | |
function index(def) { | |
return unlessExists( | |
`INDEX ${def.name}`, | |
false, // Cannot change terms or values so there's no in updating indexes. | |
q.Index(def.name), | |
q.CreateIndex(def), | |
); | |
} | |
function uniqueIndex(name, collection, ...fields) { | |
return index({ | |
name, | |
unique: true, | |
source: { collection: q.Collection(collection) }, | |
terms: fields.map(name => ({ field: ["data", name] })), | |
}); | |
} | |
function searchIndex(name, collection, terms, ...values) { | |
return index({ | |
name, | |
unique: false, | |
source: { collection: q.Collection(collection) }, | |
terms: terms && terms.length > 0 | |
? terms.map(name => ({ field: ["data", name] })) | |
: undefined, | |
values: values.length > 0 | |
? [ | |
...values.map(name => ({ field: ["data", name] })), | |
{ field: ["ref"] } | |
] | |
: undefined | |
}) | |
} | |
function fun(name, def) { | |
const f = q.Function(name) | |
return unlessExists( | |
`FUNCTION ${name}`, | |
UPD_FUN, | |
f, | |
q.CreateFunction({ name, ...def }), | |
q.Update(f, def) | |
); | |
} | |
function role(name, def) { | |
const r = q.Role(name); | |
return unlessExists( | |
`ROLE ${name}`, | |
UPD_ROLE, | |
r, | |
q.CreateRole({ name, ...def }), | |
q.Update(r, def) | |
); | |
} | |
function key(name, role) { | |
return unlessExists( | |
`KEY ${name}`, | |
UPD_KEY, | |
false, | |
q.Abort("Unexpected"), | |
q.CreateKey({ name, role }) | |
) | |
} | |
async function schemaFql(skip, cli, ...defs) { | |
const ok = []; | |
const failed = []; | |
for (const def of defs) { | |
if (skip && skip(def.label)) { | |
console.log(def.label, "SKIP"); | |
continue; | |
} | |
try { | |
const res = await cli.query(def.query); | |
console.log(def.label, "OK", res); | |
ok.push('\n ' + def.label); | |
} catch (e) { | |
console.error(def.label, "FAILED", e); | |
failed.push('\n ' + def.label); | |
} | |
} | |
ok.length > 0 && console.log("OK", ...ok); | |
failed.length > 0 && console.error("FAILED", ...failed); | |
} | |
async function schema() { | |
UPD_GQL && await schemaGql(); | |
await schemaFql( | |
false, | |
new Client({ secret: FAUNA_SECRET }), | |
// uniqueIndex("name", "collection", "field1", "field2"), | |
// index({ ... }), | |
// fun("Name", { body: q.Query(q.Lambda(["arg"], ... )) }), | |
// role("name", { ... }), | |
// key("name", q.Role("name")), | |
); | |
} | |
schema(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment