remult 3.0.1 → 3.0.3-next.0
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/remult-duckdb.js +76 -27
- package/esm/server/test-api-data-provider.js +31 -10
- package/package.json +1 -1
- package/remult-duckdb.d.ts +3 -2
- package/remult-duckdb.js +81 -31
- package/server/test-api-data-provider.d.ts +6 -0
- package/server/test-api-data-provider.js +67 -26
- package/src/column-interfaces.d.ts +4 -0
package/esm/remult-duckdb.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
+
import { DuckDBTypeId } from '@duckdb/node-api';
|
|
1
2
|
import { SqliteCoreDataProvider } from './remult-sqlite-core.js';
|
|
2
3
|
import { ValueConverters, dbNamesOf, } from './index.js';
|
|
3
4
|
import { shouldNotCreateField } from './src/filter/filter-consumer-bridge-to-sql-request.js';
|
|
4
5
|
import { isAutoIncrement } from './src/remult3/RepositoryImplementation.js';
|
|
5
6
|
export class DuckDBDataProvider extends SqliteCoreDataProvider {
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
connection;
|
|
8
|
+
constructor(connection) {
|
|
9
|
+
super(() => new DuckDBCommand(this.connection), async () => this.connection.disconnectSync(), false, true);
|
|
10
|
+
this.connection = connection;
|
|
8
11
|
}
|
|
9
12
|
wrapIdentifier(name) {
|
|
10
13
|
return `"${name}"`;
|
|
@@ -12,7 +15,8 @@ export class DuckDBDataProvider extends SqliteCoreDataProvider {
|
|
|
12
15
|
async getCreateTableSql(entity) {
|
|
13
16
|
let result = '';
|
|
14
17
|
let e = await dbNamesOf(entity, this.wrapIdentifier);
|
|
15
|
-
|
|
18
|
+
const createSequenceStatements = [];
|
|
19
|
+
let createTableSql = '';
|
|
16
20
|
for (const x of entity.fields) {
|
|
17
21
|
if (!shouldNotCreateField(x, e) || isAutoIncrement(x)) {
|
|
18
22
|
if (result.length != 0)
|
|
@@ -20,7 +24,7 @@ export class DuckDBDataProvider extends SqliteCoreDataProvider {
|
|
|
20
24
|
result += '\r\n ';
|
|
21
25
|
if (isAutoIncrement(x)) {
|
|
22
26
|
const sequenceName = `${entity.dbName}_${x.dbName}_seq`;
|
|
23
|
-
|
|
27
|
+
createSequenceStatements.push(`create sequence if not exists "${sequenceName}";`);
|
|
24
28
|
result += `${e.$dbNameOf(x)} integer default nextval('${sequenceName}')`;
|
|
25
29
|
}
|
|
26
30
|
else {
|
|
@@ -31,9 +35,9 @@ export class DuckDBDataProvider extends SqliteCoreDataProvider {
|
|
|
31
35
|
result += `,\r\n primary key (${entity.idMetadata.fields
|
|
32
36
|
.map((f) => e.$dbNameOf(f))
|
|
33
37
|
.join(',')})`;
|
|
34
|
-
|
|
38
|
+
createTableSql =
|
|
35
39
|
'create table if not exists ' + e.$entityName + ' (' + result + '\r\n)';
|
|
36
|
-
return [
|
|
40
|
+
return [...createSequenceStatements, createTableSql];
|
|
37
41
|
}
|
|
38
42
|
addColumnSqlSyntax(x, dbName, isAlterColumn) {
|
|
39
43
|
let result = dbName;
|
|
@@ -74,38 +78,83 @@ export class DuckDBDataProvider extends SqliteCoreDataProvider {
|
|
|
74
78
|
}
|
|
75
79
|
}
|
|
76
80
|
class DuckDBCommand {
|
|
77
|
-
|
|
81
|
+
connection;
|
|
78
82
|
values = [];
|
|
79
|
-
constructor(
|
|
80
|
-
this.
|
|
83
|
+
constructor(connection) {
|
|
84
|
+
this.connection = connection;
|
|
81
85
|
}
|
|
82
86
|
async execute(sql) {
|
|
83
|
-
|
|
84
|
-
this.
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
87
|
+
try {
|
|
88
|
+
const result = await this.connection.run(sql, this.values);
|
|
89
|
+
this.values = [];
|
|
90
|
+
return new DuckDBSqlResult(result);
|
|
91
|
+
}
|
|
92
|
+
catch (err) {
|
|
93
|
+
this.values = [];
|
|
94
|
+
throw err;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
addParamInternal(val) {
|
|
98
|
+
if (val === undefined) {
|
|
99
|
+
this.values.push(null);
|
|
100
|
+
}
|
|
101
|
+
else if (val instanceof Date) {
|
|
102
|
+
this.values.push(val.toISOString());
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
this.values.push(val);
|
|
106
|
+
}
|
|
107
|
+
return '?';
|
|
91
108
|
}
|
|
92
109
|
addParameterAndReturnSqlToken(val) {
|
|
93
|
-
return this.
|
|
110
|
+
return this.addParamInternal(val);
|
|
94
111
|
}
|
|
95
112
|
param(val) {
|
|
96
|
-
|
|
97
|
-
this.values.push(val);
|
|
98
|
-
return key;
|
|
113
|
+
return this.addParamInternal(val);
|
|
99
114
|
}
|
|
100
115
|
}
|
|
101
116
|
class DuckDBSqlResult {
|
|
102
|
-
|
|
103
|
-
constructor(result) {
|
|
104
|
-
this.result = result;
|
|
105
|
-
this.rows = result;
|
|
106
|
-
}
|
|
117
|
+
duckDbResult;
|
|
107
118
|
rows;
|
|
119
|
+
constructor(duckDbResult) {
|
|
120
|
+
this.duckDbResult = duckDbResult;
|
|
121
|
+
this.rows = [];
|
|
122
|
+
const columnNames = this.duckDbResult.columnNames();
|
|
123
|
+
const columnTypes = this.duckDbResult.columnTypes();
|
|
124
|
+
const chunkCount = this.duckDbResult.chunkCount;
|
|
125
|
+
for (let i = 0; i < chunkCount; i++) {
|
|
126
|
+
const chunk = this.duckDbResult.getChunk(i);
|
|
127
|
+
const chunkRowObjects = chunk.getRowObjects(columnNames).map((row) => {
|
|
128
|
+
const convertedRow = {};
|
|
129
|
+
columnNames.forEach((colName, colIndex) => {
|
|
130
|
+
const value = row[colName];
|
|
131
|
+
if (value === null) {
|
|
132
|
+
convertedRow[colName] = null;
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
const colType = columnTypes[colIndex];
|
|
136
|
+
const typeId = colType.typeId;
|
|
137
|
+
if (typeId === DuckDBTypeId.TIMESTAMP) {
|
|
138
|
+
const timestampValue = value;
|
|
139
|
+
const parts = timestampValue.toParts();
|
|
140
|
+
convertedRow[colName] = new Date(Date.UTC(parts.date.year, parts.date.month - 1, parts.date.day, parts.time.hour, parts.time.min, parts.time.sec, Math.floor(parts.time.micros / 1000)));
|
|
141
|
+
}
|
|
142
|
+
else if (typeId === DuckDBTypeId.DATE) {
|
|
143
|
+
const dateValue = value;
|
|
144
|
+
const parts = dateValue.toParts();
|
|
145
|
+
convertedRow[colName] = new Date(Date.UTC(parts.year, parts.month - 1, parts.day));
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
convertedRow[colName] = value;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
return convertedRow;
|
|
153
|
+
});
|
|
154
|
+
this.rows.push(...chunkRowObjects);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
108
157
|
getColumnKeyInResultForIndexInSelect(index) {
|
|
109
|
-
return
|
|
158
|
+
return this.duckDbResult.columnName(index);
|
|
110
159
|
}
|
|
111
160
|
}
|
|
@@ -14,17 +14,20 @@ export function TestApiDataProvider(options) {
|
|
|
14
14
|
buildGenericRequestInfo: (req) => req,
|
|
15
15
|
ignoreAsyncStorage: true,
|
|
16
16
|
});
|
|
17
|
+
const lock = new AsyncLock();
|
|
17
18
|
async function handleOnServer(req) {
|
|
18
|
-
return
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
19
|
+
return lock.runExclusive(async () => {
|
|
20
|
+
return await MakeServerCallWithDifferentStaticRemult(async () => {
|
|
21
|
+
if (newEntities.length > 0 && options?.ensureSchema != false) {
|
|
22
|
+
await (await dp).ensureSchema?.(newEntities);
|
|
23
|
+
newEntities = [];
|
|
24
|
+
}
|
|
25
|
+
var result = await server.handle(req);
|
|
26
|
+
if ((result?.statusCode ?? 200) >= 400) {
|
|
27
|
+
throw { ...result?.data, status: result?.statusCode ?? 500 };
|
|
28
|
+
}
|
|
29
|
+
return result?.data;
|
|
30
|
+
});
|
|
28
31
|
});
|
|
29
32
|
}
|
|
30
33
|
const registeredEntities = new Set();
|
|
@@ -58,6 +61,24 @@ export function TestApiDataProvider(options) {
|
|
|
58
61
|
}
|
|
59
62
|
});
|
|
60
63
|
}
|
|
64
|
+
export class AsyncLock {
|
|
65
|
+
static enabled = true;
|
|
66
|
+
current = Promise.resolve();
|
|
67
|
+
i = 0;
|
|
68
|
+
async runExclusive(fn) {
|
|
69
|
+
const previous = this.current;
|
|
70
|
+
let resolveNext;
|
|
71
|
+
this.current = new Promise((resolve) => (resolveNext = resolve));
|
|
72
|
+
if (AsyncLock.enabled)
|
|
73
|
+
await previous;
|
|
74
|
+
try {
|
|
75
|
+
return await fn();
|
|
76
|
+
}
|
|
77
|
+
finally {
|
|
78
|
+
resolveNext();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
61
82
|
async function MakeServerCallWithDifferentStaticRemult(what) {
|
|
62
83
|
var x = remultStatic.asyncContext;
|
|
63
84
|
var y = remultStatic.remultFactory;
|
package/package.json
CHANGED
package/remult-duckdb.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { DuckDBConnection } from '@duckdb/node-api';
|
|
2
2
|
import { SqliteCoreDataProvider } from './remult-sqlite-core.js';
|
|
3
3
|
import { type FieldMetadata, type EntityMetadata } from './index.js';
|
|
4
4
|
export declare class DuckDBDataProvider extends SqliteCoreDataProvider {
|
|
5
|
-
|
|
5
|
+
private connection;
|
|
6
|
+
constructor(connection: DuckDBConnection);
|
|
6
7
|
wrapIdentifier(name: string): string;
|
|
7
8
|
getCreateTableSql(entity: EntityMetadata<any>): Promise<string[]>;
|
|
8
9
|
addColumnSqlSyntax(x: FieldMetadata, dbName: string, isAlterColumn: boolean): string;
|
package/remult-duckdb.js
CHANGED
|
@@ -2,19 +2,18 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.DuckDBDataProvider = void 0;
|
|
4
4
|
var tslib_1 = require("tslib");
|
|
5
|
+
var node_api_1 = require("@duckdb/node-api");
|
|
5
6
|
var remult_sqlite_core_js_1 = require("./remult-sqlite-core.js");
|
|
6
7
|
var index_js_1 = require("./index.js");
|
|
7
8
|
var filter_consumer_bridge_to_sql_request_js_1 = require("./src/filter/filter-consumer-bridge-to-sql-request.js");
|
|
8
9
|
var RepositoryImplementation_js_1 = require("./src/remult3/RepositoryImplementation.js");
|
|
9
10
|
var DuckDBDataProvider = /** @class */ (function (_super) {
|
|
10
11
|
tslib_1.__extends(DuckDBDataProvider, _super);
|
|
11
|
-
function DuckDBDataProvider(
|
|
12
|
-
var _this = _super.call(this, function () { return new DuckDBCommand(
|
|
13
|
-
|
|
14
|
-
case 0: return [4 /*yield*/, db];
|
|
15
|
-
case 1: return [2 /*return*/, (_a.sent()).close()];
|
|
16
|
-
}
|
|
12
|
+
function DuckDBDataProvider(connection) {
|
|
13
|
+
var _this = _super.call(this, function () { return new DuckDBCommand(_this.connection); }, function () { return tslib_1.__awaiter(_this, void 0, void 0, function () { return tslib_1.__generator(this, function (_a) {
|
|
14
|
+
return [2 /*return*/, this.connection.disconnectSync()];
|
|
17
15
|
}); }); }, false, true) || this;
|
|
16
|
+
_this.connection = connection;
|
|
18
17
|
return _this;
|
|
19
18
|
}
|
|
20
19
|
DuckDBDataProvider.prototype.wrapIdentifier = function (name) {
|
|
@@ -22,7 +21,7 @@ var DuckDBDataProvider = /** @class */ (function (_super) {
|
|
|
22
21
|
};
|
|
23
22
|
DuckDBDataProvider.prototype.getCreateTableSql = function (entity) {
|
|
24
23
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
25
|
-
var result, e,
|
|
24
|
+
var result, e, createSequenceStatements, createTableSql, _a, _b, x, sequenceName;
|
|
26
25
|
var e_1, _c;
|
|
27
26
|
return tslib_1.__generator(this, function (_d) {
|
|
28
27
|
switch (_d.label) {
|
|
@@ -31,7 +30,8 @@ var DuckDBDataProvider = /** @class */ (function (_super) {
|
|
|
31
30
|
return [4 /*yield*/, (0, index_js_1.dbNamesOf)(entity, this.wrapIdentifier)];
|
|
32
31
|
case 1:
|
|
33
32
|
e = _d.sent();
|
|
34
|
-
|
|
33
|
+
createSequenceStatements = [];
|
|
34
|
+
createTableSql = '';
|
|
35
35
|
try {
|
|
36
36
|
for (_a = tslib_1.__values(entity.fields), _b = _a.next(); !_b.done; _b = _a.next()) {
|
|
37
37
|
x = _b.value;
|
|
@@ -41,7 +41,7 @@ var DuckDBDataProvider = /** @class */ (function (_super) {
|
|
|
41
41
|
result += '\r\n ';
|
|
42
42
|
if ((0, RepositoryImplementation_js_1.isAutoIncrement)(x)) {
|
|
43
43
|
sequenceName = "".concat(entity.dbName, "_").concat(x.dbName, "_seq");
|
|
44
|
-
|
|
44
|
+
createSequenceStatements.push("create sequence if not exists \"".concat(sequenceName, "\";"));
|
|
45
45
|
result += "".concat(e.$dbNameOf(x), " integer default nextval('").concat(sequenceName, "')");
|
|
46
46
|
}
|
|
47
47
|
else {
|
|
@@ -60,9 +60,9 @@ var DuckDBDataProvider = /** @class */ (function (_super) {
|
|
|
60
60
|
result += ",\r\n primary key (".concat(entity.idMetadata.fields
|
|
61
61
|
.map(function (f) { return e.$dbNameOf(f); })
|
|
62
62
|
.join(','), ")");
|
|
63
|
-
|
|
63
|
+
createTableSql =
|
|
64
64
|
'create table if not exists ' + e.$entityName + ' (' + result + '\r\n)';
|
|
65
|
-
return [2 /*return*/, [
|
|
65
|
+
return [2 /*return*/, tslib_1.__spreadArray(tslib_1.__spreadArray([], tslib_1.__read(createSequenceStatements), false), [createTableSql], false)];
|
|
66
66
|
}
|
|
67
67
|
});
|
|
68
68
|
});
|
|
@@ -108,43 +108,93 @@ var DuckDBDataProvider = /** @class */ (function (_super) {
|
|
|
108
108
|
}(remult_sqlite_core_js_1.SqliteCoreDataProvider));
|
|
109
109
|
exports.DuckDBDataProvider = DuckDBDataProvider;
|
|
110
110
|
var DuckDBCommand = /** @class */ (function () {
|
|
111
|
-
function DuckDBCommand(
|
|
112
|
-
this.
|
|
111
|
+
function DuckDBCommand(connection) {
|
|
112
|
+
this.connection = connection;
|
|
113
113
|
this.values = [];
|
|
114
114
|
}
|
|
115
115
|
DuckDBCommand.prototype.execute = function (sql) {
|
|
116
116
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
117
|
-
var
|
|
117
|
+
var result, err_1;
|
|
118
118
|
return tslib_1.__generator(this, function (_a) {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
119
|
+
switch (_a.label) {
|
|
120
|
+
case 0:
|
|
121
|
+
_a.trys.push([0, 2, , 3]);
|
|
122
|
+
return [4 /*yield*/, this.connection.run(sql, this.values)];
|
|
123
|
+
case 1:
|
|
124
|
+
result = _a.sent();
|
|
125
|
+
this.values = [];
|
|
126
|
+
return [2 /*return*/, new DuckDBSqlResult(result)];
|
|
127
|
+
case 2:
|
|
128
|
+
err_1 = _a.sent();
|
|
129
|
+
this.values = [];
|
|
130
|
+
throw err_1;
|
|
131
|
+
case 3: return [2 /*return*/];
|
|
132
|
+
}
|
|
128
133
|
});
|
|
129
134
|
});
|
|
130
135
|
};
|
|
136
|
+
DuckDBCommand.prototype.addParamInternal = function (val) {
|
|
137
|
+
if (val === undefined) {
|
|
138
|
+
this.values.push(null);
|
|
139
|
+
}
|
|
140
|
+
else if (val instanceof Date) {
|
|
141
|
+
this.values.push(val.toISOString());
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
this.values.push(val);
|
|
145
|
+
}
|
|
146
|
+
return '?';
|
|
147
|
+
};
|
|
131
148
|
DuckDBCommand.prototype.addParameterAndReturnSqlToken = function (val) {
|
|
132
|
-
return this.
|
|
149
|
+
return this.addParamInternal(val);
|
|
133
150
|
};
|
|
134
151
|
DuckDBCommand.prototype.param = function (val) {
|
|
135
|
-
|
|
136
|
-
this.values.push(val);
|
|
137
|
-
return key;
|
|
152
|
+
return this.addParamInternal(val);
|
|
138
153
|
};
|
|
139
154
|
return DuckDBCommand;
|
|
140
155
|
}());
|
|
141
156
|
var DuckDBSqlResult = /** @class */ (function () {
|
|
142
|
-
function DuckDBSqlResult(
|
|
143
|
-
|
|
144
|
-
this.
|
|
157
|
+
function DuckDBSqlResult(duckDbResult) {
|
|
158
|
+
var _a;
|
|
159
|
+
this.duckDbResult = duckDbResult;
|
|
160
|
+
this.rows = [];
|
|
161
|
+
var columnNames = this.duckDbResult.columnNames();
|
|
162
|
+
var columnTypes = this.duckDbResult.columnTypes();
|
|
163
|
+
var chunkCount = this.duckDbResult.chunkCount;
|
|
164
|
+
for (var i = 0; i < chunkCount; i++) {
|
|
165
|
+
var chunk = this.duckDbResult.getChunk(i);
|
|
166
|
+
var chunkRowObjects = chunk.getRowObjects(columnNames).map(function (row) {
|
|
167
|
+
var convertedRow = {};
|
|
168
|
+
columnNames.forEach(function (colName, colIndex) {
|
|
169
|
+
var value = row[colName];
|
|
170
|
+
if (value === null) {
|
|
171
|
+
convertedRow[colName] = null;
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
var colType = columnTypes[colIndex];
|
|
175
|
+
var typeId = colType.typeId;
|
|
176
|
+
if (typeId === node_api_1.DuckDBTypeId.TIMESTAMP) {
|
|
177
|
+
var timestampValue = value;
|
|
178
|
+
var parts = timestampValue.toParts();
|
|
179
|
+
convertedRow[colName] = new Date(Date.UTC(parts.date.year, parts.date.month - 1, parts.date.day, parts.time.hour, parts.time.min, parts.time.sec, Math.floor(parts.time.micros / 1000)));
|
|
180
|
+
}
|
|
181
|
+
else if (typeId === node_api_1.DuckDBTypeId.DATE) {
|
|
182
|
+
var dateValue = value;
|
|
183
|
+
var parts = dateValue.toParts();
|
|
184
|
+
convertedRow[colName] = new Date(Date.UTC(parts.year, parts.month - 1, parts.day));
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
convertedRow[colName] = value;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
return convertedRow;
|
|
192
|
+
});
|
|
193
|
+
(_a = this.rows).push.apply(_a, tslib_1.__spreadArray([], tslib_1.__read(chunkRowObjects), false));
|
|
194
|
+
}
|
|
145
195
|
}
|
|
146
196
|
DuckDBSqlResult.prototype.getColumnKeyInResultForIndexInSelect = function (index) {
|
|
147
|
-
return
|
|
197
|
+
return this.duckDbResult.columnName(index);
|
|
148
198
|
};
|
|
149
199
|
return DuckDBSqlResult;
|
|
150
200
|
}());
|
|
@@ -1,3 +1,9 @@
|
|
|
1
1
|
import { RestDataProvider } from '../index.js';
|
|
2
2
|
import type { RemultServerOptions } from './index.js';
|
|
3
3
|
export declare function TestApiDataProvider(options?: Pick<RemultServerOptions<unknown>, 'ensureSchema' | 'dataProvider'>): RestDataProvider;
|
|
4
|
+
export declare class AsyncLock {
|
|
5
|
+
static enabled: boolean;
|
|
6
|
+
private current;
|
|
7
|
+
i: number;
|
|
8
|
+
runExclusive<T>(fn: () => Promise<T>): Promise<T>;
|
|
9
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AsyncLock = void 0;
|
|
3
4
|
exports.TestApiDataProvider = TestApiDataProvider;
|
|
4
5
|
var tslib_1 = require("tslib");
|
|
5
6
|
var index_js_1 = require("../index.js");
|
|
@@ -23,36 +24,42 @@ function TestApiDataProvider(options) {
|
|
|
23
24
|
buildGenericRequestInfo: function (req) { return req; },
|
|
24
25
|
ignoreAsyncStorage: true,
|
|
25
26
|
});
|
|
27
|
+
var lock = new AsyncLock();
|
|
26
28
|
function handleOnServer(req) {
|
|
27
29
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
28
30
|
var _this = this;
|
|
29
31
|
return tslib_1.__generator(this, function (_a) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
32
|
+
return [2 /*return*/, lock.runExclusive(function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
33
|
+
var _this = this;
|
|
34
|
+
return tslib_1.__generator(this, function (_a) {
|
|
35
|
+
switch (_a.label) {
|
|
36
|
+
case 0: return [4 /*yield*/, MakeServerCallWithDifferentStaticRemult(function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
37
|
+
var result;
|
|
38
|
+
var _a, _b, _c, _d;
|
|
39
|
+
return tslib_1.__generator(this, function (_e) {
|
|
40
|
+
switch (_e.label) {
|
|
41
|
+
case 0:
|
|
42
|
+
if (!(newEntities.length > 0 && (options === null || options === void 0 ? void 0 : options.ensureSchema) != false)) return [3 /*break*/, 3];
|
|
43
|
+
return [4 /*yield*/, dp];
|
|
44
|
+
case 1: return [4 /*yield*/, ((_b = (_a = (_e.sent())).ensureSchema) === null || _b === void 0 ? void 0 : _b.call(_a, newEntities))];
|
|
45
|
+
case 2:
|
|
46
|
+
_e.sent();
|
|
47
|
+
newEntities = [];
|
|
48
|
+
_e.label = 3;
|
|
49
|
+
case 3: return [4 /*yield*/, server.handle(req)];
|
|
50
|
+
case 4:
|
|
51
|
+
result = _e.sent();
|
|
52
|
+
if (((_c = result === null || result === void 0 ? void 0 : result.statusCode) !== null && _c !== void 0 ? _c : 200) >= 400) {
|
|
53
|
+
throw tslib_1.__assign(tslib_1.__assign({}, result === null || result === void 0 ? void 0 : result.data), { status: (_d = result === null || result === void 0 ? void 0 : result.statusCode) !== null && _d !== void 0 ? _d : 500 });
|
|
54
|
+
}
|
|
55
|
+
return [2 /*return*/, result === null || result === void 0 ? void 0 : result.data];
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}); })];
|
|
59
|
+
case 1: return [2 /*return*/, _a.sent()];
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
}); })];
|
|
56
63
|
});
|
|
57
64
|
});
|
|
58
65
|
}
|
|
@@ -95,6 +102,40 @@ function TestApiDataProvider(options) {
|
|
|
95
102
|
}
|
|
96
103
|
});
|
|
97
104
|
}
|
|
105
|
+
var AsyncLock = /** @class */ (function () {
|
|
106
|
+
function AsyncLock() {
|
|
107
|
+
this.current = Promise.resolve();
|
|
108
|
+
this.i = 0;
|
|
109
|
+
}
|
|
110
|
+
AsyncLock.prototype.runExclusive = function (fn) {
|
|
111
|
+
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
112
|
+
var previous, resolveNext;
|
|
113
|
+
return tslib_1.__generator(this, function (_a) {
|
|
114
|
+
switch (_a.label) {
|
|
115
|
+
case 0:
|
|
116
|
+
previous = this.current;
|
|
117
|
+
this.current = new Promise(function (resolve) { return (resolveNext = resolve); });
|
|
118
|
+
if (!AsyncLock.enabled) return [3 /*break*/, 2];
|
|
119
|
+
return [4 /*yield*/, previous];
|
|
120
|
+
case 1:
|
|
121
|
+
_a.sent();
|
|
122
|
+
_a.label = 2;
|
|
123
|
+
case 2:
|
|
124
|
+
_a.trys.push([2, , 4, 5]);
|
|
125
|
+
return [4 /*yield*/, fn()];
|
|
126
|
+
case 3: return [2 /*return*/, _a.sent()];
|
|
127
|
+
case 4:
|
|
128
|
+
resolveNext();
|
|
129
|
+
return [7 /*endfinally*/];
|
|
130
|
+
case 5: return [2 /*return*/];
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
};
|
|
135
|
+
AsyncLock.enabled = true;
|
|
136
|
+
return AsyncLock;
|
|
137
|
+
}());
|
|
138
|
+
exports.AsyncLock = AsyncLock;
|
|
98
139
|
function MakeServerCallWithDifferentStaticRemult(what) {
|
|
99
140
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
100
141
|
var x, y, user, store;
|
|
@@ -35,6 +35,10 @@ export interface FieldOptions<entityType = unknown, valueType = unknown> {
|
|
|
35
35
|
* // Prevent API from updating this field
|
|
36
36
|
* @Fields.string({ allowApiUpdate: false })
|
|
37
37
|
* createdBy = remult.user?.id;
|
|
38
|
+
* @example
|
|
39
|
+
* // Allow API update only on new items
|
|
40
|
+
* @Fields.string<Category>({ allowApiUpdate: (c) => getEntityRef(c).isNew() })
|
|
41
|
+
* Description = ""
|
|
38
42
|
* @see [allowed](https://remult.dev/docs/allowed.html)
|
|
39
43
|
* @see [Access Control](https://remult.dev/docs/access-control)
|
|
40
44
|
* @type {AllowedForInstance<entityType>}
|