Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: function configuration for auto transactions #1615

Merged
merged 2 commits into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 3 additions & 22 deletions integration/testdata/audit_logs/tests.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -558,7 +558,7 @@ test("job function with identity - audit table populated", async () => {
expect(weddingUpdateAudit.data.headcount).toEqual(1);
});

test("job function with error and no rollback - audit table is not rolled back", async () => {
test("job function with error and default rollback - audit table is also rolled back", async () => {
const identity = await models.identity.create({
email: "keelson@keel.xyz",
issuer: "https://keel.so",
Expand Down Expand Up @@ -594,7 +594,7 @@ test("job function with error and no rollback - audit table is not rolled back",
>`SELECT * FROM keel_audit where table_name = 'wedding_invitee'`.execute(
useDatabase()
);
expect(inviteesAudits.rows.length).toEqual(4);
expect(inviteesAudits.rows.length).toEqual(3);

const keelsonAudit = inviteesAudits.rows.at(0)!;
expect(keelsonAudit.id).toHaveLength(27);
Expand All @@ -617,22 +617,12 @@ test("job function with error and no rollback - audit table is not rolled back",
expect(weavetonAudit.identityId).toBeNull();
expect(weavetonAudit.data.id).toEqual(prisma.id);

const keelerDeleteAudit = inviteesAudits.rows.at(3)!;
expect(keelerDeleteAudit.id).toHaveLength(27);
expect(keelerDeleteAudit.tableName).toEqual("wedding_invitee");
expect(keelerDeleteAudit.op).toEqual("delete");
expect(keelerDeleteAudit.identityId).toEqual(identity.id);
expect(keelerDeleteAudit.data.id).toEqual(keeler.id);
expect(keelerDeleteAudit.data.firstName).toEqual(keeler.firstName);
expect(keelerDeleteAudit.data.status).toEqual(keeler.status);
expect(keelerDeleteAudit.data.isFamily).toEqual(keeler.isFamily);

const weddingAudits = await sql<
Audit<Wedding>
>`SELECT * FROM keel_audit where table_name = 'wedding'`.execute(
useDatabase()
);
expect(weddingAudits.rows.length).toEqual(2);
expect(weddingAudits.rows.length).toEqual(1);

const weddingAudit = weddingAudits.rows.at(0)!;
expect(weddingAudit.id).toHaveLength(27);
Expand All @@ -642,15 +632,6 @@ test("job function with error and no rollback - audit table is not rolled back",
expect(weddingAudit.data.id).toEqual(wedding.id);
expect(weddingAudit.data.name).toEqual(wedding.name);
expect(weddingAudit.data.headcount).toEqual(0);

const weddingUpdateAudit = weddingAudits.rows.at(1)!;
expect(weddingUpdateAudit.id).toHaveLength(27);
expect(weddingUpdateAudit.tableName).toEqual("wedding");
expect(weddingUpdateAudit.op).toEqual("update");
expect(weddingUpdateAudit.identityId).toEqual(identity.id);
expect(weddingUpdateAudit.data.id).toEqual(wedding.id);
expect(weddingUpdateAudit.data.name).toEqual(wedding.name);
expect(weddingUpdateAudit.data.headcount).toEqual(1);
});

test("job function using kysely with identity - audit table populated", async () => {
Expand Down
7 changes: 2 additions & 5 deletions integration/testdata/events_basic/tests.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,8 @@ test("events from failed job", async () => {

const persons = await models.person.findMany();

expect(persons).toHaveLength(2);
expect(persons[0].verifiedEmail).toBeTruthy();
expect(persons[1].verifiedEmail).toBeTruthy();
expect(persons[0].verifiedUpdate).toBeTruthy();
expect(persons[1].verifiedUpdate).toBeTruthy();
// Due to default rollback
expect(persons).toHaveLength(0);
});

test("events from failed custom function with rollback", async () => {
Expand Down
12 changes: 6 additions & 6 deletions integration/testdata/jobs_permissions/tests.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ test("job - allowed in job code - permitted", async () => {
expect(await jobRan(id)).toBeTruthy();
});

test("job - denied in job code - not permitted without rollback transaction", async () => {
test("job - denied in job code - not permitted with default rollback transaction", async () => {
const { id } = await models.trackJob.create({ didJobRun: false });
const identity = await models.identity.create({
email: "keel@keel.so",
Expand All @@ -222,11 +222,11 @@ test("job - denied in job code - not permitted without rollback transaction", as
jobs.withIdentity(identity).manualJobDeniedInCode({ id, denyIt: true })
).toHaveAuthorizationError();

// This would be false if a transaction rolled back.
expect(await jobRan(id)).toBeTruthy();
// This would be true if the transaction didn't roll back.
expect(await jobRan(id)).toBeFalsy();
});

test("job - exception - internal error without rollback transaction", async () => {
test("job - exception - internal error with default rollback transaction", async () => {
const { id } = await models.trackJob.create({ didJobRun: false });
const identity = await models.identity.create({
email: "keel@keel.so",
Expand All @@ -240,8 +240,8 @@ test("job - exception - internal error without rollback transaction", async () =
message: "something bad has happened!",
});

// This would be false if a transaction rolled back.
expect(await jobRan(id)).toBeTruthy();
// This would be true if the transaction didn't roll back.
expect(await jobRan(id)).toBeFalsy();
});

test("scheduled job - without identity - permitted", async () => {
Expand Down
6 changes: 3 additions & 3 deletions integration/testdata/subscribers_basic/tests.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ test("subscriber - mutating field", async () => {
expect(updatedMary?.verified).toBeTruthy();
});

test("subscriber - exception - internal error without rollback transaction", async () => {
test("subscriber - exception - internal error with default rollback transaction", async () => {
await models.trackSubscriber.create({ didSubscriberRun: false });

const mary = await models.member.create({
Expand All @@ -56,8 +56,8 @@ test("subscriber - exception - internal error without rollback transaction", asy
message: "something bad has happened!",
});

// This would be false if a transaction rolled back.
expect(await subscriberRan()).toBeTruthy();
// This would be true if the transaction didn't roll back.
expect(await subscriberRan()).toBeFalsy();
});

test("subscriber - with env vars - successful", async () => {
Expand Down
14 changes: 7 additions & 7 deletions node/codegen.go
Original file line number Diff line number Diff line change
Expand Up @@ -1185,7 +1185,7 @@ func writeFunctionWrapperType(w *codegen.Writer, schema *proto.Schema, model *pr
// we use the 'declare' keyword to indicate to the typescript compiler that the function
// has already been declared in the underlying vanilla javascript and therefore we are just
// decorating existing js code with types.
w.Writef("export declare function %s", casing.ToCamel(action.Name))
w.Writef("export declare const %s: runtime.FuncWithConfig<{", casing.ToCamel(action.Name))

if action.IsArbitraryFunction() {
inputType := action.InputMessageName
Expand All @@ -1197,14 +1197,14 @@ func writeFunctionWrapperType(w *codegen.Writer, schema *proto.Schema, model *pr
w.Write(toCustomFunctionReturnType(model, action, false))
w.Write("): ")
w.Write(toCustomFunctionReturnType(model, action, false))
w.Writeln(";")
w.Writeln("}>;")
return
}

hooksType := fmt.Sprintf("%sHooks", casing.ToCamel(action.Name))

// TODO: void return type here is wrong. It should be the type of the function e.g. (ctx, inputs) => ReturnType
w.Writef("(hooks?: %s): void\n", hooksType)
w.Writef("(hooks?: %s): void}>\n", hooksType)

w.Writef("export type %s = ", hooksType)

Expand Down Expand Up @@ -1279,7 +1279,7 @@ func toCustomFunctionReturnType(model *proto.Model, op *proto.Action, isTestingP
}

func writeJobFunctionWrapperType(w *codegen.Writer, job *proto.Job) {
w.Writef("export declare function %s", casing.ToCamel(job.Name))
w.Writef("export declare const %s: runtime.FuncWithConfig<{", casing.ToCamel(job.Name))

inputType := job.InputMessageName

Expand All @@ -1289,13 +1289,13 @@ func writeJobFunctionWrapperType(w *codegen.Writer, job *proto.Job) {
w.Writef("(fn: (ctx: JobContextAPI, inputs: %s) => Promise<void>): Promise<void>", inputType)
}

w.Writeln(";")
w.Writeln("}>;")
}

func writeSubscriberFunctionWrapperType(w *codegen.Writer, subscriber *proto.Subscriber) {
w.Writef("export declare function %s", casing.ToCamel(subscriber.Name))
w.Writef("export declare const %s: runtime.FuncWithConfig<{", casing.ToCamel(subscriber.Name))
w.Writef("(fn: (ctx: SubscriberContextAPI, event: %s) => Promise<void>): Promise<void>", subscriber.InputMessageName)
w.Writeln(";")
w.Writeln("}>;")
}

func toActionReturnType(model *proto.Model, op *proto.Action) string {
Expand Down
14 changes: 7 additions & 7 deletions node/codegen_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1789,8 +1789,8 @@ model Member {
}`

expected := `
export declare function VerifyEmail(fn: (ctx: SubscriberContextAPI, event: VerifyEmailEvent) => Promise<void>): Promise<void>;
export declare function SendWelcomeEmail(fn: (ctx: SubscriberContextAPI, event: SendWelcomeEmailEvent) => Promise<void>): Promise<void>;`
export declare const VerifyEmail: runtime.FuncWithConfig<{(fn: (ctx: SubscriberContextAPI, event: VerifyEmailEvent) => Promise<void>): Promise<void>}>;
export declare const SendWelcomeEmail: runtime.FuncWithConfig<{(fn: (ctx: SubscriberContextAPI, event: SendWelcomeEmailEvent) => Promise<void>): Promise<void>}>;`

runWriterTest(t, schema, expected, func(s *proto.Schema, w *codegen.Writer) {
for _, s := range s.Subscribers {
Expand All @@ -1815,12 +1815,12 @@ job AdHocJobWithInputs {
job AdHocJobWithoutInputs {
@permission(roles: [Admin])
}
role Admin {}
`
role Admin {}`

expected := `
export declare function JobWithoutInputs(fn: (ctx: JobContextAPI) => Promise<void>): Promise<void>;
export declare function AdHocJobWithInputs(fn: (ctx: JobContextAPI, inputs: AdHocJobWithInputsMessage) => Promise<void>): Promise<void>;
export declare function AdHocJobWithoutInputs(fn: (ctx: JobContextAPI) => Promise<void>): Promise<void>;`
export declare const JobWithoutInputs: runtime.FuncWithConfig<{(fn: (ctx: JobContextAPI) => Promise<void>): Promise<void>}>;
export declare const AdHocJobWithInputs: runtime.FuncWithConfig<{(fn: (ctx: JobContextAPI, inputs: AdHocJobWithInputsMessage) => Promise<void>): Promise<void>}>;
export declare const AdHocJobWithoutInputs: runtime.FuncWithConfig<{(fn: (ctx: JobContextAPI) => Promise<void>): Promise<void>}>;`

runWriterTest(t, schema, expected, func(s *proto.Schema, w *codegen.Writer) {
for _, j := range s.Jobs {
Expand Down
Loading
Loading