vsrepo 2.3.0 → 2.4.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 +81 -83
- package/README.pt-BR.md +85 -87
- package/dist/internal/utils/vs-logger.util.d.ts +2 -2
- package/dist/internal/utils/vs-logger.util.js +7 -4
- package/dist/internal/utils/vs-logger.util.js.map +1 -1
- package/dist/internal/validators/vsrepo.validator.js +1 -1
- package/dist/internal/validators/vsrepo.validator.js.map +1 -1
- package/dist/types/vsrepo/vsrepo-options.type.d.ts +4 -1
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -13,16 +13,14 @@
|
|
|
13
13
|
|
|
14
14
|
🇺🇸 You're reading the English version. [🇧🇷 Ler em português](./README.pt-BR.md)
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
**ORM-agnostic** repository pattern library, with full **TypeScript** support and automatic **type inference**. VSRepository v2 is a rewrite of the [v1](https://github.com/jaobrabo123/VSRepository/tree/v1) library: instead of talking to Prisma directly, the core now delegates every operation to a pluggable **adapter**, so the same repository API can work against Prisma, TypeORM, or any other ORM/database that implements the adapter contract.
|
|
16
|
+
**ORM-agnostic** repository pattern library, with full **TypeScript** support and automatic **type inference**. VSRepository v2 is a rewrite of the [v1](https://github.com/jaobrabo123/VSRepository/tree/v1) library: instead of talking to Prisma directly, the core now delegates every operation to a pluggable **adapter**, so the same repository API can work against Prisma, Drizzle, or any other ORM/database that implements the adapter contract.
|
|
19
17
|
|
|
20
18
|
VSRepository lets you create strongly-typed repositories with:
|
|
21
19
|
|
|
22
20
|
- Automatic **base methods**: `get`, `getOrThrow`, `getList`, `save`, `saveList`, `remove`, `removeList`, `patch`, `merge`, `getAll`, `total`, `has`
|
|
23
21
|
- **Native soft-delete**: `softRemove`, `softRemoveList`, `restore`, `restoreList`
|
|
24
22
|
- **Dynamic methods** inferred from a `declare` field name via the `@DynamicMethod` decorator: `findByEmail`, `findManyByStatusPaginated`, `updateById`
|
|
25
|
-
- **Raw SQL query methods** via the
|
|
23
|
+
- **Raw SQL query methods** via the `@QueryMethod` decorator, bypassing the name-parsing engine entirely
|
|
26
24
|
- Ad-hoc **`select`/`relations`** per call — no more pre-declared named projections
|
|
27
25
|
- **Type safety** across 100% of operations
|
|
28
26
|
- Native ORM **transactions**, shared across repositories
|
|
@@ -71,16 +69,16 @@ If you're coming from the [v1](https://github.com/jaobrabo123/VSRepository/tree/
|
|
|
71
69
|
|
|
72
70
|
| Area | v1 | v2 |
|
|
73
71
|
| -------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
74
|
-
| Database access | Talks to **Prisma** directly, bundled in the core package | Talks to a **`VSRepoAdapter`**; ORM support ships as separate packages (`@vsrepo/prisma7-adapter`, `@vsrepo/
|
|
72
|
+
| Database access | Talks to **Prisma** directly, bundled in the core package | Talks to a **`VSRepoAdapter`**; ORM support ships as separate packages (`@vsrepo/prisma7-adapter`, `@vsrepo/drizzle-adapter`, ...) instead of being bundled in the core `vsrepo` package |
|
|
75
73
|
| Defining a repository | Functional `setupVSRepo<T, M>()({...}).build(prisma)`, **or** a `DynamicRepository` class | A single **class-based** API: `extends VSRepository<Entity, PKType, OrmTypes>` |
|
|
76
74
|
| Dynamic methods | `methods: { findByEmail: { map: true } }` config object | `@DynamicMethod()` decorator on a `declare` field |
|
|
77
75
|
| Data projections | Named, reusable `selectModels` + `defaultSelectModel` | Ad-hoc `select`/`relations` passed per call (no named models) |
|
|
78
76
|
| Eager loading | `include`/`includeModels` (Prisma-specific) | ORM-agnostic `relations` option |
|
|
79
|
-
| Global filters | `requiredWhere`
|
|
77
|
+
| Global filters | `requiredWhere` and `pushWhere` | **Removed**; Now it only accepts `softRemoveKey` + `see: "active" \| "removed" \| "all"` |
|
|
80
78
|
| Case-insensitive filter suffix | `Insensitive` | `IgnoreCase` |
|
|
81
79
|
| Inline ordering in method name | Not supported (`order` had to be passed as an argument via `Ordered`/`Paginated`) | `OrderBy<Field>Asc`/`OrderBy<Field>Desc` chains baked directly into the method name |
|
|
82
80
|
| Duplicate handling on `createMany` | `SkipDuplicates` suffix | `IgnoreConflicts` suffix |
|
|
83
|
-
| `aggregate` / `groupBy` | Supported (Prisma-native passthrough) | **
|
|
81
|
+
| `aggregate` / `groupBy` | Supported (Prisma-native passthrough) | `groupBy` is **not planned** for v2. `aggregate` as a prefix is also unlikely: the most common operations are already covered by dedicated base methods (`sum`, `average`, `min`, `max`, `increment`, `decrement`, `multiply`, `divide`) — see [Atomic and aggregate methods](#atomic-and-aggregate-methods). For anything more complex, use `@QueryMethod`. |
|
|
84
82
|
| Error types | `VSRepoError` + subclasses (`VSRepoConfigError`, `VSRepoBuildError`, `VSRepoExtendError`, `VSRepoRuntimeError`) | A base `VSRepoError` class with a `type: VSRepoErrorType` field (`DECORATOR`, `RESOLVER`, `DYNAMIC`, `VALIDATOR`, `BASE`, `ADAPTER`), plus a `VSRepoAdapterError` subclass carrying an `AdapterErrorCode` and the original ORM error |
|
|
85
83
|
| Debug logging | `showWorking: true` boolean | `logLevel: VSLogLevel` (`DEBUG`/`INFO`/`WARN`/`ERROR`) + `logSlowThresholdMs` for slow-query warnings |
|
|
86
84
|
| `vsrepo generate` CLI (type generation step) | Required before use | Not part of the v2 core — types come directly from your entity/ORM types |
|
|
@@ -97,17 +95,16 @@ VSRepository v2 is **ORM-agnostic by design**. The core package (`vsrepo`) only
|
|
|
97
95
|
- `@vsrepo/typeorm-adapter`
|
|
98
96
|
- `@vsrepo/drizzle-adapter`
|
|
99
97
|
|
|
100
|
-
The Prisma 7 adapter has now been published to npm as `@vsrepo/prisma7-adapter
|
|
98
|
+
The Prisma 7 adapter has now been published to npm as `@vsrepo/prisma7-adapter`. The Drizzle adapter is available as an **alpha** release — install it with `@vsrepo/drizzle-adapter@alpha`. Adapters for other ORMs are **planned** but not published yet. Until an official `@vsrepo/*-adapter` package exists for your ORM, you're welcome to write your own for your project, and if you'd like, publish it and open a PR to help grow the ecosystem — contributions here are very welcome.
|
|
101
99
|
|
|
102
100
|
| Adapter | Status |
|
|
103
101
|
| ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
104
102
|
| Prisma 7 (`@vsrepo/prisma7-adapter`) | 🟢 **Released** — published to npm, implements the `VSRepoAdapter` contract (CRUD, relations, transactions, `merge`, logging) with tests; see [`VSRepoPrisma7Adapter`](https://github.com/jaobrabo123/VSRepoPrisma7Adapter) for source and docs. **Note:** the atomic/aggregate methods (`incrementOne`, `decrementOne`, `multiplyOne`, `divideOne`, `sum`, `average`, `min`, `max` — see [Atomic and aggregate methods](#atomic-and-aggregate-methods)) were added to the `VSRepoAdapter` contract after this adapter's last release; confirm its changelog/version implements them before relying on `increment`/`sum`/etc. against Prisma 7. |
|
|
105
|
-
| Drizzle (`@vsrepo/drizzle-adapter`) | 🔵 **
|
|
106
|
-
| TypeORM
|
|
107
|
-
| Other ORMs (Prisma 8, Drizzle, etc.) | 🟡 **Planned, not published yet.** No official package exists yet — write your own adapter for now (see [Writing your own adapter](#writing-your-own-adapter)), and consider publishing/contributing it back. |
|
|
103
|
+
| Drizzle (`@vsrepo/drizzle-adapter`) | 🔵 **Alpha** — an early release is available on npm; install it with `npm i @vsrepo/drizzle-adapter@alpha`. The API may still change before the stable release. Check the [`DrizzleAdapter`](https://github.com/jaobrabo123/VSRepoDrizzleAdapter) repository for the current status and known limitations, and feel free to contribute. |
|
|
104
|
+
| Other ORMs (Prisma 8, TypeORM, etc.) | 🟡 **Planned, not published yet.** No official package exists yet — write your own adapter for now (see [Writing your own adapter](#writing-your-own-adapter)), and consider publishing/contributing it back. |
|
|
108
105
|
| Custom adapters | 🟢 Fully supported today — implement the [`VSRepoAdapter`](#writing-your-own-adapter) abstract class yourself for any ORM/database you need, in your own project or package, following the same shape as `@vsrepo/*-adapter` is expected to have. |
|
|
109
106
|
|
|
110
|
-
In short: the repository class, the `@DynamicMethod`/`@QueryMethod` decorators, the name-parsing engine, error handling and logging are all working end-to-end, and Prisma 7 support is now a released, published adapter. Official adapters for the remaining ORMs are on the roadmap and will ship as separate `@vsrepo/*-adapter` packages rather than as part of the core `vsrepo` package — but you don't have to wait for that: writing (and optionally publishing) your own adapter in the meantime is a fully supported way to use v2 today and to contribute back to the project.
|
|
107
|
+
In short: the repository class, the `@DynamicMethod`/`@QueryMethod` decorators, the name-parsing engine, error handling and logging are all working end-to-end, and Prisma 7 support is now a released, published adapter. The Drizzle adapter is available in alpha. Official adapters for the remaining ORMs are on the roadmap and will ship as separate `@vsrepo/*-adapter` packages rather than as part of the core `vsrepo` package — but you don't have to wait for that: writing (and optionally publishing) your own adapter in the meantime is a fully supported way to use v2 today and to contribute back to the project.
|
|
111
108
|
|
|
112
109
|
---
|
|
113
110
|
|
|
@@ -209,14 +206,14 @@ await userRepository.remove(user.id);
|
|
|
209
206
|
|
|
210
207
|
`VSRepoOptions<T, K>`, passed to `super(...)` inside your repository's constructor:
|
|
211
208
|
|
|
212
|
-
| Option | Type
|
|
213
|
-
| -------------------- |
|
|
214
|
-
| `adapter` | `VSRepoAdapter<T>`
|
|
215
|
-
| `pkName` | `keyof T`
|
|
216
|
-
| `softRemoveKey` | `keyof T`
|
|
217
|
-
| `defaultOrdering` | `Ordering<T>`
|
|
218
|
-
| `logLevel` | `VSLogLevel`
|
|
219
|
-
| `logSlowThresholdMs` | `number`
|
|
209
|
+
| Option | Type | Description |
|
|
210
|
+
| -------------------- | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
211
|
+
| `adapter` | `VSRepoAdapter<T>` | **Required.** The adapter instance that translates repository calls into calls against the underlying ORM/database. |
|
|
212
|
+
| `pkName` | `keyof T` | **Required.** Name of the field that represents the entity's primary key. |
|
|
213
|
+
| `softRemoveKey` | `keyof T` | Optional. When set, enables `softRemove`, `softRemoveList`, `restore` and `restoreList`. |
|
|
214
|
+
| `defaultOrdering` | `Ordering<T>` | Optional. Default ordering applied automatically to queries that accept `order`, unless overridden per call. |
|
|
215
|
+
| `logLevel` | `VSLogLevel` | Optional. Minimum severity printed by the internal logger. Defaults to `VSLogLevel.WARN`. |
|
|
216
|
+
| `logSlowThresholdMs` | `number \| boolean` | Optional. Duration (ms) above which a finished operation is logged as `WARN`. Defaults to 300ms. Pass `false` to disable slow-operation warnings entirely; pass `true` to use the 300ms default explicitly. |
|
|
220
217
|
|
|
221
218
|
---
|
|
222
219
|
|
|
@@ -247,7 +244,7 @@ Available automatically on every `VSRepository` subclass:
|
|
|
247
244
|
| `min(field, where?, options?)` | Minimum value of a numeric field across every matching record; `null` if none match. |
|
|
248
245
|
| `max(field, where?, options?)` | Maximum value of a numeric field across every matching record; `null` if none match. |
|
|
249
246
|
| `transaction(fn, options?)` | Runs `fn` inside a native transaction of the underlying ORM. |
|
|
250
|
-
| `getDbClient()` | Returns the
|
|
247
|
+
| `getDbClient()` | Returns the ORM client instance. |
|
|
251
248
|
| `query<T>(query, options?)` | Executes a raw SQL statement directly against the database. See [Ad-hoc raw queries with `query()`](#ad-hoc-raw-queries-with-query). |
|
|
252
249
|
|
|
253
250
|
Most of the above accept a `MethodOptions<Entity, OrmTypes>` object as their last argument (`select`, `relations`, `see`, `db`). A few — `total`, `has`, `removeList`, `sum`, `average`, `min`, `max`, and the soft-delete batch methods (`softRemoveList`/`restoreList`) — don't return/shape an `Entity`, so they accept the narrower `RestrictMethodOptions<Entity, OrmTypes>` instead (`see`, `db` only; no `select`/`relations`). `transaction`, `query`, and `getDbClient` accept their own options or none at all.
|
|
@@ -256,7 +253,7 @@ Most of the above accept a `MethodOptions<Entity, OrmTypes>` object as their las
|
|
|
256
253
|
|
|
257
254
|
## Soft-delete
|
|
258
255
|
|
|
259
|
-
Soft-delete is
|
|
256
|
+
Soft-delete is a **first-class, built-in concept**. Configure `softRemoveKey` once on the repository:
|
|
260
257
|
|
|
261
258
|
```typescript
|
|
262
259
|
super({
|
|
@@ -363,14 +360,6 @@ const userWithAddress = await userRepository.get(id, {
|
|
|
363
360
|
>
|
|
364
361
|
> The core only forwards `MethodOptions.select` and `MethodOptions.relations` to the adapter — each adapter decides how to translate them to the underlying ORM:
|
|
365
362
|
>
|
|
366
|
-
> - **TypeORM (`@vsrepo/typeorm-adapter`)** — `relations` is **required** to load any relation, even when you only want a nested projection via `select`. TypeORM will not JOIN/emit the relation unless it is listed in `relations`:
|
|
367
|
-
> ```typescript
|
|
368
|
-
> // TypeORM: select alone is NOT enough
|
|
369
|
-
> await userRepository.get(id, {
|
|
370
|
-
> select: { id: true, address: { city: true } },
|
|
371
|
-
> relations: { address: true }, // ← required in TypeORM
|
|
372
|
-
> });
|
|
373
|
-
> ```
|
|
374
363
|
> - **Prisma 7 (`@vsrepo/prisma7-adapter` / `VSRepoPrisma7Adapter`)** — `relations` is converted to Prisma `include` (`parsePrismaInclude`). **If `select` is present, `relations` is ignored** because Prisma does not allow `select` + `include` in the same query:
|
|
375
364
|
> ```typescript
|
|
376
365
|
> // Prisma7: relations is ignored when select exists
|
|
@@ -391,7 +380,7 @@ Dynamic methods are declared as a `declare` field annotated with `@DynamicMethod
|
|
|
391
380
|
```typescript
|
|
392
381
|
class UserRepository extends VSRepository<User, string> {
|
|
393
382
|
@DynamicMethod()
|
|
394
|
-
declare findByEmail: (email: string) => Promise<User[]>;
|
|
383
|
+
declare findByEmail: (email: string, options?: MethodOptions<User>) => Promise<User[]>;
|
|
395
384
|
|
|
396
385
|
@DynamicMethod()
|
|
397
386
|
declare findOneByEmail: (email: string) => Promise<User | null>;
|
|
@@ -407,12 +396,11 @@ class UserRepository extends VSRepository<User, string> {
|
|
|
407
396
|
options?: MethodOptions<User>,
|
|
408
397
|
) => Promise<User[]>;
|
|
409
398
|
|
|
410
|
-
//
|
|
399
|
+
// field filters, then pagination, then MethodOptions
|
|
411
400
|
@DynamicMethod()
|
|
412
401
|
declare findByNameIgnoreCaseOrAgeBetweenOrderByCreatedAtAscPaginated: (
|
|
413
402
|
name: string,
|
|
414
403
|
age: [number, number],
|
|
415
|
-
order: Ordering<User>,
|
|
416
404
|
pagination: Pagination,
|
|
417
405
|
options?: MethodOptions<User>,
|
|
418
406
|
) => Promise<User[]>;
|
|
@@ -421,40 +409,40 @@ class UserRepository extends VSRepository<User, string> {
|
|
|
421
409
|
|
|
422
410
|
### Available prefixes
|
|
423
411
|
|
|
424
|
-
| Prefix | Adapter method | Notes
|
|
425
|
-
| -------------------------- | --------------------- |
|
|
426
|
-
| `findBy` | `findMany` | Field filters follow the prefix.
|
|
427
|
-
| `findOneBy` | `findOne` | Field filters follow the prefix; single result.
|
|
428
|
-
| `findOneOrThrowBy` | `findOneOrThrow` | Throws if no record is found.
|
|
429
|
-
| `findOneOrThrow` | `findOneOrThrow` | No field filters; applies only soft-delete/`see`.
|
|
430
|
-
| `findOneOrThrowWhere` | `findOneOrThrow` | Receives a `VSRepoWhere<T>` as the first argument.
|
|
431
|
-
| `findWhere` | `findMany` | Receives a `VSRepoWhere<T>` as the first argument.
|
|
432
|
-
| `findOneWhere` | `findOne` | Receives a `VSRepoWhere<T>` as the first argument.
|
|
433
|
-
| `findOne` | `findOne` | No field filters; applies only soft-delete/`see`.
|
|
434
|
-
| `countBy` | `count` | Field filters follow the prefix.
|
|
435
|
-
| `countWhere` | `count` | Receives a `VSRepoWhere<T>` as the first argument.
|
|
436
|
-
| `count` | `count` | No field filters.
|
|
437
|
-
| `existsBy` | `exists` | Returns `boolean`.
|
|
438
|
-
| `existsWhere` | `exists` | Receives a `VSRepoWhere<T>` as the first argument.
|
|
439
|
-
| `create` | `create` | Receives `
|
|
440
|
-
| `createMany` | `createMany` | Receives `
|
|
441
|
-
| `createManyReturning` | `createManyReturning` | Receives `
|
|
442
|
-
| `updateBy` | `update` | Field filters + `
|
|
443
|
-
| `updateWhere` | `update` | Receives a `VSRepoWhere<T>` as the first argument, then `
|
|
444
|
-
| `updateManyBy` | `updateMany` | Field filters + `
|
|
445
|
-
| `updateManyWhere` | `updateMany` | Receives a `VSRepoWhere<T>` as the first argument, then `
|
|
446
|
-
| `updateManyReturningBy` | `updateManyReturning` | Field filters + `
|
|
447
|
-
| `updateManyReturningWhere` | `updateManyReturning` | Receives a `VSRepoWhere<T>` as the first argument, then `
|
|
448
|
-
| `upsertBy` | `upsert` | Field filters + `create`/`update` payloads.
|
|
449
|
-
| `upsertWhere` | `upsert` | Receives a `VSRepoWhere<T>` as the first argument, then `create`/`update` payloads.
|
|
450
|
-
| `deleteBy` | `delete` | Field filters follow the prefix.
|
|
451
|
-
| `deleteWhere` | `delete` | Receives a `VSRepoWhere<T>` as the first argument.
|
|
452
|
-
| `deleteManyBy` | `deleteMany` | Field filters follow the prefix.
|
|
453
|
-
| `deleteManyWhere` | `deleteMany` | Receives a `VSRepoWhere<T>` as the first argument.
|
|
454
|
-
| `deleteManyReturningBy` | `deleteManyReturning` | Field filters follow the prefix; returns deleted records.
|
|
455
|
-
| `deleteManyReturningWhere` | `deleteManyReturning` | Receives a `VSRepoWhere<T>` as the first argument; returns deleted records.
|
|
456
|
-
|
|
457
|
-
> `
|
|
412
|
+
| Prefix | Adapter method | Notes |
|
|
413
|
+
| -------------------------- | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
|
|
414
|
+
| `findBy` | `findMany` | Field filters follow the prefix. |
|
|
415
|
+
| `findOneBy` | `findOne` | Field filters follow the prefix; single result. |
|
|
416
|
+
| `findOneOrThrowBy` | `findOneOrThrow` | Throws if no record is found. |
|
|
417
|
+
| `findOneOrThrow` | `findOneOrThrow` | No field filters; applies only soft-delete/`see`. |
|
|
418
|
+
| `findOneOrThrowWhere` | `findOneOrThrow` | Receives a `VSRepoWhere<T>` as the first argument. |
|
|
419
|
+
| `findWhere` | `findMany` | Receives a `VSRepoWhere<T>` as the first argument. |
|
|
420
|
+
| `findOneWhere` | `findOne` | Receives a `VSRepoWhere<T>` as the first argument. |
|
|
421
|
+
| `findOne` | `findOne` | No field filters; applies only soft-delete/`see`. |
|
|
422
|
+
| `countBy` | `count` | Field filters follow the prefix. |
|
|
423
|
+
| `countWhere` | `count` | Receives a `VSRepoWhere<T>` as the first argument. |
|
|
424
|
+
| `count` | `count` | No field filters. |
|
|
425
|
+
| `existsBy` | `exists` | Returns `boolean`. |
|
|
426
|
+
| `existsWhere` | `exists` | Receives a `VSRepoWhere<T>` as the first argument. |
|
|
427
|
+
| `create` | `create` | Receives `DeepPartial<Entity>` as argument. |
|
|
428
|
+
| `createMany` | `createMany` | Receives `DeepPartial<Entity>[]` as argument; supports `IgnoreConflicts`. |
|
|
429
|
+
| `createManyReturning` | `createManyReturning` | Receives `DeepPartial<Entity>[]` as argument; supports `IgnoreConflicts`; returns the created records (`T[]`) instead of `CountResult`. |
|
|
430
|
+
| `updateBy` | `update` | Field filters + `DeepPartial<Entity>` as argument. |
|
|
431
|
+
| `updateWhere` | `update` | Receives a `VSRepoWhere<T>` as the first argument, then `DeepPartial<Entity>`. |
|
|
432
|
+
| `updateManyBy` | `updateMany` | Field filters + `DeepPartial<Entity>`. |
|
|
433
|
+
| `updateManyWhere` | `updateMany` | Receives a `VSRepoWhere<T>` as the first argument, then `DeepPartial<Entity>`. |
|
|
434
|
+
| `updateManyReturningBy` | `updateManyReturning` | Field filters + `DeepPartial<Entity>`; returns updated records. |
|
|
435
|
+
| `updateManyReturningWhere` | `updateManyReturning` | Receives a `VSRepoWhere<T>` as the first argument, then `DeepPartial<Entity>`; returns updated records. |
|
|
436
|
+
| `upsertBy` | `upsert` | Field filters + `create`/`update` payloads. |
|
|
437
|
+
| `upsertWhere` | `upsert` | Receives a `VSRepoWhere<T>` as the first argument, then `create`/`update` payloads. |
|
|
438
|
+
| `deleteBy` | `delete` | Field filters follow the prefix. |
|
|
439
|
+
| `deleteWhere` | `delete` | Receives a `VSRepoWhere<T>` as the first argument. |
|
|
440
|
+
| `deleteManyBy` | `deleteMany` | Field filters follow the prefix. |
|
|
441
|
+
| `deleteManyWhere` | `deleteMany` | Receives a `VSRepoWhere<T>` as the first argument. |
|
|
442
|
+
| `deleteManyReturningBy` | `deleteManyReturning` | Field filters follow the prefix; returns deleted records. |
|
|
443
|
+
| `deleteManyReturningWhere` | `deleteManyReturning` | Receives a `VSRepoWhere<T>` as the first argument; returns deleted records. |
|
|
444
|
+
|
|
445
|
+
> `groupBy` is **not planned** for v2 — it doesn't map cleanly onto the ORM-agnostic contract. `aggregate` as a separate prefix is also unlikely to be implemented: the most common aggregate operations (`sum`, `average`, `min`, `max`, `increment`, `decrement`, `multiply`, `divide`) are already available as dedicated base methods — see [Atomic and aggregate methods](#atomic-and-aggregate-methods). For anything more complex, use a `@QueryMethod` with raw SQL.
|
|
458
446
|
|
|
459
447
|
### Field filters
|
|
460
448
|
|
|
@@ -585,6 +573,11 @@ declare findOne: (options?: MethodOptions<User>) => Promise<User | null>;
|
|
|
585
573
|
| `injectOrdering` | `Ordering<T>` | Fixed ordering automatically injected, overriding the repository's `defaultOrdering`. |
|
|
586
574
|
|
|
587
575
|
```typescript
|
|
576
|
+
// proxyTo: gives the method a custom name while reusing an existing pattern
|
|
577
|
+
@DynamicMethod<User>({ proxyTo: "findByEmail" })
|
|
578
|
+
declare buscarPorEmail: (email: string, options?: MethodOptions<User>) => Promise<User[]>;
|
|
579
|
+
|
|
580
|
+
// injectOrdering: always sorts by createdAt desc, overriding defaultOrdering
|
|
588
581
|
@DynamicMethod<User>({ injectOrdering: { createdAt: "desc" } })
|
|
589
582
|
declare findByStatus: (status: string) => Promise<User[]>;
|
|
590
583
|
```
|
|
@@ -612,7 +605,7 @@ class UserRepository extends VSRepository<User, string> {
|
|
|
612
605
|
|
|
613
606
|
| Option | Type | Default | Description |
|
|
614
607
|
| -------------- | --------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
615
|
-
| `modifying` | `boolean` | `false` | When `true`,
|
|
608
|
+
| `modifying` | `boolean` | `false` | When `true`, the method resolves to the number of affected rows. When `false`, runs as a read query and resolves to the declared return type. |
|
|
616
609
|
| `singleResult` | `boolean` | `false` | When `true`, collapses an array result into its first element (`null` if empty), so you can declare the return type as a single object instead of an array. Has no effect on non-array results (e.g. a `modifying` query's affected-row count). |
|
|
617
610
|
|
|
618
611
|
Query methods accept `{ args, db? }` at the call site — `db` lets them participate in a `transaction()` block just like base and dynamic methods.
|
|
@@ -629,6 +622,10 @@ class UserRepository extends VSRepository<User, string> {
|
|
|
629
622
|
declare findByEmailAndType: (
|
|
630
623
|
...args: QueryArgs<[email: string, userType: string]>
|
|
631
624
|
) => Promise<User[]>;
|
|
625
|
+
|
|
626
|
+
// Instead of using `QueryArgs`, you can also simply set `DbArg` as the last parameter
|
|
627
|
+
@QueryMethod('SELECT * FROM "user" WHERE id = $1', { spreadArgs: true })
|
|
628
|
+
declare findById: (id: string, db?: DbArg) => Promise<User[]>;
|
|
632
629
|
}
|
|
633
630
|
|
|
634
631
|
const admins = await userRepository.findByEmailAndType("joao@email.com", "admin");
|
|
@@ -674,7 +671,7 @@ const user = await userRepository.query<User | null>('SELECT * FROM "user" WHERE
|
|
|
674
671
|
| -------------- | --------- | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
675
672
|
| `args` | `any[]` | `undefined` | Positional parameters injected into the SQL placeholders — the placeholder syntax depends on the database/driver behind your adapter. Never interpolate values directly into the SQL string. |
|
|
676
673
|
| `db` | `any` | Repository's default client | Database client or transaction to run this query in. |
|
|
677
|
-
| `modifying` | `boolean` | `false` | When `true`,
|
|
674
|
+
| `modifying` | `boolean` | `false` | When `true`, returns the number of affected rows. |
|
|
678
675
|
| `singleResult` | `boolean` | `false` | When `true`, collapses an array result into its first element (`null` if empty). Has no effect on non-array results (e.g. a `modifying` query's affected-row count). |
|
|
679
676
|
|
|
680
677
|
Just like base, dynamic and query methods, `query()` accepts `db` in `options` to participate in a `transaction()` block.
|
|
@@ -751,12 +748,12 @@ import type {
|
|
|
751
748
|
|
|
752
749
|
| Type | Description | Used by |
|
|
753
750
|
| --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
754
|
-
| `MethodOptions<T, K>` | Options accepted as the last argument
|
|
751
|
+
| `MethodOptions<T, K>` | Options accepted as the last argument by all dynamic methods and most base methods: `select`, `relations`, `see`, `db`. | [Base methods](#base-methods), [Dynamic methods](#dynamic-methods). |
|
|
755
752
|
| `RestrictMethodOptions<T, K>` | Narrowed `MethodOptions<T, K>` exposing only `see`/`db` — used by methods that don't shape/return an `Entity` (`total`, `has`, `sum`, `average`, `min`, `max`, `removeList`, `softRemoveList`, `restoreList`). | [Base methods](#base-methods), [Atomic and aggregate methods](#atomic-and-aggregate-methods). |
|
|
756
753
|
| `Pagination` | `{ limit?, offset? }` accepted by `getAll` and by `Paginated` dynamic methods. | [Base methods](#base-methods), [Ordering, pagination and distinct](#ordering-pagination-and-distinct). |
|
|
757
754
|
| `Ordering<T>` / `OrderByField<T>` / `SortDirection` | Ordering shape accepted by `getAll`, `defaultOrdering` and `injectOrdering`, and by `Ordered` dynamic methods. A single object or a chained array; nested objects order to-one relations. | [Constructor options](#constructor-options), [Decorator options](#decorator-options), [Ordering, pagination and distinct](#ordering-pagination-and-distinct). |
|
|
758
755
|
| `SeeMode` | `"active" \| "removed" \| "all"` — controls visibility of soft-deleted records. | [Soft-delete](#soft-delete). |
|
|
759
|
-
| `DeepPartial<T>` | Recursively makes every property of `T` optional, including nested objects and array elements. | `save`, `saveList`, `patch`, `merge`, and
|
|
756
|
+
| `DeepPartial<T>` | Recursively makes every property of `T` optional, including nested objects and array elements. | `save`, `saveList`, `patch`, `merge`, and all the dynamic writing methods. |
|
|
760
757
|
| `CountResult` | `{ count: number }` — the shape returned by batch operations. | `removeList`, `softRemoveList`, `restoreList`, `createManyIgnoreConflicts`. |
|
|
761
758
|
| `QueryMethodArg<T>` | `{ args?: T, db? }` — positional SQL parameters (the placeholder syntax depends on the database/driver behind your adapter: `$1`, `$2`, ... for PostgreSQL, `?` for MySQL) and transaction client for `@QueryMethod`. | [Query methods (raw SQL)](#query-methods-raw-sql). |
|
|
762
759
|
| `QueryArgs<T, O>` | Types the spread parameter list of a `@QueryMethod` declared with `{ spreadArgs: true }`: `T`'s values in order, followed by an optional trailing `DbArg<O>` built via `withDb()`. | [Spread arguments with `spreadArgs`](#spread-arguments-with-spreadargs). |
|
|
@@ -764,7 +761,7 @@ import type {
|
|
|
764
761
|
| `NumericKeys<T>` | Extracts the keys of `T` whose (non-nullable) value type is assignable to `NumericLike`. Nullable numeric fields (`number \| null`) are included. | Constrains `field` in [Atomic and aggregate methods](#atomic-and-aggregate-methods) (`increment`, `sum`, etc). |
|
|
765
762
|
| `NumericLike` | `number \| bigint \| DecimalLike`. | [Atomic and aggregate methods](#atomic-and-aggregate-methods). |
|
|
766
763
|
| `DecimalLike` | Structural shape of an arbitrary-precision decimal value (`{ toNumber(): number; decimalPlaces(): number }`), matching e.g. Prisma's `Prisma.Decimal` without importing it directly. | [Which fields are eligible](#which-fields-are-eligible). |
|
|
767
|
-
| `Primitive` | Union of scalar types (`string \| number \| boolean \| bigint \| symbol \| undefined \| null \| Date`) treated as leaves — not relations — when walking an entity's shape.
|
|
764
|
+
| `Primitive` | Union of scalar types (`string \| number \| boolean \| bigint \| symbol \| undefined \| null \| Date \| DecimalLike`) treated as leaves — not relations — when walking an entity's shape. | Used by `Ordering<T>` to tell scalar fields apart from relation fields. |
|
|
768
765
|
| `VSRepoWhere<T>` | ORM-agnostic filter type accepted by `*Where` dynamic methods (e.g. `findWhere`, `findOneWhere`, `updateWhere`). Supports field filters, logical operators (`AND`/`OR`/`NOT`), and relation filters. | [`findWhere`, `findOneWhere` and other `*Where` prefixes](#available-prefixes). |
|
|
769
766
|
| `VSRepoOrmTypes` | `{ dbClient; dbTransaction }` — describes your ORM's client/transaction types. Passed as the third generic to `VSRepository<Entity, PKType, OrmTypes>` to type `getDbClient()`, `transaction()` and the `db` option instead of `any`. | [Creating a repository](#creating-a-repository). |
|
|
770
767
|
| `VSRepoTransactionOptions` | `{ isolationLevel?, timeoutMs? }` — options accepted as the second argument of `transaction()`. | [Transactions](#transactions). |
|
|
@@ -947,13 +944,13 @@ export class MyOrmAdapter<T> extends VSRepoAdapter<T> {
|
|
|
947
944
|
}
|
|
948
945
|
```
|
|
949
946
|
|
|
950
|
-
| Method | Description
|
|
951
|
-
| ---------------------------------------------------- |
|
|
952
|
-
| `new VSLogger(logLevel, name, slowThresholdMs?)` | Creates a logger; `name` prefixes every line
|
|
953
|
-
| `logDebug/logInfo/logWarn(text, obj?)` | Logs at the given level if `logLevel` allows it; `obj` is appended as pretty-printed JSON.
|
|
954
|
-
| `logError(text, err?)` | Logs at `ERROR`; if `err` is an `Error`, only `name`/`message`/`stack`/`cause` are logged.
|
|
955
|
-
| `startPerformLog(operation)` / `endPerformLog(data)` | Bracket a block to log its duration, escalating to `WARN` if it exceeds `slowThresholdMs`.
|
|
956
|
-
| `getLogLevel()` | Returns the logger's configured `VSLogLevel`.
|
|
947
|
+
| Method | Description |
|
|
948
|
+
| ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
949
|
+
| `new VSLogger(logLevel, name, slowThresholdMs?)` | Creates a logger; `name` prefixes every line. `slowThresholdMs` controls the slow-operation threshold: a `number` sets it in ms (default 300), `false` disables slow-operation warnings entirely, `true` or omitted uses the 300ms default. |
|
|
950
|
+
| `logDebug/logInfo/logWarn(text, obj?)` | Logs at the given level if `logLevel` allows it; `obj` is appended as pretty-printed JSON. |
|
|
951
|
+
| `logError(text, err?)` | Logs at `ERROR`; if `err` is an `Error`, only `name`/`message`/`stack`/`cause` are logged. |
|
|
952
|
+
| `startPerformLog(operation)` / `endPerformLog(data)` | Bracket a block to log its duration, escalating to `WARN` if it exceeds `slowThresholdMs`. |
|
|
953
|
+
| `getLogLevel()` | Returns the logger's configured `VSLogLevel`. |
|
|
957
954
|
|
|
958
955
|
This is purely a convenience for adapter authors — nothing in the core requires your adapter to use it.
|
|
959
956
|
|
|
@@ -1088,7 +1085,8 @@ super({
|
|
|
1088
1085
|
pkName: "id",
|
|
1089
1086
|
adapter,
|
|
1090
1087
|
logLevel: VSLogLevel.DEBUG,
|
|
1091
|
-
logSlowThresholdMs: 200,
|
|
1088
|
+
logSlowThresholdMs: 200, // warn if any operation takes > 200ms
|
|
1089
|
+
// logSlowThresholdMs: false, // disable slow-operation warnings entirely
|
|
1092
1090
|
});
|
|
1093
1091
|
```
|
|
1094
1092
|
|
|
@@ -1150,11 +1148,11 @@ Notes:
|
|
|
1150
1148
|
|
|
1151
1149
|
## Contributing
|
|
1152
1150
|
|
|
1153
|
-
Contributions are welcome, especially
|
|
1151
|
+
Contributions are welcome, especially for improving the Prisma adapter and finishing the Drizzle one! (**[GitHub repository](https://github.com/jaobrabo123/VSRepository)**):
|
|
1154
1152
|
|
|
1155
1153
|
1. **Fork** the project.
|
|
1156
|
-
2. Create a branch
|
|
1154
|
+
2. Create a branch for your change: `git checkout -b v2-my-change`.
|
|
1157
1155
|
3. Push your branch: `git push origin v2-my-change`.
|
|
1158
|
-
4. Open a **Pull Request
|
|
1156
|
+
4. Open a **Pull Request**.
|
|
1159
1157
|
|
|
1160
1158
|
To report issues or suggest features, open an **Issue**.
|
package/README.pt-BR.md
CHANGED
|
@@ -13,16 +13,14 @@
|
|
|
13
13
|
|
|
14
14
|
🇧🇷 Você está lendo a versão em português. [🇺🇸 Read in English](./README.md)
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
Biblioteca de repository pattern **agnóstica de ORM**, com suporte completo a **TypeScript** e **type inference** automático. O VSRepository v2 é uma reescrita da biblioteca [v1](https://github.com/jaobrabo123/VSRepository/tree/v1): em vez de falar diretamente com o Prisma, o núcleo agora delega toda operação a um **adapter** plugável, permitindo que a mesma API de repository funcione com Prisma, TypeORM ou qualquer outro ORM/banco que implemente o contrato de adapter.
|
|
16
|
+
Biblioteca de repository pattern **agnóstica de ORM**, com suporte completo a **TypeScript** e **type inference** automático. O VSRepository v2 é uma reescrita da biblioteca [v1](https://github.com/jaobrabo123/VSRepository/tree/v1): em vez de falar diretamente com o Prisma, o núcleo agora delega toda operação a um **adapter** plugável, permitindo que a mesma API de repository funcione com Prisma, Drizzle ou qualquer outro ORM/banco que implemente o contrato de adapter.
|
|
19
17
|
|
|
20
18
|
O VSRepository permite criar repositories fortemente tipados com:
|
|
21
19
|
|
|
22
20
|
- **Métodos base** automáticos: `get`, `getOrThrow`, `getList`, `save`, `saveList`, `remove`, `removeList`, `patch`, `merge`, `getAll`, `total`, `has`
|
|
23
21
|
- **Soft-delete nativo**: `softRemove`, `softRemoveList`, `restore`, `restoreList`
|
|
24
22
|
- **Métodos dinâmicos** inferidos a partir do nome de um campo `declare` via o decorador `@DynamicMethod`: `findByEmail`, `findManyByStatusPaginated`, `updateById`
|
|
25
|
-
- **Métodos de query SQL raw** através do
|
|
23
|
+
- **Métodos de query SQL raw** através do decorador `@QueryMethod`, ignorando totalmente o engine de parsing por nome
|
|
26
24
|
- **`select`/`relations`** ad-hoc em cada chamada — sem mais projeções nomeadas pré-declaradas
|
|
27
25
|
- **Type safety** em 100% das operações
|
|
28
26
|
- **Transações** nativas do ORM, compartilhadas entre repositories
|
|
@@ -71,16 +69,16 @@ Se você vem do código/docs da [v1](https://github.com/jaobrabo123/VSRepository
|
|
|
71
69
|
|
|
72
70
|
| Área | v1 | v2 |
|
|
73
71
|
| ------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
74
|
-
| Acesso ao banco | Fala diretamente com o **Prisma**, embutido no pacote core | Fala com um **`VSRepoAdapter`**; o suporte a cada ORM é distribuído em pacotes separados (`@vsrepo/prisma7-adapter`, `@vsrepo/
|
|
72
|
+
| Acesso ao banco | Fala diretamente com o **Prisma**, embutido no pacote core | Fala com um **`VSRepoAdapter`**; o suporte a cada ORM é distribuído em pacotes separados (`@vsrepo/prisma7-adapter`, `@vsrepo/drizzle-adapter`, ...) em vez de vir embutido no pacote core `vsrepo` |
|
|
75
73
|
| Definindo um repository | `setupVSRepo<T, M>()({...}).build(prisma)` funcional, **ou** uma classe `DynamicRepository` | Uma única API **baseada em classes**: `extends VSRepository<Entity, PKType, OrmTypes>` |
|
|
76
74
|
| Métodos dinâmicos | Objeto de config `methods: { findByEmail: { map: true } }` | Decorador `@DynamicMethod()` em um campo `declare` |
|
|
77
75
|
| Projeções de dados | `selectModels` + `defaultSelectModel` nomeados e reutilizáveis | `select`/`relations` ad-hoc passados em cada chamada (sem modelos nomeados) |
|
|
78
76
|
| Eager loading | `include`/`includeModels` (específico do Prisma) | Option `relations` agnóstica de ORM |
|
|
79
|
-
| Filtros globais | `requiredWhere`
|
|
77
|
+
| Filtros globais | `requiredWhere` e `pushWhere` | **Removidos**; Agora aceita apenas `softRemoveKey` + `see: "active" \| "removed" \| "all"` |
|
|
80
78
|
| Sufixo de filtro case-insensitive | `Insensitive` | `IgnoreCase` |
|
|
81
79
|
| Ordenação inline no nome do método | Não suportado (`order` tinha que ser passado como argumento via `Ordered`/`Paginated`) | Cadeias `OrderBy<Campo>Asc`/`OrderBy<Campo>Desc` embutidas diretamente no nome do método |
|
|
82
80
|
| Tratamento de duplicatas no `createMany` | Sufixo `SkipDuplicates` | Sufixo `IgnoreConflicts` |
|
|
83
|
-
| `aggregate` / `groupBy` | Suportado (passthrough nativo do Prisma) | **
|
|
81
|
+
| `aggregate` / `groupBy` | Suportado (passthrough nativo do Prisma) | `groupBy` **não está planejado** para a v2. Um prefixo `aggregate` separado também dificilmente será implementado: as operações mais comuns já são cobertas por métodos base dedicados (`sum`, `average`, `min`, `max`, `increment`, `decrement`, `multiply`, `divide`) — veja [Métodos atômicos e de agregação](#métodos-atômicos-e-de-agregação). Para qualquer coisa mais complexa, use `@QueryMethod`. |
|
|
84
82
|
| Tipos de erro | `VSRepoError` + subclasses (`VSRepoConfigError`, `VSRepoBuildError`, `VSRepoExtendError`, `VSRepoRuntimeError`) | Uma classe base `VSRepoError` com um campo `type: VSRepoErrorType` (`DECORATOR`, `RESOLVER`, `DYNAMIC`, `VALIDATOR`, `BASE`, `ADAPTER`), além de uma subclasse `VSRepoAdapterError` que carrega um `AdapterErrorCode` e o erro original do ORM |
|
|
85
83
|
| Log de debug | Boolean `showWorking: true` | `logLevel: VSLogLevel` (`DEBUG`/`INFO`/`WARN`/`ERROR`) + `logSlowThresholdMs` para avisos de queries lentas |
|
|
86
84
|
| CLI `vsrepo generate` (etapa de geração de tipos) | Obrigatória antes de usar | Não faz parte do núcleo da v2 — os tipos vêm diretamente das suas entidades/tipos do ORM |
|
|
@@ -97,17 +95,16 @@ O VSRepository v2 é **agnóstico de ORM por design**. O pacote core (`vsrepo`)
|
|
|
97
95
|
- `@vsrepo/typeorm-adapter`
|
|
98
96
|
- `@vsrepo/drizzle-adapter`
|
|
99
97
|
|
|
100
|
-
O adapter do Prisma 7 já foi publicado no npm como `@vsrepo/prisma7-adapter
|
|
98
|
+
O adapter do Prisma 7 já foi publicado no npm como `@vsrepo/prisma7-adapter`. O adapter do Drizzle está disponível em versão **alpha** — instale com `npm i @vsrepo/drizzle-adapter@alpha`. Os adapters para outros ORMs estão **planejados**, mas ainda não foram publicados. Até que exista um pacote `@vsrepo/*-adapter` oficial para o seu ORM, você pode escrever o seu próprio para o seu projeto e, se quiser, publicá-lo e abrir um PR para ajudar a fazer o ecossistema crescer — contribuições nesse sentido são muito bem-vindas.
|
|
101
99
|
|
|
102
|
-
| Adapter
|
|
103
|
-
|
|
|
104
|
-
| Prisma 7 (`@vsrepo/prisma7-adapter`)
|
|
105
|
-
| Drizzle (`@vsrepo/drizzle-adapter`)
|
|
106
|
-
| TypeORM
|
|
107
|
-
|
|
|
108
|
-
| Adapters customizados | 🟢 Totalmente suportados hoje — implemente você mesmo a classe abstrata [`VSRepoAdapter`](#escrevendo-seu-próprio-adapter) para qualquer ORM/banco que precisar, no seu próprio projeto ou pacote, seguindo o mesmo formato esperado dos `@vsrepo/*-adapter`. |
|
|
100
|
+
| Adapter | Status |
|
|
101
|
+
| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
102
|
+
| Prisma 7 (`@vsrepo/prisma7-adapter`) | 🟢 **Lançado** — publicado no npm, implementa o contrato de `VSRepoAdapter` (CRUD, relations, transactions, `merge`, logging) com testes; veja o [`VSRepoPrisma7Adapter`](https://github.com/jaobrabo123/VSRepoPrisma7Adapter) para o código-fonte e docs. **Nota:** os métodos atômicos/de agregação (`incrementOne`, `decrementOne`, `multiplyOne`, `divideOne`, `sum`, `average`, `min`, `max` — veja [Métodos atômicos e de agregação](#métodos-atômicos-e-de-agregação)) foram adicionados ao contrato do `VSRepoAdapter` depois do último release desse adapter; confirme no changelog/versão dele se já implementam esses métodos antes de depender de `increment`/`sum`/etc. contra o Prisma 7. |
|
|
103
|
+
| Drizzle (`@vsrepo/drizzle-adapter`) | 🔵 **Alpha** — uma versão inicial já está disponível no npm; instale com `npm i @vsrepo/drizzle-adapter@alpha`. A API ainda pode mudar antes do release estável. Veja o repositório do [`DrizzleAdapter`](https://github.com/jaobrabo123/VSRepoDrizzleAdapter) para o estado atual e limitações conhecidas, e sinta-se à vontade para contribuir. |
|
|
104
|
+
| Outros ORMs (Prisma 8, TypeORM, etc.) | 🟡 **Planejados, ainda não publicados.** Nenhum pacote oficial existe ainda — por enquanto, escreva o seu próprio adapter (veja [Escrevendo seu próprio adapter](#escrevendo-seu-próprio-adapter)) e considere publicá-lo/contribuir de volta com o projeto. |
|
|
105
|
+
| Adapters customizados | 🟢 Totalmente suportados hoje — implemente você mesmo a classe abstrata [`VSRepoAdapter`](#escrevendo-seu-próprio-adapter) para qualquer ORM/banco que precisar, no seu próprio projeto ou pacote, seguindo o mesmo formato esperado dos `@vsrepo/*-adapter`. |
|
|
109
106
|
|
|
110
|
-
Resumindo: a classe de repository, os decoradores `@DynamicMethod`/`@QueryMethod`, o engine de parsing de nomes, o tratamento de erros e o logging já funcionam de ponta a ponta, e o suporte ao Prisma 7 agora é um adapter lançado e publicado. Adapters oficiais para os demais ORMs estão no roadmap e serão distribuídos como pacotes `@vsrepo/*-adapter` separados, e não como parte do pacote core `vsrepo` — mas você não precisa esperar por isso: escrever (e opcionalmente publicar) o seu próprio adapter enquanto isso é uma forma totalmente suportada de usar a v2 hoje e de contribuir de volta com o projeto.
|
|
107
|
+
Resumindo: a classe de repository, os decoradores `@DynamicMethod`/`@QueryMethod`, o engine de parsing de nomes, o tratamento de erros e o logging já funcionam de ponta a ponta, e o suporte ao Prisma 7 agora é um adapter lançado e publicado. O adapter do Drizzle está disponível em alpha. Adapters oficiais para os demais ORMs estão no roadmap e serão distribuídos como pacotes `@vsrepo/*-adapter` separados, e não como parte do pacote core `vsrepo` — mas você não precisa esperar por isso: escrever (e opcionalmente publicar) o seu próprio adapter enquanto isso é uma forma totalmente suportada de usar a v2 hoje e de contribuir de volta com o projeto.
|
|
111
108
|
|
|
112
109
|
---
|
|
113
110
|
|
|
@@ -209,14 +206,14 @@ await userRepository.remove(usuario.id);
|
|
|
209
206
|
|
|
210
207
|
`VSRepoOptions<T, K>`, passado para o `super(...)` dentro do construtor do seu repository:
|
|
211
208
|
|
|
212
|
-
| Option | Tipo
|
|
213
|
-
| -------------------- |
|
|
214
|
-
| `adapter` | `VSRepoAdapter<T>`
|
|
215
|
-
| `pkName` | `keyof T`
|
|
216
|
-
| `softRemoveKey` | `keyof T`
|
|
217
|
-
| `defaultOrdering` | `Ordering<T>`
|
|
218
|
-
| `logLevel` | `VSLogLevel`
|
|
219
|
-
| `logSlowThresholdMs` | `number`
|
|
209
|
+
| Option | Tipo | Descrição |
|
|
210
|
+
| -------------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
211
|
+
| `adapter` | `VSRepoAdapter<T>` | **Obrigatório.** A instância do adapter que traduz as chamadas do repository em chamadas contra o ORM/banco por trás dele. |
|
|
212
|
+
| `pkName` | `keyof T` | **Obrigatório.** Nome do campo que representa a primary key da entidade. |
|
|
213
|
+
| `softRemoveKey` | `keyof T` | Opcional. Quando definido, habilita `softRemove`, `softRemoveList`, `restore` e `restoreList`. |
|
|
214
|
+
| `defaultOrdering` | `Ordering<T>` | Opcional. Ordenação padrão aplicada automaticamente em queries que aceitam `order`, a menos que seja sobrescrita em uma chamada específica. |
|
|
215
|
+
| `logLevel` | `VSLogLevel` | Opcional. Severidade mínima impressa pelo logger interno. Padrão: `VSLogLevel.WARN`. |
|
|
216
|
+
| `logSlowThresholdMs` | `number \| boolean` | Opcional. Duração (ms) acima da qual uma operação concluída é logada como `WARN`. Padrão: 300ms. Passe `false` para desabilitar completamente os avisos de operação lenta; passe `true` para usar explicitamente o threshold padrão de 300ms. |
|
|
220
217
|
|
|
221
218
|
---
|
|
222
219
|
|
|
@@ -247,7 +244,7 @@ Disponíveis automaticamente em toda subclasse de `VSRepository`:
|
|
|
247
244
|
| `min(field, where?, options?)` | Valor mínimo de um campo numérico em todos os registros que baterem no filtro; `null` se nenhum bater. |
|
|
248
245
|
| `max(field, where?, options?)` | Valor máximo de um campo numérico em todos os registros que baterem no filtro; `null` se nenhum bater. |
|
|
249
246
|
| `transaction(fn, options?)` | Executa `fn` dentro de uma transação nativa do ORM. |
|
|
250
|
-
| `getDbClient()` | Retorna a instância do client do ORM
|
|
247
|
+
| `getDbClient()` | Retorna a instância do client do ORM. |
|
|
251
248
|
| `query<T>(query, options?)` | Executa uma instrução SQL raw diretamente contra o banco. Veja [Queries raw pontuais com `query()`](#queries-raw-pontuais-com-query). |
|
|
252
249
|
|
|
253
250
|
A maioria dos métodos acima aceita um objeto `MethodOptions<Entity, OrmTypes>` como último argumento (`select`, `relations`, `see`, `db`). Alguns — `total`, `has`, `removeList`, `sum`, `average`, `min`, `max`, e os métodos em lote de soft-delete (`softRemoveList`/`restoreList`) — não retornam/moldam uma `Entity`, então aceitam o tipo mais restrito `RestrictMethodOptions<Entity, OrmTypes>` (só `see`, `db`; sem `select`/`relations`). `transaction`, `query` e `getDbClient` recebem options próprias ou nenhuma.
|
|
@@ -256,7 +253,7 @@ A maioria dos métodos acima aceita um objeto `MethodOptions<Entity, OrmTypes>`
|
|
|
256
253
|
|
|
257
254
|
## Soft-delete
|
|
258
255
|
|
|
259
|
-
O soft-delete
|
|
256
|
+
O soft-delete é um **conceito nativo de primeira classe**. Configure `softRemoveKey` uma vez no repository:
|
|
260
257
|
|
|
261
258
|
```typescript
|
|
262
259
|
super({
|
|
@@ -363,14 +360,6 @@ const usuarioComEndereco = await userRepository.get(id, {
|
|
|
363
360
|
>
|
|
364
361
|
> O core apenas repassa `MethodOptions.select` e `MethodOptions.relations` ao adapter — cada adapter decide como traduzi-los para o ORM subjacente:
|
|
365
362
|
>
|
|
366
|
-
> - **TypeORM (`@vsrepo/typeorm-adapter`)** — `relations` é **obrigatório** para carregar qualquer relação, mesmo quando você quer apenas uma projeção aninhada via `select`. O TypeORM não fará JOIN/carregar a relação a menos que ela esteja listada em `relations`:
|
|
367
|
-
> ```typescript
|
|
368
|
-
> // TypeORM: apenas select NÃO é suficiente
|
|
369
|
-
> await userRepository.get(id, {
|
|
370
|
-
> select: { id: true, address: { city: true } },
|
|
371
|
-
> relations: { address: true }, // ← obrigatório no TypeORM
|
|
372
|
-
> });
|
|
373
|
-
> ```
|
|
374
363
|
> - **Prisma 7 (`@vsrepo/prisma7-adapter` / `VSRepoPrisma7Adapter`)** — `relations` é convertido para `include` do Prisma (`parsePrismaInclude`). **Se `select` estiver presente, `relations` é ignorado** porque o Prisma não permite `select` + `include` na mesma query:
|
|
375
364
|
> ```typescript
|
|
376
365
|
> // Prisma7: relations é ignorado quando select existe
|
|
@@ -391,7 +380,7 @@ Métodos dinâmicos são declarados como um campo `declare` anotado com `@Dynami
|
|
|
391
380
|
```typescript
|
|
392
381
|
class UserRepository extends VSRepository<User, string> {
|
|
393
382
|
@DynamicMethod()
|
|
394
|
-
declare findByEmail: (email: string) => Promise<User[]>;
|
|
383
|
+
declare findByEmail: (email: string, options?: MethodOptions<User>) => Promise<User[]>;
|
|
395
384
|
|
|
396
385
|
@DynamicMethod()
|
|
397
386
|
declare findOneByEmail: (email: string) => Promise<User | null>;
|
|
@@ -407,12 +396,11 @@ class UserRepository extends VSRepository<User, string> {
|
|
|
407
396
|
options?: MethodOptions<User>,
|
|
408
397
|
) => Promise<User[]>;
|
|
409
398
|
|
|
410
|
-
//
|
|
399
|
+
// filtros de campo, depois pagination, depois MethodOptions
|
|
411
400
|
@DynamicMethod()
|
|
412
401
|
declare findByNameIgnoreCaseOrAgeBetweenOrderByCreatedAtAscPaginated: (
|
|
413
402
|
name: string,
|
|
414
403
|
age: [number, number],
|
|
415
|
-
order: Ordering<User>,
|
|
416
404
|
pagination: Pagination,
|
|
417
405
|
options?: MethodOptions<User>,
|
|
418
406
|
) => Promise<User[]>;
|
|
@@ -421,40 +409,40 @@ class UserRepository extends VSRepository<User, string> {
|
|
|
421
409
|
|
|
422
410
|
### Prefixos disponíveis
|
|
423
411
|
|
|
424
|
-
| Prefixo | Método do adapter | Observações
|
|
425
|
-
| -------------------------- | --------------------- |
|
|
426
|
-
| `findBy` | `findMany` | Filtros de campo seguem o prefixo.
|
|
427
|
-
| `findOneBy` | `findOne` | Filtros de campo seguem o prefixo; resultado único.
|
|
428
|
-
| `findOneOrThrowBy` | `findOneOrThrow` | Lança erro se não encontrar.
|
|
429
|
-
| `findOneOrThrow` | `findOneOrThrow` | Sem filtros de campo; aplica só soft-delete/`see`.
|
|
430
|
-
| `findOneOrThrowWhere` | `findOneOrThrow` | Recebe um `VSRepoWhere<T>` como primeiro argumento.
|
|
431
|
-
| `findWhere` | `findMany` | Recebe um `VSRepoWhere<T>` como primeiro argumento.
|
|
432
|
-
| `findOneWhere` | `findOne` | Recebe um `VSRepoWhere<T>` como primeiro argumento.
|
|
433
|
-
| `findOne` | `findOne` | Sem filtros de campo; aplica só soft-delete/`see`.
|
|
434
|
-
| `countBy` | `count` | Filtros de campo seguem o prefixo.
|
|
435
|
-
| `countWhere` | `count` | Recebe um `VSRepoWhere<T>` como primeiro argumento.
|
|
436
|
-
| `count` | `count` | Sem filtros de campo.
|
|
437
|
-
| `existsBy` | `exists` | Retorna `boolean`.
|
|
438
|
-
| `existsWhere` | `exists` | Recebe um `VSRepoWhere<T>` como primeiro argumento.
|
|
439
|
-
| `create` | `create` | Recebe `
|
|
440
|
-
| `createMany` | `createMany` | Recebe `
|
|
441
|
-
| `createManyReturning` | `createManyReturning` | Recebe `
|
|
442
|
-
| `updateBy` | `update` | Filtros de campo + `
|
|
443
|
-
| `updateWhere` | `update` | Recebe um `VSRepoWhere<T>` como primeiro argumento, depois `
|
|
444
|
-
| `updateManyBy` | `updateMany` | Filtros de campo + `
|
|
445
|
-
| `updateManyWhere` | `updateMany` | Recebe um `VSRepoWhere<T>` como primeiro argumento, depois `
|
|
446
|
-
| `updateManyReturningBy` | `updateManyReturning` | Filtros de campo + `
|
|
447
|
-
| `updateManyReturningWhere` | `updateManyReturning` | Recebe um `VSRepoWhere<T>` como primeiro argumento, depois `
|
|
448
|
-
| `upsertBy` | `upsert` | Filtros de campo + payloads `create`/`update`.
|
|
449
|
-
| `upsertWhere` | `upsert` | Recebe um `VSRepoWhere<T>` como primeiro argumento, depois os payloads `create`/`update`.
|
|
450
|
-
| `deleteBy` | `delete` | Filtros de campo seguem o prefixo.
|
|
451
|
-
| `deleteWhere` | `delete` | Recebe um `VSRepoWhere<T>` como primeiro argumento.
|
|
452
|
-
| `deleteManyBy` | `deleteMany` | Filtros de campo seguem o prefixo.
|
|
453
|
-
| `deleteManyWhere` | `deleteMany` | Recebe um `VSRepoWhere<T>` como primeiro argumento.
|
|
454
|
-
| `deleteManyReturningBy` | `deleteManyReturning` | Filtros de campo seguem o prefixo; retorna os registros removidos.
|
|
455
|
-
| `deleteManyReturningWhere` | `deleteManyReturning` | Recebe um `VSRepoWhere<T>` como primeiro argumento; retorna os registros removidos.
|
|
456
|
-
|
|
457
|
-
> `aggregate`
|
|
412
|
+
| Prefixo | Método do adapter | Observações |
|
|
413
|
+
| -------------------------- | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
|
|
414
|
+
| `findBy` | `findMany` | Filtros de campo seguem o prefixo. |
|
|
415
|
+
| `findOneBy` | `findOne` | Filtros de campo seguem o prefixo; resultado único. |
|
|
416
|
+
| `findOneOrThrowBy` | `findOneOrThrow` | Lança erro se não encontrar. |
|
|
417
|
+
| `findOneOrThrow` | `findOneOrThrow` | Sem filtros de campo; aplica só soft-delete/`see`. |
|
|
418
|
+
| `findOneOrThrowWhere` | `findOneOrThrow` | Recebe um `VSRepoWhere<T>` como primeiro argumento. |
|
|
419
|
+
| `findWhere` | `findMany` | Recebe um `VSRepoWhere<T>` como primeiro argumento. |
|
|
420
|
+
| `findOneWhere` | `findOne` | Recebe um `VSRepoWhere<T>` como primeiro argumento. |
|
|
421
|
+
| `findOne` | `findOne` | Sem filtros de campo; aplica só soft-delete/`see`. |
|
|
422
|
+
| `countBy` | `count` | Filtros de campo seguem o prefixo. |
|
|
423
|
+
| `countWhere` | `count` | Recebe um `VSRepoWhere<T>` como primeiro argumento. |
|
|
424
|
+
| `count` | `count` | Sem filtros de campo. |
|
|
425
|
+
| `existsBy` | `exists` | Retorna `boolean`. |
|
|
426
|
+
| `existsWhere` | `exists` | Recebe um `VSRepoWhere<T>` como primeiro argumento. |
|
|
427
|
+
| `create` | `create` | Recebe `DeepPartial<Entity>` como argumento. |
|
|
428
|
+
| `createMany` | `createMany` | Recebe `DeepPartial<Entity>[]` como argumento; suporta `IgnoreConflicts`. |
|
|
429
|
+
| `createManyReturning` | `createManyReturning` | Recebe `DeepPartial<Entity>[]` como argumento; suporta `IgnoreConflicts`; retorna os registros criados (`T[]`), em vez de `CountResult`. |
|
|
430
|
+
| `updateBy` | `update` | Filtros de campo + `DeepPartial<Entity>` como argumento. |
|
|
431
|
+
| `updateWhere` | `update` | Recebe um `VSRepoWhere<T>` como primeiro argumento, depois `DeepPartial<Entity>`. |
|
|
432
|
+
| `updateManyBy` | `updateMany` | Filtros de campo + `DeepPartial<Entity>`. |
|
|
433
|
+
| `updateManyWhere` | `updateMany` | Recebe um `VSRepoWhere<T>` como primeiro argumento, depois `DeepPartial<Entity>`. |
|
|
434
|
+
| `updateManyReturningBy` | `updateManyReturning` | Filtros de campo + `DeepPartial<Entity>`; retorna os registros atualizados. |
|
|
435
|
+
| `updateManyReturningWhere` | `updateManyReturning` | Recebe um `VSRepoWhere<T>` como primeiro argumento, depois `DeepPartial<Entity>`; retorna os registros atualizados. |
|
|
436
|
+
| `upsertBy` | `upsert` | Filtros de campo + payloads `create`/`update`. |
|
|
437
|
+
| `upsertWhere` | `upsert` | Recebe um `VSRepoWhere<T>` como primeiro argumento, depois os payloads `create`/`update`. |
|
|
438
|
+
| `deleteBy` | `delete` | Filtros de campo seguem o prefixo. |
|
|
439
|
+
| `deleteWhere` | `delete` | Recebe um `VSRepoWhere<T>` como primeiro argumento. |
|
|
440
|
+
| `deleteManyBy` | `deleteMany` | Filtros de campo seguem o prefixo. |
|
|
441
|
+
| `deleteManyWhere` | `deleteMany` | Recebe um `VSRepoWhere<T>` como primeiro argumento. |
|
|
442
|
+
| `deleteManyReturningBy` | `deleteManyReturning` | Filtros de campo seguem o prefixo; retorna os registros removidos. |
|
|
443
|
+
| `deleteManyReturningWhere` | `deleteManyReturning` | Recebe um `VSRepoWhere<T>` como primeiro argumento; retorna os registros removidos. |
|
|
444
|
+
|
|
445
|
+
> `groupBy` **não está planejado** para a v2 — ele não se encaixa bem no contrato agnóstico de ORM. Um prefixo `aggregate` separado também dificilmente será implementado: as operações de agregação mais comuns (`sum`, `average`, `min`, `max`, `increment`, `decrement`, `multiply`, `divide`) já estão disponíveis como métodos base dedicados — veja [Métodos atômicos e de agregação](#métodos-atômicos-e-de-agregação). Para qualquer coisa mais complexa, use um `@QueryMethod` com SQL raw.
|
|
458
446
|
|
|
459
447
|
### Filtros de campo
|
|
460
448
|
|
|
@@ -585,6 +573,11 @@ declare findOne: (options?: MethodOptions<User>) => Promise<User | null>;
|
|
|
585
573
|
| `injectOrdering` | `Ordering<T>` | Ordenação fixa injetada automaticamente, sobrescrevendo o `defaultOrdering` do repository. |
|
|
586
574
|
|
|
587
575
|
```typescript
|
|
576
|
+
// proxyTo: dá um nome customizado ao método reutilizando um padrão existente
|
|
577
|
+
@DynamicMethod<User>({ proxyTo: "findByEmail" })
|
|
578
|
+
declare buscarPorEmail: (email: string, options?: MethodOptions<User>) => Promise<User[]>;
|
|
579
|
+
|
|
580
|
+
// injectOrdering: sempre ordena por createdAt desc, sobrescrevendo o defaultOrdering
|
|
588
581
|
@DynamicMethod<User>({ injectOrdering: { createdAt: "desc" } })
|
|
589
582
|
declare findByStatus: (status: string) => Promise<User[]>;
|
|
590
583
|
```
|
|
@@ -612,7 +605,7 @@ class UserRepository extends VSRepository<User, string> {
|
|
|
612
605
|
|
|
613
606
|
| Option | Tipo | Padrão | Descrição |
|
|
614
607
|
| -------------- | --------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
615
|
-
| `modifying` | `boolean` | `false` | Quando `true`,
|
|
608
|
+
| `modifying` | `boolean` | `false` | Quando `true`, o método resolve para o número de linhas afetadas. Quando `false`, executa como query de leitura e resolve para o tipo de retorno declarado. |
|
|
616
609
|
| `singleResult` | `boolean` | `false` | Quando `true`, transforma um resultado em array no seu primeiro elemento (`null` se vazio), permitindo declarar o tipo de retorno como um objeto único em vez de array. Não tem efeito em resultados que não são array (ex.: o número de linhas afetadas de uma query `modifying`). |
|
|
617
610
|
|
|
618
611
|
Query methods aceitam `{ args, db? }` na chamada — `db` permite que participem de um bloco `transaction()`, assim como os métodos base e dinâmicos.
|
|
@@ -629,6 +622,10 @@ class UserRepository extends VSRepository<User, string> {
|
|
|
629
622
|
declare findByEmailAndType: (
|
|
630
623
|
...args: QueryArgs<[email: string, userType: string]>
|
|
631
624
|
) => Promise<User[]>;
|
|
625
|
+
|
|
626
|
+
// Ao invés de usar o `QueryArgs`, você também pode simplesmente definir `DbArg` como último parâmetro
|
|
627
|
+
@QueryMethod('SELECT * FROM "user" WHERE id = $1', { spreadArgs: true })
|
|
628
|
+
declare findById: (id: string, db?: DbArg) => Promise<User[]>;
|
|
632
629
|
}
|
|
633
630
|
|
|
634
631
|
const admins = await userRepository.findByEmailAndType("joao@email.com", "admin");
|
|
@@ -674,7 +671,7 @@ const user = await userRepository.query<User | null>('SELECT * FROM "user" WHERE
|
|
|
674
671
|
| -------------- | --------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
675
672
|
| `args` | `any[]` | `undefined` | Parâmetros posicionais injetados nos placeholders do SQL — a sintaxe dos placeholders depende do banco/driver usado pelo seu adapter. Nunca interpole valores diretamente na string SQL. |
|
|
676
673
|
| `db` | `any` | Client padrão do repository | Client ou transação do banco em que essa query deve rodar. |
|
|
677
|
-
| `modifying` | `boolean` | `false` | Quando `true`,
|
|
674
|
+
| `modifying` | `boolean` | `false` | Quando `true`, retorna o número de linhas afetadas. |
|
|
678
675
|
| `singleResult` | `boolean` | `false` | Quando `true`, transforma um resultado em array no seu primeiro elemento (`null` se vazio). Não tem efeito em resultados que não são array (ex.: o número de linhas afetadas de uma query `modifying`). |
|
|
679
676
|
|
|
680
677
|
Assim como os métodos base, dinâmicos e query, `query()` aceita `db` em `options` para participar de um bloco `transaction()`.
|
|
@@ -754,12 +751,12 @@ import type {
|
|
|
754
751
|
|
|
755
752
|
| Tipo | Descrição | Usado por |
|
|
756
753
|
| --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
757
|
-
| `MethodOptions<T, K>` | Options aceitas como último argumento pela maioria dos métodos base
|
|
754
|
+
| `MethodOptions<T, K>` | Options aceitas como último argumento por todos os métodos dinâmicos e pela maioria dos métodos base: `select`, `relations`, `see`, `db`. | [Métodos base](#métodos-base), [Métodos Dinâmicos](#métodos-dinâmicos). |
|
|
758
755
|
| `RestrictMethodOptions<T, K>` | `MethodOptions<T, K>` restrito, expondo só `see`/`db` — usado pelos métodos que não retornam/moldam uma `Entity` (`total`, `has`, `sum`, `average`, `min`, `max`, `removeList`, `softRemoveList`, `restoreList`). | [Métodos base](#métodos-base), [Métodos atômicos e de agregação](#métodos-atômicos-e-de-agregação). |
|
|
759
756
|
| `Pagination` | `{ limit?, offset? }` aceito por `getAll` e pelos métodos dinâmicos com `Paginated`. | [Métodos base](#métodos-base), [Ordenação, paginação e distinct](#ordenação-paginação-e-distinct). |
|
|
760
757
|
| `Ordering<T>` / `OrderByField<T>` / `SortDirection` | Formato de ordenação aceito por `getAll`, `defaultOrdering` e `injectOrdering`, e pelos métodos dinâmicos com `Ordered`. Pode ser um único objeto ou um array encadeado; objetos aninhados ordenam relações to-one. | [Options do construtor](#options-do-construtor), [Options do decorador](#options-do-decorador), [Ordenação, paginação e distinct](#ordenação-paginação-e-distinct). |
|
|
761
758
|
| `SeeMode` | `"active" \| "removed" \| "all"` — controla a visibilidade de registros com soft-delete. | [Soft-delete](#soft-delete). |
|
|
762
|
-
| `DeepPartial<T>` | Torna todas as propriedades de `T` opcionais recursivamente, incluindo objetos aninhados e elementos de array. | `save`, `saveList`, `patch`, `merge`, e todo
|
|
759
|
+
| `DeepPartial<T>` | Torna todas as propriedades de `T` opcionais recursivamente, incluindo objetos aninhados e elementos de array. | `save`, `saveList`, `patch`, `merge`, e todo os métodos dinâmicos de escrita. |
|
|
763
760
|
| `CountResult` | `{ count: number }` — o formato retornado por operações em lote. | `removeList`, `softRemoveList`, `restoreList`, `createManyIgnoreConflicts`. |
|
|
764
761
|
| `QueryMethodArg<T>` | `{ args?: T, db? }` — parâmetros posicionais do SQL (a sintaxe dos placeholders depende do banco/driver usado pelo seu adapter: `$1`, `$2`, ... para PostgreSQL, `?` para MySQL) e cliente de transação para o `@QueryMethod`. | [Query methods (SQL raw)](#query-methods-sql-raw). |
|
|
765
762
|
| `QueryArgs<T, O>` | Tipa a lista de parâmetros via spread de um `@QueryMethod` declarado com `{ spreadArgs: true }`: os valores de `T`, em ordem, seguidos de um `DbArg<O>` opcional construído via `withDb()`. | [Argumentos via spread com `spreadArgs`](#argumentos-via-spread-com-spreadargs). |
|
|
@@ -767,7 +764,7 @@ import type {
|
|
|
767
764
|
| `NumericKeys<T>` | Extrai as chaves de `T` cujo tipo de valor (ignorando `null`/`undefined`) é atribuível a `NumericLike`. Campos numéricos nullable (`number \| null`) são incluídos. | Restringe `field` em [Métodos atômicos e de agregação](#métodos-atômicos-e-de-agregação) (`increment`, `sum`, etc). |
|
|
768
765
|
| `NumericLike` | `number \| bigint \| DecimalLike`. | [Métodos atômicos e de agregação](#métodos-atômicos-e-de-agregação). |
|
|
769
766
|
| `DecimalLike` | Formato estrutural de um valor decimal de precisão arbitrária (`{ toNumber(): number; decimalPlaces(): number }`), compatível com o `Prisma.Decimal` do Prisma sem precisar importá-lo diretamente. | [Quais campos são elegíveis](#quais-campos-são-elegíveis). |
|
|
770
|
-
| `Primitive` | União de tipos escalares (`string \| number \| boolean \| bigint \| symbol \| undefined \| null \| Date`) tratados como valores-folha — e não relações — ao percorrer o formato de uma entidade.
|
|
767
|
+
| `Primitive` | União de tipos escalares (`string \| number \| boolean \| bigint \| symbol \| undefined \| null \| Date \| DecimalLike`) tratados como valores-folha — e não relações — ao percorrer o formato de uma entidade. | Usado por `Ordering<T>` para distinguir campos escalares de campos de relação. |
|
|
771
768
|
| `VSRepoWhere<T>` | Tipo de filtro agnóstico de ORM aceito pelos métodos dinâmicos `*Where` (ex.: `findWhere`, `findOneWhere`, `updateWhere`). Suporta filtros de campo, operadores lógicos (`AND`/`OR`/`NOT`) e filtros de relação. | [Prefixos `findWhere`, `findOneWhere` e demais `*Where`](#prefixos-disponíveis). |
|
|
772
769
|
| `VSRepoOrmTypes` | `{ dbClient; dbTransaction }` — descreve os tipos de client/transaction do seu ORM. Passado como terceiro generic de `VSRepository<Entity, PKType, OrmTypes>` para tipar `getDbClient()`, `transaction()` e a option `db` em vez de `any`. | [Criando um repository](#criando-um-repository). |
|
|
773
770
|
| `VSRepoTransactionOptions` | `{ isolationLevel?, timeoutMs? }` — options aceitas como segundo argumento de `transaction()`. | [Transações](#transações). |
|
|
@@ -950,13 +947,13 @@ export class MyOrmAdapter<T> extends VSRepoAdapter<T> {
|
|
|
950
947
|
}
|
|
951
948
|
```
|
|
952
949
|
|
|
953
|
-
| Método | Descrição
|
|
954
|
-
| ---------------------------------------------------- |
|
|
955
|
-
| `new VSLogger(logLevel, name, slowThresholdMs?)` | Cria um logger; `name` prefixa cada linha
|
|
956
|
-
| `logDebug/logInfo/logWarn(text, obj?)` | Loga no nível dado se `logLevel` permitir; `obj` é anexado como JSON formatado.
|
|
957
|
-
| `logError(text, err?)` | Loga em `ERROR`; se `err` for uma `Error`, só `name`/`message`/`stack`/`cause` são logados.
|
|
958
|
-
| `startPerformLog(operation)` / `endPerformLog(data)` | Envolve um trecho de código para logar sua duração, escalando pra `WARN` se ultrapassar `slowThresholdMs`.
|
|
959
|
-
| `getLogLevel()` | Retorna o `VSLogLevel` configurado do logger.
|
|
950
|
+
| Método | Descrição |
|
|
951
|
+
| ---------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
952
|
+
| `new VSLogger(logLevel, name, slowThresholdMs?)` | Cria um logger; `name` prefixa cada linha. `slowThresholdMs` controla o threshold de operação lenta: um `number` define o valor em ms (padrão 300), `false` desabilita os avisos de operação lenta completamente, `true` ou omitido usa o padrão de 300ms. |
|
|
953
|
+
| `logDebug/logInfo/logWarn(text, obj?)` | Loga no nível dado se `logLevel` permitir; `obj` é anexado como JSON formatado. |
|
|
954
|
+
| `logError(text, err?)` | Loga em `ERROR`; se `err` for uma `Error`, só `name`/`message`/`stack`/`cause` são logados. |
|
|
955
|
+
| `startPerformLog(operation)` / `endPerformLog(data)` | Envolve um trecho de código para logar sua duração, escalando pra `WARN` se ultrapassar `slowThresholdMs`. |
|
|
956
|
+
| `getLogLevel()` | Retorna o `VSLogLevel` configurado do logger. |
|
|
960
957
|
|
|
961
958
|
Isso é puramente uma conveniência para autores de adapters — nada no core exige que seu adapter o utilize.
|
|
962
959
|
|
|
@@ -1091,7 +1088,8 @@ super({
|
|
|
1091
1088
|
pkName: "id",
|
|
1092
1089
|
adapter,
|
|
1093
1090
|
logLevel: VSLogLevel.DEBUG,
|
|
1094
|
-
logSlowThresholdMs: 200,
|
|
1091
|
+
logSlowThresholdMs: 200, // avisa se qualquer operação levar mais de 200ms
|
|
1092
|
+
// logSlowThresholdMs: false, // desabilita os avisos de operação lenta completamente
|
|
1095
1093
|
});
|
|
1096
1094
|
```
|
|
1097
1095
|
|
|
@@ -1153,11 +1151,11 @@ Observações:
|
|
|
1153
1151
|
|
|
1154
1152
|
## Contribuindo
|
|
1155
1153
|
|
|
1156
|
-
Contribuições são bem-vindas, especialmente para
|
|
1154
|
+
Contribuições são bem-vindas, especialmente para melhorar o adapter do Prisma e finalizar o do Drizzle! (**[Repositório do GitHub](https://github.com/jaobrabo123/VSRepository)**):
|
|
1157
1155
|
|
|
1158
1156
|
1. Faça um **Fork** do projeto.
|
|
1159
|
-
2. Crie uma branch
|
|
1157
|
+
2. Crie uma branch para sua alteração: `git checkout -b v2-minha-alteracao`.
|
|
1160
1158
|
3. Faça o push da sua branch: `git push origin v2-minha-alteracao`.
|
|
1161
|
-
4. Abra um **Pull Request
|
|
1159
|
+
4. Abra um **Pull Request**.
|
|
1162
1160
|
|
|
1163
1161
|
Para reportar problemas ou sugerir funcionalidades, abra uma **Issue**.
|
|
@@ -3,10 +3,10 @@ import { PerformData } from "../../types/utils/perform-data.type";
|
|
|
3
3
|
export declare class VSLogger {
|
|
4
4
|
private readonly logLevel;
|
|
5
5
|
private readonly loggerName;
|
|
6
|
-
private readonly slowOperationThresholdMs;
|
|
7
6
|
private static readonly DEFAULT_SLOW_OPERATION_MS;
|
|
7
|
+
private readonly slowOperationThresholdMs;
|
|
8
8
|
private readonly useColors;
|
|
9
|
-
constructor(logLevel: VSLogLevel, loggerName: string, slowOperationThresholdMs?: number);
|
|
9
|
+
constructor(logLevel: VSLogLevel, loggerName: string, slowOperationThresholdMs?: number | boolean);
|
|
10
10
|
getLogLevel(): VSLogLevel;
|
|
11
11
|
private color;
|
|
12
12
|
private stringfy;
|
|
@@ -32,14 +32,17 @@ const LEVEL_COLOR = {
|
|
|
32
32
|
class VSLogger {
|
|
33
33
|
logLevel;
|
|
34
34
|
loggerName;
|
|
35
|
-
slowOperationThresholdMs;
|
|
36
35
|
// * Acima disso, uma operação concluída é logada como WARN ao invés de DEBUG
|
|
37
36
|
static DEFAULT_SLOW_OPERATION_MS = 300;
|
|
37
|
+
slowOperationThresholdMs;
|
|
38
38
|
useColors;
|
|
39
|
-
constructor(logLevel, loggerName, slowOperationThresholdMs
|
|
39
|
+
constructor(logLevel, loggerName, slowOperationThresholdMs) {
|
|
40
40
|
this.logLevel = logLevel;
|
|
41
41
|
this.loggerName = loggerName;
|
|
42
|
-
this.slowOperationThresholdMs =
|
|
42
|
+
this.slowOperationThresholdMs =
|
|
43
|
+
typeof slowOperationThresholdMs === "number" || slowOperationThresholdMs === false
|
|
44
|
+
? slowOperationThresholdMs
|
|
45
|
+
: VSLogger.DEFAULT_SLOW_OPERATION_MS;
|
|
43
46
|
this.useColors = !process.env.NO_COLOR && !!process.stdout?.isTTY;
|
|
44
47
|
}
|
|
45
48
|
getLogLevel() {
|
|
@@ -129,7 +132,7 @@ class VSLogger {
|
|
|
129
132
|
const end = performance.now();
|
|
130
133
|
const timeTook = end - data.start;
|
|
131
134
|
const timeTookLabel = timeTook.toFixed(2);
|
|
132
|
-
if (timeTook >= this.slowOperationThresholdMs) {
|
|
135
|
+
if (this.slowOperationThresholdMs !== false && timeTook >= this.slowOperationThresholdMs) {
|
|
133
136
|
this.logWarn(`Took ${timeTookLabel}ms to ${data.operation} (slower than the ${this.slowOperationThresholdMs}ms threshold)`);
|
|
134
137
|
return;
|
|
135
138
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vs-logger.util.js","sourceRoot":"","sources":["../../../src/internal/utils/vs-logger.util.ts"],"names":[],"mappings":";;;AAAA,kEAAwD;AAGxD;;;;GAIG;AACH,MAAM,IAAI,GAAG;IACT,KAAK,EAAE,SAAS;IAChB,IAAI,EAAE,SAAS;IACf,GAAG,EAAE,SAAS;IACd,IAAI,EAAE,UAAU;IAChB,IAAI,EAAE,UAAU;IAChB,MAAM,EAAE,UAAU;IAClB,GAAG,EAAE,UAAU;IACf,OAAO,EAAE,UAAU;CACb,CAAC;AAEX,MAAM,WAAW,GAA+B;IAC5C,CAAC,8BAAU,CAAC,KAAK,CAAC,EAAE,OAAO;IAC3B,CAAC,8BAAU,CAAC,IAAI,CAAC,EAAE,MAAM;IACzB,CAAC,8BAAU,CAAC,IAAI,CAAC,EAAE,MAAM;IACzB,CAAC,8BAAU,CAAC,KAAK,CAAC,EAAE,OAAO;CAC9B,CAAC;AAEF,MAAM,WAAW,GAA+B;IAC5C,CAAC,8BAAU,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,IAAI;IAC7B,CAAC,8BAAU,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,IAAI;IAC5B,CAAC,8BAAU,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,MAAM;IAC9B,CAAC,8BAAU,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,GAAG;CAC/B,CAAC;AAEF,MAAa,QAAQ;
|
|
1
|
+
{"version":3,"file":"vs-logger.util.js","sourceRoot":"","sources":["../../../src/internal/utils/vs-logger.util.ts"],"names":[],"mappings":"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"}
|
|
@@ -66,7 +66,7 @@ class VSRepoValidator {
|
|
|
66
66
|
pkName: v.string(),
|
|
67
67
|
softRemoveKey: v.optional(v.string()),
|
|
68
68
|
logLevel: v.optional(v.enum(vs_log_level_enum_1.VSLogLevel)),
|
|
69
|
-
logSlowThresholdMs: v.optional(v.pipe(v.number(), v.gtValue(0))),
|
|
69
|
+
logSlowThresholdMs: v.optional(v.union([v.pipe(v.number(), v.gtValue(0)), v.boolean()])),
|
|
70
70
|
defaultOrdering: v.optional(ordering_schema_1.default),
|
|
71
71
|
});
|
|
72
72
|
validateConstructorOptions(options) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vsrepo.validator.js","sourceRoot":"","sources":["../../../src/internal/validators/vsrepo.validator.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAA6B;AAE7B,kEAAwD;AACxD,0DAAuD;AACvD,gFAAuD;AAGvD,4EAAkE;AAElE,gGAAsF;AAKtF,oFAA2D;AAC3D,0EAAiD;AAMjD,MAAa,eAAe;IACxB,uFAAuF;IACvF,yGAAyG;IACjG,MAAM,CAAY;IAE1B,SAAS,CAAC,MAAgB;QACtB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACzB,CAAC;IAEO,cAAc,CAClB,KAAiC,EACjC,IAAqB,EACrB,YAAY,GAAG,SAAS;QAExB,MAAM,IAAI,GAAG,KAAK,EAAE,IAAI,EAAE,MAAM;YAC5B,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;YAC9C,CAAC,CAAC,YAAY,CAAC;QACnB,MAAM,OAAO,GAAG,GAAG,IAAI,KAAK,KAAK,EAAE,OAAO,IAAI,mBAAmB,EAAE,CAAC;QAEpE,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,sBAAsB,IAAI,MAAM,OAAO,EAAE,CAAC,CAAC;QAEjE,MAAM,IAAI,yBAAW,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACzC,CAAC;IAEgB,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC;QACjD,sEAAsE;QACtE,OAAO,EAAE,CAAC,CAAC,GAAG,EAAE;QAChB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;QAClB,aAAa,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;QACrC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,8BAAU,CAAC,CAAC;QACxC,kBAAkB,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"vsrepo.validator.js","sourceRoot":"","sources":["../../../src/internal/validators/vsrepo.validator.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAA6B;AAE7B,kEAAwD;AACxD,0DAAuD;AACvD,gFAAuD;AAGvD,4EAAkE;AAElE,gGAAsF;AAKtF,oFAA2D;AAC3D,0EAAiD;AAMjD,MAAa,eAAe;IACxB,uFAAuF;IACvF,yGAAyG;IACjG,MAAM,CAAY;IAE1B,SAAS,CAAC,MAAgB;QACtB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACzB,CAAC;IAEO,cAAc,CAClB,KAAiC,EACjC,IAAqB,EACrB,YAAY,GAAG,SAAS;QAExB,MAAM,IAAI,GAAG,KAAK,EAAE,IAAI,EAAE,MAAM;YAC5B,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;YAC9C,CAAC,CAAC,YAAY,CAAC;QACnB,MAAM,OAAO,GAAG,GAAG,IAAI,KAAK,KAAK,EAAE,OAAO,IAAI,mBAAmB,EAAE,CAAC;QAEpE,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,sBAAsB,IAAI,MAAM,OAAO,EAAE,CAAC,CAAC;QAEjE,MAAM,IAAI,yBAAW,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACzC,CAAC;IAEgB,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC;QACjD,sEAAsE;QACtE,OAAO,EAAE,CAAC,CAAC,GAAG,EAAE;QAChB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;QAClB,aAAa,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;QACrC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,8BAAU,CAAC,CAAC;QACxC,kBAAkB,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACxF,eAAe,EAAE,CAAC,CAAC,QAAQ,CAAC,yBAAc,CAAC;KAC9C,CAAC,CAAC;IAEH,0BAA0B,CAAC,OAAgB;QACvC,MAAM,MAAM,GAAG,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,wBAAwB,EAAE,OAAO,CAAC,CAAC;QAEnE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAClB,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,wCAAe,CAAC,SAAS,CAAC,CAAC;QACrE,CAAC;QAED,OAAO,MAAM,CAAC,MAAwC,CAAC;IAC3D,CAAC;IAEgB,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;QAC5C,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;QACvB,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC;QACzD,SAAS,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QACxC,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;KACxC,CAAC,CAAC;IAEH,qBAAqB,CAAC,OAAiB;QACnC,MAAM,MAAM,GAAG,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,mBAAmB,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC;QAEpE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAClB,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,wCAAe,CAAC,SAAS,CAAC,CAAC;QACrE,CAAC;QAED,OAAO,MAAM,CAAC,MAAqC,CAAC;IACxD,CAAC;IAEgB,2BAA2B,GAAG,CAAC,CAAC,MAAM,CAAC;QACpD,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;QACvB,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC;KAC5D,CAAC,CAAC;IAEH,6BAA6B,CAAC,OAAiB;QAC3C,MAAM,MAAM,GAAG,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,2BAA2B,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC;QAE5E,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAClB,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,wCAAe,CAAC,SAAS,CAAC,CAAC;QACrE,CAAC;QAED,OAAO,MAAM,CAAC,MAAgD,CAAC;IACnE,CAAC;IAEgB,yBAAyB,GAAG,CAAC,CAAC,MAAM,CAAC;QAClD,GAAG,IAAI,CAAC,mBAAmB,CAAC,OAAO;QACnC,KAAK,EAAE,CAAC,CAAC,QAAQ,CAAC,yBAAc,CAAC;QACjC,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,2BAAgB,CAAC;KAC3C,CAAC,CAAC;IAEH,2BAA2B,CAAC,OAAiB;QAIzC,MAAM,MAAM,GAAG,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,yBAAyB,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC;QAE1E,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAClB,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,wCAAe,CAAC,SAAS,CAAC,CAAC;QACrE,CAAC;QAED,OAAO,MAAM,CAAC,MAAqC,CAAC;IACxD,CAAC;IAEO,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;QAC9B,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;QAClC,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;KAC1B,CAAC,CAAC;IAEH,sBAAsB,CAAC,GAAa;QAChC,MAAM,MAAM,GAAG,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,cAAc,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC;QAE3D,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAClB,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,wCAAe,CAAC,SAAS,CAAC,CAAC;QACrE,CAAC;QAED,OAAO,MAAM,CAAC,MAAM,CAAC;IACzB,CAAC;IAEO,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;QAClC,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;QAClC,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;QACvB,SAAS,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;QAClC,YAAY,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;KACxC,CAAC,CAAC;IAEH,oBAAoB,CAAC,OAAiB;QAClC,MAAM,MAAM,GAAG,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,kBAAkB,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC;QAEnE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAClB,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,wCAAe,CAAC,SAAS,CAAC,CAAC;QACrE,CAAC;QAED,OAAO,MAAM,CAAC,MAAM,CAAC;IACzB,CAAC;IAEO,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC;QACxC,SAAS,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;QACjC,cAAc,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,4DAAyB,CAAC,CAAC;KAChE,CAAC,CAAC;IAEH,0BAA0B,CAAC,OAAgB;QACvC,MAAM,MAAM,GAAG,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,wBAAwB,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC;QAEzE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAClB,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,wCAAe,CAAC,SAAS,CAAC,CAAC;QACrE,CAAC;QAED,OAAO,MAAM,CAAC,MAAM,CAAC;IACzB,CAAC;IAED,gBAAgB,CAAC,KAAc;QAC3B,MAAM,MAAM,GAAG,CAAC,CAAC,SAAS,CAAC,yBAAc,EAAE,KAAK,CAAC,CAAC;QAElD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAClB,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,wCAAe,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QACjF,CAAC;QAED,OAAO,MAAM,CAAC,MAAqB,CAAC;IACxC,CAAC;IAED,kBAAkB,CAAC,KAAc;QAC7B,MAAM,MAAM,GAAG,CAAC,CAAC,SAAS,CAAC,2BAAgB,EAAE,KAAK,CAAC,CAAC;QAEpD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAClB,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,wCAAe,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;QACnF,CAAC;QAED,OAAO,MAAM,CAAC,MAAM,CAAC;IACzB,CAAC;IAED,aAAa,CAAC,KAAc;QACxB,MAAM,MAAM,GAAG,CAAC,CAAC,SAAS,CAAC,sBAAW,EAAE,KAAK,CAAC,CAAC;QAE/C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAClB,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,wCAAe,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAC9E,CAAC;QAED,OAAO,MAAM,CAAC,MAAwB,CAAC;IAC3C,CAAC;IAEO,iBAAiB,GAAG,CAAC,CAAC,WAAW,CAAC;QACtC,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE;QACtB,aAAa,EAAE,CAAC,CAAC,QAAQ,EAAE;KAC9B,CAAC,CAAC;IAEK,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;IAEtF,mBAAmB,CAAC,KAAc;QAC9B,MAAM,MAAM,GAAG,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAC;QAE1D,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAClB,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,wCAAe,CAAC,SAAS,CAAC,CAAC;QACrE,CAAC;IACL,CAAC;CACJ;AA1LD,0CA0LC"}
|
|
@@ -27,8 +27,11 @@ export type VSRepoOptions<T, K> = {
|
|
|
27
27
|
/**
|
|
28
28
|
* Duration (in ms) above which a finished operation is logged as WARN
|
|
29
29
|
* instead of DEBUG, flagging potentially slow queries. Defaults to 300ms.
|
|
30
|
+
*
|
|
31
|
+
* Pass `false` to disable slow-operation warnings entirely.
|
|
32
|
+
* Pass `true` to use the default 300ms threshold explicitly.
|
|
30
33
|
*/
|
|
31
|
-
logSlowThresholdMs?: number;
|
|
34
|
+
logSlowThresholdMs?: number | boolean;
|
|
32
35
|
/** Default ordering automatically applied to queries that accept `order`, unless the call overrides it. */
|
|
33
36
|
defaultOrdering?: Ordering<T>;
|
|
34
37
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vsrepo",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
4
4
|
"description": "ORM-agnostic repository pattern library with full TypeScript support and automatic type inference.",
|
|
5
5
|
"homepage": "https://github.com/jaobrabo123/VSRepository#readme",
|
|
6
6
|
"repository": {
|
|
@@ -45,7 +45,11 @@
|
|
|
45
45
|
"vsrepo",
|
|
46
46
|
"vsrepository"
|
|
47
47
|
],
|
|
48
|
-
"author":
|
|
48
|
+
"author": {
|
|
49
|
+
"email": "joaodev.azevedo@outlook.com",
|
|
50
|
+
"url": "https://github.com/jaobrabo123",
|
|
51
|
+
"name": "João Pedro Azevedo Freire Mecenas"
|
|
52
|
+
},
|
|
49
53
|
"license": "MIT",
|
|
50
54
|
"devDependencies": {
|
|
51
55
|
"@jest/globals": "^30.4.1",
|