@avleon/data 0.0.0-stage → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +212 -2
- package/dist/datasource.d.ts +20 -0
- package/dist/datasource.js +66 -0
- package/dist/datasource.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/knex-provider.d.ts +28 -0
- package/dist/knex-provider.js +71 -0
- package/dist/knex-provider.js.map +1 -0
- package/dist/plugin.d.ts +21 -0
- package/dist/plugin.js +47 -0
- package/dist/plugin.js.map +1 -0
- package/dist/repository.d.ts +16 -0
- package/dist/repository.js +33 -0
- package/dist/repository.js.map +1 -0
- package/dist/typeorm-provider.d.ts +120 -0
- package/dist/typeorm-provider.js +303 -0
- package/dist/typeorm-provider.js.map +1 -0
- package/package.json +99 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Tareq Hossain
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,213 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @avleon/data
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
TypeORM and Knex integration for [Avleon](https://avleonjs.github.io).
|
|
4
|
+
|
|
5
|
+
`@avleon/data` is an Avleon [plugin](https://avleonjs.github.io/advanced/plugins).
|
|
6
|
+
Once it is installed, the app gains `app.useTypeORM()` and `app.useKnex()`; nothing
|
|
7
|
+
needs to be imported to enable them.
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @avleon/data typeorm pg # TypeORM
|
|
11
|
+
npm install @avleon/data knex pg # Knex
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Projects created with `avleon new` load the plugin's types through the generated
|
|
15
|
+
`avleon-env.d.ts`. In other projects, add the file yourself and include it in
|
|
16
|
+
`tsconfig.json`:
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
// avleon-env.d.ts
|
|
20
|
+
/// <reference types="@avleon/data" />
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Both methods connect before they resolve, register the connection with the
|
|
24
|
+
container, and close it when the app shuts down (`app.close()`, SIGTERM or SIGINT).
|
|
25
|
+
For a bundled app, which has no `package.json` to discover plugins from, pass the
|
|
26
|
+
plugin explicitly:
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
import { Avleon } from "@avleon/core";
|
|
30
|
+
import { dataPlugin } from "@avleon/data";
|
|
31
|
+
|
|
32
|
+
const app = Avleon.createApplication({ plugins: [dataPlugin] });
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Knex
|
|
36
|
+
|
|
37
|
+
`useKnex` connects eagerly and verifies the connection, so it returns a promise:
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
await app.useKnex({
|
|
41
|
+
client: "mysql",
|
|
42
|
+
connection: {
|
|
43
|
+
host: "127.0.0.1",
|
|
44
|
+
port: 3306,
|
|
45
|
+
user: "root",
|
|
46
|
+
password: "password",
|
|
47
|
+
database: "myapp",
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Using a config class:
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
import { AppConfig, AvleonConfig, Environment } from "@avleon/core";
|
|
56
|
+
import type { Knex } from "knex";
|
|
57
|
+
|
|
58
|
+
@AppConfig
|
|
59
|
+
export class KnexConfig extends AvleonConfig<Knex.Config> {
|
|
60
|
+
config(env: Environment): Knex.Config {
|
|
61
|
+
return {
|
|
62
|
+
client: "mysql",
|
|
63
|
+
connection: {
|
|
64
|
+
host: env.get("DB_HOST") || "127.0.0.1",
|
|
65
|
+
port: Number(env.get("DB_PORT")) || 3306,
|
|
66
|
+
user: env.get("DB_USER") || "root",
|
|
67
|
+
password: env.get("DB_PASS") || "password",
|
|
68
|
+
database: env.get("DB_NAME") || "myapp",
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
await app.useKnex(KnexConfig);
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Using in a service:
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
import { AppService } from "@avleon/core";
|
|
81
|
+
import { KnexDB } from "@avleon/data";
|
|
82
|
+
|
|
83
|
+
@AppService
|
|
84
|
+
export class UsersService {
|
|
85
|
+
constructor(private readonly db: KnexDB) {}
|
|
86
|
+
|
|
87
|
+
async findAll() {
|
|
88
|
+
return this.db.client.select("*").from("users");
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
async page(page: number) {
|
|
92
|
+
return this.db.paginate(this.db.client("users").orderBy("id"), {
|
|
93
|
+
page,
|
|
94
|
+
perPage: 20,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## TypeORM
|
|
103
|
+
|
|
104
|
+
`useTypeORM` initializes the DataSource, so it returns a promise:
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
await app.useTypeORM({
|
|
108
|
+
type: "postgres",
|
|
109
|
+
host: "localhost",
|
|
110
|
+
port: 5432,
|
|
111
|
+
username: "postgres",
|
|
112
|
+
password: "password",
|
|
113
|
+
database: "avleon",
|
|
114
|
+
entities: [User],
|
|
115
|
+
synchronize: true,
|
|
116
|
+
});
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Using a config class:
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
import { AppConfig, AvleonConfig, Environment } from "@avleon/core";
|
|
123
|
+
import type { DataSourceOptions } from "typeorm";
|
|
124
|
+
|
|
125
|
+
@AppConfig
|
|
126
|
+
export class DataSourceConfig extends AvleonConfig<DataSourceOptions> {
|
|
127
|
+
config(env: Environment): DataSourceOptions {
|
|
128
|
+
return {
|
|
129
|
+
type: "postgres",
|
|
130
|
+
host: env.get("DB_HOST") || "localhost",
|
|
131
|
+
port: Number(env.get("DB_PORT")) || 5432,
|
|
132
|
+
username: env.get("DB_USER") || "postgres",
|
|
133
|
+
password: env.get("DB_PASS") || "password",
|
|
134
|
+
database: env.get("DB_NAME") || "avleon",
|
|
135
|
+
entities: [User],
|
|
136
|
+
synchronize: true,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
await app.useTypeORM(DataSourceConfig);
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**Injecting a repository.** `@InjectRepository` gives you the TypeORM repository
|
|
145
|
+
plus a `paginate()` method:
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
import { AppService } from "@avleon/core";
|
|
149
|
+
import { InjectRepository, PaginatedRepository } from "@avleon/data";
|
|
150
|
+
import { User } from "./user.entity";
|
|
151
|
+
|
|
152
|
+
@AppService
|
|
153
|
+
export class UserService {
|
|
154
|
+
constructor(
|
|
155
|
+
@InjectRepository(User)
|
|
156
|
+
private readonly userRepo: PaginatedRepository<User>,
|
|
157
|
+
) {}
|
|
158
|
+
|
|
159
|
+
findAll() {
|
|
160
|
+
return this.userRepo.find();
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
page(page: number) {
|
|
164
|
+
return this.userRepo.paginate({ page, perPage: 20 });
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
**Custom repositories.** Extend `AvleonRepository` for pagination, transactions
|
|
170
|
+
and your own query methods. Query operators (`Like`, `In`, `Not`, `Between`,
|
|
171
|
+
`IsNull`, `Equal`, `ArrayContains`, …) are exported from `@avleon/data`.
|
|
172
|
+
|
|
173
|
+
In 0.3.0, give the class an explicit constructor that calls `super()`, even if
|
|
174
|
+
it has no dependencies (see [Known Issues](#known-issues-in-030)):
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
import { AvleonRepository, Repository, Like } from "@avleon/data";
|
|
178
|
+
|
|
179
|
+
@Repository(User)
|
|
180
|
+
export class UserRepository extends AvleonRepository<User> {
|
|
181
|
+
constructor(private readonly audit: AuditService) {
|
|
182
|
+
super();
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
search(term: string, page = 1) {
|
|
186
|
+
return this.paginate(
|
|
187
|
+
{ where: { name: Like(`%${term}%`) } },
|
|
188
|
+
{ page, perPage: 20 },
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
async rename(id: number, name: string) {
|
|
193
|
+
return this.transaction(async (tx) => {
|
|
194
|
+
await tx.update({ id }, { name });
|
|
195
|
+
await this.audit.log("rename", id);
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
`transaction()` joins an already active transaction instead of opening a nested
|
|
202
|
+
one. `withManager(manager)` returns a copy of the repository bound to another
|
|
203
|
+
`EntityManager`.
|
|
204
|
+
|
|
205
|
+
## Pagination
|
|
206
|
+
|
|
207
|
+
`repo.paginate()`, `AvleonRepository.paginate()`, `KnexDB.paginate()` and
|
|
208
|
+
`paginateKnex()` return core's unified `{ data, meta }` shape; see
|
|
209
|
+
[Pagination](https://github.com/avleonjs/avleon/tree/main/packages/core#pagination).
|
|
210
|
+
|
|
211
|
+
## License
|
|
212
|
+
|
|
213
|
+
MIT
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { DataSource } from "typeorm";
|
|
2
|
+
/**
|
|
3
|
+
* String token under which the TypeORM `DataSource` is registered. Used by
|
|
4
|
+
* `paginatedRepository` and `@InjectRepository`.
|
|
5
|
+
*/
|
|
6
|
+
export declare const DATASOURCE_TOKEN = "idatasource";
|
|
7
|
+
/**
|
|
8
|
+
* Register the application's TypeORM `DataSource` with the DI container.
|
|
9
|
+
*
|
|
10
|
+
* Sets both the `"idatasource"` string token and the `DataSource` class token
|
|
11
|
+
* (the class the instance was built from, and the consumer's `typeorm`
|
|
12
|
+
* `DataSource` export if that differs), so `@Repository`, `@InjectRepository`,
|
|
13
|
+
* `paginatedRepository` and `Container.get(DataSource)` all resolve it.
|
|
14
|
+
*/
|
|
15
|
+
export declare function registerDataSource(dataSource: DataSource): DataSource;
|
|
16
|
+
/**
|
|
17
|
+
* Resolve the registered TypeORM `DataSource`, or throw a clear error if the
|
|
18
|
+
* application has not called `useTypeORM` (or `registerDataSource`) yet.
|
|
19
|
+
*/
|
|
20
|
+
export declare function getDataSource(): DataSource;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DATASOURCE_TOKEN = void 0;
|
|
4
|
+
exports.registerDataSource = registerDataSource;
|
|
5
|
+
exports.getDataSource = getDataSource;
|
|
6
|
+
/**
|
|
7
|
+
* @copyright 2024
|
|
8
|
+
* @author Tareq Hossain
|
|
9
|
+
* @email xtrinsic96@gmail.com
|
|
10
|
+
* @url https://github.com/xtareq
|
|
11
|
+
*/
|
|
12
|
+
const core_1 = require("@avleon/core");
|
|
13
|
+
/**
|
|
14
|
+
* String token under which the TypeORM `DataSource` is registered. Used by
|
|
15
|
+
* `paginatedRepository` and `@InjectRepository`.
|
|
16
|
+
*/
|
|
17
|
+
exports.DATASOURCE_TOKEN = "idatasource";
|
|
18
|
+
/**
|
|
19
|
+
* Register the application's TypeORM `DataSource` with the DI container.
|
|
20
|
+
*
|
|
21
|
+
* Sets both the `"idatasource"` string token and the `DataSource` class token
|
|
22
|
+
* (the class the instance was built from, and the consumer's `typeorm`
|
|
23
|
+
* `DataSource` export if that differs), so `@Repository`, `@InjectRepository`,
|
|
24
|
+
* `paginatedRepository` and `Container.get(DataSource)` all resolve it.
|
|
25
|
+
*/
|
|
26
|
+
function registerDataSource(dataSource) {
|
|
27
|
+
if (!dataSource) {
|
|
28
|
+
throw new Error("[Avleon] registerDataSource() requires a DataSource instance.");
|
|
29
|
+
}
|
|
30
|
+
core_1.AvleonContainer.set(exports.DATASOURCE_TOKEN, dataSource);
|
|
31
|
+
const ctor = dataSource.constructor;
|
|
32
|
+
if (typeof ctor === "function" && ctor !== Object) {
|
|
33
|
+
core_1.AvleonContainer.set(ctor, dataSource);
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
const typeorm = (0, core_1.loadPackageFromClient)("typeorm");
|
|
37
|
+
if (typeorm?.DataSource && typeorm.DataSource !== ctor) {
|
|
38
|
+
core_1.AvleonContainer.set(typeorm.DataSource, dataSource);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
// typeorm not resolvable from the app root; the constructor token is enough.
|
|
43
|
+
}
|
|
44
|
+
return dataSource;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Resolve the registered TypeORM `DataSource`, or throw a clear error if the
|
|
48
|
+
* application has not called `useTypeORM` (or `registerDataSource`) yet.
|
|
49
|
+
*/
|
|
50
|
+
function getDataSource() {
|
|
51
|
+
if (core_1.AvleonContainer.has(exports.DATASOURCE_TOKEN)) {
|
|
52
|
+
return core_1.AvleonContainer.get(exports.DATASOURCE_TOKEN);
|
|
53
|
+
}
|
|
54
|
+
try {
|
|
55
|
+
const typeorm = (0, core_1.loadPackageFromClient)("typeorm");
|
|
56
|
+
if (core_1.AvleonContainer.has(typeorm.DataSource)) {
|
|
57
|
+
return core_1.AvleonContainer.get(typeorm.DataSource);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// fall through to the error below
|
|
62
|
+
}
|
|
63
|
+
throw new Error("[Avleon] No TypeORM DataSource is registered. Call app.useTypeORM(...) " +
|
|
64
|
+
"(or registerDataSource(dataSource)) before resolving repositories.");
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=datasource.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"datasource.js","sourceRoot":"","sources":["../src/datasource.ts"],"names":[],"mappings":";;;AAuBA,gDAwBC;AAMD,sCAkBC;AAvED;;;;;GAKG;AACH,uCAAmF;AAGnF;;;GAGG;AACU,QAAA,gBAAgB,GAAG,aAAa,CAAC;AAE9C;;;;;;;GAOG;AACH,SAAgB,kBAAkB,CAAC,UAAsB;IACvD,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CACb,+DAA+D,CAChE,CAAC;IACJ,CAAC;IAED,sBAAS,CAAC,GAAG,CAAC,wBAAgB,EAAE,UAAU,CAAC,CAAC;IAE5C,MAAM,IAAI,GAAI,UAAkB,CAAC,WAAW,CAAC;IAC7C,IAAI,OAAO,IAAI,KAAK,UAAU,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QAClD,sBAAS,CAAC,GAAG,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAClC,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAA,4BAAqB,EAA2B,SAAS,CAAC,CAAC;QAC3E,IAAI,OAAO,EAAE,UAAU,IAAI,OAAO,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;YACvD,sBAAS,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,6EAA6E;IAC/E,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;GAGG;AACH,SAAgB,aAAa;IAC3B,IAAI,sBAAS,CAAC,GAAG,CAAC,wBAAgB,CAAC,EAAE,CAAC;QACpC,OAAO,sBAAS,CAAC,GAAG,CAAa,wBAAgB,CAAC,CAAC;IACrD,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAA,4BAAqB,EAA2B,SAAS,CAAC,CAAC;QAC3E,IAAI,sBAAS,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;YACtC,OAAO,sBAAS,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,kCAAkC;IACpC,CAAC;IAED,MAAM,IAAI,KAAK,CACb,yEAAyE;QACvE,oEAAoE,CACvE,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.dataPlugin = void 0;
|
|
18
|
+
__exportStar(require("./datasource"), exports);
|
|
19
|
+
__exportStar(require("./typeorm-provider"), exports);
|
|
20
|
+
__exportStar(require("./knex-provider"), exports);
|
|
21
|
+
__exportStar(require("./repository"), exports);
|
|
22
|
+
var plugin_1 = require("./plugin");
|
|
23
|
+
Object.defineProperty(exports, "dataPlugin", { enumerable: true, get: function () { return plugin_1.dataPlugin; } });
|
|
24
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,+CAA6B;AAC7B,qDAAmC;AACnC,kDAAgC;AAChC,+CAA6B;AAC7B,mCAAsC;AAA7B,oGAAA,UAAU,OAAA"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Token, type PageRequest, type Paginated } from "@avleon/core";
|
|
2
|
+
import type { Knex } from "knex";
|
|
3
|
+
/** DI token holding the initialized Knex instance. Set by `app.useKnex(...)`. */
|
|
4
|
+
export declare const AVLEON_KNEX_DB: Token<Knex<any, any[]>>;
|
|
5
|
+
/**
|
|
6
|
+
* Injectable accessor for the application's Knex connection.
|
|
7
|
+
*
|
|
8
|
+
* The connection itself is created by `app.useKnex(...)`, which registers it
|
|
9
|
+
* under {@link AVLEON_KNEX_DB}. Resolving this service before that call throws.
|
|
10
|
+
*/
|
|
11
|
+
export declare class KnexDB {
|
|
12
|
+
private readonly connection;
|
|
13
|
+
constructor();
|
|
14
|
+
get client(): Knex;
|
|
15
|
+
/**
|
|
16
|
+
* Run `query` for one page, returning the unified pagination shape.
|
|
17
|
+
*
|
|
18
|
+
* ```ts
|
|
19
|
+
* const { data, meta } = await db.paginate(db.client("users").where("active", true), { page: 2 });
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* The total is counted on a clone of the query with its select, order and
|
|
23
|
+
* limit/offset cleared.
|
|
24
|
+
*/
|
|
25
|
+
paginate<T = any>(query: Knex.QueryBuilder, options?: PageRequest): Promise<Paginated<T>>;
|
|
26
|
+
}
|
|
27
|
+
/** Paginate any Knex query builder into the unified `{ data, meta }` shape. */
|
|
28
|
+
export declare function paginateKnex<T = any>(query: Knex.QueryBuilder, options?: PageRequest): Promise<Paginated<T>>;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.KnexDB = exports.AVLEON_KNEX_DB = void 0;
|
|
13
|
+
exports.paginateKnex = paginateKnex;
|
|
14
|
+
const core_1 = require("@avleon/core");
|
|
15
|
+
/** DI token holding the initialized Knex instance. Set by `app.useKnex(...)`. */
|
|
16
|
+
exports.AVLEON_KNEX_DB = new core_1.Token("AVLEON_KNEX_DB");
|
|
17
|
+
/**
|
|
18
|
+
* Injectable accessor for the application's Knex connection.
|
|
19
|
+
*
|
|
20
|
+
* The connection itself is created by `app.useKnex(...)`, which registers it
|
|
21
|
+
* under {@link AVLEON_KNEX_DB}. Resolving this service before that call throws.
|
|
22
|
+
*/
|
|
23
|
+
let KnexDB = class KnexDB {
|
|
24
|
+
connection;
|
|
25
|
+
constructor() {
|
|
26
|
+
const existing = core_1.AvleonContainer.has(exports.AVLEON_KNEX_DB)
|
|
27
|
+
? core_1.AvleonContainer.get(exports.AVLEON_KNEX_DB)
|
|
28
|
+
: null;
|
|
29
|
+
if (!existing) {
|
|
30
|
+
throw new Error("Knex is not initialized. Call useKnex first.");
|
|
31
|
+
}
|
|
32
|
+
this.connection = existing;
|
|
33
|
+
}
|
|
34
|
+
get client() {
|
|
35
|
+
return this.connection;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Run `query` for one page, returning the unified pagination shape.
|
|
39
|
+
*
|
|
40
|
+
* ```ts
|
|
41
|
+
* const { data, meta } = await db.paginate(db.client("users").where("active", true), { page: 2 });
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* The total is counted on a clone of the query with its select, order and
|
|
45
|
+
* limit/offset cleared.
|
|
46
|
+
*/
|
|
47
|
+
async paginate(query, options) {
|
|
48
|
+
return paginateKnex(query, options);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
exports.KnexDB = KnexDB;
|
|
52
|
+
exports.KnexDB = KnexDB = __decorate([
|
|
53
|
+
(0, core_1.Injectable)(),
|
|
54
|
+
__metadata("design:paramtypes", [])
|
|
55
|
+
], KnexDB);
|
|
56
|
+
/** Paginate any Knex query builder into the unified `{ data, meta }` shape. */
|
|
57
|
+
async function paginateKnex(query, options) {
|
|
58
|
+
const { page, perPage, offset } = (0, core_1.normalizePageRequest)(options);
|
|
59
|
+
const countRow = await query
|
|
60
|
+
.clone()
|
|
61
|
+
.clearSelect()
|
|
62
|
+
.clearOrder()
|
|
63
|
+
.clear("limit")
|
|
64
|
+
.clear("offset")
|
|
65
|
+
.count({ total: "*" })
|
|
66
|
+
.first();
|
|
67
|
+
const total = Number(countRow?.total ?? 0);
|
|
68
|
+
const data = (await query.clone().offset(offset).limit(perPage));
|
|
69
|
+
return (0, core_1.paginated)(data, total, page, perPage);
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=knex-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"knex-provider.js","sourceRoot":"","sources":["../src/knex-provider.ts"],"names":[],"mappings":";;;;;;;;;;;;AA2DA,oCAkBC;AA7ED,uCAQsB;AAGtB,iFAAiF;AACpE,QAAA,cAAc,GAAG,IAAI,YAAK,CAAO,gBAAgB,CAAC,CAAC;AAEhE;;;;;GAKG;AAEI,IAAM,MAAM,GAAZ,MAAM,MAAM;IACA,UAAU,CAAO;IAElC;QACE,MAAM,QAAQ,GAAG,sBAAS,CAAC,GAAG,CAAC,sBAAc,CAAC;YAC5C,CAAC,CAAC,sBAAS,CAAC,GAAG,CAAO,sBAAc,CAAC;YACrC,CAAC,CAAC,IAAI,CAAC;QAET,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;QAClE,CAAC;QAED,IAAI,CAAC,UAAU,GAAG,QAAQ,CAAC;IAC7B,CAAC;IAED,IAAW,MAAM;QACf,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED;;;;;;;;;OASG;IACH,KAAK,CAAC,QAAQ,CACZ,KAAwB,EACxB,OAAqB;QAErB,OAAO,YAAY,CAAI,KAAK,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC;CACF,CAAA;AAnCY,wBAAM;iBAAN,MAAM;IADlB,IAAA,iBAAU,GAAE;;GACA,MAAM,CAmClB;AAED,+EAA+E;AACxE,KAAK,UAAU,YAAY,CAChC,KAAwB,EACxB,OAAqB;IAErB,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAA,2BAAoB,EAAC,OAAO,CAAC,CAAC;IAEhE,MAAM,QAAQ,GAAQ,MAAM,KAAK;SAC9B,KAAK,EAAE;SACP,WAAW,EAAE;SACb,UAAU,EAAE;SACZ,KAAK,CAAC,OAAc,CAAC;SACrB,KAAK,CAAC,QAAe,CAAC;SACtB,KAAK,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;SACrB,KAAK,EAAE,CAAC;IACX,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC;IAE3C,MAAM,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAQ,CAAC;IACxE,OAAO,IAAA,gBAAS,EAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;AAC/C,CAAC"}
|
package/dist/plugin.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type AvleonConfigClass } from "@avleon/core";
|
|
2
|
+
import type { Knex } from "knex";
|
|
3
|
+
import type { DataSourceOptions } from "typeorm";
|
|
4
|
+
declare module "@avleon/core" {
|
|
5
|
+
interface AvleonApplication {
|
|
6
|
+
/**
|
|
7
|
+
* Connect Knex from a config object or an `@AppConfig` class, and register
|
|
8
|
+
* it for `KnexDB`. Resolves once a test query succeeds. The connection is
|
|
9
|
+
* destroyed when the app shuts down.
|
|
10
|
+
*/
|
|
11
|
+
useKnex(options: Knex.Config | AvleonConfigClass<Knex.Config>): Promise<this>;
|
|
12
|
+
/**
|
|
13
|
+
* Initialize a TypeORM DataSource from its options or an `@AppConfig`
|
|
14
|
+
* class, and register it for repositories. Resolves once connected. The
|
|
15
|
+
* DataSource is destroyed when the app shuts down.
|
|
16
|
+
*/
|
|
17
|
+
useTypeORM(options: DataSourceOptions | AvleonConfigClass<DataSourceOptions>): Promise<this>;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export declare const dataPlugin: import("@avleon/core").AvleonPlugin;
|
|
21
|
+
export default dataPlugin;
|
package/dist/plugin.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.dataPlugin = void 0;
|
|
4
|
+
const core_1 = require("@avleon/core");
|
|
5
|
+
const datasource_1 = require("./datasource");
|
|
6
|
+
const knex_provider_1 = require("./knex-provider");
|
|
7
|
+
/** Options given directly, or built by an `@AppConfig` class from the environment. */
|
|
8
|
+
function resolveOptions(ctx, options) {
|
|
9
|
+
if (typeof options === "function" && options.prototype instanceof core_1.AvleonConfig) {
|
|
10
|
+
const config = ctx.container.get(options);
|
|
11
|
+
return config.config(ctx.container.get(core_1.Environment));
|
|
12
|
+
}
|
|
13
|
+
return options;
|
|
14
|
+
}
|
|
15
|
+
exports.dataPlugin = (0, core_1.definePlugin)({
|
|
16
|
+
name: "@avleon/data",
|
|
17
|
+
register(ctx) {
|
|
18
|
+
ctx.extend("useKnex", async (options) => {
|
|
19
|
+
const knex = (0, core_1.loadPackageFromClient)("knex");
|
|
20
|
+
const config = resolveOptions(ctx, options);
|
|
21
|
+
// Fail early with an install hint if the driver is missing.
|
|
22
|
+
if (typeof config?.client === "string")
|
|
23
|
+
(0, core_1.loadPackageFromClient)(config.client);
|
|
24
|
+
const db = knex(config);
|
|
25
|
+
ctx.container.set(knex_provider_1.AVLEON_KNEX_DB, db);
|
|
26
|
+
await db.raw("SELECT 1");
|
|
27
|
+
ctx.onClose(() => db.destroy());
|
|
28
|
+
return ctx.app;
|
|
29
|
+
});
|
|
30
|
+
ctx.extend("useTypeORM", async (options) => {
|
|
31
|
+
const typeorm = (0, core_1.loadPackageFromClient)("typeorm");
|
|
32
|
+
const dataSource = (0, datasource_1.registerDataSource)(new typeorm.DataSource(resolveOptions(ctx, options)));
|
|
33
|
+
try {
|
|
34
|
+
await dataSource.initialize();
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
ctx.logger.error({ err: error }, "Database connection failed");
|
|
38
|
+
throw error;
|
|
39
|
+
}
|
|
40
|
+
ctx.logger.info("Database connected");
|
|
41
|
+
ctx.onClose(() => dataSource.destroy());
|
|
42
|
+
return ctx.app;
|
|
43
|
+
});
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
exports.default = exports.dataPlugin;
|
|
47
|
+
//# sourceMappingURL=plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":";;;AAAA,uCAOsB;AAGtB,6CAAkD;AAClD,mDAAiD;AAqBjD,sFAAsF;AACtF,SAAS,cAAc,CAAI,GAAkB,EAAE,OAAiC;IAC9E,IAAI,OAAO,OAAO,KAAK,UAAU,IAAI,OAAO,CAAC,SAAS,YAAY,mBAAY,EAAE,CAAC;QAC/E,MAAM,MAAM,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAkB,OAA+B,CAAC,CAAC;QACnF,OAAO,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,kBAAW,CAAC,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,OAAY,CAAC;AACtB,CAAC;AAEY,QAAA,UAAU,GAAG,IAAA,mBAAY,EAAC;IACrC,IAAI,EAAE,cAAc;IACpB,QAAQ,CAAC,GAAG;QACV,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,EAAE,OAAqD,EAAE,EAAE;YACpF,MAAM,IAAI,GAAG,IAAA,4BAAqB,EAAwB,MAAM,CAAC,CAAC;YAClE,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YAC5C,4DAA4D;YAC5D,IAAI,OAAO,MAAM,EAAE,MAAM,KAAK,QAAQ;gBAAE,IAAA,4BAAqB,EAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAE7E,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;YACxB,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,8BAAc,EAAE,EAAE,CAAC,CAAC;YACtC,MAAM,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YACzB,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;YAChC,OAAO,GAAG,CAAC,GAAG,CAAC;QACjB,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,MAAM,CACR,YAAY,EACZ,KAAK,EAAE,OAAiE,EAAE,EAAE;YAC1E,MAAM,OAAO,GAAG,IAAA,4BAAqB,EAA2B,SAAS,CAAC,CAAC;YAC3E,MAAM,UAAU,GAAG,IAAA,+BAAkB,EACnC,IAAI,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CACrD,CAAC;YACF,IAAI,CAAC;gBACH,MAAM,UAAU,CAAC,UAAU,EAAE,CAAC;YAChC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,4BAA4B,CAAC,CAAC;gBAC/D,MAAM,KAAK,CAAC;YACd,CAAC;YACD,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;YACtC,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC;YACxC,OAAO,GAAG,CAAC,GAAG,CAAC;QACjB,CAAC,CACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC;AAEH,kBAAe,kBAAU,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type PageRequest, type Paginated } from "@avleon/core";
|
|
2
|
+
import type { EntityTarget, ObjectLiteral, Repository } from "typeorm";
|
|
3
|
+
/** A TypeORM repository extended with the unified `paginate`. */
|
|
4
|
+
export type PaginatedRepository<T extends ObjectLiteral> = Repository<T> & {
|
|
5
|
+
paginate(options?: PageRequest): Promise<Paginated<T>>;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* The TypeORM repository for `entity`, from the registered DataSource, with
|
|
9
|
+
* the unified `paginate({ page, perPage })` added.
|
|
10
|
+
*/
|
|
11
|
+
export declare function paginatedRepository<T extends ObjectLiteral>(entity: EntityTarget<T>, dataSource?: import("typeorm").DataSource): PaginatedRepository<T>;
|
|
12
|
+
/**
|
|
13
|
+
* Inject the TypeORM repository for `model`, extended with the unified
|
|
14
|
+
* `paginate({ page, perPage })`. Requires a registered DataSource.
|
|
15
|
+
*/
|
|
16
|
+
export declare function InjectRepository<T extends ObjectLiteral>(model: EntityTarget<T>): (object: any, propertyName: string | symbol | undefined, index?: number) => void;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.paginatedRepository = paginatedRepository;
|
|
4
|
+
exports.InjectRepository = InjectRepository;
|
|
5
|
+
const core_1 = require("@avleon/core");
|
|
6
|
+
const datasource_1 = require("./datasource");
|
|
7
|
+
async function paginateRepository(repo, options) {
|
|
8
|
+
const { page, perPage, offset } = (0, core_1.normalizePageRequest)(options);
|
|
9
|
+
const [data, total] = await repo.findAndCount({
|
|
10
|
+
skip: offset,
|
|
11
|
+
take: perPage,
|
|
12
|
+
});
|
|
13
|
+
return (0, core_1.paginated)(data, total, page, perPage);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* The TypeORM repository for `entity`, from the registered DataSource, with
|
|
17
|
+
* the unified `paginate({ page, perPage })` added.
|
|
18
|
+
*/
|
|
19
|
+
function paginatedRepository(entity, dataSource = (0, datasource_1.getDataSource)()) {
|
|
20
|
+
return dataSource.getRepository(entity).extend({
|
|
21
|
+
paginate(options) {
|
|
22
|
+
return paginateRepository(this, options);
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Inject the TypeORM repository for `model`, extended with the unified
|
|
28
|
+
* `paginate({ page, perPage })`. Requires a registered DataSource.
|
|
29
|
+
*/
|
|
30
|
+
function InjectRepository(model) {
|
|
31
|
+
return (0, core_1.createInjectDecorator)(() => paginatedRepository(model));
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=repository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repository.js","sourceRoot":"","sources":["../src/repository.ts"],"names":[],"mappings":";;AA+BA,kDASC;AAMD,4CAIC;AAlDD,uCAMsB;AAEtB,6CAA6C;AAO7C,KAAK,UAAU,kBAAkB,CAC/B,IAAmB,EACnB,OAAqB;IAErB,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAA,2BAAoB,EAAC,OAAO,CAAC,CAAC;IAChE,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC;QAC5C,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,OAAO;KACd,CAAC,CAAC;IACH,OAAO,IAAA,gBAAS,EAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;AAC/C,CAAC;AAED;;;GAGG;AACH,SAAgB,mBAAmB,CACjC,MAAuB,EACvB,UAAU,GAAG,IAAA,0BAAa,GAAE;IAE5B,OAAO,UAAU,CAAC,aAAa,CAAI,MAAM,CAAC,CAAC,MAAM,CAAC;QAChD,QAAQ,CAAsB,OAAqB;YACjD,OAAO,kBAAkB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC3C,CAAC;KACF,CAA2B,CAAC;AAC/B,CAAC;AAED;;;GAGG;AACH,SAAgB,gBAAgB,CAC9B,KAAsB;IAEtB,OAAO,IAAA,4BAAqB,EAAC,GAAG,EAAE,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC;AACjE,CAAC"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import type { EntityManager, EntityTarget, FindManyOptions, FindOneOptions, FindOptionsWhere, DeepPartial, Repository as OrmRepository, ObjectLiteral, SelectQueryBuilder, QueryRunner, InsertResult, UpdateResult, DeleteResult, ObjectId, SaveOptions, RemoveOptions, EntityMetadata } from "typeorm";
|
|
2
|
+
import { type Constructor, type PageRequest, type Paginated } from "@avleon/core";
|
|
3
|
+
export declare const Like: typeof import("typeorm").Like;
|
|
4
|
+
export declare const ILike: typeof import("typeorm").ILike;
|
|
5
|
+
export declare const In: typeof import("typeorm").In;
|
|
6
|
+
export declare const Not: typeof import("typeorm").Not;
|
|
7
|
+
export declare const Between: typeof import("typeorm").Between;
|
|
8
|
+
export declare const LessThan: typeof import("typeorm").LessThan;
|
|
9
|
+
export declare const LessThanOrEqual: typeof import("typeorm").LessThanOrEqual;
|
|
10
|
+
export declare const MoreThan: typeof import("typeorm").MoreThan;
|
|
11
|
+
export declare const MoreThanOrEqual: typeof import("typeorm").MoreThanOrEqual;
|
|
12
|
+
export declare const IsNull: typeof import("typeorm").IsNull;
|
|
13
|
+
export declare const Any: typeof import("typeorm").Any;
|
|
14
|
+
export declare const Raw: typeof import("typeorm").Raw;
|
|
15
|
+
export declare const Equal: typeof import("typeorm").Equal;
|
|
16
|
+
export declare const ArrayContains: typeof import("typeorm").ArrayContains;
|
|
17
|
+
/** @deprecated Use {@link PageRequest} (`{ page, perPage }`). */
|
|
18
|
+
export interface PaginationOptions {
|
|
19
|
+
page: number;
|
|
20
|
+
limit: number;
|
|
21
|
+
}
|
|
22
|
+
/** @deprecated Use {@link Paginated}. Kept as an alias of the unified shape. */
|
|
23
|
+
export type PaginatedResult<T> = Paginated<T>;
|
|
24
|
+
export interface SoftDeletable {
|
|
25
|
+
deletedAt?: Date | null;
|
|
26
|
+
}
|
|
27
|
+
export declare class AvleonRepository<TEntity extends ObjectLiteral> {
|
|
28
|
+
protected orm: OrmRepository<TEntity>;
|
|
29
|
+
protected entity: EntityTarget<TEntity>;
|
|
30
|
+
protected manager: EntityManager;
|
|
31
|
+
/**
|
|
32
|
+
* Both arguments are optional for `@Repository(Entity)` classes: the entity
|
|
33
|
+
* comes from the decorator and the manager from the registered DataSource,
|
|
34
|
+
* so a subclass constructor can take its own injected dependencies and
|
|
35
|
+
* call `super()` with no arguments.
|
|
36
|
+
*/
|
|
37
|
+
constructor(entity?: EntityTarget<TEntity>, manager?: EntityManager);
|
|
38
|
+
get metadata(): EntityMetadata;
|
|
39
|
+
get target(): EntityTarget<TEntity>;
|
|
40
|
+
find(options?: FindManyOptions<TEntity>): Promise<TEntity[]>;
|
|
41
|
+
findOne(options: FindOneOptions<TEntity>): Promise<TEntity | null>;
|
|
42
|
+
findOneBy(where: FindOptionsWhere<TEntity> | FindOptionsWhere<TEntity>[]): Promise<TEntity | null>;
|
|
43
|
+
findBy(where: FindOptionsWhere<TEntity> | FindOptionsWhere<TEntity>[]): Promise<TEntity[]>;
|
|
44
|
+
findById(id: number | string | ObjectId): Promise<TEntity | null>;
|
|
45
|
+
findByIds(ids: (number | string | ObjectId)[]): Promise<TEntity[]>;
|
|
46
|
+
findAndCount(options?: FindManyOptions<TEntity>): Promise<[TEntity[], number]>;
|
|
47
|
+
findAndCountBy(where: FindOptionsWhere<TEntity> | FindOptionsWhere<TEntity>[]): Promise<[TEntity[], number]>;
|
|
48
|
+
count(options?: FindManyOptions<TEntity>): Promise<number>;
|
|
49
|
+
countBy(where: FindOptionsWhere<TEntity> | FindOptionsWhere<TEntity>[]): Promise<number>;
|
|
50
|
+
exists(options?: FindManyOptions<TEntity>): Promise<boolean>;
|
|
51
|
+
existsBy(where: FindOptionsWhere<TEntity> | FindOptionsWhere<TEntity>[]): Promise<boolean>;
|
|
52
|
+
/**
|
|
53
|
+
* Fetch one page of entities.
|
|
54
|
+
*
|
|
55
|
+
* ```ts
|
|
56
|
+
* const { data, meta } = await repo.paginate({ where: { active: true } }, { page: 2, perPage: 20 });
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
paginate(options?: FindManyOptions<TEntity>, pagination?: PageRequest): Promise<Paginated<TEntity>>;
|
|
60
|
+
create(data?: DeepPartial<TEntity>): TEntity[];
|
|
61
|
+
createMany(dataArray: DeepPartial<TEntity>[]): TEntity[][];
|
|
62
|
+
save(data: DeepPartial<TEntity>, options?: SaveOptions): Promise<TEntity>;
|
|
63
|
+
saveMany(dataArray: DeepPartial<TEntity>[], options?: SaveOptions): Promise<TEntity[]>;
|
|
64
|
+
insert(data: DeepPartial<TEntity> | DeepPartial<TEntity>[]): Promise<InsertResult>;
|
|
65
|
+
upsert(data: DeepPartial<TEntity> | DeepPartial<TEntity>[], conflictPaths: string[] | any): Promise<InsertResult>;
|
|
66
|
+
update(criteria: string | string[] | number | number[] | FindOptionsWhere<TEntity>, data: DeepPartial<TEntity>): Promise<UpdateResult>;
|
|
67
|
+
updateById(id: number | string, data: DeepPartial<TEntity>): Promise<UpdateResult>;
|
|
68
|
+
delete(criteria: string | string[] | number | number[] | FindOptionsWhere<TEntity>): Promise<DeleteResult>;
|
|
69
|
+
deleteById(id: number | string): Promise<DeleteResult>;
|
|
70
|
+
remove(entity: TEntity, options?: RemoveOptions): Promise<TEntity>;
|
|
71
|
+
removeMany(entities: TEntity[], options?: RemoveOptions): Promise<TEntity[]>;
|
|
72
|
+
softDelete(criteria: string | string[] | number | number[] | FindOptionsWhere<TEntity>): Promise<UpdateResult>;
|
|
73
|
+
softDeleteById(id: number | string): Promise<UpdateResult>;
|
|
74
|
+
restore(criteria: string | string[] | number | number[] | FindOptionsWhere<TEntity>): Promise<UpdateResult>;
|
|
75
|
+
softRemove(entity: TEntity, options?: SaveOptions): Promise<TEntity>;
|
|
76
|
+
sum(column: keyof TEntity, where?: FindOptionsWhere<TEntity>): Promise<number | null>;
|
|
77
|
+
avg(column: keyof TEntity, where?: FindOptionsWhere<TEntity>): Promise<number | null>;
|
|
78
|
+
min(column: keyof TEntity, where?: FindOptionsWhere<TEntity>): Promise<number | null>;
|
|
79
|
+
max(column: keyof TEntity, where?: FindOptionsWhere<TEntity>): Promise<number | null>;
|
|
80
|
+
/**
|
|
81
|
+
* Run a callback inside a transaction. If the callback throws,
|
|
82
|
+
* the transaction is rolled back automatically.
|
|
83
|
+
*/
|
|
84
|
+
transaction<T>(work: (repo: this, queryRunner: QueryRunner) => Promise<T>): Promise<T>;
|
|
85
|
+
/**
|
|
86
|
+
* A copy of this repository bound to another `EntityManager` (for example a
|
|
87
|
+
* transaction's). The copy keeps every injected dependency of the original;
|
|
88
|
+
* no constructor runs.
|
|
89
|
+
*/
|
|
90
|
+
withManager(manager: EntityManager): this;
|
|
91
|
+
/** Create a QueryBuilder with a default alias of the entity table name. */
|
|
92
|
+
qb(alias?: string): SelectQueryBuilder<TEntity>;
|
|
93
|
+
/**
|
|
94
|
+
* Efficient bulk insert using chunking to avoid hitting SQL parameter limits.
|
|
95
|
+
*/
|
|
96
|
+
bulkInsert(rows: DeepPartial<TEntity>[], chunkSize?: number): Promise<void>;
|
|
97
|
+
/**
|
|
98
|
+
* Execute raw SQL. Use sparingly — prefer the query builder.
|
|
99
|
+
* @param sql Parameterised SQL string
|
|
100
|
+
* @param params Positional parameters
|
|
101
|
+
*/
|
|
102
|
+
raw<T = any>(sql: string, params?: any[]): Promise<T[]>;
|
|
103
|
+
protected getRepository(): OrmRepository<TEntity>;
|
|
104
|
+
protected getManager(): EntityManager;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Class decorator that registers a repository with the DI container and binds
|
|
108
|
+
* it to `entity`. The DataSource is resolved from the container when the
|
|
109
|
+
* repository is constructed.
|
|
110
|
+
*
|
|
111
|
+
* The class keeps its own constructor, so it can inject other services:
|
|
112
|
+
*
|
|
113
|
+
* ```ts
|
|
114
|
+
* @Repository(User)
|
|
115
|
+
* class UserRepository extends AvleonRepository<User> {
|
|
116
|
+
* constructor(private readonly audit: AuditService) { super(); }
|
|
117
|
+
* }
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
120
|
+
export declare function Repository<TEntity extends ObjectLiteral>(entity: EntityTarget<TEntity>): <TBase extends Constructor<AvleonRepository<TEntity>>>(Base: TBase) => TBase;
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AvleonRepository = exports.ArrayContains = exports.Equal = exports.Raw = exports.Any = exports.IsNull = exports.MoreThanOrEqual = exports.MoreThan = exports.LessThanOrEqual = exports.LessThan = exports.Between = exports.Not = exports.In = exports.ILike = exports.Like = void 0;
|
|
4
|
+
exports.Repository = Repository;
|
|
5
|
+
const core_1 = require("@avleon/core");
|
|
6
|
+
const datasource_1 = require("./datasource");
|
|
7
|
+
function typeormOperator(name) {
|
|
8
|
+
return ((...args) => {
|
|
9
|
+
const typeorm = (0, core_1.loadPackageFromClient)("typeorm");
|
|
10
|
+
return typeorm[name](...args);
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
exports.Like = typeormOperator("Like");
|
|
14
|
+
exports.ILike = typeormOperator("ILike");
|
|
15
|
+
exports.In = typeormOperator("In");
|
|
16
|
+
exports.Not = typeormOperator("Not");
|
|
17
|
+
exports.Between = typeormOperator("Between");
|
|
18
|
+
exports.LessThan = typeormOperator("LessThan");
|
|
19
|
+
exports.LessThanOrEqual = typeormOperator("LessThanOrEqual");
|
|
20
|
+
exports.MoreThan = typeormOperator("MoreThan");
|
|
21
|
+
exports.MoreThanOrEqual = typeormOperator("MoreThanOrEqual");
|
|
22
|
+
exports.IsNull = typeormOperator("IsNull");
|
|
23
|
+
exports.Any = typeormOperator("Any");
|
|
24
|
+
exports.Raw = typeormOperator("Raw");
|
|
25
|
+
exports.Equal = typeormOperator("Equal");
|
|
26
|
+
exports.ArrayContains = typeormOperator("ArrayContains");
|
|
27
|
+
// ─── Base Repository ─────────────────────────────────────────────────────────
|
|
28
|
+
const REPOSITORY_ENTITY = Symbol.for("avleon:repository:entity");
|
|
29
|
+
class AvleonRepository {
|
|
30
|
+
orm;
|
|
31
|
+
entity;
|
|
32
|
+
manager;
|
|
33
|
+
/**
|
|
34
|
+
* Both arguments are optional for `@Repository(Entity)` classes: the entity
|
|
35
|
+
* comes from the decorator and the manager from the registered DataSource,
|
|
36
|
+
* so a subclass constructor can take its own injected dependencies and
|
|
37
|
+
* call `super()` with no arguments.
|
|
38
|
+
*/
|
|
39
|
+
constructor(entity, manager) {
|
|
40
|
+
const resolvedEntity = entity ??
|
|
41
|
+
this.constructor[REPOSITORY_ENTITY];
|
|
42
|
+
if (!resolvedEntity) {
|
|
43
|
+
throw new Error(`[Avleon] ${this.constructor.name} has no entity. Decorate it with @Repository(Entity) or pass the entity to super().`);
|
|
44
|
+
}
|
|
45
|
+
this.entity = resolvedEntity;
|
|
46
|
+
this.manager = manager ?? (0, datasource_1.getDataSource)().manager;
|
|
47
|
+
this.orm = this.manager.getRepository(this.entity);
|
|
48
|
+
}
|
|
49
|
+
// ─── Metadata ────────────────────────────────────────────────────────────
|
|
50
|
+
get metadata() {
|
|
51
|
+
return this.orm.metadata;
|
|
52
|
+
}
|
|
53
|
+
get target() {
|
|
54
|
+
return this.entity;
|
|
55
|
+
}
|
|
56
|
+
// ─── Basic CRUD ──────────────────────────────────────────────────────────
|
|
57
|
+
find(options) {
|
|
58
|
+
return this.orm.find(options);
|
|
59
|
+
}
|
|
60
|
+
findOne(options) {
|
|
61
|
+
return this.orm.findOne(options);
|
|
62
|
+
}
|
|
63
|
+
findOneBy(where) {
|
|
64
|
+
return this.orm.findOneBy(where);
|
|
65
|
+
}
|
|
66
|
+
findBy(where) {
|
|
67
|
+
return this.orm.findBy(where);
|
|
68
|
+
}
|
|
69
|
+
findById(id) {
|
|
70
|
+
return this.orm.findOne({ where: { id } });
|
|
71
|
+
}
|
|
72
|
+
findByIds(ids) {
|
|
73
|
+
return this.orm.findBy({ id: (0, exports.In)(ids) });
|
|
74
|
+
}
|
|
75
|
+
findAndCount(options) {
|
|
76
|
+
return this.orm.findAndCount(options);
|
|
77
|
+
}
|
|
78
|
+
findAndCountBy(where) {
|
|
79
|
+
return this.orm.findAndCountBy(where);
|
|
80
|
+
}
|
|
81
|
+
count(options) {
|
|
82
|
+
return this.orm.count(options);
|
|
83
|
+
}
|
|
84
|
+
countBy(where) {
|
|
85
|
+
return this.orm.countBy(where);
|
|
86
|
+
}
|
|
87
|
+
exists(options) {
|
|
88
|
+
return this.orm.exists(options);
|
|
89
|
+
}
|
|
90
|
+
existsBy(where) {
|
|
91
|
+
return this.orm.existsBy(where);
|
|
92
|
+
}
|
|
93
|
+
// ─── Pagination ──────────────────────────────────────────────────────────
|
|
94
|
+
/**
|
|
95
|
+
* Fetch one page of entities.
|
|
96
|
+
*
|
|
97
|
+
* ```ts
|
|
98
|
+
* const { data, meta } = await repo.paginate({ where: { active: true } }, { page: 2, perPage: 20 });
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
async paginate(options = {}, pagination = {}) {
|
|
102
|
+
const { page, perPage, offset } = (0, core_1.normalizePageRequest)(pagination);
|
|
103
|
+
const [data, total] = await this.orm.findAndCount({
|
|
104
|
+
...options,
|
|
105
|
+
skip: offset,
|
|
106
|
+
take: perPage,
|
|
107
|
+
});
|
|
108
|
+
return (0, core_1.paginated)(data, total, page, perPage);
|
|
109
|
+
}
|
|
110
|
+
// ─── Create & Save ───────────────────────────────────────────────────────
|
|
111
|
+
create(data) {
|
|
112
|
+
return this.orm.create(data);
|
|
113
|
+
}
|
|
114
|
+
createMany(dataArray) {
|
|
115
|
+
return dataArray.map((d) => this.orm.create(d));
|
|
116
|
+
}
|
|
117
|
+
async save(data, options) {
|
|
118
|
+
return this.orm.save(data, options);
|
|
119
|
+
}
|
|
120
|
+
async saveMany(dataArray, options) {
|
|
121
|
+
return this.orm.save(dataArray, options);
|
|
122
|
+
}
|
|
123
|
+
// ─── Insert ──────────────────────────────────────────────────────────────
|
|
124
|
+
async insert(data) {
|
|
125
|
+
return this.orm.insert(data);
|
|
126
|
+
}
|
|
127
|
+
// ─── Upsert ──────────────────────────────────────────────────────────────
|
|
128
|
+
async upsert(data, conflictPaths) {
|
|
129
|
+
return this.orm.upsert(data, conflictPaths);
|
|
130
|
+
}
|
|
131
|
+
// ─── Update ──────────────────────────────────────────────────────────────
|
|
132
|
+
async update(criteria, data) {
|
|
133
|
+
return this.orm.update(criteria, data);
|
|
134
|
+
}
|
|
135
|
+
async updateById(id, data) {
|
|
136
|
+
return this.orm.update(id, data);
|
|
137
|
+
}
|
|
138
|
+
// ─── Delete & Remove ─────────────────────────────────────────────────────
|
|
139
|
+
async delete(criteria) {
|
|
140
|
+
return this.orm.delete(criteria);
|
|
141
|
+
}
|
|
142
|
+
async deleteById(id) {
|
|
143
|
+
return this.orm.delete(id);
|
|
144
|
+
}
|
|
145
|
+
async remove(entity, options) {
|
|
146
|
+
return this.orm.remove(entity, options);
|
|
147
|
+
}
|
|
148
|
+
async removeMany(entities, options) {
|
|
149
|
+
return this.orm.remove(entities, options);
|
|
150
|
+
}
|
|
151
|
+
// ─── Soft Delete (requires @DeleteDateColumn) ────────────────────────────
|
|
152
|
+
async softDelete(criteria) {
|
|
153
|
+
return this.orm.softDelete(criteria);
|
|
154
|
+
}
|
|
155
|
+
async softDeleteById(id) {
|
|
156
|
+
return this.orm.softDelete(id);
|
|
157
|
+
}
|
|
158
|
+
async restore(criteria) {
|
|
159
|
+
return this.orm.restore(criteria);
|
|
160
|
+
}
|
|
161
|
+
async softRemove(entity, options) {
|
|
162
|
+
return this.orm.softRemove(entity, options);
|
|
163
|
+
}
|
|
164
|
+
// ─── Aggregation via Query Builder ───────────────────────────────────────
|
|
165
|
+
async sum(column, where) {
|
|
166
|
+
const alias = "e";
|
|
167
|
+
const qb = this.orm
|
|
168
|
+
.createQueryBuilder(alias)
|
|
169
|
+
.select(`SUM(${alias}.${String(column)})`, "sum");
|
|
170
|
+
if (where)
|
|
171
|
+
qb.where(where);
|
|
172
|
+
const result = await qb.getRawOne();
|
|
173
|
+
return result?.sum != null ? Number(result.sum) : null;
|
|
174
|
+
}
|
|
175
|
+
async avg(column, where) {
|
|
176
|
+
const alias = "e";
|
|
177
|
+
const qb = this.orm
|
|
178
|
+
.createQueryBuilder(alias)
|
|
179
|
+
.select(`AVG(${alias}.${String(column)})`, "avg");
|
|
180
|
+
if (where)
|
|
181
|
+
qb.where(where);
|
|
182
|
+
const result = await qb.getRawOne();
|
|
183
|
+
return result?.avg != null ? Number(result.avg) : null;
|
|
184
|
+
}
|
|
185
|
+
async min(column, where) {
|
|
186
|
+
const alias = "e";
|
|
187
|
+
const qb = this.orm
|
|
188
|
+
.createQueryBuilder(alias)
|
|
189
|
+
.select(`MIN(${alias}.${String(column)})`, "min");
|
|
190
|
+
if (where)
|
|
191
|
+
qb.where(where);
|
|
192
|
+
const result = await qb.getRawOne();
|
|
193
|
+
return result?.min != null ? Number(result.min) : null;
|
|
194
|
+
}
|
|
195
|
+
async max(column, where) {
|
|
196
|
+
const alias = "e";
|
|
197
|
+
const qb = this.orm
|
|
198
|
+
.createQueryBuilder(alias)
|
|
199
|
+
.select(`MAX(${alias}.${String(column)})`, "max");
|
|
200
|
+
if (where)
|
|
201
|
+
qb.where(where);
|
|
202
|
+
const result = await qb.getRawOne();
|
|
203
|
+
return result?.max != null ? Number(result.max) : null;
|
|
204
|
+
}
|
|
205
|
+
// ─── Transactions ────────────────────────────────────────────────────────
|
|
206
|
+
/**
|
|
207
|
+
* Run a callback inside a transaction. If the callback throws,
|
|
208
|
+
* the transaction is rolled back automatically.
|
|
209
|
+
*/
|
|
210
|
+
async transaction(work) {
|
|
211
|
+
// Already inside a transaction: join it rather than opening a new one.
|
|
212
|
+
const current = this.manager.queryRunner;
|
|
213
|
+
if (current?.isTransactionActive) {
|
|
214
|
+
return work(this, current);
|
|
215
|
+
}
|
|
216
|
+
const queryRunner = this.manager.connection.createQueryRunner();
|
|
217
|
+
await queryRunner.connect();
|
|
218
|
+
await queryRunner.startTransaction();
|
|
219
|
+
const txRepo = this.withManager(queryRunner.manager);
|
|
220
|
+
try {
|
|
221
|
+
const result = await work(txRepo, queryRunner);
|
|
222
|
+
await queryRunner.commitTransaction();
|
|
223
|
+
return result;
|
|
224
|
+
}
|
|
225
|
+
catch (err) {
|
|
226
|
+
await queryRunner.rollbackTransaction();
|
|
227
|
+
throw err;
|
|
228
|
+
}
|
|
229
|
+
finally {
|
|
230
|
+
await queryRunner.release();
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* A copy of this repository bound to another `EntityManager` (for example a
|
|
235
|
+
* transaction's). The copy keeps every injected dependency of the original;
|
|
236
|
+
* no constructor runs.
|
|
237
|
+
*/
|
|
238
|
+
withManager(manager) {
|
|
239
|
+
const copy = Object.create(Object.getPrototypeOf(this));
|
|
240
|
+
Object.assign(copy, this);
|
|
241
|
+
copy.manager = manager;
|
|
242
|
+
copy.orm = manager.getRepository(this.entity);
|
|
243
|
+
return copy;
|
|
244
|
+
}
|
|
245
|
+
// ─── Query Builder Access ────────────────────────────────────────────────
|
|
246
|
+
/** Create a QueryBuilder with a default alias of the entity table name. */
|
|
247
|
+
qb(alias) {
|
|
248
|
+
return this.orm.createQueryBuilder(alias ?? this.orm.metadata.tableName);
|
|
249
|
+
}
|
|
250
|
+
// ─── Bulk / Raw ──────────────────────────────────────────────────────────
|
|
251
|
+
/**
|
|
252
|
+
* Efficient bulk insert using chunking to avoid hitting SQL parameter limits.
|
|
253
|
+
*/
|
|
254
|
+
async bulkInsert(rows, chunkSize = 500) {
|
|
255
|
+
for (let i = 0; i < rows.length; i += chunkSize) {
|
|
256
|
+
await this.orm.insert(rows.slice(i, i + chunkSize));
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Execute raw SQL. Use sparingly — prefer the query builder.
|
|
261
|
+
* @param sql Parameterised SQL string
|
|
262
|
+
* @param params Positional parameters
|
|
263
|
+
*/
|
|
264
|
+
async raw(sql, params) {
|
|
265
|
+
return this.manager.query(sql, params);
|
|
266
|
+
}
|
|
267
|
+
// ─── Protected helpers ───────────────────────────────────────────────────
|
|
268
|
+
getRepository() {
|
|
269
|
+
return this.orm;
|
|
270
|
+
}
|
|
271
|
+
getManager() {
|
|
272
|
+
return this.manager;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
exports.AvleonRepository = AvleonRepository;
|
|
276
|
+
// ─── @Repository decorator ───────────────────────────────────────────────────
|
|
277
|
+
/**
|
|
278
|
+
* Class decorator that registers a repository with the DI container and binds
|
|
279
|
+
* it to `entity`. The DataSource is resolved from the container when the
|
|
280
|
+
* repository is constructed.
|
|
281
|
+
*
|
|
282
|
+
* The class keeps its own constructor, so it can inject other services:
|
|
283
|
+
*
|
|
284
|
+
* ```ts
|
|
285
|
+
* @Repository(User)
|
|
286
|
+
* class UserRepository extends AvleonRepository<User> {
|
|
287
|
+
* constructor(private readonly audit: AuditService) { super(); }
|
|
288
|
+
* }
|
|
289
|
+
* ```
|
|
290
|
+
*/
|
|
291
|
+
function Repository(entity) {
|
|
292
|
+
return function (Base) {
|
|
293
|
+
Object.defineProperty(Base, REPOSITORY_ENTITY, {
|
|
294
|
+
value: entity,
|
|
295
|
+
enumerable: false,
|
|
296
|
+
configurable: true,
|
|
297
|
+
writable: true,
|
|
298
|
+
});
|
|
299
|
+
(0, core_1.Injectable)()(Base);
|
|
300
|
+
return Base;
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
//# sourceMappingURL=typeorm-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typeorm-provider.js","sourceRoot":"","sources":["../src/typeorm-provider.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,101 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@avleon/data",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.4.1",
|
|
4
|
+
"description": "TypeORM and Knex integration for Avleon",
|
|
5
|
+
"author": "Tareq Hossain",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"require": "./dist/index.js",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"./plugin": {
|
|
16
|
+
"types": "./dist/plugin.d.ts",
|
|
17
|
+
"require": "./dist/plugin.js",
|
|
18
|
+
"default": "./dist/plugin.js"
|
|
19
|
+
},
|
|
20
|
+
"./package.json": "./package.json"
|
|
21
|
+
},
|
|
22
|
+
"avleon": {
|
|
23
|
+
"plugin": "./dist/plugin.js"
|
|
24
|
+
},
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=20.0.0"
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"dist",
|
|
30
|
+
"README.md",
|
|
31
|
+
"LICENSE"
|
|
32
|
+
],
|
|
33
|
+
"keywords": [
|
|
34
|
+
"avleon",
|
|
35
|
+
"typeorm",
|
|
36
|
+
"knex",
|
|
37
|
+
"database",
|
|
38
|
+
"typescript"
|
|
39
|
+
],
|
|
40
|
+
"scripts": {
|
|
41
|
+
"build": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.json",
|
|
42
|
+
"typecheck": "tsc --noEmit -p tsconfig.json && tsc --noEmit -p tsconfig.test.json",
|
|
43
|
+
"test": "vitest run",
|
|
44
|
+
"test:watch": "vitest",
|
|
45
|
+
"prepublishOnly": "npm run build"
|
|
46
|
+
},
|
|
47
|
+
"peerDependencies": {
|
|
48
|
+
"@avleon/core": "^0.4.1",
|
|
49
|
+
"better-sqlite3": ">=12.0.0",
|
|
50
|
+
"knex": ">=2.0.0",
|
|
51
|
+
"mssql": ">=11.0.0",
|
|
52
|
+
"mysql2": ">=3.0.0",
|
|
53
|
+
"pg": ">=8.0.0",
|
|
54
|
+
"sqlite3": ">=5.0.0",
|
|
55
|
+
"typeorm": ">=0.3.0"
|
|
56
|
+
},
|
|
57
|
+
"peerDependenciesMeta": {
|
|
58
|
+
"better-sqlite3": {
|
|
59
|
+
"optional": true
|
|
60
|
+
},
|
|
61
|
+
"knex": {
|
|
62
|
+
"optional": true
|
|
63
|
+
},
|
|
64
|
+
"mssql": {
|
|
65
|
+
"optional": true
|
|
66
|
+
},
|
|
67
|
+
"mysql2": {
|
|
68
|
+
"optional": true
|
|
69
|
+
},
|
|
70
|
+
"pg": {
|
|
71
|
+
"optional": true
|
|
72
|
+
},
|
|
73
|
+
"sqlite3": {
|
|
74
|
+
"optional": true
|
|
75
|
+
},
|
|
76
|
+
"typeorm": {
|
|
77
|
+
"optional": true
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
"devDependencies": {
|
|
81
|
+
"@avleon/core": "^0.4.1",
|
|
82
|
+
"@swc/core": "^1.16.20",
|
|
83
|
+
"@types/node": "^20.19.17",
|
|
84
|
+
"better-sqlite3": "^12.9.0",
|
|
85
|
+
"knex": "^3.1.0",
|
|
86
|
+
"reflect-metadata": "^0.2.2",
|
|
87
|
+
"typeorm": "^0.3.28",
|
|
88
|
+
"typescript": "^5.7.2",
|
|
89
|
+
"unplugin-swc": "^2.0.0",
|
|
90
|
+
"vitest": "^4.1.12"
|
|
91
|
+
},
|
|
92
|
+
"repository": {
|
|
93
|
+
"type": "git",
|
|
94
|
+
"url": "git+https://github.com/avleonjs/avleon.git",
|
|
95
|
+
"directory": "packages/data"
|
|
96
|
+
},
|
|
97
|
+
"publishConfig": {
|
|
98
|
+
"access": "public"
|
|
99
|
+
},
|
|
100
|
+
"gitHead": "6c29ba1d028d41ade15fda5ec9444a86d7c3df19"
|
|
101
|
+
}
|