Skip to content

Instantly share code, notes, and snippets.

@wpcarro
Last active July 8, 2024 17:20
Show Gist options
  • Save wpcarro/ffa8bdce39572aedd37471739cd6072b to your computer and use it in GitHub Desktop.
Save wpcarro/ffa8bdce39572aedd37471739cd6072b to your computer and use it in GitHub Desktop.
Proof of concept for type-generation from jsonnet.
////////////////////////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////////////////////////
local string = {
typescript: 'string',
python: 'str',
psql: 'VARCHAR',
};
local integer = {
typescript: 'number',
python: 'int',
psql: 'INT',
};
local struct(name, fields) = { name: name, fields: fields };
local table(name, pk, fields) = { name: name, pk: pk, fields: fields };
local typescript(structs) = std.join(
'\n',
std.map(function(x) 'export type %s = {%s};' % [
x.name,
std.join('; ', std.map(function(k) '%s: %s' % [k, x.fields[k].typescript], std.objectFields(x.fields))),
], structs)
);
local python(structs) = std.join(
'\n\n',
std.map(function(x) 'class %s(pydantic.BaseModel):\n%s' % [
x.name,
std.join('\n', std.map(function(k) ' %s: %s' % [k, x.fields[k].python], std.objectFields(x.fields))),
], structs)
);
// TODO: Support PKs, FKs ad hoc.
local postgres(tables) = std.join(
'\n\n',
std.map(function(x) 'CREATE TABLE %s(\n%s\n)' % [
x.name,
std.join(',\n', std.map(function(k) if k == x.pk then ' %s %s PRIMARY KEY' % [k, x.fields[k].psql] else ' %s %s NOT NULL' % [k, x.fields[k].psql], std.objectFields(x.fields))),
], tables)
);
////////////////////////////////////////////////////////////////////////////////
// Types
////////////////////////////////////////////////////////////////////////////////
local person = struct(name='Person', fields={
first: string,
last: string,
age: integer,
});
local place = struct(name='Place', fields={
city: string,
state: string,
zip: string,
});
local person_table = table(name='Person', pk='first', fields=person.fields);
local place_table = table(name='Place', pk='city', fields=place.fields);
////////////////////////////////////////////////////////////////////////////////
// Main
////////////////////////////////////////////////////////////////////////////////
{
client: typescript(structs=[person, place]),
server: python(structs=[person, place]),
database: postgres(tables=[person_table, place_table]),
}
@wpcarro
Copy link
Author

wpcarro commented Jul 8, 2024

Can generate source code for client, server, database with:

set -euo pipefail

jsonnet generated.jsonnet | jq -r .client > path/to/client/types.ts
jsonnet generated.jsonnet | jq -r .server > path/to/server/types.py
jsonnet generated.jsonnet | jq -r .database > path/to/server/tables.sql

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment