@edium/halifax 1.0.0 → 2.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.
Files changed (150) hide show
  1. package/CHANGELOG.md +97 -0
  2. package/README.md +72 -50
  3. package/README_AUTOCRUD.md +94 -19
  4. package/README_QUERYBUILDER.md +1 -1
  5. package/README_REPO_ADAPTERS.md +80 -11
  6. package/dist/adapters/http/ExpressAdapter.d.ts +34 -5
  7. package/dist/adapters/http/ExpressAdapter.js +20 -12
  8. package/dist/adapters/http/FastifyAdapter.d.ts +93 -0
  9. package/dist/adapters/http/FastifyAdapter.js +125 -0
  10. package/dist/adapters/http/HyperExpressAdapter.d.ts +82 -0
  11. package/dist/adapters/http/HyperExpressAdapter.js +128 -0
  12. package/dist/adapters/http/UltimateExpressAdapter.d.ts +84 -0
  13. package/dist/adapters/http/UltimateExpressAdapter.js +108 -0
  14. package/dist/adapters/orm/prisma/PrismaAdapter.d.ts +89 -40
  15. package/dist/adapters/orm/prisma/PrismaAdapter.js +233 -71
  16. package/dist/adapters/orm/prisma/astToPrisma.d.ts +26 -0
  17. package/dist/adapters/orm/prisma/astToPrisma.js +140 -0
  18. package/dist/adapters/orm/prisma/createPrismaResources.d.ts +1 -2
  19. package/dist/adapters/orm/prisma/createPrismaResources.js +10 -6
  20. package/dist/adapters/orm/prisma/helpers.d.ts +0 -1
  21. package/dist/adapters/orm/prisma/helpers.js +0 -1
  22. package/dist/adapters/orm/prisma/index.d.ts +1 -2
  23. package/dist/adapters/orm/prisma/index.js +0 -1
  24. package/dist/adapters/orm/prisma/types.d.ts +14 -9
  25. package/dist/adapters/orm/prisma/types.js +0 -1
  26. package/dist/auth/AuthStrategy.d.ts +0 -9
  27. package/dist/auth/AuthStrategy.js +0 -7
  28. package/dist/core/cache/CacheStore.d.ts +25 -0
  29. package/dist/core/cache/CacheStore.js +1 -0
  30. package/dist/core/cache/createCachingRepository.d.ts +39 -0
  31. package/dist/core/cache/createCachingRepository.js +116 -0
  32. package/dist/core/cache/in-memory/InMemoryCacheStore.d.ts +19 -0
  33. package/dist/core/cache/in-memory/InMemoryCacheStore.js +34 -0
  34. package/dist/core/cache/index.d.ts +5 -0
  35. package/dist/core/cache/index.js +5 -0
  36. package/dist/core/cache/redis/RedisCacheStore.d.ts +28 -0
  37. package/dist/core/cache/redis/RedisCacheStore.js +42 -0
  38. package/dist/core/cache/redis/RedisLikeClient.d.ts +12 -0
  39. package/dist/core/cache/redis/RedisLikeClient.js +1 -0
  40. package/dist/core/crudRouter.d.ts +72 -8
  41. package/dist/core/crudRouter.js +266 -105
  42. package/dist/core/queryString.d.ts +3 -3
  43. package/dist/core/queryString.js +16 -7
  44. package/dist/core/types.d.ts +151 -31
  45. package/dist/core/types.js +13 -1
  46. package/dist/core/validation.d.ts +12 -4
  47. package/dist/core/validation.js +33 -13
  48. package/dist/enums/SqlComparison.d.ts +13 -3
  49. package/dist/enums/SqlComparison.js +12 -2
  50. package/dist/enums/SqlOperator.d.ts +0 -1
  51. package/dist/enums/SqlOperator.js +0 -1
  52. package/dist/enums/SqlOrder.d.ts +0 -1
  53. package/dist/enums/SqlOrder.js +0 -1
  54. package/dist/errors/AuthenticationError.d.ts +0 -1
  55. package/dist/errors/AuthenticationError.js +0 -1
  56. package/dist/errors/AuthorizationError.d.ts +0 -1
  57. package/dist/errors/AuthorizationError.js +0 -1
  58. package/dist/errors/BadRequestError.d.ts +0 -1
  59. package/dist/errors/BadRequestError.js +0 -1
  60. package/dist/errors/HttpError.d.ts +0 -1
  61. package/dist/errors/HttpError.js +0 -1
  62. package/dist/errors/MethodNotAllowedError.d.ts +0 -1
  63. package/dist/errors/MethodNotAllowedError.js +0 -1
  64. package/dist/errors/NotAcceptableError.d.ts +0 -1
  65. package/dist/errors/NotAcceptableError.js +0 -1
  66. package/dist/errors/NotFoundError.d.ts +0 -1
  67. package/dist/errors/NotFoundError.js +0 -1
  68. package/dist/errors/NotImplementedError.d.ts +0 -1
  69. package/dist/errors/NotImplementedError.js +0 -1
  70. package/dist/errors/ServerError.d.ts +0 -1
  71. package/dist/errors/ServerError.js +0 -1
  72. package/dist/errors/UnprocessableEntityError.d.ts +0 -1
  73. package/dist/errors/UnprocessableEntityError.js +0 -1
  74. package/dist/errors/UnsupportedMediaTypeError.d.ts +0 -1
  75. package/dist/errors/UnsupportedMediaTypeError.js +0 -1
  76. package/dist/index.d.ts +1 -3
  77. package/dist/index.js +1 -3
  78. package/dist/interfaces/IQueryFilter.d.ts +1 -2
  79. package/dist/interfaces/IQueryFilter.js +0 -1
  80. package/dist/interfaces/IQueryOptions.d.ts +9 -9
  81. package/dist/interfaces/IQueryOptions.js +0 -1
  82. package/dist/interfaces/ISort.d.ts +0 -1
  83. package/dist/interfaces/ISort.js +0 -1
  84. package/package.json +10 -8
  85. package/dist/adapters/http/ExpressAdapter.d.ts.map +0 -1
  86. package/dist/adapters/http/ExpressAdapter.js.map +0 -1
  87. package/dist/adapters/orm/prisma/PrismaAdapter.d.ts.map +0 -1
  88. package/dist/adapters/orm/prisma/PrismaAdapter.js.map +0 -1
  89. package/dist/adapters/orm/prisma/createPrismaResources.d.ts.map +0 -1
  90. package/dist/adapters/orm/prisma/createPrismaResources.js.map +0 -1
  91. package/dist/adapters/orm/prisma/helpers.d.ts.map +0 -1
  92. package/dist/adapters/orm/prisma/helpers.js.map +0 -1
  93. package/dist/adapters/orm/prisma/index.d.ts.map +0 -1
  94. package/dist/adapters/orm/prisma/index.js.map +0 -1
  95. package/dist/adapters/orm/prisma/types.d.ts.map +0 -1
  96. package/dist/adapters/orm/prisma/types.js.map +0 -1
  97. package/dist/auth/AuthStrategy.d.ts.map +0 -1
  98. package/dist/auth/AuthStrategy.js.map +0 -1
  99. package/dist/classes/QueryBuilder.d.ts +0 -33
  100. package/dist/classes/QueryBuilder.d.ts.map +0 -1
  101. package/dist/classes/QueryBuilder.js +0 -262
  102. package/dist/classes/QueryBuilder.js.map +0 -1
  103. package/dist/core/crudRouter.d.ts.map +0 -1
  104. package/dist/core/crudRouter.js.map +0 -1
  105. package/dist/core/queryString.d.ts.map +0 -1
  106. package/dist/core/queryString.js.map +0 -1
  107. package/dist/core/types.d.ts.map +0 -1
  108. package/dist/core/types.js.map +0 -1
  109. package/dist/core/validation.d.ts.map +0 -1
  110. package/dist/core/validation.js.map +0 -1
  111. package/dist/enums/SqlComparison.d.ts.map +0 -1
  112. package/dist/enums/SqlComparison.js.map +0 -1
  113. package/dist/enums/SqlOperator.d.ts.map +0 -1
  114. package/dist/enums/SqlOperator.js.map +0 -1
  115. package/dist/enums/SqlOrder.d.ts.map +0 -1
  116. package/dist/enums/SqlOrder.js.map +0 -1
  117. package/dist/errors/AuthenticationError.d.ts.map +0 -1
  118. package/dist/errors/AuthenticationError.js.map +0 -1
  119. package/dist/errors/AuthorizationError.d.ts.map +0 -1
  120. package/dist/errors/AuthorizationError.js.map +0 -1
  121. package/dist/errors/BadRequestError.d.ts.map +0 -1
  122. package/dist/errors/BadRequestError.js.map +0 -1
  123. package/dist/errors/HttpError.d.ts.map +0 -1
  124. package/dist/errors/HttpError.js.map +0 -1
  125. package/dist/errors/MethodNotAllowedError.d.ts.map +0 -1
  126. package/dist/errors/MethodNotAllowedError.js.map +0 -1
  127. package/dist/errors/NotAcceptableError.d.ts.map +0 -1
  128. package/dist/errors/NotAcceptableError.js.map +0 -1
  129. package/dist/errors/NotFoundError.d.ts.map +0 -1
  130. package/dist/errors/NotFoundError.js.map +0 -1
  131. package/dist/errors/NotImplementedError.d.ts.map +0 -1
  132. package/dist/errors/NotImplementedError.js.map +0 -1
  133. package/dist/errors/ServerError.d.ts.map +0 -1
  134. package/dist/errors/ServerError.js.map +0 -1
  135. package/dist/errors/UnprocessableEntityError.d.ts.map +0 -1
  136. package/dist/errors/UnprocessableEntityError.js.map +0 -1
  137. package/dist/errors/UnsupportedMediaTypeError.d.ts.map +0 -1
  138. package/dist/errors/UnsupportedMediaTypeError.js.map +0 -1
  139. package/dist/index.d.ts.map +0 -1
  140. package/dist/index.js.map +0 -1
  141. package/dist/interfaces/IParamQuery.d.ts +0 -8
  142. package/dist/interfaces/IParamQuery.d.ts.map +0 -1
  143. package/dist/interfaces/IParamQuery.js +0 -2
  144. package/dist/interfaces/IParamQuery.js.map +0 -1
  145. package/dist/interfaces/IQueryFilter.d.ts.map +0 -1
  146. package/dist/interfaces/IQueryFilter.js.map +0 -1
  147. package/dist/interfaces/IQueryOptions.d.ts.map +0 -1
  148. package/dist/interfaces/IQueryOptions.js.map +0 -1
  149. package/dist/interfaces/ISort.d.ts.map +0 -1
  150. package/dist/interfaces/ISort.js.map +0 -1
@@ -0,0 +1,108 @@
1
+ import ultimateExpress from 'ultimate-express';
2
+ import { registerCrudApi } from '../../core/crudRouter.js';
3
+ const { Router } = ultimateExpress;
4
+ /** Maps a Halifax {@link HttpMethod} to the corresponding Ultimate Express registration method name. */
5
+ const METHOD_TO_REGISTRAR = {
6
+ GET: 'get',
7
+ POST: 'post',
8
+ PUT: 'put',
9
+ PATCH: 'patch',
10
+ DELETE: 'delete'
11
+ };
12
+ /**
13
+ * Wraps an Ultimate Express request in Halifax's framework-agnostic {@link HttpRequest}.
14
+ * @param req - The Ultimate Express request to adapt.
15
+ * @returns A Halifax-compatible {@link HttpRequest} with the original request in `raw`.
16
+ */
17
+ function adaptRequest(req) {
18
+ return {
19
+ method: req.method,
20
+ params: req.params,
21
+ query: req.query,
22
+ body: req.body,
23
+ headers: req.headers,
24
+ raw: req
25
+ };
26
+ }
27
+ /**
28
+ * Wraps an Ultimate Express response in Halifax's framework-agnostic {@link HttpResponse}.
29
+ * @param res - The Ultimate Express response to adapt.
30
+ * @returns A Halifax-compatible {@link HttpResponse} with the original response in `raw`.
31
+ */
32
+ function adaptResponse(res) {
33
+ return {
34
+ raw: res,
35
+ status(code) {
36
+ res.status(code);
37
+ return this;
38
+ },
39
+ json(payload) {
40
+ res.json(payload);
41
+ },
42
+ send(payload) {
43
+ res.send(payload);
44
+ },
45
+ setHeader(name, value) {
46
+ res.setHeader(name, value);
47
+ }
48
+ };
49
+ }
50
+ /**
51
+ * Adapts an Ultimate Express `App` or `Router` to Halifax's {@link HttpServer} interface.
52
+ *
53
+ * Because Ultimate Express implements the Express API, this adapter is a near-identical
54
+ * twin of {@link ExpressHttpServer}: it uses the same route methods, `:id` named params
55
+ * (never `*` path wildcards), and request/response surface. The difference is purely the
56
+ * underlying transport (uWebSockets), which is faster but otherwise transparent.
57
+ */
58
+ export class UltimateExpressHttpServer {
59
+ app;
60
+ /**
61
+ * @param app - Ultimate Express application or router to register routes on.
62
+ * When an `App` is provided, `start()` will call `listen()`.
63
+ * When a `Router` is provided, `start()` is a no-op.
64
+ */
65
+ constructor(app) {
66
+ this.app = app;
67
+ }
68
+ /**
69
+ * Registers a route on the app for the given method and path.
70
+ * @param method - HTTP method (or `'*'` to register a catch-all via `app.all`).
71
+ * @param path - Route path pattern (e.g. `'/users/:id'`).
72
+ * @param handler - Halifax route handler to invoke on matching requests.
73
+ */
74
+ registerRoute(method, path, handler) {
75
+ const cb = (req, res) => {
76
+ void Promise.resolve(handler(adaptRequest(req), adaptResponse(res)));
77
+ };
78
+ const register = method === '*' ? this.app.all : this.app[METHOD_TO_REGISTRAR[method]];
79
+ register.call(this.app, path, cb);
80
+ }
81
+ /**
82
+ * Starts the server. No-op when the underlying app does not expose a `listen` method
83
+ * (e.g. when `app` is a `Router` mounted on an existing app).
84
+ * @param port - TCP port number to bind to.
85
+ * @param host - Hostname or IP address to bind to (defaults to all interfaces when omitted).
86
+ */
87
+ async start(port, host) {
88
+ await new Promise((resolve) => {
89
+ if (typeof this.app.listen === 'function') {
90
+ this.app.listen(port, host, () => resolve());
91
+ return;
92
+ }
93
+ resolve();
94
+ });
95
+ }
96
+ }
97
+ /**
98
+ * Creates a fully-wired Ultimate Express `Router` with CRUD routes for every resource.
99
+ *
100
+ * @param resources - Resource definitions to register (use {@link createPrismaResources} to generate these).
101
+ * @param options - Auth strategy, query-builder path overrides, etc.
102
+ * @returns An Ultimate Express `Router` ready to mount with `app.use('/api', router)`.
103
+ */
104
+ export function createUltimateExpressCrudRouter(resources, options = {}) {
105
+ const router = Router();
106
+ registerCrudApi(new UltimateExpressHttpServer(router), resources, options);
107
+ return router;
108
+ }
@@ -1,35 +1,80 @@
1
1
  import type { IQueryOptions } from '../../../interfaces/IQueryOptions.js';
2
- import type { Repository, RepositoryCapabilities, DeleteManyResult, ListOptions, ListResult, NativeQueryResult, UpdateManyResult } from '../../../core/types.js';
2
+ import type { Repository, RepositoryCapabilities, DeleteManyResult, ListOptions, ListResult, QueryResult, TenantScope, UpdateManyResult } from '../../../core/types.js';
3
3
  import type { FieldDefinition, RelationDefinition, ModelSchema } from '../../../core/types.js';
4
4
  import type { PrismaAdapterOptions } from './types.js';
5
5
  /**
6
- * PrismaAdapter is a generic repository implementation that uses Prisma delegates to perform database operations.
7
- * It supports basic CRUD operations and can be extended to support more complex queries.
8
- * The adapter can optionally use a Prisma client for executing raw SQL queries when needed.
9
- * It also extracts field and relation definitions from a provided Prisma model schema to enhance query capabilities.
6
+ * PrismaAdapter is a generic repository implementation that uses Prisma delegates to perform
7
+ * database operations. It handles CRUD plus the query-builder/bulk paths by compiling the
8
+ * query AST to portable Prisma Client calls (no raw SQL), so it works on every Prisma
9
+ * provider. It also extracts field and relation definitions from a provided model schema.
10
10
  */
11
11
  export declare class PrismaAdapter<TRecord = unknown, TCreate = Partial<TRecord>, TUpdate = Partial<TRecord>> implements Repository<TRecord, TCreate, TUpdate> {
12
- /** Private properties to hold the Prisma delegate, client, and configuration options. */
12
+ /** Private properties to hold the Prisma delegate and configuration options. */
13
13
  private readonly delegate;
14
- /** Optional Prisma client for executing raw SQL queries, required for certain operations like updateMany and deleteMany. */
15
- private readonly client?;
16
14
  /** The field name used for the primary key in the model. */
17
- private readonly idField;
18
- /** The name of the database table associated with the model. */
19
- private readonly tableName?;
15
+ readonly idField: string;
20
16
  /** A flag indicating whether to return created records. */
21
17
  private readonly returnCreated;
18
+ /** The original construction options, used to build request-scoped clones. */
19
+ private readonly options;
20
+ /** Tenant constraint bound to this instance, or `undefined` for unscoped access. */
21
+ private readonly scope?;
22
22
  /** A set of capabilities that the repository supports. */
23
23
  readonly capabilities: RepositoryCapabilities;
24
- /** An array of field definitions for the model. */
25
- readonly fields: FieldDefinition[] | undefined;
26
- /** An array of relation definitions for the model. */
27
- readonly relations: RelationDefinition[] | undefined;
24
+ /** An array of field definitions for the model (present when built with a `model`). */
25
+ readonly fields?: FieldDefinition[];
26
+ /** An array of relation definitions for the model (present when built with a `model`). */
27
+ readonly relations?: RelationDefinition[];
28
28
  /**
29
29
  * Constructs a new instance of PrismaAdapter with the provided options.
30
- * @param options - An object containing the Prisma delegate, optional client, and configuration settings for the adapter.
30
+ * @param options - The Prisma delegate plus optional id field, return-created flag, and model schema.
31
31
  */
32
32
  constructor(options: PrismaAdapterOptions);
33
+ /**
34
+ * Returns a request-scoped clone of this adapter bound to `scope`. Every read is
35
+ * filtered by the scope, every write is stamped with it, and every bulk/SQL operation
36
+ * has the scope AND-ed into its WHERE clause. The original instance is never mutated.
37
+ * @param scope - The resolved tenant constraint for the current request.
38
+ * @returns A new {@link PrismaAdapter} that enforces `scope` on all operations.
39
+ */
40
+ withScope(scope: TenantScope): PrismaAdapter<TRecord, TCreate, TUpdate>;
41
+ /**
42
+ * Merges the bound tenant constraint into a Prisma `where` object. The scope is spread
43
+ * last so it always wins over any caller-supplied value for the same key.
44
+ * @param where - The caller-derived where clause (may be undefined).
45
+ * @returns A where object with the tenant constraint applied, or `where` when unscoped.
46
+ */
47
+ private scopedWhere;
48
+ /**
49
+ * Removes the tenant field from a write payload so callers can never reassign a row
50
+ * to another tenant via create/update/upsert bodies. No-op when unscoped.
51
+ * @param data - The write payload to sanitise.
52
+ * @returns A copy of `data` without the tenant field, or `data` when unscoped.
53
+ */
54
+ private stripTenant;
55
+ /**
56
+ * Stamps the bound tenant value onto a create payload, overriding any caller-supplied
57
+ * value for the tenant field. No-op when unscoped.
58
+ * @param data - The create payload.
59
+ * @returns A copy of `data` with the tenant field forced to the scope value.
60
+ */
61
+ private stampTenant;
62
+ /**
63
+ * AND-s the bound tenant constraint into a query-builder WHERE clause. The caller's filters
64
+ * are nested as a child group beneath the tenant condition, so a caller-supplied `OR` can
65
+ * never break out of the tenant boundary once the AST is compiled to a Prisma `where`.
66
+ * @param where - The caller-supplied filter list (may be undefined/empty).
67
+ * @returns A new filter list with the tenant condition enforced, or `where` when unscoped.
68
+ */
69
+ private scopedFilters;
70
+ /**
71
+ * Resolves a query-builder AST for the tenant-scoped paths: applies the tenant constraint
72
+ * via {@link PrismaAdapter.scopedFilters}. The `where` key is only set when defined (to
73
+ * satisfy `exactOptionalPropertyTypes`).
74
+ * @param query - The incoming query AST.
75
+ * @returns A new AST with the tenant scope applied.
76
+ */
77
+ private resolveScopedQuery;
33
78
  /**
34
79
  * Extracts field definitions from a Prisma model schema.
35
80
  * @param model - The Prisma model schema.
@@ -81,21 +126,19 @@ export declare class PrismaAdapter<TRecord = unknown, TCreate = Partial<TRecord>
81
126
  */
82
127
  updateOne(id: string | number, data: TUpdate): Promise<TRecord | null>;
83
128
  /**
84
- * Updates multiple records that match the provided query options with the given data.
85
- * This method requires a Prisma client for executing raw SQL queries, as Prisma does not
86
- * natively support bulk updates with return values. It first selects the IDs of the records
87
- * to be updated based on the query options, then executes an update query, and finally returns
88
- * the IDs of the updated records.
129
+ * Updates every record matching the query and returns the IDs of the affected rows.
89
130
  *
90
- * **Note:** The SELECT and UPDATE are issued as two separate queries without a transaction.
91
- * Under concurrent writes, rows inserted or deleted between the two queries may cause the
92
- * returned `updated` IDs to differ from the rows actually modified.
131
+ * The query AST is compiled to a portable Prisma `where` (no raw SQL), so this works on
132
+ * every Prisma provider. Because Prisma's `updateMany` only returns a count, the matching
133
+ * IDs are selected first and then the bulk update is applied.
134
+ *
135
+ * **Note:** the SELECT and UPDATE are two separate statements without a transaction; under
136
+ * concurrent writes the returned `updated` IDs may differ from the rows actually modified.
93
137
  *
94
- * @param query - An object containing query options to filter the records that should be updated, such as where conditions, sorting, and pagination.
95
- * @param data - An object containing the data to update the matching records with.
96
- * @returns A promise that resolves to an object containing an array of the IDs of the updated records.
97
- * @throws NotImplementedError if the Prisma client or tableName is not provided, as they are required for executing raw SQL queries.
98
- * @throws ServerError if the Prisma client does not support the required methods for executing raw SQL queries.
138
+ * @param query - Query AST describing which rows to update (filtered, tenant-scoped).
139
+ * @param data - Fields to apply to all matching rows (the tenant field is stripped).
140
+ * @returns The IDs of the updated rows.
141
+ * @throws NotImplementedError when the delegate does not support `updateMany`.
99
142
  */
100
143
  updateMany(query: IQueryOptions, data: TUpdate): Promise<UpdateManyResult<TRecord>>;
101
144
  /**
@@ -125,19 +168,25 @@ export declare class PrismaAdapter<TRecord = unknown, TCreate = Partial<TRecord>
125
168
  * Under concurrent writes, rows inserted or deleted between the two queries may cause the
126
169
  * returned `deleted` IDs to differ from the rows actually removed.
127
170
  *
128
- * @param query - An object containing query options to filter the records that should be deleted, such as where conditions, sorting, and pagination.
129
- * @returns A promise that resolves to an object containing an array of the IDs of the deleted records.
130
- * @throws NotImplementedError if the Prisma client or tableName is not provided, as they are required for executing raw SQL queries.
131
- * @throws ServerError if the Prisma client does not support the required methods for executing raw SQL queries.
171
+ * @param query - Query AST describing which rows to delete (filtered, tenant-scoped).
172
+ * @returns The IDs of the deleted rows.
173
+ * @throws NotImplementedError when the delegate does not support `deleteMany`.
132
174
  */
133
175
  deleteMany(query: IQueryOptions): Promise<DeleteManyResult>;
134
176
  /**
135
- * Executes a query built using the QueryBuilder, which allows for complex filtering, sorting, pagination, and field selection. This method requires a Prisma client for executing raw SQL queries, as it relies on the QueryBuilder to generate SQL statements. It first builds a count query to get the total number of matching records and then builds a select query to retrieve the actual records based on the provided query options.
136
- * @param query - An object containing query options such as filtering conditions, sorting, pagination, and field selection, which will be used to build the SQL queries.
137
- * @returns A promise that resolves to an object containing the total count of matching records and an array of the retrieved records.
138
- * @throws NotImplementedError if the Prisma client or tableName is not provided, as they are required for executing raw SQL queries.
139
- * @throws ServerError if the Prisma client does not support the required methods for executing raw SQL queries.
177
+ * Executes a query-builder AST as a portable Prisma query: the WHERE tree is compiled to a
178
+ * Prisma `where`, and field projection, ordering, pagination, and `distinct` are mapped to
179
+ * `findMany` arguments. No raw SQL is generated, so the same query runs identically on every
180
+ * Prisma provider (PostgreSQL, MySQL, SQLite, SQL Server, CockroachDB, MongoDB).
181
+ *
182
+ * Validation (field/comparison/depth checks → 4xx) happens in the router *before* this
183
+ * method, so malformed queries never reach Prisma.
184
+ *
185
+ * **Note:** the COUNT and SELECT are two separate statements without a transaction; under
186
+ * concurrent writes the returned `count` may differ from the number of rows in `results`.
187
+ *
188
+ * @param query - The validated query AST (filters, sort, pagination, projection, distinct).
189
+ * @returns A count-and-results envelope for the matching rows.
140
190
  */
141
- executeQueryBuilder(query: IQueryOptions): Promise<NativeQueryResult<TRecord>>;
191
+ executeQuery(query: IQueryOptions): Promise<QueryResult<TRecord>>;
142
192
  }
143
- //# sourceMappingURL=PrismaAdapter.d.ts.map