@elysiumjs/drizzle 0.0.0-stage → 0.1.1

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.
@@ -0,0 +1,105 @@
1
+ import type { TenancyStrategy } from '@elysiumjs/olympus/mnemosyne';
2
+ import type { AnyPgColumnBuilder, PgAsyncTransaction, PgSchema, PgTable } from 'drizzle-orm/pg-core';
3
+ import type { DrizzleConnection } from './database';
4
+ /**
5
+ * Returns the Drizzle `PgSchema` for the given tenant, creating it if needed.
6
+ * @author Axel Nana <ax.lnana@outlook.com>
7
+ * @param tenant The tenant identifier.
8
+ * @returns The tenant's PostgreSQL schema.
9
+ * @throws {Error} If the tenant identifier is malformed.
10
+ */
11
+ export declare const getTenantSchema: (tenant: string) => PgSchema;
12
+ /**
13
+ * Registers a new tenant schema in the registry.
14
+ * @author Axel Nana <ax.lnana@outlook.com>
15
+ * @param tenant The tenant identifier.
16
+ * @returns The newly registered (or existing) `PgSchema`.
17
+ * @throws {Error} If the tenant identifier is malformed.
18
+ */
19
+ export declare const registerTenantSchema: (tenant: string) => PgSchema;
20
+ /**
21
+ * Wraps a table definition in a tenant-specific schema.
22
+ *
23
+ * For the `'public'` tenant, returns a standard `pgTable`.
24
+ * For other tenants, creates a schema-qualified table and caches it.
25
+ *
26
+ * @author Axel Nana <ax.lnana@outlook.com>
27
+ * @param tenant The tenant identifier.
28
+ * @param tableName The table name.
29
+ * @param columns The column definitions.
30
+ * @returns A tenant-scoped `PgTable`.
31
+ * @throws {Error} If the tenant identifier is malformed.
32
+ */
33
+ export declare const wrapTenantSchema: <TTableName extends string, TColumnsMap extends Record<string, AnyPgColumnBuilder>>(tenant: string, tableName: TTableName, columns: TColumnsMap) => PgTable;
34
+ /**
35
+ * Executes a callback within an RLS-scoped transaction for the given tenant.
36
+ *
37
+ * The transaction is registered in the async context, so repositories and
38
+ * `Database.getConnection()` use it inside the callback. When a transaction is already open on the
39
+ * connection, the callback joins it if it is bound to the same tenant. Work for several tenants
40
+ * (such as an admin fan-out) must use one `withRLS()` per tenant, outside any transaction.
41
+ * @author Axel Nana <ax.lnana@outlook.com>
42
+ * @param tenant The tenant identifier (or `null` for 'public').
43
+ * @param callback The function to execute within the transaction.
44
+ * @param connectionName The database connection name.
45
+ * @returns The return value of the callback.
46
+ * @throws {TenantMismatchError} If the open transaction is bound to another tenant.
47
+ */
48
+ export declare const withRLS: <T>(tenant: string | null, callback: (tx: PgAsyncTransaction<any, any>) => Promise<T>, connectionName?: string) => Promise<T>;
49
+ /**
50
+ * Reads the current tenant from the PostgreSQL tenant variable, on the open transaction when
51
+ * there is one.
52
+ * @author Axel Nana <ax.lnana@outlook.com>
53
+ * @param connectionName The database connection name.
54
+ * @returns The current tenant identifier, or `null`.
55
+ */
56
+ export declare const getSessionTenant: (connectionName?: string) => Promise<string | null>;
57
+ /**
58
+ * Creates an RLS policy for tenant isolation on a table.
59
+ * @author Axel Nana <ax.lnana@outlook.com>
60
+ * @param tableName The table name.
61
+ * @param columnName The tenant column name (defaults to config or 'tenant_id').
62
+ * @param policyName The policy name (defaults to `{tableName}_tenant_isolation`).
63
+ * @returns A Drizzle `PgPolicy` instance.
64
+ */
65
+ export declare const createRLSPolicy: (tableName: string, columnName?: string, policyName?: string) => import("drizzle-orm/pg-core").PgPolicy;
66
+ /**
67
+ * Schema-based tenancy strategy for Drizzle.
68
+ *
69
+ * Each tenant gets its own PostgreSQL schema. Table resolution maps
70
+ * the base table to a schema-qualified equivalent.
71
+ *
72
+ * @author Axel Nana <ax.lnana@outlook.com>
73
+ */
74
+ export declare class DrizzleSchemaTenancy implements TenancyStrategy<PgTable, DrizzleConnection> {
75
+ readonly mode = "schema";
76
+ resolveTable(table: PgTable, tenant: string): PgTable;
77
+ withIsolation<T>(_connection: DrizzleConnection, _tenant: string, callback: () => Promise<T>): Promise<T>;
78
+ }
79
+ /**
80
+ * Row-Level Security tenancy strategy for Drizzle.
81
+ *
82
+ * All tenants share the same schema. Isolation is achieved via
83
+ * PostgreSQL RLS policies and a session variable set in each transaction.
84
+ *
85
+ * @author Axel Nana <ax.lnana@outlook.com>
86
+ */
87
+ export declare class DrizzleRLSTenancy implements TenancyStrategy<PgTable, DrizzleConnection> {
88
+ readonly mode = "rls";
89
+ resolveTable(table: PgTable, _tenant: string): PgTable;
90
+ /**
91
+ * Runs a callback in a transaction scoped to the given tenant.
92
+ *
93
+ * The transaction is bound to the tenant for its whole life, registered in the async context
94
+ * for the connection, and the tenant set as the current tenant, for the duration of the
95
+ * callback. When a transaction is already open on the connection, the callback joins it, which
96
+ * is only allowed when that transaction is bound to the same tenant.
97
+ * @author Axel Nana <ax.lnana@outlook.com>
98
+ * @param connection The base connection (see `Database.getBaseConnection`).
99
+ * @param tenant The tenant identifier.
100
+ * @param callback The function to execute within the isolated context.
101
+ * @returns The return value of the callback.
102
+ * @throws {TenantMismatchError} If the open transaction is bound to another tenant.
103
+ */
104
+ withIsolation<T>(connection: DrizzleConnection, tenant: string, callback: () => Promise<T>): Promise<T>;
105
+ }
package/package.json CHANGED
@@ -1,6 +1,103 @@
1
1
  {
2
- "name": "@elysiumjs/drizzle",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
2
+ "name": "@elysiumjs/drizzle",
3
+ "version": "0.1.1",
4
+ "license": "Apache-2.0",
5
+ "description": "Drizzle ORM backend for the Elysium.js framework: database drivers, models, repositories, queries, migrations, tenancy, the moirai stores, the notification and file stores, abilities as SQL, and the postgres lock.",
6
+ "private": false,
7
+ "author": "Axel Nana <ax.lnana@outlook.com>",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/na2axl/elysiumjs.git",
11
+ "directory": "@elysiumjs/drizzle"
12
+ },
13
+ "homepage": "https://github.com/na2axl/elysiumjs/tree/main/@elysiumjs/drizzle#readme",
14
+ "bugs": {
15
+ "url": "https://github.com/na2axl/elysiumjs/issues"
16
+ },
17
+ "scripts": {
18
+ "format": "prettier --write \"./src/**/*.ts\"",
19
+ "clean": "rimraf dist",
20
+ "build": "bun run clean && bun run build:js && bun run build:ts",
21
+ "typecheck": "tsc --noEmit && tsc -p tsconfig.types.json",
22
+ "prepublishOnly": "bun run build",
23
+ "test": "bun test",
24
+ "test:coverage": "bun test --coverage",
25
+ "build:js": "bun build ./src/index.ts ./src/drivers/bun-sql.ts ./src/drivers/postgres-js.ts ./src/drivers/node-postgres.ts ./src/drivers/hyperdrive.ts --outdir ./dist --target node --packages external --root ./src --minify-syntax --minify-whitespace",
26
+ "build:ts": "tsc --emitDeclarationOnly"
27
+ },
28
+ "keywords": [
29
+ "elysium",
30
+ "database",
31
+ "orm",
32
+ "drizzle",
33
+ "postgresql"
34
+ ],
35
+ "module": "dist/index.js",
36
+ "type": "module",
37
+ "types": "dist/index.d.ts",
38
+ "exports": {
39
+ ".": {
40
+ "types": "./dist/index.d.ts",
41
+ "import": "./dist/index.js"
42
+ },
43
+ "./bun-sql": {
44
+ "types": "./dist/drivers/bun-sql.d.ts",
45
+ "import": "./dist/drivers/bun-sql.js"
46
+ },
47
+ "./postgres-js": {
48
+ "types": "./dist/drivers/postgres-js.d.ts",
49
+ "import": "./dist/drivers/postgres-js.js"
50
+ },
51
+ "./node-postgres": {
52
+ "types": "./dist/drivers/node-postgres.d.ts",
53
+ "import": "./dist/drivers/node-postgres.js"
54
+ },
55
+ "./hyperdrive": {
56
+ "types": "./dist/drivers/hyperdrive.d.ts",
57
+ "import": "./dist/drivers/hyperdrive.js"
58
+ }
59
+ },
60
+ "files": [
61
+ "dist",
62
+ "CHANGELOG.md"
63
+ ],
64
+ "sideEffects": [
65
+ "./dist/index.js",
66
+ "./src/index.ts",
67
+ "./src/lock.ts",
68
+ "./src/hermes.ts",
69
+ "./src/pithos.ts"
70
+ ],
71
+ "peerDependencies": {
72
+ "@elysiumjs/olympus": "^0.25.0",
73
+ "@elysiumjs/workers": "^0.1.0",
74
+ "pg": "^8.0.0",
75
+ "postgres": "^3.4.0"
76
+ },
77
+ "dependencies": {
78
+ "@casl/ability": "^7.0.2",
79
+ "drizzle-orm": "^1.0.0-rc.5",
80
+ "prompts": "^2.4.2",
81
+ "radash": "^12.1.1"
82
+ },
83
+ "devDependencies": {
84
+ "@elysiumjs/olympus": "0.25.0",
85
+ "@elysiumjs/bun": "0.1.0",
86
+ "@elysiumjs/workers": "0.1.0",
87
+ "@types/pg": "8.15.5",
88
+ "@types/prompts": "^2.4.9",
89
+ "pg": "8.16.3",
90
+ "postgres": "3.4.7"
91
+ },
92
+ "peerDependenciesMeta": {
93
+ "@elysiumjs/workers": {
94
+ "optional": true
95
+ },
96
+ "pg": {
97
+ "optional": true
98
+ },
99
+ "postgres": {
100
+ "optional": true
101
+ }
102
+ }
103
+ }