remult 0.26.22 → 0.26.23-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/SseSubscriptionServer.d.ts +3 -4
- package/assign.js +1 -2
- package/esm/graphql.js +1 -1
- package/esm/remult-hono.js +3 -1
- package/esm/remult-knex/index.js +3 -1
- package/esm/remult-sqlite3.js +4 -1
- package/esm/remult-sveltekit.js +1 -0
- package/esm/server/index.js +3 -2
- package/esm/server/initAsyncHooks.js +3 -3
- package/esm/server/remult-admin.js +1 -4
- package/esm/server/remult-api-server.js +47 -48
- package/esm/src/CompoundIdField.js +9 -9
- package/esm/src/data-api.js +1 -1
- package/esm/src/data-providers/json-entity-opfs-storage.js +9 -5
- package/esm/src/data-providers/sql-database.js +9 -9
- package/esm/src/filter/filter-consumer-bridge-to-sql-request.js +3 -1
- package/esm/src/live-query/LiveQueryClient.js +0 -1
- package/esm/src/remult-proxy.js +1 -3
- package/esm/src/remult-static.js +1 -0
- package/esm/src/remult3/Fields.js +4 -3
- package/esm/src/remult3/RepositoryImplementation.js +134 -102
- package/esm/src/remult3/entity.js +1 -1
- package/esm/src/remult3/relation-loader.js +2 -2
- package/esm/src/remult3/remult3.js +9 -0
- package/esm/src/server-action.js +16 -12
- package/esm/src/sort.js +0 -2
- package/esm/src/validators.js +3 -3
- package/esm/src/valueConverters.js +2 -2
- package/graphql.js +3 -4
- package/index.js +2 -2
- package/live-query/data-provider-live-query-storage.js +6 -6
- package/migrations/compare-migration-snapshots.js +48 -49
- package/migrations/generate-migrations.js +1 -2
- package/migrations/migrate.js +2 -3
- package/migrations/migration-types.d.ts +1 -1
- package/migrations/migration-types.js +4 -4
- package/migrations/update-migrations-ts-file.js +1 -2
- package/myLog.js +1 -2
- package/package.json +1 -1
- package/postgres/postgres-data-provider.d.ts +2 -2
- package/postgres/postgres-data-provider.js +5 -5
- package/postgres/schema-builder.js +3 -3
- package/remult-express.js +4 -3
- package/remult-fastify.js +4 -3
- package/remult-fresh.js +1 -2
- package/remult-hapi.js +4 -3
- package/remult-hono.js +6 -3
- package/remult-knex/index.d.ts +1 -1
- package/remult-knex/index.js +7 -5
- package/remult-mongo.d.ts +1 -1
- package/remult-next.d.ts +4 -5
- package/remult-next.js +11 -6
- package/remult-nuxt.js +1 -2
- package/remult-solid-start.js +1 -2
- package/remult-sqlite3.js +4 -1
- package/remult-sveltekit.js +33 -35
- package/server/JsonEntityFileStorage.d.ts +1 -1
- package/server/get-remult-admin-html.js +1 -2
- package/server/index.d.ts +1 -1
- package/server/index.js +4 -3
- package/server/initAsyncHooks.d.ts +10 -10
- package/server/initAsyncHooks.js +5 -2
- package/server/initDataProvider.js +1 -2
- package/server/initDataProviderOrJson.js +1 -2
- package/server/remult-admin.js +3 -7
- package/server/remult-api-server.d.ts +22 -22
- package/server/remult-api-server.js +54 -48
- package/src/CompoundIdField.d.ts +1 -1
- package/src/CompoundIdField.js +9 -0
- package/src/buildRestDataProvider.d.ts +1 -1
- package/src/buildRestDataProvider.js +8 -8
- package/src/column-interfaces.d.ts +8 -8
- package/src/column-interfaces.js +1 -2
- package/src/column.d.ts +4 -4
- package/src/column.js +2 -2
- package/src/context.d.ts +4 -4
- package/src/context.js +5 -5
- package/src/data-api.d.ts +2 -2
- package/src/data-api.js +4 -4
- package/src/data-interfaces.js +1 -2
- package/src/data-providers/json-entity-opfs-storage.js +30 -16
- package/src/data-providers/rest-data-provider.d.ts +3 -3
- package/src/data-providers/rest-data-provider.js +4 -4
- package/src/data-providers/sql-database.js +11 -11
- package/src/filter/filter-consumer-bridge-to-sql-request.d.ts +3 -3
- package/src/filter/filter-consumer-bridge-to-sql-request.js +21 -19
- package/src/filter/filter-interfaces.d.ts +1 -1
- package/src/filter/filter-interfaces.js +10 -6
- package/src/isOfType.js +2 -3
- package/src/live-query/SubscriptionServer.js +95 -97
- package/src/remult-proxy.js +1 -3
- package/src/remult-static.d.ts +2 -2
- package/src/remult-static.js +7 -4
- package/src/remult3/Fields.d.ts +2 -2
- package/src/remult3/Fields.js +11 -9
- package/src/remult3/RepositoryImplementation.d.ts +41 -39
- package/src/remult3/RepositoryImplementation.js +383 -346
- package/src/remult3/__updateEntityBasedOnWhere.js +1 -2
- package/src/remult3/addValidator.d.ts +1 -1
- package/src/remult3/addValidator.js +1 -2
- package/src/remult3/classDescribers.d.ts +3 -3
- package/src/remult3/classDescribers.js +3 -4
- package/src/remult3/entity.js +2 -4
- package/src/remult3/getEntityRef.js +4 -4
- package/src/remult3/relation-loader.d.ts +1 -1
- package/src/remult3/relationInfoMember.d.ts +2 -2
- package/src/remult3/relationInfoMember.js +4 -5
- package/src/remult3/remult3.d.ts +13 -10
- package/src/remult3/remult3.js +9 -0
- package/src/remult3/repository-internals.d.ts +3 -3
- package/src/remult3/repository-internals.js +2 -2
- package/src/server-action.d.ts +1 -1
- package/src/server-action.js +65 -58
- package/src/sort.d.ts +1 -1
- package/src/sort.js +0 -2
- package/src/sql-command.d.ts +1 -1
- package/src/validators.d.ts +1 -1
- package/src/validators.js +13 -11
- package/src/valueConverters.js +3 -2
|
@@ -333,7 +333,8 @@ export class RepositoryImplementation {
|
|
|
333
333
|
if (!ref) {
|
|
334
334
|
const instance = new this._entity(this._remult);
|
|
335
335
|
for (const field of this._fieldsOf(entity)) {
|
|
336
|
-
|
|
336
|
+
const key = field.key;
|
|
337
|
+
instance[key] = entity[key];
|
|
337
338
|
}
|
|
338
339
|
this._fixTypes(instance);
|
|
339
340
|
let row = new rowHelperImplementation(this._info, instance, this, this._edp, this._remult, false);
|
|
@@ -386,7 +387,8 @@ export class RepositoryImplementation {
|
|
|
386
387
|
}
|
|
387
388
|
listener.error ??= () => { };
|
|
388
389
|
listener.complete ??= () => { };
|
|
389
|
-
return this._remult.liveQuerySubscriber.subscribe(
|
|
390
|
+
return this._remult.liveQuerySubscriber.subscribe(//TODO - figure out why the type was required
|
|
391
|
+
this, options, listener);
|
|
390
392
|
},
|
|
391
393
|
};
|
|
392
394
|
}
|
|
@@ -481,15 +483,17 @@ export class RepositoryImplementation {
|
|
|
481
483
|
let rel = getRelationFieldInfo(col);
|
|
482
484
|
let incl = col.options
|
|
483
485
|
.defaultIncluded;
|
|
484
|
-
|
|
485
|
-
|
|
486
|
+
const include = loadOptions?.include?.[col.key];
|
|
487
|
+
if (include !== undefined) {
|
|
488
|
+
incl = include;
|
|
486
489
|
}
|
|
487
490
|
if (rel && incl) {
|
|
488
491
|
const otherRepo = rel.toRepo;
|
|
489
492
|
for (const row of result) {
|
|
490
493
|
let { findOptions, returnNull } = this._findOptionsBasedOnRelation(rel, col, incl, row, otherRepo);
|
|
494
|
+
const colKey = col.key;
|
|
491
495
|
if (returnNull)
|
|
492
|
-
row[
|
|
496
|
+
row[colKey] = null;
|
|
493
497
|
else {
|
|
494
498
|
const entityType = rel.toEntity;
|
|
495
499
|
const toRepo = otherRepo;
|
|
@@ -502,7 +506,7 @@ export class RepositoryImplementation {
|
|
|
502
506
|
.then((result) => {
|
|
503
507
|
if (result.length == 0 && rel.type == 'toOne')
|
|
504
508
|
return;
|
|
505
|
-
row[
|
|
509
|
+
row[colKey] =
|
|
506
510
|
rel.type !== 'toMany'
|
|
507
511
|
? result.length == 0
|
|
508
512
|
? null
|
|
@@ -580,8 +584,6 @@ export class RepositoryImplementation {
|
|
|
580
584
|
return { findOptions, returnNull, returnUndefined };
|
|
581
585
|
}
|
|
582
586
|
async _mapRawDataToResult(r, loadFields) {
|
|
583
|
-
if (!r)
|
|
584
|
-
return undefined;
|
|
585
587
|
let x = new this._entity(this._remult);
|
|
586
588
|
let helper = new rowHelperImplementation(this._info, x, this, this._edp, this._remult, false);
|
|
587
589
|
Object.defineProperty(x, entityMember, {
|
|
@@ -608,17 +610,18 @@ export class RepositoryImplementation {
|
|
|
608
610
|
return json.map((item) => this.fromJson(item, newRow));
|
|
609
611
|
let result = new this._entity(this._remult);
|
|
610
612
|
for (const col of this._fieldsOf(json)) {
|
|
613
|
+
const colKey = col.key;
|
|
611
614
|
let ei = getEntitySettings(col.valueType, false);
|
|
612
615
|
if (ei) {
|
|
613
616
|
let val = json[col.key];
|
|
614
617
|
if (typeof val === 'string' || typeof val === 'number')
|
|
615
|
-
result[
|
|
618
|
+
result[colKey] = val;
|
|
616
619
|
else
|
|
617
|
-
result[
|
|
620
|
+
result[colKey] = this._remult.repo(col.valueType).fromJson(val);
|
|
618
621
|
}
|
|
619
622
|
else {
|
|
620
|
-
if (json[
|
|
621
|
-
result[
|
|
623
|
+
if (json[colKey] !== undefined) {
|
|
624
|
+
result[colKey] = col.valueConverter.fromJson(json[col.key]);
|
|
622
625
|
}
|
|
623
626
|
}
|
|
624
627
|
}
|
|
@@ -654,11 +657,10 @@ export class RepositoryImplementation {
|
|
|
654
657
|
}
|
|
655
658
|
}
|
|
656
659
|
_cache = new Map();
|
|
657
|
-
async findOne(
|
|
660
|
+
async findOne(pOptions, skipOrderByAndLimit = false) {
|
|
658
661
|
let r;
|
|
659
662
|
let cacheInfo;
|
|
660
|
-
|
|
661
|
-
options = {};
|
|
663
|
+
let options = pOptions ?? {};
|
|
662
664
|
if (options.useCache) {
|
|
663
665
|
let f = findOptionsToJson(options, this.metadata);
|
|
664
666
|
let key = JSON.stringify(f);
|
|
@@ -670,7 +672,7 @@ export class RepositoryImplementation {
|
|
|
670
672
|
this._cache.delete(key);
|
|
671
673
|
}
|
|
672
674
|
else
|
|
673
|
-
return
|
|
675
|
+
return cacheInfo.promise;
|
|
674
676
|
}
|
|
675
677
|
else {
|
|
676
678
|
cacheInfo = {
|
|
@@ -723,7 +725,8 @@ export class RepositoryImplementation {
|
|
|
723
725
|
let r = new this._entity(this._remult);
|
|
724
726
|
if (item) {
|
|
725
727
|
for (const field of this._fieldsOf(item)) {
|
|
726
|
-
|
|
728
|
+
const key = field.key;
|
|
729
|
+
r[key] = item[key];
|
|
727
730
|
}
|
|
728
731
|
this._fixTypes(r);
|
|
729
732
|
}
|
|
@@ -755,7 +758,7 @@ export class RepositoryImplementation {
|
|
|
755
758
|
}
|
|
756
759
|
findId(id, options) {
|
|
757
760
|
if (id === null || id === undefined)
|
|
758
|
-
return null;
|
|
761
|
+
return Promise.resolve(null);
|
|
759
762
|
if (typeof id !== 'string' && typeof id !== 'number')
|
|
760
763
|
throw new Error('id can be either number or string, but got: ' + typeof id);
|
|
761
764
|
return this.findFirst({}, {
|
|
@@ -764,24 +767,23 @@ export class RepositoryImplementation {
|
|
|
764
767
|
}, true);
|
|
765
768
|
}
|
|
766
769
|
async _translateWhereToFilter(where) {
|
|
767
|
-
|
|
768
|
-
where = {};
|
|
770
|
+
let safeWhere = where ?? {};
|
|
769
771
|
if (this._defaultFindOptions?.where) {
|
|
770
|
-
let z =
|
|
771
|
-
|
|
772
|
+
let z = safeWhere;
|
|
773
|
+
safeWhere = {
|
|
772
774
|
$and: [z, this._defaultFindOptions?.where],
|
|
773
775
|
};
|
|
774
776
|
}
|
|
775
777
|
if (!this._dataProvider.isProxy) {
|
|
776
778
|
if (this.metadata.options.backendPreprocessFilter) {
|
|
777
|
-
|
|
779
|
+
safeWhere = await this.metadata.options.backendPreprocessFilter(safeWhere, {
|
|
778
780
|
metadata: this.metadata,
|
|
779
|
-
getFilterPreciseValues: (filter) => Filter.getPreciseValues(this.metadata, filter ||
|
|
781
|
+
getFilterPreciseValues: (filter) => Filter.getPreciseValues(this.metadata, filter || safeWhere),
|
|
780
782
|
});
|
|
781
783
|
}
|
|
782
784
|
if (this.metadata.options.backendPrefilter) {
|
|
783
|
-
let z =
|
|
784
|
-
|
|
785
|
+
let z = safeWhere;
|
|
786
|
+
safeWhere = {
|
|
785
787
|
$and: [
|
|
786
788
|
z,
|
|
787
789
|
await Filter.resolve(this.metadata.options.backendPrefilter),
|
|
@@ -789,7 +791,7 @@ export class RepositoryImplementation {
|
|
|
789
791
|
};
|
|
790
792
|
}
|
|
791
793
|
}
|
|
792
|
-
let r = await Filter.fromEntityFilter(this.metadata,
|
|
794
|
+
let r = await Filter.fromEntityFilter(this.metadata, safeWhere);
|
|
793
795
|
if (r && !this._dataProvider.isProxy) {
|
|
794
796
|
r = await Filter.translateCustomWhere(r, this.metadata, this._remult);
|
|
795
797
|
}
|
|
@@ -822,8 +824,11 @@ export function createOldEntity(entity, remult) {
|
|
|
822
824
|
for (const key of functions) {
|
|
823
825
|
if (baseSettings[key] && baseSettings[key] !== info[key]) {
|
|
824
826
|
let x = info[key];
|
|
827
|
+
//@ts-ignore
|
|
825
828
|
info[key] = async (a, b) => {
|
|
829
|
+
//@ts-ignore
|
|
826
830
|
await x(a, b);
|
|
831
|
+
//@ts-ignore
|
|
827
832
|
await baseSettings[key](a, b);
|
|
828
833
|
};
|
|
829
834
|
}
|
|
@@ -894,37 +899,41 @@ class rowHelperBase {
|
|
|
894
899
|
});
|
|
895
900
|
lookup.set(val);
|
|
896
901
|
}
|
|
897
|
-
else
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
902
|
+
else {
|
|
903
|
+
const rel = getRelationFieldInfo(col);
|
|
904
|
+
if (rel?.type === 'toOne') {
|
|
905
|
+
let hasVal = instance.hasOwnProperty(col.key);
|
|
906
|
+
let val = instance[col.key];
|
|
907
|
+
if (isNewRow && !val)
|
|
908
|
+
hasVal = false;
|
|
909
|
+
Object.defineProperty(instance, col.key, {
|
|
910
|
+
get: () => {
|
|
911
|
+
return val;
|
|
912
|
+
},
|
|
913
|
+
set: (newVal) => {
|
|
914
|
+
val = newVal;
|
|
915
|
+
if (newVal === undefined)
|
|
916
|
+
return;
|
|
917
|
+
const op = col.options;
|
|
918
|
+
if (op.field) {
|
|
919
|
+
this.instance[op.field] =
|
|
920
|
+
rel.toRepo.metadata.idMetadata.getId(newVal);
|
|
921
|
+
}
|
|
922
|
+
if (op.fields) {
|
|
923
|
+
for (const key in op.fields) {
|
|
924
|
+
if (Object.prototype.hasOwnProperty.call(op.fields, key)) {
|
|
925
|
+
const element = op.fields[key];
|
|
926
|
+
this.instance[element] =
|
|
927
|
+
newVal == null ? null : newVal[key];
|
|
928
|
+
}
|
|
920
929
|
}
|
|
921
930
|
}
|
|
922
|
-
}
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
931
|
+
},
|
|
932
|
+
enumerable: true,
|
|
933
|
+
});
|
|
934
|
+
if (hasVal)
|
|
935
|
+
instance[col.key] = val;
|
|
936
|
+
}
|
|
928
937
|
}
|
|
929
938
|
}
|
|
930
939
|
}
|
|
@@ -937,6 +946,7 @@ class rowHelperBase {
|
|
|
937
946
|
initSubscribers() {
|
|
938
947
|
if (!this._subscribers) {
|
|
939
948
|
this._subscribers = new SubscribableImp();
|
|
949
|
+
const safeSubscribers = this._subscribers;
|
|
940
950
|
for (const col of this.fieldsMetadata) {
|
|
941
951
|
let ei = getEntitySettings(col.valueType, false);
|
|
942
952
|
let refImpl = this.fields.find(col.key);
|
|
@@ -947,13 +957,13 @@ class rowHelperBase {
|
|
|
947
957
|
let val = this.instance[col.key];
|
|
948
958
|
Object.defineProperty(this.instance, col.key, {
|
|
949
959
|
get: () => {
|
|
950
|
-
|
|
960
|
+
safeSubscribers.reportObserved();
|
|
951
961
|
refImpl._subscribers.reportObserved();
|
|
952
962
|
return val;
|
|
953
963
|
},
|
|
954
964
|
set: (value) => {
|
|
955
965
|
val = value;
|
|
956
|
-
|
|
966
|
+
safeSubscribers.reportChanged();
|
|
957
967
|
refImpl._subscribers.reportChanged();
|
|
958
968
|
},
|
|
959
969
|
enumerable: true,
|
|
@@ -986,9 +996,11 @@ class rowHelperBase {
|
|
|
986
996
|
};
|
|
987
997
|
if (!error.message) {
|
|
988
998
|
for (const col of this.fieldsMetadata) {
|
|
989
|
-
if (this.errors[col.key]) {
|
|
999
|
+
if (this.errors?.[col.key]) {
|
|
990
1000
|
error.message =
|
|
991
|
-
this.fields[col.key].metadata.caption +
|
|
1001
|
+
this.fields[col.key].metadata.caption +
|
|
1002
|
+
': ' +
|
|
1003
|
+
this.errors[col.key];
|
|
992
1004
|
this.error = error.message;
|
|
993
1005
|
break;
|
|
994
1006
|
}
|
|
@@ -1161,12 +1173,13 @@ export class rowHelperImplementation extends rowHelperBase {
|
|
|
1161
1173
|
this.metadata = info;
|
|
1162
1174
|
if (_isNew) {
|
|
1163
1175
|
for (const col of info.fieldsMetadata) {
|
|
1164
|
-
|
|
1176
|
+
const colKey = col.key;
|
|
1177
|
+
if (col.options.defaultValue && instance[colKey] === undefined) {
|
|
1165
1178
|
if (typeof col.options.defaultValue === 'function') {
|
|
1166
|
-
instance[
|
|
1179
|
+
instance[colKey] = col.options.defaultValue(instance);
|
|
1167
1180
|
}
|
|
1168
|
-
else if (!instance[
|
|
1169
|
-
instance[
|
|
1181
|
+
else if (!instance[colKey])
|
|
1182
|
+
instance[colKey] = col.options.defaultValue;
|
|
1170
1183
|
}
|
|
1171
1184
|
}
|
|
1172
1185
|
}
|
|
@@ -1232,12 +1245,17 @@ export class rowHelperImplementation extends rowHelperBase {
|
|
|
1232
1245
|
if (!this._columns) {
|
|
1233
1246
|
let _items = [];
|
|
1234
1247
|
let r = {
|
|
1235
|
-
|
|
1248
|
+
//@ts-ignore
|
|
1249
|
+
find: (c) =>
|
|
1250
|
+
//@ts-ignore
|
|
1251
|
+
r[typeof c === 'string' ? c : c.key],
|
|
1236
1252
|
[Symbol.iterator]: () => _items[Symbol.iterator](),
|
|
1237
1253
|
toArray: () => _items,
|
|
1238
1254
|
};
|
|
1239
1255
|
for (const c of this.info.fieldsMetadata) {
|
|
1240
|
-
_items.push(
|
|
1256
|
+
_items.push(
|
|
1257
|
+
//@ts-ignore
|
|
1258
|
+
(r[c.key] = new FieldRefImplementation(c.options, c, this.instance, this, this)));
|
|
1241
1259
|
}
|
|
1242
1260
|
this._columns = r;
|
|
1243
1261
|
}
|
|
@@ -1324,8 +1342,8 @@ export class rowHelperImplementation extends rowHelperBase {
|
|
|
1324
1342
|
if (this.info.entityInfo.saved)
|
|
1325
1343
|
await this.info.entityInfo.saved(this.instance, e);
|
|
1326
1344
|
if (this.repository.listeners)
|
|
1327
|
-
for (const listener of this.repository.listeners
|
|
1328
|
-
await listener.saved(this.instance, isNew);
|
|
1345
|
+
for (const listener of this.repository.listeners) {
|
|
1346
|
+
await listener.saved?.(this.instance, isNew);
|
|
1329
1347
|
}
|
|
1330
1348
|
}
|
|
1331
1349
|
await this.repository._remult.liveQueryPublisher.itemChanged(this.repository.metadata.key, [{ id: this.getId(), oldId: this.getOriginalId(), deleted: false }]);
|
|
@@ -1334,7 +1352,7 @@ export class rowHelperImplementation extends rowHelperBase {
|
|
|
1334
1352
|
return this.instance;
|
|
1335
1353
|
}
|
|
1336
1354
|
catch (err) {
|
|
1337
|
-
await this.catchSaveErrors(err);
|
|
1355
|
+
throw await this.catchSaveErrors(err);
|
|
1338
1356
|
}
|
|
1339
1357
|
}
|
|
1340
1358
|
finally {
|
|
@@ -1397,14 +1415,14 @@ export class rowHelperImplementation extends rowHelperBase {
|
|
|
1397
1415
|
await this.info.entityInfo.deleted(this.instance, e);
|
|
1398
1416
|
}
|
|
1399
1417
|
if (this.repository.listeners)
|
|
1400
|
-
for (const listener of this.repository.listeners
|
|
1401
|
-
await listener.deleted(this.instance);
|
|
1418
|
+
for (const listener of this.repository.listeners) {
|
|
1419
|
+
await listener.deleted?.(this.instance);
|
|
1402
1420
|
}
|
|
1403
1421
|
await this.repository._remult.liveQueryPublisher.itemChanged(this.repository.metadata.key, [{ id: this.getId(), oldId: this.getOriginalId(), deleted: true }]);
|
|
1404
1422
|
this._wasDeleted = true;
|
|
1405
1423
|
}
|
|
1406
1424
|
catch (err) {
|
|
1407
|
-
await this.catchSaveErrors(err);
|
|
1425
|
+
throw await this.catchSaveErrors(err);
|
|
1408
1426
|
}
|
|
1409
1427
|
}
|
|
1410
1428
|
async loadDataFrom(data, loadItems) {
|
|
@@ -1437,7 +1455,8 @@ export class rowHelperImplementation extends rowHelperBase {
|
|
|
1437
1455
|
//y2 should be changed to be based on data provider - consider naming
|
|
1438
1456
|
for (const col of this.info.fieldsMetadata) {
|
|
1439
1457
|
if (col.options.serverExpression) {
|
|
1440
|
-
this.instance[col.key] =
|
|
1458
|
+
this.instance[col.key] =
|
|
1459
|
+
await col.options.serverExpression(this.instance);
|
|
1441
1460
|
}
|
|
1442
1461
|
}
|
|
1443
1462
|
}
|
|
@@ -1467,8 +1486,8 @@ export class rowHelperImplementation extends rowHelperBase {
|
|
|
1467
1486
|
await this.info.entityInfo.validation(this.instance, e);
|
|
1468
1487
|
}
|
|
1469
1488
|
if (this.repository.listeners)
|
|
1470
|
-
for (const listener of this.repository.listeners
|
|
1471
|
-
await listener.validating(this.instance);
|
|
1489
|
+
for (const listener of this.repository.listeners) {
|
|
1490
|
+
await listener.validating?.(this.instance);
|
|
1472
1491
|
}
|
|
1473
1492
|
}
|
|
1474
1493
|
}
|
|
@@ -1481,7 +1500,9 @@ export function getFields(container, remult) {
|
|
|
1481
1500
|
}
|
|
1482
1501
|
export function getControllerRef(container, remultArg) {
|
|
1483
1502
|
const remultVar = remultArg || defaultRemult;
|
|
1503
|
+
//@ts-ignore
|
|
1484
1504
|
let result = container[controllerColumns];
|
|
1505
|
+
//@ts-ignore
|
|
1485
1506
|
if (!result)
|
|
1486
1507
|
result = container[entityMember];
|
|
1487
1508
|
if (!result) {
|
|
@@ -1496,7 +1517,9 @@ export function getControllerRef(container, remultArg) {
|
|
|
1496
1517
|
}
|
|
1497
1518
|
base = Object.getPrototypeOf(base);
|
|
1498
1519
|
}
|
|
1499
|
-
|
|
1520
|
+
//@ts-ignore
|
|
1521
|
+
container[controllerColumns] = result = new controllerRefImpl(prepareColumnInfo(columnSettings, remultVar).map((x) => new columnDefsImpl(x, undefined, //TODO - not sure
|
|
1522
|
+
remultVar)), container, remultVar);
|
|
1500
1523
|
}
|
|
1501
1524
|
return result;
|
|
1502
1525
|
}
|
|
@@ -1536,7 +1559,7 @@ export class FieldRefImplementation {
|
|
|
1536
1559
|
this.helper = helper;
|
|
1537
1560
|
this.rowBase = rowBase;
|
|
1538
1561
|
this.target = this.settings.target;
|
|
1539
|
-
this.entityRef = this.helper;
|
|
1562
|
+
this.entityRef = this.helper; //todo - I'm not sure this is correct in the case of ControllerInstance
|
|
1540
1563
|
}
|
|
1541
1564
|
_subscribers;
|
|
1542
1565
|
subscribe(listener) {
|
|
@@ -1561,10 +1584,9 @@ export class FieldRefImplementation {
|
|
|
1561
1584
|
async load() {
|
|
1562
1585
|
let lu = this.rowBase.lookups.get(this.metadata.key);
|
|
1563
1586
|
let rel = getRelationFieldInfo(this.metadata);
|
|
1564
|
-
if (rel) {
|
|
1587
|
+
if (rel && this.helper) {
|
|
1565
1588
|
if (rel.type === 'toMany') {
|
|
1566
|
-
return (this.container[this.metadata.key] = await this.helper.repository
|
|
1567
|
-
.relations(this.container)[this.metadata.key].find());
|
|
1589
|
+
return (this.container[this.metadata.key] = await this.helper.repository.relations(this.container)[this.metadata.key].find());
|
|
1568
1590
|
}
|
|
1569
1591
|
else {
|
|
1570
1592
|
let val = await this.helper.repository
|
|
@@ -1572,7 +1594,7 @@ export class FieldRefImplementation {
|
|
|
1572
1594
|
if (val)
|
|
1573
1595
|
this.container[this.metadata.key] = val;
|
|
1574
1596
|
else
|
|
1575
|
-
return null;
|
|
1597
|
+
return null; //TODO: check if this (!) is correct
|
|
1576
1598
|
}
|
|
1577
1599
|
}
|
|
1578
1600
|
else if (lu) {
|
|
@@ -1686,7 +1708,7 @@ export class FieldRefImplementation {
|
|
|
1686
1708
|
set error(value) {
|
|
1687
1709
|
self.error = value;
|
|
1688
1710
|
},
|
|
1689
|
-
isNew: this.entityRef?.isNew(),
|
|
1711
|
+
isNew: this.entityRef?.isNew() ?? false,
|
|
1690
1712
|
load: () => self.load(),
|
|
1691
1713
|
metadata: self.metadata,
|
|
1692
1714
|
originalValue: self.originalValue,
|
|
@@ -1709,7 +1731,7 @@ export class FieldRefImplementation {
|
|
|
1709
1731
|
if (typeof error === 'string')
|
|
1710
1732
|
this.error = error;
|
|
1711
1733
|
else
|
|
1712
|
-
this.error = error
|
|
1734
|
+
this.error = error?.message;
|
|
1713
1735
|
}
|
|
1714
1736
|
}
|
|
1715
1737
|
async validate() {
|
|
@@ -1723,14 +1745,14 @@ let tempCaptionTransformer = {
|
|
|
1723
1745
|
export const CaptionTransformer = remultStatic.captionTransformer ||
|
|
1724
1746
|
(remultStatic.captionTransformer = tempCaptionTransformer);
|
|
1725
1747
|
export function buildCaption(caption, key, remult, metaData) {
|
|
1726
|
-
let result;
|
|
1748
|
+
let result = undefined;
|
|
1727
1749
|
if (typeof caption === 'function') {
|
|
1728
1750
|
if (remult)
|
|
1729
1751
|
result = caption(remult);
|
|
1730
1752
|
}
|
|
1731
1753
|
else if (caption)
|
|
1732
1754
|
result = caption;
|
|
1733
|
-
result = CaptionTransformer.transformCaption(remult, key, result, metaData);
|
|
1755
|
+
result = CaptionTransformer.transformCaption(remult, key, result ?? '', metaData);
|
|
1734
1756
|
if (result)
|
|
1735
1757
|
return result;
|
|
1736
1758
|
if (key)
|
|
@@ -1747,7 +1769,7 @@ export class columnDefsImpl {
|
|
|
1747
1769
|
this.remult = remult;
|
|
1748
1770
|
this.options = this.settings;
|
|
1749
1771
|
this.target = this.settings.target;
|
|
1750
|
-
this.valueConverter = new Proxy(this.settings.valueConverter, {
|
|
1772
|
+
this.valueConverter = new Proxy(this.settings.valueConverter ?? {}, {
|
|
1751
1773
|
get: (target, prop) => {
|
|
1752
1774
|
let result = target[prop];
|
|
1753
1775
|
if (typeof result === 'function') {
|
|
@@ -1810,7 +1832,7 @@ export class columnDefsImpl {
|
|
|
1810
1832
|
}
|
|
1811
1833
|
options;
|
|
1812
1834
|
target;
|
|
1813
|
-
readonly;
|
|
1835
|
+
readonly = false;
|
|
1814
1836
|
valueConverter;
|
|
1815
1837
|
allowNull;
|
|
1816
1838
|
caption;
|
|
@@ -1818,9 +1840,9 @@ export class columnDefsImpl {
|
|
|
1818
1840
|
inputType;
|
|
1819
1841
|
key;
|
|
1820
1842
|
get dbReadOnly() {
|
|
1821
|
-
return this.settings.dbReadOnly;
|
|
1843
|
+
return Boolean(this.settings.dbReadOnly);
|
|
1822
1844
|
}
|
|
1823
|
-
isServerExpression;
|
|
1845
|
+
isServerExpression = false;
|
|
1824
1846
|
valueType;
|
|
1825
1847
|
}
|
|
1826
1848
|
class EntityFullInfo {
|
|
@@ -1882,8 +1904,9 @@ class EntityFullInfo {
|
|
|
1882
1904
|
this.idMetadata.field = r;
|
|
1883
1905
|
}
|
|
1884
1906
|
if (!this.idMetadata.field) {
|
|
1885
|
-
|
|
1886
|
-
|
|
1907
|
+
const idField = this.fields['id'];
|
|
1908
|
+
if (idField)
|
|
1909
|
+
this.idMetadata.field = idField;
|
|
1887
1910
|
else
|
|
1888
1911
|
this.idMetadata.field = [...this.fields][0];
|
|
1889
1912
|
}
|
|
@@ -1946,6 +1969,10 @@ class EntityFullInfo {
|
|
|
1946
1969
|
return {
|
|
1947
1970
|
$or: items.map((x) => this.idMetadata.getIdFilter(getEntityRef(x).getId())),
|
|
1948
1971
|
};
|
|
1972
|
+
else
|
|
1973
|
+
return {
|
|
1974
|
+
[this.fields.toArray()[0].key]: [],
|
|
1975
|
+
};
|
|
1949
1976
|
},
|
|
1950
1977
|
isIdField: (col) => {
|
|
1951
1978
|
return col.key == this.idMetadata.field.key;
|
|
@@ -1976,7 +2003,7 @@ class EntityFullInfo {
|
|
|
1976
2003
|
caption;
|
|
1977
2004
|
}
|
|
1978
2005
|
export function FieldType(...options) {
|
|
1979
|
-
return (target
|
|
2006
|
+
return (target) => {
|
|
1980
2007
|
if (!options) {
|
|
1981
2008
|
options = [];
|
|
1982
2009
|
}
|
|
@@ -1989,7 +2016,7 @@ export function isAutoIncrement(f) {
|
|
|
1989
2016
|
return f.options?.valueConverter?.fieldTypeInDb === 'autoincrement';
|
|
1990
2017
|
}
|
|
1991
2018
|
export function ValueListFieldType(...options) {
|
|
1992
|
-
return (type
|
|
2019
|
+
return (type) => {
|
|
1993
2020
|
FieldType((o) => {
|
|
1994
2021
|
;
|
|
1995
2022
|
(o.valueConverter = ValueListInfo.get(type)),
|
|
@@ -2001,7 +2028,7 @@ export function ValueListFieldType(...options) {
|
|
|
2001
2028
|
}
|
|
2002
2029
|
return Validators.in(values)(entity, ref);
|
|
2003
2030
|
};
|
|
2004
|
-
}, ...options)(type
|
|
2031
|
+
}, ...options)(type);
|
|
2005
2032
|
};
|
|
2006
2033
|
}
|
|
2007
2034
|
export class ValueListInfo {
|
|
@@ -2102,7 +2129,7 @@ export function getValueList(type) {
|
|
|
2102
2129
|
if (options)
|
|
2103
2130
|
return ValueListInfo.get(type).getValues();
|
|
2104
2131
|
}
|
|
2105
|
-
let optionalValues = meta?.options[fieldOptionalValuesFunctionKey];
|
|
2132
|
+
let optionalValues = (meta?.options)[fieldOptionalValuesFunctionKey];
|
|
2106
2133
|
if (optionalValues)
|
|
2107
2134
|
return optionalValues();
|
|
2108
2135
|
return undefined;
|
|
@@ -2201,17 +2228,19 @@ export function decorateColumnSettings(settings, remult) {
|
|
|
2201
2228
|
if (!settings.valueConverter.fromJson) {
|
|
2202
2229
|
settings.valueConverter.fromJson = (x) => x;
|
|
2203
2230
|
}
|
|
2231
|
+
const fromJson = settings.valueConverter.fromJson;
|
|
2232
|
+
const toJson = settings.valueConverter.toJson;
|
|
2204
2233
|
if (!settings.valueConverter.toDb) {
|
|
2205
|
-
settings.valueConverter.toDb = (x) =>
|
|
2234
|
+
settings.valueConverter.toDb = (x) => toJson(x);
|
|
2206
2235
|
}
|
|
2207
2236
|
if (!settings.valueConverter.fromDb) {
|
|
2208
|
-
settings.valueConverter.fromDb = (x) =>
|
|
2237
|
+
settings.valueConverter.fromDb = (x) => fromJson(x);
|
|
2209
2238
|
}
|
|
2210
2239
|
if (!settings.valueConverter.toInput) {
|
|
2211
|
-
settings.valueConverter.toInput = (x) =>
|
|
2240
|
+
settings.valueConverter.toInput = (x) => toJson(x);
|
|
2212
2241
|
}
|
|
2213
2242
|
if (!settings.valueConverter.fromInput) {
|
|
2214
|
-
settings.valueConverter.fromInput = (x) =>
|
|
2243
|
+
settings.valueConverter.fromInput = (x) => fromJson(x);
|
|
2215
2244
|
}
|
|
2216
2245
|
return settings;
|
|
2217
2246
|
}
|
|
@@ -2266,7 +2295,7 @@ class QueryResultImpl {
|
|
|
2266
2295
|
}
|
|
2267
2296
|
_count = undefined;
|
|
2268
2297
|
async getPage(page) {
|
|
2269
|
-
if (page < 1)
|
|
2298
|
+
if ((page ?? 0) < 1)
|
|
2270
2299
|
page = 1;
|
|
2271
2300
|
return this.repo.find({
|
|
2272
2301
|
where: this.options.where,
|
|
@@ -2301,7 +2330,9 @@ class QueryResultImpl {
|
|
|
2301
2330
|
load: this.options.load,
|
|
2302
2331
|
include: this.options.include,
|
|
2303
2332
|
});
|
|
2304
|
-
let nextPage =
|
|
2333
|
+
let nextPage = () => {
|
|
2334
|
+
throw new Error('no more pages');
|
|
2335
|
+
};
|
|
2305
2336
|
let hasNextPage = items.length == this.options.pageSize;
|
|
2306
2337
|
if (hasNextPage) {
|
|
2307
2338
|
let nextPageFilter = await this.repo._createAfterFilter(this.options.orderBy, items[items.length - 1]);
|
|
@@ -2341,7 +2372,7 @@ class QueryResultImpl {
|
|
|
2341
2372
|
return { value: undefined, done: true };
|
|
2342
2373
|
}
|
|
2343
2374
|
else {
|
|
2344
|
-
if (prev?.items.length > 0) {
|
|
2375
|
+
if (prev?.items.length ?? 0 > 0) {
|
|
2345
2376
|
if (this.repo.getEntityRef(prev.items[0]).getId() ==
|
|
2346
2377
|
this.repo.getEntityRef(currentPage.items[0]).getId())
|
|
2347
2378
|
throw new Error('pagination failure, returned same first row');
|
|
@@ -2350,6 +2381,7 @@ class QueryResultImpl {
|
|
|
2350
2381
|
}
|
|
2351
2382
|
if (itemIndex < currentPage.items.length)
|
|
2352
2383
|
return { value: currentPage.items[itemIndex++], done: false };
|
|
2384
|
+
return { done: true, value: undefined };
|
|
2353
2385
|
};
|
|
2354
2386
|
return {
|
|
2355
2387
|
next: async () => {
|
|
@@ -30,7 +30,7 @@ export function Entity(key, ...options) {
|
|
|
30
30
|
for (const rawFilterMember in target) {
|
|
31
31
|
if (Object.prototype.hasOwnProperty.call(target, rawFilterMember)) {
|
|
32
32
|
const element = target[rawFilterMember];
|
|
33
|
-
if (element?.rawFilterInfo
|
|
33
|
+
if (element?.rawFilterInfo) {
|
|
34
34
|
if (!element.rawFilterInfo.key)
|
|
35
35
|
element.rawFilterInfo.key = rawFilterMember;
|
|
36
36
|
}
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
export const flags = {
|
|
2
2
|
error500RetryCount: 4,
|
|
3
3
|
};
|
|
4
|
+
/*y1 - typing discussion:
|
|
5
|
+
* all fields required in fields
|
|
6
|
+
* key as key of entity
|
|
7
|
+
* continue with?
|
|
8
|
+
* should and / or accept also undefined members? the code supports it, not sure if the api should
|
|
9
|
+
* Sql server expression supports undefined as a response
|
|
10
|
+
*/
|
|
4
11
|
//p1 - fix query docs to also explain how it can be used for infinite scroll and pagination.
|
|
5
12
|
//y1 - 'test expression columns without aliases'
|
|
13
|
+
//y1 - ts issue with fields - when a field is optional, it's $ is also optional and thats a problem
|
|
6
14
|
//p1 - see if I can fix the no alias problem in selects
|
|
7
15
|
//p1 - add luid - it's cool for order by.
|
|
8
16
|
//p1 - replace uuid with crypto.randomUUID and allow custom fallback
|
|
@@ -51,6 +59,7 @@ const result = await repo.batch(x=>({
|
|
|
51
59
|
//p1 - article on displayValue including it's definition for entities that is used in relations
|
|
52
60
|
//p1 - article auth.js with express - played with it, requires type="module" and a few more configurations - https://github.com/noam-honig/express-auth
|
|
53
61
|
//p2 - fix remult admin not to load the html into memory until used
|
|
62
|
+
//p2 - add update to entityRef and EntityBase
|
|
54
63
|
//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?
|
|
55
64
|
//p2 - create foreign key constraints in user code - https://codesandbox.io/p/devbox/fk-validator-tdshcs
|
|
56
65
|
//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
|