@kysera/timestamps 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/index.d.ts +79 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/package.json +57 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 LuxQuant
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { Plugin } from '@kysera/repository';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Timestamp methods added to repositories
|
|
5
|
+
*/
|
|
6
|
+
interface TimestampMethods<T> {
|
|
7
|
+
findCreatedAfter(date: Date | string): Promise<T[]>;
|
|
8
|
+
findCreatedBefore(date: Date | string): Promise<T[]>;
|
|
9
|
+
findCreatedBetween(startDate: Date | string, endDate: Date | string): Promise<T[]>;
|
|
10
|
+
findUpdatedAfter(date: Date | string): Promise<T[]>;
|
|
11
|
+
findRecentlyUpdated(limit?: number): Promise<T[]>;
|
|
12
|
+
findRecentlyCreated(limit?: number): Promise<T[]>;
|
|
13
|
+
createWithoutTimestamps(input: unknown): Promise<T>;
|
|
14
|
+
updateWithoutTimestamp(id: number, input: unknown): Promise<T>;
|
|
15
|
+
touch(id: number): Promise<void>;
|
|
16
|
+
getTimestampColumns(): {
|
|
17
|
+
createdAt: string;
|
|
18
|
+
updatedAt: string;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Options for the timestamps plugin
|
|
23
|
+
*/
|
|
24
|
+
interface TimestampsOptions {
|
|
25
|
+
/**
|
|
26
|
+
* Name of the created_at column
|
|
27
|
+
* @default 'created_at'
|
|
28
|
+
*/
|
|
29
|
+
createdAtColumn?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Name of the updated_at column
|
|
32
|
+
* @default 'updated_at'
|
|
33
|
+
*/
|
|
34
|
+
updatedAtColumn?: string;
|
|
35
|
+
/**
|
|
36
|
+
* Whether to set updated_at on insert
|
|
37
|
+
* @default false
|
|
38
|
+
*/
|
|
39
|
+
setUpdatedAtOnInsert?: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* List of tables that should have timestamps
|
|
42
|
+
* If not specified, all tables will have timestamps
|
|
43
|
+
*/
|
|
44
|
+
tables?: string[];
|
|
45
|
+
/**
|
|
46
|
+
* Tables that should be excluded from timestamps
|
|
47
|
+
*/
|
|
48
|
+
excludeTables?: string[];
|
|
49
|
+
/**
|
|
50
|
+
* Custom timestamp function (defaults to new Date().toISOString())
|
|
51
|
+
*/
|
|
52
|
+
getTimestamp?: () => Date | string | number;
|
|
53
|
+
/**
|
|
54
|
+
* Date format for database (ISO string by default)
|
|
55
|
+
*/
|
|
56
|
+
dateFormat?: 'iso' | 'unix' | 'date';
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Timestamps Plugin
|
|
60
|
+
*
|
|
61
|
+
* Automatically manages created_at and updated_at timestamps for database records.
|
|
62
|
+
* Works by overriding repository methods to add timestamp values.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```typescript
|
|
66
|
+
* import { timestampsPlugin } from '@kysera/timestamps'
|
|
67
|
+
*
|
|
68
|
+
* const plugin = timestampsPlugin({
|
|
69
|
+
* createdAtColumn: 'created_at',
|
|
70
|
+
* updatedAtColumn: 'updated_at',
|
|
71
|
+
* tables: ['users', 'posts', 'comments']
|
|
72
|
+
* })
|
|
73
|
+
*
|
|
74
|
+
* const orm = createORM(db, [plugin])
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
declare const timestampsPlugin: (options?: TimestampsOptions) => Plugin;
|
|
78
|
+
|
|
79
|
+
export { type TimestampMethods, type TimestampsOptions, timestampsPlugin as default, timestampsPlugin };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
function c(r){if(r.getTimestamp)return r.getTimestamp();let t=new Date;switch(r.dateFormat){case "unix":return Math.floor(t.getTime()/1e3);case "date":return t;case "iso":default:return t.toISOString()}}function T(r,t){return t.excludeTables?.includes(r)?false:t.tables?t.tables.includes(r):true}function l(r,t,i){return {select(){return r.selectFrom(t)},where(d,u){return r.selectFrom(t).where(i,d,u)}}}var y=(r={})=>{let{createdAtColumn:t="created_at",updatedAtColumn:i="updated_at",setUpdatedAtOnInsert:d=false}=r;return {name:"@kysera/timestamps",version:"1.0.0",interceptQuery(u,a){return u},extendRepository(u){if(!("tableName"in u)||!("executor"in u))return u;let a=u;if(!T(a.tableName,r))return u;let p=a.create.bind(a),g=a.update.bind(a),o=a.executor;return {...a,async create(e){let n=e,s=c(r),m={...n,[t]:n[t]??s};return d&&(m[i]=n[i]??s),await p(m)},async update(e,n){let s=n,m=c(r),w={...s,[i]:s[i]??m};return await g(e,w)},async findCreatedAfter(e){return await l(o,a.tableName,t).where(">",String(e)).selectAll().execute()},async findCreatedBefore(e){return await l(o,a.tableName,t).where("<",String(e)).selectAll().execute()},async findCreatedBetween(e,n){return await o.selectFrom(a.tableName).selectAll().where(t,">=",e).where(t,"<=",n).execute()},async findUpdatedAfter(e){return await l(o,a.tableName,i).where(">",String(e)).selectAll().execute()},async findRecentlyUpdated(e=10){return await o.selectFrom(a.tableName).selectAll().orderBy(i,"desc").limit(e).execute()},async findRecentlyCreated(e=10){return await o.selectFrom(a.tableName).selectAll().orderBy(t,"desc").limit(e).execute()},async createWithoutTimestamps(e){return await p(e)},async updateWithoutTimestamp(e,n){return await g(e,n)},async touch(e){let n=c(r),s={[i]:n};await o.updateTable(a.tableName).set(s).where("id","=",e).execute();},getTimestampColumns(){return {createdAt:t,updatedAt:i}}}}}},f=y;export{f as default,y as timestampsPlugin};//# sourceMappingURL=index.js.map
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":["getTimestamp","options","now","shouldApplyTimestamps","tableName","createTimestampQuery","executor","column","operator","value","timestampsPlugin","createdAtColumn","updatedAtColumn","setUpdatedAtOnInsert","qb","_context","repo","baseRepo","originalCreate","originalUpdate","input","data","timestamp","dataWithTimestamps","id","dataWithTimestamp","date","startDate","endDate","limit","updateData","index_default"],"mappings":"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","file":"index.js","sourcesContent":["import type { Plugin } from '@kysera/repository'\nimport type { Kysely, SelectQueryBuilder } from 'kysely'\n\n/**\n * Database schema with timestamp columns\n */\ntype TimestampedTable = Record<string, unknown>;\n\n/**\n * Timestamp methods added to repositories\n */\nexport interface TimestampMethods<T> {\n findCreatedAfter(date: Date | string): Promise<T[]>\n findCreatedBefore(date: Date | string): Promise<T[]>\n findCreatedBetween(startDate: Date | string, endDate: Date | string): Promise<T[]>\n findUpdatedAfter(date: Date | string): Promise<T[]>\n findRecentlyUpdated(limit?: number): Promise<T[]>\n findRecentlyCreated(limit?: number): Promise<T[]>\n createWithoutTimestamps(input: unknown): Promise<T>\n updateWithoutTimestamp(id: number, input: unknown): Promise<T>\n touch(id: number): Promise<void>\n getTimestampColumns(): { createdAt: string; updatedAt: string }\n}\n\n/**\n * Options for the timestamps plugin\n */\nexport interface TimestampsOptions {\n /**\n * Name of the created_at column\n * @default 'created_at'\n */\n createdAtColumn?: string\n\n /**\n * Name of the updated_at column\n * @default 'updated_at'\n */\n updatedAtColumn?: string\n\n /**\n * Whether to set updated_at on insert\n * @default false\n */\n setUpdatedAtOnInsert?: boolean\n\n /**\n * List of tables that should have timestamps\n * If not specified, all tables will have timestamps\n */\n tables?: string[]\n\n /**\n * Tables that should be excluded from timestamps\n */\n excludeTables?: string[]\n\n /**\n * Custom timestamp function (defaults to new Date().toISOString())\n */\n getTimestamp?: () => Date | string | number\n\n /**\n * Date format for database (ISO string by default)\n */\n dateFormat?: 'iso' | 'unix' | 'date'\n}\n\n/**\n * Get the current timestamp based on options\n */\nfunction getTimestamp(options: TimestampsOptions): Date | string | number {\n if (options.getTimestamp) {\n return options.getTimestamp()\n }\n\n const now = new Date()\n\n switch (options.dateFormat) {\n case 'unix':\n return Math.floor(now.getTime() / 1000)\n case 'date':\n return now\n case 'iso':\n default:\n return now.toISOString()\n }\n}\n\n/**\n * Check if a table should have timestamps\n */\nfunction shouldApplyTimestamps(tableName: string, options: TimestampsOptions): boolean {\n if (options.excludeTables?.includes(tableName)) {\n return false\n }\n\n if (options.tables) {\n return options.tables.includes(tableName)\n }\n\n return true\n}\n\n/**\n * Type-safe query builder for timestamp operations\n */\nfunction createTimestampQuery(\n executor: Kysely<Record<string, TimestampedTable>>,\n tableName: string,\n column: string\n): {\n select(): SelectQueryBuilder<Record<string, TimestampedTable>, typeof tableName, {}>\n where<V>(operator: string, value: V): SelectQueryBuilder<Record<string, TimestampedTable>, typeof tableName, {}>\n} {\n return {\n select() {\n return executor.selectFrom(tableName as never)\n },\n where<V>(operator: string, value: V) {\n return executor\n .selectFrom(tableName as never)\n .where(column as never, operator as never, value as never)\n }\n }\n}\n\n/**\n * Timestamps Plugin\n *\n * Automatically manages created_at and updated_at timestamps for database records.\n * Works by overriding repository methods to add timestamp values.\n *\n * @example\n * ```typescript\n * import { timestampsPlugin } from '@kysera/timestamps'\n *\n * const plugin = timestampsPlugin({\n * createdAtColumn: 'created_at',\n * updatedAtColumn: 'updated_at',\n * tables: ['users', 'posts', 'comments']\n * })\n *\n * const orm = createORM(db, [plugin])\n * ```\n */\nexport const timestampsPlugin = (options: TimestampsOptions = {}): Plugin => {\n const {\n createdAtColumn = 'created_at',\n updatedAtColumn = 'updated_at',\n setUpdatedAtOnInsert = false\n } = options\n\n return {\n name: '@kysera/timestamps',\n version: '1.0.0',\n\n interceptQuery(qb, _context) {\n // The interceptQuery method can't modify INSERT/UPDATE values in Kysely\n // We handle timestamps through repository method overrides instead\n return qb\n },\n\n extendRepository<T extends object>(repo: T): T {\n // Check if it's actually a repository (has required properties)\n if (!('tableName' in repo) || !('executor' in repo)) {\n return repo\n }\n\n // Type assertion is safe here as we've checked for properties\n const baseRepo = repo as T & { tableName: string; executor: unknown; create: Function; update: Function }\n\n // Skip if table doesn't support timestamps\n if (!shouldApplyTimestamps(baseRepo.tableName, options)) {\n return repo\n }\n\n // Save original methods\n const originalCreate = baseRepo.create.bind(baseRepo)\n const originalUpdate = baseRepo.update.bind(baseRepo)\n const executor = baseRepo.executor as Kysely<Record<string, TimestampedTable>>\n\n const extendedRepo = {\n ...baseRepo,\n\n // Override create to add timestamps\n async create(input: unknown): Promise<unknown> {\n const data = input as Record<string, unknown>\n const timestamp = getTimestamp(options)\n const dataWithTimestamps: Record<string, unknown> = {\n ...data,\n [createdAtColumn]: data[createdAtColumn] ?? timestamp\n }\n\n if (setUpdatedAtOnInsert) {\n dataWithTimestamps[updatedAtColumn] = data[updatedAtColumn] ?? timestamp\n }\n\n return await originalCreate(dataWithTimestamps)\n },\n\n // Override update to set updated_at\n async update(id: number, input: unknown): Promise<unknown> {\n const data = input as Record<string, unknown>\n const timestamp = getTimestamp(options)\n const dataWithTimestamp: Record<string, unknown> = {\n ...data,\n [updatedAtColumn]: data[updatedAtColumn] ?? timestamp\n }\n\n return await originalUpdate(id, dataWithTimestamp)\n },\n\n /**\n * Find records created after a specific date\n */\n async findCreatedAfter(date: Date | string | number): Promise<unknown[]> {\n const query = createTimestampQuery(executor, baseRepo.tableName, createdAtColumn)\n const result = await query.where('>', String(date))\n .selectAll()\n .execute()\n return result\n },\n\n /**\n * Find records created before a specific date\n */\n async findCreatedBefore(date: Date | string | number): Promise<unknown[]> {\n const query = createTimestampQuery(executor, baseRepo.tableName, createdAtColumn)\n const result = await query.where('<', String(date))\n .selectAll()\n .execute()\n return result\n },\n\n /**\n * Find records created between two dates\n */\n async findCreatedBetween(startDate: Date | string | number, endDate: Date | string | number): Promise<unknown[]> {\n const result = await executor\n .selectFrom(baseRepo.tableName as never)\n .selectAll()\n .where(createdAtColumn as never, '>=', startDate as never)\n .where(createdAtColumn as never, '<=', endDate as never)\n .execute()\n return result\n },\n\n /**\n * Find records updated after a specific date\n */\n async findUpdatedAfter(date: Date | string | number): Promise<unknown[]> {\n const query = createTimestampQuery(executor, baseRepo.tableName, updatedAtColumn)\n const result = await query.where('>', String(date))\n .selectAll()\n .execute()\n return result\n },\n\n /**\n * Find recently updated records\n */\n async findRecentlyUpdated(limit = 10): Promise<unknown[]> {\n const result = await executor\n .selectFrom(baseRepo.tableName as never)\n .selectAll()\n .orderBy(updatedAtColumn as never, 'desc')\n .limit(limit)\n .execute()\n return result\n },\n\n /**\n * Find recently created records\n */\n async findRecentlyCreated(limit = 10): Promise<unknown[]> {\n const result = await executor\n .selectFrom(baseRepo.tableName as never)\n .selectAll()\n .orderBy(createdAtColumn as never, 'desc')\n .limit(limit)\n .execute()\n return result\n },\n\n /**\n * Create without adding timestamps\n */\n async createWithoutTimestamps(input: unknown): Promise<unknown> {\n return await originalCreate(input)\n },\n\n /**\n * Update without modifying timestamp\n */\n async updateWithoutTimestamp(id: number, input: unknown): Promise<unknown> {\n return await originalUpdate(id, input)\n },\n\n /**\n * Touch a record (update its timestamp)\n */\n async touch(id: number): Promise<void> {\n const timestamp = getTimestamp(options)\n const updateData = { [updatedAtColumn]: timestamp }\n\n await executor\n .updateTable(baseRepo.tableName as never)\n .set(updateData as never)\n .where('id' as never, '=', id as never)\n .execute()\n },\n\n /**\n * Get the timestamp column names\n */\n getTimestampColumns(): { createdAt: string; updatedAt: string } {\n return {\n createdAt: createdAtColumn,\n updatedAt: updatedAtColumn\n }\n }\n }\n\n return extendedRepo as T\n }\n }\n}\n\n/**\n * Default export\n */\nexport default timestampsPlugin"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@kysera/timestamps",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "Automatic timestamp management plugin for Kysera ORM",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"README.md"
|
|
17
|
+
],
|
|
18
|
+
"keywords": [
|
|
19
|
+
"kysely",
|
|
20
|
+
"orm",
|
|
21
|
+
"timestamps",
|
|
22
|
+
"created_at",
|
|
23
|
+
"updated_at",
|
|
24
|
+
"plugin",
|
|
25
|
+
"typescript"
|
|
26
|
+
],
|
|
27
|
+
"author": "Kysera Team",
|
|
28
|
+
"license": "MIT",
|
|
29
|
+
"peerDependencies": {
|
|
30
|
+
"kysely": "^0.28.7",
|
|
31
|
+
"@kysera/repository": "0.3.0"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/node": "^24.6.0",
|
|
35
|
+
"kysely": "^0.28.7",
|
|
36
|
+
"typescript": "^5.9.2",
|
|
37
|
+
"vitest": "^3.2.4",
|
|
38
|
+
"better-sqlite3": "^12.4.1",
|
|
39
|
+
"@types/better-sqlite3": "^7.6.12",
|
|
40
|
+
"tsup": "^8.5.0",
|
|
41
|
+
"zod": "^4.1.11",
|
|
42
|
+
"@kysera/repository": "0.3.0"
|
|
43
|
+
},
|
|
44
|
+
"sideEffects": false,
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": ">=20.0.0",
|
|
47
|
+
"bun": ">=1.0.0"
|
|
48
|
+
},
|
|
49
|
+
"scripts": {
|
|
50
|
+
"build": "tsup",
|
|
51
|
+
"dev": "tsup --watch",
|
|
52
|
+
"test": "vitest run",
|
|
53
|
+
"test:watch": "vitest",
|
|
54
|
+
"typecheck": "tsc --noEmit",
|
|
55
|
+
"lint": "eslint src test --ext .ts"
|
|
56
|
+
}
|
|
57
|
+
}
|