Skip to content

Commit

Permalink
fix: extend camelcasePlugin to ignore rich types
Browse files Browse the repository at this point in the history
  • Loading branch information
RutZap committed Jan 20, 2025
1 parent 4dbef57 commit 96a5bf5
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 17 deletions.
17 changes: 10 additions & 7 deletions integration/testdata/duration/functions/createDurationInHook.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { CreateDurationInHook, CreateDurationInHookHooks, Duration } from '@teamkeel/sdk';
import {
CreateDurationInHook,
CreateDurationInHookHooks,
Duration,
} from "@teamkeel/sdk";

// To learn more about what you can do with hooks, visit https://docs.keel.so/functions
const hooks: CreateDurationInHookHooks = {
beforeWrite: async (ctx, inputs) => {
return {
dur: Duration.fromISOString("PT1H")
}
},
beforeWrite: async (ctx, inputs) => {
return {
dur: Duration.fromISOString("PT1H"),
};
},
};

export default CreateDurationInHook(hooks);

10 changes: 5 additions & 5 deletions integration/testdata/duration/functions/writeCustomFunction.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { WriteCustomFunction, models } from '@teamkeel/sdk';
import { WriteCustomFunction, models } from "@teamkeel/sdk";

// To learn more about what you can do with custom functions, visit https://docs.keel.so/functions
export default WriteCustomFunction(async (ctx, inputs) => {
const mod = await models.myDuration.create({ dur: inputs.dur })
return {
model: mod
}
const mod = await models.myDuration.create({ dur: inputs.dur });
return {
model: mod,
};
});
2 changes: 1 addition & 1 deletion integration/testdata/duration/tests.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ test("duration - write custom function", async () => {

expect(result.model.dur).toEqual("PT1H2M3S");

const mydurs = await useDatabase()
const mydurs = await useDatabase()
.selectFrom("my_duration")
.selectAll()
.execute();
Expand Down
45 changes: 45 additions & 0 deletions packages/functions-runtime/src/camelCasePlugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
const { CamelCasePlugin } = require("kysely");
const { isPlainObject, isRichType } = require("./parsing");
// KeelCamelCasePlugin is a wrapper around kysely's camel case plugin.
class KeelCamelCasePlugin {
constructor(opt) {
this.opt = opt;
this.CamelCasePlugin = new CamelCasePlugin(opt);
}

transformQuery(args) {
return this.CamelCasePlugin.transformQuery(args);
}

async transformResult(args) {
if (args.result.rows && Array.isArray(args.result.rows)) {
return {
...args.result,
rows: args.result.rows.map((row) => this.mapRow(row)),
};
}
return args.result;
}
mapRow(row) {
return Object.keys(row).reduce((obj, key) => {
let value = row[key];
if (Array.isArray(value)) {
value = value.map((it) =>
canMap(it, this.opt) ? this.mapRow(it) : it
);
} else if (canMap(value, this.opt)) {
value = this.mapRow(value);
}
obj[this.CamelCasePlugin.camelCase(key)] = value;
return obj;
}, {});
}
}

function canMap(obj, opt) {
return (
isPlainObject(obj) && !opt?.maintainNestedObjectKeys && !isRichType(obj)
);
}

module.exports.KeelCamelCasePlugin = KeelCamelCasePlugin;
7 changes: 3 additions & 4 deletions packages/functions-runtime/src/database.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
const { Kysely, PostgresDialect, CamelCasePlugin } = require("kysely");
const { Kysely, PostgresDialect } = require("kysely");
const neonserverless = require("@neondatabase/serverless");
const { AsyncLocalStorage } = require("async_hooks");
const { AuditContextPlugin } = require("./auditing");
const { KeelCamelCasePlugin } = require("./camelCasePlugin");
const pg = require("pg");
const { withSpan } = require("./tracing");
const ws = require("ws");
Expand Down Expand Up @@ -78,9 +79,7 @@ function createDatabaseClient({ connString } = {}) {
// https://kysely-org.github.io/kysely/classes/CamelCasePlugin.html
// If they don't, then we can create a custom implementation of the plugin where we control
// the casing behaviour (see url above for example)
new CamelCasePlugin({
maintainNestedObjectKeys: true,
}),
new KeelCamelCasePlugin(),
],
log(event) {
if ("DEBUG" in process.env) {
Expand Down
9 changes: 9 additions & 0 deletions packages/functions-runtime/src/parsing.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,14 @@ function isPlainObject(obj) {
return Object.prototype.toString.call(obj) === "[object Object]";
}

function isRichType(obj) {
if (!isPlainObject(obj)) {
return false;
}

return obj instanceof Duration;
}

function isReferencingExistingRecord(value) {
return Object.keys(value).length === 1 && value.id;
}
Expand All @@ -94,5 +102,6 @@ module.exports = {
parseOutputs,
transformRichDataTypes,
isPlainObject,
isRichType,
isReferencingExistingRecord,
};

0 comments on commit 96a5bf5

Please sign in to comment.