remult 0.25.8-exp.8 → 0.25.8
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/README.md +12 -6
- package/esm/graphql.js +2 -2
- package/esm/postgres/postgres-data-provider.js +3 -24
- package/esm/postgres/schema-builder.js +26 -35
- package/esm/remult-knex/index.js +30 -118
- package/esm/remult-mongo.js +2 -2
- package/esm/remult-sql-js.js +2 -7
- package/esm/server/expressBridge.js +29 -130
- package/esm/src/CompoundIdField.js +2 -8
- package/esm/src/context.js +8 -14
- package/esm/src/data-api.js +25 -56
- package/esm/src/data-providers/rest-data-provider.js +15 -17
- package/esm/src/data-providers/sql-database.js +5 -16
- package/esm/src/data-providers/web-sql-data-provider.js +9 -1
- package/esm/src/filter/filter-consumer-bridge-to-sql-request.js +0 -4
- package/esm/src/filter/filter-interfaces.js +0 -31
- package/esm/src/remult3/Fields.js +0 -66
- package/esm/src/remult3/RepositoryImplementation.js +3 -7
- package/esm/src/remult3/remult3.js +55 -15
- package/esm/src/server-action.js +2 -2
- package/esm/src/validators.js +1 -1
- package/esm/src/valueConverters.js +1 -1
- package/graphql.js +4 -2
- package/package.json +1 -6
- package/postgres/postgres-data-provider.d.ts +3 -8
- package/postgres/postgres-data-provider.js +3 -46
- package/postgres/schema-builder.js +48 -81
- package/remult-knex/index.d.ts +4 -11
- package/remult-knex/index.js +58 -176
- package/remult-mongo.d.ts +2 -2
- package/remult-mongo.js +2 -2
- package/remult-sql-js.d.ts +0 -2
- package/remult-sql-js.js +1 -15
- package/server/expressBridge.d.ts +1 -30
- package/server/expressBridge.js +32 -140
- package/src/CompoundIdField.js +2 -8
- package/src/column-interfaces.d.ts +3 -9
- package/src/context.d.ts +1 -3
- package/src/context.js +8 -16
- package/src/data-api.d.ts +8 -12
- package/src/data-api.js +75 -115
- package/src/data-providers/rest-data-provider.js +15 -26
- package/src/data-providers/sql-database.d.ts +4 -5
- package/src/data-providers/sql-database.js +5 -13
- package/src/data-providers/web-sql-data-provider.d.ts +2 -1
- package/src/data-providers/web-sql-data-provider.js +8 -4
- package/src/filter/filter-consumer-bridge-to-sql-request.d.ts +0 -1
- package/src/filter/filter-consumer-bridge-to-sql-request.js +1 -6
- package/src/filter/filter-interfaces.js +12 -64
- package/src/remult3/Fields.d.ts +0 -36
- package/src/remult3/Fields.js +0 -77
- package/src/remult3/RepositoryImplementation.d.ts +3 -7
- package/src/remult3/RepositoryImplementation.js +51 -57
- package/src/remult3/remult3.d.ts +3 -7
- package/src/remult3/remult3.js +55 -15
- package/src/server-action.js +2 -2
- package/src/sql-command.d.ts +0 -5
- package/src/validators.js +1 -3
- package/src/valueConverters.js +1 -1
- package/esm/migrations/compare-migration-snapshots.js +0 -39
- package/esm/migrations/generate-migrations.js +0 -63
- package/esm/migrations/index.js +0 -2
- package/esm/migrations/migrate.js +0 -76
- package/esm/migrations/migration-types.js +0 -12
- package/esm/migrations/update-migrations-ts-file.js +0 -112
- package/esm/src/isOfType.js +0 -9
- package/esm/src/remult3/addValidatorKey.js +0 -1
- package/migrations/compare-migration-snapshots.d.ts +0 -26
- package/migrations/compare-migration-snapshots.js +0 -100
- package/migrations/generate-migrations.d.ts +0 -21
- package/migrations/generate-migrations.js +0 -100
- package/migrations/index.d.ts +0 -3
- package/migrations/index.js +0 -7
- package/migrations/migrate.d.ts +0 -18
- package/migrations/migrate.js +0 -169
- package/migrations/migration-types.d.ts +0 -43
- package/migrations/migration-types.js +0 -27
- package/migrations/update-migrations-ts-file.d.ts +0 -1
- package/migrations/update-migrations-ts-file.js +0 -135
- package/src/isOfType.d.ts +0 -2
- package/src/isOfType.js +0 -14
- package/src/remult3/addValidatorKey.d.ts +0 -1
- package/src/remult3/addValidatorKey.js +0 -4
package/README.md
CHANGED
|
@@ -5,17 +5,23 @@
|
|
|
5
5
|
<h1>Remult</h1>
|
|
6
6
|
<p>Full-stack CRUD, simplified, with SSOT TypeScript entities</p>
|
|
7
7
|
<a href="https://circleci.com/gh/remult/remult/tree/master" rel="nofollow">
|
|
8
|
-
<img alt="CircleCI" src="https://circleci.com/gh/remult/remult/tree/master.svg?style=shield"
|
|
8
|
+
<img alt="CircleCI" src="https://circleci.com/gh/remult/remult/tree/master.svg?style=shield">
|
|
9
|
+
</a>
|
|
9
10
|
<a href="https://codecov.io/gh/remult/remult" rel="nofollow">
|
|
10
|
-
<img src="https://codecov.io/gh/remult/remult/branch/master/graph/badge.svg?token=LYWQRUN3D1"
|
|
11
|
+
<img src="https://codecov.io/gh/remult/remult/branch/master/graph/badge.svg?token=LYWQRUN3D1"/>
|
|
12
|
+
</a>
|
|
11
13
|
<a href="https://raw.githubusercontent.com/remult/remult/master/LICENSE" rel="nofollow">
|
|
12
|
-
<img alt="GitHub license" src="https://img.shields.io/badge/license-MIT-blue.svg"
|
|
14
|
+
<img alt="GitHub license" src="https://img.shields.io/badge/license-MIT-blue.svg">
|
|
15
|
+
</a>
|
|
13
16
|
<a href="https://www.npmjs.com/package/remult" rel="nofollow">
|
|
14
|
-
<img alt="npm version" src="https://badge.fury.io/js/remult.svg"
|
|
17
|
+
<img alt="npm version" src="https://badge.fury.io/js/remult.svg">
|
|
18
|
+
</a>
|
|
15
19
|
<a href="https://www.npmjs.com/package/remult" rel="nofollow">
|
|
16
|
-
<img alt="npm downloads" src="https://img.shields.io/npm/dm/remult"
|
|
20
|
+
<img alt="npm downloads" src="https://img.shields.io/npm/dm/remult">
|
|
21
|
+
</a>
|
|
17
22
|
<a href="https://discord.gg/GXHk7ZfuG5" rel="nofollow">
|
|
18
|
-
<img alt="Join Discord" src="https://badgen.net/discord/members/GXHk7ZfuG5?icon=discord&label=Discord"
|
|
23
|
+
<img alt="Join Discord" src="https://badgen.net/discord/online-members/GXHk7ZfuG5?icon=discord&label=Discord"/>
|
|
24
|
+
</a>
|
|
19
25
|
</div>
|
|
20
26
|
|
|
21
27
|
<br/>
|
package/esm/graphql.js
CHANGED
|
@@ -904,7 +904,7 @@ export function translateWhereToRestBody(fields, { where }) {
|
|
|
904
904
|
}
|
|
905
905
|
}
|
|
906
906
|
if (where.OR) {
|
|
907
|
-
result.OR = where.OR.map((where) => translateWhereToRestBody(fields, { where })
|
|
907
|
+
result.OR = where.OR.map((where) => translateWhereToRestBody(fields, { where }));
|
|
908
908
|
}
|
|
909
|
-
return
|
|
909
|
+
return result;
|
|
910
910
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { remult as defaultRemult } from '../src/remult-proxy.js';
|
|
2
1
|
import pg from 'pg';
|
|
3
2
|
const { Pool } = pg;
|
|
4
3
|
import { Remult } from '../src/context.js';
|
|
@@ -8,11 +7,9 @@ export class PostgresDataProvider {
|
|
|
8
7
|
pool;
|
|
9
8
|
options;
|
|
10
9
|
supportsJsonColumnType = true;
|
|
11
|
-
static getDb(
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
throw 'the data provider is not an SqlDatabase';
|
|
15
|
-
const me = r._getSourceSql();
|
|
10
|
+
static getDb(remult) {
|
|
11
|
+
const sql = SqlDatabase.getDb(remult);
|
|
12
|
+
const me = sql._getSourceSql();
|
|
16
13
|
if (!me.pool) {
|
|
17
14
|
throw 'the data provider is not a PostgresDataProvider';
|
|
18
15
|
}
|
|
@@ -38,21 +35,6 @@ export class PostgresDataProvider {
|
|
|
38
35
|
this.pool = new PostgresSchemaWrapper(pool, options.schema);
|
|
39
36
|
}
|
|
40
37
|
}
|
|
41
|
-
end() {
|
|
42
|
-
return this.pool.end();
|
|
43
|
-
}
|
|
44
|
-
provideMigrationBuilder(builder) {
|
|
45
|
-
var db = new SqlDatabase(this);
|
|
46
|
-
var sb = new PostgresSchemaBuilder(db, this.options?.schema);
|
|
47
|
-
return {
|
|
48
|
-
addColumn: async (meta, field) => {
|
|
49
|
-
builder.addSql(await sb.getAddColumnScript(meta, field));
|
|
50
|
-
},
|
|
51
|
-
createTable: async (meta) => {
|
|
52
|
-
builder.addSql(await sb.createTableScript(meta));
|
|
53
|
-
},
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
38
|
wrapIdentifier = (name) => name
|
|
57
39
|
.split('.')
|
|
58
40
|
.map((name) => name.startsWith('"') ? name : '"' + name.replace(/"/g, '""') + '"')
|
|
@@ -190,7 +172,4 @@ export class PostgresSchemaWrapper {
|
|
|
190
172
|
c.release();
|
|
191
173
|
}
|
|
192
174
|
}
|
|
193
|
-
end() {
|
|
194
|
-
return this.pool.end();
|
|
195
|
-
}
|
|
196
175
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { dbNamesOf,
|
|
1
|
+
import { dbNamesOf, shouldNotCreateField, } from '../src/filter/filter-consumer-bridge-to-sql-request.js';
|
|
2
2
|
import { remult as defaultRemult } from '../src/remult-proxy.js';
|
|
3
3
|
import { remultStatic } from '../src/remult-static.js';
|
|
4
4
|
import { isAutoIncrement } from '../src/remult3/RepositoryImplementation.js';
|
|
@@ -19,7 +19,7 @@ export function postgresColumnSyntax(x, dbName) {
|
|
|
19
19
|
if (x.valueConverter == ValueConverters.DateOnly)
|
|
20
20
|
result += ' date';
|
|
21
21
|
else
|
|
22
|
-
result += '
|
|
22
|
+
result += ' timestamp';
|
|
23
23
|
else
|
|
24
24
|
result += ' ' + x.valueConverter.fieldTypeInDb;
|
|
25
25
|
}
|
|
@@ -109,9 +109,11 @@ export class PostgresSchemaBuilder {
|
|
|
109
109
|
for (const entity of entities) {
|
|
110
110
|
let e = await dbNamesOf(entity, this.pool.wrapIdentifier);
|
|
111
111
|
try {
|
|
112
|
-
if (
|
|
113
|
-
|
|
114
|
-
|
|
112
|
+
if (!entity.options.sqlExpression) {
|
|
113
|
+
if (e.$entityName.toLowerCase().indexOf('from ') < 0) {
|
|
114
|
+
await this.createIfNotExist(entity);
|
|
115
|
+
await this.verifyAllColumns(entity);
|
|
116
|
+
}
|
|
115
117
|
}
|
|
116
118
|
}
|
|
117
119
|
catch (err) {
|
|
@@ -128,41 +130,29 @@ export class PostgresSchemaBuilder {
|
|
|
128
130
|
`${this.whereTableAndSchema(c, e)}`)
|
|
129
131
|
.then(async (r) => {
|
|
130
132
|
if (r.rows.length == 0) {
|
|
131
|
-
|
|
133
|
+
let result = '';
|
|
134
|
+
for (const x of entity.fields) {
|
|
135
|
+
if (!shouldNotCreateField(x, e) || isAutoIncrement(x)) {
|
|
136
|
+
if (result.length != 0)
|
|
137
|
+
result += ',';
|
|
138
|
+
result += '\r\n ';
|
|
139
|
+
if (isAutoIncrement(x))
|
|
140
|
+
result += e.$dbNameOf(x) + ' serial';
|
|
141
|
+
else {
|
|
142
|
+
result += postgresColumnSyntax(x, e.$dbNameOf(x));
|
|
143
|
+
}
|
|
144
|
+
if (x == entity.idMetadata.field)
|
|
145
|
+
result += ' primary key';
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
let sql = `CREATE SCHEMA IF NOT EXISTS ${this.schemaOnly(e)};
|
|
149
|
+
CREATE table ${this.schemaAndName(e)} (${result}\r\n)`;
|
|
132
150
|
if (PostgresSchemaBuilder.logToConsole)
|
|
133
151
|
console.info(sql);
|
|
134
152
|
await this.pool.execute(sql);
|
|
135
153
|
}
|
|
136
154
|
});
|
|
137
155
|
}
|
|
138
|
-
/* @internal*/
|
|
139
|
-
async getAddColumnScript(entity, field) {
|
|
140
|
-
let e = await dbNamesOf(entity, this.pool.wrapIdentifier);
|
|
141
|
-
return (`ALTER table ${this.schemaAndName(e)} ` +
|
|
142
|
-
`ADD column ${postgresColumnSyntax(field, e.$dbNameOf(field))}`);
|
|
143
|
-
}
|
|
144
|
-
/* @internal*/
|
|
145
|
-
async createTableScript(entity) {
|
|
146
|
-
let result = '';
|
|
147
|
-
let e = await dbNamesOf(entity, this.pool.wrapIdentifier);
|
|
148
|
-
for (const x of entity.fields) {
|
|
149
|
-
if (!shouldNotCreateField(x, e) || isAutoIncrement(x)) {
|
|
150
|
-
if (result.length != 0)
|
|
151
|
-
result += ',';
|
|
152
|
-
result += '\r\n ';
|
|
153
|
-
if (isAutoIncrement(x))
|
|
154
|
-
result += e.$dbNameOf(x) + ' serial';
|
|
155
|
-
else {
|
|
156
|
-
result += postgresColumnSyntax(x, e.$dbNameOf(x));
|
|
157
|
-
}
|
|
158
|
-
if (x == entity.idMetadata.field)
|
|
159
|
-
result += ' primary key';
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
let sql = `CREATE SCHEMA IF NOT EXISTS ${this.schemaOnly(e)};
|
|
163
|
-
CREATE table ${this.schemaAndName(e)} (${result}\r\n)`;
|
|
164
|
-
return sql;
|
|
165
|
-
}
|
|
166
156
|
async addColumnIfNotExist(entity, c) {
|
|
167
157
|
let e = await dbNamesOf(entity, this.pool.wrapIdentifier);
|
|
168
158
|
if (shouldNotCreateField(c(entity), e))
|
|
@@ -173,7 +163,8 @@ CREATE table ${this.schemaAndName(e)} (${result}\r\n)`;
|
|
|
173
163
|
if ((await cmd.execute(`SELECT 1 FROM information_schema.columns WHERE ` +
|
|
174
164
|
`${this.whereTableAndSchema(cmd, e)} ` +
|
|
175
165
|
`AND column_name=${cmd.param(colName.toLocaleLowerCase())}`)).rows.length == 0) {
|
|
176
|
-
let sql =
|
|
166
|
+
let sql = `ALTER table ${this.schemaAndName(e)} ` +
|
|
167
|
+
`ADD column ${postgresColumnSyntax(c(entity), colName)}`;
|
|
177
168
|
if (PostgresSchemaBuilder.logToConsole)
|
|
178
169
|
console.info(sql);
|
|
179
170
|
await this.pool.execute(sql);
|
package/esm/remult-knex/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { dbNamesOf, isDbReadonly,
|
|
1
|
+
import { dbNamesOf, isDbReadonly, shouldNotCreateField, } from '../src/filter/filter-consumer-bridge-to-sql-request.js';
|
|
2
2
|
import { customDatabaseFilterToken, Filter, } from '../src/filter/filter-interfaces.js';
|
|
3
3
|
import { CompoundIdField } from '../src/CompoundIdField.js';
|
|
4
4
|
import { remult as remultContext } from '../src/remult-proxy.js';
|
|
@@ -13,36 +13,8 @@ export class KnexDataProvider {
|
|
|
13
13
|
constructor(knex) {
|
|
14
14
|
this.knex = knex;
|
|
15
15
|
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
/* @internal */
|
|
20
|
-
provideMigrationBuilder(builder) {
|
|
21
|
-
var sb = new KnexSchemaBuilder(this.knex);
|
|
22
|
-
return {
|
|
23
|
-
async createTable(entity) {
|
|
24
|
-
let e = await dbNamesOf(entity, (x) => x);
|
|
25
|
-
sb.createTableKnexCommand(entity, e)
|
|
26
|
-
.toSQL()
|
|
27
|
-
.forEach((sql) => builder.addSql(sql.sql));
|
|
28
|
-
},
|
|
29
|
-
async addColumn(entity, field) {
|
|
30
|
-
let e = await dbNamesOf(entity, (x) => x);
|
|
31
|
-
await sb
|
|
32
|
-
.createColumnKnexCommand(e, field, e.$dbNameOf(field))
|
|
33
|
-
.toSQL()
|
|
34
|
-
.forEach((sql) => builder.addSql(sql.sql));
|
|
35
|
-
},
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
createCommand() {
|
|
39
|
-
return new KnexBridgeToSQLCommand(this.knex);
|
|
40
|
-
}
|
|
41
|
-
execute(sql) {
|
|
42
|
-
return this.createCommand().execute(sql);
|
|
43
|
-
}
|
|
44
|
-
static getDb(dataProvider) {
|
|
45
|
-
const r = (dataProvider || remultContext.dataProvider);
|
|
16
|
+
static getDb(remult) {
|
|
17
|
+
const r = (remult || remultContext).dataProvider;
|
|
46
18
|
if (!r.knex)
|
|
47
19
|
throw 'the data provider is not an KnexDataProvider';
|
|
48
20
|
return r.knex;
|
|
@@ -378,9 +350,11 @@ export class KnexSchemaBuilder {
|
|
|
378
350
|
for (const entity of entities) {
|
|
379
351
|
let e = await dbNamesOf(entity, (x) => x);
|
|
380
352
|
try {
|
|
381
|
-
if (
|
|
382
|
-
|
|
383
|
-
|
|
353
|
+
if (!entity.options.sqlExpression) {
|
|
354
|
+
if (e.$entityName.toLowerCase().indexOf('from ') < 0) {
|
|
355
|
+
await this.createIfNotExist(entity);
|
|
356
|
+
await this.verifyAllColumns(entity);
|
|
357
|
+
}
|
|
384
358
|
}
|
|
385
359
|
}
|
|
386
360
|
catch (err) {
|
|
@@ -392,30 +366,27 @@ export class KnexSchemaBuilder {
|
|
|
392
366
|
async createIfNotExist(entity) {
|
|
393
367
|
const e = await dbNamesOf(entity, (x) => x);
|
|
394
368
|
if (!(await this.knex.schema.hasTable(e.$entityName))) {
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
buildColumn(x, cols.get(x).name, b, supportsJsonDataStorage(this.knex));
|
|
413
|
-
if (x == entity.idMetadata.field)
|
|
414
|
-
b.primary([cols.get(x).name]);
|
|
369
|
+
let cols = new Map();
|
|
370
|
+
for (const f of entity.fields) {
|
|
371
|
+
cols.set(f, {
|
|
372
|
+
name: e.$dbNameOf(f),
|
|
373
|
+
readonly: shouldNotCreateField(f, e),
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
await logSql(this.knex.schema.createTable(e.$entityName, (b) => {
|
|
377
|
+
for (const x of entity.fields) {
|
|
378
|
+
if (!cols.get(x).readonly || isAutoIncrement(x)) {
|
|
379
|
+
if (isAutoIncrement(x))
|
|
380
|
+
b.increments(cols.get(x).name);
|
|
381
|
+
else {
|
|
382
|
+
buildColumn(x, cols.get(x).name, b, supportsJsonDataStorage(this.knex));
|
|
383
|
+
if (x == entity.idMetadata.field)
|
|
384
|
+
b.primary([cols.get(x).name]);
|
|
385
|
+
}
|
|
415
386
|
}
|
|
416
387
|
}
|
|
417
|
-
}
|
|
418
|
-
}
|
|
388
|
+
}));
|
|
389
|
+
}
|
|
419
390
|
}
|
|
420
391
|
async addColumnIfNotExist(entity, c) {
|
|
421
392
|
let e = await dbNamesOf(entity, (x) => x);
|
|
@@ -424,14 +395,11 @@ export class KnexSchemaBuilder {
|
|
|
424
395
|
let col = c(entity);
|
|
425
396
|
let colName = e.$dbNameOf(col);
|
|
426
397
|
if (!(await this.knex.schema.hasColumn(e.$entityName, colName))) {
|
|
427
|
-
await logSql(this.
|
|
398
|
+
await logSql(this.knex.schema.alterTable(e.$entityName, (b) => {
|
|
399
|
+
buildColumn(col, colName, b, supportsJsonDataStorage(this.knex));
|
|
400
|
+
}));
|
|
428
401
|
}
|
|
429
402
|
}
|
|
430
|
-
createColumnKnexCommand(e, col, colName) {
|
|
431
|
-
return this.knex.schema.alterTable(e.$entityName, (b) => {
|
|
432
|
-
buildColumn(col, colName, b, supportsJsonDataStorage(this.knex));
|
|
433
|
-
});
|
|
434
|
-
}
|
|
435
403
|
async verifyAllColumns(entity) {
|
|
436
404
|
let e = await dbNamesOf(entity, (x) => x);
|
|
437
405
|
try {
|
|
@@ -534,59 +502,3 @@ function translateValueAndHandleArrayAndHandleArray(field, val) {
|
|
|
534
502
|
return JSON.stringify(result);
|
|
535
503
|
return result;
|
|
536
504
|
}
|
|
537
|
-
class KnexBridgeToSQLCommand {
|
|
538
|
-
source;
|
|
539
|
-
constructor(source) {
|
|
540
|
-
this.source = source;
|
|
541
|
-
}
|
|
542
|
-
values = [];
|
|
543
|
-
addParameterAndReturnSqlToken(val) {
|
|
544
|
-
return this.param(val);
|
|
545
|
-
}
|
|
546
|
-
param(val) {
|
|
547
|
-
if (Array.isArray(val))
|
|
548
|
-
val = JSON.stringify(val);
|
|
549
|
-
this.values.push(val);
|
|
550
|
-
return '?';
|
|
551
|
-
}
|
|
552
|
-
async execute(sql) {
|
|
553
|
-
return await this.source.raw(sql, this.values).then((r) => {
|
|
554
|
-
switch (this.source.client.config.client) {
|
|
555
|
-
case 'mysql':
|
|
556
|
-
case 'mysql2':
|
|
557
|
-
return new KnexPostgresBridgeToSQLQueryResult({
|
|
558
|
-
fields: r[1],
|
|
559
|
-
rows: r[0],
|
|
560
|
-
});
|
|
561
|
-
case 'pg':
|
|
562
|
-
return new KnexPostgresBridgeToSQLQueryResult(r);
|
|
563
|
-
default:
|
|
564
|
-
case 'better-sqlite3':
|
|
565
|
-
case 'mssql':
|
|
566
|
-
return new KnexPostgresBridgeToSQLQueryResult({
|
|
567
|
-
rows: r,
|
|
568
|
-
});
|
|
569
|
-
}
|
|
570
|
-
});
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
|
-
class KnexPostgresBridgeToSQLQueryResult {
|
|
574
|
-
r;
|
|
575
|
-
getColumnKeyInResultForIndexInSelect(index) {
|
|
576
|
-
if (this.r.fields)
|
|
577
|
-
return this.r.fields[index].name;
|
|
578
|
-
if (this.rows.length == 0)
|
|
579
|
-
throw Error('No rows');
|
|
580
|
-
let i = 0;
|
|
581
|
-
for (let m in this.rows[0]) {
|
|
582
|
-
if (i++ == index)
|
|
583
|
-
return m;
|
|
584
|
-
}
|
|
585
|
-
throw Error('index not found');
|
|
586
|
-
}
|
|
587
|
-
constructor(r) {
|
|
588
|
-
this.r = r;
|
|
589
|
-
this.rows = r.rows;
|
|
590
|
-
}
|
|
591
|
-
rows;
|
|
592
|
-
}
|
package/esm/remult-mongo.js
CHANGED
|
@@ -16,8 +16,8 @@ export class MongoDataProvider {
|
|
|
16
16
|
}
|
|
17
17
|
session;
|
|
18
18
|
disableTransactions = false;
|
|
19
|
-
static getDb(
|
|
20
|
-
const r = (
|
|
19
|
+
static getDb(remult) {
|
|
20
|
+
const r = (remult || remultContext).dataProvider;
|
|
21
21
|
if (!r.db)
|
|
22
22
|
throw 'the data provider is not a MongoDataProvider';
|
|
23
23
|
return { db: r.db, session: r.session };
|
package/esm/remult-sql-js.js
CHANGED
|
@@ -1,16 +1,11 @@
|
|
|
1
1
|
import { SqlDatabase } from './src/data-providers/sql-database.js';
|
|
2
|
-
import { dbNamesOf,
|
|
2
|
+
import { dbNamesOf, isDbReadonly, } from './src/filter/filter-consumer-bridge-to-sql-request.js';
|
|
3
3
|
import { isAutoIncrement } from './src/remult3/RepositoryImplementation.js';
|
|
4
4
|
export class SqlJsDataProvider {
|
|
5
5
|
db;
|
|
6
6
|
constructor(db) {
|
|
7
7
|
this.db = db;
|
|
8
8
|
}
|
|
9
|
-
orderByNullsFirst;
|
|
10
|
-
async end() {
|
|
11
|
-
;
|
|
12
|
-
(await this.db).close();
|
|
13
|
-
}
|
|
14
9
|
getLimitSqlSyntax(limit, offset) {
|
|
15
10
|
return ' limit ' + limit + ' offset ' + offset;
|
|
16
11
|
}
|
|
@@ -57,7 +52,7 @@ export class SqlJsDataProvider {
|
|
|
57
52
|
let result = '';
|
|
58
53
|
let e = await dbNamesOf(entity);
|
|
59
54
|
for (const x of entity.fields) {
|
|
60
|
-
if (!
|
|
55
|
+
if (!isDbReadonly(x, e) || isAutoIncrement(x)) {
|
|
61
56
|
if (result.length != 0)
|
|
62
57
|
result += ',';
|
|
63
58
|
result += '\r\n ';
|
|
@@ -13,7 +13,6 @@ import { serverActionField } from '../src/server-action-info.js';
|
|
|
13
13
|
import { initDataProvider } from './initDataProvider.js';
|
|
14
14
|
import { remultStatic } from '../src/remult-static.js';
|
|
15
15
|
import remultAdminHtml from './remult-admin.js';
|
|
16
|
-
import { isOfType } from '../src/isOfType.js';
|
|
17
16
|
export function createRemultServerCore(options, serverCoreOptions) {
|
|
18
17
|
if (!options) {
|
|
19
18
|
options = {};
|
|
@@ -250,8 +249,8 @@ export class RemultServerImplementation {
|
|
|
250
249
|
console.info('[remult] ' + myRoute);
|
|
251
250
|
r.route(myRoute)
|
|
252
251
|
.get(this.process((c, req, res, orig) => dataApiFactory(c).httpGet(res, req, () => this.serializeContext(c))))
|
|
253
|
-
.put(this.process(async (c, req, res, _, __, orig) => dataApiFactory(c).
|
|
254
|
-
.delete(this.process(async (c, req, res,
|
|
252
|
+
.put(this.process(async (c, req, res, _, __, orig) => dataApiFactory(c).put(res, '', await this.coreOptions.getRequestBody(orig))))
|
|
253
|
+
.delete(this.process(async (c, req, res, orig) => dataApiFactory(c).delete(res, '')))
|
|
255
254
|
.post(this.process(async (c, req, res, _, __, orig) => dataApiFactory(c).httpPost(res, req, await this.coreOptions.getRequestBody(orig), () => this.serializeContext(c))));
|
|
256
255
|
r.route(myRoute + '/:id')
|
|
257
256
|
//@ts-ignore
|
|
@@ -286,7 +285,7 @@ export class RemultServerImplementation {
|
|
|
286
285
|
genReq.params = req['_tempParams'];
|
|
287
286
|
}
|
|
288
287
|
let myReq = new ExpressRequestBridgeToDataApiRequest(genReq);
|
|
289
|
-
let myRes = new ExpressResponseBridgeToDataApiResponse(origRes, req
|
|
288
|
+
let myRes = new ExpressResponseBridgeToDataApiResponse(origRes, req);
|
|
290
289
|
try {
|
|
291
290
|
await this.runWithRemult(async (remult) => {
|
|
292
291
|
if (req) {
|
|
@@ -316,7 +315,7 @@ export class RemultServerImplementation {
|
|
|
316
315
|
});
|
|
317
316
|
}
|
|
318
317
|
catch (err) {
|
|
319
|
-
myRes.error(err
|
|
318
|
+
myRes.error(serializeError(err));
|
|
320
319
|
}
|
|
321
320
|
};
|
|
322
321
|
}
|
|
@@ -467,17 +466,6 @@ export class RemultServerImplementation {
|
|
|
467
466
|
return secureBase(condition, def, item);
|
|
468
467
|
};
|
|
469
468
|
let apiPath = (spec.paths[this.options.rootPath + '/' + key] = {});
|
|
470
|
-
let itemInBody = {
|
|
471
|
-
requestBody: {
|
|
472
|
-
content: {
|
|
473
|
-
'application/json': {
|
|
474
|
-
schema: {
|
|
475
|
-
$ref: '#/components/schemas/' + mutationKey,
|
|
476
|
-
},
|
|
477
|
-
},
|
|
478
|
-
},
|
|
479
|
-
},
|
|
480
|
-
};
|
|
481
469
|
let apiPathWithId = (spec.paths[this.options.rootPath + '/' + key + '/{id}'] = {});
|
|
482
470
|
//https://github.com/2fd/open-api.d.ts
|
|
483
471
|
apiPath.get = secure(meta.options.allowApiRead, true, {
|
|
@@ -530,73 +518,6 @@ export class RemultServerImplementation {
|
|
|
530
518
|
},
|
|
531
519
|
},
|
|
532
520
|
});
|
|
533
|
-
apiPath.delete = secure(meta.options.allowApiDelete, true, {
|
|
534
|
-
description: 'deletes row of ' +
|
|
535
|
-
key +
|
|
536
|
-
'. supports filter operators. For more info on filtering [see this article](https://remult.dev/docs/rest-api.html#filter)',
|
|
537
|
-
parameters: [...parameters],
|
|
538
|
-
responses: {
|
|
539
|
-
'400': {
|
|
540
|
-
description: 'Error: Bad Request',
|
|
541
|
-
content: {
|
|
542
|
-
'application/json': {
|
|
543
|
-
schema: {
|
|
544
|
-
$ref: '#/components/schemas/InvalidResponse',
|
|
545
|
-
},
|
|
546
|
-
},
|
|
547
|
-
},
|
|
548
|
-
},
|
|
549
|
-
'200': {
|
|
550
|
-
description: 'returns the number of deleted rows ' + key,
|
|
551
|
-
content: {
|
|
552
|
-
'application/json': {
|
|
553
|
-
schema: {
|
|
554
|
-
type: 'object',
|
|
555
|
-
properties: {
|
|
556
|
-
deleted: {
|
|
557
|
-
type: 'number',
|
|
558
|
-
},
|
|
559
|
-
},
|
|
560
|
-
},
|
|
561
|
-
},
|
|
562
|
-
},
|
|
563
|
-
},
|
|
564
|
-
},
|
|
565
|
-
});
|
|
566
|
-
apiPath.put = secure(meta.options.allowApiDelete, true, {
|
|
567
|
-
description: 'updates row of ' +
|
|
568
|
-
key +
|
|
569
|
-
'. supports filter operators. For more info on filtering [see this article](https://remult.dev/docs/rest-api.html#filter)',
|
|
570
|
-
parameters: [...parameters],
|
|
571
|
-
...itemInBody,
|
|
572
|
-
responses: {
|
|
573
|
-
'400': {
|
|
574
|
-
description: 'Error: Bad Request',
|
|
575
|
-
content: {
|
|
576
|
-
'application/json': {
|
|
577
|
-
schema: {
|
|
578
|
-
$ref: '#/components/schemas/InvalidResponse',
|
|
579
|
-
},
|
|
580
|
-
},
|
|
581
|
-
},
|
|
582
|
-
},
|
|
583
|
-
'200': {
|
|
584
|
-
description: 'returns the number of updated rows ' + key,
|
|
585
|
-
content: {
|
|
586
|
-
'application/json': {
|
|
587
|
-
schema: {
|
|
588
|
-
type: 'object',
|
|
589
|
-
properties: {
|
|
590
|
-
updated: {
|
|
591
|
-
type: 'number',
|
|
592
|
-
},
|
|
593
|
-
},
|
|
594
|
-
},
|
|
595
|
-
},
|
|
596
|
-
},
|
|
597
|
-
},
|
|
598
|
-
},
|
|
599
|
-
});
|
|
600
521
|
let idParameter = {
|
|
601
522
|
name: 'id',
|
|
602
523
|
in: 'path',
|
|
@@ -604,6 +525,17 @@ export class RemultServerImplementation {
|
|
|
604
525
|
required: true,
|
|
605
526
|
schema: { type: 'string' },
|
|
606
527
|
};
|
|
528
|
+
let itemInBody = {
|
|
529
|
+
requestBody: {
|
|
530
|
+
content: {
|
|
531
|
+
'application/json': {
|
|
532
|
+
schema: {
|
|
533
|
+
$ref: '#/components/schemas/' + mutationKey,
|
|
534
|
+
},
|
|
535
|
+
},
|
|
536
|
+
},
|
|
537
|
+
},
|
|
538
|
+
};
|
|
607
539
|
apiPath.post = secure(meta.options.allowApiInsert, false, {
|
|
608
540
|
//"summary": "insert a " + key,
|
|
609
541
|
//"description": "insert a " + key,
|
|
@@ -741,17 +673,15 @@ class ExpressRequestBridgeToDataApiRequest {
|
|
|
741
673
|
class ExpressResponseBridgeToDataApiResponse {
|
|
742
674
|
r;
|
|
743
675
|
req;
|
|
744
|
-
handleError;
|
|
745
676
|
forbidden() {
|
|
746
|
-
this.
|
|
677
|
+
this.setStatus(403).end();
|
|
747
678
|
}
|
|
748
679
|
setStatus(status) {
|
|
749
680
|
return this.r.status(status);
|
|
750
681
|
}
|
|
751
|
-
constructor(r, req
|
|
682
|
+
constructor(r, req) {
|
|
752
683
|
this.r = r;
|
|
753
684
|
this.req = req;
|
|
754
|
-
this.handleError = handleError;
|
|
755
685
|
}
|
|
756
686
|
progress(progress) { }
|
|
757
687
|
success(data) {
|
|
@@ -764,53 +694,22 @@ class ExpressResponseBridgeToDataApiResponse {
|
|
|
764
694
|
this.setStatus(204).end();
|
|
765
695
|
}
|
|
766
696
|
notFound() {
|
|
767
|
-
this.
|
|
697
|
+
this.setStatus(404).end();
|
|
768
698
|
}
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
exception.isForbiddenError) {
|
|
777
|
-
httpStatusCode = 403;
|
|
778
|
-
}
|
|
779
|
-
else if (data.modelState) {
|
|
780
|
-
httpStatusCode = 400;
|
|
781
|
-
}
|
|
782
|
-
else {
|
|
783
|
-
httpStatusCode = 500;
|
|
784
|
-
}
|
|
785
|
-
}
|
|
786
|
-
let responseSent = false;
|
|
787
|
-
const sendError = (httpStatusCode, body) => {
|
|
788
|
-
if (responseSent) {
|
|
789
|
-
throw Error('Error response already sent');
|
|
790
|
-
}
|
|
791
|
-
responseSent = true;
|
|
792
|
-
console.error({
|
|
793
|
-
message: body.message,
|
|
794
|
-
httpStatusCode,
|
|
795
|
-
stack: data.stack?.split('\n'),
|
|
796
|
-
url: this.req?.url,
|
|
797
|
-
method: this.req?.method,
|
|
798
|
-
});
|
|
799
|
-
this.setStatus(httpStatusCode).json(body);
|
|
800
|
-
};
|
|
801
|
-
await this.handleError?.({
|
|
802
|
-
httpStatusCode,
|
|
803
|
-
req: this.req,
|
|
804
|
-
entity,
|
|
805
|
-
exception,
|
|
806
|
-
responseBody: data,
|
|
807
|
-
sendError,
|
|
699
|
+
error(data) {
|
|
700
|
+
data = serializeError(data);
|
|
701
|
+
console.error({
|
|
702
|
+
message: data.message,
|
|
703
|
+
stack: data.stack?.split('\n'),
|
|
704
|
+
url: this.req?.url,
|
|
705
|
+
method: this.req?.method,
|
|
808
706
|
});
|
|
809
|
-
|
|
810
|
-
sendError(httpStatusCode, data);
|
|
811
|
-
}
|
|
707
|
+
this.setStatus(400).json(data);
|
|
812
708
|
}
|
|
813
709
|
}
|
|
710
|
+
function throwError() {
|
|
711
|
+
throw 'Invalid';
|
|
712
|
+
}
|
|
814
713
|
class inProcessQueueHandler {
|
|
815
714
|
storage;
|
|
816
715
|
constructor(storage) {
|
|
@@ -22,17 +22,11 @@ export class CompoundIdField {
|
|
|
22
22
|
return Promise.resolve('');
|
|
23
23
|
}
|
|
24
24
|
getId(instance) {
|
|
25
|
-
let get = (field) => {
|
|
26
|
-
return instance[field.key];
|
|
27
|
-
};
|
|
28
|
-
if (typeof instance === 'function') {
|
|
29
|
-
get = instance;
|
|
30
|
-
}
|
|
31
25
|
let r = '';
|
|
32
26
|
this.fields.forEach((c) => {
|
|
33
27
|
if (r.length > 0)
|
|
34
28
|
r += ',';
|
|
35
|
-
r += c.
|
|
29
|
+
r += instance[c.key];
|
|
36
30
|
});
|
|
37
31
|
return r;
|
|
38
32
|
}
|
|
@@ -55,7 +49,7 @@ export class CompoundIdField {
|
|
|
55
49
|
let val = value.toString();
|
|
56
50
|
let id = val.split(',');
|
|
57
51
|
this.fields.forEach((c, i) => {
|
|
58
|
-
result[c.key] =
|
|
52
|
+
result[c.key] = id[i];
|
|
59
53
|
});
|
|
60
54
|
return result;
|
|
61
55
|
}
|