remult 0.26.3 → 0.26.5-exp.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/postgres/schema-builder.js +3 -2
- package/esm/remult-knex/index.js +2 -8
- package/esm/remult-mongo.js +1 -7
- package/esm/remult-sqlite-core.js +1 -1
- package/esm/server/remult-admin.js +2 -7
- package/esm/src/data-providers/sql-database.js +1 -11
- package/esm/src/filter/filter-consumer-bridge-to-sql-request.js +9 -1
- package/esm/src/remult3/Fields.js +15 -9
- package/esm/src/remult3/RepositoryImplementation.js +21 -12
- package/esm/src/remult3/remult3.js +14 -6
- package/esm/src/validators.js +9 -5
- package/package.json +1 -1
- package/postgres/schema-builder.js +3 -2
- package/remult-knex/index.js +2 -8
- package/remult-mongo.js +24 -40
- package/remult-sqlite-core.js +1 -1
- package/server/expressBridge.d.ts +4 -1
- package/server/remult-admin.js +10 -15
- package/src/data-providers/sql-database.js +5 -18
- package/src/entity.d.ts +13 -1
- package/src/filter/filter-consumer-bridge-to-sql-request.js +15 -5
- package/src/remult3/Fields.d.ts +4 -4
- package/src/remult3/Fields.js +27 -13
- package/src/remult3/RepositoryImplementation.d.ts +4 -2
- package/src/remult3/RepositoryImplementation.js +22 -14
- package/src/remult3/remult3.d.ts +3 -1
- package/src/remult3/remult3.js +14 -6
- package/src/validators.js +12 -8
- package/esm/src/resultCompoundIdFilter.js +0 -16
- package/src/resultCompoundIdFilter.d.ts +0 -3
- package/src/resultCompoundIdFilter.js +0 -20
|
@@ -155,10 +155,11 @@ export class PostgresSchemaBuilder {
|
|
|
155
155
|
else {
|
|
156
156
|
result += postgresColumnSyntax(x, e.$dbNameOf(x));
|
|
157
157
|
}
|
|
158
|
-
if (x == entity.idMetadata.field)
|
|
159
|
-
result += ' primary key';
|
|
160
158
|
}
|
|
161
159
|
}
|
|
160
|
+
result += `,\r\n primary key (${entity.idMetadata.fields
|
|
161
|
+
.map((f) => e.$dbNameOf(f))
|
|
162
|
+
.join(',')})`;
|
|
162
163
|
let sql = `CREATE SCHEMA IF NOT EXISTS ${this.schemaOnly(e)};
|
|
163
164
|
CREATE table ${this.schemaAndName(e)} (${result}\r\n)`;
|
|
164
165
|
return sql;
|
package/esm/remult-knex/index.js
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { CustomSqlFilterBuilder, } from '../src/filter/filter-consumer-bridge-to-sql-request.js';
|
|
2
2
|
import { dbNamesOf, isDbReadonly, shouldCreateEntity, shouldNotCreateField, } from '../src/filter/filter-consumer-bridge-to-sql-request.js';
|
|
3
3
|
import { customDatabaseFilterToken, Filter, } from '../src/filter/filter-interfaces.js';
|
|
4
|
-
import { CompoundIdField } from '../src/CompoundIdField.js';
|
|
5
4
|
import { remult as remultContext } from '../src/remult-proxy.js';
|
|
6
5
|
import { getRepository, isAutoIncrement, } from '../src/remult3/RepositoryImplementation.js';
|
|
7
6
|
import { Sort } from '../src/sort.js';
|
|
8
7
|
import { ValueConverters } from '../src/valueConverters.js';
|
|
9
|
-
import { resultCompoundIdFilter as resultCompoundIdFilter } from '../src/resultCompoundIdFilter.js';
|
|
10
8
|
import { getRepositoryInternals } from '../src/remult3/repository-internals.js';
|
|
11
9
|
import { remultStatic } from '../src/remult-static.js';
|
|
12
10
|
export class KnexDataProvider {
|
|
@@ -233,10 +231,7 @@ class KnexEntityDataProvider {
|
|
|
233
231
|
async insert(data) {
|
|
234
232
|
const e = await this.init();
|
|
235
233
|
let resultFilter;
|
|
236
|
-
|
|
237
|
-
resultFilter = resultCompoundIdFilter(this.entity.idMetadata.field, undefined, data);
|
|
238
|
-
else
|
|
239
|
-
resultFilter = Filter.fromEntityFilter(this.entity, this.entity.idMetadata.getIdFilter(data[this.entity.idMetadata.field.key]));
|
|
234
|
+
resultFilter = Filter.fromEntityFilter(this.entity, this.entity.idMetadata.getIdFilter(data[this.entity.idMetadata.field.key]));
|
|
240
235
|
let insertObject = {};
|
|
241
236
|
for (const x of this.entity.fields) {
|
|
242
237
|
if (isDbReadonly(x, e)) {
|
|
@@ -426,11 +421,10 @@ export class KnexSchemaBuilder {
|
|
|
426
421
|
b.increments(cols.get(x).name);
|
|
427
422
|
else {
|
|
428
423
|
buildColumn(x, cols.get(x).name, b, supportsJsonDataStorage(this.knex));
|
|
429
|
-
if (x == entity.idMetadata.field)
|
|
430
|
-
b.primary([cols.get(x).name]);
|
|
431
424
|
}
|
|
432
425
|
}
|
|
433
426
|
}
|
|
427
|
+
b.primary(entity.idMetadata.fields.map((f) => e.$dbNameOf(f)));
|
|
434
428
|
});
|
|
435
429
|
}
|
|
436
430
|
async addColumnIfNotExist(entity, c) {
|
package/esm/remult-mongo.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { ObjectId, } from 'mongodb';
|
|
2
|
-
import {
|
|
2
|
+
import { Filter } from './index.js';
|
|
3
3
|
import { dbNamesOf } from './src/filter/filter-consumer-bridge-to-sql-request.js';
|
|
4
4
|
import { remult as remultContext } from './src/remult-proxy.js';
|
|
5
5
|
import { getRepository } from './src/remult3/RepositoryImplementation.js';
|
|
6
|
-
import { resultCompoundIdFilter } from './src/resultCompoundIdFilter.js';
|
|
7
6
|
import { getRepositoryInternals } from './src/remult3/repository-internals.js';
|
|
8
7
|
export class MongoDataProvider {
|
|
9
8
|
db;
|
|
@@ -130,11 +129,6 @@ class MongoEntityDataProvider {
|
|
|
130
129
|
let resultFilter = this.entity.idMetadata.getIdFilter(id);
|
|
131
130
|
if (data.id != undefined)
|
|
132
131
|
resultFilter = this.entity.idMetadata.getIdFilter(data.id);
|
|
133
|
-
for (const x of this.entity.fields) {
|
|
134
|
-
if (x instanceof CompoundIdField) {
|
|
135
|
-
resultFilter = resultCompoundIdFilter(x, id, data);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
132
|
let newR = {};
|
|
139
133
|
let keys = Object.keys(data);
|
|
140
134
|
for (const f of this.entity.fields) {
|
|
@@ -84,7 +84,7 @@ export class SqliteCoreDataProvider {
|
|
|
84
84
|
result += '\r\n ';
|
|
85
85
|
if (isAutoIncrement(x)) {
|
|
86
86
|
if (x.key != entity.idMetadata.field.key)
|
|
87
|
-
throw 'in
|
|
87
|
+
throw 'in sqlite, autoincrement is only allowed for primary key';
|
|
88
88
|
result += e.$dbNameOf(x) + ' integer primary key autoincrement';
|
|
89
89
|
}
|
|
90
90
|
else {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { CompoundIdField } from '../src/CompoundIdField.js';
|
|
2
1
|
import { getRelationFieldInfo, } from '../src/remult3/relationInfoMember.js';
|
|
3
2
|
import { Filter } from '../src/filter/filter-interfaces.js';
|
|
4
3
|
import { getHtml } from './get-remult-admin-html.js';
|
|
@@ -17,13 +16,9 @@ export function buildEntityInfo(options) {
|
|
|
17
16
|
let fields = [];
|
|
18
17
|
let relations = [];
|
|
19
18
|
let ids = {};
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
ids[field.key] = true;
|
|
23
|
-
}
|
|
19
|
+
for (const f of metadata.idMetadata.fields) {
|
|
20
|
+
ids[f.key] = true;
|
|
24
21
|
}
|
|
25
|
-
else
|
|
26
|
-
ids[metadata.idMetadata.field.key] = true;
|
|
27
22
|
for (const x of metadata.fields.toArray()) {
|
|
28
23
|
if (!x.includedInApi(undefined))
|
|
29
24
|
continue;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { CompoundIdField } from '../CompoundIdField.js';
|
|
2
1
|
import { FilterConsumerBridgeToSqlRequest, dbNamesOf, isDbReadonly, } from '../filter/filter-consumer-bridge-to-sql-request.js';
|
|
3
2
|
import { Filter, customDatabaseFilterToken, } from '../filter/filter-interfaces.js';
|
|
4
3
|
import { remult as defaultRemult } from '../remult-proxy.js';
|
|
@@ -256,14 +255,7 @@ class ActualSQLServerDataProvider {
|
|
|
256
255
|
let first = true;
|
|
257
256
|
let segs = [];
|
|
258
257
|
for (const s of options.orderBy.Segments) {
|
|
259
|
-
|
|
260
|
-
segs.push(...s.field.fields.map((c) => ({
|
|
261
|
-
field: c,
|
|
262
|
-
isDescending: s.isDescending,
|
|
263
|
-
})));
|
|
264
|
-
}
|
|
265
|
-
else
|
|
266
|
-
segs.push(s);
|
|
258
|
+
segs.push(s);
|
|
267
259
|
}
|
|
268
260
|
for (const c of segs) {
|
|
269
261
|
if (first) {
|
|
@@ -336,8 +328,6 @@ class ActualSQLServerDataProvider {
|
|
|
336
328
|
let statement = 'update ' + e.$entityName + ' set ';
|
|
337
329
|
let added = false;
|
|
338
330
|
for (const x of this.entity.fields) {
|
|
339
|
-
if (x instanceof CompoundIdField) {
|
|
340
|
-
}
|
|
341
331
|
if (isDbReadonly(x, e)) {
|
|
342
332
|
}
|
|
343
333
|
else if (data[x.key] !== undefined) {
|
|
@@ -229,7 +229,15 @@ export async function entityDbName(metadata, wrapIdentifier = (x) => x) {
|
|
|
229
229
|
if (typeof metadata.options.sqlExpression === 'string')
|
|
230
230
|
return metadata.options.sqlExpression;
|
|
231
231
|
else if (typeof metadata.options.sqlExpression === 'function') {
|
|
232
|
-
|
|
232
|
+
const prev = metadata.options.sqlExpression;
|
|
233
|
+
try {
|
|
234
|
+
metadata.options.sqlExpression =
|
|
235
|
+
"recursive sqlExpression call for entity '" + metadata.key + "'. ";
|
|
236
|
+
return await prev(metadata);
|
|
237
|
+
}
|
|
238
|
+
finally {
|
|
239
|
+
metadata.options.sqlExpression = prev;
|
|
240
|
+
}
|
|
233
241
|
}
|
|
234
242
|
}
|
|
235
243
|
return wrapIdentifier(metadata.dbName);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { createId } from '@paralleldrive/cuid2';
|
|
2
2
|
import { v4 as uuid } from 'uuid';
|
|
3
3
|
import { ValueConverters } from '../valueConverters.js';
|
|
4
|
-
import { buildOptions } from './RepositoryImplementation.js';
|
|
5
|
-
import { Validators, createValueValidator, getEnumValues } from '../validators.js';
|
|
4
|
+
import { buildOptions, fieldOptionalValuesFunctionKey, } from './RepositoryImplementation.js';
|
|
5
|
+
import { Validators, createValueValidator, getEnumValues, } from '../validators.js';
|
|
6
6
|
import { relationInfoMemberInOptions } from './relationInfoMember.js';
|
|
7
7
|
import { remultStatic } from '../remult-static.js';
|
|
8
8
|
import { addValidator } from './addValidator.js';
|
|
@@ -84,10 +84,10 @@ export class Fields {
|
|
|
84
84
|
}, ...options);
|
|
85
85
|
}
|
|
86
86
|
/**
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
87
|
+
* A CUID (Collision Resistant Unique Identifier) field.
|
|
88
|
+
* This id value is determined on the backend on insert, and can't be updated through the API.
|
|
89
|
+
* The CUID is generated using the `@paralleldrive/cuid2` npm package.
|
|
90
|
+
*/
|
|
91
91
|
static cuid(...options) {
|
|
92
92
|
return Field(() => String, {
|
|
93
93
|
allowApiUpdate: false,
|
|
@@ -129,7 +129,9 @@ export class Fields {
|
|
|
129
129
|
*/
|
|
130
130
|
static literal(optionalValues, ...options) {
|
|
131
131
|
return Fields.string({
|
|
132
|
-
validate: (entity, event) => Validators.in(optionalValues())(entity, event)
|
|
132
|
+
validate: (entity, event) => Validators.in(optionalValues())(entity, event),
|
|
133
|
+
//@ts-expect-error as we are adding this to options without it being defined in options
|
|
134
|
+
[fieldOptionalValuesFunctionKey]: optionalValues,
|
|
133
135
|
}, ...options);
|
|
134
136
|
}
|
|
135
137
|
static enum(enumType, ...options) {
|
|
@@ -137,12 +139,16 @@ export class Fields {
|
|
|
137
139
|
return Field(() =>
|
|
138
140
|
//@ts-ignore
|
|
139
141
|
enumType(), {
|
|
140
|
-
validate: (entity, event) => Validators.enum(enumType())(entity, event)
|
|
142
|
+
validate: (entity, event) => Validators.enum(enumType())(entity, event),
|
|
143
|
+
[fieldOptionalValuesFunctionKey]: () => getEnumValues(enumType()),
|
|
141
144
|
}, ...options, (options) => {
|
|
145
|
+
options[fieldOptionalValuesFunctionKey] = () => getEnumValues(enumType());
|
|
142
146
|
if (valueConverter === undefined) {
|
|
143
147
|
let enumObj = enumType();
|
|
144
148
|
let enumValues = getEnumValues(enumObj);
|
|
145
|
-
valueConverter = enumValues.find(x => typeof x ===
|
|
149
|
+
valueConverter = enumValues.find((x) => typeof x === 'string')
|
|
150
|
+
? ValueConverters.String
|
|
151
|
+
: ValueConverters.Integer;
|
|
146
152
|
}
|
|
147
153
|
if (!options.valueConverter) {
|
|
148
154
|
options.valueConverter = valueConverter;
|
|
@@ -16,6 +16,7 @@ import { entityDbName, fieldDbName, } from '../filter/filter-consumer-bridge-to-
|
|
|
16
16
|
import { remultStatic } from '../remult-static.js';
|
|
17
17
|
import { Validators } from '../validators.js';
|
|
18
18
|
import { addValidator } from './addValidator.js';
|
|
19
|
+
import { isOfType } from '../isOfType.js';
|
|
19
20
|
//import { remult } from "../remult-proxy";
|
|
20
21
|
let classValidatorValidate = undefined;
|
|
21
22
|
// import ("class-validator".toString())
|
|
@@ -271,7 +272,7 @@ export class RepositoryImplementation {
|
|
|
271
272
|
}
|
|
272
273
|
}
|
|
273
274
|
}
|
|
274
|
-
async updateMany({ where
|
|
275
|
+
async updateMany({ where, set, }) {
|
|
275
276
|
Filter.throwErrorIfFilterIsEmpty(where, 'updateMany');
|
|
276
277
|
if (this._dataProvider.isProxy) {
|
|
277
278
|
return this._edp.updateMany(await this._translateWhereToFilter(where), set);
|
|
@@ -1927,6 +1928,11 @@ class EntityFullInfo {
|
|
|
1927
1928
|
return item[this.idMetadata.field.key];
|
|
1928
1929
|
},
|
|
1929
1930
|
field: undefined,
|
|
1931
|
+
get fields() {
|
|
1932
|
+
return this.field instanceof CompoundIdField
|
|
1933
|
+
? this.field.fields
|
|
1934
|
+
: [this.field];
|
|
1935
|
+
},
|
|
1930
1936
|
createIdInFilter: (items) => {
|
|
1931
1937
|
if (items.length > 0)
|
|
1932
1938
|
return {
|
|
@@ -2079,19 +2085,22 @@ export class ValueListInfo {
|
|
|
2079
2085
|
}
|
|
2080
2086
|
const typeCache = new Map();
|
|
2081
2087
|
export function getValueList(type) {
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2088
|
+
let meta = type?.metadata;
|
|
2089
|
+
if (!meta && isOfType(type, 'options'))
|
|
2090
|
+
meta = type;
|
|
2091
|
+
type = meta?.valueType || type;
|
|
2092
|
+
if (type) {
|
|
2093
|
+
var options = type[storableMember];
|
|
2094
|
+
if (options)
|
|
2095
|
+
return ValueListInfo.get(type).getValues();
|
|
2096
|
+
}
|
|
2097
|
+
let optionalValues = meta?.options[fieldOptionalValuesFunctionKey];
|
|
2098
|
+
if (optionalValues)
|
|
2099
|
+
return optionalValues();
|
|
2100
|
+
return undefined;
|
|
2093
2101
|
}
|
|
2094
2102
|
export const storableMember = Symbol.for('storableMember');
|
|
2103
|
+
export const fieldOptionalValuesFunctionKey = Symbol.for('fieldOptionalValues');
|
|
2095
2104
|
export function buildOptions(options, remult) {
|
|
2096
2105
|
let r = {};
|
|
2097
2106
|
for (const o of options) {
|
|
@@ -1,22 +1,31 @@
|
|
|
1
1
|
export {};
|
|
2
2
|
//y1 - https://discord.com/channels/975754286384418847/1230386433093533698/1230386433093533698
|
|
3
3
|
//y1 - fix async hooks - was it fixed?
|
|
4
|
+
//y1 - repo batch - for multiple operations:
|
|
5
|
+
/*
|
|
6
|
+
const result = await repo.batch(x=>({
|
|
7
|
+
data:x.find(),
|
|
8
|
+
count:x.count()
|
|
9
|
+
}))
|
|
10
|
+
*/
|
|
11
|
+
//p1 - adjust react tutorial to esm
|
|
12
|
+
//p1 - add solid tutorial to the getting started page
|
|
13
|
+
//p1 - update the examples section
|
|
14
|
+
//p1 - add documentation for bun sqlite
|
|
4
15
|
//p1 - consider upsert (where,set)
|
|
5
|
-
//p1 - consider id to also support keyof (id:['company','index'])
|
|
6
16
|
//p1 - wait a second to close stream
|
|
7
|
-
//
|
|
8
|
-
//p1 - add documentation for bun sqlite
|
|
17
|
+
//y1 - consider id to also support keyof (id:['company','index']) - had problem with | (keyof Partial<entityType>)[] & `entity`
|
|
9
18
|
//p1 - describe entity
|
|
10
19
|
//p1 - prepare the createEntity discussion
|
|
11
20
|
//p1 - write active record article
|
|
12
|
-
//p1 - maybe add decorator comment in the readme as well (I heard you've lost me in decorators) - and improve the describeClass function
|
|
13
21
|
//p1 - return error on connection error
|
|
14
22
|
//p1 - consider including the admin in the tutorial - and maybe even in the demo when we setup the api
|
|
23
|
+
//p1 - reconsider key typing to be keyof & string
|
|
15
24
|
//p2 -fix remult admin not to load the html into memory until used
|
|
16
25
|
//y2 - JY suggestion of having generate as part of the ensure schema - not sure
|
|
17
26
|
//y2 - currently for string fields we default for 255 in knex (which is their default) why not just use text (varchar max) - and only use exact length when one is provided?
|
|
18
27
|
//p2 - create foreign key constraints in user code - https://codesandbox.io/p/devbox/fk-validator-tdshcs
|
|
19
|
-
//
|
|
28
|
+
//p2 - admin url1 - pocketbase use /_ for the admin //{allowed?:Allowed,url?:string} also checkout the admin* as it should probably be something else and didn't work in hono
|
|
20
29
|
//p1 - article auth.js with express - played with it, requires type="module" and a few more configurations - https://github.com/noam-honig/express-auth
|
|
21
30
|
//y2 - fix validators cache
|
|
22
31
|
//y2 - should we validate relations
|
|
@@ -88,4 +97,3 @@ export {};
|
|
|
88
97
|
//y2 - add some api testing framework for user unit tests (will help with codesandbox based discussions)
|
|
89
98
|
//[ ] V2 - what to do about for relations count?
|
|
90
99
|
//[ ] V2 - condition? not to fetch if null etc....
|
|
91
|
-
//p1 - adjust react tutorial to esm
|
package/esm/src/validators.js
CHANGED
|
@@ -26,10 +26,15 @@ export class Validators {
|
|
|
26
26
|
static regex = createValueValidatorWithArgs((val, regex) => regex.test(val));
|
|
27
27
|
static email = createValueValidator((val) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(val), 'Invalid Email');
|
|
28
28
|
static url = createValueValidator((val) => !!new URL(val), 'Invalid Url');
|
|
29
|
-
static in = createValueValidatorWithArgs((val, values) => values.includes(val), (values) => `Value must be one of ${values
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
static in = createValueValidatorWithArgs((val, values) => values.includes(val), (values) => `Value must be one of: ${values
|
|
30
|
+
.map((y) => typeof y === 'object'
|
|
31
|
+
? y['id'] !== undefined
|
|
32
|
+
? y['id']
|
|
33
|
+
: y.toString()
|
|
34
|
+
: y)
|
|
32
35
|
.join(', ')}`);
|
|
36
|
+
static notNull = createValueValidator((val) => val != null, 'Should not be null');
|
|
37
|
+
static enum = createValueValidatorWithArgs((value, enumObj) => Object.values(enumObj).includes(value), (enumObj) => `Value must be one of ${getEnumValues(enumObj).join(', ')}`);
|
|
33
38
|
static relationExists = createValidator(async (_, e) => {
|
|
34
39
|
if (e.valueIsNull())
|
|
35
40
|
return true;
|
|
@@ -134,6 +139,5 @@ function createValidatorWithArgsInternal(validate, defaultMessage, isValueValida
|
|
|
134
139
|
});
|
|
135
140
|
}
|
|
136
141
|
export function getEnumValues(enumObj) {
|
|
137
|
-
return Object.values(enumObj)
|
|
138
|
-
.filter((x) => typeof enumObj[x] !== 'number');
|
|
142
|
+
return Object.values(enumObj).filter((x) => typeof enumObj[x] !== 'number');
|
|
139
143
|
}
|
package/package.json
CHANGED
|
@@ -287,8 +287,6 @@ var PostgresSchemaBuilder = /** @class */ (function () {
|
|
|
287
287
|
else {
|
|
288
288
|
result += postgresColumnSyntax(x, e.$dbNameOf(x));
|
|
289
289
|
}
|
|
290
|
-
if (x == entity.idMetadata.field)
|
|
291
|
-
result += ' primary key';
|
|
292
290
|
}
|
|
293
291
|
}
|
|
294
292
|
}
|
|
@@ -299,6 +297,9 @@ var PostgresSchemaBuilder = /** @class */ (function () {
|
|
|
299
297
|
}
|
|
300
298
|
finally { if (e_3) throw e_3.error; }
|
|
301
299
|
}
|
|
300
|
+
result += ",\r\n primary key (".concat(entity.idMetadata.fields
|
|
301
|
+
.map(function (f) { return e.$dbNameOf(f); })
|
|
302
|
+
.join(','), ")");
|
|
302
303
|
sql = "CREATE SCHEMA IF NOT EXISTS ".concat(this.schemaOnly(e), ";\nCREATE table ").concat(this.schemaAndName(e), " (").concat(result, "\r\n)");
|
|
303
304
|
return [2 /*return*/, sql];
|
|
304
305
|
}
|
package/remult-knex/index.js
CHANGED
|
@@ -5,12 +5,10 @@ var tslib_1 = require("tslib");
|
|
|
5
5
|
var filter_consumer_bridge_to_sql_request_js_1 = require("../src/filter/filter-consumer-bridge-to-sql-request.js");
|
|
6
6
|
var filter_consumer_bridge_to_sql_request_js_2 = require("../src/filter/filter-consumer-bridge-to-sql-request.js");
|
|
7
7
|
var filter_interfaces_js_1 = require("../src/filter/filter-interfaces.js");
|
|
8
|
-
var CompoundIdField_js_1 = require("../src/CompoundIdField.js");
|
|
9
8
|
var remult_proxy_js_1 = require("../src/remult-proxy.js");
|
|
10
9
|
var RepositoryImplementation_js_1 = require("../src/remult3/RepositoryImplementation.js");
|
|
11
10
|
var sort_js_1 = require("../src/sort.js");
|
|
12
11
|
var valueConverters_js_1 = require("../src/valueConverters.js");
|
|
13
|
-
var resultCompoundIdFilter_js_1 = require("../src/resultCompoundIdFilter.js");
|
|
14
12
|
var repository_internals_js_1 = require("../src/remult3/repository-internals.js");
|
|
15
13
|
var remult_static_js_1 = require("../src/remult-static.js");
|
|
16
14
|
var KnexDataProvider = /** @class */ (function () {
|
|
@@ -422,10 +420,7 @@ var KnexEntityDataProvider = /** @class */ (function () {
|
|
|
422
420
|
case 0: return [4 /*yield*/, this.init()];
|
|
423
421
|
case 1:
|
|
424
422
|
e = _d.sent();
|
|
425
|
-
|
|
426
|
-
resultFilter = (0, resultCompoundIdFilter_js_1.resultCompoundIdFilter)(this.entity.idMetadata.field, undefined, data);
|
|
427
|
-
else
|
|
428
|
-
resultFilter = filter_interfaces_js_1.Filter.fromEntityFilter(this.entity, this.entity.idMetadata.getIdFilter(data[this.entity.idMetadata.field.key]));
|
|
423
|
+
resultFilter = filter_interfaces_js_1.Filter.fromEntityFilter(this.entity, this.entity.idMetadata.getIdFilter(data[this.entity.idMetadata.field.key]));
|
|
429
424
|
insertObject = {};
|
|
430
425
|
_d.label = 2;
|
|
431
426
|
case 2:
|
|
@@ -838,8 +833,6 @@ var KnexSchemaBuilder = /** @class */ (function () {
|
|
|
838
833
|
b.increments(cols.get(x).name);
|
|
839
834
|
else {
|
|
840
835
|
buildColumn(x, cols.get(x).name, b, supportsJsonDataStorage(_this.knex));
|
|
841
|
-
if (x == entity.idMetadata.field)
|
|
842
|
-
b.primary([cols.get(x).name]);
|
|
843
836
|
}
|
|
844
837
|
}
|
|
845
838
|
}
|
|
@@ -851,6 +844,7 @@ var KnexSchemaBuilder = /** @class */ (function () {
|
|
|
851
844
|
}
|
|
852
845
|
finally { if (e_10) throw e_10.error; }
|
|
853
846
|
}
|
|
847
|
+
b.primary(entity.idMetadata.fields.map(function (f) { return e.$dbNameOf(f); }));
|
|
854
848
|
});
|
|
855
849
|
};
|
|
856
850
|
KnexSchemaBuilder.prototype.addColumnIfNotExist = function (entity, c) {
|
package/remult-mongo.js
CHANGED
|
@@ -7,7 +7,6 @@ var index_js_1 = require("./index.js");
|
|
|
7
7
|
var filter_consumer_bridge_to_sql_request_js_1 = require("./src/filter/filter-consumer-bridge-to-sql-request.js");
|
|
8
8
|
var remult_proxy_js_1 = require("./src/remult-proxy.js");
|
|
9
9
|
var RepositoryImplementation_js_1 = require("./src/remult3/RepositoryImplementation.js");
|
|
10
|
-
var resultCompoundIdFilter_js_1 = require("./src/resultCompoundIdFilter.js");
|
|
11
10
|
var repository_internals_js_1 = require("./src/remult3/repository-internals.js");
|
|
12
11
|
var MongoDataProvider = /** @class */ (function () {
|
|
13
12
|
function MongoDataProvider(db, client, options) {
|
|
@@ -222,38 +221,23 @@ var MongoEntityDataProvider = /** @class */ (function () {
|
|
|
222
221
|
};
|
|
223
222
|
MongoEntityDataProvider.prototype.update = function (id, data) {
|
|
224
223
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
225
|
-
var _a, collection, e, f, resultFilter,
|
|
226
|
-
var e_4,
|
|
227
|
-
return tslib_1.__generator(this, function (
|
|
228
|
-
switch (
|
|
224
|
+
var _a, collection, e, f, resultFilter, newR, keys, _b, _c, f_1, r, _d, _e;
|
|
225
|
+
var e_4, _f;
|
|
226
|
+
return tslib_1.__generator(this, function (_g) {
|
|
227
|
+
switch (_g.label) {
|
|
229
228
|
case 0: return [4 /*yield*/, this.collection()];
|
|
230
229
|
case 1:
|
|
231
|
-
_a =
|
|
230
|
+
_a = _g.sent(), collection = _a.collection, e = _a.e;
|
|
232
231
|
f = new FilterConsumerBridgeToMongo(e);
|
|
233
232
|
index_js_1.Filter.fromEntityFilter(this.entity, this.entity.idMetadata.getIdFilter(id)).__applyToConsumer(f);
|
|
234
233
|
resultFilter = this.entity.idMetadata.getIdFilter(id);
|
|
235
234
|
if (data.id != undefined)
|
|
236
235
|
resultFilter = this.entity.idMetadata.getIdFilter(data.id);
|
|
237
|
-
try {
|
|
238
|
-
for (_b = tslib_1.__values(this.entity.fields), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
239
|
-
x = _c.value;
|
|
240
|
-
if (x instanceof index_js_1.CompoundIdField) {
|
|
241
|
-
resultFilter = (0, resultCompoundIdFilter_js_1.resultCompoundIdFilter)(x, id, data);
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
catch (e_4_1) { e_4 = { error: e_4_1 }; }
|
|
246
|
-
finally {
|
|
247
|
-
try {
|
|
248
|
-
if (_c && !_c.done && (_h = _b.return)) _h.call(_b);
|
|
249
|
-
}
|
|
250
|
-
finally { if (e_4) throw e_4.error; }
|
|
251
|
-
}
|
|
252
236
|
newR = {};
|
|
253
237
|
keys = Object.keys(data);
|
|
254
238
|
try {
|
|
255
|
-
for (
|
|
256
|
-
f_1 =
|
|
239
|
+
for (_b = tslib_1.__values(this.entity.fields), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
240
|
+
f_1 = _c.value;
|
|
257
241
|
if (!f_1.dbReadOnly && !f_1.isServerExpression) {
|
|
258
242
|
if (keys.includes(f_1.key)) {
|
|
259
243
|
newR[f_1.key] = toDb(f_1, data[f_1.key]);
|
|
@@ -261,21 +245,21 @@ var MongoEntityDataProvider = /** @class */ (function () {
|
|
|
261
245
|
}
|
|
262
246
|
}
|
|
263
247
|
}
|
|
264
|
-
catch (
|
|
248
|
+
catch (e_4_1) { e_4 = { error: e_4_1 }; }
|
|
265
249
|
finally {
|
|
266
250
|
try {
|
|
267
|
-
if (
|
|
251
|
+
if (_c && !_c.done && (_f = _b.return)) _f.call(_b);
|
|
268
252
|
}
|
|
269
|
-
finally { if (
|
|
253
|
+
finally { if (e_4) throw e_4.error; }
|
|
270
254
|
}
|
|
271
|
-
|
|
255
|
+
_e = (_d = collection).updateOne;
|
|
272
256
|
return [4 /*yield*/, f.resolveWhere()];
|
|
273
|
-
case 2: return [4 /*yield*/,
|
|
257
|
+
case 2: return [4 /*yield*/, _e.apply(_d, [_g.sent(), {
|
|
274
258
|
$set: newR,
|
|
275
259
|
},
|
|
276
260
|
{ session: this.session }])];
|
|
277
261
|
case 3:
|
|
278
|
-
r =
|
|
262
|
+
r = _g.sent();
|
|
279
263
|
return [2 /*return*/, this.find({
|
|
280
264
|
where: index_js_1.Filter.fromEntityFilter(this.entity, resultFilter),
|
|
281
265
|
}).then(function (y) { return y[0]; })];
|
|
@@ -350,8 +334,8 @@ var FilterConsumerBridgeToMongo = /** @class */ (function () {
|
|
|
350
334
|
}
|
|
351
335
|
FilterConsumerBridgeToMongo.prototype.resolveWhere = function () {
|
|
352
336
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
353
|
-
var p, p_1, p_1_1, pr,
|
|
354
|
-
var
|
|
337
|
+
var p, p_1, p_1_1, pr, e_5_1;
|
|
338
|
+
var e_5, _a;
|
|
355
339
|
return tslib_1.__generator(this, function (_b) {
|
|
356
340
|
switch (_b.label) {
|
|
357
341
|
case 0:
|
|
@@ -361,7 +345,7 @@ var FilterConsumerBridgeToMongo = /** @class */ (function () {
|
|
|
361
345
|
_b.label = 1;
|
|
362
346
|
case 1:
|
|
363
347
|
_b.trys.push([1, 6, 7, 8]);
|
|
364
|
-
p_1 = (
|
|
348
|
+
p_1 = (e_5 = void 0, tslib_1.__values(p)), p_1_1 = p_1.next();
|
|
365
349
|
_b.label = 2;
|
|
366
350
|
case 2:
|
|
367
351
|
if (!!p_1_1.done) return [3 /*break*/, 5];
|
|
@@ -375,14 +359,14 @@ var FilterConsumerBridgeToMongo = /** @class */ (function () {
|
|
|
375
359
|
return [3 /*break*/, 2];
|
|
376
360
|
case 5: return [3 /*break*/, 8];
|
|
377
361
|
case 6:
|
|
378
|
-
|
|
379
|
-
|
|
362
|
+
e_5_1 = _b.sent();
|
|
363
|
+
e_5 = { error: e_5_1 };
|
|
380
364
|
return [3 /*break*/, 8];
|
|
381
365
|
case 7:
|
|
382
366
|
try {
|
|
383
367
|
if (p_1_1 && !p_1_1.done && (_a = p_1.return)) _a.call(p_1);
|
|
384
368
|
}
|
|
385
|
-
finally { if (
|
|
369
|
+
finally { if (e_5) throw e_5.error; }
|
|
386
370
|
return [7 /*endfinally*/];
|
|
387
371
|
case 8: return [3 /*break*/, 0];
|
|
388
372
|
case 9:
|
|
@@ -401,8 +385,8 @@ var FilterConsumerBridgeToMongo = /** @class */ (function () {
|
|
|
401
385
|
FilterConsumerBridgeToMongo.prototype.or = function (orElements) {
|
|
402
386
|
var _this = this;
|
|
403
387
|
this.promises.push((function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
404
|
-
var result, orElements_1, orElements_1_1, element, f, where,
|
|
405
|
-
var
|
|
388
|
+
var result, orElements_1, orElements_1_1, element, f, where, e_6_1;
|
|
389
|
+
var e_6, _a;
|
|
406
390
|
var _b;
|
|
407
391
|
return tslib_1.__generator(this, function (_c) {
|
|
408
392
|
switch (_c.label) {
|
|
@@ -433,14 +417,14 @@ var FilterConsumerBridgeToMongo = /** @class */ (function () {
|
|
|
433
417
|
return [3 /*break*/, 2];
|
|
434
418
|
case 5: return [3 /*break*/, 8];
|
|
435
419
|
case 6:
|
|
436
|
-
|
|
437
|
-
|
|
420
|
+
e_6_1 = _c.sent();
|
|
421
|
+
e_6 = { error: e_6_1 };
|
|
438
422
|
return [3 /*break*/, 8];
|
|
439
423
|
case 7:
|
|
440
424
|
try {
|
|
441
425
|
if (orElements_1_1 && !orElements_1_1.done && (_a = orElements_1.return)) _a.call(orElements_1);
|
|
442
426
|
}
|
|
443
|
-
finally { if (
|
|
427
|
+
finally { if (e_6) throw e_6.error; }
|
|
444
428
|
return [7 /*endfinally*/];
|
|
445
429
|
case 8:
|
|
446
430
|
this.result.push(function () { return ({
|
package/remult-sqlite-core.js
CHANGED
|
@@ -184,7 +184,7 @@ var SqliteCoreDataProvider = /** @class */ (function () {
|
|
|
184
184
|
result += '\r\n ';
|
|
185
185
|
if ((0, RepositoryImplementation_js_1.isAutoIncrement)(x)) {
|
|
186
186
|
if (x.key != entity.idMetadata.field.key)
|
|
187
|
-
throw 'in
|
|
187
|
+
throw 'in sqlite, autoincrement is only allowed for primary key';
|
|
188
188
|
result += e.$dbNameOf(x) + ' integer primary key autoincrement';
|
|
189
189
|
}
|
|
190
190
|
else {
|
|
@@ -50,7 +50,10 @@ export interface RemultServerOptions<RequestType> {
|
|
|
50
50
|
/** When set to true, will display an admin ui in the `/api/admin` url.
|
|
51
51
|
* Can also be set to an arrow function for fine grained control
|
|
52
52
|
* @example
|
|
53
|
-
*
|
|
53
|
+
* admin: true
|
|
54
|
+
* @example
|
|
55
|
+
* admin: ()=> remult.isAllowed('admin')
|
|
56
|
+
* @see [allowed](http://remult.dev/docs/allowed.html)
|
|
54
57
|
*/
|
|
55
58
|
admin?: Allowed;
|
|
56
59
|
/** Storage to use for backend methods that use queue */
|
package/server/remult-admin.js
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.buildEntityInfo = void 0;
|
|
4
4
|
var tslib_1 = require("tslib");
|
|
5
|
-
var CompoundIdField_js_1 = require("../src/CompoundIdField.js");
|
|
6
5
|
var relationInfoMember_js_1 = require("../src/remult3/relationInfoMember.js");
|
|
7
6
|
var filter_interfaces_js_1 = require("../src/filter/filter-interfaces.js");
|
|
8
7
|
var get_remult_admin_html_js_1 = require("./get-remult-admin-html.js");
|
|
@@ -24,23 +23,19 @@ function buildEntityInfo(options) {
|
|
|
24
23
|
var fields = [];
|
|
25
24
|
var relations = [];
|
|
26
25
|
var ids = {};
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
ids[field.key] = true;
|
|
32
|
-
}
|
|
26
|
+
try {
|
|
27
|
+
for (var _g = (e_2 = void 0, tslib_1.__values(metadata.idMetadata.fields)), _h = _g.next(); !_h.done; _h = _g.next()) {
|
|
28
|
+
var f = _h.value;
|
|
29
|
+
ids[f.key] = true;
|
|
33
30
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
finally { if (e_2) throw e_2.error; }
|
|
31
|
+
}
|
|
32
|
+
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
33
|
+
finally {
|
|
34
|
+
try {
|
|
35
|
+
if (_h && !_h.done && (_b = _g.return)) _b.call(_g);
|
|
40
36
|
}
|
|
37
|
+
finally { if (e_2) throw e_2.error; }
|
|
41
38
|
}
|
|
42
|
-
else
|
|
43
|
-
ids[metadata.idMetadata.field.key] = true;
|
|
44
39
|
var _loop_1 = function (x) {
|
|
45
40
|
if (!x.includedInApi(undefined))
|
|
46
41
|
return "continue";
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SqlDatabase = void 0;
|
|
4
4
|
var tslib_1 = require("tslib");
|
|
5
|
-
var CompoundIdField_js_1 = require("../CompoundIdField.js");
|
|
6
5
|
var filter_consumer_bridge_to_sql_request_js_1 = require("../filter/filter-consumer-bridge-to-sql-request.js");
|
|
7
6
|
var filter_interfaces_js_1 = require("../filter/filter-interfaces.js");
|
|
8
7
|
var remult_proxy_js_1 = require("../remult-proxy.js");
|
|
@@ -343,7 +342,7 @@ var ActualSQLServerDataProvider = /** @class */ (function () {
|
|
|
343
342
|
};
|
|
344
343
|
ActualSQLServerDataProvider.prototype.find = function (options) {
|
|
345
344
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
346
|
-
var e, _a, colKeys, select, r, where, _b, first, segs,
|
|
345
|
+
var e, _a, colKeys, select, r, where, _b, first, segs, _c, _d, s, segs_1, segs_1_1, c, page;
|
|
347
346
|
var e_2, _e, e_3, _f;
|
|
348
347
|
var _this = this;
|
|
349
348
|
return tslib_1.__generator(this, function (_g) {
|
|
@@ -374,20 +373,10 @@ var ActualSQLServerDataProvider = /** @class */ (function () {
|
|
|
374
373
|
if (options.orderBy) {
|
|
375
374
|
first = true;
|
|
376
375
|
segs = [];
|
|
377
|
-
_loop_1 = function (s) {
|
|
378
|
-
if (s.field instanceof CompoundIdField_js_1.CompoundIdField) {
|
|
379
|
-
segs.push.apply(segs, tslib_1.__spreadArray([], tslib_1.__read(s.field.fields.map(function (c) { return ({
|
|
380
|
-
field: c,
|
|
381
|
-
isDescending: s.isDescending,
|
|
382
|
-
}); })), false));
|
|
383
|
-
}
|
|
384
|
-
else
|
|
385
|
-
segs.push(s);
|
|
386
|
-
};
|
|
387
376
|
try {
|
|
388
377
|
for (_c = tslib_1.__values(options.orderBy.Segments), _d = _c.next(); !_d.done; _d = _c.next()) {
|
|
389
378
|
s = _d.value;
|
|
390
|
-
|
|
379
|
+
segs.push(s);
|
|
391
380
|
}
|
|
392
381
|
}
|
|
393
382
|
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
@@ -502,8 +491,6 @@ var ActualSQLServerDataProvider = /** @class */ (function () {
|
|
|
502
491
|
try {
|
|
503
492
|
for (_a = tslib_1.__values(this.entity.fields), _b = _a.next(); !_b.done; _b = _a.next()) {
|
|
504
493
|
x = _b.value;
|
|
505
|
-
if (x instanceof CompoundIdField_js_1.CompoundIdField) {
|
|
506
|
-
}
|
|
507
494
|
if ((0, filter_consumer_bridge_to_sql_request_js_1.isDbReadonly)(x, e)) {
|
|
508
495
|
}
|
|
509
496
|
else if (data[x.key] !== undefined) {
|
|
@@ -652,14 +639,14 @@ var myDummySQLCommand = /** @class */ (function () {
|
|
|
652
639
|
}());
|
|
653
640
|
function bulkInsert(array, db) {
|
|
654
641
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
655
|
-
var chunkSize,
|
|
642
|
+
var chunkSize, _loop_1, i;
|
|
656
643
|
return tslib_1.__generator(this, function (_a) {
|
|
657
644
|
switch (_a.label) {
|
|
658
645
|
case 0:
|
|
659
646
|
if (array.length == 0)
|
|
660
647
|
return [2 /*return*/];
|
|
661
648
|
chunkSize = 250;
|
|
662
|
-
|
|
649
|
+
_loop_1 = function (i) {
|
|
663
650
|
var items, c, sql, _b, _c;
|
|
664
651
|
return tslib_1.__generator(this, function (_d) {
|
|
665
652
|
switch (_d.label) {
|
|
@@ -697,7 +684,7 @@ function bulkInsert(array, db) {
|
|
|
697
684
|
_a.label = 1;
|
|
698
685
|
case 1:
|
|
699
686
|
if (!(i < array.length)) return [3 /*break*/, 4];
|
|
700
|
-
return [5 /*yield**/,
|
|
687
|
+
return [5 /*yield**/, _loop_1(i)];
|
|
701
688
|
case 2:
|
|
702
689
|
_a.sent();
|
|
703
690
|
_a.label = 3;
|
package/src/entity.d.ts
CHANGED
|
@@ -150,7 +150,19 @@ export interface EntityOptions<entityType = any> {
|
|
|
150
150
|
* dbName:'public."myProducts"'
|
|
151
151
|
*/
|
|
152
152
|
dbName?: string;
|
|
153
|
-
/** For entities that are based on SQL expressions instead of a physical table or view
|
|
153
|
+
/** For entities that are based on SQL expressions instead of a physical table or view
|
|
154
|
+
* @example
|
|
155
|
+
* .@Entity('people',{
|
|
156
|
+
* sqlExpression:`select id,name from employees
|
|
157
|
+
* union all select id,name from contractors`,
|
|
158
|
+
* })
|
|
159
|
+
* export class Person{
|
|
160
|
+
* .@Fields.string()
|
|
161
|
+
* id=''
|
|
162
|
+
* .@Fields.string()
|
|
163
|
+
* name=''
|
|
164
|
+
* }
|
|
165
|
+
*/
|
|
154
166
|
sqlExpression?: string | ((entity: EntityMetadata<entityType>) => string | Promise<string>);
|
|
155
167
|
/** An arrow function that identifies the `id` column to use for this entity
|
|
156
168
|
* @example
|
|
@@ -369,17 +369,27 @@ exports.dbNamesOf = dbNamesOf;
|
|
|
369
369
|
function entityDbName(metadata, wrapIdentifier) {
|
|
370
370
|
if (wrapIdentifier === void 0) { wrapIdentifier = function (x) { return x; }; }
|
|
371
371
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
372
|
+
var prev;
|
|
372
373
|
return tslib_1.__generator(this, function (_a) {
|
|
373
374
|
switch (_a.label) {
|
|
374
375
|
case 0:
|
|
375
|
-
if (!metadata.options.sqlExpression) return [3 /*break*/,
|
|
376
|
+
if (!metadata.options.sqlExpression) return [3 /*break*/, 5];
|
|
376
377
|
if (!(typeof metadata.options.sqlExpression === 'string')) return [3 /*break*/, 1];
|
|
377
378
|
return [2 /*return*/, metadata.options.sqlExpression];
|
|
378
379
|
case 1:
|
|
379
|
-
if (!(typeof metadata.options.sqlExpression === 'function')) return [3 /*break*/,
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
case
|
|
380
|
+
if (!(typeof metadata.options.sqlExpression === 'function')) return [3 /*break*/, 5];
|
|
381
|
+
prev = metadata.options.sqlExpression;
|
|
382
|
+
_a.label = 2;
|
|
383
|
+
case 2:
|
|
384
|
+
_a.trys.push([2, , 4, 5]);
|
|
385
|
+
metadata.options.sqlExpression =
|
|
386
|
+
"recursive sqlExpression call for entity '" + metadata.key + "'. ";
|
|
387
|
+
return [4 /*yield*/, prev(metadata)];
|
|
388
|
+
case 3: return [2 /*return*/, _a.sent()];
|
|
389
|
+
case 4:
|
|
390
|
+
metadata.options.sqlExpression = prev;
|
|
391
|
+
return [7 /*endfinally*/];
|
|
392
|
+
case 5: return [2 /*return*/, wrapIdentifier(metadata.dbName)];
|
|
383
393
|
}
|
|
384
394
|
});
|
|
385
395
|
});
|
package/src/remult3/Fields.d.ts
CHANGED
|
@@ -17,10 +17,10 @@ export declare class Fields {
|
|
|
17
17
|
static updatedAt<entityType = any>(...options: (FieldOptions<entityType, Date> | ((options: FieldOptions<entityType, Date>, remult: Remult) => void))[]): ClassFieldDecorator<entityType, Date | undefined>;
|
|
18
18
|
static uuid<entityType = any>(...options: (FieldOptions<entityType, string> | ((options: FieldOptions<entityType, string>, remult: Remult) => void))[]): ClassFieldDecorator<entityType, string | undefined>;
|
|
19
19
|
/**
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
* A CUID (Collision Resistant Unique Identifier) field.
|
|
21
|
+
* This id value is determined on the backend on insert, and can't be updated through the API.
|
|
22
|
+
* The CUID is generated using the `@paralleldrive/cuid2` npm package.
|
|
23
|
+
*/
|
|
24
24
|
static cuid<entityType = any>(...options: (FieldOptions<entityType, string> | ((options: FieldOptions<entityType, string>, remult: Remult) => void))[]): ClassFieldDecorator<entityType, string | undefined>;
|
|
25
25
|
/**
|
|
26
26
|
* Defines a field that can hold a value from a specified set of string literals.
|
package/src/remult3/Fields.js
CHANGED
|
@@ -87,7 +87,8 @@ var Fields = /** @class */ (function () {
|
|
|
87
87
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
88
88
|
options[_i] = arguments[_i];
|
|
89
89
|
}
|
|
90
|
-
return Field.apply(void 0, tslib_1.__spreadArray([function () { return Number; },
|
|
90
|
+
return Field.apply(void 0, tslib_1.__spreadArray([function () { return Number; },
|
|
91
|
+
{
|
|
91
92
|
validate: validateNumber,
|
|
92
93
|
}], tslib_1.__read(options), false));
|
|
93
94
|
};
|
|
@@ -135,10 +136,10 @@ var Fields = /** @class */ (function () {
|
|
|
135
136
|
}], tslib_1.__read(options), false));
|
|
136
137
|
};
|
|
137
138
|
/**
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
139
|
+
* A CUID (Collision Resistant Unique Identifier) field.
|
|
140
|
+
* This id value is determined on the backend on insert, and can't be updated through the API.
|
|
141
|
+
* The CUID is generated using the `@paralleldrive/cuid2` npm package.
|
|
142
|
+
*/
|
|
142
143
|
Fields.cuid = function () {
|
|
143
144
|
var options = [];
|
|
144
145
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
@@ -184,15 +185,22 @@ var Fields = /** @class */ (function () {
|
|
|
184
185
|
* // This approach allows easy management and updates of the allowed values for the `status` field.
|
|
185
186
|
*/
|
|
186
187
|
Fields.literal = function (optionalValues) {
|
|
188
|
+
var _a;
|
|
187
189
|
var options = [];
|
|
188
190
|
for (var _i = 1; _i < arguments.length; _i++) {
|
|
189
191
|
options[_i - 1] = arguments[_i];
|
|
190
192
|
}
|
|
191
|
-
return Fields.string.apply(Fields, tslib_1.__spreadArray([{
|
|
192
|
-
|
|
193
|
-
|
|
193
|
+
return Fields.string.apply(Fields, tslib_1.__spreadArray([(_a = {
|
|
194
|
+
validate: function (entity, event) {
|
|
195
|
+
return validators_js_1.Validators.in(optionalValues())(entity, event);
|
|
196
|
+
}
|
|
197
|
+
},
|
|
198
|
+
//@ts-expect-error as we are adding this to options without it being defined in options
|
|
199
|
+
_a[RepositoryImplementation_js_1.fieldOptionalValuesFunctionKey] = optionalValues,
|
|
200
|
+
_a)], tslib_1.__read(options), false));
|
|
194
201
|
};
|
|
195
202
|
Fields.enum = function (enumType) {
|
|
203
|
+
var _a;
|
|
196
204
|
var options = [];
|
|
197
205
|
for (var _i = 1; _i < arguments.length; _i++) {
|
|
198
206
|
options[_i - 1] = arguments[_i];
|
|
@@ -201,14 +209,20 @@ var Fields = /** @class */ (function () {
|
|
|
201
209
|
return Field.apply(void 0, tslib_1.__spreadArray(tslib_1.__spreadArray([function () {
|
|
202
210
|
//@ts-ignore
|
|
203
211
|
return (enumType());
|
|
204
|
-
},
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
212
|
+
}, (_a = {
|
|
213
|
+
validate: function (entity, event) { return validators_js_1.Validators.enum(enumType())(entity, event); }
|
|
214
|
+
},
|
|
215
|
+
_a[RepositoryImplementation_js_1.fieldOptionalValuesFunctionKey] = function () { return (0, validators_js_1.getEnumValues)(enumType()); },
|
|
216
|
+
_a)], tslib_1.__read(options), false), [function (options) {
|
|
217
|
+
options[RepositoryImplementation_js_1.fieldOptionalValuesFunctionKey] = function () {
|
|
218
|
+
return (0, validators_js_1.getEnumValues)(enumType());
|
|
219
|
+
};
|
|
208
220
|
if (valueConverter === undefined) {
|
|
209
221
|
var enumObj = enumType();
|
|
210
222
|
var enumValues = (0, validators_js_1.getEnumValues)(enumObj);
|
|
211
|
-
valueConverter = enumValues.find(function (x) { return typeof x ===
|
|
223
|
+
valueConverter = enumValues.find(function (x) { return typeof x === 'string'; })
|
|
224
|
+
? valueConverters_js_1.ValueConverters.String
|
|
225
|
+
: valueConverters_js_1.ValueConverters.Integer;
|
|
212
226
|
}
|
|
213
227
|
if (!options.valueConverter) {
|
|
214
228
|
options.valueConverter = valueConverter;
|
|
@@ -47,9 +47,10 @@ export declare class RepositoryImplementation<entityType> implements Repository<
|
|
|
47
47
|
insert(item: Partial<MembersOnly<entityType>>): Promise<entityType>;
|
|
48
48
|
get fields(): FieldsMetadata<entityType>;
|
|
49
49
|
validate(entity: Partial<MembersOnly<entityType>>, ...fields: Extract<keyof MembersOnly<entityType>, string>[]): Promise<ErrorInfo<entityType> | undefined>;
|
|
50
|
-
updateMany({ where }: {
|
|
50
|
+
updateMany({ where, set, }: {
|
|
51
51
|
where: EntityFilter<entityType>;
|
|
52
|
-
|
|
52
|
+
set: Partial<MembersOnly<entityType>>;
|
|
53
|
+
}): Promise<number>;
|
|
53
54
|
update(id: idType<entityType>, item: Partial<MembersOnly<entityType>>): Promise<entityType>;
|
|
54
55
|
update(originalItem: Partial<MembersOnly<entityType>>, item: Partial<MembersOnly<entityType>>): Promise<entityType>;
|
|
55
56
|
private _getRefForExistingRow;
|
|
@@ -295,6 +296,7 @@ export declare function getValueList<T>(field: FieldRef<T>): T[];
|
|
|
295
296
|
export declare function getValueList<T>(field: FieldMetadata<T>): T[];
|
|
296
297
|
export declare function getValueList<T>(type: ClassType<T>): T[];
|
|
297
298
|
export declare const storableMember: unique symbol;
|
|
299
|
+
export declare const fieldOptionalValuesFunctionKey: unique symbol;
|
|
298
300
|
export declare function buildOptions<entityType = any, valueType = any>(options: (FieldOptions<entityType, valueType> | ((options: FieldOptions<entityType, valueType>, remult: Remult) => void))[], remult: Remult): FieldOptions<entityType, valueType>;
|
|
299
301
|
export declare function decorateColumnSettings<valueType>(settings: FieldOptions<any, valueType>, remult: Remult): FieldOptions<any, valueType>;
|
|
300
302
|
export declare class EntityBase {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getRepository = exports.getEntityMetadata = exports.ControllerBase = exports.EntityBase = exports.decorateColumnSettings = exports.buildOptions = exports.storableMember = exports.getValueList = exports.ValueListInfo = exports.ValueListFieldType = exports.isAutoIncrement = exports.FieldType = exports.columnDefsImpl = exports.buildCaption = exports.CaptionTransformer = exports.FieldRefImplementation = exports.controllerRefImpl = exports.getControllerRef = exports.getFields = exports.rowHelperImplementation = exports.createOldEntity = exports.RepositoryImplementation = void 0;
|
|
3
|
+
exports.getRepository = exports.getEntityMetadata = exports.ControllerBase = exports.EntityBase = exports.decorateColumnSettings = exports.buildOptions = exports.fieldOptionalValuesFunctionKey = exports.storableMember = exports.getValueList = exports.ValueListInfo = exports.ValueListFieldType = exports.isAutoIncrement = exports.FieldType = exports.columnDefsImpl = exports.buildCaption = exports.CaptionTransformer = exports.FieldRefImplementation = exports.controllerRefImpl = exports.getControllerRef = exports.getFields = exports.rowHelperImplementation = exports.createOldEntity = exports.RepositoryImplementation = void 0;
|
|
4
4
|
var tslib_1 = require("tslib");
|
|
5
5
|
var column_js_1 = require("../column.js");
|
|
6
6
|
var CompoundIdField_js_1 = require("../CompoundIdField.js");
|
|
@@ -20,6 +20,7 @@ var filter_consumer_bridge_to_sql_request_js_1 = require("../filter/filter-consu
|
|
|
20
20
|
var remult_static_js_1 = require("../remult-static.js");
|
|
21
21
|
var validators_js_1 = require("../validators.js");
|
|
22
22
|
var addValidator_js_1 = require("./addValidator.js");
|
|
23
|
+
var isOfType_js_1 = require("../isOfType.js");
|
|
23
24
|
//import { remult } from "../remult-proxy";
|
|
24
25
|
var classValidatorValidate = undefined;
|
|
25
26
|
// import ("class-validator".toString())
|
|
@@ -437,9 +438,9 @@ var RepositoryImplementation = /** @class */ (function () {
|
|
|
437
438
|
});
|
|
438
439
|
});
|
|
439
440
|
};
|
|
440
|
-
RepositoryImplementation.prototype.updateMany = function (_a
|
|
441
|
+
RepositoryImplementation.prototype.updateMany = function (_a) {
|
|
441
442
|
var _b, e_7, _c, _d;
|
|
442
|
-
var where = _a.where;
|
|
443
|
+
var where = _a.where, set = _a.set;
|
|
443
444
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
444
445
|
var _e, _f, updated, _g, _h, _j, item, e_7_1;
|
|
445
446
|
return tslib_1.__generator(this, function (_k) {
|
|
@@ -3100,6 +3101,11 @@ var EntityFullInfo = /** @class */ (function () {
|
|
|
3100
3101
|
return item[_this.idMetadata.field.key];
|
|
3101
3102
|
},
|
|
3102
3103
|
field: undefined,
|
|
3104
|
+
get fields() {
|
|
3105
|
+
return this.field instanceof CompoundIdField_js_1.CompoundIdField
|
|
3106
|
+
? this.field.fields
|
|
3107
|
+
: [this.field];
|
|
3108
|
+
},
|
|
3103
3109
|
createIdInFilter: function (items) {
|
|
3104
3110
|
if (items.length > 0)
|
|
3105
3111
|
return {
|
|
@@ -3385,21 +3391,23 @@ var ValueListInfo = /** @class */ (function () {
|
|
|
3385
3391
|
exports.ValueListInfo = ValueListInfo;
|
|
3386
3392
|
var typeCache = new Map();
|
|
3387
3393
|
function getValueList(type) {
|
|
3388
|
-
var
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
if (fr)
|
|
3397
|
-
return ValueListInfo.get(fr).getValues();
|
|
3394
|
+
var meta = type === null || type === void 0 ? void 0 : type.metadata;
|
|
3395
|
+
if (!meta && (0, isOfType_js_1.isOfType)(type, 'options'))
|
|
3396
|
+
meta = type;
|
|
3397
|
+
type = (meta === null || meta === void 0 ? void 0 : meta.valueType) || type;
|
|
3398
|
+
if (type) {
|
|
3399
|
+
var options = type[exports.storableMember];
|
|
3400
|
+
if (options)
|
|
3401
|
+
return ValueListInfo.get(type).getValues();
|
|
3398
3402
|
}
|
|
3399
|
-
|
|
3403
|
+
var optionalValues = meta === null || meta === void 0 ? void 0 : meta.options[exports.fieldOptionalValuesFunctionKey];
|
|
3404
|
+
if (optionalValues)
|
|
3405
|
+
return optionalValues();
|
|
3406
|
+
return undefined;
|
|
3400
3407
|
}
|
|
3401
3408
|
exports.getValueList = getValueList;
|
|
3402
3409
|
exports.storableMember = Symbol.for('storableMember');
|
|
3410
|
+
exports.fieldOptionalValuesFunctionKey = Symbol.for('fieldOptionalValues');
|
|
3403
3411
|
function buildOptions(options, remult) {
|
|
3404
3412
|
var e_47, _a;
|
|
3405
3413
|
var r = {};
|
package/src/remult3/remult3.d.ts
CHANGED
|
@@ -174,6 +174,7 @@ export interface IdMetadata<entityType = any> {
|
|
|
174
174
|
*/
|
|
175
175
|
getId(item: Partial<MembersOnly<entityType>>): any;
|
|
176
176
|
field: FieldMetadata<any>;
|
|
177
|
+
fields: FieldMetadata<unknown>[];
|
|
177
178
|
getIdFilter(...ids: any[]): EntityFilter<entityType>;
|
|
178
179
|
isIdField(col: FieldMetadata): boolean;
|
|
179
180
|
createIdInFilter(items: Partial<MembersOnly<entityType>>[]): EntityFilter<entityType>;
|
|
@@ -317,7 +318,8 @@ export interface Repository<entityType> {
|
|
|
317
318
|
*/
|
|
318
319
|
updateMany(options: {
|
|
319
320
|
where: EntityFilter<entityType>;
|
|
320
|
-
|
|
321
|
+
set: Partial<MembersOnly<entityType>>;
|
|
322
|
+
}): Promise<number>;
|
|
321
323
|
/** Deletes an Item*/
|
|
322
324
|
delete(id: idType<entityType>): Promise<void>;
|
|
323
325
|
delete(item: Partial<MembersOnly<entityType>>): Promise<void>;
|
package/src/remult3/remult3.js
CHANGED
|
@@ -2,22 +2,31 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
//y1 - https://discord.com/channels/975754286384418847/1230386433093533698/1230386433093533698
|
|
4
4
|
//y1 - fix async hooks - was it fixed?
|
|
5
|
+
//y1 - repo batch - for multiple operations:
|
|
6
|
+
/*
|
|
7
|
+
const result = await repo.batch(x=>({
|
|
8
|
+
data:x.find(),
|
|
9
|
+
count:x.count()
|
|
10
|
+
}))
|
|
11
|
+
*/
|
|
12
|
+
//p1 - adjust react tutorial to esm
|
|
13
|
+
//p1 - add solid tutorial to the getting started page
|
|
14
|
+
//p1 - update the examples section
|
|
15
|
+
//p1 - add documentation for bun sqlite
|
|
5
16
|
//p1 - consider upsert (where,set)
|
|
6
|
-
//p1 - consider id to also support keyof (id:['company','index'])
|
|
7
17
|
//p1 - wait a second to close stream
|
|
8
|
-
//
|
|
9
|
-
//p1 - add documentation for bun sqlite
|
|
18
|
+
//y1 - consider id to also support keyof (id:['company','index']) - had problem with | (keyof Partial<entityType>)[] & `entity`
|
|
10
19
|
//p1 - describe entity
|
|
11
20
|
//p1 - prepare the createEntity discussion
|
|
12
21
|
//p1 - write active record article
|
|
13
|
-
//p1 - maybe add decorator comment in the readme as well (I heard you've lost me in decorators) - and improve the describeClass function
|
|
14
22
|
//p1 - return error on connection error
|
|
15
23
|
//p1 - consider including the admin in the tutorial - and maybe even in the demo when we setup the api
|
|
24
|
+
//p1 - reconsider key typing to be keyof & string
|
|
16
25
|
//p2 -fix remult admin not to load the html into memory until used
|
|
17
26
|
//y2 - JY suggestion of having generate as part of the ensure schema - not sure
|
|
18
27
|
//y2 - currently for string fields we default for 255 in knex (which is their default) why not just use text (varchar max) - and only use exact length when one is provided?
|
|
19
28
|
//p2 - create foreign key constraints in user code - https://codesandbox.io/p/devbox/fk-validator-tdshcs
|
|
20
|
-
//
|
|
29
|
+
//p2 - admin url1 - pocketbase use /_ for the admin //{allowed?:Allowed,url?:string} also checkout the admin* as it should probably be something else and didn't work in hono
|
|
21
30
|
//p1 - article auth.js with express - played with it, requires type="module" and a few more configurations - https://github.com/noam-honig/express-auth
|
|
22
31
|
//y2 - fix validators cache
|
|
23
32
|
//y2 - should we validate relations
|
|
@@ -89,4 +98,3 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
89
98
|
//y2 - add some api testing framework for user unit tests (will help with codesandbox based discussions)
|
|
90
99
|
//[ ] V2 - what to do about for relations count?
|
|
91
100
|
//[ ] V2 - condition? not to fetch if null etc....
|
|
92
|
-
//p1 - adjust react tutorial to esm
|
package/src/validators.js
CHANGED
|
@@ -48,14 +48,19 @@ var Validators = /** @class */ (function () {
|
|
|
48
48
|
});
|
|
49
49
|
Validators.email = createValueValidator(function (val) { return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(val); }, 'Invalid Email');
|
|
50
50
|
Validators.url = createValueValidator(function (val) { return !!new URL(val); }, 'Invalid Url');
|
|
51
|
-
Validators.in = createValueValidatorWithArgs(function (val, values) { return values.includes(val); }, function (values) {
|
|
52
|
-
return
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
51
|
+
Validators.in = createValueValidatorWithArgs(function (val, values) { return values.includes(val); }, function (values) {
|
|
52
|
+
return "Value must be one of: ".concat(values
|
|
53
|
+
.map(function (y) {
|
|
54
|
+
return typeof y === 'object'
|
|
55
|
+
? y['id'] !== undefined
|
|
56
|
+
? y['id']
|
|
57
|
+
: y.toString()
|
|
58
|
+
: y;
|
|
59
|
+
})
|
|
57
60
|
.join(', '));
|
|
58
61
|
});
|
|
62
|
+
Validators.notNull = createValueValidator(function (val) { return val != null; }, 'Should not be null');
|
|
63
|
+
Validators.enum = createValueValidatorWithArgs(function (value, enumObj) { return Object.values(enumObj).includes(value); }, function (enumObj) { return "Value must be one of ".concat(getEnumValues(enumObj).join(', ')); });
|
|
59
64
|
Validators.relationExists = createValidator(function (_, e) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
|
|
60
65
|
var _b;
|
|
61
66
|
return tslib_1.__generator(_a, function (_c) {
|
|
@@ -209,7 +214,6 @@ function createValidatorWithArgsInternal(validate, defaultMessage, isValueValida
|
|
|
209
214
|
});
|
|
210
215
|
}
|
|
211
216
|
function getEnumValues(enumObj) {
|
|
212
|
-
return Object.values(enumObj)
|
|
213
|
-
.filter(function (x) { return typeof enumObj[x] !== 'number'; });
|
|
217
|
+
return Object.values(enumObj).filter(function (x) { return typeof enumObj[x] !== 'number'; });
|
|
214
218
|
}
|
|
215
219
|
exports.getEnumValues = getEnumValues;
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { Filter } from './filter/filter-interfaces.js';
|
|
2
|
-
export function resultCompoundIdFilter(idField, id, data) {
|
|
3
|
-
return new Filter((add) => {
|
|
4
|
-
let idParts = [];
|
|
5
|
-
if (id != undefined)
|
|
6
|
-
idParts = id.split(',');
|
|
7
|
-
idField.fields.forEach((c, i) => {
|
|
8
|
-
let val = undefined;
|
|
9
|
-
if (i < idParts.length)
|
|
10
|
-
val = idParts[i];
|
|
11
|
-
if (data[c.key] != undefined)
|
|
12
|
-
val = data[c.key];
|
|
13
|
-
add.isEqualTo(c, val);
|
|
14
|
-
});
|
|
15
|
-
});
|
|
16
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.resultCompoundIdFilter = void 0;
|
|
4
|
-
var filter_interfaces_js_1 = require("./filter/filter-interfaces.js");
|
|
5
|
-
function resultCompoundIdFilter(idField, id, data) {
|
|
6
|
-
return new filter_interfaces_js_1.Filter(function (add) {
|
|
7
|
-
var idParts = [];
|
|
8
|
-
if (id != undefined)
|
|
9
|
-
idParts = id.split(',');
|
|
10
|
-
idField.fields.forEach(function (c, i) {
|
|
11
|
-
var val = undefined;
|
|
12
|
-
if (i < idParts.length)
|
|
13
|
-
val = idParts[i];
|
|
14
|
-
if (data[c.key] != undefined)
|
|
15
|
-
val = data[c.key];
|
|
16
|
-
add.isEqualTo(c, val);
|
|
17
|
-
});
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
exports.resultCompoundIdFilter = resultCompoundIdFilter;
|