remult 0.13.21 → 0.13.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/package.json +2 -3
- package/readme.md +45 -30
- package/server/expressBridge.d.ts +5 -4
- package/server/expressBridge.js +11 -5
- package/server/register-actions-on-server.d.ts +2 -1
- package/server/register-actions-on-server.js +36 -4
- package/server/register-entities-on-server.d.ts +2 -1
- package/server/register-entities-on-server.js +4 -2
- package/src/data-providers/web-sql-data-provider.d.ts +1 -1
- package/src/data-providers/web-sql-data-provider.js +3 -2
- package/src/remult3/RepositoryImplementation.d.ts +1 -1
- package/src/remult3/remult3.d.ts +2 -2
- package/src/server-action.d.ts +1 -0
- package/src/server-action.js +8 -3
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "remult",
|
|
3
|
-
"version": "0.13.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.13.24",
|
|
4
|
+
"description": "A CRUD framework for full-stack TypeScript",
|
|
5
5
|
"homepage": "https://remult.dev/",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -13,7 +13,6 @@
|
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"uuid": "^8.3.2",
|
|
16
|
-
"body-parser": "^1.18.3",
|
|
17
16
|
"reflect-metadata": "^0.1.13",
|
|
18
17
|
"tslib": "^2.3.1"
|
|
19
18
|
}
|
package/readme.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
</a>
|
|
5
5
|
<h1>Remult</h1>
|
|
6
6
|
<a href="https://circleci.com/gh/remult/remult/tree/master">
|
|
7
|
-
<img alt="CircleCI" src="https://circleci.com/gh/remult/remult/tree/master.svg?style=
|
|
7
|
+
<img alt="CircleCI" src="https://circleci.com/gh/remult/remult/tree/master.svg?style=shield">
|
|
8
8
|
</a>
|
|
9
9
|
<a href="https://codecov.io/gh/remult/remult">
|
|
10
10
|
<img src="https://codecov.io/gh/remult/remult/branch/master/graph/badge.svg?token=LYWQRUN3D1"/>
|
|
@@ -18,33 +18,36 @@
|
|
|
18
18
|
<a href="https://www.npmjs.com/package/remult">
|
|
19
19
|
<img alt="npm downloads" src="https://img.shields.io/npm/dm/remult">
|
|
20
20
|
</a>
|
|
21
|
-
<a href="https://
|
|
22
|
-
<img alt="
|
|
23
|
-
|
|
24
|
-
<a href="https://github.com/remult/remult/pulse" alt="Activity">
|
|
25
|
-
<img src="https://img.shields.io/github/commit-activity/m/remult/remult" /></a>
|
|
21
|
+
<a href="https://discord.gg/GXHk7ZfuG5">
|
|
22
|
+
<img alt="chat on discord" src="https://img.shields.io/badge/chat-on%20discord-blueviolet"/>
|
|
23
|
+
</a>
|
|
26
24
|
</div>
|
|
27
25
|
|
|
28
26
|
## What is Remult?
|
|
29
27
|
|
|
30
|
-
**Remult** is a
|
|
28
|
+
**Remult** is a full-stack CRUD framework that uses your TypeScript model types to provide:
|
|
31
29
|
|
|
32
30
|
* Secure REST API (highly configurable)
|
|
33
31
|
* Type-safe frontend API client
|
|
34
32
|
* Type-safe backend query builder
|
|
35
33
|
|
|
36
|
-
#### Remult :heart:
|
|
34
|
+
#### Remult :heart: Code Sharing
|
|
37
35
|
|
|
38
|
-
|
|
36
|
+
With model types shared between frontend and backend code, Remult can **enforce data validation and constraints, defined once, both in the front-end and witin back-end API routes**.
|
|
39
37
|
|
|
40
38
|
## Getting started
|
|
41
|
-
The best way to learn Remult is by following a tutorial of a simple Todo app with a Node.js Express backend.
|
|
39
|
+
The best way to learn Remult is by following a tutorial of a simple Todo web app with a Node.js Express backend.
|
|
40
|
+
|
|
41
|
+
* [Tutorial with React](https://remult.dev/tutorials/react/)
|
|
42
|
+
* [Tutorial with Angular](https://remult.dev/tutorials/angular/)
|
|
42
43
|
|
|
43
44
|
## Installation
|
|
44
45
|
```sh
|
|
45
46
|
npm i remult
|
|
46
47
|
```
|
|
47
48
|
|
|
49
|
+
## Usage
|
|
50
|
+
|
|
48
51
|
### Setup API backend using a Node.js Express middleware
|
|
49
52
|
```ts
|
|
50
53
|
import express from 'express';
|
|
@@ -60,14 +63,14 @@ app.listen(port, () => {
|
|
|
60
63
|
});
|
|
61
64
|
```
|
|
62
65
|
|
|
63
|
-
|
|
66
|
+
### Define model classes
|
|
64
67
|
```ts
|
|
65
|
-
import { Entity,
|
|
68
|
+
import { Entity, Fields } from 'remult';
|
|
66
69
|
|
|
67
70
|
@Entity('products', {
|
|
68
71
|
allowApiCrud: true
|
|
69
72
|
})
|
|
70
|
-
export class Product
|
|
73
|
+
export class Product {
|
|
71
74
|
@Fields.string()
|
|
72
75
|
name = '';
|
|
73
76
|
|
|
@@ -83,13 +86,14 @@ export class Product extends EntityBase {
|
|
|
83
86
|
[{"name":"Tofu","unitPrice":5}]
|
|
84
87
|
```
|
|
85
88
|
|
|
86
|
-
|
|
89
|
+
### Find and manipulate data in type-safe frontend code
|
|
87
90
|
```ts
|
|
88
91
|
async function increasePriceOfTofu(priceIncrease: number) {
|
|
89
|
-
const
|
|
92
|
+
const productsRepo = remult.repo(Product);
|
|
90
93
|
|
|
94
|
+
const product = await productsRepo.findFirst({ name: 'Tofu' });
|
|
91
95
|
product.unitPrice += priceIncrease;
|
|
92
|
-
|
|
96
|
+
productsRepo.save(product);
|
|
93
97
|
}
|
|
94
98
|
```
|
|
95
99
|
|
|
@@ -97,26 +101,27 @@ async function increasePriceOfTofu(priceIncrease: number) {
|
|
|
97
101
|
```ts
|
|
98
102
|
@BackendMethod({ allowed: Allow.authenticated })
|
|
99
103
|
static async increasePriceOfTofu(priceIncrease: number, remult?: Remult) {
|
|
100
|
-
const
|
|
104
|
+
const productsRepo = remult!.repo(Product);
|
|
101
105
|
|
|
106
|
+
const product = await productsRepo.findFirst({ name: 'Tofu' });
|
|
102
107
|
product.unitPrice += priceIncrease;
|
|
103
|
-
|
|
108
|
+
productsRepo.save(product);
|
|
104
109
|
}
|
|
105
110
|
```
|
|
106
111
|
|
|
107
|
-
|
|
112
|
+
### :ballot_box_with_check: Data validation and constraints - defined once
|
|
108
113
|
|
|
109
114
|
```ts
|
|
110
|
-
import { Entity,
|
|
115
|
+
import { Entity, Fields } from 'remult';
|
|
111
116
|
|
|
112
117
|
@Entity('products', {
|
|
113
118
|
allowApiCrud: true
|
|
114
119
|
})
|
|
115
|
-
export class Product
|
|
120
|
+
export class Product {
|
|
116
121
|
@Fields.string<Product>({
|
|
117
122
|
validate: product => {
|
|
118
123
|
if (product.name.trim().length == 0)
|
|
119
|
-
|
|
124
|
+
throw 'required';
|
|
120
125
|
}
|
|
121
126
|
})
|
|
122
127
|
name = '';
|
|
@@ -124,7 +129,7 @@ export class Product extends EntityBase {
|
|
|
124
129
|
@Fields.number({
|
|
125
130
|
validate: (_, field) => {
|
|
126
131
|
if (field.value < 0)
|
|
127
|
-
|
|
132
|
+
throw "must not be less than 0";
|
|
128
133
|
}
|
|
129
134
|
})
|
|
130
135
|
unitPrice = 0;
|
|
@@ -133,31 +138,31 @@ export class Product extends EntityBase {
|
|
|
133
138
|
|
|
134
139
|
### Enforced in frontend:
|
|
135
140
|
```ts
|
|
136
|
-
const product =
|
|
141
|
+
const product = productsRepo.create();
|
|
137
142
|
|
|
138
143
|
try {
|
|
139
|
-
await
|
|
144
|
+
await productsRepo.save(product);
|
|
140
145
|
}
|
|
141
|
-
catch {
|
|
142
|
-
console.error(
|
|
146
|
+
catch (e: any) {
|
|
147
|
+
console.error(e.message); // Browser console will display - "Name: required"
|
|
143
148
|
}
|
|
144
149
|
```
|
|
145
150
|
|
|
146
151
|
### Enforced in backend:
|
|
147
152
|
```sh
|
|
148
|
-
> curl
|
|
153
|
+
> curl http://localhost:3001/api/products -H "Content-Type: application/json" -d "{""unitPrice"":-1}"
|
|
149
154
|
|
|
150
155
|
{"modelState":{"unitPrice":"must not be less than 0","name":"required"},"message":"Name: required"}
|
|
151
156
|
```
|
|
152
157
|
|
|
153
|
-
|
|
158
|
+
### :lock: Secure the API with fine-grained authorization
|
|
154
159
|
```ts
|
|
155
160
|
@Entity<Article>('Articles', {
|
|
156
161
|
allowApiRead: true,
|
|
157
162
|
allowApiInsert: remult => remult.authenticated(),
|
|
158
163
|
allowApiUpdate: (remult, article) => article.author.id == remult.user.id
|
|
159
164
|
})
|
|
160
|
-
export class Article
|
|
165
|
+
export class Article {
|
|
161
166
|
@Fields.string({ allowApiUpdate: false })
|
|
162
167
|
slug = '';
|
|
163
168
|
|
|
@@ -168,3 +173,13 @@ export class Article extends EntityBase {
|
|
|
168
173
|
content = '';
|
|
169
174
|
}
|
|
170
175
|
```
|
|
176
|
+
|
|
177
|
+
## Example App
|
|
178
|
+
|
|
179
|
+
[CRM demo](https://github.com/remult/crm-demo) with a React + [MUI](https://mui.com) front-end and Postgres database.
|
|
180
|
+
|
|
181
|
+
## Contributing
|
|
182
|
+
Contributions are welcome. See [CONTRIBUTING](CONTRIBUTING.md).
|
|
183
|
+
|
|
184
|
+
## License
|
|
185
|
+
Remult is [MIT Licensed](LICENSE).
|
|
@@ -6,10 +6,10 @@ import { DataApi, DataApiRequest, DataApiResponse } from '../src/data-api';
|
|
|
6
6
|
import { AllowedForInstance } from '../src/context';
|
|
7
7
|
import { ClassType } from '../classType';
|
|
8
8
|
export declare function remultExpress(options?: {
|
|
9
|
-
/**
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
/** Sets a database connection for Remult.
|
|
10
|
+
*
|
|
11
|
+
* @see [Connecting to a Database](https://remult.dev/docs/databases.html).
|
|
12
|
+
*/
|
|
13
13
|
dataProvider?: DataProvider | Promise<DataProvider> | (() => Promise<DataProvider | undefined>);
|
|
14
14
|
bodySizeLimit?: string;
|
|
15
15
|
disableAutoApi?: boolean;
|
|
@@ -20,6 +20,7 @@ export declare function remultExpress(options?: {
|
|
|
20
20
|
defaultGetLimit?: number;
|
|
21
21
|
entities?: ClassType<any>[];
|
|
22
22
|
controllers?: ClassType<any>[];
|
|
23
|
+
bodyParser?: boolean;
|
|
23
24
|
}): RemultExpressBridge;
|
|
24
25
|
export interface RemultExpressBridge extends express.RequestHandler {
|
|
25
26
|
getRemult(req: express.Request): Promise<Remult>;
|
package/server/expressBridge.js
CHANGED
|
@@ -4,7 +4,6 @@ exports.JobsInQueueEntity = exports.EntityQueueStorage = exports.ExpressRequestB
|
|
|
4
4
|
var tslib_1 = require("tslib");
|
|
5
5
|
var __1 = require("../");
|
|
6
6
|
var express = require("express");
|
|
7
|
-
var bodyParser = require("body-parser");
|
|
8
7
|
var register_actions_on_server_1 = require("./register-actions-on-server");
|
|
9
8
|
var register_entities_on_server_1 = require("./register-entities-on-server");
|
|
10
9
|
var JsonEntityFileStorage_1 = require("./JsonEntityFileStorage");
|
|
@@ -29,8 +28,10 @@ function remultExpress(options) {
|
|
|
29
28
|
if (!options.queueStorage) {
|
|
30
29
|
options.queueStorage = new InMemoryQueueStorage();
|
|
31
30
|
}
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
if ((options === null || options === void 0 ? void 0 : options.bodyParser) !== false) {
|
|
32
|
+
app.use(express.json({ limit: options.bodySizeLimit }));
|
|
33
|
+
app.use(express.urlencoded({ extended: true, limit: options.bodySizeLimit }));
|
|
34
|
+
}
|
|
34
35
|
var dataProvider;
|
|
35
36
|
if (typeof options.dataProvider === "function") {
|
|
36
37
|
dataProvider = options.dataProvider();
|
|
@@ -62,8 +63,13 @@ function remultExpress(options) {
|
|
|
62
63
|
bridge.logApiEndPoints = options.logApiEndPoints;
|
|
63
64
|
var apiArea = bridge.addArea(__1.Remult.apiBaseUrl);
|
|
64
65
|
if (!options.disableAutoApi) {
|
|
65
|
-
|
|
66
|
-
|
|
66
|
+
var actions = [];
|
|
67
|
+
if (options.entities)
|
|
68
|
+
actions.push.apply(actions, tslib_1.__spread(options.entities));
|
|
69
|
+
if (options.controllers)
|
|
70
|
+
actions.push.apply(actions, tslib_1.__spread(options.controllers));
|
|
71
|
+
register_actions_on_server_1.registerActionsOnServer(apiArea, actions);
|
|
72
|
+
register_entities_on_server_1.registerEntitiesOnServer(apiArea, options.entities);
|
|
67
73
|
}
|
|
68
74
|
return Object.assign(app, {
|
|
69
75
|
getRemult: function (req) { return bridge.getRemult(req); },
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.registerActionsOnServer = void 0;
|
|
4
|
+
var tslib_1 = require("tslib");
|
|
4
5
|
var server_action_1 = require("../src/server-action");
|
|
5
|
-
function registerActionsOnServer(area) {
|
|
6
|
+
function registerActionsOnServer(area, controllers) {
|
|
7
|
+
var e_1, _a, e_2, _b;
|
|
6
8
|
var addAction = function (a) {
|
|
7
9
|
var x = a[server_action_1.serverActionField];
|
|
8
10
|
if (!x) {
|
|
@@ -11,8 +13,38 @@ function registerActionsOnServer(area) {
|
|
|
11
13
|
area.addAction(x);
|
|
12
14
|
};
|
|
13
15
|
server_action_1.actionInfo.runningOnServer = true;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
if (controllers && controllers.length > 0) {
|
|
17
|
+
try {
|
|
18
|
+
for (var controllers_1 = tslib_1.__values(controllers), controllers_1_1 = controllers_1.next(); !controllers_1_1.done; controllers_1_1 = controllers_1.next()) {
|
|
19
|
+
var c = controllers_1_1.value;
|
|
20
|
+
var z = c[server_action_1.classBackendMethodsArray];
|
|
21
|
+
if (z)
|
|
22
|
+
try {
|
|
23
|
+
for (var z_1 = (e_2 = void 0, tslib_1.__values(z)), z_1_1 = z_1.next(); !z_1_1.done; z_1_1 = z_1.next()) {
|
|
24
|
+
var a = z_1_1.value;
|
|
25
|
+
addAction(a);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
29
|
+
finally {
|
|
30
|
+
try {
|
|
31
|
+
if (z_1_1 && !z_1_1.done && (_b = z_1.return)) _b.call(z_1);
|
|
32
|
+
}
|
|
33
|
+
finally { if (e_2) throw e_2.error; }
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
38
|
+
finally {
|
|
39
|
+
try {
|
|
40
|
+
if (controllers_1_1 && !controllers_1_1.done && (_a = controllers_1.return)) _a.call(controllers_1);
|
|
41
|
+
}
|
|
42
|
+
finally { if (e_1) throw e_1.error; }
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
else
|
|
46
|
+
server_action_1.actionInfo.allActions.forEach(function (a) {
|
|
47
|
+
addAction(a);
|
|
48
|
+
});
|
|
17
49
|
}
|
|
18
50
|
exports.registerActionsOnServer = registerActionsOnServer;
|
|
@@ -4,9 +4,11 @@ exports.registerEntitiesOnServer = void 0;
|
|
|
4
4
|
var remult3_1 = require("../src/remult3");
|
|
5
5
|
var context_1 = require("../src/context");
|
|
6
6
|
var data_api_1 = require("../src/data-api");
|
|
7
|
-
function registerEntitiesOnServer(area) {
|
|
7
|
+
function registerEntitiesOnServer(area, entities) {
|
|
8
|
+
if (!entities)
|
|
9
|
+
entities = context_1.allEntities;
|
|
8
10
|
//add Api Entries
|
|
9
|
-
|
|
11
|
+
entities.forEach(function (e) {
|
|
10
12
|
var key = remult3_1.getEntityKey(e);
|
|
11
13
|
if (key != undefined)
|
|
12
14
|
area.add(key, function (c) {
|
|
@@ -6,7 +6,7 @@ export declare class WebSqlDataProvider implements SqlImplementation, __RowsOfDa
|
|
|
6
6
|
rows: {
|
|
7
7
|
[tableName: string]: any;
|
|
8
8
|
};
|
|
9
|
-
constructor(databaseName: string);
|
|
9
|
+
constructor(databaseName: string, databaseSize?: number);
|
|
10
10
|
getLimitSqlSyntax(limit: number, offset: number): string;
|
|
11
11
|
entityIsUsedForTheFirstTime(entity: EntityMetadata): Promise<void>;
|
|
12
12
|
dropTable(entity: EntityMetadata): Promise<void>;
|
|
@@ -7,10 +7,11 @@ var sql_database_1 = require("./sql-database");
|
|
|
7
7
|
var filter_consumer_bridge_to_sql_request_1 = require("../filter/filter-consumer-bridge-to-sql-request");
|
|
8
8
|
//SqlDatabase.LogToConsole = true;
|
|
9
9
|
var WebSqlDataProvider = /** @class */ (function () {
|
|
10
|
-
function WebSqlDataProvider(databaseName) {
|
|
10
|
+
function WebSqlDataProvider(databaseName, databaseSize) {
|
|
11
|
+
if (databaseSize === void 0) { databaseSize = 2 * 1024 * 1024; }
|
|
11
12
|
this.databaseName = databaseName;
|
|
12
13
|
//@ts-ignore
|
|
13
|
-
this.db = window.openDatabase(databaseName, '1.0', databaseName,
|
|
14
|
+
this.db = window.openDatabase(databaseName, '1.0', databaseName, databaseSize);
|
|
14
15
|
}
|
|
15
16
|
WebSqlDataProvider.prototype.getLimitSqlSyntax = function (limit, offset) {
|
|
16
17
|
return ' limit ' + limit + ' offset ' + offset;
|
|
@@ -224,7 +224,7 @@ export declare function isAutoIncrement(f: FieldMetadata): boolean;
|
|
|
224
224
|
export interface StringFieldOptions<entityType = any> extends FieldOptions<entityType, string> {
|
|
225
225
|
maxLength?: number;
|
|
226
226
|
}
|
|
227
|
-
export declare function ValueListFieldType<
|
|
227
|
+
export declare function ValueListFieldType<valueType extends ValueListItem = any>(...options: (ValueListFieldOptions<any, valueType> | ((options: FieldOptions<any, valueType>, remult: Remult) => void))[]): (type: ClassType<valueType>) => void;
|
|
228
228
|
export interface ValueListFieldOptions<entityType, valueType> extends FieldOptions<entityType, valueType> {
|
|
229
229
|
getValues?: () => valueType[];
|
|
230
230
|
}
|
package/src/remult3/remult3.d.ts
CHANGED
|
@@ -82,7 +82,7 @@ export interface FieldRef<entityType = any, valueType = any> extends Subscribabl
|
|
|
82
82
|
valueChanged(): boolean;
|
|
83
83
|
entityRef: EntityRef<entityType>;
|
|
84
84
|
container: entityType;
|
|
85
|
-
metadata: FieldMetadata<
|
|
85
|
+
metadata: FieldMetadata<valueType>;
|
|
86
86
|
load(): Promise<valueType>;
|
|
87
87
|
valueIsNull(): boolean;
|
|
88
88
|
originalValueIsNull(): boolean;
|
|
@@ -245,7 +245,7 @@ export interface FindOptionsBase<entityType> extends LoadOptions<entityType> {
|
|
|
245
245
|
/** filters the data
|
|
246
246
|
* @example
|
|
247
247
|
* await taskRepo.find({where: { completed:false }})
|
|
248
|
-
* @see For more usage examples see [EntityFilter](https://remult.
|
|
248
|
+
* @see For more usage examples see [EntityFilter](https://remult.dev/docs/entityFilter.html)
|
|
249
249
|
*/
|
|
250
250
|
where?: EntityFilter<entityType>;
|
|
251
251
|
/** Determines the order of items returned .
|
package/src/server-action.d.ts
CHANGED
|
@@ -66,4 +66,5 @@ export declare class ProgressListener {
|
|
|
66
66
|
}
|
|
67
67
|
export declare function prepareArgsToSend(types: any[], args: any[]): any[];
|
|
68
68
|
export declare function prepareReceivedArgs(types: any[], args: any[], remult: Remult, ds: DataProvider, res: DataApiResponse): Promise<any[]>;
|
|
69
|
+
export declare const classBackendMethodsArray: unique symbol;
|
|
69
70
|
export {};
|
package/src/server-action.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.prepareReceivedArgs = exports.prepareArgsToSend = exports.ProgressListener = exports.BackendMethod = exports.Controller = exports.serverActionField = exports.actionInfo = exports.myServerAction = exports.Action = void 0;
|
|
3
|
+
exports.classBackendMethodsArray = exports.prepareReceivedArgs = exports.prepareArgsToSend = exports.ProgressListener = exports.BackendMethod = exports.Controller = exports.serverActionField = exports.actionInfo = exports.myServerAction = exports.Action = void 0;
|
|
4
4
|
var tslib_1 = require("tslib");
|
|
5
5
|
require("reflect-metadata");
|
|
6
6
|
var context_1 = require("./context");
|
|
@@ -216,7 +216,7 @@ function BackendMethod(options) {
|
|
|
216
216
|
});
|
|
217
217
|
});
|
|
218
218
|
};
|
|
219
|
-
|
|
219
|
+
registerAction(target, descriptor);
|
|
220
220
|
descriptor.value[exports.serverActionField] = serverAction_1;
|
|
221
221
|
return descriptor;
|
|
222
222
|
}
|
|
@@ -479,7 +479,7 @@ function BackendMethod(options) {
|
|
|
479
479
|
});
|
|
480
480
|
});
|
|
481
481
|
};
|
|
482
|
-
|
|
482
|
+
registerAction(target.constructor, descriptor);
|
|
483
483
|
descriptor.value[exports.serverActionField] = serverAction;
|
|
484
484
|
return descriptor;
|
|
485
485
|
};
|
|
@@ -488,6 +488,10 @@ exports.BackendMethod = BackendMethod;
|
|
|
488
488
|
var customUndefined = {
|
|
489
489
|
_isUndefined: true
|
|
490
490
|
};
|
|
491
|
+
function registerAction(target, descriptor) {
|
|
492
|
+
(target[exports.classBackendMethodsArray] || (target[exports.classBackendMethodsArray] = [])).push(descriptor.value);
|
|
493
|
+
exports.actionInfo.allActions.push(descriptor.value);
|
|
494
|
+
}
|
|
491
495
|
function isCustomUndefined(x) {
|
|
492
496
|
return x && x._isUndefined;
|
|
493
497
|
}
|
|
@@ -592,3 +596,4 @@ function prepareReceivedArgs(types, args, remult, ds, res) {
|
|
|
592
596
|
});
|
|
593
597
|
}
|
|
594
598
|
exports.prepareReceivedArgs = prepareReceivedArgs;
|
|
599
|
+
exports.classBackendMethodsArray = Symbol('classBackendMethodsArray');
|