@geekmidas/db 0.0.3 → 0.1.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/README.md +495 -0
- package/dist/kysely-0FOi6ZdO.d.cts +11 -0
- package/dist/kysely-8WPSKCZG.cjs +17 -0
- package/dist/kysely-8WPSKCZG.cjs.map +1 -0
- package/dist/kysely-Di1LVvL2.d.mts +11 -0
- package/dist/kysely-DmfA94RY.mjs +11 -0
- package/dist/kysely-DmfA94RY.mjs.map +1 -0
- package/dist/kysely.cjs +2 -8
- package/dist/kysely.d.cts +2 -7
- package/dist/kysely.d.mts +2 -7
- package/dist/kysely.mjs +1 -6
- package/dist/rls.cjs +72 -0
- package/dist/rls.cjs.map +1 -0
- package/dist/rls.d.cts +57 -0
- package/dist/rls.d.mts +57 -0
- package/dist/rls.mjs +48 -0
- package/dist/rls.mjs.map +1 -0
- package/package.json +13 -1
- package/src/__tests__/kysely.integration.spec.ts +741 -0
- package/src/__tests__/kysely.spec.ts +394 -0
- package/src/__tests__/rls.spec.ts +444 -0
- package/src/kysely.ts +20 -4
- package/src/rls.ts +90 -0
package/dist/rls.d.cts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { DatabaseConnection, TransactionSettings } from "./kysely-0FOi6ZdO.cjs";
|
|
2
|
+
import { Transaction } from "kysely";
|
|
3
|
+
|
|
4
|
+
//#region src/rls.d.ts
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* RLS context - key-value pairs to set as PostgreSQL session variables.
|
|
8
|
+
* Keys become `prefix.key` (e.g., `app.user_id`).
|
|
9
|
+
*/
|
|
10
|
+
interface RlsContext {
|
|
11
|
+
[key: string]: string | number | boolean | null | undefined;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Options for withRlsContext function.
|
|
15
|
+
*/
|
|
16
|
+
interface WithRlsContextOptions {
|
|
17
|
+
/** Prefix for PostgreSQL session variables (default: 'app') */
|
|
18
|
+
prefix?: string;
|
|
19
|
+
/** Transaction settings (isolation level) */
|
|
20
|
+
settings?: TransactionSettings;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Execute a callback within a transaction with RLS context variables set.
|
|
24
|
+
*
|
|
25
|
+
* Sets PostgreSQL session variables using `SET LOCAL` which scopes them to the
|
|
26
|
+
* current transaction. Variables are automatically cleared when the transaction
|
|
27
|
+
* ends (commit or rollback).
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```ts
|
|
31
|
+
* await withRlsContext(
|
|
32
|
+
* db,
|
|
33
|
+
* { user_id: session.userId, tenant_id: session.tenantId },
|
|
34
|
+
* async (trx) => {
|
|
35
|
+
* // RLS policies can now use current_setting('app.user_id')
|
|
36
|
+
* return trx.selectFrom('orders').selectAll().execute();
|
|
37
|
+
* }
|
|
38
|
+
* );
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* @param db - Database connection (Kysely, Transaction, or ControlledTransaction)
|
|
42
|
+
* @param context - Key-value pairs to set as session variables
|
|
43
|
+
* @param callback - Function to execute within the RLS context
|
|
44
|
+
* @param options - Optional prefix and transaction settings
|
|
45
|
+
*/
|
|
46
|
+
declare function withRlsContext<DB, T>(db: DatabaseConnection<DB>, context: RlsContext, callback: (trx: Transaction<DB>) => Promise<T>, options?: WithRlsContextOptions): Promise<T>;
|
|
47
|
+
/**
|
|
48
|
+
* Bypass marker symbol for explicitly skipping RLS context.
|
|
49
|
+
*/
|
|
50
|
+
declare const RLS_BYPASS: unique symbol;
|
|
51
|
+
/**
|
|
52
|
+
* Type for RLS bypass marker.
|
|
53
|
+
*/
|
|
54
|
+
type RlsBypass = typeof RLS_BYPASS;
|
|
55
|
+
//#endregion
|
|
56
|
+
export { RLS_BYPASS, RlsBypass, RlsContext, WithRlsContextOptions, withRlsContext };
|
|
57
|
+
//# sourceMappingURL=rls.d.cts.map
|
package/dist/rls.d.mts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { DatabaseConnection, TransactionSettings } from "./kysely-Di1LVvL2.mjs";
|
|
2
|
+
import { Transaction } from "kysely";
|
|
3
|
+
|
|
4
|
+
//#region src/rls.d.ts
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* RLS context - key-value pairs to set as PostgreSQL session variables.
|
|
8
|
+
* Keys become `prefix.key` (e.g., `app.user_id`).
|
|
9
|
+
*/
|
|
10
|
+
interface RlsContext {
|
|
11
|
+
[key: string]: string | number | boolean | null | undefined;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Options for withRlsContext function.
|
|
15
|
+
*/
|
|
16
|
+
interface WithRlsContextOptions {
|
|
17
|
+
/** Prefix for PostgreSQL session variables (default: 'app') */
|
|
18
|
+
prefix?: string;
|
|
19
|
+
/** Transaction settings (isolation level) */
|
|
20
|
+
settings?: TransactionSettings;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Execute a callback within a transaction with RLS context variables set.
|
|
24
|
+
*
|
|
25
|
+
* Sets PostgreSQL session variables using `SET LOCAL` which scopes them to the
|
|
26
|
+
* current transaction. Variables are automatically cleared when the transaction
|
|
27
|
+
* ends (commit or rollback).
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```ts
|
|
31
|
+
* await withRlsContext(
|
|
32
|
+
* db,
|
|
33
|
+
* { user_id: session.userId, tenant_id: session.tenantId },
|
|
34
|
+
* async (trx) => {
|
|
35
|
+
* // RLS policies can now use current_setting('app.user_id')
|
|
36
|
+
* return trx.selectFrom('orders').selectAll().execute();
|
|
37
|
+
* }
|
|
38
|
+
* );
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* @param db - Database connection (Kysely, Transaction, or ControlledTransaction)
|
|
42
|
+
* @param context - Key-value pairs to set as session variables
|
|
43
|
+
* @param callback - Function to execute within the RLS context
|
|
44
|
+
* @param options - Optional prefix and transaction settings
|
|
45
|
+
*/
|
|
46
|
+
declare function withRlsContext<DB, T>(db: DatabaseConnection<DB>, context: RlsContext, callback: (trx: Transaction<DB>) => Promise<T>, options?: WithRlsContextOptions): Promise<T>;
|
|
47
|
+
/**
|
|
48
|
+
* Bypass marker symbol for explicitly skipping RLS context.
|
|
49
|
+
*/
|
|
50
|
+
declare const RLS_BYPASS: unique symbol;
|
|
51
|
+
/**
|
|
52
|
+
* Type for RLS bypass marker.
|
|
53
|
+
*/
|
|
54
|
+
type RlsBypass = typeof RLS_BYPASS;
|
|
55
|
+
//#endregion
|
|
56
|
+
export { RLS_BYPASS, RlsBypass, RlsContext, WithRlsContextOptions, withRlsContext };
|
|
57
|
+
//# sourceMappingURL=rls.d.mts.map
|
package/dist/rls.mjs
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { withTransaction } from "./kysely-DmfA94RY.mjs";
|
|
2
|
+
import { sql } from "kysely";
|
|
3
|
+
|
|
4
|
+
//#region src/rls.ts
|
|
5
|
+
/**
|
|
6
|
+
* Execute a callback within a transaction with RLS context variables set.
|
|
7
|
+
*
|
|
8
|
+
* Sets PostgreSQL session variables using `SET LOCAL` which scopes them to the
|
|
9
|
+
* current transaction. Variables are automatically cleared when the transaction
|
|
10
|
+
* ends (commit or rollback).
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* await withRlsContext(
|
|
15
|
+
* db,
|
|
16
|
+
* { user_id: session.userId, tenant_id: session.tenantId },
|
|
17
|
+
* async (trx) => {
|
|
18
|
+
* // RLS policies can now use current_setting('app.user_id')
|
|
19
|
+
* return trx.selectFrom('orders').selectAll().execute();
|
|
20
|
+
* }
|
|
21
|
+
* );
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* @param db - Database connection (Kysely, Transaction, or ControlledTransaction)
|
|
25
|
+
* @param context - Key-value pairs to set as session variables
|
|
26
|
+
* @param callback - Function to execute within the RLS context
|
|
27
|
+
* @param options - Optional prefix and transaction settings
|
|
28
|
+
*/
|
|
29
|
+
async function withRlsContext(db, context, callback, options) {
|
|
30
|
+
const prefix = options?.prefix ?? "app";
|
|
31
|
+
return withTransaction(db, async (trx) => {
|
|
32
|
+
for (const [key, value] of Object.entries(context)) {
|
|
33
|
+
if (value === null || value === void 0) continue;
|
|
34
|
+
const settingName = `${prefix}.${key}`;
|
|
35
|
+
const settingValue = String(value);
|
|
36
|
+
await sql`SELECT set_config(${settingName}, ${settingValue}, true)`.execute(trx);
|
|
37
|
+
}
|
|
38
|
+
return callback(trx);
|
|
39
|
+
}, options?.settings);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Bypass marker symbol for explicitly skipping RLS context.
|
|
43
|
+
*/
|
|
44
|
+
const RLS_BYPASS = Symbol.for("geekmidas.rls.bypass");
|
|
45
|
+
|
|
46
|
+
//#endregion
|
|
47
|
+
export { RLS_BYPASS, withRlsContext };
|
|
48
|
+
//# sourceMappingURL=rls.mjs.map
|
package/dist/rls.mjs.map
ADDED
|
@@ -0,0 +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 type DatabaseConnection,\n type TransactionSettings,\n withTransaction,\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 [key: string]: string | number | boolean | null | undefined;\n}\n\n/**\n * Options for withRlsContext function.\n */\nexport interface WithRlsContextOptions {\n /** Prefix for PostgreSQL session variables (default: 'app') */\n prefix?: string;\n /** Transaction settings (isolation level) */\n settings?: 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 db: DatabaseConnection<DB>,\n context: RlsContext,\n callback: (trx: Transaction<DB>) => Promise<T>,\n options?: WithRlsContextOptions,\n): Promise<T> {\n const prefix = options?.prefix ?? 'app';\n\n return withTransaction(\n db,\n async (trx) => {\n // Set each context variable using SET LOCAL (scoped to transaction)\n for (const [key, value] of Object.entries(context)) {\n if (value === null || value === undefined) continue;\n\n const settingName = `${prefix}.${key}`;\n const settingValue = String(value);\n\n // Use raw SQL for SET LOCAL with proper escaping\n // The setting name is an identifier, value is a string literal\n await sql`SELECT set_config(${settingName}, ${settingValue}, true)`.execute(\n trx,\n );\n }\n\n return callback(trx);\n },\n options?.settings,\n );\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,eACpBA,IACAC,SACAC,UACAC,SACY;CACZ,MAAM,SAAS,SAAS,UAAU;AAElC,QAAO,gBACL,IACA,OAAO,QAAQ;AAEb,OAAK,MAAM,CAAC,KAAK,MAAM,IAAI,OAAO,QAAQ,QAAQ,EAAE;AAClD,OAAI,UAAU,QAAQ,iBAAqB;GAE3C,MAAM,eAAe,EAAE,OAAO,GAAG,IAAI;GACrC,MAAM,eAAe,OAAO,MAAM;AAIlC,SAAM,IAAI,oBAAoB,YAAY,IAAI,aAAa,SAAS,QAClE,IACD;EACF;AAED,SAAO,SAAS,IAAI;CACrB,GACD,SAAS,SACV;AACF;;;;AAKD,MAAa,aAAa,OAAO,IAAI,uBAAuB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@geekmidas/db",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -8,6 +8,11 @@
|
|
|
8
8
|
"types": "./dist/kysely.d.ts",
|
|
9
9
|
"import": "./dist/kysely.mjs",
|
|
10
10
|
"require": "./dist/kysely.cjs"
|
|
11
|
+
},
|
|
12
|
+
"./rls": {
|
|
13
|
+
"types": "./dist/rls.d.ts",
|
|
14
|
+
"import": "./dist/rls.mjs",
|
|
15
|
+
"require": "./dist/rls.cjs"
|
|
11
16
|
}
|
|
12
17
|
},
|
|
13
18
|
"dependencies": {
|
|
@@ -16,6 +21,10 @@
|
|
|
16
21
|
"devDependencies": {
|
|
17
22
|
"@types/pg": "~8.15.4"
|
|
18
23
|
},
|
|
24
|
+
"repository": {
|
|
25
|
+
"type": "git",
|
|
26
|
+
"url": "https://github.com/geekmidas/toolbox"
|
|
27
|
+
},
|
|
19
28
|
"publishConfig": {
|
|
20
29
|
"registry": "https://registry.npmjs.org/",
|
|
21
30
|
"access": "public"
|
|
@@ -27,5 +36,8 @@
|
|
|
27
36
|
"objection": "~3.1.5",
|
|
28
37
|
"db-errors": "~0.2.3",
|
|
29
38
|
"vitest": "~3.2.4"
|
|
39
|
+
},
|
|
40
|
+
"scripts": {
|
|
41
|
+
"ts": "tsc --noEmit --skipLibCheck src/**/*.ts"
|
|
30
42
|
}
|
|
31
43
|
}
|