Skip to content

Commit

Permalink
Add options.schema, options.exclude (#2)
Browse files Browse the repository at this point in the history
  • Loading branch information
koistya committed Aug 17, 2021
1 parent 2d0a1ec commit 1dddd09
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 48 deletions.
24 changes: 13 additions & 11 deletions main.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,35 +10,37 @@ export declare type Options = {
* Name overrides for enums, classes, and fields.
*
* @example
* {
* overrides: { "identity_provider.linkedin": "LinkedIn" }
* overrides: {
* "identity_provider.linkedin": "LinkedIn"
* }
*/
overrides?: Record<string, string>;
prefix?: string;
/**
* Schemas that should be included/excluded when generating types.
*
* By default if this is null/not specified, 'public' will be the only schema added, but if this property
* By default if this is null/not specified, "public" will be the only schema added, but if this property
* is specified, public will be excluded by default and has to be included in the list to be added to the output.
* If a schema is added by its name, i.e. 'log' all tables from that schema will be added.
* If a schema name is added with an exclamation mark it will be ignored, i.e. '!log'.
* If a schema name is added with an exclamation mark it will be ignored, i.e. "!log".
*
* The table-type will be prefixed by its schema name, the table log.message will become LogMessage.
*
* @example
* ['public', 'log', '!secret']
*
* This will include public and log, but exclude the secret schema.
* // This will include "public" and "log", but exclude the "auth" schema.
* schema: ["public", "log", "!auth"]
* @default
* "public"
*/
schemas?: string[];
schema?: string[] | string;
/**
* Tables that should be skipped when generating types.
* A comma separated list or an array of tables that should be excluded when
* generating types.
*
* @example
* ['login']
* exclude: ["migration", "migration_lock"]
*/
skip?: string[];
exclude?: string[] | string;
};
/**
* Generates TypeScript definitions (types) from a PostgreSQL database schema.
Expand Down
14 changes: 5 additions & 9 deletions main.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,18 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
* Generates TypeScript definitions (types) from a PostgreSQL database schema.
*/
async function updateTypes(db, options) {
var _options$overrides, _options$skip;
var _options$overrides, _ref, _ref2;

const overrides = (_options$overrides = options.overrides) !== null && _options$overrides !== void 0 ? _options$overrides : {};
const output = typeof options.output === "string" ? _fs.default.createWriteStream(options.output, {
encoding: "utf-8"
}) : options.output;
["// The TypeScript definitions below are automatically generated.\n", "// Do not touch them, or risk, your modifications being lost.\n\n"].forEach(line => output.write(line));
const includeSchemas = ["public"];
const excludeSchemas = [];
const schema = (_ref = typeof options.schema === "string" ? options.schema.split(",").map(x => x.trim()) : options.schema) !== null && _ref !== void 0 ? _ref : ["public"]; // Schemas to include or exclude

if (options.schemas) {
includeSchemas.length = 0;
options.schemas.forEach(x => (x[0] === "!" ? excludeSchemas : includeSchemas).push(x));
}
const [includeSchemas, excludeSchemas] = schema.reduce((acc, s) => acc[+s.startsWith("!")].push(s) && acc, [[], []]); // Tables to exclude

const skip = (_options$skip = options.skip) !== null && _options$skip !== void 0 ? _options$skip : [];
const exclude = (_ref2 = typeof options.exclude === "string" ? options.exclude.split(",").map(x => x.trim()) : options.exclude) !== null && _ref2 !== void 0 ? _ref2 : [];

if (options.prefix) {
output.write(options.prefix);
Expand Down Expand Up @@ -73,7 +69,7 @@ async function updateTypes(db, options) {
return [x.key, (_overrides$x$key2 = overrides[x.key]) !== null && _overrides$x$key2 !== void 0 ? _overrides$x$key2 : (0, _upperFirst2.default)((0, _camelCase2.default)(x.key))];
})); // Fetch the list of tables/columns

const columns = await db.withSchema("information_schema").table("columns").whereIn("table_schema", includeSchemas).whereNotIn("table_schema", excludeSchemas).whereNotIn("table_name", skip).orderBy("table_schema").orderBy("table_name").orderBy("ordinal_position").select("table_schema as schema", "table_name as table", "column_name as column", db.raw("(is_nullable = 'YES') as nullable"), "column_default as default", "data_type as type", "udt_name as udt"); // The list of database tables as enum
const columns = await db.withSchema("information_schema").table("columns").whereIn("table_schema", includeSchemas).whereNotIn("table_schema", excludeSchemas).whereNotIn("table_name", exclude).orderBy("table_schema").orderBy("table_name").orderBy("ordinal_position").select("table_schema as schema", "table_name as table", "column_name as column", db.raw("(is_nullable = 'YES') as nullable"), "column_default as default", "data_type as type", "udt_name as udt"); // The list of database tables as enum

output.write("export enum Table {\n");
const tableSet = new Set(columns.map(x => {
Expand Down
9 changes: 3 additions & 6 deletions main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,12 @@ test("updateTypes", async function () {
"identity_provider.linkedin": "LinkedIn",
};

const prefix = 'import { PostgresInterval} from "postgres-interval";';
const includedSchemas = ["public", "log", "!secret"];
const skipTables = ["login"];
await updateTypes(db, {
output,
overrides,
prefix,
schemas: includedSchemas,
skip: skipTables,
prefix: 'import { PostgresInterval} from "postgres-interval";',
schema: ["public", "log", "!secret"],
exclude: ["login"],
});

expect(await toString(output)).toMatchInlineSnapshot(`
Expand Down
51 changes: 30 additions & 21 deletions main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ export type Options = {
* Name overrides for enums, classes, and fields.
*
* @example
* {
* overrides: { "identity_provider.linkedin": "LinkedIn" }
* overrides: {
* "identity_provider.linkedin": "LinkedIn"
* }
*/
overrides?: Record<string, string>;
Expand All @@ -27,27 +27,29 @@ export type Options = {
/**
* Schemas that should be included/excluded when generating types.
*
* By default if this is null/not specified, 'public' will be the only schema added, but if this property
* By default if this is null/not specified, "public" will be the only schema added, but if this property
* is specified, public will be excluded by default and has to be included in the list to be added to the output.
* If a schema is added by its name, i.e. 'log' all tables from that schema will be added.
* If a schema name is added with an exclamation mark it will be ignored, i.e. '!log'.
* If a schema name is added with an exclamation mark it will be ignored, i.e. "!log".
*
* The table-type will be prefixed by its schema name, the table log.message will become LogMessage.
*
* @example
* ['public', 'log', '!secret']
*
* This will include public and log, but exclude the secret schema.
* // This will include "public" and "log", but exclude the "auth" schema.
* schema: ["public", "log", "!auth"]
* @default
* "public"
*/
schemas?: string[];
schema?: string[] | string;

/**
* Tables that should be skipped when generating types.
* A comma separated list or an array of tables that should be excluded when
* generating types.
*
* @example
* ['login']
* exclude: ["migration", "migration_lock"]
*/
skip?: string[];
exclude?: string[] | string;
};

/**
Expand All @@ -65,15 +67,22 @@ export async function updateTypes(db: Knex, options: Options): Promise<void> {
"// Do not touch them, or risk, your modifications being lost.\n\n",
].forEach((line) => output.write(line));

const includeSchemas: string[] = ["public"];
const excludeSchemas: string[] = [];
if (options.schemas) {
includeSchemas.length = 0;
options.schemas.forEach((x) =>
(x[0] === "!" ? excludeSchemas : includeSchemas).push(x)
);
}
const skip: string[] = options.skip ?? [];
const schema = (typeof options.schema === "string"
? options.schema.split(",").map((x) => x.trim())
: options.schema) ?? ["public"];

// Schemas to include or exclude
const [includeSchemas, excludeSchemas] = schema.reduce(
(acc, s) =>
(acc[+s.startsWith("!")].push(s) && acc) as [string[], string[]],
[[] as string[], [] as string[]]
);

// Tables to exclude
const exclude =
(typeof options.exclude === "string"
? options.exclude.split(",").map((x) => x.trim())
: options.exclude) ?? [];

if (options.prefix) {
output.write(options.prefix);
Expand Down Expand Up @@ -122,7 +131,7 @@ export async function updateTypes(db: Knex, options: Options): Promise<void> {
.table("columns")
.whereIn("table_schema", includeSchemas)
.whereNotIn("table_schema", excludeSchemas)
.whereNotIn("table_name", skip)
.whereNotIn("table_name", exclude)
.orderBy("table_schema")
.orderBy("table_name")
.orderBy("ordinal_position")
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "knex-types",
"version": "0.2.0",
"version": "0.3.0",
"description": "Generates TypeScript definitions (types) from a (PostgreSQL) database schema.",
"keywords": [
"database",
Expand Down

0 comments on commit 1dddd09

Please sign in to comment.