remult 0.19.2 → 0.20.0-exp.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/esm/graphql.d.ts +1 -1
- package/esm/remult-express.d.ts +1 -1
- package/esm/remult-express.js +3 -1
- package/esm/remult-fastify.d.ts +1 -1
- package/esm/remult-fastify.js +3 -1
- package/esm/remult-fresh.d.ts +3 -3
- package/esm/remult-fresh.js +4 -2
- package/esm/remult-next.d.ts +1 -1
- package/esm/remult-next.js +3 -1
- package/esm/remult-svletekit.d.ts +3 -0
- package/esm/remult-svletekit.js +83 -0
- package/esm/server/expressBridge.d.ts +13 -10
- package/esm/server/expressBridge.js +57 -52
- package/esm/server/index.d.ts +2 -2
- package/esm/server/index.js +2 -2
- package/esm/src/data-api.d.ts +2 -2
- package/esm/src/live-query/SubscriptionServer.js +3 -3
- package/esm/src/remult3/RepositoryImplementation.js +2 -5
- package/esm/src/shared-tests/db-tests.db-tests.js +8 -0
- package/esm/src/tests/testHelper.spec.js +2 -2
- package/esm/src/valueConverters.d.ts +1 -0
- package/esm/src/valueConverters.js +15 -0
- package/graphql.d.ts +1 -1
- package/package.json +9 -1
- package/remult-express.d.ts +1 -1
- package/remult-express.js +3 -1
- package/remult-fastify.d.ts +1 -1
- package/remult-fastify.js +3 -1
- package/remult-fresh.d.ts +3 -3
- package/remult-fresh.js +4 -2
- package/remult-next.d.ts +1 -1
- package/remult-next.js +3 -1
- package/remult-svletekit.d.ts +3 -0
- package/remult-svletekit.js +136 -0
- package/server/expressBridge.d.ts +13 -10
- package/server/expressBridge.js +145 -113
- package/server/index.d.ts +2 -2
- package/server/index.js +2 -2
- package/src/data-api.d.ts +2 -2
- package/src/live-query/SubscriptionServer.js +3 -3
- package/src/remult3/RepositoryImplementation.js +2 -5
- package/src/shared-tests/db-tests.db-tests.js +20 -0
- package/src/tests/testHelper.spec.js +8 -2
- package/src/valueConverters.d.ts +1 -0
- package/src/valueConverters.js +15 -0
package/esm/graphql.d.ts
CHANGED
package/esm/remult-express.d.ts
CHANGED
|
@@ -3,4 +3,4 @@ import { RemultServer, RemultServerOptions } from './server/expressBridge';
|
|
|
3
3
|
export declare function remultExpress(options?: RemultServerOptions<express.Request> & {
|
|
4
4
|
bodyParser?: boolean;
|
|
5
5
|
bodySizeLimit?: string;
|
|
6
|
-
}): express.RequestHandler & RemultServer
|
|
6
|
+
}): express.RequestHandler & RemultServer<express.Request>;
|
package/esm/remult-express.js
CHANGED
|
@@ -12,7 +12,9 @@ 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
|
-
const server = createRemultServer(options
|
|
15
|
+
const server = createRemultServer(options, {
|
|
16
|
+
buildGenericRequest: req => req
|
|
17
|
+
});
|
|
16
18
|
server.registerRouter(app);
|
|
17
19
|
return Object.assign(app, {
|
|
18
20
|
getRemult: (req) => server.getRemult(req),
|
package/esm/remult-fastify.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { FastifyPluginCallback, FastifyRequest } from 'fastify';
|
|
2
2
|
import { RemultServer, RemultServerOptions } from './server/expressBridge';
|
|
3
|
-
export declare function remultFastify(options: RemultServerOptions<FastifyRequest>): FastifyPluginCallback & RemultServer
|
|
3
|
+
export declare function remultFastify(options: RemultServerOptions<FastifyRequest>): FastifyPluginCallback & RemultServer<FastifyRequest>;
|
package/esm/remult-fastify.js
CHANGED
|
@@ -29,7 +29,9 @@ export function remultFastify(options) {
|
|
|
29
29
|
};
|
|
30
30
|
return response;
|
|
31
31
|
}
|
|
32
|
-
const api = createRemultServer(options
|
|
32
|
+
const api = createRemultServer(options, {
|
|
33
|
+
buildGenericRequest: req => req
|
|
34
|
+
});
|
|
33
35
|
const pluginFunction = async (instance, op) => {
|
|
34
36
|
//@ts-ignore
|
|
35
37
|
let fastifyRouter = {
|
package/esm/remult-fresh.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { RemultServerOptions
|
|
1
|
+
import { RemultServerOptions } from "./server/expressBridge";
|
|
2
2
|
import { Remult } from "./src/context";
|
|
3
|
-
export declare function remultFresh
|
|
3
|
+
export declare function remultFresh(options: RemultServerOptions<FreshRequest>, response: FreshResponse): RemultFresh;
|
|
4
4
|
export interface RemultFresh {
|
|
5
|
-
getRemult(req:
|
|
5
|
+
getRemult(req: FreshRequest): Promise<Remult>;
|
|
6
6
|
openApiDoc(options: {
|
|
7
7
|
title: string;
|
|
8
8
|
}): any;
|
package/esm/remult-fresh.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { createRemultServerCore } from "./server/expressBridge";
|
|
2
2
|
export function remultFresh(options, response) {
|
|
3
|
-
const server = createRemultServerCore(options
|
|
3
|
+
const server = createRemultServerCore(options, {
|
|
4
|
+
buildGenericRequest: r => r
|
|
5
|
+
});
|
|
4
6
|
return {
|
|
5
7
|
getRemult: r => server.getRemult(r),
|
|
6
8
|
openApiDoc: x => server.openApiDoc(x),
|
|
@@ -17,7 +19,7 @@ export function remultFresh(options, response) {
|
|
|
17
19
|
break;
|
|
18
20
|
}
|
|
19
21
|
let init = {};
|
|
20
|
-
const res = await server.handle(
|
|
22
|
+
const res = await server.handle(req);
|
|
21
23
|
if (res) {
|
|
22
24
|
init.status = res.statusCode;
|
|
23
25
|
if (res.data) {
|
package/esm/remult-next.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import type { GetServerSideProps, NextApiRequest, PreviewData, NextApiHandler } from "next";
|
|
3
3
|
import type { ParsedUrlQuery } from "querystring";
|
|
4
4
|
import { RemultServer, RemultServerOptions } from "./server";
|
|
5
|
-
export declare function remultNext(options?: RemultServerOptions<NextApiRequest>): RemultServer & NextApiHandler & {
|
|
5
|
+
export declare function remultNext(options?: RemultServerOptions<NextApiRequest>): RemultServer<NextApiRequest> & NextApiHandler & {
|
|
6
6
|
getServerSideProps<P extends {
|
|
7
7
|
[key: string]: any;
|
|
8
8
|
} = {
|
package/esm/remult-next.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { createRemultServer } from "./server";
|
|
2
2
|
export function remultNext(options) {
|
|
3
|
-
let result = createRemultServer(options
|
|
3
|
+
let result = createRemultServer(options, {
|
|
4
|
+
buildGenericRequest: req => req
|
|
5
|
+
});
|
|
4
6
|
return Object.assign((req, res) => result.handle(req, res), result, {
|
|
5
7
|
getRemult: (...args) => result.getRemult(...args),
|
|
6
8
|
handle: (...args) => result.handle(...args),
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { createRemultServer } from './server';
|
|
2
|
+
export function remultSveltekit(options) {
|
|
3
|
+
let result = createRemultServer(options, {
|
|
4
|
+
buildGenericRequest: event => ({
|
|
5
|
+
url: event.request.url,
|
|
6
|
+
method: event.request.method,
|
|
7
|
+
body: event.locals["_tempJson"],
|
|
8
|
+
on: (e, do1) => {
|
|
9
|
+
if (e === 'close') {
|
|
10
|
+
event.locals["_tempOnClose"] = do1;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
})
|
|
14
|
+
});
|
|
15
|
+
const handler = async ({ event, resolve }) => {
|
|
16
|
+
if (event.url.pathname.startsWith(options.rootPath)) {
|
|
17
|
+
let json = {};
|
|
18
|
+
try {
|
|
19
|
+
if (event.request.method == 'POST' || event.request.method == 'PUT') {
|
|
20
|
+
json = await event.request.json();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
console.log(error);
|
|
25
|
+
}
|
|
26
|
+
let sseResponse = undefined;
|
|
27
|
+
event.locals["_tempOnClose"] = () => { };
|
|
28
|
+
const response = {
|
|
29
|
+
end: () => { },
|
|
30
|
+
json: () => { },
|
|
31
|
+
status: () => {
|
|
32
|
+
return response;
|
|
33
|
+
},
|
|
34
|
+
write: () => { },
|
|
35
|
+
writeHead: (status, headers) => {
|
|
36
|
+
if (status === 200 && headers) {
|
|
37
|
+
const contentType = headers['Content-Type'];
|
|
38
|
+
if (contentType === 'text/event-stream') {
|
|
39
|
+
const messages = [];
|
|
40
|
+
response.write = (x) => messages.push(x);
|
|
41
|
+
const stream = new ReadableStream({
|
|
42
|
+
start: (controller) => {
|
|
43
|
+
for (const message of messages) {
|
|
44
|
+
controller.enqueue(message);
|
|
45
|
+
}
|
|
46
|
+
response.write = (data) => {
|
|
47
|
+
controller.enqueue(data);
|
|
48
|
+
};
|
|
49
|
+
},
|
|
50
|
+
cancel: () => {
|
|
51
|
+
response.write = () => { };
|
|
52
|
+
event.locals["_tempOnClose"]();
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
sseResponse = new Response(stream, { headers });
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
event.locals["_tempJson"] = json;
|
|
61
|
+
const responseFromRemultHandler = await result.handle(event, response);
|
|
62
|
+
if (sseResponse !== undefined) {
|
|
63
|
+
return sseResponse;
|
|
64
|
+
}
|
|
65
|
+
if (responseFromRemultHandler) {
|
|
66
|
+
return new Response(JSON.stringify(responseFromRemultHandler.data), {
|
|
67
|
+
status: responseFromRemultHandler.statusCode
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return new Promise((res) => {
|
|
72
|
+
result.withRemult(event, undefined, async () => {
|
|
73
|
+
res(await resolve(event));
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
};
|
|
77
|
+
return Object.assign(handler, {
|
|
78
|
+
getRemult: (req) => result.getRemult(req),
|
|
79
|
+
openApiDoc: (options) => result.openApiDoc(options),
|
|
80
|
+
registerRouter: x => result.registerRouter(x),
|
|
81
|
+
withRemult: (...args) => result.withRemult(...args)
|
|
82
|
+
});
|
|
83
|
+
}
|
|
@@ -5,7 +5,7 @@ import { ClassType } from '../classType';
|
|
|
5
5
|
import { Repository } from '../src/remult3';
|
|
6
6
|
import { IdEntity } from '../src/id-entity';
|
|
7
7
|
import { LiveQueryStorage, SubscriptionServer } from '../src/live-query/SubscriptionServer';
|
|
8
|
-
export interface RemultServerOptions<RequestType
|
|
8
|
+
export interface RemultServerOptions<RequestType> {
|
|
9
9
|
/**Entities to use for the api */
|
|
10
10
|
entities?: ClassType<any>[];
|
|
11
11
|
/**Controller to use for the api */
|
|
@@ -41,10 +41,10 @@ export interface RemultServerOptions<RequestType extends GenericRequest> {
|
|
|
41
41
|
subscriptionServer?: SubscriptionServer;
|
|
42
42
|
/** A storage to use to store live queries, relevant mostly for serverless scenarios or larger scales */
|
|
43
43
|
liveQueryStorage?: LiveQueryStorage;
|
|
44
|
-
/** Used to store the
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
/** Used to store the context relevant info for re running a live query */
|
|
45
|
+
contextSerializer?: {
|
|
46
|
+
serialize(remult: Remult): Promise<any>;
|
|
47
|
+
deserialize(json: any, remult: Remult): Promise<void>;
|
|
48
48
|
};
|
|
49
49
|
/** Storage to use for backend methods that use queue */
|
|
50
50
|
queueStorage?: QueueStorage;
|
|
@@ -53,21 +53,21 @@ export interface InitRequestOptions {
|
|
|
53
53
|
liveQueryStorage: LiveQueryStorage;
|
|
54
54
|
readonly remult: Remult;
|
|
55
55
|
}
|
|
56
|
-
export declare function createRemultServerCore<RequestType
|
|
56
|
+
export declare function createRemultServerCore<RequestType>(options: RemultServerOptions<RequestType>, serverCoreOptions: ServerCoreOptions<RequestType>): RemultServer<RequestType>;
|
|
57
57
|
export declare type GenericRequestHandler = (req: GenericRequest, res: GenericResponse, next: VoidFunction) => void;
|
|
58
58
|
export interface ServerHandleResponse {
|
|
59
59
|
data?: any;
|
|
60
60
|
statusCode: number;
|
|
61
61
|
}
|
|
62
|
-
export interface RemultServer {
|
|
63
|
-
getRemult(req:
|
|
62
|
+
export interface RemultServer<RequestType> {
|
|
63
|
+
getRemult(req: RequestType): Promise<Remult>;
|
|
64
64
|
openApiDoc(options: {
|
|
65
65
|
title: string;
|
|
66
66
|
version?: string;
|
|
67
67
|
}): any;
|
|
68
68
|
registerRouter(r: GenericRouter): void;
|
|
69
|
-
handle(req:
|
|
70
|
-
withRemult(req:
|
|
69
|
+
handle(req: RequestType, gRes?: GenericResponse): Promise<ServerHandleResponse | undefined>;
|
|
70
|
+
withRemult(req: RequestType, res: GenericResponse, next: VoidFunction): any;
|
|
71
71
|
}
|
|
72
72
|
export declare type GenericRouter = {
|
|
73
73
|
route(path: string): SpecificRoute;
|
|
@@ -128,3 +128,6 @@ export declare class JobsInQueueEntity extends IdEntity {
|
|
|
128
128
|
error: boolean;
|
|
129
129
|
progress: number;
|
|
130
130
|
}
|
|
131
|
+
export interface ServerCoreOptions<RequestType> {
|
|
132
|
+
buildGenericRequest(req: RequestType): GenericRequest;
|
|
133
|
+
}
|
|
@@ -10,7 +10,7 @@ import { liveQueryKeepAliveRoute, streamUrl } from '../src/live-query/Subscripti
|
|
|
10
10
|
import { initDataProvider } from './initDataProvider';
|
|
11
11
|
import { SseSubscriptionServer } from "../SseSubscriptionServer";
|
|
12
12
|
;
|
|
13
|
-
export function createRemultServerCore(options) {
|
|
13
|
+
export function createRemultServerCore(options, serverCoreOptions) {
|
|
14
14
|
if (!options) {
|
|
15
15
|
options = {};
|
|
16
16
|
}
|
|
@@ -63,23 +63,6 @@ export function createRemultServerCore(options) {
|
|
|
63
63
|
});
|
|
64
64
|
return dp;
|
|
65
65
|
});
|
|
66
|
-
if (!options.requestSerializer) {
|
|
67
|
-
options.requestSerializer = {
|
|
68
|
-
toJson: x => {
|
|
69
|
-
const r = {
|
|
70
|
-
url: x.url
|
|
71
|
-
};
|
|
72
|
-
for (const key of ['session', 'auth', 'user']) {
|
|
73
|
-
if (x[key])
|
|
74
|
-
r[key] = x[key];
|
|
75
|
-
}
|
|
76
|
-
return r;
|
|
77
|
-
},
|
|
78
|
-
fromJson: x => {
|
|
79
|
-
return x;
|
|
80
|
-
}
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
66
|
{
|
|
84
67
|
let allControllers = [];
|
|
85
68
|
if (!options.entities)
|
|
@@ -93,7 +76,7 @@ export function createRemultServerCore(options) {
|
|
|
93
76
|
if (options.rootPath === undefined)
|
|
94
77
|
options.rootPath = '/api';
|
|
95
78
|
actionInfo.runningOnServer = true;
|
|
96
|
-
let bridge = new RemultServerImplementation(new inProcessQueueHandler(options.queueStorage), options, dataProvider);
|
|
79
|
+
let bridge = new RemultServerImplementation(new inProcessQueueHandler(options.queueStorage), options, dataProvider, serverCoreOptions);
|
|
97
80
|
return bridge;
|
|
98
81
|
}
|
|
99
82
|
;
|
|
@@ -129,20 +112,22 @@ export class RemultAsyncLocalStorage {
|
|
|
129
112
|
RemultAsyncLocalStorage.instance = new RemultAsyncLocalStorage(undefined);
|
|
130
113
|
/* @internal*/
|
|
131
114
|
export class RemultServerImplementation {
|
|
132
|
-
constructor(queue, options, dataProvider) {
|
|
115
|
+
constructor(queue, options, dataProvider, coreOptions) {
|
|
133
116
|
this.queue = queue;
|
|
134
117
|
this.options = options;
|
|
135
118
|
this.dataProvider = dataProvider;
|
|
119
|
+
this.coreOptions = coreOptions;
|
|
136
120
|
this.liveQueryStorage = new InMemoryLiveQueryStorage();
|
|
137
|
-
this.
|
|
121
|
+
this.runWithSerializedJsonContextData = async (jsonContextData, entityKey, what) => {
|
|
138
122
|
for (const e of this.options.entities) {
|
|
139
123
|
let key = getEntityKey(e);
|
|
140
124
|
if (key === entityKey) {
|
|
141
|
-
await
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
}
|
|
125
|
+
await this.runWithRemult(async (remult) => {
|
|
126
|
+
remult.user = jsonContextData.user;
|
|
127
|
+
if (this.options.contextSerializer) {
|
|
128
|
+
await this.options.contextSerializer.deserialize(jsonContextData, remult);
|
|
129
|
+
}
|
|
130
|
+
await what(remult.repo(e));
|
|
146
131
|
});
|
|
147
132
|
return;
|
|
148
133
|
}
|
|
@@ -164,7 +149,7 @@ export class RemultServerImplementation {
|
|
|
164
149
|
}
|
|
165
150
|
getRouteImpl() {
|
|
166
151
|
if (!this.routeImpl) {
|
|
167
|
-
this.routeImpl = new RouteImplementation();
|
|
152
|
+
this.routeImpl = new RouteImplementation(this.coreOptions);
|
|
168
153
|
this.registerRouter(this.routeImpl);
|
|
169
154
|
}
|
|
170
155
|
return this.routeImpl;
|
|
@@ -230,14 +215,24 @@ export class RemultServerImplementation {
|
|
|
230
215
|
}, r);
|
|
231
216
|
});
|
|
232
217
|
}
|
|
218
|
+
async serializeContext(remult) {
|
|
219
|
+
let result = {
|
|
220
|
+
user: remult.user,
|
|
221
|
+
context: undefined
|
|
222
|
+
};
|
|
223
|
+
if (this.options.contextSerializer) {
|
|
224
|
+
result.context = await this.options.contextSerializer.serialize(remult);
|
|
225
|
+
}
|
|
226
|
+
return result;
|
|
227
|
+
}
|
|
233
228
|
add(key, dataApiFactory, r) {
|
|
234
229
|
let myRoute = this.options.rootPath + '/' + key;
|
|
235
230
|
if (this.options.logApiEndPoints)
|
|
236
231
|
console.info("[remult] " + myRoute);
|
|
237
232
|
r.route(myRoute)
|
|
238
|
-
.get(this.process((c, req, res, orig) => dataApiFactory(c).httpGet(res, req, () => this.
|
|
233
|
+
.get(this.process((c, req, res, orig) => dataApiFactory(c).httpGet(res, req, () => this.serializeContext(c)))).put(this.process(async (c, req, res, orig) => dataApiFactory(c).put(res, '', orig.body)))
|
|
239
234
|
.delete(this.process(async (c, req, res, orig) => dataApiFactory(c).delete(res, '')))
|
|
240
|
-
.post(this.process(async (c, req, res, orig) => dataApiFactory(c).httpPost(res, req, orig.body, () => this.
|
|
235
|
+
.post(this.process(async (c, req, res, orig) => dataApiFactory(c).httpPost(res, req, orig.body, () => this.serializeContext(c))));
|
|
241
236
|
r.route(myRoute + '/:id')
|
|
242
237
|
//@ts-ignore
|
|
243
238
|
.get(this.process(async (c, req, res, orig) => dataApiFactory(c).get(res, orig.params.id)))
|
|
@@ -246,29 +241,38 @@ export class RemultServerImplementation {
|
|
|
246
241
|
//@ts-ignore
|
|
247
242
|
.delete(this.process(async (c, req, res, orig) => dataApiFactory(c).delete(res, orig.params.id)));
|
|
248
243
|
}
|
|
244
|
+
async runWithRemult(what) {
|
|
245
|
+
let remult = new Remult();
|
|
246
|
+
remult.liveQueryPublisher = new LiveQueryPublisher(() => remult.subscriptionServer, () => remult.liveQueryStorage, this.runWithSerializedJsonContextData);
|
|
247
|
+
remult.dataProvider = (await this.dataProvider);
|
|
248
|
+
remult.subscriptionServer = this.subscriptionServer;
|
|
249
|
+
remult.liveQueryStorage = this.liveQueryStorage;
|
|
250
|
+
await new Promise(res => {
|
|
251
|
+
RemultAsyncLocalStorage.instance.run(remult, async () => {
|
|
252
|
+
res(await what(remult));
|
|
253
|
+
});
|
|
254
|
+
});
|
|
255
|
+
}
|
|
249
256
|
process(what) {
|
|
250
257
|
return async (req, origRes) => {
|
|
251
258
|
let myReq = new ExpressRequestBridgeToDataApiRequest(req);
|
|
252
259
|
let myRes = new ExpressResponseBridgeToDataApiResponse(origRes, req);
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
if (
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
user = req['
|
|
266
|
-
if (!user)
|
|
267
|
-
user = req['auth'];
|
|
268
|
-
}
|
|
269
|
-
if (user)
|
|
270
|
-
remult.user = (user);
|
|
260
|
+
await this.runWithRemult(async (remult) => {
|
|
261
|
+
remult.liveQueryPublisher = new LiveQueryPublisher(() => remult.subscriptionServer, () => remult.liveQueryStorage, this.runWithSerializedJsonContextData);
|
|
262
|
+
remult.dataProvider = (await this.dataProvider);
|
|
263
|
+
remult.subscriptionServer = this.subscriptionServer;
|
|
264
|
+
remult.liveQueryStorage = this.liveQueryStorage;
|
|
265
|
+
if (req) {
|
|
266
|
+
let user;
|
|
267
|
+
if (this.options.getUser)
|
|
268
|
+
user = await this.options.getUser(req);
|
|
269
|
+
else {
|
|
270
|
+
user = req['user'];
|
|
271
|
+
if (!user)
|
|
272
|
+
user = req['auth'];
|
|
271
273
|
}
|
|
274
|
+
if (user)
|
|
275
|
+
remult.user = (user);
|
|
272
276
|
if (this.options.initRequest) {
|
|
273
277
|
await this.options.initRequest(req, {
|
|
274
278
|
remult,
|
|
@@ -280,9 +284,8 @@ export class RemultServerImplementation {
|
|
|
280
284
|
}
|
|
281
285
|
});
|
|
282
286
|
}
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
});
|
|
287
|
+
}
|
|
288
|
+
await what(remult, myReq, myRes, req, origRes);
|
|
286
289
|
});
|
|
287
290
|
};
|
|
288
291
|
}
|
|
@@ -776,7 +779,8 @@ export class EntityQueueStorage {
|
|
|
776
779
|
}
|
|
777
780
|
}
|
|
778
781
|
class RouteImplementation {
|
|
779
|
-
constructor() {
|
|
782
|
+
constructor(coreOptions) {
|
|
783
|
+
this.coreOptions = coreOptions;
|
|
780
784
|
this.map = new Map();
|
|
781
785
|
}
|
|
782
786
|
route(path) {
|
|
@@ -846,7 +850,8 @@ class RouteImplementation {
|
|
|
846
850
|
this.middleware(req, response, () => res(undefined));
|
|
847
851
|
});
|
|
848
852
|
}
|
|
849
|
-
middleware(
|
|
853
|
+
middleware(origReq, res, next) {
|
|
854
|
+
const req = this.coreOptions.buildGenericRequest(origReq);
|
|
850
855
|
let theUrl = req.url;
|
|
851
856
|
if (theUrl.startsWith('/')) //next sends a partial url '/api/tasks' and not the full url
|
|
852
857
|
theUrl = 'http://stam' + theUrl;
|
package/esm/server/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { RemultServer, RemultServerOptions, ServerCoreOptions } from './expressBridge';
|
|
2
2
|
export { queuedJobInfo, QueueStorage, GenericRequest, GenericRequestHandler, GenericResponse, GenericRouter, RemultServerOptions, SpecificRoute, RemultServer, InitRequestOptions } from './expressBridge';
|
|
3
3
|
export { JsonEntityFileStorage, JsonFileDataProvider } from './JsonEntityFileStorage';
|
|
4
4
|
export { DataProviderLiveQueryStorage } from '../live-query/data-provider-live-query-storage';
|
|
5
5
|
export { SseSubscriptionServer } from '../SseSubscriptionServer';
|
|
6
|
-
export declare function createRemultServer<RequestType
|
|
6
|
+
export declare function createRemultServer<RequestType>(options: RemultServerOptions<RequestType>, serverCoreOptions?: ServerCoreOptions<RequestType>): RemultServer<RequestType>;
|
package/esm/server/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import { initAsyncHooks } from './initAsyncHooks';
|
|
|
3
3
|
export { JsonEntityFileStorage, JsonFileDataProvider } from './JsonEntityFileStorage';
|
|
4
4
|
export { DataProviderLiveQueryStorage } from '../live-query/data-provider-live-query-storage';
|
|
5
5
|
export { SseSubscriptionServer } from '../SseSubscriptionServer';
|
|
6
|
-
export function createRemultServer(options) {
|
|
6
|
+
export function createRemultServer(options, serverCoreOptions) {
|
|
7
7
|
initAsyncHooks();
|
|
8
|
-
return createRemultServerCore(options);
|
|
8
|
+
return createRemultServerCore(options, serverCoreOptions || { buildGenericRequest: req => req });
|
|
9
9
|
}
|
package/esm/src/data-api.d.ts
CHANGED
|
@@ -5,8 +5,8 @@ export declare class DataApi<T = any> {
|
|
|
5
5
|
private repository;
|
|
6
6
|
private remult;
|
|
7
7
|
constructor(repository: Repository<T>, remult: Remult);
|
|
8
|
-
httpGet(res: DataApiResponse, req: DataApiRequest, serializeRequest: () => any): Promise<void>;
|
|
9
|
-
httpPost(res: DataApiResponse, req: DataApiRequest, body: any, serializeRequest: () => any): Promise<void>;
|
|
8
|
+
httpGet(res: DataApiResponse, req: DataApiRequest, serializeRequest: () => Promise<any>): Promise<void>;
|
|
9
|
+
httpPost(res: DataApiResponse, req: DataApiRequest, body: any, serializeRequest: () => Promise<any>): Promise<void>;
|
|
10
10
|
static defaultGetLimit: number;
|
|
11
11
|
get(response: DataApiResponse, id: any): Promise<void>;
|
|
12
12
|
count(response: DataApiResponse, request: DataApiRequest, filterBody?: any): Promise<void>;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { findOptionsFromJson } from '../data-providers/rest-data-provider';
|
|
2
2
|
/* @internal*/
|
|
3
3
|
export class LiveQueryPublisher {
|
|
4
|
-
constructor(subscriptionServer, liveQueryStorage,
|
|
4
|
+
constructor(subscriptionServer, liveQueryStorage, performWithContext) {
|
|
5
5
|
this.subscriptionServer = subscriptionServer;
|
|
6
6
|
this.liveQueryStorage = liveQueryStorage;
|
|
7
|
-
this.
|
|
7
|
+
this.performWithContext = performWithContext;
|
|
8
8
|
this.debugFileSaver = (x) => { };
|
|
9
9
|
}
|
|
10
10
|
runPromise(p) { }
|
|
@@ -12,7 +12,7 @@ export class LiveQueryPublisher {
|
|
|
12
12
|
//TODO 2 - optimize so that the user will get their messages first. Based on user id
|
|
13
13
|
await (this.liveQueryStorage().forEach(entityKey, async ({ query: q, setData }) => {
|
|
14
14
|
let query = { ...q.data };
|
|
15
|
-
await this.
|
|
15
|
+
await this.performWithContext(query.requestJson, entityKey, async (repo) => {
|
|
16
16
|
const messages = [];
|
|
17
17
|
const currentItems = await repo.find(findOptionsFromJson(query.findOptionsJson, repo.metadata));
|
|
18
18
|
const currentIds = currentItems.map(x => repo.getEntityRef(x).getId());
|
|
@@ -1259,7 +1259,7 @@ export class columnDefsImpl {
|
|
|
1259
1259
|
get includedInApi() {
|
|
1260
1260
|
if (this.options.includeInApi === undefined)
|
|
1261
1261
|
return true;
|
|
1262
|
-
return this.remult.isAllowed(this.options.includeInApi); //TODO - consolidate other code paths to go through here
|
|
1262
|
+
return this.remult.isAllowed(this.options.includeInApi); //TODO 2- consolidate other code paths to go through here
|
|
1263
1263
|
}
|
|
1264
1264
|
toInput(value, inputType) {
|
|
1265
1265
|
return this.valueConverter.toInput(value, inputType);
|
|
@@ -1711,10 +1711,7 @@ export function decorateColumnSettings(settings, remult) {
|
|
|
1711
1711
|
if (settings.valueType == String) {
|
|
1712
1712
|
let x = settings;
|
|
1713
1713
|
if (!settings.valueConverter)
|
|
1714
|
-
x.valueConverter =
|
|
1715
|
-
toJson: x => x,
|
|
1716
|
-
fromJson: x => x
|
|
1717
|
-
};
|
|
1714
|
+
x.valueConverter = ValueConverters.String;
|
|
1718
1715
|
}
|
|
1719
1716
|
if (settings.valueType == Number) {
|
|
1720
1717
|
let x = settings;
|
|
@@ -25,6 +25,14 @@ testAll("what", async ({ remult, createEntity }) => {
|
|
|
25
25
|
await (await createEntity(stam)).create({ id: 1, title: 'noam' }).save();
|
|
26
26
|
expect(await remult.repo(stam).count()).toBe(1);
|
|
27
27
|
}, false);
|
|
28
|
+
testAll("data types", async ({ remult, createEntity }) => {
|
|
29
|
+
let r = await (await createEntity(stam)).create({
|
|
30
|
+
id: 1,
|
|
31
|
+
//@ts-ignore
|
|
32
|
+
title: 42
|
|
33
|
+
}).save();
|
|
34
|
+
expect(r.title).toEqual("42");
|
|
35
|
+
}, false);
|
|
28
36
|
testAll("filter works on all db", async ({ createEntity }) => {
|
|
29
37
|
let s = await entityWithValidations.create4RowsInDp(createEntity);
|
|
30
38
|
expect((await s.find({ where: { myId: [1, 3] } })).length).toBe(2);
|
|
@@ -186,7 +186,7 @@ export function createMockHttpDataProvider(dataApi) {
|
|
|
186
186
|
r.success = data => { result = data; };
|
|
187
187
|
try {
|
|
188
188
|
testConfiguration.restDbRunningOnServer = true;
|
|
189
|
-
await dataApi.httpGet(r, urlToReq(url), () => "");
|
|
189
|
+
await dataApi.httpGet(r, urlToReq(url), async () => "");
|
|
190
190
|
}
|
|
191
191
|
finally {
|
|
192
192
|
testConfiguration.restDbRunningOnServer = false;
|
|
@@ -200,7 +200,7 @@ export function createMockHttpDataProvider(dataApi) {
|
|
|
200
200
|
r.success = data => { result = data; };
|
|
201
201
|
try {
|
|
202
202
|
testConfiguration.restDbRunningOnServer = true;
|
|
203
|
-
await dataApi.httpPost(r, urlToReq(url), data, () => ({}));
|
|
203
|
+
await dataApi.httpPost(r, urlToReq(url), data, async () => ({}));
|
|
204
204
|
}
|
|
205
205
|
finally {
|
|
206
206
|
testConfiguration.restDbRunningOnServer = false;
|
|
@@ -5,6 +5,7 @@ export declare class ValueConverters {
|
|
|
5
5
|
static readonly DateOnlyString: ValueConverter<Date>;
|
|
6
6
|
static readonly Boolean: ValueConverter<Boolean>;
|
|
7
7
|
static readonly Number: ValueConverter<number>;
|
|
8
|
+
static readonly String: ValueConverter<String>;
|
|
8
9
|
static readonly Integer: ValueConverter<number>;
|
|
9
10
|
static readonly Default: Required<ValueConverter<any>>;
|
|
10
11
|
static readonly JsonString: ValueConverter<any>;
|
|
@@ -141,6 +141,14 @@ ValueConverters.Number = {
|
|
|
141
141
|
},
|
|
142
142
|
inputType: InputTypes.number
|
|
143
143
|
};
|
|
144
|
+
ValueConverters.String = {
|
|
145
|
+
fromDb: enforceString,
|
|
146
|
+
toDb: enforceString,
|
|
147
|
+
fromJson: enforceString,
|
|
148
|
+
toJson: enforceString,
|
|
149
|
+
fromInput: enforceString,
|
|
150
|
+
toInput: enforceString,
|
|
151
|
+
};
|
|
144
152
|
ValueConverters.Integer = {
|
|
145
153
|
...ValueConverters.Number,
|
|
146
154
|
toJson: value => {
|
|
@@ -180,3 +188,10 @@ ValueConverters.JsonValue = {
|
|
|
180
188
|
toInput: x => ValueConverters.JsonString.toJson(x),
|
|
181
189
|
fieldTypeInDb: 'json'
|
|
182
190
|
};
|
|
191
|
+
function enforceString(value) {
|
|
192
|
+
if (value === null || value === undefined)
|
|
193
|
+
return value;
|
|
194
|
+
if (typeof (value) !== "string")
|
|
195
|
+
return value.toString();
|
|
196
|
+
return value;
|
|
197
|
+
}
|
package/graphql.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "remult",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0-exp.1",
|
|
4
4
|
"description": "A CRUD framework for full-stack TypeScript",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -78,6 +78,14 @@
|
|
|
78
78
|
},
|
|
79
79
|
"import": "./esm/remult-fresh.js"
|
|
80
80
|
},
|
|
81
|
+
"./remult-sveltekit": {
|
|
82
|
+
"require": "./remult-sveltekit.js",
|
|
83
|
+
"node": {
|
|
84
|
+
"require": "./remult-sveltekit.js",
|
|
85
|
+
"import": "./remult-sveltekit.js"
|
|
86
|
+
},
|
|
87
|
+
"import": "./esm/remult-sveltekit.js"
|
|
88
|
+
},
|
|
81
89
|
"./postgres": {
|
|
82
90
|
"require": "./postgres/index.js",
|
|
83
91
|
"node": {
|
package/remult-express.d.ts
CHANGED
|
@@ -3,4 +3,4 @@ import { RemultServer, RemultServerOptions } from './server/expressBridge';
|
|
|
3
3
|
export declare function remultExpress(options?: RemultServerOptions<express.Request> & {
|
|
4
4
|
bodyParser?: boolean;
|
|
5
5
|
bodySizeLimit?: string;
|
|
6
|
-
}): express.RequestHandler & RemultServer
|
|
6
|
+
}): express.RequestHandler & RemultServer<express.Request>;
|
package/remult-express.js
CHANGED
|
@@ -16,7 +16,9 @@ function remultExpress(options) {
|
|
|
16
16
|
app.use(express.json({ limit: options.bodySizeLimit }));
|
|
17
17
|
app.use(express.urlencoded({ extended: true, limit: options.bodySizeLimit }));
|
|
18
18
|
}
|
|
19
|
-
var server = index_1.createRemultServer(options
|
|
19
|
+
var server = index_1.createRemultServer(options, {
|
|
20
|
+
buildGenericRequest: function (req) { return req; }
|
|
21
|
+
});
|
|
20
22
|
server.registerRouter(app);
|
|
21
23
|
return Object.assign(app, {
|
|
22
24
|
getRemult: function (req) { return server.getRemult(req); },
|
package/remult-fastify.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { FastifyPluginCallback, FastifyRequest } from 'fastify';
|
|
2
2
|
import { RemultServer, RemultServerOptions } from './server/expressBridge';
|
|
3
|
-
export declare function remultFastify(options: RemultServerOptions<FastifyRequest>): FastifyPluginCallback & RemultServer
|
|
3
|
+
export declare function remultFastify(options: RemultServerOptions<FastifyRequest>): FastifyPluginCallback & RemultServer<FastifyRequest>;
|