Skip to content

Instantly share code, notes, and snippets.

@rorhug
Created February 17, 2021 13:55
Show Gist options
  • Save rorhug/ea7c3e0997d81c11f13d694960fa63ca to your computer and use it in GitHub Desktop.
Save rorhug/ea7c3e0997d81c11f13d694960fa63ca to your computer and use it in GitHub Desktop.
Hasura - Change casing of build in fields and columns to camel case
// Run this to set the graphql exposed name for columns and built-in hasura graphql action to
// Afterwards run metadata export as the metadata set into the server does not write back out through docker to local file system
// `npx hasura --project ../hasura metadata export`
import { getIntrospectionQuery } from 'graphql'
import http from 'http'
import url from 'url'
import fs from 'fs'
import dotenv from 'dotenv'
import fetch from 'node-fetch'
dotenv.config()
const toCamel = (s) => {
return s.replace(/([-_][a-z])/ig, ($1) => {
return $1.toUpperCase()
.replace('-', '')
.replace('_', '');
});
};
const hasuraQuery = async (q) => {
const response = await fetch(process.env['NEXT_PUBLIC_GRAPHQL_API_URL'].replace("/graphql", "/query"), {
method: 'post',
body: JSON.stringify(q),
headers: { 'X-Hasura-Admin-Secret': process.env['HASURA_GRAPHQL_ADMIN_SECRET'], 'Content-Type': 'application/json' }
})
return response.json()
}
// https://github.com/hasura/graphql-engine/issues/3207
const tablesQuery = {"type":"select","args":{
"table":{"name":"hdb_table","schema":"hdb_catalog"},
"columns":[
"table_schema",
"table_name",
// "is_enum",
"configuration",
// {"name":"primary_key","columns":["*"]},
{"name":"columns","columns":["*"]},
{"name":"relationships","columns":["*"]},
// {"name":"permissions","columns":["*"]},
// {"name":"unique_constraints","columns":["*"]},
{
"name":"check_constraints",
"columns":["*"],
"order_by":{
"column":"constraint_name",
"type":"asc"
}
},
// {
// "name":"computed_fields",
// "columns":["*"],
// "order_by":{ "column":"computed_field_name","type":"asc" }
// }
],
"order_by":[{"column":"table_name","type":"asc"}]},
"where":{"table_schema":"public"}
}
const tablesQueryResult = await hasuraQuery(tablesQuery)
const setTableNames = async (table, cols) => {
const camelName = toCamel(table)
const pascalName = camelName.charAt(0).toUpperCase() + camelName.slice(1)
const custom_column_names = cols.reduce((o, c) => ({ ...o, [c]: toCamel(c) }), {})
const body = {
"type": "set_table_custom_fields",
"version": 2,
"args": {
"table": table,
"custom_root_fields": {
"select": camelName,
"select_by_pk": `${camelName}ByPk`,
"select_aggregate": `${camelName}Aggregate`,
"insert": `insert${pascalName}`,
"insert_one":`insert${pascalName}One`,
"update": `update${pascalName}`,
"update_by_pk": `update${pascalName}ByPk`,
"delete": `delete${pascalName}`,
"delete_by_pk": `delete${pascalName}ByPk`
},
custom_column_names
}
}
console.log(body)
return hasuraQuery(body)
}
const setRelationshipNames = async (table, relationshipNames) => {
console.log(`Relationships for ${table}`)
for (const name of relationshipNames) {
const camel = toCamel(name)
if (camel === name) { console.log(` no change to ${name}`); continue; }
console.log(` changing ${name.name} to ${camel}`)
const result = await hasuraQuery({
"type": "rename_relationship",
"args": { table, name, "new_name": camel }
})
console.log(result)
}
}
const publicTables = tablesQueryResult.filter(t => t.table_schema === "public")
for (const table of publicTables) {
const { columns, configuration, relationships, table_name } = table
console.log(`\n\n\nDoing ${table_name}\n`)
const setTableNamesResult = await setTableNames(
table_name,
columns.map(c => c.column_name),
)
const setRelationshipNamesResult = await setRelationshipNames(
table_name,
relationships.map(r => r.rel_name)
)
}
// via the schema... not a good method
// const fieldTypes = {
// "An array relationship": "relationship",
// "An object relationship": "relationship",
// "A computed field, executes function": "computed",
// "Remote relationship field": "remote"
// }
// const fieldTypeKeys = Object.keys(fieldTypes)
// const response = await fetch(process.env['NEXT_PUBLIC_GRAPHQL_API_URL'], {
// method: 'post',
// body: JSON.stringify({ query: getIntrospectionQuery() }),
// headers: {
// 'X-Hasura-Admin-Secret': process.env['HASURA_GRAPHQL_ADMIN_SECRET'],
// 'Content-Type': 'application/json'
// }
// });
// const json = await response.json();
// console.log(json)
// const tables = json.data.__schema.types.filter(t => t.kind === "OBJECT" && t.description && t.description.includes("columns and relationships"))
// then per table
// const types = table.fields.reduce((types, f) => {
// if (f.name.endsWith("_aggregate")) { return types }
// const fieldType = fieldTypeKeys.find(k => f.description && f.description.includes(k))
// console.log(fieldType)
// types[fieldType ? fieldTypes[fieldType] : "column"].push(f)
// return types
// }, { column: [], relationship: [], computed: [], remote: [] })
// const custom_column_names = types.column.reduce((o, f) => ({ ...o, [f.name]: toCamel(f.name) }), {})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment