Skip to content

Commit cfbecb1

Browse files
committed
more plugin tests
1 parent 757eb96 commit cfbecb1

File tree

4 files changed

+110
-19
lines changed

4 files changed

+110
-19
lines changed

packages/runtime/src/client/plugin.ts

+19-19
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import type { MaybePromise } from '../utils/type-utils';
1212
import type { QueryContext } from './query-executor';
1313

1414
/**
15-
* The result of the lifecycle interception filter.
15+
* The result of the hooks interception filter.
1616
*/
1717
export type MutationInterceptionFilterResult = {
1818
/**
@@ -36,7 +36,7 @@ export type MutationInterceptionFilterResult = {
3636
loadAfterMutationEntity?: boolean;
3737
};
3838

39-
type MutationLifecycleEventArgs<Schema extends SchemaDef> = {
39+
type MutationHooksArgs<Schema extends SchemaDef> = {
4040
/**
4141
* The model that is being mutated.
4242
*/
@@ -71,12 +71,12 @@ export type PluginTransformKyselyResultArgs<Schema extends SchemaDef> = {
7171
};
7272

7373
export type PluginBeforeEntityMutationArgs<Schema extends SchemaDef> =
74-
MutationLifecycleEventArgs<Schema> & {
74+
MutationHooksArgs<Schema> & {
7575
entities?: Record<string, unknown>[];
7676
};
7777

7878
export type PluginAfterEntityMutationArgs<Schema extends SchemaDef> =
79-
MutationLifecycleEventArgs<Schema> & {
79+
MutationHooksArgs<Schema> & {
8080
beforeMutationEntities?: Record<string, unknown>[];
8181
afterMutationEntities?: Record<string, unknown>[];
8282
};
@@ -100,20 +100,6 @@ export interface RuntimePlugin<Schema extends SchemaDef = SchemaDef> {
100100
*/
101101
description?: string;
102102

103-
/**
104-
* Kysely query transformation. See {@link KyselyPlugin.transformQuery}.
105-
*/
106-
transformKyselyQuery?: (
107-
args: PluginTransformKyselyQueryArgs<Schema>
108-
) => RootOperationNode;
109-
110-
/**
111-
* Kysely query result transformation. See {@link KyselyPlugin.transformResult}.
112-
*/
113-
transformKyselyResult?: (
114-
args: PluginTransformKyselyResultArgs<Schema>
115-
) => Promise<QueryResult<UnknownRow>>;
116-
117103
/**
118104
* Called before an ORM query is executed.
119105
*/
@@ -129,12 +115,26 @@ export interface RuntimePlugin<Schema extends SchemaDef = SchemaDef> {
129115
} & PluginContext<Schema>
130116
) => MaybePromise<void>;
131117

118+
/**
119+
* Kysely query transformation. See {@link KyselyPlugin.transformQuery}.
120+
*/
121+
transformKyselyQuery?: (
122+
args: PluginTransformKyselyQueryArgs<Schema>
123+
) => RootOperationNode;
124+
125+
/**
126+
* Kysely query result transformation. See {@link KyselyPlugin.transformResult}.
127+
*/
128+
transformKyselyResult?: (
129+
args: PluginTransformKyselyResultArgs<Schema>
130+
) => Promise<QueryResult<UnknownRow>>;
131+
132132
/**
133133
* This callback determines whether a mutation should be intercepted, and if so,
134134
* what data should be loaded before and after the mutation.
135135
*/
136136
mutationInterceptionFilter?: (
137-
args: MutationLifecycleEventArgs<Schema>
137+
args: MutationHooksArgs<Schema>
138138
) => MaybePromise<MutationInterceptionFilterResult>;
139139

140140
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import {
2+
AndNode,
3+
BinaryOperationNode,
4+
ColumnNode,
5+
OperatorNode,
6+
ReferenceNode,
7+
SelectQueryNode,
8+
TableNode,
9+
ValueNode,
10+
WhereNode,
11+
} from 'kysely';
12+
import { beforeEach, describe, expect, it } from 'vitest';
13+
import { ZenStackClient, type ClientContract } from '../../src';
14+
import { schema } from '../test-schema';
15+
16+
describe('Entity lifecycle tests', () => {
17+
let _client: ClientContract<typeof schema>;
18+
19+
beforeEach(async () => {
20+
_client = await new ZenStackClient(schema);
21+
await _client.$pushSchema();
22+
});
23+
24+
it('supports transforming kysely queries', async () => {
25+
const client = _client.$use({
26+
id: 'test-plugin',
27+
transformKyselyQuery(args) {
28+
if (SelectQueryNode.is(args.node)) {
29+
// inject filter: email = '[email protected]'
30+
const additionalFilter = BinaryOperationNode.create(
31+
ReferenceNode.create(
32+
ColumnNode.create('email'),
33+
TableNode.create('User')
34+
),
35+
OperatorNode.create('='),
36+
ValueNode.create('[email protected]')
37+
);
38+
args.node = {
39+
...args.node,
40+
where: WhereNode.create(
41+
args.node.where
42+
? AndNode.create(
43+
args.node.where.where,
44+
additionalFilter
45+
)
46+
: additionalFilter
47+
),
48+
};
49+
}
50+
return args.node;
51+
},
52+
});
53+
54+
const user = await client.user.create({
55+
data: { email: '[email protected]' },
56+
});
57+
58+
await expect(
59+
client.user.findFirst({
60+
where: { id: user.id },
61+
})
62+
).toResolveNull();
63+
64+
await client.user.update({
65+
where: { id: user.id },
66+
data: { email: '[email protected]' },
67+
});
68+
await expect(
69+
client.user.findFirst({
70+
where: { id: user.id },
71+
})
72+
).resolves.toMatchObject({ id: user.id });
73+
});
74+
75+
it('supports transforming kysely results', async () => {
76+
const client = _client.$use({
77+
id: 'test-plugin',
78+
async transformKyselyResult(args) {
79+
args.result.rows.forEach((row) => {
80+
(row as any).happy = true;
81+
});
82+
return args.result;
83+
},
84+
});
85+
await expect(
86+
client.user.create({
87+
data: { email: '[email protected]' },
88+
})
89+
).resolves.toMatchObject({ email: '[email protected]', happy: true });
90+
});
91+
});

0 commit comments

Comments
 (0)