remult 0.27.15 → 0.27.17
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/server/remult-api-server.js +2 -1
- package/esm/src/buildRestDataProvider.js +1 -1
- package/esm/src/context.js +14 -2
- package/esm/src/data-providers/rest-data-provider.js +6 -4
- package/esm/src/remult-proxy.js +3 -0
- package/esm/src/remult3/entity.js +10 -6
- package/esm/src/remult3/remult3.js +39 -0
- package/package.json +1 -1
- package/server/remult-api-server.js +4 -3
- package/src/buildRestDataProvider.js +1 -1
- package/src/context.d.ts +7 -0
- package/src/context.js +23 -1
- package/src/data-providers/rest-data-provider.d.ts +1 -0
- package/src/data-providers/rest-data-provider.js +7 -4
- package/src/remult-proxy.js +3 -0
- package/src/remult3/entity.js +10 -6
- package/src/remult3/remult3.js +39 -0
|
@@ -216,6 +216,7 @@ export class RemultServerImplementation {
|
|
|
216
216
|
r.route(this.options.rootPath + '/admin/').get(admin);
|
|
217
217
|
r.route(this.options.rootPath + '/admin').get(admin);
|
|
218
218
|
}
|
|
219
|
+
r.route(this.options.rootPath + '/me').get(this.process(async (remult, req, res) => res.success(remult.user ?? null)));
|
|
219
220
|
if (this.options.subscriptionServer instanceof SseSubscriptionServer) {
|
|
220
221
|
const streamPath = this.options.rootPath + '/' + streamUrl;
|
|
221
222
|
r.route(streamPath).get(this.process(async (remult, req, res, origReq, origRes) => {
|
|
@@ -332,7 +333,7 @@ export class RemultServerImplementation {
|
|
|
332
333
|
await what(remult, myReq, myRes, genReq, origRes, req);
|
|
333
334
|
}
|
|
334
335
|
finally {
|
|
335
|
-
remultStatic.asyncContext.setInInitRequest(false)
|
|
336
|
+
// remultStatic.asyncContext.setInInitRequest(false)
|
|
336
337
|
}
|
|
337
338
|
}
|
|
338
339
|
});
|
package/esm/src/context.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RestDataProvider } from './data-providers/rest-data-provider.js';
|
|
1
|
+
import { buildFullUrl, RestDataProvider, } from './data-providers/rest-data-provider.js';
|
|
2
2
|
import { LiveQueryClient } from './live-query/LiveQueryClient.js';
|
|
3
3
|
import { SseSubscriptionClient } from './live-query/SseSubscriptionClient.js';
|
|
4
4
|
import { remult } from './remult-proxy.js';
|
|
@@ -16,7 +16,7 @@ export class RemultAsyncLocalStorage {
|
|
|
16
16
|
if (r)
|
|
17
17
|
return r.remult;
|
|
18
18
|
else
|
|
19
|
-
throw new Error('remult object was requested outside of a valid context, try running
|
|
19
|
+
throw new Error('remult object was requested outside of a valid request cycle.valid context, try running `withRemult` or run within initApi or a remult request cycle');
|
|
20
20
|
};
|
|
21
21
|
}
|
|
22
22
|
static disable() {
|
|
@@ -76,6 +76,18 @@ export class Remult {
|
|
|
76
76
|
};
|
|
77
77
|
/** Returns the current user's info */
|
|
78
78
|
user;
|
|
79
|
+
/**
|
|
80
|
+
* Fetches user information from the backend and updates the `remult.user` object.
|
|
81
|
+
* Typically used during application initialization and user authentication.
|
|
82
|
+
*
|
|
83
|
+
* @returns {Promise<UserInfo | undefined>} A promise that resolves to the user's information or `undefined` if unavailable.
|
|
84
|
+
*/
|
|
85
|
+
async initUser() {
|
|
86
|
+
const dp = buildRestDataProvider(this.apiClient.httpClient);
|
|
87
|
+
const data = await dp.get(buildFullUrl(this.apiClient.url, 'me'));
|
|
88
|
+
this.user = data ?? undefined;
|
|
89
|
+
return this.user;
|
|
90
|
+
}
|
|
79
91
|
/** Checks if a user was authenticated */
|
|
80
92
|
authenticated() {
|
|
81
93
|
return this.user?.id !== undefined;
|
|
@@ -10,10 +10,7 @@ export class RestDataProvider {
|
|
|
10
10
|
}
|
|
11
11
|
getEntityDataProvider(entity) {
|
|
12
12
|
return new RestEntityDataProvider(() => {
|
|
13
|
-
|
|
14
|
-
if (url === undefined || url === null)
|
|
15
|
-
url = '/api';
|
|
16
|
-
return url + '/' + entity.key;
|
|
13
|
+
return buildFullUrl(this.apiProvider()?.url, entity.key);
|
|
17
14
|
}, () => {
|
|
18
15
|
return buildRestDataProvider(this.apiProvider().httpClient);
|
|
19
16
|
}, entity);
|
|
@@ -23,6 +20,11 @@ export class RestDataProvider {
|
|
|
23
20
|
}
|
|
24
21
|
isProxy = true;
|
|
25
22
|
}
|
|
23
|
+
export function buildFullUrl(httpClientUrl, entityKey) {
|
|
24
|
+
if (httpClientUrl === undefined || httpClientUrl === null)
|
|
25
|
+
httpClientUrl = '/api';
|
|
26
|
+
return httpClientUrl + '/' + entityKey;
|
|
27
|
+
}
|
|
26
28
|
//@internal
|
|
27
29
|
export function findOptionsToJson(options, meta) {
|
|
28
30
|
if (options.include) {
|
package/esm/src/remult-proxy.js
CHANGED
|
@@ -28,6 +28,9 @@ export class RemultProxy {
|
|
|
28
28
|
set liveQueryPublisher(val) {
|
|
29
29
|
remultStatic.remultFactory().liveQueryPublisher = val;
|
|
30
30
|
}
|
|
31
|
+
initUser() {
|
|
32
|
+
return remultStatic.remultFactory().initUser();
|
|
33
|
+
}
|
|
31
34
|
call(backendMethod, self, ...args) {
|
|
32
35
|
return remultStatic.remultFactory().call(backendMethod, self, ...args);
|
|
33
36
|
}
|
|
@@ -27,14 +27,18 @@ import { remultStatic } from '../remult-static.js';
|
|
|
27
27
|
*/
|
|
28
28
|
export function Entity(key, ...options) {
|
|
29
29
|
return (target, info) => {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
if (
|
|
34
|
-
|
|
35
|
-
|
|
30
|
+
let theClass = target;
|
|
31
|
+
while (theClass != null) {
|
|
32
|
+
for (const rawFilterMember in theClass) {
|
|
33
|
+
if (Object.prototype.hasOwnProperty.call(theClass, rawFilterMember)) {
|
|
34
|
+
const element = target[rawFilterMember];
|
|
35
|
+
if (element?.rawFilterInfo) {
|
|
36
|
+
if (!element.rawFilterInfo.key)
|
|
37
|
+
element.rawFilterInfo.key = rawFilterMember;
|
|
38
|
+
}
|
|
36
39
|
}
|
|
37
40
|
}
|
|
41
|
+
theClass = Object.getPrototypeOf(theClass);
|
|
38
42
|
}
|
|
39
43
|
let factory = (remult) => {
|
|
40
44
|
let r = {};
|
|
@@ -17,6 +17,45 @@ const wnn = [
|
|
|
17
17
|
export const flags = {
|
|
18
18
|
error500RetryCount: 4,
|
|
19
19
|
};
|
|
20
|
+
/*p1 - create-remult discussion
|
|
21
|
+
|
|
22
|
+
p1 - should we add to remult some init code that populates remult based on a built in server route for current user.
|
|
23
|
+
- yes, `remult.initUser` - the url will be /api/me
|
|
24
|
+
- ask to add a todo example
|
|
25
|
+
- admin question
|
|
26
|
+
- ask to add a user table + password hash
|
|
27
|
+
|
|
28
|
+
- changeOrigin false to vite config
|
|
29
|
+
- test angular with auth
|
|
30
|
+
- check nextauth if the env variable should be called NEXTAUTH_SECRET or just AUTH_SECRET
|
|
31
|
+
/** @type {import('next').NextConfig}
|
|
32
|
+
const nextConfig = {
|
|
33
|
+
experimental: {
|
|
34
|
+
serverComponentsExternalPackages: ["knex"],
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export default nextConfig;
|
|
39
|
+
|
|
40
|
+
p1 - Landing page:
|
|
41
|
+
- p2 include the selections (react,vite, postgres,auth)
|
|
42
|
+
- include server is alive test (remind to run dev-node)
|
|
43
|
+
- include the authenticated user with links to sign in & sign out
|
|
44
|
+
- include link to admin
|
|
45
|
+
- include todo
|
|
46
|
+
|
|
47
|
+
p1 - README:
|
|
48
|
+
- the selections
|
|
49
|
+
- how to run dev
|
|
50
|
+
- which environment variables to set
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
- should we add admin? ensureSchema:false etc...
|
|
54
|
+
- should we read existing database?
|
|
55
|
+
- knex issue with next
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
*/
|
|
20
59
|
//p1 - add aggregate to query
|
|
21
60
|
//p1 - add parameter all to deleteMany, and updateMany
|
|
22
61
|
//p1 filter.apply ApiPreFilter
|
package/package.json
CHANGED
|
@@ -378,6 +378,9 @@ var RemultServerImplementation = /** @class */ (function () {
|
|
|
378
378
|
r.route(this.options.rootPath + '/admin/').get(admin);
|
|
379
379
|
r.route(this.options.rootPath + '/admin').get(admin);
|
|
380
380
|
}
|
|
381
|
+
r.route(this.options.rootPath + '/me').get(this.process(function (remult, req, res) { return tslib_1.__awaiter(_this, void 0, void 0, function () { var _a; return tslib_1.__generator(this, function (_b) {
|
|
382
|
+
return [2 /*return*/, res.success((_a = remult.user) !== null && _a !== void 0 ? _a : null)];
|
|
383
|
+
}); }); }));
|
|
381
384
|
if (this.options.subscriptionServer instanceof SseSubscriptionServer_js_1.SseSubscriptionServer) {
|
|
382
385
|
var streamPath = this.options.rootPath + '/' + SubscriptionChannel_js_1.streamUrl;
|
|
383
386
|
r.route(streamPath).get(this.process(function (remult, req, res, origReq, origRes) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
@@ -629,9 +632,7 @@ var RemultServerImplementation = /** @class */ (function () {
|
|
|
629
632
|
case 7:
|
|
630
633
|
_a.sent();
|
|
631
634
|
return [3 /*break*/, 9];
|
|
632
|
-
case 8:
|
|
633
|
-
remult_static_js_1.remultStatic.asyncContext.setInInitRequest(false);
|
|
634
|
-
return [7 /*endfinally*/];
|
|
635
|
+
case 8: return [7 /*endfinally*/];
|
|
635
636
|
case 9: return [2 /*return*/];
|
|
636
637
|
}
|
|
637
638
|
});
|
package/src/context.d.ts
CHANGED
|
@@ -37,6 +37,13 @@ export declare class Remult {
|
|
|
37
37
|
repo: <T>(entity: ClassType<T>, dataProvider?: DataProvider) => Repository<T>;
|
|
38
38
|
/** Returns the current user's info */
|
|
39
39
|
user?: UserInfo;
|
|
40
|
+
/**
|
|
41
|
+
* Fetches user information from the backend and updates the `remult.user` object.
|
|
42
|
+
* Typically used during application initialization and user authentication.
|
|
43
|
+
*
|
|
44
|
+
* @returns {Promise<UserInfo | undefined>} A promise that resolves to the user's information or `undefined` if unavailable.
|
|
45
|
+
*/
|
|
46
|
+
initUser(): Promise<UserInfo | undefined>;
|
|
40
47
|
/** Checks if a user was authenticated */
|
|
41
48
|
authenticated(): boolean;
|
|
42
49
|
/** checks if the user has any of the roles specified in the parameters
|
package/src/context.js
CHANGED
|
@@ -26,7 +26,7 @@ var RemultAsyncLocalStorage = /** @class */ (function () {
|
|
|
26
26
|
if (r)
|
|
27
27
|
return r.remult;
|
|
28
28
|
else
|
|
29
|
-
throw new Error('remult object was requested outside of a valid context, try running
|
|
29
|
+
throw new Error('remult object was requested outside of a valid request cycle.valid context, try running `withRemult` or run within initApi or a remult request cycle');
|
|
30
30
|
};
|
|
31
31
|
};
|
|
32
32
|
RemultAsyncLocalStorage.disable = function () {
|
|
@@ -132,6 +132,28 @@ var Remult = /** @class */ (function () {
|
|
|
132
132
|
this.apiClient.wrapMessageHandling = apiClient.wrapMessageHandling;
|
|
133
133
|
}
|
|
134
134
|
}
|
|
135
|
+
/**
|
|
136
|
+
* Fetches user information from the backend and updates the `remult.user` object.
|
|
137
|
+
* Typically used during application initialization and user authentication.
|
|
138
|
+
*
|
|
139
|
+
* @returns {Promise<UserInfo | undefined>} A promise that resolves to the user's information or `undefined` if unavailable.
|
|
140
|
+
*/
|
|
141
|
+
Remult.prototype.initUser = function () {
|
|
142
|
+
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
143
|
+
var dp, data;
|
|
144
|
+
return tslib_1.__generator(this, function (_a) {
|
|
145
|
+
switch (_a.label) {
|
|
146
|
+
case 0:
|
|
147
|
+
dp = (0, buildRestDataProvider_js_1.buildRestDataProvider)(this.apiClient.httpClient);
|
|
148
|
+
return [4 /*yield*/, dp.get((0, rest_data_provider_js_1.buildFullUrl)(this.apiClient.url, 'me'))];
|
|
149
|
+
case 1:
|
|
150
|
+
data = _a.sent();
|
|
151
|
+
this.user = data !== null && data !== void 0 ? data : undefined;
|
|
152
|
+
return [2 /*return*/, this.user];
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
};
|
|
135
157
|
/** Checks if a user was authenticated */
|
|
136
158
|
Remult.prototype.authenticated = function () {
|
|
137
159
|
var _a;
|
|
@@ -10,6 +10,7 @@ export declare class RestDataProvider implements DataProvider {
|
|
|
10
10
|
transaction(action: (dataProvider: DataProvider) => Promise<void>): Promise<void>;
|
|
11
11
|
isProxy: boolean;
|
|
12
12
|
}
|
|
13
|
+
export declare function buildFullUrl(httpClientUrl: string | undefined, entityKey: string): string;
|
|
13
14
|
export declare class RestEntityDataProvider implements EntityDataProvider, ProxyEntityDataProvider {
|
|
14
15
|
private url;
|
|
15
16
|
private http;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.liveQueryAction = exports.RestDataProviderHttpProviderUsingFetch = exports.RestEntityDataProvider = exports.RestDataProvider = void 0;
|
|
4
|
+
exports.buildFullUrl = buildFullUrl;
|
|
4
5
|
exports.findOptionsToJson = findOptionsToJson;
|
|
5
6
|
exports.findOptionsFromJson = findOptionsFromJson;
|
|
6
7
|
exports.addFilterToUrlAndReturnTrueIfSuccessful = addFilterToUrlAndReturnTrueIfSuccessful;
|
|
@@ -19,10 +20,7 @@ var RestDataProvider = /** @class */ (function () {
|
|
|
19
20
|
var _this = this;
|
|
20
21
|
return new RestEntityDataProvider(function () {
|
|
21
22
|
var _a;
|
|
22
|
-
|
|
23
|
-
if (url === undefined || url === null)
|
|
24
|
-
url = '/api';
|
|
25
|
-
return url + '/' + entity.key;
|
|
23
|
+
return buildFullUrl((_a = _this.apiProvider()) === null || _a === void 0 ? void 0 : _a.url, entity.key);
|
|
26
24
|
}, function () {
|
|
27
25
|
return (0, buildRestDataProvider_js_1.buildRestDataProvider)(_this.apiProvider().httpClient);
|
|
28
26
|
}, entity);
|
|
@@ -37,6 +35,11 @@ var RestDataProvider = /** @class */ (function () {
|
|
|
37
35
|
return RestDataProvider;
|
|
38
36
|
}());
|
|
39
37
|
exports.RestDataProvider = RestDataProvider;
|
|
38
|
+
function buildFullUrl(httpClientUrl, entityKey) {
|
|
39
|
+
if (httpClientUrl === undefined || httpClientUrl === null)
|
|
40
|
+
httpClientUrl = '/api';
|
|
41
|
+
return httpClientUrl + '/' + entityKey;
|
|
42
|
+
}
|
|
40
43
|
//@internal
|
|
41
44
|
function findOptionsToJson(options, meta) {
|
|
42
45
|
if (options.include) {
|
package/src/remult-proxy.js
CHANGED
|
@@ -284,6 +284,9 @@ var RemultProxy = /** @class */ (function () {
|
|
|
284
284
|
enumerable: false,
|
|
285
285
|
configurable: true
|
|
286
286
|
});
|
|
287
|
+
RemultProxy.prototype.initUser = function () {
|
|
288
|
+
return remult_static_js_1.remultStatic.remultFactory().initUser();
|
|
289
|
+
};
|
|
287
290
|
RemultProxy.prototype.call = function (backendMethod, self) {
|
|
288
291
|
var _a;
|
|
289
292
|
var args = [];
|
package/src/remult3/entity.js
CHANGED
|
@@ -35,14 +35,18 @@ function Entity(key) {
|
|
|
35
35
|
options[_i - 1] = arguments[_i];
|
|
36
36
|
}
|
|
37
37
|
return function (target, info) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
if (
|
|
42
|
-
|
|
43
|
-
|
|
38
|
+
var theClass = target;
|
|
39
|
+
while (theClass != null) {
|
|
40
|
+
for (var rawFilterMember in theClass) {
|
|
41
|
+
if (Object.prototype.hasOwnProperty.call(theClass, rawFilterMember)) {
|
|
42
|
+
var element = target[rawFilterMember];
|
|
43
|
+
if (element === null || element === void 0 ? void 0 : element.rawFilterInfo) {
|
|
44
|
+
if (!element.rawFilterInfo.key)
|
|
45
|
+
element.rawFilterInfo.key = rawFilterMember;
|
|
46
|
+
}
|
|
44
47
|
}
|
|
45
48
|
}
|
|
49
|
+
theClass = Object.getPrototypeOf(theClass);
|
|
46
50
|
}
|
|
47
51
|
var factory = function (remult) {
|
|
48
52
|
var e_1, _a;
|
package/src/remult3/remult3.js
CHANGED
|
@@ -20,6 +20,45 @@ var wnn = [
|
|
|
20
20
|
exports.flags = {
|
|
21
21
|
error500RetryCount: 4,
|
|
22
22
|
};
|
|
23
|
+
/*p1 - create-remult discussion
|
|
24
|
+
|
|
25
|
+
p1 - should we add to remult some init code that populates remult based on a built in server route for current user.
|
|
26
|
+
- yes, `remult.initUser` - the url will be /api/me
|
|
27
|
+
- ask to add a todo example
|
|
28
|
+
- admin question
|
|
29
|
+
- ask to add a user table + password hash
|
|
30
|
+
|
|
31
|
+
- changeOrigin false to vite config
|
|
32
|
+
- test angular with auth
|
|
33
|
+
- check nextauth if the env variable should be called NEXTAUTH_SECRET or just AUTH_SECRET
|
|
34
|
+
/** @type {import('next').NextConfig}
|
|
35
|
+
const nextConfig = {
|
|
36
|
+
experimental: {
|
|
37
|
+
serverComponentsExternalPackages: ["knex"],
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export default nextConfig;
|
|
42
|
+
|
|
43
|
+
p1 - Landing page:
|
|
44
|
+
- p2 include the selections (react,vite, postgres,auth)
|
|
45
|
+
- include server is alive test (remind to run dev-node)
|
|
46
|
+
- include the authenticated user with links to sign in & sign out
|
|
47
|
+
- include link to admin
|
|
48
|
+
- include todo
|
|
49
|
+
|
|
50
|
+
p1 - README:
|
|
51
|
+
- the selections
|
|
52
|
+
- how to run dev
|
|
53
|
+
- which environment variables to set
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
- should we add admin? ensureSchema:false etc...
|
|
57
|
+
- should we read existing database?
|
|
58
|
+
- knex issue with next
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
*/
|
|
23
62
|
//p1 - add aggregate to query
|
|
24
63
|
//p1 - add parameter all to deleteMany, and updateMany
|
|
25
64
|
//p1 filter.apply ApiPreFilter
|