Created
February 17, 2021 13:55
-
-
Save rorhug/ea7c3e0997d81c11f13d694960fa63ca to your computer and use it in GitHub Desktop.
Hasura - Change casing of build in fields and columns to camel case
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
// 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