remult 0.14.21 → 0.14.24
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/esm/index.d.ts +1 -1
- package/esm/index.js +1 -1
- package/esm/postgres/schema-builder.js +1 -1
- package/esm/remult-express.d.ts +7 -1
- package/esm/remult-express.js +7 -2
- package/esm/remult-fastify.d.ts +3 -0
- package/esm/remult-fastify.js +57 -0
- package/esm/remult-knex/index.js +1 -1
- package/esm/remult-middleware.d.ts +7 -1
- package/esm/remult-middleware.js +6 -4
- package/esm/server/expressBridge.d.ts +17 -13
- package/esm/server/expressBridge.js +2 -6
- package/esm/src/backend-tests/test-http-server.backend-spec.js +32 -8
- package/esm/src/remult3/RepositoryImplementation.js +1 -1
- package/esm/src/server-action.js +2 -1
- package/esm/src/valueConverters.d.ts +12 -0
- package/esm/src/valueConverters.js +169 -0
- package/index.d.ts +1 -1
- package/index.js +1 -1
- package/package.json +21 -1
- package/postgres/schema-builder.js +1 -1
- package/remult-express.d.ts +7 -1
- package/remult-express.js +6 -1
- package/remult-fastify.d.ts +3 -0
- package/remult-fastify.js +66 -0
- package/remult-knex/index.js +1 -1
- package/remult-middleware.d.ts +7 -1
- package/remult-middleware.js +5 -3
- package/server/expressBridge.d.ts +17 -13
- package/server/expressBridge.js +4 -8
- package/src/backend-tests/test-http-server.backend-spec.js +69 -12
- package/src/remult3/RepositoryImplementation.js +1 -1
- package/src/server-action.js +4 -2
- package/src/valueConverters.d.ts +12 -0
- package/src/valueConverters.js +168 -0
package/esm/index.d.ts
CHANGED
|
@@ -19,4 +19,4 @@ export { Filter } from './src/filter/filter-interfaces';
|
|
|
19
19
|
export { FilterConsumerBridgeToSqlRequest } from './src/filter/filter-consumer-bridge-to-sql-request';
|
|
20
20
|
export { UrlBuilder } from './urlBuilder';
|
|
21
21
|
export { Validators } from './src/validators';
|
|
22
|
-
export { ValueConverters } from './valueConverters';
|
|
22
|
+
export { ValueConverters } from './src/valueConverters';
|
package/esm/index.js
CHANGED
|
@@ -18,4 +18,4 @@ export { Filter } from './src/filter/filter-interfaces';
|
|
|
18
18
|
export { FilterConsumerBridgeToSqlRequest } from './src/filter/filter-consumer-bridge-to-sql-request';
|
|
19
19
|
export { UrlBuilder } from './urlBuilder';
|
|
20
20
|
export { Validators } from './src/validators';
|
|
21
|
-
export { ValueConverters } from './valueConverters';
|
|
21
|
+
export { ValueConverters } from './src/valueConverters';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { allEntities } from '../src/context';
|
|
2
2
|
import { getDbNameProvider } from '../src/filter/filter-consumer-bridge-to-sql-request';
|
|
3
3
|
import { isAutoIncrement } from '../src/remult3';
|
|
4
|
-
import { ValueConverters } from '../valueConverters';
|
|
4
|
+
import { ValueConverters } from '../src/valueConverters';
|
|
5
5
|
export function postgresColumnSyntax(x, dbName) {
|
|
6
6
|
let result = dbName;
|
|
7
7
|
if (x.valueType == Number) {
|
package/esm/remult-express.d.ts
CHANGED
|
@@ -2,4 +2,10 @@ import { RemultMiddlewareOptions } from './server/expressBridge';
|
|
|
2
2
|
export declare function remultExpress(options?: RemultMiddlewareOptions & {
|
|
3
3
|
bodyParser?: boolean;
|
|
4
4
|
bodySizeLimit?: string;
|
|
5
|
-
}): import("
|
|
5
|
+
}): import("express-serve-static-core").Router & {
|
|
6
|
+
getRemult: (req: any) => Promise<import(".").Remult>;
|
|
7
|
+
openApiDoc: (options: {
|
|
8
|
+
title: string;
|
|
9
|
+
}) => any;
|
|
10
|
+
addArea: (x: any) => any;
|
|
11
|
+
};
|
package/esm/remult-express.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as express from 'express';
|
|
2
|
-
import {
|
|
2
|
+
import { buildRemultServer } from './server/expressBridge';
|
|
3
3
|
export function remultExpress(options) {
|
|
4
4
|
let app = express.Router();
|
|
5
5
|
if (!options) {
|
|
@@ -12,5 +12,10 @@ export function remultExpress(options) {
|
|
|
12
12
|
app.use(express.json({ limit: options.bodySizeLimit }));
|
|
13
13
|
app.use(express.urlencoded({ extended: true, limit: options.bodySizeLimit }));
|
|
14
14
|
}
|
|
15
|
-
|
|
15
|
+
const server = buildRemultServer(app, options);
|
|
16
|
+
return Object.assign(app, {
|
|
17
|
+
getRemult: (req) => server.getRemult(req),
|
|
18
|
+
openApiDoc: (options) => server.openApiDoc(options),
|
|
19
|
+
addArea: x => server.addArea(x)
|
|
20
|
+
});
|
|
16
21
|
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { buildRemultServer } from './server/expressBridge';
|
|
2
|
+
export function remultFastify(options) {
|
|
3
|
+
function fastifyHandler(handler) {
|
|
4
|
+
const response = (req, res) => {
|
|
5
|
+
const myRes = {
|
|
6
|
+
status(statusCode) {
|
|
7
|
+
res.status(statusCode);
|
|
8
|
+
return myRes;
|
|
9
|
+
},
|
|
10
|
+
end() {
|
|
11
|
+
res.send();
|
|
12
|
+
},
|
|
13
|
+
json(data) {
|
|
14
|
+
res.send(data);
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
handler(req, myRes, () => { });
|
|
18
|
+
};
|
|
19
|
+
return response;
|
|
20
|
+
}
|
|
21
|
+
let api;
|
|
22
|
+
const pluginFunction = async (instance, options) => {
|
|
23
|
+
//@ts-ignore
|
|
24
|
+
let fastifyRouter = {
|
|
25
|
+
route(path) {
|
|
26
|
+
let r = {
|
|
27
|
+
delete(handler) {
|
|
28
|
+
instance.delete(path, fastifyHandler(handler));
|
|
29
|
+
return r;
|
|
30
|
+
},
|
|
31
|
+
get(handler) {
|
|
32
|
+
instance.get(path, fastifyHandler(handler));
|
|
33
|
+
return r;
|
|
34
|
+
}, post(handler) {
|
|
35
|
+
instance.post(path, fastifyHandler(handler));
|
|
36
|
+
return r;
|
|
37
|
+
}, put(handler) {
|
|
38
|
+
instance.put(path, fastifyHandler(handler));
|
|
39
|
+
return r;
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
return r;
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
api = buildRemultServer(fastifyRouter, options);
|
|
46
|
+
};
|
|
47
|
+
const getApi = () => {
|
|
48
|
+
if (!api)
|
|
49
|
+
throw "Please call fastify's register before using this method";
|
|
50
|
+
return api;
|
|
51
|
+
};
|
|
52
|
+
return Object.assign(pluginFunction, {
|
|
53
|
+
addArea: x => getApi().addArea(x),
|
|
54
|
+
getRemult: x => getApi().getRemult(x),
|
|
55
|
+
openApiDoc: x => getApi().openApiDoc(x)
|
|
56
|
+
});
|
|
57
|
+
}
|
package/esm/remult-knex/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import { customDatabaseFilterToken, Filter } from "../src/filter/filter-interfac
|
|
|
3
3
|
import { getDbNameProvider } from "../src/filter/filter-consumer-bridge-to-sql-request";
|
|
4
4
|
import { allEntities, Remult } from "../src/context";
|
|
5
5
|
import { isAutoIncrement } from "../src/remult3";
|
|
6
|
-
import { ValueConverters } from "../valueConverters";
|
|
6
|
+
import { ValueConverters } from "../src/valueConverters";
|
|
7
7
|
import { CompoundIdField } from '../src/column';
|
|
8
8
|
export class KnexDataProvider {
|
|
9
9
|
constructor(knex) {
|
|
@@ -1,2 +1,8 @@
|
|
|
1
1
|
import { RemultMiddlewareOptions } from './server/expressBridge';
|
|
2
|
-
export declare function remultMiddleware(options?: RemultMiddlewareOptions):
|
|
2
|
+
export declare function remultMiddleware(options?: RemultMiddlewareOptions): ((req: any, res: any, next: any) => void) & {
|
|
3
|
+
getRemult: (req: any) => Promise<import(".").Remult>;
|
|
4
|
+
openApiDoc: (options: {
|
|
5
|
+
title: string;
|
|
6
|
+
}) => any;
|
|
7
|
+
addArea: (x: any) => any;
|
|
8
|
+
};
|
package/esm/remult-middleware.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { buildRemultServer } from './server/expressBridge';
|
|
2
2
|
export function remultMiddleware(options) {
|
|
3
3
|
const m = new middleware();
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
const server = buildRemultServer(m, options);
|
|
5
|
+
return Object.assign((req, res, next) => m.handleRequest(req, res, next), {
|
|
6
|
+
getRemult: (req) => server.getRemult(req),
|
|
7
|
+
openApiDoc: (options) => server.openApiDoc(options),
|
|
8
|
+
addArea: x => server.addArea(x)
|
|
6
9
|
});
|
|
7
|
-
return remultMiddlewareBase(app, options);
|
|
8
10
|
}
|
|
9
11
|
class middleware {
|
|
10
12
|
constructor() {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { queuedJobInfoResponse } from '../src/server-action';
|
|
2
2
|
import { DataProvider } from '../src/data-interfaces';
|
|
3
3
|
import { DataApi, DataApiRequest, DataApiResponse } from '../src/data-api';
|
|
4
|
-
import { AllowedForInstance, Remult } from '../src/context';
|
|
4
|
+
import { AllowedForInstance, Remult, UserInfo } from '../src/context';
|
|
5
5
|
import { ClassType } from '../classType';
|
|
6
6
|
import { Repository } from '../src/remult3';
|
|
7
7
|
import { IdEntity } from '../src/id-entity';
|
|
@@ -22,20 +22,34 @@ export declare type RemultMiddlewareOptions = {
|
|
|
22
22
|
bodyParser?: boolean;
|
|
23
23
|
rootPath?: string;
|
|
24
24
|
};
|
|
25
|
-
export declare function
|
|
26
|
-
export
|
|
25
|
+
export declare function buildRemultServer(app: GenericRouter, options: RemultMiddlewareOptions): RemultServer;
|
|
26
|
+
export declare type GenericRequestHandler = (req: GenericRequest, res: GenericResponse, next: VoidFunction) => void;
|
|
27
|
+
export interface RemultExpressBridge extends GenericRequestHandler, RemultServer {
|
|
28
|
+
}
|
|
29
|
+
export interface RemultServer {
|
|
27
30
|
getRemult(req: GenericRequest): Promise<Remult>;
|
|
28
31
|
openApiDoc(options: {
|
|
29
32
|
title: string;
|
|
30
33
|
}): any;
|
|
31
34
|
addArea(rootUrl: string): any;
|
|
32
35
|
}
|
|
36
|
+
export declare type GenericRouter = {
|
|
37
|
+
route(path: string): SpecificRoute;
|
|
38
|
+
};
|
|
39
|
+
export declare type SpecificRoute = {
|
|
40
|
+
get(handler: GenericRequestHandler): SpecificRoute;
|
|
41
|
+
put(handler: GenericRequestHandler): SpecificRoute;
|
|
42
|
+
post(handler: GenericRequestHandler): SpecificRoute;
|
|
43
|
+
delete(handler: GenericRequestHandler): SpecificRoute;
|
|
44
|
+
};
|
|
33
45
|
export interface GenericRequest {
|
|
34
46
|
url: string;
|
|
35
47
|
method?: any;
|
|
36
48
|
body?: any;
|
|
37
49
|
query?: any;
|
|
38
50
|
params?: any;
|
|
51
|
+
user?: UserInfo;
|
|
52
|
+
auth?: UserInfo;
|
|
39
53
|
}
|
|
40
54
|
export interface GenericResponse {
|
|
41
55
|
json(data: any): any;
|
|
@@ -43,16 +57,6 @@ export interface GenericResponse {
|
|
|
43
57
|
setStatus?(statusCode: number): GenericResponse;
|
|
44
58
|
end(): any;
|
|
45
59
|
}
|
|
46
|
-
export declare type GenericRouter = GenericRequestHandler & {
|
|
47
|
-
route(path: string): SpecificRoute;
|
|
48
|
-
};
|
|
49
|
-
export declare type SpecificRoute = {
|
|
50
|
-
get(handler: GenericRequestHandler): SpecificRoute;
|
|
51
|
-
put(handler: GenericRequestHandler): SpecificRoute;
|
|
52
|
-
post(handler: GenericRequestHandler): SpecificRoute;
|
|
53
|
-
delete(handler: GenericRequestHandler): SpecificRoute;
|
|
54
|
-
};
|
|
55
|
-
export declare type GenericRequestHandler = (req: GenericRequest, res: GenericResponse, next: VoidFunction) => void;
|
|
56
60
|
declare class ExpressBridge {
|
|
57
61
|
private app;
|
|
58
62
|
queue: inProcessQueueHandler;
|
|
@@ -8,7 +8,7 @@ import { allEntities, Remult } from '../src/context';
|
|
|
8
8
|
import { Entity, Fields, getEntityKey } from '../src/remult3';
|
|
9
9
|
import { JsonDataProvider } from '../src/data-providers/json-data-provider';
|
|
10
10
|
import { IdEntity } from '../src/id-entity';
|
|
11
|
-
export function
|
|
11
|
+
export function buildRemultServer(app, options) {
|
|
12
12
|
if (!options) {
|
|
13
13
|
options = {};
|
|
14
14
|
}
|
|
@@ -52,11 +52,7 @@ export function remultMiddlewareBase(app, options) {
|
|
|
52
52
|
registerActionsOnServer(apiArea, actions);
|
|
53
53
|
registerEntitiesOnServer(apiArea, options.entities);
|
|
54
54
|
}
|
|
55
|
-
return
|
|
56
|
-
getRemult: (req) => bridge.getRemult(req),
|
|
57
|
-
openApiDoc: (options) => bridge.openApiDoc(options),
|
|
58
|
-
addArea: x => bridge.addArea(x)
|
|
59
|
-
});
|
|
55
|
+
return bridge;
|
|
60
56
|
}
|
|
61
57
|
;
|
|
62
58
|
class ExpressBridge {
|
|
@@ -3,22 +3,41 @@ import axios from 'axios';
|
|
|
3
3
|
import { HttpProviderBridgeToRestDataProviderHttpProvider, Remult } from '../context';
|
|
4
4
|
import { Entity, Fields } from '../remult3';
|
|
5
5
|
import { Action, BackendMethod } from '../server-action';
|
|
6
|
-
Remult.apiBaseUrl = 'http://localhost:
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
Remult.apiBaseUrl = 'http://localhost:3003/api';
|
|
7
|
+
let path = Remult.apiBaseUrl + '/tasks';
|
|
8
|
+
const environments = [
|
|
9
|
+
["next", 3000],
|
|
10
|
+
["nest", 3001],
|
|
11
|
+
["koa", 3002],
|
|
12
|
+
["fastify", 3003],
|
|
13
|
+
["express", 3004],
|
|
14
|
+
["middleware", 3005],
|
|
15
|
+
];
|
|
16
|
+
function test(name, test) {
|
|
17
|
+
for (const [env, port] of environments) {
|
|
18
|
+
const theTest = async () => {
|
|
19
|
+
Remult.apiBaseUrl = `http://localhost:${port}/api`;
|
|
20
|
+
path = Remult.apiBaseUrl + '/tasks';
|
|
21
|
+
await test();
|
|
22
|
+
};
|
|
23
|
+
const testName = env + ` ${port}: ${name}`;
|
|
24
|
+
fit(testName, theTest);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
test("works", async () => {
|
|
9
28
|
const repo = await create3Tasks();
|
|
10
29
|
const tasks = await repo.find({ where: { completed: true } });
|
|
11
30
|
expect(tasks.length).toBe(1);
|
|
12
31
|
await repo.save({ ...tasks[0], completed: false });
|
|
13
32
|
expect(await repo.count({ completed: true })).toBe(0);
|
|
14
33
|
});
|
|
15
|
-
|
|
34
|
+
test("test multiple items", async () => {
|
|
16
35
|
const repo = await create3Tasks();
|
|
17
36
|
expect(await repo.count({
|
|
18
37
|
title: { "!=": ["a", "c"] }
|
|
19
38
|
})).toBe(1);
|
|
20
39
|
});
|
|
21
|
-
|
|
40
|
+
test("validation", async () => {
|
|
22
41
|
const r = await create3Tasks();
|
|
23
42
|
let err = undefined;
|
|
24
43
|
try {
|
|
@@ -35,7 +54,7 @@ fit("validation", async () => {
|
|
|
35
54
|
}
|
|
36
55
|
});
|
|
37
56
|
});
|
|
38
|
-
|
|
57
|
+
test("forbidden", async () => {
|
|
39
58
|
let err = undefined;
|
|
40
59
|
try {
|
|
41
60
|
await Task.testForbidden();
|
|
@@ -45,7 +64,7 @@ fit("forbidden", async () => {
|
|
|
45
64
|
}
|
|
46
65
|
expect(err.httpStatusCode).toEqual(403);
|
|
47
66
|
});
|
|
48
|
-
|
|
67
|
+
test("test http 404", async () => {
|
|
49
68
|
const repo = create3Tasks();
|
|
50
69
|
const task = await (await repo).findFirst();
|
|
51
70
|
let result = await axios.get(path + "/" + task.id);
|
|
@@ -60,13 +79,18 @@ fit("test http 404", async () => {
|
|
|
60
79
|
}
|
|
61
80
|
expect(error.response.status).toBe(404);
|
|
62
81
|
});
|
|
63
|
-
|
|
82
|
+
test("test http 201", async () => {
|
|
64
83
|
let result = await axios.post(path, { title: "z", id: "" });
|
|
65
84
|
expect(result.data.title).toBe("z");
|
|
66
85
|
expect(result.status).toBe(201);
|
|
67
86
|
result = await axios.delete(path + "/" + result.data.id);
|
|
68
87
|
expect(result.status).toBe(204);
|
|
69
88
|
});
|
|
89
|
+
test("test regular api call", async () => {
|
|
90
|
+
await create3Tasks();
|
|
91
|
+
let result = await axios.get(Remult.apiBaseUrl + "/test");
|
|
92
|
+
expect(result.data.result).toBe(3);
|
|
93
|
+
});
|
|
70
94
|
let Task = class Task {
|
|
71
95
|
constructor() {
|
|
72
96
|
this.title = '';
|
|
@@ -3,7 +3,7 @@ import { allEntities, Remult, isBackend, queryConfig as queryConfig, setControll
|
|
|
3
3
|
import { entityFilterToJson, Filter } from "../filter/filter-interfaces";
|
|
4
4
|
import { Sort } from "../sort";
|
|
5
5
|
import { v4 as uuid } from 'uuid';
|
|
6
|
-
import { ValueConverters } from "
|
|
6
|
+
import { ValueConverters } from "../valueConverters";
|
|
7
7
|
import { filterHelper } from "../filter/filter-interfaces";
|
|
8
8
|
import { assign } from "../../assign";
|
|
9
9
|
let classValidatorValidate = undefined;
|
package/esm/src/server-action.js
CHANGED
|
@@ -46,7 +46,7 @@ export class Action {
|
|
|
46
46
|
res.success(r);
|
|
47
47
|
}
|
|
48
48
|
catch (err) {
|
|
49
|
-
if (err
|
|
49
|
+
if (err.isForbiddenError) // got a problem in next with instance of ForbiddenError - so replaced it with this bool
|
|
50
50
|
res.forbidden();
|
|
51
51
|
else
|
|
52
52
|
res.error(err);
|
|
@@ -58,6 +58,7 @@ Action.apiUrlForJobStatus = 'jobStatusInQueue';
|
|
|
58
58
|
class ForbiddenError extends Error {
|
|
59
59
|
constructor() {
|
|
60
60
|
super("Forbidden");
|
|
61
|
+
this.isForbiddenError = true;
|
|
61
62
|
}
|
|
62
63
|
}
|
|
63
64
|
export class myServerAction extends Action {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ValueConverter } from "./column-interfaces";
|
|
2
|
+
export declare class ValueConverters {
|
|
3
|
+
static readonly Date: ValueConverter<Date>;
|
|
4
|
+
static readonly DateOnly: ValueConverter<Date>;
|
|
5
|
+
static readonly DateOnlyString: ValueConverter<Date>;
|
|
6
|
+
static readonly Boolean: ValueConverter<Boolean>;
|
|
7
|
+
static readonly Number: ValueConverter<number>;
|
|
8
|
+
static readonly Integer: ValueConverter<number>;
|
|
9
|
+
static readonly Default: ValueConverter<any>;
|
|
10
|
+
static readonly JsonString: ValueConverter<any>;
|
|
11
|
+
static readonly JsonValue: ValueConverter<any>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { InputTypes } from "../inputTypes";
|
|
2
|
+
export class ValueConverters {
|
|
3
|
+
}
|
|
4
|
+
ValueConverters.Date = {
|
|
5
|
+
toJson: (val) => {
|
|
6
|
+
if (!val)
|
|
7
|
+
return '';
|
|
8
|
+
if (typeof (val) === "string")
|
|
9
|
+
val = new Date(val);
|
|
10
|
+
if (val instanceof Date) {
|
|
11
|
+
return val.toISOString();
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
console.log("ToJsonError", val);
|
|
15
|
+
throw new Error("Expected date but got val");
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
fromJson: (val) => {
|
|
19
|
+
if (val == undefined)
|
|
20
|
+
return undefined;
|
|
21
|
+
if (val == '')
|
|
22
|
+
return undefined;
|
|
23
|
+
if (val.startsWith('0000-00-00'))
|
|
24
|
+
return undefined;
|
|
25
|
+
return new Date(Date.parse(val));
|
|
26
|
+
},
|
|
27
|
+
toDb: x => x,
|
|
28
|
+
fromDb: x => x,
|
|
29
|
+
fromInput: x => ValueConverters.Date.fromJson(x),
|
|
30
|
+
toInput: x => ValueConverters.Date.toJson(x),
|
|
31
|
+
displayValue: (val) => {
|
|
32
|
+
if (!val)
|
|
33
|
+
return '';
|
|
34
|
+
return val.toLocaleString();
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
ValueConverters.DateOnly = {
|
|
38
|
+
fromInput: x => ValueConverters.DateOnly.fromJson(x),
|
|
39
|
+
toInput: x => ValueConverters.DateOnly.toJson(x),
|
|
40
|
+
toJson: (val) => {
|
|
41
|
+
var d = val;
|
|
42
|
+
if (typeof d === "string" || typeof (d) === "number")
|
|
43
|
+
d = new Date(d);
|
|
44
|
+
if (!d || d == null)
|
|
45
|
+
return null;
|
|
46
|
+
if (d.getHours() == 0)
|
|
47
|
+
return new Date(d.valueOf() - d.getTimezoneOffset() * 60000).toISOString().substring(0, 10);
|
|
48
|
+
else
|
|
49
|
+
return d.toISOString().substring(0, 10);
|
|
50
|
+
},
|
|
51
|
+
fromJson: (value) => {
|
|
52
|
+
if (!value || value == '' || value == '0000-00-00')
|
|
53
|
+
return null;
|
|
54
|
+
let d = new Date(Date.parse(value));
|
|
55
|
+
d.setMinutes(d.getMinutes() + d.getTimezoneOffset());
|
|
56
|
+
return d;
|
|
57
|
+
},
|
|
58
|
+
inputType: InputTypes.date,
|
|
59
|
+
toDb: (val) => {
|
|
60
|
+
if (!val)
|
|
61
|
+
return null;
|
|
62
|
+
return ValueConverters.DateOnly.fromJson(ValueConverters.DateOnly.toJson(val));
|
|
63
|
+
} //when using date storage, the database expects and returns a date local and every where else we reflect on date iso
|
|
64
|
+
,
|
|
65
|
+
fromDb: (val) => {
|
|
66
|
+
var d = val;
|
|
67
|
+
if (!d)
|
|
68
|
+
return null;
|
|
69
|
+
return val;
|
|
70
|
+
},
|
|
71
|
+
fieldTypeInDb: 'date',
|
|
72
|
+
displayValue: (value) => {
|
|
73
|
+
if (!value)
|
|
74
|
+
return '';
|
|
75
|
+
return value.toLocaleDateString(undefined);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
ValueConverters.DateOnlyString = {
|
|
79
|
+
...ValueConverters.DateOnly,
|
|
80
|
+
toDb: (d) => {
|
|
81
|
+
let val = ValueConverters.DateOnly.toJson(d);
|
|
82
|
+
if (!val)
|
|
83
|
+
return undefined;
|
|
84
|
+
return val.replace(/-/g, '');
|
|
85
|
+
},
|
|
86
|
+
fromDb: (val) => {
|
|
87
|
+
if (val === null)
|
|
88
|
+
return null;
|
|
89
|
+
if (!val)
|
|
90
|
+
return undefined;
|
|
91
|
+
return new Date(val.substring(0, 4) + '-' + val.substring(4, 6) + '-' + val.substring(6, 8));
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
ValueConverters.Boolean = {
|
|
95
|
+
toDb: (val) => val,
|
|
96
|
+
inputType: InputTypes.checkbox,
|
|
97
|
+
fromDb: (value) => {
|
|
98
|
+
return ValueConverters.Boolean.fromJson(value);
|
|
99
|
+
},
|
|
100
|
+
fromJson: value => {
|
|
101
|
+
if (typeof value === "boolean")
|
|
102
|
+
return value;
|
|
103
|
+
if (value !== undefined && value !== null) {
|
|
104
|
+
return value.toString().trim().toLowerCase() == 'true';
|
|
105
|
+
}
|
|
106
|
+
return value;
|
|
107
|
+
},
|
|
108
|
+
toJson: x => x,
|
|
109
|
+
fromInput: x => ValueConverters.Boolean.fromJson(x),
|
|
110
|
+
toInput: x => ValueConverters.Boolean.toJson(x)
|
|
111
|
+
};
|
|
112
|
+
ValueConverters.Number = {
|
|
113
|
+
fromDb: value => {
|
|
114
|
+
if (value === null)
|
|
115
|
+
return null;
|
|
116
|
+
if (value !== undefined)
|
|
117
|
+
return +value;
|
|
118
|
+
return undefined;
|
|
119
|
+
},
|
|
120
|
+
toDb: value => value,
|
|
121
|
+
fromJson: value => ValueConverters.Number.fromDb(value),
|
|
122
|
+
toJson: value => ValueConverters.Number.toDb(value),
|
|
123
|
+
fromInput: (x, type) => {
|
|
124
|
+
let r = +x;
|
|
125
|
+
if (!x)
|
|
126
|
+
return undefined;
|
|
127
|
+
return r;
|
|
128
|
+
},
|
|
129
|
+
toInput: (x, type) => {
|
|
130
|
+
return x?.toString();
|
|
131
|
+
},
|
|
132
|
+
inputType: InputTypes.number
|
|
133
|
+
};
|
|
134
|
+
ValueConverters.Integer = {
|
|
135
|
+
...ValueConverters.Number,
|
|
136
|
+
toJson: value => {
|
|
137
|
+
let val = ValueConverters.Number.toDb(value);
|
|
138
|
+
if (!val)
|
|
139
|
+
return val;
|
|
140
|
+
return +(+val).toFixed(0);
|
|
141
|
+
},
|
|
142
|
+
toDb: value => ValueConverters.Integer.toJson(value),
|
|
143
|
+
fieldTypeInDb: 'integer'
|
|
144
|
+
};
|
|
145
|
+
ValueConverters.Default = {
|
|
146
|
+
fromJson: x => x,
|
|
147
|
+
toJson: x => x,
|
|
148
|
+
fromDb: x => ValueConverters.JsonString.fromDb(x),
|
|
149
|
+
toDb: x => ValueConverters.JsonString.toDb(x),
|
|
150
|
+
fromInput: x => ValueConverters.Default.fromJson(x),
|
|
151
|
+
toInput: x => ValueConverters.Default.toJson(x)
|
|
152
|
+
};
|
|
153
|
+
ValueConverters.JsonString = {
|
|
154
|
+
fromJson: x => x,
|
|
155
|
+
toJson: x => x,
|
|
156
|
+
fromDb: x => x == null ? null : x ? JSON.parse(ValueConverters.JsonString.fromJson(x)) : undefined,
|
|
157
|
+
toDb: x => x !== undefined ? x === null ? null : JSON.stringify(ValueConverters.JsonString.toJson(x)) : undefined,
|
|
158
|
+
fromInput: x => ValueConverters.JsonString.fromJson(x),
|
|
159
|
+
toInput: x => ValueConverters.JsonString.toJson(x)
|
|
160
|
+
};
|
|
161
|
+
ValueConverters.JsonValue = {
|
|
162
|
+
fromJson: x => x,
|
|
163
|
+
toJson: x => x,
|
|
164
|
+
fromDb: x => x,
|
|
165
|
+
toDb: x => x,
|
|
166
|
+
fromInput: x => ValueConverters.JsonString.fromJson(x),
|
|
167
|
+
toInput: x => ValueConverters.JsonString.toJson(x),
|
|
168
|
+
fieldTypeInDb: 'json'
|
|
169
|
+
};
|
package/index.d.ts
CHANGED
|
@@ -19,4 +19,4 @@ export { Filter } from './src/filter/filter-interfaces';
|
|
|
19
19
|
export { FilterConsumerBridgeToSqlRequest } from './src/filter/filter-consumer-bridge-to-sql-request';
|
|
20
20
|
export { UrlBuilder } from './urlBuilder';
|
|
21
21
|
export { Validators } from './src/validators';
|
|
22
|
-
export { ValueConverters } from './valueConverters';
|
|
22
|
+
export { ValueConverters } from './src/valueConverters';
|
package/index.js
CHANGED
|
@@ -55,5 +55,5 @@ var urlBuilder_1 = require("./urlBuilder");
|
|
|
55
55
|
Object.defineProperty(exports, "UrlBuilder", { enumerable: true, get: function () { return urlBuilder_1.UrlBuilder; } });
|
|
56
56
|
var validators_1 = require("./src/validators");
|
|
57
57
|
Object.defineProperty(exports, "Validators", { enumerable: true, get: function () { return validators_1.Validators; } });
|
|
58
|
-
var valueConverters_1 = require("./valueConverters");
|
|
58
|
+
var valueConverters_1 = require("./src/valueConverters");
|
|
59
59
|
Object.defineProperty(exports, "ValueConverters", { enumerable: true, get: function () { return valueConverters_1.ValueConverters; } });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "remult",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.24",
|
|
4
4
|
"description": "A CRUD framework for full-stack TypeScript",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -32,9 +32,29 @@
|
|
|
32
32
|
"require": "./remult-middleware.js",
|
|
33
33
|
"import": "./esm/remult-middleware.js"
|
|
34
34
|
},
|
|
35
|
+
"./remult-fastify": {
|
|
36
|
+
"require": "./remult-fastify.js",
|
|
37
|
+
"import": "./esm/remult-fastify.js"
|
|
38
|
+
},
|
|
39
|
+
"./postgres": {
|
|
40
|
+
"require": "./postgres/index.js",
|
|
41
|
+
"import": "./esm/postgres/index.js"
|
|
42
|
+
},
|
|
35
43
|
"./postgres/schema-builder": {
|
|
36
44
|
"require": "./postgres/schema-builder.js",
|
|
37
45
|
"import": "./esm/postgres/schema-builder.js"
|
|
46
|
+
},
|
|
47
|
+
"./remult-knex": {
|
|
48
|
+
"require": "./remult-knex/index.js",
|
|
49
|
+
"import": "./esm/remult-knex/index.js"
|
|
50
|
+
},
|
|
51
|
+
"./remult-mongo": {
|
|
52
|
+
"require": "./remult-mongo.js",
|
|
53
|
+
"import": "./esm/remult-mongo.js"
|
|
54
|
+
},
|
|
55
|
+
"./graphql": {
|
|
56
|
+
"require": "./graphql.js",
|
|
57
|
+
"import": "./esm/graphql.js"
|
|
38
58
|
}
|
|
39
59
|
}
|
|
40
60
|
}
|
|
@@ -5,7 +5,7 @@ var tslib_1 = require("tslib");
|
|
|
5
5
|
var context_1 = require("../src/context");
|
|
6
6
|
var filter_consumer_bridge_to_sql_request_1 = require("../src/filter/filter-consumer-bridge-to-sql-request");
|
|
7
7
|
var remult3_1 = require("../src/remult3");
|
|
8
|
-
var valueConverters_1 = require("../valueConverters");
|
|
8
|
+
var valueConverters_1 = require("../src/valueConverters");
|
|
9
9
|
function postgresColumnSyntax(x, dbName) {
|
|
10
10
|
var result = dbName;
|
|
11
11
|
if (x.valueType == Number) {
|
package/remult-express.d.ts
CHANGED
|
@@ -2,4 +2,10 @@ import { RemultMiddlewareOptions } from './server/expressBridge';
|
|
|
2
2
|
export declare function remultExpress(options?: RemultMiddlewareOptions & {
|
|
3
3
|
bodyParser?: boolean;
|
|
4
4
|
bodySizeLimit?: string;
|
|
5
|
-
}): import("
|
|
5
|
+
}): import("express-serve-static-core").Router & {
|
|
6
|
+
getRemult: (req: any) => Promise<import(".").Remult>;
|
|
7
|
+
openApiDoc: (options: {
|
|
8
|
+
title: string;
|
|
9
|
+
}) => any;
|
|
10
|
+
addArea: (x: any) => any;
|
|
11
|
+
};
|
package/remult-express.js
CHANGED
|
@@ -15,6 +15,11 @@ function remultExpress(options) {
|
|
|
15
15
|
app.use(express.json({ limit: options.bodySizeLimit }));
|
|
16
16
|
app.use(express.urlencoded({ extended: true, limit: options.bodySizeLimit }));
|
|
17
17
|
}
|
|
18
|
-
|
|
18
|
+
var server = expressBridge_1.buildRemultServer(app, options);
|
|
19
|
+
return Object.assign(app, {
|
|
20
|
+
getRemult: function (req) { return server.getRemult(req); },
|
|
21
|
+
openApiDoc: function (options) { return server.openApiDoc(options); },
|
|
22
|
+
addArea: function (x) { return server.addArea(x); }
|
|
23
|
+
});
|
|
19
24
|
}
|
|
20
25
|
exports.remultExpress = remultExpress;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.remultFastify = void 0;
|
|
4
|
+
var tslib_1 = require("tslib");
|
|
5
|
+
var expressBridge_1 = require("./server/expressBridge");
|
|
6
|
+
function remultFastify(options) {
|
|
7
|
+
var _this = this;
|
|
8
|
+
function fastifyHandler(handler) {
|
|
9
|
+
var response = function (req, res) {
|
|
10
|
+
var myRes = {
|
|
11
|
+
status: function (statusCode) {
|
|
12
|
+
res.status(statusCode);
|
|
13
|
+
return myRes;
|
|
14
|
+
},
|
|
15
|
+
end: function () {
|
|
16
|
+
res.send();
|
|
17
|
+
},
|
|
18
|
+
json: function (data) {
|
|
19
|
+
res.send(data);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
handler(req, myRes, function () { });
|
|
23
|
+
};
|
|
24
|
+
return response;
|
|
25
|
+
}
|
|
26
|
+
var api;
|
|
27
|
+
var pluginFunction = function (instance, options) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
28
|
+
var fastifyRouter;
|
|
29
|
+
return tslib_1.__generator(this, function (_a) {
|
|
30
|
+
fastifyRouter = {
|
|
31
|
+
route: function (path) {
|
|
32
|
+
var r = {
|
|
33
|
+
delete: function (handler) {
|
|
34
|
+
instance.delete(path, fastifyHandler(handler));
|
|
35
|
+
return r;
|
|
36
|
+
},
|
|
37
|
+
get: function (handler) {
|
|
38
|
+
instance.get(path, fastifyHandler(handler));
|
|
39
|
+
return r;
|
|
40
|
+
}, post: function (handler) {
|
|
41
|
+
instance.post(path, fastifyHandler(handler));
|
|
42
|
+
return r;
|
|
43
|
+
}, put: function (handler) {
|
|
44
|
+
instance.put(path, fastifyHandler(handler));
|
|
45
|
+
return r;
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
return r;
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
api = expressBridge_1.buildRemultServer(fastifyRouter, options);
|
|
52
|
+
return [2 /*return*/];
|
|
53
|
+
});
|
|
54
|
+
}); };
|
|
55
|
+
var getApi = function () {
|
|
56
|
+
if (!api)
|
|
57
|
+
throw "Please call fastify's register before using this method";
|
|
58
|
+
return api;
|
|
59
|
+
};
|
|
60
|
+
return Object.assign(pluginFunction, {
|
|
61
|
+
addArea: function (x) { return getApi().addArea(x); },
|
|
62
|
+
getRemult: function (x) { return getApi().getRemult(x); },
|
|
63
|
+
openApiDoc: function (x) { return getApi().openApiDoc(x); }
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
exports.remultFastify = remultFastify;
|
package/remult-knex/index.js
CHANGED
|
@@ -7,7 +7,7 @@ var filter_interfaces_1 = require("../src/filter/filter-interfaces");
|
|
|
7
7
|
var filter_consumer_bridge_to_sql_request_1 = require("../src/filter/filter-consumer-bridge-to-sql-request");
|
|
8
8
|
var context_1 = require("../src/context");
|
|
9
9
|
var remult3_1 = require("../src/remult3");
|
|
10
|
-
var valueConverters_1 = require("../valueConverters");
|
|
10
|
+
var valueConverters_1 = require("../src/valueConverters");
|
|
11
11
|
var column_1 = require("../src/column");
|
|
12
12
|
var KnexDataProvider = /** @class */ (function () {
|
|
13
13
|
function KnexDataProvider(knex) {
|
package/remult-middleware.d.ts
CHANGED
|
@@ -1,2 +1,8 @@
|
|
|
1
1
|
import { RemultMiddlewareOptions } from './server/expressBridge';
|
|
2
|
-
export declare function remultMiddleware(options?: RemultMiddlewareOptions):
|
|
2
|
+
export declare function remultMiddleware(options?: RemultMiddlewareOptions): ((req: any, res: any, next: any) => void) & {
|
|
3
|
+
getRemult: (req: any) => Promise<import(".").Remult>;
|
|
4
|
+
openApiDoc: (options: {
|
|
5
|
+
title: string;
|
|
6
|
+
}) => any;
|
|
7
|
+
addArea: (x: any) => any;
|
|
8
|
+
};
|
package/remult-middleware.js
CHANGED
|
@@ -4,10 +4,12 @@ exports.remultMiddleware = void 0;
|
|
|
4
4
|
var expressBridge_1 = require("./server/expressBridge");
|
|
5
5
|
function remultMiddleware(options) {
|
|
6
6
|
var m = new middleware();
|
|
7
|
-
var
|
|
8
|
-
|
|
7
|
+
var server = expressBridge_1.buildRemultServer(m, options);
|
|
8
|
+
return Object.assign(function (req, res, next) { return m.handleRequest(req, res, next); }, {
|
|
9
|
+
getRemult: function (req) { return server.getRemult(req); },
|
|
10
|
+
openApiDoc: function (options) { return server.openApiDoc(options); },
|
|
11
|
+
addArea: function (x) { return server.addArea(x); }
|
|
9
12
|
});
|
|
10
|
-
return expressBridge_1.remultMiddlewareBase(app, options);
|
|
11
13
|
}
|
|
12
14
|
exports.remultMiddleware = remultMiddleware;
|
|
13
15
|
var middleware = /** @class */ (function () {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { queuedJobInfoResponse } from '../src/server-action';
|
|
2
2
|
import { DataProvider } from '../src/data-interfaces';
|
|
3
3
|
import { DataApi, DataApiRequest, DataApiResponse } from '../src/data-api';
|
|
4
|
-
import { AllowedForInstance, Remult } from '../src/context';
|
|
4
|
+
import { AllowedForInstance, Remult, UserInfo } from '../src/context';
|
|
5
5
|
import { ClassType } from '../classType';
|
|
6
6
|
import { Repository } from '../src/remult3';
|
|
7
7
|
import { IdEntity } from '../src/id-entity';
|
|
@@ -22,20 +22,34 @@ export declare type RemultMiddlewareOptions = {
|
|
|
22
22
|
bodyParser?: boolean;
|
|
23
23
|
rootPath?: string;
|
|
24
24
|
};
|
|
25
|
-
export declare function
|
|
26
|
-
export
|
|
25
|
+
export declare function buildRemultServer(app: GenericRouter, options: RemultMiddlewareOptions): RemultServer;
|
|
26
|
+
export declare type GenericRequestHandler = (req: GenericRequest, res: GenericResponse, next: VoidFunction) => void;
|
|
27
|
+
export interface RemultExpressBridge extends GenericRequestHandler, RemultServer {
|
|
28
|
+
}
|
|
29
|
+
export interface RemultServer {
|
|
27
30
|
getRemult(req: GenericRequest): Promise<Remult>;
|
|
28
31
|
openApiDoc(options: {
|
|
29
32
|
title: string;
|
|
30
33
|
}): any;
|
|
31
34
|
addArea(rootUrl: string): any;
|
|
32
35
|
}
|
|
36
|
+
export declare type GenericRouter = {
|
|
37
|
+
route(path: string): SpecificRoute;
|
|
38
|
+
};
|
|
39
|
+
export declare type SpecificRoute = {
|
|
40
|
+
get(handler: GenericRequestHandler): SpecificRoute;
|
|
41
|
+
put(handler: GenericRequestHandler): SpecificRoute;
|
|
42
|
+
post(handler: GenericRequestHandler): SpecificRoute;
|
|
43
|
+
delete(handler: GenericRequestHandler): SpecificRoute;
|
|
44
|
+
};
|
|
33
45
|
export interface GenericRequest {
|
|
34
46
|
url: string;
|
|
35
47
|
method?: any;
|
|
36
48
|
body?: any;
|
|
37
49
|
query?: any;
|
|
38
50
|
params?: any;
|
|
51
|
+
user?: UserInfo;
|
|
52
|
+
auth?: UserInfo;
|
|
39
53
|
}
|
|
40
54
|
export interface GenericResponse {
|
|
41
55
|
json(data: any): any;
|
|
@@ -43,16 +57,6 @@ export interface GenericResponse {
|
|
|
43
57
|
setStatus?(statusCode: number): GenericResponse;
|
|
44
58
|
end(): any;
|
|
45
59
|
}
|
|
46
|
-
export declare type GenericRouter = GenericRequestHandler & {
|
|
47
|
-
route(path: string): SpecificRoute;
|
|
48
|
-
};
|
|
49
|
-
export declare type SpecificRoute = {
|
|
50
|
-
get(handler: GenericRequestHandler): SpecificRoute;
|
|
51
|
-
put(handler: GenericRequestHandler): SpecificRoute;
|
|
52
|
-
post(handler: GenericRequestHandler): SpecificRoute;
|
|
53
|
-
delete(handler: GenericRequestHandler): SpecificRoute;
|
|
54
|
-
};
|
|
55
|
-
export declare type GenericRequestHandler = (req: GenericRequest, res: GenericResponse, next: VoidFunction) => void;
|
|
56
60
|
declare class ExpressBridge {
|
|
57
61
|
private app;
|
|
58
62
|
queue: inProcessQueueHandler;
|
package/server/expressBridge.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
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.buildRemultServer = void 0;
|
|
4
4
|
var tslib_1 = require("tslib");
|
|
5
5
|
var register_actions_on_server_1 = require("./register-actions-on-server");
|
|
6
6
|
var register_entities_on_server_1 = require("./register-entities-on-server");
|
|
@@ -11,7 +11,7 @@ var context_1 = require("../src/context");
|
|
|
11
11
|
var remult3_1 = require("../src/remult3");
|
|
12
12
|
var json_data_provider_1 = require("../src/data-providers/json-data-provider");
|
|
13
13
|
var id_entity_1 = require("../src/id-entity");
|
|
14
|
-
function
|
|
14
|
+
function buildRemultServer(app, options) {
|
|
15
15
|
var _this = this;
|
|
16
16
|
if (!options) {
|
|
17
17
|
options = {};
|
|
@@ -64,13 +64,9 @@ function remultMiddlewareBase(app, options) {
|
|
|
64
64
|
register_actions_on_server_1.registerActionsOnServer(apiArea, actions);
|
|
65
65
|
register_entities_on_server_1.registerEntitiesOnServer(apiArea, options.entities);
|
|
66
66
|
}
|
|
67
|
-
return
|
|
68
|
-
getRemult: function (req) { return bridge.getRemult(req); },
|
|
69
|
-
openApiDoc: function (options) { return bridge.openApiDoc(options); },
|
|
70
|
-
addArea: function (x) { return bridge.addArea(x); }
|
|
71
|
-
});
|
|
67
|
+
return bridge;
|
|
72
68
|
}
|
|
73
|
-
exports.
|
|
69
|
+
exports.buildRemultServer = buildRemultServer;
|
|
74
70
|
;
|
|
75
71
|
var ExpressBridge = /** @class */ (function () {
|
|
76
72
|
function ExpressBridge(app, queue, initRequest, dataProvider) {
|
|
@@ -6,9 +6,51 @@ var axios_1 = require("axios");
|
|
|
6
6
|
var context_1 = require("../context");
|
|
7
7
|
var remult3_1 = require("../remult3");
|
|
8
8
|
var server_action_1 = require("../server-action");
|
|
9
|
-
context_1.Remult.apiBaseUrl = 'http://localhost:
|
|
9
|
+
context_1.Remult.apiBaseUrl = 'http://localhost:3003/api';
|
|
10
10
|
var path = context_1.Remult.apiBaseUrl + '/tasks';
|
|
11
|
-
|
|
11
|
+
var environments = [
|
|
12
|
+
["next", 3000],
|
|
13
|
+
["nest", 3001],
|
|
14
|
+
["koa", 3002],
|
|
15
|
+
["fastify", 3003],
|
|
16
|
+
["express", 3004],
|
|
17
|
+
["middleware", 3005],
|
|
18
|
+
];
|
|
19
|
+
function test(name, test) {
|
|
20
|
+
var e_1, _a;
|
|
21
|
+
var _this = this;
|
|
22
|
+
var _loop_1 = function (env, port) {
|
|
23
|
+
var theTest = function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
24
|
+
return tslib_1.__generator(this, function (_a) {
|
|
25
|
+
switch (_a.label) {
|
|
26
|
+
case 0:
|
|
27
|
+
context_1.Remult.apiBaseUrl = "http://localhost:" + port + "/api";
|
|
28
|
+
path = context_1.Remult.apiBaseUrl + '/tasks';
|
|
29
|
+
return [4 /*yield*/, test()];
|
|
30
|
+
case 1:
|
|
31
|
+
_a.sent();
|
|
32
|
+
return [2 /*return*/];
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}); };
|
|
36
|
+
var testName = env + (" " + port + ": " + name);
|
|
37
|
+
fit(testName, theTest);
|
|
38
|
+
};
|
|
39
|
+
try {
|
|
40
|
+
for (var environments_1 = tslib_1.__values(environments), environments_1_1 = environments_1.next(); !environments_1_1.done; environments_1_1 = environments_1.next()) {
|
|
41
|
+
var _b = tslib_1.__read(environments_1_1.value, 2), env = _b[0], port = _b[1];
|
|
42
|
+
_loop_1(env, port);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
46
|
+
finally {
|
|
47
|
+
try {
|
|
48
|
+
if (environments_1_1 && !environments_1_1.done && (_a = environments_1.return)) _a.call(environments_1);
|
|
49
|
+
}
|
|
50
|
+
finally { if (e_1) throw e_1.error; }
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
test("works", function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
|
12
54
|
var repo, tasks, _a;
|
|
13
55
|
return tslib_1.__generator(this, function (_b) {
|
|
14
56
|
switch (_b.label) {
|
|
@@ -30,7 +72,7 @@ fit("works", function () { return tslib_1.__awaiter(void 0, void 0, void 0, func
|
|
|
30
72
|
}
|
|
31
73
|
});
|
|
32
74
|
}); });
|
|
33
|
-
|
|
75
|
+
test("test multiple items", function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
|
34
76
|
var repo, _a;
|
|
35
77
|
return tslib_1.__generator(this, function (_b) {
|
|
36
78
|
switch (_b.label) {
|
|
@@ -47,7 +89,7 @@ fit("test multiple items", function () { return tslib_1.__awaiter(void 0, void 0
|
|
|
47
89
|
}
|
|
48
90
|
});
|
|
49
91
|
}); });
|
|
50
|
-
|
|
92
|
+
test("validation", function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
|
51
93
|
var r, err, error_1;
|
|
52
94
|
return tslib_1.__generator(this, function (_a) {
|
|
53
95
|
switch (_a.label) {
|
|
@@ -78,7 +120,7 @@ fit("validation", function () { return tslib_1.__awaiter(void 0, void 0, void 0,
|
|
|
78
120
|
}
|
|
79
121
|
});
|
|
80
122
|
}); });
|
|
81
|
-
|
|
123
|
+
test("forbidden", function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
|
82
124
|
var err, error_2;
|
|
83
125
|
return tslib_1.__generator(this, function (_a) {
|
|
84
126
|
switch (_a.label) {
|
|
@@ -101,7 +143,7 @@ fit("forbidden", function () { return tslib_1.__awaiter(void 0, void 0, void 0,
|
|
|
101
143
|
}
|
|
102
144
|
});
|
|
103
145
|
}); });
|
|
104
|
-
|
|
146
|
+
test("test http 404", function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
|
105
147
|
var repo, task, result, error, err_1;
|
|
106
148
|
return tslib_1.__generator(this, function (_a) {
|
|
107
149
|
switch (_a.label) {
|
|
@@ -134,7 +176,7 @@ fit("test http 404", function () { return tslib_1.__awaiter(void 0, void 0, void
|
|
|
134
176
|
}
|
|
135
177
|
});
|
|
136
178
|
}); });
|
|
137
|
-
|
|
179
|
+
test("test http 201", function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
|
138
180
|
var result;
|
|
139
181
|
return tslib_1.__generator(this, function (_a) {
|
|
140
182
|
switch (_a.label) {
|
|
@@ -151,6 +193,21 @@ fit("test http 201", function () { return tslib_1.__awaiter(void 0, void 0, void
|
|
|
151
193
|
}
|
|
152
194
|
});
|
|
153
195
|
}); });
|
|
196
|
+
test("test regular api call", function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
|
197
|
+
var result;
|
|
198
|
+
return tslib_1.__generator(this, function (_a) {
|
|
199
|
+
switch (_a.label) {
|
|
200
|
+
case 0: return [4 /*yield*/, create3Tasks()];
|
|
201
|
+
case 1:
|
|
202
|
+
_a.sent();
|
|
203
|
+
return [4 /*yield*/, axios_1.default.get(context_1.Remult.apiBaseUrl + "/test")];
|
|
204
|
+
case 2:
|
|
205
|
+
result = _a.sent();
|
|
206
|
+
expect(result.data.result).toBe(3);
|
|
207
|
+
return [2 /*return*/];
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
}); });
|
|
154
211
|
var Task = /** @class */ (function () {
|
|
155
212
|
function Task() {
|
|
156
213
|
this.title = '';
|
|
@@ -188,8 +245,8 @@ var Task = /** @class */ (function () {
|
|
|
188
245
|
exports.Task = Task;
|
|
189
246
|
function create3Tasks() {
|
|
190
247
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
191
|
-
var remult, taskRepo, _a, _b, task,
|
|
192
|
-
var
|
|
248
|
+
var remult, taskRepo, _a, _b, task, e_2_1, _c, _d;
|
|
249
|
+
var e_2, _e;
|
|
193
250
|
return tslib_1.__generator(this, function (_f) {
|
|
194
251
|
switch (_f.label) {
|
|
195
252
|
case 0:
|
|
@@ -215,14 +272,14 @@ function create3Tasks() {
|
|
|
215
272
|
return [3 /*break*/, 3];
|
|
216
273
|
case 6: return [3 /*break*/, 9];
|
|
217
274
|
case 7:
|
|
218
|
-
|
|
219
|
-
|
|
275
|
+
e_2_1 = _f.sent();
|
|
276
|
+
e_2 = { error: e_2_1 };
|
|
220
277
|
return [3 /*break*/, 9];
|
|
221
278
|
case 8:
|
|
222
279
|
try {
|
|
223
280
|
if (_b && !_b.done && (_e = _a.return)) _e.call(_a);
|
|
224
281
|
}
|
|
225
|
-
finally { if (
|
|
282
|
+
finally { if (e_2) throw e_2.error; }
|
|
226
283
|
return [7 /*endfinally*/];
|
|
227
284
|
case 9:
|
|
228
285
|
_c = expect;
|
|
@@ -7,7 +7,7 @@ var context_1 = require("../context");
|
|
|
7
7
|
var filter_interfaces_1 = require("../filter/filter-interfaces");
|
|
8
8
|
var sort_1 = require("../sort");
|
|
9
9
|
var uuid_1 = require("uuid");
|
|
10
|
-
var valueConverters_1 = require("
|
|
10
|
+
var valueConverters_1 = require("../valueConverters");
|
|
11
11
|
var filter_interfaces_2 = require("../filter/filter-interfaces");
|
|
12
12
|
var assign_1 = require("../../assign");
|
|
13
13
|
var classValidatorValidate = undefined;
|
package/src/server-action.js
CHANGED
|
@@ -81,7 +81,7 @@ var Action = /** @class */ (function () {
|
|
|
81
81
|
return [3 /*break*/, 3];
|
|
82
82
|
case 2:
|
|
83
83
|
err_1 = _a.sent();
|
|
84
|
-
if (err_1
|
|
84
|
+
if (err_1.isForbiddenError) // got a problem in next with instance of ForbiddenError - so replaced it with this bool
|
|
85
85
|
res.forbidden();
|
|
86
86
|
else
|
|
87
87
|
res.error(err_1);
|
|
@@ -98,7 +98,9 @@ exports.Action = Action;
|
|
|
98
98
|
var ForbiddenError = /** @class */ (function (_super) {
|
|
99
99
|
tslib_1.__extends(ForbiddenError, _super);
|
|
100
100
|
function ForbiddenError() {
|
|
101
|
-
|
|
101
|
+
var _this = _super.call(this, "Forbidden") || this;
|
|
102
|
+
_this.isForbiddenError = true;
|
|
103
|
+
return _this;
|
|
102
104
|
}
|
|
103
105
|
return ForbiddenError;
|
|
104
106
|
}(Error));
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ValueConverter } from "./column-interfaces";
|
|
2
|
+
export declare class ValueConverters {
|
|
3
|
+
static readonly Date: ValueConverter<Date>;
|
|
4
|
+
static readonly DateOnly: ValueConverter<Date>;
|
|
5
|
+
static readonly DateOnlyString: ValueConverter<Date>;
|
|
6
|
+
static readonly Boolean: ValueConverter<Boolean>;
|
|
7
|
+
static readonly Number: ValueConverter<number>;
|
|
8
|
+
static readonly Integer: ValueConverter<number>;
|
|
9
|
+
static readonly Default: ValueConverter<any>;
|
|
10
|
+
static readonly JsonString: ValueConverter<any>;
|
|
11
|
+
static readonly JsonValue: ValueConverter<any>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ValueConverters = void 0;
|
|
4
|
+
var tslib_1 = require("tslib");
|
|
5
|
+
var inputTypes_1 = require("../inputTypes");
|
|
6
|
+
var ValueConverters = /** @class */ (function () {
|
|
7
|
+
function ValueConverters() {
|
|
8
|
+
}
|
|
9
|
+
ValueConverters.Date = {
|
|
10
|
+
toJson: function (val) {
|
|
11
|
+
if (!val)
|
|
12
|
+
return '';
|
|
13
|
+
if (typeof (val) === "string")
|
|
14
|
+
val = new Date(val);
|
|
15
|
+
if (val instanceof Date) {
|
|
16
|
+
return val.toISOString();
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
console.log("ToJsonError", val);
|
|
20
|
+
throw new Error("Expected date but got val");
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
fromJson: function (val) {
|
|
24
|
+
if (val == undefined)
|
|
25
|
+
return undefined;
|
|
26
|
+
if (val == '')
|
|
27
|
+
return undefined;
|
|
28
|
+
if (val.startsWith('0000-00-00'))
|
|
29
|
+
return undefined;
|
|
30
|
+
return new Date(Date.parse(val));
|
|
31
|
+
},
|
|
32
|
+
toDb: function (x) { return x; },
|
|
33
|
+
fromDb: function (x) { return x; },
|
|
34
|
+
fromInput: function (x) { return ValueConverters.Date.fromJson(x); },
|
|
35
|
+
toInput: function (x) { return ValueConverters.Date.toJson(x); },
|
|
36
|
+
displayValue: function (val) {
|
|
37
|
+
if (!val)
|
|
38
|
+
return '';
|
|
39
|
+
return val.toLocaleString();
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
ValueConverters.DateOnly = {
|
|
43
|
+
fromInput: function (x) { return ValueConverters.DateOnly.fromJson(x); },
|
|
44
|
+
toInput: function (x) { return ValueConverters.DateOnly.toJson(x); },
|
|
45
|
+
toJson: function (val) {
|
|
46
|
+
var d = val;
|
|
47
|
+
if (typeof d === "string" || typeof (d) === "number")
|
|
48
|
+
d = new Date(d);
|
|
49
|
+
if (!d || d == null)
|
|
50
|
+
return null;
|
|
51
|
+
if (d.getHours() == 0)
|
|
52
|
+
return new Date(d.valueOf() - d.getTimezoneOffset() * 60000).toISOString().substring(0, 10);
|
|
53
|
+
else
|
|
54
|
+
return d.toISOString().substring(0, 10);
|
|
55
|
+
},
|
|
56
|
+
fromJson: function (value) {
|
|
57
|
+
if (!value || value == '' || value == '0000-00-00')
|
|
58
|
+
return null;
|
|
59
|
+
var d = new Date(Date.parse(value));
|
|
60
|
+
d.setMinutes(d.getMinutes() + d.getTimezoneOffset());
|
|
61
|
+
return d;
|
|
62
|
+
},
|
|
63
|
+
inputType: inputTypes_1.InputTypes.date,
|
|
64
|
+
toDb: function (val) {
|
|
65
|
+
if (!val)
|
|
66
|
+
return null;
|
|
67
|
+
return ValueConverters.DateOnly.fromJson(ValueConverters.DateOnly.toJson(val));
|
|
68
|
+
} //when using date storage, the database expects and returns a date local and every where else we reflect on date iso
|
|
69
|
+
,
|
|
70
|
+
fromDb: function (val) {
|
|
71
|
+
var d = val;
|
|
72
|
+
if (!d)
|
|
73
|
+
return null;
|
|
74
|
+
return val;
|
|
75
|
+
},
|
|
76
|
+
fieldTypeInDb: 'date',
|
|
77
|
+
displayValue: function (value) {
|
|
78
|
+
if (!value)
|
|
79
|
+
return '';
|
|
80
|
+
return value.toLocaleDateString(undefined);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
ValueConverters.DateOnlyString = tslib_1.__assign(tslib_1.__assign({}, ValueConverters.DateOnly), { toDb: function (d) {
|
|
84
|
+
var val = ValueConverters.DateOnly.toJson(d);
|
|
85
|
+
if (!val)
|
|
86
|
+
return undefined;
|
|
87
|
+
return val.replace(/-/g, '');
|
|
88
|
+
}, fromDb: function (val) {
|
|
89
|
+
if (val === null)
|
|
90
|
+
return null;
|
|
91
|
+
if (!val)
|
|
92
|
+
return undefined;
|
|
93
|
+
return new Date(val.substring(0, 4) + '-' + val.substring(4, 6) + '-' + val.substring(6, 8));
|
|
94
|
+
} });
|
|
95
|
+
ValueConverters.Boolean = {
|
|
96
|
+
toDb: function (val) { return val; },
|
|
97
|
+
inputType: inputTypes_1.InputTypes.checkbox,
|
|
98
|
+
fromDb: function (value) {
|
|
99
|
+
return ValueConverters.Boolean.fromJson(value);
|
|
100
|
+
},
|
|
101
|
+
fromJson: function (value) {
|
|
102
|
+
if (typeof value === "boolean")
|
|
103
|
+
return value;
|
|
104
|
+
if (value !== undefined && value !== null) {
|
|
105
|
+
return value.toString().trim().toLowerCase() == 'true';
|
|
106
|
+
}
|
|
107
|
+
return value;
|
|
108
|
+
},
|
|
109
|
+
toJson: function (x) { return x; },
|
|
110
|
+
fromInput: function (x) { return ValueConverters.Boolean.fromJson(x); },
|
|
111
|
+
toInput: function (x) { return ValueConverters.Boolean.toJson(x); }
|
|
112
|
+
};
|
|
113
|
+
ValueConverters.Number = {
|
|
114
|
+
fromDb: function (value) {
|
|
115
|
+
if (value === null)
|
|
116
|
+
return null;
|
|
117
|
+
if (value !== undefined)
|
|
118
|
+
return +value;
|
|
119
|
+
return undefined;
|
|
120
|
+
},
|
|
121
|
+
toDb: function (value) { return value; },
|
|
122
|
+
fromJson: function (value) { return ValueConverters.Number.fromDb(value); },
|
|
123
|
+
toJson: function (value) { return ValueConverters.Number.toDb(value); },
|
|
124
|
+
fromInput: function (x, type) {
|
|
125
|
+
var r = +x;
|
|
126
|
+
if (!x)
|
|
127
|
+
return undefined;
|
|
128
|
+
return r;
|
|
129
|
+
},
|
|
130
|
+
toInput: function (x, type) {
|
|
131
|
+
return x === null || x === void 0 ? void 0 : x.toString();
|
|
132
|
+
},
|
|
133
|
+
inputType: inputTypes_1.InputTypes.number
|
|
134
|
+
};
|
|
135
|
+
ValueConverters.Integer = tslib_1.__assign(tslib_1.__assign({}, ValueConverters.Number), { toJson: function (value) {
|
|
136
|
+
var val = ValueConverters.Number.toDb(value);
|
|
137
|
+
if (!val)
|
|
138
|
+
return val;
|
|
139
|
+
return +(+val).toFixed(0);
|
|
140
|
+
}, toDb: function (value) { return ValueConverters.Integer.toJson(value); }, fieldTypeInDb: 'integer' });
|
|
141
|
+
ValueConverters.Default = {
|
|
142
|
+
fromJson: function (x) { return x; },
|
|
143
|
+
toJson: function (x) { return x; },
|
|
144
|
+
fromDb: function (x) { return ValueConverters.JsonString.fromDb(x); },
|
|
145
|
+
toDb: function (x) { return ValueConverters.JsonString.toDb(x); },
|
|
146
|
+
fromInput: function (x) { return ValueConverters.Default.fromJson(x); },
|
|
147
|
+
toInput: function (x) { return ValueConverters.Default.toJson(x); }
|
|
148
|
+
};
|
|
149
|
+
ValueConverters.JsonString = {
|
|
150
|
+
fromJson: function (x) { return x; },
|
|
151
|
+
toJson: function (x) { return x; },
|
|
152
|
+
fromDb: function (x) { return x == null ? null : x ? JSON.parse(ValueConverters.JsonString.fromJson(x)) : undefined; },
|
|
153
|
+
toDb: function (x) { return x !== undefined ? x === null ? null : JSON.stringify(ValueConverters.JsonString.toJson(x)) : undefined; },
|
|
154
|
+
fromInput: function (x) { return ValueConverters.JsonString.fromJson(x); },
|
|
155
|
+
toInput: function (x) { return ValueConverters.JsonString.toJson(x); }
|
|
156
|
+
};
|
|
157
|
+
ValueConverters.JsonValue = {
|
|
158
|
+
fromJson: function (x) { return x; },
|
|
159
|
+
toJson: function (x) { return x; },
|
|
160
|
+
fromDb: function (x) { return x; },
|
|
161
|
+
toDb: function (x) { return x; },
|
|
162
|
+
fromInput: function (x) { return ValueConverters.JsonString.fromJson(x); },
|
|
163
|
+
toInput: function (x) { return ValueConverters.JsonString.toJson(x); },
|
|
164
|
+
fieldTypeInDb: 'json'
|
|
165
|
+
};
|
|
166
|
+
return ValueConverters;
|
|
167
|
+
}());
|
|
168
|
+
exports.ValueConverters = ValueConverters;
|