remult 0.13.27 → 0.14.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/package.json +1 -1
- package/readme.md +18 -6
- package/remult-express.d.ts +5 -1
- package/remult-express.js +16 -1
- package/remult-middleware.d.ts +2 -0
- package/remult-middleware.js +69 -0
- package/server/expressBridge.d.ts +40 -14
- package/server/expressBridge.js +25 -29
- package/src/column-interfaces.d.ts +3 -3
- package/src/context.js +9 -9
- package/src/data-providers/array-entity-data-provider.js +37 -34
- package/src/entity.d.ts +2 -2
- package/src/remult3/RepositoryImplementation.d.ts +6 -5
- package/src/remult3/RepositoryImplementation.js +6 -5
- package/src/remult3/remult3.d.ts +8 -3
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -21,6 +21,9 @@
|
|
|
21
21
|
<a href="https://discord.gg/GXHk7ZfuG5">
|
|
22
22
|
<img alt="chat on discord" src="https://img.shields.io/badge/chat-on%20discord-blueviolet"/>
|
|
23
23
|
</a>
|
|
24
|
+
<a href="https://twitter.com/remultjs">
|
|
25
|
+
<img alt="Twitter Follow" src="https://img.shields.io/twitter/follow/remultjs?style=social">
|
|
26
|
+
</a>
|
|
24
27
|
</div>
|
|
25
28
|
|
|
26
29
|
## What is Remult?
|
|
@@ -114,24 +117,29 @@ static async increasePriceOfTofu(priceIncrease: number, remult?: Remult) {
|
|
|
114
117
|
### :ballot_box_with_check: Data validation and constraints - defined once
|
|
115
118
|
|
|
116
119
|
```ts
|
|
117
|
-
import { Entity, Fields } from 'remult';
|
|
120
|
+
import { Entity, Fields, Validators } from 'remult';
|
|
118
121
|
|
|
119
122
|
@Entity('products', {
|
|
120
123
|
allowApiCrud: true
|
|
121
124
|
})
|
|
122
125
|
export class Product {
|
|
126
|
+
@Fields.string({
|
|
127
|
+
validate: Validators.required
|
|
128
|
+
})
|
|
129
|
+
name = '';
|
|
130
|
+
|
|
123
131
|
@Fields.string<Product>({
|
|
124
132
|
validate: product => {
|
|
125
|
-
if (product.
|
|
126
|
-
throw
|
|
133
|
+
if (product.description.trim().length < 50)
|
|
134
|
+
throw "too short";
|
|
127
135
|
}
|
|
128
136
|
})
|
|
129
|
-
|
|
137
|
+
description = '';
|
|
130
138
|
|
|
131
139
|
@Fields.number({
|
|
132
140
|
validate: (_, field) => {
|
|
133
141
|
if (field.value < 0)
|
|
134
|
-
throw "must not be less than 0";
|
|
142
|
+
field.error = "must not be less than 0"; // or: throw "must not be less than 0";
|
|
135
143
|
}
|
|
136
144
|
})
|
|
137
145
|
unitPrice = 0;
|
|
@@ -181,7 +189,11 @@ export class Article {
|
|
|
181
189
|
[CRM demo](https://github.com/remult/crm-demo) with a React + [MUI](https://mui.com) front-end and Postgres database.
|
|
182
190
|
|
|
183
191
|
## Contributing
|
|
184
|
-
Contributions are welcome. See [CONTRIBUTING](CONTRIBUTING.md).
|
|
192
|
+
Contributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
193
|
+
|
|
194
|
+
* :speech_balloon: Any feedback or suggestions? Start a [discussion](https://github.com/remult/remult/discussions).
|
|
195
|
+
* :muscle: Want to help out? Look for "help wanted" labeled [issues](https://github.com/remult/remult/issues).
|
|
196
|
+
* :star: Give this repo a star.
|
|
185
197
|
|
|
186
198
|
## License
|
|
187
199
|
Remult is [MIT Licensed](LICENSE).
|
package/remult-express.d.ts
CHANGED
|
@@ -1 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
import { RemultMiddlewareOptions } from './server/expressBridge';
|
|
2
|
+
export declare function remultExpress(options?: RemultMiddlewareOptions & {
|
|
3
|
+
bodyParser?: boolean;
|
|
4
|
+
bodySizeLimit?: string;
|
|
5
|
+
}): import("./server/expressBridge").RemultExpressBridge;
|
package/remult-express.js
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.remultExpress = void 0;
|
|
4
|
+
var express = require("express");
|
|
4
5
|
var expressBridge_1 = require("./server/expressBridge");
|
|
5
|
-
|
|
6
|
+
function remultExpress(options) {
|
|
7
|
+
var app = express.Router();
|
|
8
|
+
if (!options) {
|
|
9
|
+
options = {};
|
|
10
|
+
}
|
|
11
|
+
if (options.bodySizeLimit === undefined) {
|
|
12
|
+
options.bodySizeLimit = '10mb';
|
|
13
|
+
}
|
|
14
|
+
if ((options === null || options === void 0 ? void 0 : options.bodyParser) !== false) {
|
|
15
|
+
app.use(express.json({ limit: options.bodySizeLimit }));
|
|
16
|
+
app.use(express.urlencoded({ extended: true, limit: options.bodySizeLimit }));
|
|
17
|
+
}
|
|
18
|
+
return expressBridge_1.remultMiddlewareBase(app, options);
|
|
19
|
+
}
|
|
20
|
+
exports.remultExpress = remultExpress;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.remultMiddleware = void 0;
|
|
4
|
+
var expressBridge_1 = require("./server/expressBridge");
|
|
5
|
+
function remultMiddleware(options) {
|
|
6
|
+
var m = new middleware();
|
|
7
|
+
var app = Object.assign(m, function (req, res, next) { return m.handleRequest(req, res, next); });
|
|
8
|
+
return expressBridge_1.remultMiddlewareBase(app, options);
|
|
9
|
+
}
|
|
10
|
+
exports.remultMiddleware = remultMiddleware;
|
|
11
|
+
var middleware = /** @class */ (function () {
|
|
12
|
+
function middleware() {
|
|
13
|
+
this.map = new Map();
|
|
14
|
+
}
|
|
15
|
+
middleware.prototype.route = function (path) {
|
|
16
|
+
//consider using:
|
|
17
|
+
//* https://raw.githubusercontent.com/cmorten/opine/main/src/utils/pathToRegex.ts
|
|
18
|
+
//* https://github.com/pillarjs/path-to-regexp
|
|
19
|
+
var r = path.toLowerCase();
|
|
20
|
+
var m = new Map();
|
|
21
|
+
this.map.set(r, m);
|
|
22
|
+
var route = {
|
|
23
|
+
get: function (h) {
|
|
24
|
+
m.set("get", h);
|
|
25
|
+
return route;
|
|
26
|
+
},
|
|
27
|
+
put: function (h) {
|
|
28
|
+
m.set("put", h);
|
|
29
|
+
return route;
|
|
30
|
+
},
|
|
31
|
+
post: function (h) {
|
|
32
|
+
m.set("post", h);
|
|
33
|
+
return route;
|
|
34
|
+
},
|
|
35
|
+
delete: function (h) {
|
|
36
|
+
m.set("delete", h);
|
|
37
|
+
return route;
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
return route;
|
|
41
|
+
};
|
|
42
|
+
middleware.prototype.handleRequest = function (req, res, next) {
|
|
43
|
+
var lowerPath = req.path.toLowerCase();
|
|
44
|
+
var m = this.map.get(lowerPath);
|
|
45
|
+
if (m) {
|
|
46
|
+
var h = m.get(req.method.toLowerCase());
|
|
47
|
+
if (h) {
|
|
48
|
+
h(req, res, next);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
var idPosition = req.path.lastIndexOf('/');
|
|
53
|
+
if (idPosition >= 0) {
|
|
54
|
+
lowerPath = req.path.substring(0, idPosition) + '/:id';
|
|
55
|
+
m = this.map.get(lowerPath);
|
|
56
|
+
if (m) {
|
|
57
|
+
var h = m.get(req.method.toLowerCase());
|
|
58
|
+
if (h) {
|
|
59
|
+
req.params.id = req.path.substring(idPosition + 1);
|
|
60
|
+
h(req, res, next);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
console.log(req.path);
|
|
66
|
+
next();
|
|
67
|
+
};
|
|
68
|
+
return middleware;
|
|
69
|
+
}());
|
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
import { DataProvider, Remult, IdEntity } from '../';
|
|
2
|
-
import * as express from 'express';
|
|
3
2
|
import { Repository } from '../src/remult3';
|
|
4
3
|
import { queuedJobInfoResponse } from '../src/server-action';
|
|
5
4
|
import { DataApi, DataApiRequest, DataApiResponse } from '../src/data-api';
|
|
6
5
|
import { AllowedForInstance } from '../src/context';
|
|
7
6
|
import { ClassType } from '../classType';
|
|
8
|
-
export declare
|
|
7
|
+
export declare type RemultMiddlewareOptions = {
|
|
9
8
|
/** Sets a database connection for Remult.
|
|
10
9
|
*
|
|
11
10
|
* @see [Connecting to a Database](https://remult.dev/docs/databases.html).
|
|
12
11
|
*/
|
|
13
12
|
dataProvider?: DataProvider | Promise<DataProvider> | (() => Promise<DataProvider | undefined>);
|
|
14
|
-
bodySizeLimit?: string;
|
|
15
13
|
disableAutoApi?: boolean;
|
|
16
14
|
queueStorage?: QueueStorage;
|
|
17
|
-
initRequest?: (remult: Remult, origReq:
|
|
15
|
+
initRequest?: (remult: Remult, origReq: GenericRequest) => Promise<void>;
|
|
18
16
|
initApi?: (remult: Remult) => void | Promise<void>;
|
|
19
17
|
logApiEndPoints?: boolean;
|
|
20
18
|
defaultGetLimit?: number;
|
|
@@ -22,42 +20,70 @@ export declare function remultExpress(options?: {
|
|
|
22
20
|
controllers?: ClassType<any>[];
|
|
23
21
|
bodyParser?: boolean;
|
|
24
22
|
rootPath?: string;
|
|
25
|
-
}
|
|
26
|
-
export
|
|
27
|
-
|
|
23
|
+
};
|
|
24
|
+
export declare function remultMiddlewareBase(app: GenericRouter, options: RemultMiddlewareOptions): RemultExpressBridge;
|
|
25
|
+
export interface RemultExpressBridge extends GenericRequestHandler {
|
|
26
|
+
getRemult(req: GenericRequest): Promise<Remult>;
|
|
28
27
|
openApiDoc(options: {
|
|
29
28
|
title: string;
|
|
30
29
|
}): any;
|
|
31
30
|
addArea(rootUrl: string): any;
|
|
32
31
|
}
|
|
32
|
+
export interface GenericRequest {
|
|
33
|
+
method: any;
|
|
34
|
+
path: any;
|
|
35
|
+
originalUrl: any;
|
|
36
|
+
query: any;
|
|
37
|
+
body: any;
|
|
38
|
+
params: any;
|
|
39
|
+
}
|
|
40
|
+
export interface GenericResponse {
|
|
41
|
+
status(arg0: number): any;
|
|
42
|
+
statusCode: number;
|
|
43
|
+
json(data: any): any;
|
|
44
|
+
writeHead(status: number): {
|
|
45
|
+
end: VoidFunction;
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export declare type GenericRouter = GenericRequestHandler & {
|
|
49
|
+
route(path: string): SpecificRoute;
|
|
50
|
+
};
|
|
51
|
+
export declare type SpecificRoute = {
|
|
52
|
+
get(handler: GenericRequestHandler): SpecificRoute;
|
|
53
|
+
put(handler: GenericRequestHandler): SpecificRoute;
|
|
54
|
+
post(handler: GenericRequestHandler): SpecificRoute;
|
|
55
|
+
delete(handler: GenericRequestHandler): SpecificRoute;
|
|
56
|
+
};
|
|
57
|
+
export declare type GenericRequestHandler = (req: GenericRequest, res: GenericResponse, next: VoidFunction) => void;
|
|
33
58
|
declare class ExpressBridge {
|
|
34
59
|
private app;
|
|
35
60
|
queue: inProcessQueueHandler;
|
|
36
|
-
initRequest: (remult: Remult, origReq:
|
|
61
|
+
initRequest: (remult: Remult, origReq: GenericRequest) => Promise<void>;
|
|
37
62
|
dataProvider: DataProvider | Promise<DataProvider>;
|
|
38
63
|
openApiDoc(options: {
|
|
39
64
|
title: string;
|
|
65
|
+
version?: string;
|
|
40
66
|
}): any;
|
|
41
67
|
backendMethodsOpenApi: {
|
|
42
68
|
path: string;
|
|
43
69
|
allowed: AllowedForInstance<any>;
|
|
44
70
|
tag: string;
|
|
45
71
|
}[];
|
|
46
|
-
constructor(app:
|
|
72
|
+
constructor(app: GenericRouter, queue: inProcessQueueHandler, initRequest: (remult: Remult, origReq: GenericRequest) => Promise<void>, dataProvider: DataProvider | Promise<DataProvider>);
|
|
47
73
|
logApiEndPoints: boolean;
|
|
48
74
|
private firstArea;
|
|
49
75
|
addArea(rootUrl: string): SiteArea;
|
|
50
|
-
getRemult(req?:
|
|
76
|
+
getRemult(req?: GenericRequest): Promise<Remult>;
|
|
51
77
|
}
|
|
52
78
|
export declare class SiteArea {
|
|
53
79
|
private bridge;
|
|
54
80
|
private app;
|
|
55
81
|
private rootUrl;
|
|
56
82
|
private logApiEndpoints;
|
|
57
|
-
constructor(bridge: ExpressBridge, app:
|
|
83
|
+
constructor(bridge: ExpressBridge, app: GenericRouter, rootUrl: string, logApiEndpoints: boolean);
|
|
58
84
|
add(key: string, dataApiFactory: ((req: Remult) => DataApi)): void;
|
|
59
|
-
process(what: (remult: Remult, myReq: DataApiRequest, myRes: DataApiResponse, origReq:
|
|
60
|
-
getRemult(req:
|
|
85
|
+
process(what: (remult: Remult, myReq: DataApiRequest, myRes: DataApiResponse, origReq: GenericRequest) => Promise<void>): (req: GenericRequest, res: GenericResponse) => Promise<void>;
|
|
86
|
+
getRemult(req: GenericRequest): Promise<Remult>;
|
|
61
87
|
initQueue(): void;
|
|
62
88
|
addAction(action: {
|
|
63
89
|
__register: (reg: (url: string, queue: boolean, allowed: AllowedForInstance<any>, what: ((data: any, req: Remult, res: DataApiResponse) => void)) => void) => void;
|
|
@@ -66,7 +92,7 @@ export declare class SiteArea {
|
|
|
66
92
|
export declare class ExpressRequestBridgeToDataApiRequest implements DataApiRequest {
|
|
67
93
|
private r;
|
|
68
94
|
get(key: string): any;
|
|
69
|
-
constructor(r:
|
|
95
|
+
constructor(r: GenericRequest);
|
|
70
96
|
}
|
|
71
97
|
declare class inProcessQueueHandler {
|
|
72
98
|
private storage;
|
package/server/expressBridge.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.JobsInQueueEntity = exports.EntityQueueStorage = exports.ExpressRequestBridgeToDataApiRequest = exports.SiteArea = exports.
|
|
3
|
+
exports.JobsInQueueEntity = exports.EntityQueueStorage = exports.ExpressRequestBridgeToDataApiRequest = exports.SiteArea = exports.remultMiddlewareBase = void 0;
|
|
4
4
|
var tslib_1 = require("tslib");
|
|
5
5
|
var __1 = require("../");
|
|
6
|
-
var express = require("express");
|
|
7
6
|
var register_actions_on_server_1 = require("./register-actions-on-server");
|
|
8
7
|
var register_entities_on_server_1 = require("./register-entities-on-server");
|
|
9
8
|
var JsonEntityFileStorage_1 = require("./JsonEntityFileStorage");
|
|
@@ -12,9 +11,8 @@ var remult3_1 = require("../src/remult3");
|
|
|
12
11
|
var server_action_1 = require("../src/server-action");
|
|
13
12
|
var data_api_1 = require("../src/data-api");
|
|
14
13
|
var context_1 = require("../src/context");
|
|
15
|
-
function
|
|
14
|
+
function remultMiddlewareBase(app, options) {
|
|
16
15
|
var _this = this;
|
|
17
|
-
var app = express.Router();
|
|
18
16
|
if (!options) {
|
|
19
17
|
options = {};
|
|
20
18
|
}
|
|
@@ -22,16 +20,9 @@ function remultExpress(options) {
|
|
|
22
20
|
if (options.defaultGetLimit) {
|
|
23
21
|
data_api_1.DataApi.defaultGetLimit = options.defaultGetLimit;
|
|
24
22
|
}
|
|
25
|
-
if (options.bodySizeLimit === undefined) {
|
|
26
|
-
options.bodySizeLimit = '10mb';
|
|
27
|
-
}
|
|
28
23
|
if (!options.queueStorage) {
|
|
29
24
|
options.queueStorage = new InMemoryQueueStorage();
|
|
30
25
|
}
|
|
31
|
-
if ((options === null || options === void 0 ? void 0 : options.bodyParser) !== false) {
|
|
32
|
-
app.use(express.json({ limit: options.bodySizeLimit }));
|
|
33
|
-
app.use(express.urlencoded({ extended: true, limit: options.bodySizeLimit }));
|
|
34
|
-
}
|
|
35
26
|
var dataProvider;
|
|
36
27
|
if (typeof options.dataProvider === "function") {
|
|
37
28
|
dataProvider = options.dataProvider();
|
|
@@ -61,7 +52,9 @@ function remultExpress(options) {
|
|
|
61
52
|
var bridge = new ExpressBridge(app, new inProcessQueueHandler(options.queueStorage), options.initRequest, dataProvider);
|
|
62
53
|
if (options.logApiEndPoints !== undefined)
|
|
63
54
|
bridge.logApiEndPoints = options.logApiEndPoints;
|
|
64
|
-
|
|
55
|
+
if (options.rootPath === undefined)
|
|
56
|
+
options.rootPath = __1.Remult.apiBaseUrl;
|
|
57
|
+
var apiArea = bridge.addArea(options.rootPath);
|
|
65
58
|
if (!options.disableAutoApi) {
|
|
66
59
|
var actions = [];
|
|
67
60
|
if (options.entities)
|
|
@@ -77,7 +70,7 @@ function remultExpress(options) {
|
|
|
77
70
|
addArea: function (x) { return bridge.addArea(x); }
|
|
78
71
|
});
|
|
79
72
|
}
|
|
80
|
-
exports.
|
|
73
|
+
exports.remultMiddlewareBase = remultMiddlewareBase;
|
|
81
74
|
var ExpressBridge = /** @class */ (function () {
|
|
82
75
|
function ExpressBridge(app, queue, initRequest, dataProvider) {
|
|
83
76
|
this.app = app;
|
|
@@ -91,11 +84,14 @@ var ExpressBridge = /** @class */ (function () {
|
|
|
91
84
|
ExpressBridge.prototype.openApiDoc = function (options) {
|
|
92
85
|
var e_1, _a, e_2, _b;
|
|
93
86
|
var r = new __1.Remult();
|
|
87
|
+
if (!options.version)
|
|
88
|
+
options.version = "1.0.0";
|
|
94
89
|
var spec = {
|
|
95
|
-
info: { title: options.title },
|
|
90
|
+
info: { title: options.title, version: options.version },
|
|
96
91
|
openapi: "3.0.0",
|
|
97
92
|
//swagger: "2.0",
|
|
98
93
|
"components": {
|
|
94
|
+
"schemas": {},
|
|
99
95
|
"securitySchemes": {
|
|
100
96
|
"bearerAuth": {
|
|
101
97
|
"scheme": "bearer",
|
|
@@ -104,8 +100,7 @@ var ExpressBridge = /** @class */ (function () {
|
|
|
104
100
|
}
|
|
105
101
|
}
|
|
106
102
|
},
|
|
107
|
-
paths: {}
|
|
108
|
-
definitions: {}
|
|
103
|
+
paths: {}
|
|
109
104
|
};
|
|
110
105
|
var validationError = {
|
|
111
106
|
"400": {
|
|
@@ -113,7 +108,7 @@ var ExpressBridge = /** @class */ (function () {
|
|
|
113
108
|
"content": {
|
|
114
109
|
"application/json": {
|
|
115
110
|
"schema": {
|
|
116
|
-
"$ref": "#/
|
|
111
|
+
"$ref": "#/components/schemas/InvalidResponse"
|
|
117
112
|
}
|
|
118
113
|
}
|
|
119
114
|
}
|
|
@@ -180,12 +175,12 @@ var ExpressBridge = /** @class */ (function () {
|
|
|
180
175
|
}
|
|
181
176
|
finally { if (e_3) throw e_3.error; }
|
|
182
177
|
}
|
|
183
|
-
spec.
|
|
178
|
+
spec.components.schemas[key] = {
|
|
184
179
|
type: "object",
|
|
185
180
|
properties: properties
|
|
186
181
|
};
|
|
187
182
|
var definition = {
|
|
188
|
-
"$ref": "#/
|
|
183
|
+
"$ref": "#/components/schemas/" + key
|
|
189
184
|
};
|
|
190
185
|
var secure = function (condition, def, item) {
|
|
191
186
|
item.tags = [meta.key];
|
|
@@ -204,28 +199,28 @@ var ExpressBridge = /** @class */ (function () {
|
|
|
204
199
|
"description": "limit the number of returned rows, default 100",
|
|
205
200
|
"required": false,
|
|
206
201
|
"style": "simple",
|
|
207
|
-
"type": "
|
|
202
|
+
"schema": { "type": "integer" }
|
|
208
203
|
},
|
|
209
204
|
{
|
|
210
205
|
"name": "_page",
|
|
211
206
|
"in": "query",
|
|
212
207
|
"description": "to be used for paging",
|
|
213
208
|
"required": false,
|
|
214
|
-
"type": "
|
|
209
|
+
"schema": { "type": "integer" }
|
|
215
210
|
},
|
|
216
211
|
{
|
|
217
212
|
"name": "_sort",
|
|
218
213
|
"in": "query",
|
|
219
214
|
"description": "the columns to sort on",
|
|
220
215
|
"required": false,
|
|
221
|
-
"type": "string"
|
|
216
|
+
"schema": { "type": "string" }
|
|
222
217
|
},
|
|
223
218
|
{
|
|
224
219
|
"name": "_order",
|
|
225
220
|
"in": "query",
|
|
226
221
|
"description": "the sort order to user for the columns in `_sort`",
|
|
227
222
|
"required": false,
|
|
228
|
-
"type": "string"
|
|
223
|
+
"schema": { "type": "string" }
|
|
229
224
|
}], parameters),
|
|
230
225
|
responses: {
|
|
231
226
|
"200": {
|
|
@@ -246,14 +241,14 @@ var ExpressBridge = /** @class */ (function () {
|
|
|
246
241
|
"in": "path",
|
|
247
242
|
"description": "id of " + key,
|
|
248
243
|
"required": true,
|
|
249
|
-
"type": "string"
|
|
244
|
+
"schema": { "type": "string" },
|
|
250
245
|
};
|
|
251
246
|
var itemInBody = {
|
|
252
247
|
"requestBody": {
|
|
253
248
|
"content": {
|
|
254
249
|
"application/json": {
|
|
255
250
|
"schema": {
|
|
256
|
-
"$ref": "#/
|
|
251
|
+
"$ref": "#/components/schemas/" + key
|
|
257
252
|
}
|
|
258
253
|
}
|
|
259
254
|
}
|
|
@@ -267,7 +262,7 @@ var ExpressBridge = /** @class */ (function () {
|
|
|
267
262
|
"content": {
|
|
268
263
|
"application/json": {
|
|
269
264
|
"schema": {
|
|
270
|
-
"$ref": "#/
|
|
265
|
+
"$ref": "#/components/schemas/" + key
|
|
271
266
|
}
|
|
272
267
|
}
|
|
273
268
|
}
|
|
@@ -280,7 +275,7 @@ var ExpressBridge = /** @class */ (function () {
|
|
|
280
275
|
"content": {
|
|
281
276
|
"application/json": {
|
|
282
277
|
"schema": {
|
|
283
|
-
"$ref": "#/
|
|
278
|
+
"$ref": "#/components/schemas/" + key
|
|
284
279
|
}
|
|
285
280
|
}
|
|
286
281
|
}
|
|
@@ -297,7 +292,7 @@ var ExpressBridge = /** @class */ (function () {
|
|
|
297
292
|
"content": {
|
|
298
293
|
"application/json": {
|
|
299
294
|
"schema": {
|
|
300
|
-
"$ref": "#/
|
|
295
|
+
"$ref": "#/components/schemas/" + key
|
|
301
296
|
}
|
|
302
297
|
}
|
|
303
298
|
}
|
|
@@ -376,7 +371,7 @@ var ExpressBridge = /** @class */ (function () {
|
|
|
376
371
|
}
|
|
377
372
|
finally { if (e_2) throw e_2.error; }
|
|
378
373
|
}
|
|
379
|
-
spec.
|
|
374
|
+
spec.components.schemas["InvalidResponse"] = {
|
|
380
375
|
"type": "object",
|
|
381
376
|
properties: {
|
|
382
377
|
"message": {
|
|
@@ -856,3 +851,4 @@ var JobsInQueueEntity = /** @class */ (function (_super) {
|
|
|
856
851
|
return JobsInQueueEntity;
|
|
857
852
|
}(__1.IdEntity));
|
|
858
853
|
exports.JobsInQueueEntity = JobsInQueueEntity;
|
|
854
|
+
context_1.allEntities.splice(context_1.allEntities.indexOf(JobsInQueueEntity), 1);
|
|
@@ -14,18 +14,18 @@ export interface FieldOptions<entityType = any, valueType = any> {
|
|
|
14
14
|
allowApiUpdate?: AllowedForInstance<entityType>;
|
|
15
15
|
/** An arrow function that'll be used to perform validations on it
|
|
16
16
|
* @example
|
|
17
|
-
*
|
|
17
|
+
* @Fields.string({
|
|
18
18
|
* validate: Validators.required
|
|
19
19
|
* })
|
|
20
20
|
* @example
|
|
21
|
-
*
|
|
21
|
+
* @Fields.string<Task>({
|
|
22
22
|
* validate: task=>{
|
|
23
23
|
* if (task.title.length<3)
|
|
24
24
|
* throw "Too Short";
|
|
25
25
|
* }
|
|
26
26
|
* })
|
|
27
27
|
* @example
|
|
28
|
-
*
|
|
28
|
+
* @Fields.string({
|
|
29
29
|
* validate: (_, fieldRef)=>{
|
|
30
30
|
* if (fieldRef.value.length<3)
|
|
31
31
|
* fieldRef.error = "Too Short";
|
package/src/context.js
CHANGED
|
@@ -41,28 +41,28 @@ var HttpProviderBridgeToRestDataProviderHttpProvider = /** @class */ (function (
|
|
|
41
41
|
}());
|
|
42
42
|
exports.HttpProviderBridgeToRestDataProviderHttpProvider = HttpProviderBridgeToRestDataProviderHttpProvider;
|
|
43
43
|
function retry(what) {
|
|
44
|
-
var _a, _b, _c;
|
|
44
|
+
var _a, _b, _c, _d;
|
|
45
45
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
46
46
|
var err_1;
|
|
47
|
-
return tslib_1.__generator(this, function (
|
|
48
|
-
switch (
|
|
47
|
+
return tslib_1.__generator(this, function (_e) {
|
|
48
|
+
switch (_e.label) {
|
|
49
49
|
case 0:
|
|
50
50
|
if (!true) return [3 /*break*/, 7];
|
|
51
|
-
|
|
51
|
+
_e.label = 1;
|
|
52
52
|
case 1:
|
|
53
|
-
|
|
53
|
+
_e.trys.push([1, 3, , 6]);
|
|
54
54
|
return [4 /*yield*/, what()];
|
|
55
|
-
case 2: return [2 /*return*/,
|
|
55
|
+
case 2: return [2 /*return*/, _e.sent()];
|
|
56
56
|
case 3:
|
|
57
|
-
err_1 =
|
|
58
|
-
if (!(((_a = err_1.message) === null || _a === void 0 ? void 0 : _a.startsWith("Error occurred while trying to proxy")) || ((_b = err_1.message) === null || _b === void 0 ? void 0 : _b.startsWith("Error occured while trying to proxy")) || ((_c = err_1.message) === null || _c === void 0 ? void 0 : _c.startsWith("Gateway Timeout")))) return [3 /*break*/, 5];
|
|
57
|
+
err_1 = _e.sent();
|
|
58
|
+
if (!(((_a = err_1.message) === null || _a === void 0 ? void 0 : _a.startsWith("Error occurred while trying to proxy")) || ((_b = err_1.message) === null || _b === void 0 ? void 0 : _b.startsWith("Error occured while trying to proxy")) || ((_c = err_1.message) === null || _c === void 0 ? void 0 : _c.includes("http proxy error")) || ((_d = err_1.message) === null || _d === void 0 ? void 0 : _d.startsWith("Gateway Timeout")))) return [3 /*break*/, 5];
|
|
59
59
|
return [4 /*yield*/, new Promise(function (res, req) {
|
|
60
60
|
setTimeout(function () {
|
|
61
61
|
res({});
|
|
62
62
|
}, 250);
|
|
63
63
|
})];
|
|
64
64
|
case 4:
|
|
65
|
-
|
|
65
|
+
_e.sent();
|
|
66
66
|
return [3 /*break*/, 0];
|
|
67
67
|
case 5: throw err_1;
|
|
68
68
|
case 6: return [3 /*break*/, 0];
|
|
@@ -4,7 +4,6 @@ exports.ArrayEntityDataProvider = void 0;
|
|
|
4
4
|
var tslib_1 = require("tslib");
|
|
5
5
|
var filter_interfaces_1 = require("../filter/filter-interfaces");
|
|
6
6
|
var column_1 = require("../column");
|
|
7
|
-
var sort_1 = require("../sort");
|
|
8
7
|
var ArrayEntityDataProvider = /** @class */ (function () {
|
|
9
8
|
function ArrayEntityDataProvider(entity, rows) {
|
|
10
9
|
var e_1, _a;
|
|
@@ -220,34 +219,38 @@ var ArrayEntityDataProvider = /** @class */ (function () {
|
|
|
220
219
|
ArrayEntityDataProvider.prototype.insert = function (data) {
|
|
221
220
|
var _a;
|
|
222
221
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
223
|
-
var idf,
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
222
|
+
var idf, _b, _c, row, j;
|
|
223
|
+
var e_6, _d;
|
|
224
|
+
return tslib_1.__generator(this, function (_e) {
|
|
225
|
+
idf = this.entity.idMetadata.field;
|
|
226
|
+
if (!(idf instanceof column_1.CompoundIdField)) {
|
|
227
|
+
if (((_a = idf.options.valueConverter) === null || _a === void 0 ? void 0 : _a.fieldTypeInDb) === 'autoincrement') {
|
|
228
|
+
data[idf.key] = 1;
|
|
229
|
+
try {
|
|
230
|
+
for (_b = tslib_1.__values(this.rows), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
231
|
+
row = _c.value;
|
|
232
|
+
if (row[idf.key] >= data[idf.key])
|
|
233
|
+
data[idf.key] = row[idf.key] + 1;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
catch (e_6_1) { e_6 = { error: e_6_1 }; }
|
|
237
|
+
finally {
|
|
238
|
+
try {
|
|
239
|
+
if (_c && !_c.done && (_d = _b.return)) _d.call(_b);
|
|
240
|
+
}
|
|
241
|
+
finally { if (e_6) throw e_6.error; }
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
if (data[idf.key])
|
|
245
|
+
this.rows.forEach(function (i) {
|
|
246
|
+
if (data[idf.key] == i[idf.key])
|
|
247
|
+
throw Error("id already exists");
|
|
248
|
+
});
|
|
250
249
|
}
|
|
250
|
+
j = this.translateToJson(data);
|
|
251
|
+
this.verifyThatRowHasAllNotNullColumns(j);
|
|
252
|
+
this.rows.push(j);
|
|
253
|
+
return [2 /*return*/, Promise.resolve(this.translateFromJson(j))];
|
|
251
254
|
});
|
|
252
255
|
});
|
|
253
256
|
};
|
|
@@ -287,7 +290,7 @@ var FilterConsumerBridgeToObject = /** @class */ (function () {
|
|
|
287
290
|
throw new Error('Custom Filter should be translated before it gets here');
|
|
288
291
|
};
|
|
289
292
|
FilterConsumerBridgeToObject.prototype.or = function (orElements) {
|
|
290
|
-
var
|
|
293
|
+
var e_7, _a;
|
|
291
294
|
try {
|
|
292
295
|
for (var orElements_1 = tslib_1.__values(orElements), orElements_1_1 = orElements_1.next(); !orElements_1_1.done; orElements_1_1 = orElements_1.next()) {
|
|
293
296
|
var element = orElements_1_1.value;
|
|
@@ -298,12 +301,12 @@ var FilterConsumerBridgeToObject = /** @class */ (function () {
|
|
|
298
301
|
}
|
|
299
302
|
}
|
|
300
303
|
}
|
|
301
|
-
catch (
|
|
304
|
+
catch (e_7_1) { e_7 = { error: e_7_1 }; }
|
|
302
305
|
finally {
|
|
303
306
|
try {
|
|
304
307
|
if (orElements_1_1 && !orElements_1_1.done && (_a = orElements_1.return)) _a.call(orElements_1);
|
|
305
308
|
}
|
|
306
|
-
finally { if (
|
|
309
|
+
finally { if (e_7) throw e_7.error; }
|
|
307
310
|
}
|
|
308
311
|
this.ok = false;
|
|
309
312
|
};
|
|
@@ -316,7 +319,7 @@ var FilterConsumerBridgeToObject = /** @class */ (function () {
|
|
|
316
319
|
this.ok = false;
|
|
317
320
|
};
|
|
318
321
|
FilterConsumerBridgeToObject.prototype.isIn = function (col, val) {
|
|
319
|
-
var
|
|
322
|
+
var e_8, _a;
|
|
320
323
|
try {
|
|
321
324
|
for (var val_1 = tslib_1.__values(val), val_1_1 = val_1.next(); !val_1_1.done; val_1_1 = val_1.next()) {
|
|
322
325
|
var v = val_1_1.value;
|
|
@@ -325,12 +328,12 @@ var FilterConsumerBridgeToObject = /** @class */ (function () {
|
|
|
325
328
|
}
|
|
326
329
|
}
|
|
327
330
|
}
|
|
328
|
-
catch (
|
|
331
|
+
catch (e_8_1) { e_8 = { error: e_8_1 }; }
|
|
329
332
|
finally {
|
|
330
333
|
try {
|
|
331
334
|
if (val_1_1 && !val_1_1.done && (_a = val_1.return)) _a.call(val_1);
|
|
332
335
|
}
|
|
333
|
-
finally { if (
|
|
336
|
+
finally { if (e_8) throw e_8.error; }
|
|
334
337
|
}
|
|
335
338
|
this.ok = false;
|
|
336
339
|
};
|
package/src/entity.d.ts
CHANGED
|
@@ -29,7 +29,7 @@ export interface EntityOptions<entityType = any> {
|
|
|
29
29
|
apiPrefilter?: EntityFilter<entityType> | (() => EntityFilter<entityType> | Promise<EntityFilter<entityType>>);
|
|
30
30
|
/** A filter that will be used for all queries from this entity both from the API and from within the backend.
|
|
31
31
|
* @example
|
|
32
|
-
*
|
|
32
|
+
* backendPrefilter: { archive:false }
|
|
33
33
|
* @see [EntityFilter](http://remult.dev/docs/entityFilter.html)
|
|
34
34
|
*/
|
|
35
35
|
backendPrefilter?: EntityFilter<entityType> | (() => EntityFilter<entityType> | Promise<EntityFilter<entityType>>);
|
|
@@ -45,7 +45,7 @@ export interface EntityOptions<entityType = any> {
|
|
|
45
45
|
* If the `error` property of the entity's ref or any of it's fields will be set, the save will be aborted and an exception will be thrown.
|
|
46
46
|
* this is the place to run logic that we want to run in any case before an entity is saved.
|
|
47
47
|
* @example
|
|
48
|
-
*
|
|
48
|
+
* @Entity<Task>("tasks", {
|
|
49
49
|
* saving: async task => {
|
|
50
50
|
* task.lastUpdated = new Date()
|
|
51
51
|
* }
|
|
@@ -256,11 +256,11 @@ export declare function getValueList<T>(type: ClassType<T>): T[];
|
|
|
256
256
|
* FieldOptions can be set in two ways:
|
|
257
257
|
* @example
|
|
258
258
|
* // as an object
|
|
259
|
-
*
|
|
259
|
+
* @Fields.string({ includeInApi:false })
|
|
260
260
|
* title='';
|
|
261
261
|
* @example
|
|
262
262
|
* // as an arrow function that receives `remult` as a parameter
|
|
263
|
-
*
|
|
263
|
+
* @Fields.string((options,remult) => options.includeInApi = true)
|
|
264
264
|
* title='';
|
|
265
265
|
*/
|
|
266
266
|
export declare function Field<entityType = any, valueType = any>(valueType: () => ClassType<valueType>, ...options: (FieldOptions<entityType, valueType> | ((options: FieldOptions<entityType, valueType>, remult: Remult) => void))[]): (target: any, key: any, c?: any) => void;
|
|
@@ -289,13 +289,14 @@ export declare function BuildEntity<entityType>(c: ClassType<entityType>, key: s
|
|
|
289
289
|
* @Fields.boolean()
|
|
290
290
|
* completed = false;
|
|
291
291
|
* }
|
|
292
|
-
*
|
|
292
|
+
* @note
|
|
293
|
+
* EntityOptions can be set in two ways:
|
|
293
294
|
* @example
|
|
294
295
|
* // as an object
|
|
295
|
-
*
|
|
296
|
+
* @Entity("tasks",{ allowApiCrud:true })
|
|
296
297
|
* @example
|
|
297
298
|
* // as an arrow function that receives `remult` as a parameter
|
|
298
|
-
*
|
|
299
|
+
* @Entity("tasks", (options,remult) => options.allowApiCrud = true)
|
|
299
300
|
*/
|
|
300
301
|
export declare function Entity<entityType>(key: string, ...options: (EntityOptions<entityType> | ((options: EntityOptions<entityType>, remult: Remult) => void))[]): (target: any) => any;
|
|
301
302
|
export declare class EntityBase {
|
|
@@ -2467,11 +2467,11 @@ exports.getValueList = getValueList;
|
|
|
2467
2467
|
* FieldOptions can be set in two ways:
|
|
2468
2468
|
* @example
|
|
2469
2469
|
* // as an object
|
|
2470
|
-
*
|
|
2470
|
+
* @Fields.string({ includeInApi:false })
|
|
2471
2471
|
* title='';
|
|
2472
2472
|
* @example
|
|
2473
2473
|
* // as an arrow function that receives `remult` as a parameter
|
|
2474
|
-
*
|
|
2474
|
+
* @Fields.string((options,remult) => options.includeInApi = true)
|
|
2475
2475
|
* title='';
|
|
2476
2476
|
*/
|
|
2477
2477
|
function Field(valueType) {
|
|
@@ -2637,13 +2637,14 @@ exports.BuildEntity = BuildEntity;
|
|
|
2637
2637
|
* @Fields.boolean()
|
|
2638
2638
|
* completed = false;
|
|
2639
2639
|
* }
|
|
2640
|
-
*
|
|
2640
|
+
* @note
|
|
2641
|
+
* EntityOptions can be set in two ways:
|
|
2641
2642
|
* @example
|
|
2642
2643
|
* // as an object
|
|
2643
|
-
*
|
|
2644
|
+
* @Entity("tasks",{ allowApiCrud:true })
|
|
2644
2645
|
* @example
|
|
2645
2646
|
* // as an arrow function that receives `remult` as a parameter
|
|
2646
|
-
*
|
|
2647
|
+
* @Entity("tasks", (options,remult) => options.allowApiCrud = true)
|
|
2647
2648
|
*/
|
|
2648
2649
|
function Entity(key) {
|
|
2649
2650
|
var options = [];
|
package/src/remult3/remult3.d.ts
CHANGED
|
@@ -112,7 +112,12 @@ export declare type OmitEB<T> = Omit<T, keyof import('./RepositoryImplementation
|
|
|
112
112
|
export interface Repository<entityType> {
|
|
113
113
|
/** returns a result array based on the provided options */
|
|
114
114
|
find(options?: FindOptions<entityType>): Promise<entityType[]>;
|
|
115
|
-
/** returns the first item that matchers the `where` condition
|
|
115
|
+
/** returns the first item that matchers the `where` condition
|
|
116
|
+
* @example
|
|
117
|
+
* await taskRepo.findFirst({ completed:false })
|
|
118
|
+
* @example
|
|
119
|
+
* await taskRepo.findFirst({ completed:false },{ createIfNotFound: true })
|
|
120
|
+
* */
|
|
116
121
|
findFirst(where?: EntityFilter<entityType>, options?: FindFirstOptions<entityType>): Promise<entityType>;
|
|
117
122
|
/** returns the items that matches the idm the result is cached unless specified differently in the `options` parameter */
|
|
118
123
|
findId(id: entityType extends {
|
|
@@ -285,7 +290,7 @@ export interface QueryResult<entityType> {
|
|
|
285
290
|
[Symbol.asyncIterator](): {
|
|
286
291
|
next: () => Promise<IteratorResult<entityType, entityType>>;
|
|
287
292
|
};
|
|
288
|
-
/** returns the number of rows that match the query
|
|
293
|
+
/** returns the number of rows that match the query criteria */
|
|
289
294
|
count(): Promise<number>;
|
|
290
295
|
/** Returns a `Paginator` object that is used for efficient paging */
|
|
291
296
|
paginator(): Promise<Paginator<entityType>>;
|
|
@@ -300,7 +305,7 @@ export interface Paginator<entityType> {
|
|
|
300
305
|
items: entityType[];
|
|
301
306
|
/** True if next page exists */
|
|
302
307
|
hasNextPage: boolean;
|
|
303
|
-
/**
|
|
308
|
+
/** Gets the next page in the `query`'s result set */
|
|
304
309
|
nextPage(): Promise<Paginator<entityType>>;
|
|
305
310
|
/** the count of the total items in the `query`'s result */
|
|
306
311
|
count(): Promise<number>;
|