@geekmidas/db 0.2.0 → 1.0.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/CHANGELOG.md +7 -0
- package/dist/kysely/pagination.cjs.map +1 -1
- package/dist/kysely/pagination.d.cts +1 -0
- package/dist/kysely/pagination.d.cts.map +1 -0
- package/dist/kysely/pagination.d.mts +1 -0
- package/dist/kysely/pagination.d.mts.map +1 -0
- package/dist/kysely/pagination.mjs.map +1 -1
- package/dist/kysely-8WPSKCZG.cjs.map +1 -1
- package/dist/{kysely-0FOi6ZdO.d.cts → kysely-D3eeuId4.d.cts} +3 -1
- package/dist/kysely-D3eeuId4.d.cts.map +1 -0
- package/dist/{kysely-Di1LVvL2.d.mts → kysely-DUdsB0BP.d.mts} +3 -1
- package/dist/kysely-DUdsB0BP.d.mts.map +1 -0
- package/dist/kysely-DmfA94RY.mjs.map +1 -1
- package/dist/kysely.d.cts +1 -1
- package/dist/kysely.d.mts +1 -1
- package/dist/rls.cjs.map +1 -1
- package/dist/rls.d.cts +2 -1
- package/dist/rls.d.cts.map +1 -0
- package/dist/rls.d.mts +2 -1
- package/dist/rls.d.mts.map +1 -0
- package/dist/rls.mjs.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/kysely.integration.spec.ts +729 -729
- package/src/__tests__/kysely.spec.ts +388 -388
- package/src/__tests__/rls.spec.ts +399 -399
- package/src/kysely/__tests__/pagination.integration.spec.ts +327 -327
- package/src/kysely/pagination.ts +84 -84
- package/src/kysely.ts +19 -19
- package/src/rls.ts +31 -31
- package/tsconfig.json +9 -0
package/CHANGELOG.md
ADDED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pagination.cjs","names":["value: unknown","cursor: string"],"sources":["../../src/kysely/pagination.ts"],"sourcesContent":["import type { SelectQueryBuilder } from 'kysely';\n\n/**\n * Sort direction for cursor-based pagination.\n */\nexport enum Direction {\n
|
|
1
|
+
{"version":3,"file":"pagination.cjs","names":["value: unknown","cursor: string"],"sources":["../../src/kysely/pagination.ts"],"sourcesContent":["import type { SelectQueryBuilder } from 'kysely';\n\n/**\n * Sort direction for cursor-based pagination.\n */\nexport enum Direction {\n\tAsc = 'asc',\n\tDesc = 'desc',\n}\n\n/**\n * Result of a paginated query.\n */\nexport interface PaginationResult<TItem> {\n\titems: TItem[];\n\tpagination: {\n\t\ttotal: number;\n\t\thasMore: boolean;\n\t\tcursor?: string;\n\t};\n}\n\n/**\n * Options for paginated search.\n */\nexport interface PaginatedSearchOptions<\n\tTRow,\n\tTMapRow extends (row: TRow) => unknown,\n> {\n\t/** The base Kysely query to paginate */\n\tquery: SelectQueryBuilder<any, any, TRow>;\n\t/** Cursor value for pagination (value of cursorField from previous page) */\n\tcursor?: string;\n\t/** Maximum number of items per page (default: 20) */\n\tlimit?: number;\n\t/** Function to transform each row to the output format */\n\tmapRow: TMapRow;\n\t/** Field to use for cursor pagination (default: 'id') */\n\tcursorField?: string;\n\t/** Sort direction for cursor field (default: Direction.Asc) */\n\tcursorDirection?: Direction;\n}\n\n/**\n * Generic paginated search function that handles:\n * - Total count calculation\n * - Cursor-based pagination\n * - Fetching one extra row to determine hasMore\n * - Mapping rows to output format\n *\n * @example\n * ```typescript\n * const result = await paginatedSearch({\n * query: db.selectFrom('users').selectAll(),\n * cursor: previousCursor,\n * limit: 20,\n * mapRow: (row) => ({ id: row.id, name: row.name }),\n * cursorField: 'id',\n * cursorDirection: Direction.Asc,\n * });\n * ```\n */\nexport async function paginatedSearch<\n\tTRow extends Record<string, unknown>,\n\tTMapRow extends (row: TRow) => unknown,\n>({\n\tquery,\n\tcursor,\n\tlimit = 20,\n\tmapRow,\n\tcursorField = 'id',\n\tcursorDirection = Direction.Asc,\n}: PaginatedSearchOptions<TRow, TMapRow>): Promise<\n\tPaginationResult<Awaited<ReturnType<TMapRow>>>\n> {\n\t// Get total count (without cursor)\n\tconst countResult = await query\n\t\t.clearSelect()\n\t\t.clearOrderBy()\n\t\t.select((eb) => eb.fn.countAll().as('count'))\n\t\t.executeTakeFirstOrThrow();\n\n\tconst count = countResult.count;\n\n\t// Apply cursor if provided\n\tlet paginatedQuery = query;\n\tif (cursor) {\n\t\tconst operator = cursorDirection === Direction.Asc ? '>' : '<';\n\t\tpaginatedQuery = paginatedQuery.where(\n\t\t\tcursorField as any,\n\t\t\toperator,\n\t\t\tcursor,\n\t\t) as typeof query;\n\t}\n\n\t// Fetch one extra to determine if there are more results\n\tconst data = await paginatedQuery\n\t\t.orderBy(cursorField as any, cursorDirection)\n\t\t.limit(limit + 1)\n\t\t.execute();\n\n\tconst hasMore = data.length > limit;\n\tconst rows = hasMore ? data.slice(0, limit) : data;\n\tconst lastRow = rows[rows.length - 1];\n\tconst nextCursor =\n\t\thasMore && lastRow ? String(lastRow[cursorField]) : undefined;\n\n\tconst items = (await Promise.all(rows.map(mapRow))) as Awaited<\n\t\tReturnType<TMapRow>\n\t>[];\n\n\treturn {\n\t\titems,\n\t\tpagination: {\n\t\t\ttotal: Number(count),\n\t\t\thasMore,\n\t\t\tcursor: nextCursor,\n\t\t},\n\t};\n}\n\n/**\n * Encode a cursor value for safe URL transmission.\n * Supports various types: string, number, Date, etc.\n */\nexport function encodeCursor(value: unknown): string {\n\tconst payload = {\n\t\tv: value instanceof Date ? value.toISOString() : value,\n\t\tt: value instanceof Date ? 'date' : typeof value,\n\t};\n\treturn Buffer.from(JSON.stringify(payload)).toString('base64url');\n}\n\n/**\n * Decode a cursor string back to its original value.\n */\nexport function decodeCursor(cursor: string): unknown {\n\ttry {\n\t\tconst json = Buffer.from(cursor, 'base64url').toString('utf-8');\n\t\tconst payload = JSON.parse(json);\n\n\t\tif (payload.t === 'date') {\n\t\t\treturn new Date(payload.v);\n\t\t}\n\n\t\treturn payload.v;\n\t} catch {\n\t\tthrow new Error('Invalid cursor format');\n\t}\n}\n"],"mappings":";;;;;AAKA,IAAY,kDAAL;AACN;AACA;;AACA;;;;;;;;;;;;;;;;;;;;AAsDD,eAAsB,gBAGpB,EACD,OACA,QACA,QAAQ,IACR,QACA,cAAc,MACd,kBAAkB,UAAU,KACW,EAEtC;CAED,MAAM,cAAc,MAAM,MACxB,aAAa,CACb,cAAc,CACd,OAAO,CAAC,OAAO,GAAG,GAAG,UAAU,CAAC,GAAG,QAAQ,CAAC,CAC5C,yBAAyB;CAE3B,MAAM,QAAQ,YAAY;CAG1B,IAAI,iBAAiB;AACrB,KAAI,QAAQ;EACX,MAAM,WAAW,oBAAoB,UAAU,MAAM,MAAM;AAC3D,mBAAiB,eAAe,MAC/B,aACA,UACA,OACA;CACD;CAGD,MAAM,OAAO,MAAM,eACjB,QAAQ,aAAoB,gBAAgB,CAC5C,MAAM,QAAQ,EAAE,CAChB,SAAS;CAEX,MAAM,UAAU,KAAK,SAAS;CAC9B,MAAM,OAAO,UAAU,KAAK,MAAM,GAAG,MAAM,GAAG;CAC9C,MAAM,UAAU,KAAK,KAAK,SAAS;CACnC,MAAM,aACL,WAAW,UAAU,OAAO,QAAQ,aAAa;CAElD,MAAM,QAAS,MAAM,QAAQ,IAAI,KAAK,IAAI,OAAO,CAAC;AAIlD,QAAO;EACN;EACA,YAAY;GACX,OAAO,OAAO,MAAM;GACpB;GACA,QAAQ;EACR;CACD;AACD;;;;;AAMD,SAAgB,aAAaA,OAAwB;CACpD,MAAM,UAAU;EACf,GAAG,iBAAiB,OAAO,MAAM,aAAa,GAAG;EACjD,GAAG,iBAAiB,OAAO,gBAAgB;CAC3C;AACD,QAAO,OAAO,KAAK,KAAK,UAAU,QAAQ,CAAC,CAAC,SAAS,YAAY;AACjE;;;;AAKD,SAAgB,aAAaC,QAAyB;AACrD,KAAI;EACH,MAAM,OAAO,OAAO,KAAK,QAAQ,YAAY,CAAC,SAAS,QAAQ;EAC/D,MAAM,UAAU,KAAK,MAAM,KAAK;AAEhC,MAAI,QAAQ,MAAM,OACjB,QAAO,IAAI,KAAK,QAAQ;AAGzB,SAAO,QAAQ;CACf,QAAO;AACP,QAAM,IAAI,MAAM;CAChB;AACD"}
|
|
@@ -73,6 +73,7 @@ declare function encodeCursor(value: unknown): string;
|
|
|
73
73
|
* Decode a cursor string back to its original value.
|
|
74
74
|
*/
|
|
75
75
|
declare function decodeCursor(cursor: string): unknown;
|
|
76
|
+
//# sourceMappingURL=pagination.d.ts.map
|
|
76
77
|
//#endregion
|
|
77
78
|
export { Direction, PaginatedSearchOptions, PaginationResult, decodeCursor, encodeCursor, paginatedSearch };
|
|
78
79
|
//# sourceMappingURL=pagination.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pagination.d.cts","names":[],"sources":["../../src/kysely/pagination.ts"],"sourcesContent":[],"mappings":";;;;;;AAKA;AAQiB,aARL,SAAA;EAoBK,GAAA,GAAA,KAAA;EAAsB,IAAA,GAAA,MAAA;;;;;AAepB,UA3BF,gBA2BE,CAAA,KAAA,CAAA,CAAA;EAAS,KAAA,EA1BpB,KA0BoB,EAAA;EAsBN,UAAA,EAAA;IAAe,KAAA,EAAA,MAAA;IACvB,OAAA,EAAA,OAAA;IACS,MAAA,CAAA,EAAA,MAAA;EAAI,CAAA;;;;;AAO1B,UA9CgB,sBA8ChB,CAAA,IAAA,EAAA,gBAAA,CAAA,GAAA,EA5CsB,IA4CtB,EAAA,GAAA,OAAA,CAAA,CAAA;EAA+B;EACF,KAAE,EA1CxB,kBA0CwB,CAAA,GAAA,EAAA,GAAA,EA1CK,IA0CL,CAAA;EAAO;EAAd,MACY,CAAA,EAAA,MAAA;EAAO;EAAR,KAAlB,CAAA,EAAA,MAAA;EAAO;EAAR,MAD0B,EApClC,OAoCkC;EAAO;EAqDlC,WAAA,CAAA,EAAA,MAAY;EAWZ;oBAhGG;;;;;;;;;;;;;;;;;;;;;iBAsBG,6BACR,+CACS;;;;;;;GAQpB,uBAAuB,MAAM,WAAW,QAC1C,iBAAiB,QAAQ,WAAW;;;;;iBAoDrB,YAAA;;;;iBAWA,YAAA"}
|
|
@@ -73,6 +73,7 @@ declare function encodeCursor(value: unknown): string;
|
|
|
73
73
|
* Decode a cursor string back to its original value.
|
|
74
74
|
*/
|
|
75
75
|
declare function decodeCursor(cursor: string): unknown;
|
|
76
|
+
//# sourceMappingURL=pagination.d.ts.map
|
|
76
77
|
//#endregion
|
|
77
78
|
export { Direction, PaginatedSearchOptions, PaginationResult, decodeCursor, encodeCursor, paginatedSearch };
|
|
78
79
|
//# sourceMappingURL=pagination.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pagination.d.mts","names":[],"sources":["../../src/kysely/pagination.ts"],"sourcesContent":[],"mappings":";;;;;;AAKA;AAQiB,aARL,SAAA;EAoBK,GAAA,GAAA,KAAA;EAAsB,IAAA,GAAA,MAAA;;;;;AAepB,UA3BF,gBA2BE,CAAA,KAAA,CAAA,CAAA;EAAS,KAAA,EA1BpB,KA0BoB,EAAA;EAsBN,UAAA,EAAA;IAAe,KAAA,EAAA,MAAA;IACvB,OAAA,EAAA,OAAA;IACS,MAAA,CAAA,EAAA,MAAA;EAAI,CAAA;;;;;AAO1B,UA9CgB,sBA8ChB,CAAA,IAAA,EAAA,gBAAA,CAAA,GAAA,EA5CsB,IA4CtB,EAAA,GAAA,OAAA,CAAA,CAAA;EAA+B;EACF,KAAE,EA1CxB,kBA0CwB,CAAA,GAAA,EAAA,GAAA,EA1CK,IA0CL,CAAA;EAAO;EAAd,MACY,CAAA,EAAA,MAAA;EAAO;EAAR,KAAlB,CAAA,EAAA,MAAA;EAAO;EAAR,MAD0B,EApClC,OAoCkC;EAAO;EAqDlC,WAAA,CAAA,EAAA,MAAY;EAWZ;oBAhGG;;;;;;;;;;;;;;;;;;;;;iBAsBG,6BACR,+CACS;;;;;;;GAQpB,uBAAuB,MAAM,WAAW,QAC1C,iBAAiB,QAAQ,WAAW;;;;;iBAoDrB,YAAA;;;;iBAWA,YAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pagination.mjs","names":["value: unknown","cursor: string"],"sources":["../../src/kysely/pagination.ts"],"sourcesContent":["import type { SelectQueryBuilder } from 'kysely';\n\n/**\n * Sort direction for cursor-based pagination.\n */\nexport enum Direction {\n
|
|
1
|
+
{"version":3,"file":"pagination.mjs","names":["value: unknown","cursor: string"],"sources":["../../src/kysely/pagination.ts"],"sourcesContent":["import type { SelectQueryBuilder } from 'kysely';\n\n/**\n * Sort direction for cursor-based pagination.\n */\nexport enum Direction {\n\tAsc = 'asc',\n\tDesc = 'desc',\n}\n\n/**\n * Result of a paginated query.\n */\nexport interface PaginationResult<TItem> {\n\titems: TItem[];\n\tpagination: {\n\t\ttotal: number;\n\t\thasMore: boolean;\n\t\tcursor?: string;\n\t};\n}\n\n/**\n * Options for paginated search.\n */\nexport interface PaginatedSearchOptions<\n\tTRow,\n\tTMapRow extends (row: TRow) => unknown,\n> {\n\t/** The base Kysely query to paginate */\n\tquery: SelectQueryBuilder<any, any, TRow>;\n\t/** Cursor value for pagination (value of cursorField from previous page) */\n\tcursor?: string;\n\t/** Maximum number of items per page (default: 20) */\n\tlimit?: number;\n\t/** Function to transform each row to the output format */\n\tmapRow: TMapRow;\n\t/** Field to use for cursor pagination (default: 'id') */\n\tcursorField?: string;\n\t/** Sort direction for cursor field (default: Direction.Asc) */\n\tcursorDirection?: Direction;\n}\n\n/**\n * Generic paginated search function that handles:\n * - Total count calculation\n * - Cursor-based pagination\n * - Fetching one extra row to determine hasMore\n * - Mapping rows to output format\n *\n * @example\n * ```typescript\n * const result = await paginatedSearch({\n * query: db.selectFrom('users').selectAll(),\n * cursor: previousCursor,\n * limit: 20,\n * mapRow: (row) => ({ id: row.id, name: row.name }),\n * cursorField: 'id',\n * cursorDirection: Direction.Asc,\n * });\n * ```\n */\nexport async function paginatedSearch<\n\tTRow extends Record<string, unknown>,\n\tTMapRow extends (row: TRow) => unknown,\n>({\n\tquery,\n\tcursor,\n\tlimit = 20,\n\tmapRow,\n\tcursorField = 'id',\n\tcursorDirection = Direction.Asc,\n}: PaginatedSearchOptions<TRow, TMapRow>): Promise<\n\tPaginationResult<Awaited<ReturnType<TMapRow>>>\n> {\n\t// Get total count (without cursor)\n\tconst countResult = await query\n\t\t.clearSelect()\n\t\t.clearOrderBy()\n\t\t.select((eb) => eb.fn.countAll().as('count'))\n\t\t.executeTakeFirstOrThrow();\n\n\tconst count = countResult.count;\n\n\t// Apply cursor if provided\n\tlet paginatedQuery = query;\n\tif (cursor) {\n\t\tconst operator = cursorDirection === Direction.Asc ? '>' : '<';\n\t\tpaginatedQuery = paginatedQuery.where(\n\t\t\tcursorField as any,\n\t\t\toperator,\n\t\t\tcursor,\n\t\t) as typeof query;\n\t}\n\n\t// Fetch one extra to determine if there are more results\n\tconst data = await paginatedQuery\n\t\t.orderBy(cursorField as any, cursorDirection)\n\t\t.limit(limit + 1)\n\t\t.execute();\n\n\tconst hasMore = data.length > limit;\n\tconst rows = hasMore ? data.slice(0, limit) : data;\n\tconst lastRow = rows[rows.length - 1];\n\tconst nextCursor =\n\t\thasMore && lastRow ? String(lastRow[cursorField]) : undefined;\n\n\tconst items = (await Promise.all(rows.map(mapRow))) as Awaited<\n\t\tReturnType<TMapRow>\n\t>[];\n\n\treturn {\n\t\titems,\n\t\tpagination: {\n\t\t\ttotal: Number(count),\n\t\t\thasMore,\n\t\t\tcursor: nextCursor,\n\t\t},\n\t};\n}\n\n/**\n * Encode a cursor value for safe URL transmission.\n * Supports various types: string, number, Date, etc.\n */\nexport function encodeCursor(value: unknown): string {\n\tconst payload = {\n\t\tv: value instanceof Date ? value.toISOString() : value,\n\t\tt: value instanceof Date ? 'date' : typeof value,\n\t};\n\treturn Buffer.from(JSON.stringify(payload)).toString('base64url');\n}\n\n/**\n * Decode a cursor string back to its original value.\n */\nexport function decodeCursor(cursor: string): unknown {\n\ttry {\n\t\tconst json = Buffer.from(cursor, 'base64url').toString('utf-8');\n\t\tconst payload = JSON.parse(json);\n\n\t\tif (payload.t === 'date') {\n\t\t\treturn new Date(payload.v);\n\t\t}\n\n\t\treturn payload.v;\n\t} catch {\n\t\tthrow new Error('Invalid cursor format');\n\t}\n}\n"],"mappings":";;;;AAKA,IAAY,kDAAL;AACN;AACA;;AACA;;;;;;;;;;;;;;;;;;;;AAsDD,eAAsB,gBAGpB,EACD,OACA,QACA,QAAQ,IACR,QACA,cAAc,MACd,kBAAkB,UAAU,KACW,EAEtC;CAED,MAAM,cAAc,MAAM,MACxB,aAAa,CACb,cAAc,CACd,OAAO,CAAC,OAAO,GAAG,GAAG,UAAU,CAAC,GAAG,QAAQ,CAAC,CAC5C,yBAAyB;CAE3B,MAAM,QAAQ,YAAY;CAG1B,IAAI,iBAAiB;AACrB,KAAI,QAAQ;EACX,MAAM,WAAW,oBAAoB,UAAU,MAAM,MAAM;AAC3D,mBAAiB,eAAe,MAC/B,aACA,UACA,OACA;CACD;CAGD,MAAM,OAAO,MAAM,eACjB,QAAQ,aAAoB,gBAAgB,CAC5C,MAAM,QAAQ,EAAE,CAChB,SAAS;CAEX,MAAM,UAAU,KAAK,SAAS;CAC9B,MAAM,OAAO,UAAU,KAAK,MAAM,GAAG,MAAM,GAAG;CAC9C,MAAM,UAAU,KAAK,KAAK,SAAS;CACnC,MAAM,aACL,WAAW,UAAU,OAAO,QAAQ,aAAa;CAElD,MAAM,QAAS,MAAM,QAAQ,IAAI,KAAK,IAAI,OAAO,CAAC;AAIlD,QAAO;EACN;EACA,YAAY;GACX,OAAO,OAAO,MAAM;GACpB;GACA,QAAQ;EACR;CACD;AACD;;;;;AAMD,SAAgB,aAAaA,OAAwB;CACpD,MAAM,UAAU;EACf,GAAG,iBAAiB,OAAO,MAAM,aAAa,GAAG;EACjD,GAAG,iBAAiB,OAAO,gBAAgB;CAC3C;AACD,QAAO,OAAO,KAAK,KAAK,UAAU,QAAQ,CAAC,CAAC,SAAS,YAAY;AACjE;;;;AAKD,SAAgB,aAAaC,QAAyB;AACrD,KAAI;EACH,MAAM,OAAO,OAAO,KAAK,QAAQ,YAAY,CAAC,SAAS,QAAQ;EAC/D,MAAM,UAAU,KAAK,MAAM,KAAK;AAEhC,MAAI,QAAQ,MAAM,OACjB,QAAO,IAAI,KAAK,QAAQ;AAGzB,SAAO,QAAQ;CACf,QAAO;AACP,QAAM,IAAI,MAAM;CAChB;AACD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kysely-8WPSKCZG.cjs","names":["db: DatabaseConnection<DB>","cb: (trx: Transaction<DB>) => Promise<T>","settings?: TransactionSettings"],"sources":["../src/kysely.ts"],"sourcesContent":["import type {\n
|
|
1
|
+
{"version":3,"file":"kysely-8WPSKCZG.cjs","names":["db: DatabaseConnection<DB>","cb: (trx: Transaction<DB>) => Promise<T>","settings?: TransactionSettings"],"sources":["../src/kysely.ts"],"sourcesContent":["import type {\n\tControlledTransaction,\n\tIsolationLevel,\n\tKysely,\n\tTransaction,\n} from 'kysely';\n\nexport interface TransactionSettings {\n\tisolationLevel?: IsolationLevel;\n}\n\nexport function withTransaction<DB, T>(\n\tdb: DatabaseConnection<DB>,\n\tcb: (trx: Transaction<DB>) => Promise<T>,\n\tsettings?: TransactionSettings,\n): Promise<T> {\n\tif (db.isTransaction) {\n\t\treturn cb(db as Transaction<DB>);\n\t}\n\n\tconst builder = db.transaction();\n\n\tif (settings?.isolationLevel) {\n\t\treturn builder.setIsolationLevel(settings.isolationLevel).execute(cb);\n\t}\n\n\treturn builder.execute(cb);\n}\n\nexport type DatabaseConnection<T> =\n\t| ControlledTransaction<T>\n\t| Kysely<T>\n\t| Transaction<T>;\n"],"mappings":";;AAWA,SAAgB,gBACfA,IACAC,IACAC,UACa;AACb,KAAI,GAAG,cACN,QAAO,GAAG,GAAsB;CAGjC,MAAM,UAAU,GAAG,aAAa;AAEhC,KAAI,UAAU,eACb,QAAO,QAAQ,kBAAkB,SAAS,eAAe,CAAC,QAAQ,GAAG;AAGtE,QAAO,QAAQ,QAAQ,GAAG;AAC1B"}
|
|
@@ -6,6 +6,8 @@ interface TransactionSettings {
|
|
|
6
6
|
}
|
|
7
7
|
declare function withTransaction<DB, T>(db: DatabaseConnection<DB>, cb: (trx: Transaction<DB>) => Promise<T>, settings?: TransactionSettings): Promise<T>;
|
|
8
8
|
type DatabaseConnection<T> = ControlledTransaction<T> | Kysely<T> | Transaction<T>;
|
|
9
|
+
//# sourceMappingURL=kysely.d.ts.map
|
|
10
|
+
|
|
9
11
|
//#endregion
|
|
10
12
|
export { DatabaseConnection, TransactionSettings, withTransaction };
|
|
11
|
-
//# sourceMappingURL=kysely-
|
|
13
|
+
//# sourceMappingURL=kysely-D3eeuId4.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kysely-D3eeuId4.d.cts","names":[],"sources":["../src/kysely.ts"],"sourcesContent":[],"mappings":";;;UAOiB,mBAAA;mBACC;AADlB;AAIgB,iBAAA,eAAe,CAAA,EAAA,EAAA,CAAA,CAAA,CAAA,EAAA,EAC1B,kBAD0B,CACP,EADO,CAAA,EAAA,EAAA,EAAA,CAAA,GAAA,EAEpB,WAFoB,CAER,EAFQ,CAAA,EAAA,GAEA,OAFA,CAEQ,CAFR,CAAA,EAAA,QAAA,CAAA,EAGnB,mBAHmB,CAAA,EAI5B,OAJ4B,CAIpB,CAJoB,CAAA;AAAA,KAkBnB,kBAlBmB,CAAA,CAAA,CAAA,GAmB5B,qBAnB4B,CAmBN,CAnBM,CAAA,GAoB5B,MApB4B,CAoBrB,CApBqB,CAAA,GAqB5B,WArB4B,CAqBhB,CArBgB,CAAA"}
|
|
@@ -6,6 +6,8 @@ interface TransactionSettings {
|
|
|
6
6
|
}
|
|
7
7
|
declare function withTransaction<DB, T>(db: DatabaseConnection<DB>, cb: (trx: Transaction<DB>) => Promise<T>, settings?: TransactionSettings): Promise<T>;
|
|
8
8
|
type DatabaseConnection<T> = ControlledTransaction<T> | Kysely<T> | Transaction<T>;
|
|
9
|
+
//# sourceMappingURL=kysely.d.ts.map
|
|
10
|
+
|
|
9
11
|
//#endregion
|
|
10
12
|
export { DatabaseConnection, TransactionSettings, withTransaction };
|
|
11
|
-
//# sourceMappingURL=kysely-
|
|
13
|
+
//# sourceMappingURL=kysely-DUdsB0BP.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kysely-DUdsB0BP.d.mts","names":[],"sources":["../src/kysely.ts"],"sourcesContent":[],"mappings":";;;UAOiB,mBAAA;mBACC;AADlB;AAIgB,iBAAA,eAAe,CAAA,EAAA,EAAA,CAAA,CAAA,CAAA,EAAA,EAC1B,kBAD0B,CACP,EADO,CAAA,EAAA,EAAA,EAAA,CAAA,GAAA,EAEpB,WAFoB,CAER,EAFQ,CAAA,EAAA,GAEA,OAFA,CAEQ,CAFR,CAAA,EAAA,QAAA,CAAA,EAGnB,mBAHmB,CAAA,EAI5B,OAJ4B,CAIpB,CAJoB,CAAA;AAAA,KAkBnB,kBAlBmB,CAAA,CAAA,CAAA,GAmB5B,qBAnB4B,CAmBN,CAnBM,CAAA,GAoB5B,MApB4B,CAoBrB,CApBqB,CAAA,GAqB5B,WArB4B,CAqBhB,CArBgB,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kysely-DmfA94RY.mjs","names":["db: DatabaseConnection<DB>","cb: (trx: Transaction<DB>) => Promise<T>","settings?: TransactionSettings"],"sources":["../src/kysely.ts"],"sourcesContent":["import type {\n
|
|
1
|
+
{"version":3,"file":"kysely-DmfA94RY.mjs","names":["db: DatabaseConnection<DB>","cb: (trx: Transaction<DB>) => Promise<T>","settings?: TransactionSettings"],"sources":["../src/kysely.ts"],"sourcesContent":["import type {\n\tControlledTransaction,\n\tIsolationLevel,\n\tKysely,\n\tTransaction,\n} from 'kysely';\n\nexport interface TransactionSettings {\n\tisolationLevel?: IsolationLevel;\n}\n\nexport function withTransaction<DB, T>(\n\tdb: DatabaseConnection<DB>,\n\tcb: (trx: Transaction<DB>) => Promise<T>,\n\tsettings?: TransactionSettings,\n): Promise<T> {\n\tif (db.isTransaction) {\n\t\treturn cb(db as Transaction<DB>);\n\t}\n\n\tconst builder = db.transaction();\n\n\tif (settings?.isolationLevel) {\n\t\treturn builder.setIsolationLevel(settings.isolationLevel).execute(cb);\n\t}\n\n\treturn builder.execute(cb);\n}\n\nexport type DatabaseConnection<T> =\n\t| ControlledTransaction<T>\n\t| Kysely<T>\n\t| Transaction<T>;\n"],"mappings":";AAWA,SAAgB,gBACfA,IACAC,IACAC,UACa;AACb,KAAI,GAAG,cACN,QAAO,GAAG,GAAsB;CAGjC,MAAM,UAAU,GAAG,aAAa;AAEhC,KAAI,UAAU,eACb,QAAO,QAAQ,kBAAkB,SAAS,eAAe,CAAC,QAAQ,GAAG;AAGtE,QAAO,QAAQ,QAAQ,GAAG;AAC1B"}
|
package/dist/kysely.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { DatabaseConnection, TransactionSettings, withTransaction } from "./kysely-
|
|
1
|
+
import { DatabaseConnection, TransactionSettings, withTransaction } from "./kysely-D3eeuId4.cjs";
|
|
2
2
|
export { DatabaseConnection, TransactionSettings, withTransaction };
|
package/dist/kysely.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { DatabaseConnection, TransactionSettings, withTransaction } from "./kysely-
|
|
1
|
+
import { DatabaseConnection, TransactionSettings, withTransaction } from "./kysely-DUdsB0BP.mjs";
|
|
2
2
|
export { DatabaseConnection, TransactionSettings, withTransaction };
|
package/dist/rls.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rls.cjs","names":["db: DatabaseConnection<DB>","context: RlsContext","callback: (trx: Transaction<DB>) => Promise<T>","options?: WithRlsContextOptions"],"sources":["../src/rls.ts"],"sourcesContent":["import type { Transaction } from 'kysely';\nimport { sql } from 'kysely';\nimport {\n
|
|
1
|
+
{"version":3,"file":"rls.cjs","names":["db: DatabaseConnection<DB>","context: RlsContext","callback: (trx: Transaction<DB>) => Promise<T>","options?: WithRlsContextOptions"],"sources":["../src/rls.ts"],"sourcesContent":["import type { Transaction } from 'kysely';\nimport { sql } from 'kysely';\nimport {\n\ttype DatabaseConnection,\n\ttype TransactionSettings,\n\twithTransaction,\n} from './kysely';\n\n/**\n * RLS context - key-value pairs to set as PostgreSQL session variables.\n * Keys become `prefix.key` (e.g., `app.user_id`).\n */\nexport interface RlsContext {\n\t[key: string]: string | number | boolean | null | undefined;\n}\n\n/**\n * Options for withRlsContext function.\n */\nexport interface WithRlsContextOptions {\n\t/** Prefix for PostgreSQL session variables (default: 'app') */\n\tprefix?: string;\n\t/** Transaction settings (isolation level) */\n\tsettings?: TransactionSettings;\n}\n\n/**\n * Execute a callback within a transaction with RLS context variables set.\n *\n * Sets PostgreSQL session variables using `SET LOCAL` which scopes them to the\n * current transaction. Variables are automatically cleared when the transaction\n * ends (commit or rollback).\n *\n * @example\n * ```ts\n * await withRlsContext(\n * db,\n * { user_id: session.userId, tenant_id: session.tenantId },\n * async (trx) => {\n * // RLS policies can now use current_setting('app.user_id')\n * return trx.selectFrom('orders').selectAll().execute();\n * }\n * );\n * ```\n *\n * @param db - Database connection (Kysely, Transaction, or ControlledTransaction)\n * @param context - Key-value pairs to set as session variables\n * @param callback - Function to execute within the RLS context\n * @param options - Optional prefix and transaction settings\n */\nexport async function withRlsContext<DB, T>(\n\tdb: DatabaseConnection<DB>,\n\tcontext: RlsContext,\n\tcallback: (trx: Transaction<DB>) => Promise<T>,\n\toptions?: WithRlsContextOptions,\n): Promise<T> {\n\tconst prefix = options?.prefix ?? 'app';\n\n\treturn withTransaction(\n\t\tdb,\n\t\tasync (trx) => {\n\t\t\t// Set each context variable using SET LOCAL (scoped to transaction)\n\t\t\tfor (const [key, value] of Object.entries(context)) {\n\t\t\t\tif (value === null || value === undefined) continue;\n\n\t\t\t\tconst settingName = `${prefix}.${key}`;\n\t\t\t\tconst settingValue = String(value);\n\n\t\t\t\t// Use raw SQL for SET LOCAL with proper escaping\n\t\t\t\t// The setting name is an identifier, value is a string literal\n\t\t\t\tawait sql`SELECT set_config(${settingName}, ${settingValue}, true)`.execute(\n\t\t\t\t\ttrx,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn callback(trx);\n\t\t},\n\t\toptions?.settings,\n\t);\n}\n\n/**\n * Bypass marker symbol for explicitly skipping RLS context.\n */\nexport const RLS_BYPASS = Symbol.for('geekmidas.rls.bypass');\n\n/**\n * Type for RLS bypass marker.\n */\nexport type RlsBypass = typeof RLS_BYPASS;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkDA,eAAsB,eACrBA,IACAC,SACAC,UACAC,SACa;CACb,MAAM,SAAS,SAAS,UAAU;AAElC,QAAO,+BACN,IACA,OAAO,QAAQ;AAEd,OAAK,MAAM,CAAC,KAAK,MAAM,IAAI,OAAO,QAAQ,QAAQ,EAAE;AACnD,OAAI,UAAU,QAAQ,iBAAqB;GAE3C,MAAM,eAAe,EAAE,OAAO,GAAG,IAAI;GACrC,MAAM,eAAe,OAAO,MAAM;AAIlC,SAAM,WAAI,oBAAoB,YAAY,IAAI,aAAa,SAAS,QACnE,IACA;EACD;AAED,SAAO,SAAS,IAAI;CACpB,GACD,SAAS,SACT;AACD;;;;AAKD,MAAa,aAAa,OAAO,IAAI,uBAAuB"}
|
package/dist/rls.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DatabaseConnection, TransactionSettings } from "./kysely-
|
|
1
|
+
import { DatabaseConnection, TransactionSettings } from "./kysely-D3eeuId4.cjs";
|
|
2
2
|
import { Transaction } from "kysely";
|
|
3
3
|
|
|
4
4
|
//#region src/rls.d.ts
|
|
@@ -52,6 +52,7 @@ declare const RLS_BYPASS: unique symbol;
|
|
|
52
52
|
* Type for RLS bypass marker.
|
|
53
53
|
*/
|
|
54
54
|
type RlsBypass = typeof RLS_BYPASS;
|
|
55
|
+
//# sourceMappingURL=rls.d.ts.map
|
|
55
56
|
//#endregion
|
|
56
57
|
export { RLS_BYPASS, RlsBypass, RlsContext, WithRlsContextOptions, withRlsContext };
|
|
57
58
|
//# sourceMappingURL=rls.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rls.d.cts","names":[],"sources":["../src/rls.ts"],"sourcesContent":[],"mappings":";;;;;;;AAYA;AAOA;AA+BsB,UAtCL,UAAA,CAsCmB;EAAA,CAAA,GAAA,EAAA,MAAA,CAAA,EAAA,MAAA,GAAA,MAAA,GAAA,OAAA,GAAA,IAAA,GAAA,SAAA;;;;;AAGnB,UAlCA,qBAAA,CAkCA;EAAW;EAAkB,MAAT,CAAA,EAAA,MAAA;EAAO;EACZ,QACrB,CAAA,EAhCC,mBAgCD;;AAAD;AA6BV;AAKA;;;;;;;;;;;;;;;;;;;;;;iBAvCsB,0BACjB,mBAAmB,cACd,4BACO,YAAY,QAAQ,QAAQ,cAClC,wBACR,QAAQ;;;;cA6BE;;;;KAKD,SAAA,UAAmB"}
|
package/dist/rls.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DatabaseConnection, TransactionSettings } from "./kysely-
|
|
1
|
+
import { DatabaseConnection, TransactionSettings } from "./kysely-DUdsB0BP.mjs";
|
|
2
2
|
import { Transaction } from "kysely";
|
|
3
3
|
|
|
4
4
|
//#region src/rls.d.ts
|
|
@@ -52,6 +52,7 @@ declare const RLS_BYPASS: unique symbol;
|
|
|
52
52
|
* Type for RLS bypass marker.
|
|
53
53
|
*/
|
|
54
54
|
type RlsBypass = typeof RLS_BYPASS;
|
|
55
|
+
//# sourceMappingURL=rls.d.ts.map
|
|
55
56
|
//#endregion
|
|
56
57
|
export { RLS_BYPASS, RlsBypass, RlsContext, WithRlsContextOptions, withRlsContext };
|
|
57
58
|
//# sourceMappingURL=rls.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rls.d.mts","names":[],"sources":["../src/rls.ts"],"sourcesContent":[],"mappings":";;;;;;;AAYA;AAOA;AA+BsB,UAtCL,UAAA,CAsCmB;EAAA,CAAA,GAAA,EAAA,MAAA,CAAA,EAAA,MAAA,GAAA,MAAA,GAAA,OAAA,GAAA,IAAA,GAAA,SAAA;;;;;AAGnB,UAlCA,qBAAA,CAkCA;EAAW;EAAkB,MAAT,CAAA,EAAA,MAAA;EAAO;EACZ,QACrB,CAAA,EAhCC,mBAgCD;;AAAD;AA6BV;AAKA;;;;;;;;;;;;;;;;;;;;;;iBAvCsB,0BACjB,mBAAmB,cACd,4BACO,YAAY,QAAQ,QAAQ,cAClC,wBACR,QAAQ;;;;cA6BE;;;;KAKD,SAAA,UAAmB"}
|
package/dist/rls.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rls.mjs","names":["db: DatabaseConnection<DB>","context: RlsContext","callback: (trx: Transaction<DB>) => Promise<T>","options?: WithRlsContextOptions"],"sources":["../src/rls.ts"],"sourcesContent":["import type { Transaction } from 'kysely';\nimport { sql } from 'kysely';\nimport {\n
|
|
1
|
+
{"version":3,"file":"rls.mjs","names":["db: DatabaseConnection<DB>","context: RlsContext","callback: (trx: Transaction<DB>) => Promise<T>","options?: WithRlsContextOptions"],"sources":["../src/rls.ts"],"sourcesContent":["import type { Transaction } from 'kysely';\nimport { sql } from 'kysely';\nimport {\n\ttype DatabaseConnection,\n\ttype TransactionSettings,\n\twithTransaction,\n} from './kysely';\n\n/**\n * RLS context - key-value pairs to set as PostgreSQL session variables.\n * Keys become `prefix.key` (e.g., `app.user_id`).\n */\nexport interface RlsContext {\n\t[key: string]: string | number | boolean | null | undefined;\n}\n\n/**\n * Options for withRlsContext function.\n */\nexport interface WithRlsContextOptions {\n\t/** Prefix for PostgreSQL session variables (default: 'app') */\n\tprefix?: string;\n\t/** Transaction settings (isolation level) */\n\tsettings?: TransactionSettings;\n}\n\n/**\n * Execute a callback within a transaction with RLS context variables set.\n *\n * Sets PostgreSQL session variables using `SET LOCAL` which scopes them to the\n * current transaction. Variables are automatically cleared when the transaction\n * ends (commit or rollback).\n *\n * @example\n * ```ts\n * await withRlsContext(\n * db,\n * { user_id: session.userId, tenant_id: session.tenantId },\n * async (trx) => {\n * // RLS policies can now use current_setting('app.user_id')\n * return trx.selectFrom('orders').selectAll().execute();\n * }\n * );\n * ```\n *\n * @param db - Database connection (Kysely, Transaction, or ControlledTransaction)\n * @param context - Key-value pairs to set as session variables\n * @param callback - Function to execute within the RLS context\n * @param options - Optional prefix and transaction settings\n */\nexport async function withRlsContext<DB, T>(\n\tdb: DatabaseConnection<DB>,\n\tcontext: RlsContext,\n\tcallback: (trx: Transaction<DB>) => Promise<T>,\n\toptions?: WithRlsContextOptions,\n): Promise<T> {\n\tconst prefix = options?.prefix ?? 'app';\n\n\treturn withTransaction(\n\t\tdb,\n\t\tasync (trx) => {\n\t\t\t// Set each context variable using SET LOCAL (scoped to transaction)\n\t\t\tfor (const [key, value] of Object.entries(context)) {\n\t\t\t\tif (value === null || value === undefined) continue;\n\n\t\t\t\tconst settingName = `${prefix}.${key}`;\n\t\t\t\tconst settingValue = String(value);\n\n\t\t\t\t// Use raw SQL for SET LOCAL with proper escaping\n\t\t\t\t// The setting name is an identifier, value is a string literal\n\t\t\t\tawait sql`SELECT set_config(${settingName}, ${settingValue}, true)`.execute(\n\t\t\t\t\ttrx,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn callback(trx);\n\t\t},\n\t\toptions?.settings,\n\t);\n}\n\n/**\n * Bypass marker symbol for explicitly skipping RLS context.\n */\nexport const RLS_BYPASS = Symbol.for('geekmidas.rls.bypass');\n\n/**\n * Type for RLS bypass marker.\n */\nexport type RlsBypass = typeof RLS_BYPASS;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkDA,eAAsB,eACrBA,IACAC,SACAC,UACAC,SACa;CACb,MAAM,SAAS,SAAS,UAAU;AAElC,QAAO,gBACN,IACA,OAAO,QAAQ;AAEd,OAAK,MAAM,CAAC,KAAK,MAAM,IAAI,OAAO,QAAQ,QAAQ,EAAE;AACnD,OAAI,UAAU,QAAQ,iBAAqB;GAE3C,MAAM,eAAe,EAAE,OAAO,GAAG,IAAI;GACrC,MAAM,eAAe,OAAO,MAAM;AAIlC,SAAM,IAAI,oBAAoB,YAAY,IAAI,aAAa,SAAS,QACnE,IACA;EACD;AAED,SAAO,SAAS,IAAI;CACpB,GACD,SAAS,SACT;AACD;;;;AAKD,MAAa,aAAa,OAAO,IAAI,uBAAuB"}
|