remult 0.15.4 → 0.16.0-exp.10
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 +4 -2
- package/esm/index.js +3 -1
- package/esm/postgres/postgres-data-provider.js +2 -2
- package/esm/remult-express.js +2 -1
- package/esm/server/expressBridge.d.ts +1 -0
- package/esm/server/expressBridge.js +48 -20
- package/esm/src/backend-tests/test-http-server.backend-spec.js +13 -10
- package/esm/src/context.d.ts +18 -20
- package/esm/src/context.js +56 -70
- package/esm/src/data-providers/rest-data-provider.d.ts +4 -4
- package/esm/src/data-providers/rest-data-provider.js +20 -14
- package/esm/src/remult-proxy.d.ts +2 -0
- package/esm/src/remult-proxy.js +48 -0
- package/esm/src/remult3/RepositoryImplementation.d.ts +2 -1
- package/esm/src/remult3/RepositoryImplementation.js +5 -3
- package/esm/src/server-action.d.ts +8 -7
- package/esm/src/server-action.js +38 -32
- package/esm/src/shared-tests/db-tests-setup.js +1 -1
- package/esm/src/tests/createData.js +1 -1
- package/esm/src/tests/frontend-database-tests-setup.spec.js +3 -3
- package/esm/src/tests/testHelper.spec.js +17 -12
- package/index.d.ts +4 -2
- package/index.js +7 -3
- package/package.json +1 -1
- package/postgres/postgres-data-provider.js +2 -2
- package/remult-express.js +9 -1
- package/server/expressBridge.d.ts +1 -0
- package/server/expressBridge.js +82 -31
- package/src/backend-tests/test-http-server.backend-spec.js +11 -8
- package/src/context.d.ts +18 -20
- package/src/context.js +65 -89
- package/src/data-providers/rest-data-provider.d.ts +4 -4
- package/src/data-providers/rest-data-provider.js +21 -13
- package/src/remult-proxy.d.ts +2 -0
- package/src/remult-proxy.js +82 -0
- package/src/remult3/RepositoryImplementation.d.ts +2 -1
- package/src/remult3/RepositoryImplementation.js +5 -3
- package/src/server-action.d.ts +8 -7
- package/src/server-action.js +130 -119
- package/src/shared-tests/db-tests-setup.js +1 -1
- package/src/tests/createData.js +1 -1
- package/src/tests/frontend-database-tests-setup.spec.js +3 -3
- package/src/tests/testHelper.spec.js +19 -14
package/esm/index.d.ts
CHANGED
|
@@ -8,10 +8,11 @@ export { RestDataProvider } from './src/data-providers/rest-data-provider';
|
|
|
8
8
|
export { InMemoryDataProvider } from './src/data-providers/in-memory-database';
|
|
9
9
|
export { ArrayEntityDataProvider } from './src/data-providers/array-entity-data-provider';
|
|
10
10
|
export { WebSqlDataProvider } from './src/data-providers/web-sql-data-provider';
|
|
11
|
-
export { SqlDatabase } from './src/data-providers/sql-database';
|
|
11
|
+
export { SqlDatabase, } from './src/data-providers/sql-database';
|
|
12
|
+
export { CustomSqlFilterObject, CustomSqlFilterBuilder } from './src/filter/filter-consumer-bridge-to-sql-request';
|
|
12
13
|
export { JsonDataProvider, JsonEntityStorage } from './src/data-providers/json-data-provider';
|
|
13
14
|
export { Controller, BackendMethodOptions, BackendMethod, ProgressListener } from './src/server-action';
|
|
14
|
-
export { Allowed, Allow, Remult, isBackend, AllowedForInstance, EventDispatcher, EventSource,
|
|
15
|
+
export { Allowed, Allow, Remult, RemultContext, ApiClient, isBackend, AllowedForInstance, EventDispatcher, EventSource, ExternalHttpProvider, Unobserve, UserInfo } from './src/context';
|
|
15
16
|
export { IdEntity } from './src/id-entity';
|
|
16
17
|
export { SortSegment, Sort } from './src/sort';
|
|
17
18
|
export { OneToMany, CompoundIdField } from './src/column';
|
|
@@ -20,3 +21,4 @@ export { FilterConsumerBridgeToSqlRequest } from './src/filter/filter-consumer-b
|
|
|
20
21
|
export { UrlBuilder } from './urlBuilder';
|
|
21
22
|
export { Validators } from './src/validators';
|
|
22
23
|
export { ValueConverters } from './src/valueConverters';
|
|
24
|
+
export { remult } from './src/remult-proxy';
|
package/esm/index.js
CHANGED
|
@@ -6,7 +6,8 @@ export { RestDataProvider } from './src/data-providers/rest-data-provider'; //V
|
|
|
6
6
|
export { InMemoryDataProvider } from './src/data-providers/in-memory-database'; //V
|
|
7
7
|
export { ArrayEntityDataProvider } from './src/data-providers/array-entity-data-provider'; //V
|
|
8
8
|
export { WebSqlDataProvider } from './src/data-providers/web-sql-data-provider'; //V
|
|
9
|
-
export { SqlDatabase } from './src/data-providers/sql-database'; //V
|
|
9
|
+
export { SqlDatabase, } from './src/data-providers/sql-database'; //V
|
|
10
|
+
export { CustomSqlFilterBuilder } from './src/filter/filter-consumer-bridge-to-sql-request';
|
|
10
11
|
export { JsonDataProvider } from './src/data-providers/json-data-provider'; //V
|
|
11
12
|
//export * from './src/data-api'; //reconsider if to make internal
|
|
12
13
|
export { Controller, BackendMethod, ProgressListener } from './src/server-action';
|
|
@@ -19,3 +20,4 @@ export { FilterConsumerBridgeToSqlRequest } from './src/filter/filter-consumer-b
|
|
|
19
20
|
export { UrlBuilder } from './urlBuilder';
|
|
20
21
|
export { Validators } from './src/validators';
|
|
21
22
|
export { ValueConverters } from './src/valueConverters';
|
|
23
|
+
export { remult } from './src/remult-proxy';
|
|
@@ -81,14 +81,14 @@ export async function createPostgresConnection(options) {
|
|
|
81
81
|
}
|
|
82
82
|
const db = new SqlDatabase(new PostgresDataProvider(new Pool(config)));
|
|
83
83
|
let remult = new Remult();
|
|
84
|
-
remult.
|
|
84
|
+
remult.dataProvider = (db);
|
|
85
85
|
if (options.autoCreateTables === undefined || options.autoCreateTables)
|
|
86
86
|
await verifyStructureOfAllEntities(db, remult);
|
|
87
87
|
return db;
|
|
88
88
|
}
|
|
89
89
|
export async function preparePostgresQueueStorage(sql) {
|
|
90
90
|
let c = new Remult();
|
|
91
|
-
c.
|
|
91
|
+
c.dataProvider = (sql);
|
|
92
92
|
let JobsInQueueEntity = (await import('../server/expressBridge')).JobsInQueueEntity;
|
|
93
93
|
let e = c.repo(JobsInQueueEntity);
|
|
94
94
|
await new PostgresSchemaBuilder(sql).createIfNotExist(e.metadata);
|
package/esm/remult-express.js
CHANGED
|
@@ -17,6 +17,7 @@ export function remultExpress(options) {
|
|
|
17
17
|
return Object.assign(app, {
|
|
18
18
|
getRemult: (req) => server.getRemult(req),
|
|
19
19
|
openApiDoc: (options) => server.openApiDoc(options),
|
|
20
|
-
registerRouter: x => server.registerRouter(x)
|
|
20
|
+
registerRouter: x => server.registerRouter(x),
|
|
21
|
+
withRemultMiddleware: (...args) => server.withRemultMiddleware(...args)
|
|
21
22
|
});
|
|
22
23
|
}
|
|
@@ -33,6 +33,7 @@ export interface RemultServer {
|
|
|
33
33
|
}): any;
|
|
34
34
|
registerRouter(r: GenericRouter): void;
|
|
35
35
|
handle(req: GenericRequest, gRes?: GenericResponse): Promise<ServerHandleResponse | undefined>;
|
|
36
|
+
withRemultMiddleware(req: GenericRequest, res: GenericResponse, next: VoidFunction): any;
|
|
36
37
|
}
|
|
37
38
|
export declare type GenericRouter = {
|
|
38
39
|
route(path: string): SpecificRoute;
|
|
@@ -4,6 +4,8 @@ import { DataApi, serializeError } from '../src/data-api';
|
|
|
4
4
|
import { allEntities, Remult } from '../src/context';
|
|
5
5
|
import { Entity, Fields, getEntityKey } from '../src/remult3';
|
|
6
6
|
import { IdEntity } from '../src/id-entity';
|
|
7
|
+
import { AsyncLocalStorage } from 'async_hooks';
|
|
8
|
+
import { remult } from '../src/remult-proxy';
|
|
7
9
|
;
|
|
8
10
|
export function createRemultServer(options) {
|
|
9
11
|
if (!options) {
|
|
@@ -32,7 +34,12 @@ export function createRemultServer(options) {
|
|
|
32
34
|
if (options.initApi) {
|
|
33
35
|
dataProvider = dataProvider.then(async (dp) => {
|
|
34
36
|
var remult = new Remult(dp);
|
|
35
|
-
await
|
|
37
|
+
await new Promise((res) => {
|
|
38
|
+
remultObjectStorage.run(remult, async () => {
|
|
39
|
+
await options.initApi(remult);
|
|
40
|
+
res({});
|
|
41
|
+
});
|
|
42
|
+
});
|
|
36
43
|
return dp;
|
|
37
44
|
});
|
|
38
45
|
}
|
|
@@ -47,12 +54,14 @@ export function createRemultServer(options) {
|
|
|
47
54
|
options.controllers = allControllers;
|
|
48
55
|
}
|
|
49
56
|
if (options.rootPath === undefined)
|
|
50
|
-
options.rootPath =
|
|
57
|
+
options.rootPath = '/api';
|
|
51
58
|
actionInfo.runningOnServer = true;
|
|
52
59
|
let bridge = new RemultServerImplementation(new inProcessQueueHandler(options.queueStorage), options, dataProvider);
|
|
53
60
|
return bridge;
|
|
54
61
|
}
|
|
55
62
|
;
|
|
63
|
+
const remultObjectStorage = new AsyncLocalStorage();
|
|
64
|
+
let remultObjectStorageWasSetup = false;
|
|
56
65
|
class RemultServerImplementation {
|
|
57
66
|
constructor(queue, options, dataProvider) {
|
|
58
67
|
this.queue = queue;
|
|
@@ -62,6 +71,19 @@ class RemultServerImplementation {
|
|
|
62
71
|
this.hasQueue = false;
|
|
63
72
|
/* internal */
|
|
64
73
|
this.backendMethodsOpenApi = [];
|
|
74
|
+
if (!remultObjectStorageWasSetup) {
|
|
75
|
+
remultObjectStorageWasSetup = true;
|
|
76
|
+
remult.remultFactory = () => {
|
|
77
|
+
const r = remultObjectStorage.getStore();
|
|
78
|
+
if (r)
|
|
79
|
+
return r;
|
|
80
|
+
else
|
|
81
|
+
throw new Error("remult object was requested outside of a valid context, try running it within initApi or a remult request cycle");
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
withRemultMiddleware(req, res, next) {
|
|
86
|
+
this.process(async () => { next(); })(req, res);
|
|
65
87
|
}
|
|
66
88
|
handle(req, gRes) {
|
|
67
89
|
if (!this.routeImpl) {
|
|
@@ -101,7 +123,8 @@ class RemultServerImplementation {
|
|
|
101
123
|
else
|
|
102
124
|
res.success(job.info);
|
|
103
125
|
});
|
|
104
|
-
}
|
|
126
|
+
},
|
|
127
|
+
doWork: undefined
|
|
105
128
|
}, r);
|
|
106
129
|
}
|
|
107
130
|
this.options.entities.forEach(e => {
|
|
@@ -133,23 +156,28 @@ class RemultServerImplementation {
|
|
|
133
156
|
let myReq = new ExpressRequestBridgeToDataApiRequest(req);
|
|
134
157
|
let myRes = new ExpressResponseBridgeToDataApiResponse(res, req);
|
|
135
158
|
let remult = new Remult();
|
|
136
|
-
remult.
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
159
|
+
remult.dataProvider = (await this.dataProvider);
|
|
160
|
+
await new Promise(res => {
|
|
161
|
+
remultObjectStorage.run(remult, async () => {
|
|
162
|
+
if (req) {
|
|
163
|
+
let user;
|
|
164
|
+
if (this.options.getUser)
|
|
165
|
+
user = await this.options.getUser(req);
|
|
166
|
+
else {
|
|
167
|
+
user = req['user'];
|
|
168
|
+
if (!user)
|
|
169
|
+
user = req['auth'];
|
|
170
|
+
}
|
|
171
|
+
if (user)
|
|
172
|
+
remult.user = (user);
|
|
173
|
+
}
|
|
174
|
+
if (this.options.initRequest) {
|
|
175
|
+
await this.options.initRequest(remult, req);
|
|
176
|
+
}
|
|
177
|
+
await what(remult, myReq, myRes, req);
|
|
178
|
+
res({});
|
|
179
|
+
});
|
|
180
|
+
});
|
|
153
181
|
};
|
|
154
182
|
}
|
|
155
183
|
;
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { __decorate, __metadata } from "tslib";
|
|
2
2
|
import axios from 'axios';
|
|
3
3
|
import { remultFresh } from '../../remult-fresh';
|
|
4
|
-
import {
|
|
4
|
+
import { Remult } from '../context';
|
|
5
5
|
import { InMemoryDataProvider } from '../data-providers/in-memory-database';
|
|
6
|
+
import { remult } from '../remult-proxy';
|
|
6
7
|
import { Entity, Fields } from '../remult3';
|
|
7
|
-
import {
|
|
8
|
+
import { BackendMethod } from '../server-action';
|
|
8
9
|
import { Categories } from '../tests/remult-3-entities';
|
|
9
|
-
|
|
10
|
-
let path =
|
|
10
|
+
remult.apiClient.url = 'http://localhost:3003/api';
|
|
11
|
+
let path = remult.apiClient.url + '/tasks';
|
|
11
12
|
const environments = [
|
|
12
13
|
// ["next", 3000],
|
|
13
14
|
// ["nest", 3001],
|
|
@@ -21,8 +22,8 @@ const environments = [
|
|
|
21
22
|
function test(name, test) {
|
|
22
23
|
for (const [env, port] of environments) {
|
|
23
24
|
const theTest = async () => {
|
|
24
|
-
|
|
25
|
-
path =
|
|
25
|
+
remult.apiClient.url = `http://localhost:${port}/api`;
|
|
26
|
+
path = remult.apiClient.url + '/tasks';
|
|
26
27
|
await test();
|
|
27
28
|
};
|
|
28
29
|
const testName = env + ` ${port}: ${name}`;
|
|
@@ -93,7 +94,7 @@ test("test http 201", async () => {
|
|
|
93
94
|
});
|
|
94
95
|
test("test regular api call", async () => {
|
|
95
96
|
await create3Tasks();
|
|
96
|
-
let result = await axios.get(
|
|
97
|
+
let result = await axios.get(remult.apiClient.url + "/test");
|
|
97
98
|
expect(result.data.result).toBe(3);
|
|
98
99
|
});
|
|
99
100
|
class FreshResponseTest {
|
|
@@ -106,9 +107,11 @@ class FreshResponseTest {
|
|
|
106
107
|
}
|
|
107
108
|
}
|
|
108
109
|
it("test fresh", async () => {
|
|
109
|
-
const api = remultFresh({
|
|
110
|
+
const api = remultFresh({
|
|
111
|
+
entities: [Categories],
|
|
110
112
|
dataProvider: new InMemoryDataProvider(),
|
|
111
|
-
rootPath: '/api'
|
|
113
|
+
rootPath: '/api'
|
|
114
|
+
}, FreshResponseTest);
|
|
112
115
|
const r = await api.handle({
|
|
113
116
|
url: '/api/Categories',
|
|
114
117
|
json() {
|
|
@@ -158,7 +161,7 @@ Task = __decorate([
|
|
|
158
161
|
export { Task };
|
|
159
162
|
async function create3Tasks() {
|
|
160
163
|
const remult = new Remult(axios);
|
|
161
|
-
|
|
164
|
+
remult.apiClient.httpClient = axios;
|
|
162
165
|
const taskRepo = remult.repo(Task);
|
|
163
166
|
for (const task of await taskRepo.find()) {
|
|
164
167
|
await taskRepo.delete(task);
|
package/esm/src/context.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { DataProvider, RestDataProviderHttpProvider } from "./data-interfaces";
|
|
2
|
+
import { RestDataProviderHttpProviderUsingFetch } from './data-providers/rest-data-provider';
|
|
2
3
|
import { EntityMetadata, EntityRef, FindOptions, Repository } from "./remult3";
|
|
3
4
|
import { ClassType } from "../classType";
|
|
4
|
-
export interface
|
|
5
|
+
export interface ExternalHttpProvider {
|
|
5
6
|
post(url: string, data: any): Promise<any> | {
|
|
6
7
|
toPromise(): Promise<any>;
|
|
7
8
|
};
|
|
@@ -17,7 +18,7 @@ export interface HttpProvider {
|
|
|
17
18
|
}
|
|
18
19
|
export declare class HttpProviderBridgeToRestDataProviderHttpProvider implements RestDataProviderHttpProvider {
|
|
19
20
|
private http;
|
|
20
|
-
constructor(http:
|
|
21
|
+
constructor(http: ExternalHttpProvider);
|
|
21
22
|
post(url: string, data: any): Promise<any>;
|
|
22
23
|
delete(url: string): Promise<void>;
|
|
23
24
|
put(url: string, data: any): Promise<any>;
|
|
@@ -37,12 +38,7 @@ export declare class Remult {
|
|
|
37
38
|
*
|
|
38
39
|
*/
|
|
39
40
|
repo<T>(entity: ClassType<T>, dataProvider?: DataProvider): Repository<T>;
|
|
40
|
-
|
|
41
|
-
get user(): UserInfo;
|
|
42
|
-
/** Set's the current user info */
|
|
43
|
-
setUser(info: UserInfo | undefined): Promise<void>;
|
|
44
|
-
private _user;
|
|
45
|
-
private _userChangeEvent;
|
|
41
|
+
user?: UserInfo;
|
|
46
42
|
/** Checks if a user was authenticated */
|
|
47
43
|
authenticated(): boolean;
|
|
48
44
|
/** checks if the user has any of the roles specified in the parameters
|
|
@@ -57,30 +53,31 @@ export declare class Remult {
|
|
|
57
53
|
* [Allowed](https://remult.dev/docs/allowed.html)
|
|
58
54
|
*/
|
|
59
55
|
isAllowedForInstance(instance: any, allowed?: AllowedForInstance<any>): boolean;
|
|
60
|
-
/** returns a dispatcher object that fires once a user has changed*/
|
|
61
|
-
get userChange(): EventDispatcher;
|
|
62
|
-
private repCache;
|
|
63
56
|
/** Creates a new instance of the `remult` object.
|
|
64
57
|
*
|
|
65
58
|
* Can receive either an HttpProvider or a DataProvider as a parameter - which will be used to fetch data from.
|
|
66
59
|
*
|
|
67
60
|
* If no provider is specified, `fetch` will be used as an http provider
|
|
68
61
|
*/
|
|
69
|
-
constructor(
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
*/
|
|
74
|
-
static apiBaseUrl: string;
|
|
62
|
+
constructor(http: ExternalHttpProvider | typeof fetch | ApiClient);
|
|
63
|
+
constructor(p: DataProvider);
|
|
64
|
+
constructor();
|
|
65
|
+
call<T extends ((...args: any[]) => Promise<Y>), Y>(backendMethod: T, self?: any): T;
|
|
75
66
|
/** The current data provider */
|
|
76
|
-
|
|
77
|
-
/** sets the current data provider */
|
|
78
|
-
setDataProvider(dataProvider: DataProvider): void;
|
|
67
|
+
dataProvider: DataProvider;
|
|
79
68
|
/** A helper callback that can be used to debug and trace all find operations. Useful in debugging scenarios */
|
|
80
69
|
static onFind: (metadata: EntityMetadata, options: FindOptions<any>) => void;
|
|
81
70
|
clearAllCache(): any;
|
|
82
71
|
/** A helper callback that is called whenever an entity is created. */
|
|
83
72
|
static entityRefInit?: (ref: EntityRef<any>, row: any) => void;
|
|
73
|
+
readonly context: RemultContext;
|
|
74
|
+
apiClient: ApiClient;
|
|
75
|
+
}
|
|
76
|
+
export interface RemultContext {
|
|
77
|
+
}
|
|
78
|
+
export interface ApiClient {
|
|
79
|
+
httpClient?: ExternalHttpProvider | typeof fetch;
|
|
80
|
+
url?: string;
|
|
84
81
|
}
|
|
85
82
|
export declare const allEntities: ClassType<any>[];
|
|
86
83
|
export interface ControllerOptions {
|
|
@@ -93,6 +90,7 @@ export declare class ClassHelper {
|
|
|
93
90
|
export declare class MethodHelper {
|
|
94
91
|
classes: Map<any, ControllerOptions>;
|
|
95
92
|
}
|
|
93
|
+
export declare function buildRestDataProvider(provider: ExternalHttpProvider | typeof fetch): RestDataProviderHttpProvider | RestDataProviderHttpProviderUsingFetch;
|
|
96
94
|
export declare function setControllerSettings(target: any, options: ControllerOptions): void;
|
|
97
95
|
export interface UserInfo {
|
|
98
96
|
id: string;
|
package/esm/src/context.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { actionInfo, serverActionField } from './server-action';
|
|
2
2
|
import { RestDataProvider, RestDataProviderHttpProviderUsingFetch } from './data-providers/rest-data-provider';
|
|
3
3
|
import { RepositoryImplementation } from "./remult3/RepositoryImplementation";
|
|
4
4
|
export class HttpProviderBridgeToRestDataProviderHttpProvider {
|
|
@@ -75,6 +75,8 @@ export async function processHttpException(ex) {
|
|
|
75
75
|
message: error,
|
|
76
76
|
};
|
|
77
77
|
}
|
|
78
|
+
if (z.modelState)
|
|
79
|
+
error.modelState = z.modelState;
|
|
78
80
|
let httpStatusCode = z.status;
|
|
79
81
|
if (httpStatusCode === undefined)
|
|
80
82
|
httpStatusCode = z.response?.status;
|
|
@@ -90,37 +92,31 @@ export function isBackend() {
|
|
|
90
92
|
return actionInfo.runningOnServer;
|
|
91
93
|
}
|
|
92
94
|
export class Remult {
|
|
93
|
-
/** Creates a new instance of the `remult` object.
|
|
94
|
-
*
|
|
95
|
-
* Can receive either an HttpProvider or a DataProvider as a parameter - which will be used to fetch data from.
|
|
96
|
-
*
|
|
97
|
-
* If no provider is specified, `fetch` will be used as an http provider
|
|
98
|
-
*/
|
|
99
95
|
constructor(provider) {
|
|
100
|
-
|
|
96
|
+
/* @internal */
|
|
101
97
|
this.repCache = new Map();
|
|
98
|
+
/** The current data provider */
|
|
99
|
+
this.dataProvider = new RestDataProvider(() => this.apiClient);
|
|
100
|
+
this.context = {};
|
|
101
|
+
this.apiClient = {
|
|
102
|
+
url: '/api'
|
|
103
|
+
};
|
|
102
104
|
if (provider && provider.getEntityDataProvider) {
|
|
103
|
-
this.
|
|
105
|
+
this.dataProvider = provider;
|
|
104
106
|
return;
|
|
105
107
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
let http = provider;
|
|
109
|
-
if (http && http.get && http.put && http.post && http.delete) {
|
|
110
|
-
dataProvider = new HttpProviderBridgeToRestDataProviderHttpProvider(http);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
if (!dataProvider) {
|
|
114
|
-
if (typeof provider === "function") {
|
|
115
|
-
dataProvider = new RestDataProviderHttpProviderUsingFetch(provider);
|
|
116
|
-
}
|
|
108
|
+
if (isExternalHttpProvider(provider)) {
|
|
109
|
+
this.apiClient.httpClient = provider;
|
|
117
110
|
}
|
|
118
|
-
if (
|
|
119
|
-
|
|
111
|
+
else if (typeof (provider) === "function")
|
|
112
|
+
this.apiClient.httpClient = provider;
|
|
113
|
+
else if (provider) {
|
|
114
|
+
const apiClient = provider;
|
|
115
|
+
if (apiClient.httpClient)
|
|
116
|
+
this.apiClient.httpClient = apiClient.httpClient;
|
|
117
|
+
if (apiClient.url)
|
|
118
|
+
this.apiClient.url = apiClient.url;
|
|
120
119
|
}
|
|
121
|
-
this._dataSource = new RestDataProvider(Remult.apiBaseUrl, dataProvider);
|
|
122
|
-
if (!Action.provider)
|
|
123
|
-
Action.provider = dataProvider;
|
|
124
120
|
}
|
|
125
121
|
/**Return's a `Repository` of the specific entity type
|
|
126
122
|
* @example
|
|
@@ -130,7 +126,7 @@ export class Remult {
|
|
|
130
126
|
*/
|
|
131
127
|
repo(entity, dataProvider) {
|
|
132
128
|
if (dataProvider === undefined)
|
|
133
|
-
dataProvider = this.
|
|
129
|
+
dataProvider = this.dataProvider;
|
|
134
130
|
let dpCache = this.repCache.get(dataProvider);
|
|
135
131
|
if (!dpCache)
|
|
136
132
|
this.repCache.set(dataProvider, dpCache = new Map());
|
|
@@ -140,39 +136,10 @@ export class Remult {
|
|
|
140
136
|
}
|
|
141
137
|
return r;
|
|
142
138
|
}
|
|
143
|
-
|
|
144
|
-
get user() {
|
|
145
|
-
if (this._user === undefined) {
|
|
146
|
-
return {
|
|
147
|
-
id: undefined,
|
|
148
|
-
name: '',
|
|
149
|
-
roles: []
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
return this._user;
|
|
153
|
-
}
|
|
154
|
-
/** Set's the current user info */
|
|
155
|
-
async setUser(info) {
|
|
156
|
-
this._user = info;
|
|
157
|
-
if (this._user === null)
|
|
158
|
-
this._user = undefined;
|
|
159
|
-
let auth = info;
|
|
160
|
-
if (auth) {
|
|
161
|
-
if (!this._user.id && auth.sub)
|
|
162
|
-
this._user.id = auth.sub;
|
|
163
|
-
if (!this._user.roles && auth.permissions) {
|
|
164
|
-
this._user.roles = auth.permissions;
|
|
165
|
-
}
|
|
166
|
-
if (!this._user.name)
|
|
167
|
-
this._user.name = auth.username;
|
|
168
|
-
}
|
|
169
|
-
if (this._user && !this._user.roles)
|
|
170
|
-
this._user.roles = [];
|
|
171
|
-
await this._userChangeEvent.fire();
|
|
172
|
-
}
|
|
139
|
+
/* delete me */
|
|
173
140
|
/** Checks if a user was authenticated */
|
|
174
141
|
authenticated() {
|
|
175
|
-
return this.user
|
|
142
|
+
return this.user?.id !== undefined;
|
|
176
143
|
}
|
|
177
144
|
/** checks if the user has any of the roles specified in the parameters
|
|
178
145
|
* @example
|
|
@@ -197,7 +164,7 @@ export class Remult {
|
|
|
197
164
|
if (typeof roles === 'boolean')
|
|
198
165
|
return roles;
|
|
199
166
|
if (typeof roles === 'string')
|
|
200
|
-
if (this.user
|
|
167
|
+
if (this.user?.roles?.indexOf(roles.toString()) >= 0)
|
|
201
168
|
return true;
|
|
202
169
|
return false;
|
|
203
170
|
}
|
|
@@ -220,25 +187,22 @@ export class Remult {
|
|
|
220
187
|
else
|
|
221
188
|
return this.isAllowed(allowed);
|
|
222
189
|
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
190
|
+
call(backendMethod, self) {
|
|
191
|
+
const z = (backendMethod[serverActionField]);
|
|
192
|
+
if (!z.doWork)
|
|
193
|
+
throw Error("The method received is not a valid backend method");
|
|
194
|
+
//@ts-ignore
|
|
195
|
+
return (...args) => {
|
|
196
|
+
return z.doWork(args, self, this.apiClient.url, buildRestDataProvider(this.apiClient.httpClient));
|
|
197
|
+
};
|
|
230
198
|
}
|
|
231
199
|
clearAllCache() {
|
|
232
200
|
this.repCache.clear();
|
|
233
201
|
}
|
|
234
202
|
}
|
|
235
|
-
/** The api Base Url to be used in all remult calls. by default it's set to `/api`.
|
|
236
|
-
*
|
|
237
|
-
* Set this property in case you want to determine a non relative api url
|
|
238
|
-
*/
|
|
239
|
-
Remult.apiBaseUrl = '/api';
|
|
240
203
|
/** A helper callback that can be used to debug and trace all find operations. Useful in debugging scenarios */
|
|
241
204
|
Remult.onFind = (metadata, options) => { };
|
|
205
|
+
;
|
|
242
206
|
export const allEntities = [];
|
|
243
207
|
export const classHelpers = new Map();
|
|
244
208
|
export class ClassHelper {
|
|
@@ -251,6 +215,28 @@ export class MethodHelper {
|
|
|
251
215
|
this.classes = new Map();
|
|
252
216
|
}
|
|
253
217
|
}
|
|
218
|
+
function isExternalHttpProvider(item) {
|
|
219
|
+
let http = item;
|
|
220
|
+
if (http && http.get && http.put && http.post && http.delete)
|
|
221
|
+
return true;
|
|
222
|
+
return false;
|
|
223
|
+
}
|
|
224
|
+
export function buildRestDataProvider(provider) {
|
|
225
|
+
if (!provider)
|
|
226
|
+
return new RestDataProviderHttpProviderUsingFetch();
|
|
227
|
+
let httpDataProvider;
|
|
228
|
+
if (!httpDataProvider) {
|
|
229
|
+
if (isExternalHttpProvider(provider)) {
|
|
230
|
+
httpDataProvider = new HttpProviderBridgeToRestDataProviderHttpProvider(provider);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
if (!httpDataProvider) {
|
|
234
|
+
if (typeof provider === "function") {
|
|
235
|
+
httpDataProvider = new RestDataProviderHttpProviderUsingFetch(provider);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return httpDataProvider;
|
|
239
|
+
}
|
|
254
240
|
export function setControllerSettings(target, options) {
|
|
255
241
|
let r = target;
|
|
256
242
|
while (true) {
|
|
@@ -2,10 +2,10 @@ import { EntityDataProvider, DataProvider, EntityDataProviderFindOptions, RestDa
|
|
|
2
2
|
import { UrlBuilder } from '../../urlBuilder';
|
|
3
3
|
import { Filter } from '../filter/filter-interfaces';
|
|
4
4
|
import { EntityMetadata } from '../remult3';
|
|
5
|
+
import { ApiClient } from '../context';
|
|
5
6
|
export declare class RestDataProvider implements DataProvider {
|
|
6
|
-
private
|
|
7
|
-
|
|
8
|
-
constructor(url: string, http: RestDataProviderHttpProvider);
|
|
7
|
+
private apiProvider;
|
|
8
|
+
constructor(apiProvider: () => ApiClient);
|
|
9
9
|
getEntityDataProvider(entity: EntityMetadata): EntityDataProvider;
|
|
10
10
|
transaction(action: (dataProvider: DataProvider) => Promise<void>): Promise<void>;
|
|
11
11
|
supportsCustomFilter: boolean;
|
|
@@ -14,7 +14,7 @@ export declare class RestEntityDataProvider implements EntityDataProvider {
|
|
|
14
14
|
private url;
|
|
15
15
|
private http;
|
|
16
16
|
private entity;
|
|
17
|
-
constructor(url: string, http: RestDataProviderHttpProvider, entity: EntityMetadata);
|
|
17
|
+
constructor(url: () => string, http: () => RestDataProviderHttpProvider, entity: EntityMetadata);
|
|
18
18
|
translateFromJson(row: any): {};
|
|
19
19
|
translateToJson(row: any): {};
|
|
20
20
|
count(where: Filter): Promise<number>;
|
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
import { UrlBuilder } from '../../urlBuilder';
|
|
2
2
|
import { customUrlToken } from '../filter/filter-interfaces';
|
|
3
|
-
import { retry } from '../context';
|
|
3
|
+
import { buildRestDataProvider, retry } from '../context';
|
|
4
4
|
export class RestDataProvider {
|
|
5
|
-
constructor(
|
|
6
|
-
this.
|
|
7
|
-
this.http = http;
|
|
5
|
+
constructor(apiProvider) {
|
|
6
|
+
this.apiProvider = apiProvider;
|
|
8
7
|
this.supportsCustomFilter = true;
|
|
9
8
|
}
|
|
10
9
|
getEntityDataProvider(entity) {
|
|
11
|
-
return new RestEntityDataProvider(
|
|
10
|
+
return new RestEntityDataProvider(() => {
|
|
11
|
+
let url = this.apiProvider()?.url;
|
|
12
|
+
if (url === undefined || url === null)
|
|
13
|
+
url = '/api';
|
|
14
|
+
return url + '/' + entity.key;
|
|
15
|
+
}, () => {
|
|
16
|
+
return buildRestDataProvider(this.apiProvider().httpClient);
|
|
17
|
+
}, entity);
|
|
12
18
|
}
|
|
13
19
|
async transaction(action) {
|
|
14
20
|
throw new Error("Method not implemented.");
|
|
@@ -35,7 +41,7 @@ export class RestEntityDataProvider {
|
|
|
35
41
|
return result;
|
|
36
42
|
}
|
|
37
43
|
async count(where) {
|
|
38
|
-
let url = new UrlBuilder(this.url);
|
|
44
|
+
let url = new UrlBuilder(this.url());
|
|
39
45
|
url.add("__action", "count");
|
|
40
46
|
let filterObject;
|
|
41
47
|
if (where) {
|
|
@@ -44,12 +50,12 @@ export class RestEntityDataProvider {
|
|
|
44
50
|
filterObject = undefined;
|
|
45
51
|
}
|
|
46
52
|
if (filterObject)
|
|
47
|
-
return this.http.post(url.url, filterObject).then(r => +(r.count));
|
|
53
|
+
return this.http().post(url.url, filterObject).then(r => +(r.count));
|
|
48
54
|
else
|
|
49
|
-
return this.http.get(url.url).then(r => +(r.count));
|
|
55
|
+
return this.http().get(url.url).then(r => +(r.count));
|
|
50
56
|
}
|
|
51
57
|
find(options) {
|
|
52
|
-
let url = new UrlBuilder(this.url);
|
|
58
|
+
let url = new UrlBuilder(this.url());
|
|
53
59
|
let filterObject;
|
|
54
60
|
if (options) {
|
|
55
61
|
if (options.where) {
|
|
@@ -78,10 +84,10 @@ export class RestEntityDataProvider {
|
|
|
78
84
|
}
|
|
79
85
|
if (filterObject) {
|
|
80
86
|
url.add("__action", "get");
|
|
81
|
-
return this.http.post(url.url, filterObject).then(x => x.map(y => this.translateFromJson(y)));
|
|
87
|
+
return this.http().post(url.url, filterObject).then(x => x.map(y => this.translateFromJson(y)));
|
|
82
88
|
}
|
|
83
89
|
else
|
|
84
|
-
return this.http.get(url.url).then(x => x.map(y => this.translateFromJson(y)));
|
|
90
|
+
return this.http().get(url.url).then(x => x.map(y => this.translateFromJson(y)));
|
|
85
91
|
;
|
|
86
92
|
}
|
|
87
93
|
update(id, data) {
|
|
@@ -91,13 +97,13 @@ export class RestEntityDataProvider {
|
|
|
91
97
|
if (keys.includes(col.key))
|
|
92
98
|
result[col.key] = col.valueConverter.toJson(data[col.key]);
|
|
93
99
|
}
|
|
94
|
-
return this.http.put(this.url + '/' + encodeURIComponent(id), result).then(y => this.translateFromJson(y));
|
|
100
|
+
return this.http().put(this.url() + '/' + encodeURIComponent(id), result).then(y => this.translateFromJson(y));
|
|
95
101
|
}
|
|
96
102
|
delete(id) {
|
|
97
|
-
return this.http.delete(this.url + '/' + encodeURIComponent(id));
|
|
103
|
+
return this.http().delete(this.url() + '/' + encodeURIComponent(id));
|
|
98
104
|
}
|
|
99
105
|
insert(data) {
|
|
100
|
-
return this.http.post(this.url, this.translateToJson(data)).then(y => this.translateFromJson(y));
|
|
106
|
+
return this.http().post(this.url(), this.translateToJson(data)).then(y => this.translateFromJson(y));
|
|
101
107
|
}
|
|
102
108
|
}
|
|
103
109
|
export class RestDataProviderHttpProviderUsingFetch {
|