mirror of
https://github.com/bknd-io/bknd/
synced 2026-08-02 08:06:00 +00:00
d9bce049ef
Introduced a new `indexStrategy` option in the timestamps plugin to configure index generation for `created_at` and `updated_at` fields. Supports "composite" and "individual" strategies for better control over database indexing. Added test coverage for different index strategies.
105 lines
3.1 KiB
TypeScript
105 lines
3.1 KiB
TypeScript
import { type App, type AppPlugin, em, entity, datetime, DatabaseEvents } from "bknd";
|
|
import { $console } from "bknd/utils";
|
|
|
|
export type TimestampsPluginOptions = {
|
|
entities: string[];
|
|
setUpdatedOnCreate?: boolean;
|
|
indexStrategy?: "composite" | "individual";
|
|
};
|
|
|
|
/**
|
|
* This plugin adds `created_at` and `updated_at` fields to the specified entities.
|
|
* Add it to your plugins in `bknd.config.ts` like this:
|
|
*
|
|
* ```ts
|
|
* export default {
|
|
* plugins: [timestamps({ entities: ["posts"] })],
|
|
* }
|
|
* ```
|
|
*/
|
|
export function timestamps({
|
|
entities = [],
|
|
setUpdatedOnCreate = true,
|
|
indexStrategy,
|
|
}: TimestampsPluginOptions): AppPlugin {
|
|
return (app: App) => ({
|
|
name: "timestamps",
|
|
schema: () => {
|
|
if (entities.length === 0) {
|
|
$console.warn("No entities specified for timestamps plugin");
|
|
return;
|
|
}
|
|
|
|
const appEntities = app.em.entities.map((e) => e.name);
|
|
const actualEntities = entities.filter((e) => appEntities.includes(e));
|
|
|
|
return em(
|
|
Object.fromEntries(
|
|
actualEntities.map((e) => [
|
|
e,
|
|
entity(e, {
|
|
created_at: datetime(),
|
|
updated_at: datetime(),
|
|
}),
|
|
]),
|
|
),
|
|
(fns, schema) => {
|
|
if (indexStrategy) {
|
|
for (const entity of actualEntities) {
|
|
if (entity in schema) {
|
|
switch (indexStrategy) {
|
|
case "composite":
|
|
fns.index(schema[entity]!).on(["created_at", "updated_at"]);
|
|
break;
|
|
case "individual":
|
|
fns.index(schema[entity]!).on(["created_at"]);
|
|
fns.index(schema[entity]!).on(["updated_at"]);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
);
|
|
},
|
|
onBuilt: async () => {
|
|
app.emgr.onEvent(
|
|
DatabaseEvents.MutatorInsertBefore,
|
|
(event) => {
|
|
const { entity, data } = event.params;
|
|
if (entities.includes(entity.name)) {
|
|
return {
|
|
...data,
|
|
created_at: new Date(),
|
|
updated_at: setUpdatedOnCreate ? new Date() : null,
|
|
};
|
|
}
|
|
return data;
|
|
},
|
|
{
|
|
mode: "sync",
|
|
id: "bknd-timestamps",
|
|
},
|
|
);
|
|
|
|
app.emgr.onEvent(
|
|
DatabaseEvents.MutatorUpdateBefore,
|
|
async (event) => {
|
|
const { entity, data } = event.params;
|
|
if (entities.includes(entity.name)) {
|
|
return {
|
|
...data,
|
|
updated_at: new Date(),
|
|
};
|
|
}
|
|
return data;
|
|
},
|
|
{
|
|
mode: "sync",
|
|
id: "bknd-timestamps",
|
|
},
|
|
);
|
|
},
|
|
});
|
|
}
|