Skip to content

Instantly share code, notes, and snippets.

@virtuallyunknown
Created June 3, 2024 16:20

Revisions

  1. virtuallyunknown created this gist Jun 3, 2024.
    62 changes: 62 additions & 0 deletions jsonb-plugin.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,62 @@
    import type { KyselyPlugin, PluginTransformQueryArgs, PluginTransformResultArgs, QueryResult, RootOperationNode, UnknownRow } from 'kysely';

    function toJsonb(func: unknown) {
    if (typeof func !== 'string') {
    throw new Error('Invalid function');
    }

    switch (func) {
    case 'json_agg': return 'jsonb_agg';
    case 'to_json': return 'to_jsonb';
    default: return func;
    }
    }

    function transformFuncKey(obj: unknown): unknown {
    if (typeof obj !== 'object' || obj === null) {
    return obj;
    }

    if (Array.isArray(obj)) {
    return obj.map(transformFuncKey);
    }

    return Object.fromEntries(
    Object.entries(obj as Record<string, unknown>).map(([key, value]) => {
    if (key === 'func' && typeof value === 'string') {
    // eslint-disable-next-line no-param-reassign
    value = toJsonb(value);
    }
    else {
    // eslint-disable-next-line no-param-reassign
    value = transformFuncKey(value);
    }
    return [key, value];
    })
    );
    }

    export class JSONBPlugin implements KyselyPlugin {
    public transformQuery(args: PluginTransformQueryArgs): RootOperationNode {
    if (args.node.kind !== 'SelectQueryNode') {
    return args.node;
    }

    const res = transformFuncKey(args.node) as RootOperationNode;
    console.log(JSON.stringify(res, null, 4));
    return transformFuncKey(args.node) as RootOperationNode;
    }

    // eslint-disable-next-line @typescript-eslint/require-await
    public async transformResult(args: PluginTransformResultArgs): Promise<QueryResult<UnknownRow>> {
    // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
    if (args.result.rows && Array.isArray(args.result.rows)) {
    return {
    ...args.result,
    rows: args.result.rows,
    };
    }

    return args.result;
    }
    }