uql-orm 0.32.1 → 0.33.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/dist/express/querierMiddleware.d.ts +1 -1
- package/dist/express/querierMiddleware.js +1 -1
- package/dist/http/fetchHandler.d.ts +1 -1
- package/dist/http/fetchHandler.js +1 -1
- package/dist/http/handler.d.ts +8 -2
- package/dist/http/handler.js +9 -7
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/nestjs/uqlModule.d.ts +3 -2
- package/dist/nestjs/uqlModule.js +4 -9
- package/package.json +1 -2
- package/dist/options.d.ts +0 -4
- package/dist/options.js +0 -13
|
@@ -7,5 +7,5 @@ export type MiddlewareOptions = RequestHandlerOptions<Request>;
|
|
|
7
7
|
* composes with custom routes; errors go to `next(err)` so user error
|
|
8
8
|
* middleware (e.g. {@link errorHandler}) keeps working.
|
|
9
9
|
*/
|
|
10
|
-
export declare function querierMiddleware(opts
|
|
10
|
+
export declare function querierMiddleware(opts: MiddlewareOptions): Router;
|
|
11
11
|
export declare function errorHandler(err: unknown, _req: Request, res: Response, _next: NextFunction): void;
|
|
@@ -7,7 +7,7 @@ import { createRequestHandler } from '../http/handler.js';
|
|
|
7
7
|
* composes with custom routes; errors go to `next(err)` so user error
|
|
8
8
|
* middleware (e.g. {@link errorHandler}) keeps working.
|
|
9
9
|
*/
|
|
10
|
-
export function querierMiddleware(opts
|
|
10
|
+
export function querierMiddleware(opts) {
|
|
11
11
|
const handle = createRequestHandler(opts);
|
|
12
12
|
const router = expressRouter();
|
|
13
13
|
router.all('/:entityPath{/:subPath}', async (req, res, next) => {
|
|
@@ -10,4 +10,4 @@ export type FetchHandlerOptions = RequestHandlerOptions<Request> & {
|
|
|
10
10
|
* `(request: Request) => Promise<Response>` in any fetch-native runtime
|
|
11
11
|
* (Hono, Next.js route handlers, Bun.serve, Deno.serve, Cloudflare Workers, SvelteKit).
|
|
12
12
|
*/
|
|
13
|
-
export declare function createFetchHandler(opts
|
|
13
|
+
export declare function createFetchHandler(opts: FetchHandlerOptions): (request: Request) => Promise<Response>;
|
|
@@ -5,7 +5,7 @@ import { createRequestHandler } from './handler.js';
|
|
|
5
5
|
* `(request: Request) => Promise<Response>` in any fetch-native runtime
|
|
6
6
|
* (Hono, Next.js route handlers, Bun.serve, Deno.serve, Cloudflare Workers, SvelteKit).
|
|
7
7
|
*/
|
|
8
|
-
export function createFetchHandler(opts
|
|
8
|
+
export function createFetchHandler(opts) {
|
|
9
9
|
const { basePath = '', ...handlerOpts } = opts;
|
|
10
10
|
const handle = createRequestHandler(handlerOpts);
|
|
11
11
|
return async (request) => {
|
package/dist/http/handler.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { EntityMeta, Query, Type, UqlContext } from '../type/index.js';
|
|
1
|
+
import type { EntityMeta, QuerierPool, Query, Type, UqlContext } from '../type/index.js';
|
|
2
2
|
import { type CrudOperation, type HttpMethod, type RequestSuccessResponse } from './contract.js';
|
|
3
3
|
/**
|
|
4
4
|
* Framework-normalized request: adapters (express, fetch, ...) reduce their native
|
|
@@ -76,6 +76,12 @@ export type RequestHandlerOptions<Ctx = unknown> = {
|
|
|
76
76
|
* automatically. Derive tenant/auth from a verified source (session, JWT) - never trust the client.
|
|
77
77
|
*/
|
|
78
78
|
getContext?: (context: Ctx) => UqlContext | undefined | Promise<UqlContext | undefined>;
|
|
79
|
+
/**
|
|
80
|
+
* The pool this handler runs on. A function is called per request, after `getContext`, with the
|
|
81
|
+
* adapter's request and the context that resolved from it - which is what lets one deployment
|
|
82
|
+
* serve a database per tenant, where a process-wide default could only serve one.
|
|
83
|
+
*/
|
|
84
|
+
pool: QuerierPool | ((context: Ctx, appContext: UqlContext) => QuerierPool | Promise<QuerierPool>);
|
|
79
85
|
};
|
|
80
86
|
/**
|
|
81
87
|
* Returns `undefined` synchronously for an unknown entity or route so adapters can fall through
|
|
@@ -83,4 +89,4 @@ export type RequestHandlerOptions<Ctx = unknown> = {
|
|
|
83
89
|
* (e.g. `toErrorResponse`).
|
|
84
90
|
*/
|
|
85
91
|
export type RequestHandler<Ctx = unknown> = (req: HandlerRequest<Ctx>) => Promise<HandlerResponse> | undefined;
|
|
86
|
-
export declare function createRequestHandler<Ctx = unknown>(opts
|
|
92
|
+
export declare function createRequestHandler<Ctx = unknown>(opts: RequestHandlerOptions<Ctx>): RequestHandler<Ctx>;
|
package/dist/http/handler.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { withContext } from '../context/context.js';
|
|
2
2
|
import { getEntities, getMeta } from '../entity/index.js';
|
|
3
|
-
import { getQuerierPool } from '../options.js';
|
|
4
3
|
import { entityPath, matchRoute, } from './contract.js';
|
|
5
4
|
import { parseQueryParams } from './query.js';
|
|
6
|
-
export function createRequestHandler(opts
|
|
7
|
-
const { include, exclude, pre, preSave, preFilter, post, getContext } = opts;
|
|
5
|
+
export function createRequestHandler(opts) {
|
|
6
|
+
const { include, exclude, pre, preSave, preFilter, post, getContext, pool } = opts;
|
|
8
7
|
let entities = include ?? getEntities();
|
|
9
8
|
if (exclude) {
|
|
10
9
|
entities = entities.filter((entity) => !exclude.includes(entity));
|
|
@@ -38,6 +37,13 @@ export function createRequestHandler(opts = {}) {
|
|
|
38
37
|
context: req.context,
|
|
39
38
|
};
|
|
40
39
|
const appContext = (await getContext?.(req.context)) ?? {};
|
|
40
|
+
// Resolved where the statement runs, not up front: a hook that aborts the request must not reach
|
|
41
|
+
// the pool at all, and picking one per request may cost a lookup this request will never use.
|
|
42
|
+
const resolvePool = async () => (typeof pool === 'function' ? pool(req.context, appContext) : pool);
|
|
43
|
+
/** Read paths: the pool acquires and releases; nothing here owns a connection. */
|
|
44
|
+
const withQuerier = async (fn) => (await resolvePool()).withQuerier(fn);
|
|
45
|
+
/** Write paths: one transaction per request, so a cascade that fails takes its parent with it. */
|
|
46
|
+
const withTransaction = async (fn) => (await resolvePool()).transaction(fn);
|
|
41
47
|
// Scope the whole request (hooks + querier + relation/cascade queries) to the resolved context.
|
|
42
48
|
return withContext(appContext, async () => {
|
|
43
49
|
await pre?.(hookCtx);
|
|
@@ -135,10 +141,6 @@ export function createRequestHandler(opts = {}) {
|
|
|
135
141
|
function ok(body) {
|
|
136
142
|
return { status: 200, body };
|
|
137
143
|
}
|
|
138
|
-
/** Read paths: the pool acquires and releases; nothing here owns a connection. */
|
|
139
|
-
const withQuerier = (fn) => getQuerierPool().withQuerier(fn);
|
|
140
|
-
/** Write paths: same, plus commit on success and rollback on failure. */
|
|
141
|
-
const withTransaction = (fn) => getQuerierPool().transaction(fn);
|
|
142
144
|
function buildIdQuery(meta, id, query) {
|
|
143
145
|
const idKey = meta.id;
|
|
144
146
|
const where = query.$where;
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,6 @@ export * from './context/context.js';
|
|
|
2
2
|
export * from './dialect/index.js';
|
|
3
3
|
export * from './entity/index.js';
|
|
4
4
|
export * from './namingStrategy/index.js';
|
|
5
|
-
export * from './options.js';
|
|
6
5
|
export * from './querier/index.js';
|
|
7
6
|
export * from './type/index.js';
|
|
8
7
|
export * from './util/index.js';
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,6 @@ export * from './context/context.js';
|
|
|
2
2
|
export * from './dialect/index.js';
|
|
3
3
|
export * from './entity/index.js';
|
|
4
4
|
export * from './namingStrategy/index.js';
|
|
5
|
-
export * from './options.js';
|
|
6
5
|
export * from './querier/index.js';
|
|
7
6
|
export * from './type/index.js';
|
|
8
7
|
export * from './util/index.js';
|
|
@@ -31,9 +31,10 @@ export type UqlModuleAsyncOptions<Req = unknown> = UqlModuleCommon<Req> & {
|
|
|
31
31
|
readonly inject?: FactoryProvider['inject'];
|
|
32
32
|
};
|
|
33
33
|
/**
|
|
34
|
-
* NestJS integration: provides the pool via DI
|
|
35
|
-
* `querierMiddleware` (express platform) and `createFetchHandler` work unchanged), optionally scopes
|
|
34
|
+
* NestJS integration: provides the pool via DI under {@link UQL_QUERIER_POOL}, optionally scopes
|
|
36
35
|
* every request to a {@link UqlContext} (multi-tenancy), and ends the pool on application shutdown.
|
|
36
|
+
* Inject the pool where you need it, `querierMiddleware`/`createFetchHandler` included: those take
|
|
37
|
+
* it as an option rather than reading a process-wide default.
|
|
37
38
|
*/
|
|
38
39
|
export declare class UqlModule {
|
|
39
40
|
/** Configure with an already-built pool. */
|
package/dist/nestjs/uqlModule.js
CHANGED
|
@@ -34,7 +34,6 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
|
|
|
34
34
|
};
|
|
35
35
|
import { Module, } from '@nestjs/common';
|
|
36
36
|
import { APP_INTERCEPTOR } from '@nestjs/core';
|
|
37
|
-
import { setQuerierPool } from '../options.js';
|
|
38
37
|
import { UqlContextInterceptor } from './uqlContextInterceptor.js';
|
|
39
38
|
/**
|
|
40
39
|
* Injection token for the configured {@link QuerierPool} - for injecting into your own
|
|
@@ -62,9 +61,10 @@ class UqlPoolLifecycle {
|
|
|
62
61
|
}
|
|
63
62
|
}
|
|
64
63
|
/**
|
|
65
|
-
* NestJS integration: provides the pool via DI
|
|
66
|
-
* `querierMiddleware` (express platform) and `createFetchHandler` work unchanged), optionally scopes
|
|
64
|
+
* NestJS integration: provides the pool via DI under {@link UQL_QUERIER_POOL}, optionally scopes
|
|
67
65
|
* every request to a {@link UqlContext} (multi-tenancy), and ends the pool on application shutdown.
|
|
66
|
+
* Inject the pool where you need it, `querierMiddleware`/`createFetchHandler` included: those take
|
|
67
|
+
* it as an option rather than reading a process-wide default.
|
|
68
68
|
*/
|
|
69
69
|
let UqlModule = (() => {
|
|
70
70
|
let _classDecorators = [Module({})];
|
|
@@ -82,18 +82,13 @@ let UqlModule = (() => {
|
|
|
82
82
|
}
|
|
83
83
|
/** Configure with an already-built pool. */
|
|
84
84
|
static forRoot({ pool, global = true, getContext }) {
|
|
85
|
-
setQuerierPool(pool);
|
|
86
85
|
return UqlModule.build(global, { provide: UQL_QUERIER_POOL, useValue: pool }, getContext);
|
|
87
86
|
}
|
|
88
87
|
/** Configure with a pool built asynchronously from injected providers (e.g. `ConfigService`). */
|
|
89
88
|
static forRootAsync({ imports, useFactory, inject = [], global = true, getContext, }) {
|
|
90
89
|
const poolProvider = {
|
|
91
90
|
provide: UQL_QUERIER_POOL,
|
|
92
|
-
useFactory
|
|
93
|
-
const pool = await useFactory(...args);
|
|
94
|
-
setQuerierPool(pool); // register as UQL's default once the pool is resolved
|
|
95
|
-
return pool;
|
|
96
|
-
},
|
|
91
|
+
useFactory,
|
|
97
92
|
inject,
|
|
98
93
|
};
|
|
99
94
|
return UqlModule.build(global, poolProvider, getContext, imports);
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"homepage": "https://uql-orm.dev",
|
|
4
4
|
"description": "JSON-native TypeScript ORM for Node.js, Bun and Deno. Supports PostgreSQL, PGlite, MySQL, MariaDB, SQLite, CockroachDB, Turso, Neon, Cloudflare D1 and MongoDB. Queries are plain JSON, typed to the leaf.",
|
|
5
5
|
"license": "MIT",
|
|
6
|
-
"version": "0.
|
|
6
|
+
"version": "0.33.0",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"engines": {
|
|
9
9
|
"node": ">=24"
|
|
@@ -27,7 +27,6 @@
|
|
|
27
27
|
"./util": "./dist/util/index.js",
|
|
28
28
|
"./namingStrategy": "./dist/namingStrategy/index.js",
|
|
29
29
|
"./migrate": "./dist/migrate/index.js",
|
|
30
|
-
"./options": "./dist/options.js",
|
|
31
30
|
"./mysql": "./dist/mysql/index.js",
|
|
32
31
|
"./postgres": "./dist/postgres/index.js",
|
|
33
32
|
"./postgres/wireCapabilities": "./dist/postgres/postgresWireDriverCapabilities.js",
|
package/dist/options.d.ts
DELETED
package/dist/options.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
let defaultPool;
|
|
2
|
-
export function setQuerierPool(pool) {
|
|
3
|
-
defaultPool = pool;
|
|
4
|
-
}
|
|
5
|
-
export function getQuerierPool() {
|
|
6
|
-
if (!defaultPool) {
|
|
7
|
-
throw new TypeError('A default querier-pool has to be set first');
|
|
8
|
-
}
|
|
9
|
-
return defaultPool;
|
|
10
|
-
}
|
|
11
|
-
export function getQuerier() {
|
|
12
|
-
return defaultPool.getQuerier();
|
|
13
|
-
}
|