Skip to content
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
13 changes: 4 additions & 9 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,7 @@
"request": "launch",
"skipFiles": ["<node_internals>/**"],
"type": "node",
"args": [
"generate",
"--schema",
"${workspaceFolder}/samples/blog/zenstack/schema.zmodel"
]
"args": ["generate", "--schema", "${workspaceFolder}/samples/blog/zenstack/schema.zmodel"]
},
{
"name": "Debug with TSX",
Expand Down Expand Up @@ -44,15 +40,14 @@

// Ignore all dependencies (optional)
"${workspaceFolder}/node_modules/**"
]
],
"cwd": "${fileDirname}"
},
{
"name": "Run Extension",
"type": "extensionHost",
"request": "launch",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}/packages/ide/vscode"
],
"args": ["--extensionDevelopmentPath=${workspaceFolder}/packages/ide/vscode"],
"sourceMaps": true,
"outFiles": ["${workspaceFolder}/packages/ide/vscode/dist/**/*.js"]
},
Expand Down
59 changes: 31 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -289,15 +289,11 @@ ORM query interception allows you to intercept the high-level ORM API calls. The
```ts
db.$use({
id: 'cost-logger',
onQuery: {
$allModels: {
$allOperations: async ({ model, operation, args, query }) => {
const start = Date.now();
const result = await query(args);
console.log(`[cost] ${model} ${operation} took ${Date.now() - start}ms`);
return result;
},
},
onQuery: async ({ model, operation, args, query }) => {
const start = Date.now();
const result = await query(args);
console.log(`[cost] ${model} ${operation} took ${Date.now() - start}ms`);
return result;
},
});
```
Expand Down Expand Up @@ -333,11 +329,14 @@ Another popular interception use case is, instead of intercepting calls, "listen
```ts
db.$use({
id: 'mutation-hook-plugin',
beforeEntityMutation({ model, action }) {
console.log(`Before ${model} ${action}`);
},
afterEntityMutation({ model, action }) {
console.log(`After ${model} ${action}`);
onEntityMutation: {
beforeEntityMutation({ model, action }) {
console.log(`Before ${model} ${action}`);
},

afterEntityMutation({ model, action }) {
console.log(`After ${model} ${action}`);
},
},
});
```
Expand All @@ -347,20 +346,24 @@ You can provide an extra `mutationInterceptionFilter` to control what to interce
```ts
db.$use({
id: 'mutation-hook-plugin',
mutationInterceptionFilter: ({ model }) => {
return {
intercept: model === 'User',
// load entities affected before the mutation (defaults to false)
loadBeforeMutationEntities: true,
// load entities affected after the mutation (defaults to false)
loadAfterMutationEntities: true,
};
},
beforeEntityMutation({ model, action, entities }) {
console.log(`Before ${model} ${action}: ${entities}`);
},
afterEntityMutation({ model, action, afterMutationEntities }) {
console.log(`After ${model} ${action}: ${afterMutationEntities}`);
onEntityMutation: {
mutationInterceptionFilter: ({ model }) => {
return {
intercept: model === 'User',
// load entities affected before the mutation (defaults to false)
loadBeforeMutationEntities: true,
// load entities affected after the mutation (defaults to false)
loadAfterMutationEntities: true,
};
},

beforeEntityMutation({ model, action, entities }) {
console.log(`Before ${model} ${action}: ${entities}`);
},

afterEntityMutation({ model, action, afterMutationEntities }) {
console.log(`After ${model} ${action}: ${afterMutationEntities}`);
},
},
});
```
Expand Down
1 change: 1 addition & 0 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@
- [ ] Short-circuit pre-create check for scalar-field only policies
- [ ] Inject "replace into"
- [ ] Inject "on conflict do update"
- [ ] Inject "insert into select from"
- [x] Migration
- [ ] Databases
- [x] SQLite
Expand Down
30 changes: 5 additions & 25 deletions packages/runtime/src/client/client-impl.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { invariant, lowerCaseFirst } from '@zenstackhq/common-helpers';
import { invariant } from '@zenstackhq/common-helpers';
import type { QueryExecutor } from 'kysely';
import {
CompiledQuery,
Expand Down Expand Up @@ -376,30 +376,10 @@ function createModelCrudHandler<Schema extends SchemaDef, Model extends GetModel
// apply plugins
const plugins = [...(client.$options.plugins ?? [])];
for (const plugin of plugins) {
if (plugin.onQuery && typeof plugin.onQuery === 'object') {
// for each model key or "$allModels"
for (const [_model, modelHooks] of Object.entries<any>(plugin.onQuery)) {
if (_model === lowerCaseFirst(model) || _model === '$allModels') {
if (modelHooks && typeof modelHooks === 'object') {
// for each operation key or "$allOperations"
for (const [op, opHooks] of Object.entries(modelHooks)) {
if (op === operation || op === '$allOperations') {
if (typeof opHooks === 'function') {
const _proceed = proceed;
proceed = () =>
opHooks({
client,
model,
operation,
args,
query: _proceed,
}) as Promise<unknown>;
}
}
}
}
}
}
const onQuery = plugin.onQuery;
if (onQuery) {
const _proceed = proceed;
proceed = () => onQuery({ client, model, operation, args, query: _proceed }) as Promise<unknown>;
}
}

Expand Down
Loading