remult 0.14.12 → 0.14.15

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.
@@ -33,9 +33,10 @@ class MongoEntityDataProvider {
33
33
  translateFromJson(row, nameProvider) {
34
34
  let result = {};
35
35
  for (const col of this.entity.fields) {
36
- result[col.key] = col.valueConverter.fromDb(row[nameProvider.nameOf(col)]);
37
- if (isNull(result[col.key]))
38
- result[col.key] = null;
36
+ let val = row[nameProvider.nameOf(col)];
37
+ if (isNull(val))
38
+ val = null;
39
+ result[col.key] = col.valueConverter.fromDb(val);
39
40
  }
40
41
  return result;
41
42
  }
@@ -39,12 +39,9 @@ export interface GenericRequest {
39
39
  params: any;
40
40
  }
41
41
  export interface GenericResponse {
42
- status(arg0: number): any;
43
- statusCode: number;
44
42
  json(data: any): any;
45
- writeHead(status: number): {
46
- end: VoidFunction;
47
- };
43
+ statusCode: number;
44
+ end(): any;
48
45
  }
49
46
  export declare type GenericRouter = GenericRequestHandler & {
50
47
  route(path: string): SpecificRoute;
@@ -482,7 +482,8 @@ class ExpressResponseBridgeToDataApiResponse {
482
482
  this.sendStatus(403);
483
483
  }
484
484
  sendStatus(status) {
485
- this.r.writeHead(status).end();
485
+ this.r.statusCode = status;
486
+ this.r.end();
486
487
  }
487
488
  progress(progress) {
488
489
  }
@@ -507,7 +508,8 @@ class ExpressResponseBridgeToDataApiResponse {
507
508
  url: this.req.originalUrl ?? this.req.path,
508
509
  method: this.req.method
509
510
  });
510
- this.r.status(400).json(data);
511
+ this.r.statusCode = 400;
512
+ this.r.json(data);
511
513
  }
512
514
  }
513
515
  function throwError() {
@@ -0,0 +1,6 @@
1
+ export declare class Task {
2
+ id: string;
3
+ title: string;
4
+ completed: boolean;
5
+ static testForbidden(): void;
6
+ }
@@ -0,0 +1,115 @@
1
+ import { __decorate, __metadata } from "tslib";
2
+ import axios from 'axios';
3
+ import { HttpProviderBridgeToRestDataProviderHttpProvider, Remult } from '../context';
4
+ import { Entity, Fields } from '../remult3';
5
+ import { Action, BackendMethod } from '../server-action';
6
+ Remult.apiBaseUrl = 'http://localhost:3001/api';
7
+ const path = Remult.apiBaseUrl + '/tasks';
8
+ fit("works", async () => {
9
+ const repo = await create3Tasks();
10
+ const tasks = await repo.find({ where: { completed: true } });
11
+ expect(tasks.length).toBe(1);
12
+ await repo.save({ ...tasks[0], completed: false });
13
+ expect(await repo.count({ completed: true })).toBe(0);
14
+ });
15
+ fit("test multiple items", async () => {
16
+ const repo = await create3Tasks();
17
+ expect(await repo.count({
18
+ title: { "!=": ["a", "c"] }
19
+ })).toBe(1);
20
+ });
21
+ fit("validation", async () => {
22
+ const r = await create3Tasks();
23
+ let err = undefined;
24
+ try {
25
+ await r.insert({ "title": "" });
26
+ }
27
+ catch (error) {
28
+ err = error;
29
+ }
30
+ expect(err).toEqual({
31
+ message: "Title: Should not be empty",
32
+ httpStatusCode: 400,
33
+ modelState: {
34
+ title: "Should not be empty"
35
+ }
36
+ });
37
+ });
38
+ fit("forbidden", async () => {
39
+ let err = undefined;
40
+ try {
41
+ await Task.testForbidden();
42
+ }
43
+ catch (error) {
44
+ err = error;
45
+ }
46
+ expect(err.httpStatusCode).toEqual(403);
47
+ });
48
+ fit("test http 404", async () => {
49
+ const repo = create3Tasks();
50
+ const task = await (await repo).findFirst();
51
+ let result = await axios.get(path + "/" + task.id);
52
+ expect(result.data.id).toBe(task.id);
53
+ expect(result.status).toBe(200);
54
+ let error = undefined;
55
+ try {
56
+ result = await axios.get(path + "/123");
57
+ }
58
+ catch (err) {
59
+ error = err;
60
+ }
61
+ expect(error.response.status).toBe(404);
62
+ });
63
+ fit("test http 201", async () => {
64
+ let result = await axios.post('http://localhost:3001/api/tasks', { title: "z", id: "" });
65
+ expect(result.data.title).toBe("z");
66
+ expect(result.status).toBe(201);
67
+ result = await axios.delete(path + "/" + result.data.id);
68
+ expect(result.status).toBe(204);
69
+ });
70
+ let Task = class Task {
71
+ constructor() {
72
+ this.title = '';
73
+ this.completed = false;
74
+ }
75
+ static testForbidden() {
76
+ }
77
+ };
78
+ __decorate([
79
+ Fields.uuid(),
80
+ __metadata("design:type", String)
81
+ ], Task.prototype, "id", void 0);
82
+ __decorate([
83
+ Fields.string({
84
+ // validate: Validators.required should only be on backend
85
+ }),
86
+ __metadata("design:type", Object)
87
+ ], Task.prototype, "title", void 0);
88
+ __decorate([
89
+ Fields.boolean(),
90
+ __metadata("design:type", Object)
91
+ ], Task.prototype, "completed", void 0);
92
+ __decorate([
93
+ BackendMethod({ allowed: false }),
94
+ __metadata("design:type", Function),
95
+ __metadata("design:paramtypes", []),
96
+ __metadata("design:returntype", void 0)
97
+ ], Task, "testForbidden", null);
98
+ Task = __decorate([
99
+ Entity("tasks", {
100
+ allowApiCrud: true
101
+ })
102
+ ], Task);
103
+ export { Task };
104
+ async function create3Tasks() {
105
+ const remult = new Remult(axios);
106
+ Action.provider = new HttpProviderBridgeToRestDataProviderHttpProvider(axios);
107
+ const taskRepo = remult.repo(Task);
108
+ for (const task of await taskRepo.find()) {
109
+ await taskRepo.delete(task);
110
+ }
111
+ expect(await taskRepo.count()).toBe(0);
112
+ await taskRepo.insert([{ title: "a" }, { title: "b", completed: true }, { title: "c" }]);
113
+ expect(await taskRepo.count()).toBe(3);
114
+ return taskRepo;
115
+ }
@@ -1,5 +1,4 @@
1
1
  import { __decorate, __metadata } from "tslib";
2
- import { SqlDatabase } from "../data-providers/sql-database";
3
2
  import { Entity, EntityBase, Field, Fields } from "../remult3";
4
3
  import { testAll } from "./db-tests-setup";
5
4
  let testNull = class testNull extends EntityBase {
@@ -42,6 +41,5 @@ testAll("test number with null", async ({ createEntity }) => {
42
41
  i.numberWithNull = 0;
43
42
  await i.save();
44
43
  expect(i.numberWithNull).toBe(0);
45
- SqlDatabase.LogToConsole = true;
46
44
  expect(await r.count({ numberWithNull: null })).toBe(0);
47
45
  }, false);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "remult",
3
- "version": "0.14.12",
3
+ "version": "0.14.15",
4
4
  "description": "A CRUD framework for full-stack TypeScript",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
File without changes
package/remult-mongo.js CHANGED
@@ -60,9 +60,10 @@ var MongoEntityDataProvider = /** @class */ (function () {
60
60
  try {
61
61
  for (var _b = tslib_1.__values(this.entity.fields), _c = _b.next(); !_c.done; _c = _b.next()) {
62
62
  var col = _c.value;
63
- result[col.key] = col.valueConverter.fromDb(row[nameProvider.nameOf(col)]);
64
- if (isNull(result[col.key]))
65
- result[col.key] = null;
63
+ var val = row[nameProvider.nameOf(col)];
64
+ if (isNull(val))
65
+ val = null;
66
+ result[col.key] = col.valueConverter.fromDb(val);
66
67
  }
67
68
  }
68
69
  catch (e_1_1) { e_1 = { error: e_1_1 }; }
@@ -39,12 +39,9 @@ export interface GenericRequest {
39
39
  params: any;
40
40
  }
41
41
  export interface GenericResponse {
42
- status(arg0: number): any;
43
- statusCode: number;
44
42
  json(data: any): any;
45
- writeHead(status: number): {
46
- end: VoidFunction;
47
- };
43
+ statusCode: number;
44
+ end(): any;
48
45
  }
49
46
  export declare type GenericRouter = GenericRequestHandler & {
50
47
  route(path: string): SpecificRoute;
@@ -580,7 +580,8 @@ var ExpressResponseBridgeToDataApiResponse = /** @class */ (function () {
580
580
  this.sendStatus(403);
581
581
  };
582
582
  ExpressResponseBridgeToDataApiResponse.prototype.sendStatus = function (status) {
583
- this.r.writeHead(status).end();
583
+ this.r.statusCode = status;
584
+ this.r.end();
584
585
  };
585
586
  ExpressResponseBridgeToDataApiResponse.prototype.progress = function (progress) {
586
587
  };
@@ -606,7 +607,8 @@ var ExpressResponseBridgeToDataApiResponse = /** @class */ (function () {
606
607
  url: (_b = this.req.originalUrl) !== null && _b !== void 0 ? _b : this.req.path,
607
608
  method: this.req.method
608
609
  });
609
- this.r.status(400).json(data);
610
+ this.r.statusCode = 400;
611
+ this.r.json(data);
610
612
  };
611
613
  return ExpressResponseBridgeToDataApiResponse;
612
614
  }());
@@ -0,0 +1,6 @@
1
+ export declare class Task {
2
+ id: string;
3
+ title: string;
4
+ completed: boolean;
5
+ static testForbidden(): void;
6
+ }
@@ -0,0 +1,243 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Task = void 0;
4
+ var tslib_1 = require("tslib");
5
+ var axios_1 = require("axios");
6
+ var context_1 = require("../context");
7
+ var remult3_1 = require("../remult3");
8
+ var server_action_1 = require("../server-action");
9
+ context_1.Remult.apiBaseUrl = 'http://localhost:3001/api';
10
+ var path = context_1.Remult.apiBaseUrl + '/tasks';
11
+ fit("works", function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
12
+ var repo, tasks, _a;
13
+ return tslib_1.__generator(this, function (_b) {
14
+ switch (_b.label) {
15
+ case 0: return [4 /*yield*/, create3Tasks()];
16
+ case 1:
17
+ repo = _b.sent();
18
+ return [4 /*yield*/, repo.find({ where: { completed: true } })];
19
+ case 2:
20
+ tasks = _b.sent();
21
+ expect(tasks.length).toBe(1);
22
+ return [4 /*yield*/, repo.save(tslib_1.__assign(tslib_1.__assign({}, tasks[0]), { completed: false }))];
23
+ case 3:
24
+ _b.sent();
25
+ _a = expect;
26
+ return [4 /*yield*/, repo.count({ completed: true })];
27
+ case 4:
28
+ _a.apply(void 0, [_b.sent()]).toBe(0);
29
+ return [2 /*return*/];
30
+ }
31
+ });
32
+ }); });
33
+ fit("test multiple items", function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
34
+ var repo, _a;
35
+ return tslib_1.__generator(this, function (_b) {
36
+ switch (_b.label) {
37
+ case 0: return [4 /*yield*/, create3Tasks()];
38
+ case 1:
39
+ repo = _b.sent();
40
+ _a = expect;
41
+ return [4 /*yield*/, repo.count({
42
+ title: { "!=": ["a", "c"] }
43
+ })];
44
+ case 2:
45
+ _a.apply(void 0, [_b.sent()]).toBe(1);
46
+ return [2 /*return*/];
47
+ }
48
+ });
49
+ }); });
50
+ fit("validation", function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
51
+ var r, err, error_1;
52
+ return tslib_1.__generator(this, function (_a) {
53
+ switch (_a.label) {
54
+ case 0: return [4 /*yield*/, create3Tasks()];
55
+ case 1:
56
+ r = _a.sent();
57
+ err = undefined;
58
+ _a.label = 2;
59
+ case 2:
60
+ _a.trys.push([2, 4, , 5]);
61
+ return [4 /*yield*/, r.insert({ "title": "" })];
62
+ case 3:
63
+ _a.sent();
64
+ return [3 /*break*/, 5];
65
+ case 4:
66
+ error_1 = _a.sent();
67
+ err = error_1;
68
+ return [3 /*break*/, 5];
69
+ case 5:
70
+ expect(err).toEqual({
71
+ message: "Title: Should not be empty",
72
+ httpStatusCode: 400,
73
+ modelState: {
74
+ title: "Should not be empty"
75
+ }
76
+ });
77
+ return [2 /*return*/];
78
+ }
79
+ });
80
+ }); });
81
+ fit("forbidden", function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
82
+ var err, error_2;
83
+ return tslib_1.__generator(this, function (_a) {
84
+ switch (_a.label) {
85
+ case 0:
86
+ err = undefined;
87
+ _a.label = 1;
88
+ case 1:
89
+ _a.trys.push([1, 3, , 4]);
90
+ return [4 /*yield*/, Task.testForbidden()];
91
+ case 2:
92
+ _a.sent();
93
+ return [3 /*break*/, 4];
94
+ case 3:
95
+ error_2 = _a.sent();
96
+ err = error_2;
97
+ return [3 /*break*/, 4];
98
+ case 4:
99
+ expect(err.httpStatusCode).toEqual(403);
100
+ return [2 /*return*/];
101
+ }
102
+ });
103
+ }); });
104
+ fit("test http 404", function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
105
+ var repo, task, result, error, err_1;
106
+ return tslib_1.__generator(this, function (_a) {
107
+ switch (_a.label) {
108
+ case 0:
109
+ repo = create3Tasks();
110
+ return [4 /*yield*/, repo];
111
+ case 1: return [4 /*yield*/, (_a.sent()).findFirst()];
112
+ case 2:
113
+ task = _a.sent();
114
+ return [4 /*yield*/, axios_1.default.get(path + "/" + task.id)];
115
+ case 3:
116
+ result = _a.sent();
117
+ expect(result.data.id).toBe(task.id);
118
+ expect(result.status).toBe(200);
119
+ error = undefined;
120
+ _a.label = 4;
121
+ case 4:
122
+ _a.trys.push([4, 6, , 7]);
123
+ return [4 /*yield*/, axios_1.default.get(path + "/123")];
124
+ case 5:
125
+ result = _a.sent();
126
+ return [3 /*break*/, 7];
127
+ case 6:
128
+ err_1 = _a.sent();
129
+ error = err_1;
130
+ return [3 /*break*/, 7];
131
+ case 7:
132
+ expect(error.response.status).toBe(404);
133
+ return [2 /*return*/];
134
+ }
135
+ });
136
+ }); });
137
+ fit("test http 201", function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
138
+ var result;
139
+ return tslib_1.__generator(this, function (_a) {
140
+ switch (_a.label) {
141
+ case 0: return [4 /*yield*/, axios_1.default.post('http://localhost:3001/api/tasks', { title: "z", id: "" })];
142
+ case 1:
143
+ result = _a.sent();
144
+ expect(result.data.title).toBe("z");
145
+ expect(result.status).toBe(201);
146
+ return [4 /*yield*/, axios_1.default.delete(path + "/" + result.data.id)];
147
+ case 2:
148
+ result = _a.sent();
149
+ expect(result.status).toBe(204);
150
+ return [2 /*return*/];
151
+ }
152
+ });
153
+ }); });
154
+ var Task = /** @class */ (function () {
155
+ function Task() {
156
+ this.title = '';
157
+ this.completed = false;
158
+ }
159
+ Task.testForbidden = function () {
160
+ };
161
+ tslib_1.__decorate([
162
+ remult3_1.Fields.uuid(),
163
+ tslib_1.__metadata("design:type", String)
164
+ ], Task.prototype, "id", void 0);
165
+ tslib_1.__decorate([
166
+ remult3_1.Fields.string({
167
+ // validate: Validators.required should only be on backend
168
+ }),
169
+ tslib_1.__metadata("design:type", Object)
170
+ ], Task.prototype, "title", void 0);
171
+ tslib_1.__decorate([
172
+ remult3_1.Fields.boolean(),
173
+ tslib_1.__metadata("design:type", Object)
174
+ ], Task.prototype, "completed", void 0);
175
+ tslib_1.__decorate([
176
+ server_action_1.BackendMethod({ allowed: false }),
177
+ tslib_1.__metadata("design:type", Function),
178
+ tslib_1.__metadata("design:paramtypes", []),
179
+ tslib_1.__metadata("design:returntype", void 0)
180
+ ], Task, "testForbidden", null);
181
+ Task = tslib_1.__decorate([
182
+ remult3_1.Entity("tasks", {
183
+ allowApiCrud: true
184
+ })
185
+ ], Task);
186
+ return Task;
187
+ }());
188
+ exports.Task = Task;
189
+ function create3Tasks() {
190
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
191
+ var remult, taskRepo, _a, _b, task, e_1_1, _c, _d;
192
+ var e_1, _e;
193
+ return tslib_1.__generator(this, function (_f) {
194
+ switch (_f.label) {
195
+ case 0:
196
+ remult = new context_1.Remult(axios_1.default);
197
+ server_action_1.Action.provider = new context_1.HttpProviderBridgeToRestDataProviderHttpProvider(axios_1.default);
198
+ taskRepo = remult.repo(Task);
199
+ _f.label = 1;
200
+ case 1:
201
+ _f.trys.push([1, 7, 8, 9]);
202
+ return [4 /*yield*/, taskRepo.find()];
203
+ case 2:
204
+ _a = tslib_1.__values.apply(void 0, [_f.sent()]), _b = _a.next();
205
+ _f.label = 3;
206
+ case 3:
207
+ if (!!_b.done) return [3 /*break*/, 6];
208
+ task = _b.value;
209
+ return [4 /*yield*/, taskRepo.delete(task)];
210
+ case 4:
211
+ _f.sent();
212
+ _f.label = 5;
213
+ case 5:
214
+ _b = _a.next();
215
+ return [3 /*break*/, 3];
216
+ case 6: return [3 /*break*/, 9];
217
+ case 7:
218
+ e_1_1 = _f.sent();
219
+ e_1 = { error: e_1_1 };
220
+ return [3 /*break*/, 9];
221
+ case 8:
222
+ try {
223
+ if (_b && !_b.done && (_e = _a.return)) _e.call(_a);
224
+ }
225
+ finally { if (e_1) throw e_1.error; }
226
+ return [7 /*endfinally*/];
227
+ case 9:
228
+ _c = expect;
229
+ return [4 /*yield*/, taskRepo.count()];
230
+ case 10:
231
+ _c.apply(void 0, [_f.sent()]).toBe(0);
232
+ return [4 /*yield*/, taskRepo.insert([{ title: "a" }, { title: "b", completed: true }, { title: "c" }])];
233
+ case 11:
234
+ _f.sent();
235
+ _d = expect;
236
+ return [4 /*yield*/, taskRepo.count()];
237
+ case 12:
238
+ _d.apply(void 0, [_f.sent()]).toBe(3);
239
+ return [2 /*return*/, taskRepo];
240
+ }
241
+ });
242
+ });
243
+ }
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  var tslib_1 = require("tslib");
4
- var sql_database_1 = require("../data-providers/sql-database");
5
4
  var remult3_1 = require("../remult3");
6
5
  var db_tests_setup_1 = require("./db-tests-setup");
7
6
  var testNull = /** @class */ (function (_super) {
@@ -77,7 +76,6 @@ db_tests_setup_1.testAll("test number with null", function (_a) {
77
76
  case 4:
78
77
  _d.sent();
79
78
  expect(i.numberWithNull).toBe(0);
80
- sql_database_1.SqlDatabase.LogToConsole = true;
81
79
  _c = expect;
82
80
  return [4 /*yield*/, r.count({ numberWithNull: null })];
83
81
  case 5:
@@ -1,2 +0,0 @@
1
- import { FieldMetadata } from '../src/column-interfaces';
2
- export declare function postgresColumnSyntax(x: FieldMetadata, dbName: string): string;
@@ -1,30 +0,0 @@
1
- import { ValueConverters } from '../valueConverters';
2
- export function postgresColumnSyntax(x, dbName) {
3
- let result = dbName;
4
- if (x.valueType == Number) {
5
- if (!x.valueConverter.fieldTypeInDb)
6
- result += " numeric" + (x.allowNull ? "" : " default 0 not null");
7
- else
8
- result += " " + x.valueConverter.fieldTypeInDb + (x.allowNull ? "" : " default 0 not null");
9
- }
10
- else if (x.valueType == Date) {
11
- if (!x.valueConverter.fieldTypeInDb)
12
- if (x.valueConverter == ValueConverters.DateOnly)
13
- result += " date";
14
- else
15
- result += " timestamp";
16
- else
17
- result += " " + x.valueConverter.fieldTypeInDb;
18
- }
19
- else if (x.valueType == Boolean)
20
- result += " boolean" + (x.allowNull ? "" : " default false not null");
21
- else if (x.valueConverter.fieldTypeInDb) {
22
- result += " " + x.valueConverter.fieldTypeInDb;
23
- if (!x.allowNull && x.valueConverter.fieldTypeInDb == 'integer') {
24
- result += " default 0 not null";
25
- }
26
- }
27
- else
28
- result += " varchar" + (x.allowNull ? "" : " default '' not null");
29
- return result;
30
- }