remult 0.23.0-exp.2 → 0.23.0-exp.21
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 +26 -27
- package/esm/graphql.js +7 -1
- package/esm/index.d.ts +16 -3
- package/esm/index.js +17 -2
- package/esm/internals.d.ts +2 -1
- package/esm/internals.js +1 -1
- package/esm/remult-express.js +1 -1
- package/esm/remult-knex/index.js +2 -1
- package/esm/remult-mongo.js +2 -1
- package/esm/server/JsonEntityFileStorage.js +1 -1
- package/esm/server/expressBridge.js +1 -1
- package/esm/src/CompoundIdField.d.ts +1 -1
- package/esm/src/CompoundIdField.js +3 -1
- package/esm/src/buildRestDataProvider.d.ts +1 -2
- package/esm/src/column-interfaces.d.ts +19 -7
- package/esm/src/column.d.ts +4 -18
- package/esm/src/column.js +10 -44
- package/esm/src/context.d.ts +1 -1
- package/esm/src/context.js +5 -1
- package/esm/src/data-interfaces.js +1 -2
- package/esm/src/data-providers/array-entity-data-provider.d.ts +1 -1
- package/esm/src/data-providers/array-entity-data-provider.js +6 -6
- package/esm/src/data-providers/sql-database.js +2 -1
- package/esm/src/data-providers/web-sql-data-provider.js +3 -3
- package/esm/src/entity.d.ts +48 -17
- package/esm/src/filter/filter-interfaces.d.ts +2 -16
- package/esm/src/filter/filter-interfaces.js +87 -6
- package/esm/src/live-query/LiveQueryClient.js +2 -1
- package/esm/src/live-query/SubscriptionChannel.js +4 -3
- package/esm/src/remult-proxy.js +10 -2
- package/esm/src/remult3/Fields.d.ts +140 -21
- package/esm/src/remult3/Fields.js +26 -30
- package/esm/src/remult3/RepositoryImplementation.d.ts +10 -16
- package/esm/src/remult3/RepositoryImplementation.js +165 -48
- package/esm/src/remult3/entity.d.ts +1 -1
- package/esm/src/remult3/entity.js +0 -1
- package/esm/src/remult3/getEntityRef.d.ts +1 -1
- package/esm/src/remult3/getEntityRef.js +1 -1
- package/esm/src/remult3/relation-loader.js +4 -1
- package/esm/src/remult3/remult3.d.ts +132 -7
- package/esm/src/remult3/remult3.js +30 -0
- package/esm/src/remult3/repository-internals.d.ts +14 -0
- package/esm/src/remult3/repository-internals.js +7 -0
- package/esm/src/server-action.js +1 -1
- package/esm/src/sort.d.ts +3 -3
- package/esm/src/sort.js +36 -8
- package/graphql.js +10 -2
- package/index.d.ts +16 -3
- package/index.js +19 -3
- package/internals.d.ts +2 -1
- package/internals.js +3 -1
- package/package.json +1 -1
- package/remult-express.js +1 -1
- package/remult-knex/index.js +2 -1
- package/remult-mongo.js +2 -1
- package/server/JsonEntityFileStorage.js +1 -1
- package/server/expressBridge.js +1 -1
- package/src/CompoundIdField.d.ts +1 -1
- package/src/CompoundIdField.js +3 -0
- package/src/buildRestDataProvider.d.ts +1 -2
- package/src/column-interfaces.d.ts +19 -7
- package/src/column.d.ts +4 -18
- package/src/column.js +10 -56
- package/src/context.d.ts +1 -1
- package/src/context.js +5 -1
- package/src/data-interfaces.js +1 -2
- package/src/data-providers/array-entity-data-provider.d.ts +1 -1
- package/src/data-providers/array-entity-data-provider.js +5 -6
- package/src/data-providers/sql-database.js +2 -1
- package/src/data-providers/web-sql-data-provider.js +3 -3
- package/src/entity.d.ts +48 -17
- package/src/filter/filter-interfaces.d.ts +2 -16
- package/src/filter/filter-interfaces.js +101 -9
- package/src/live-query/LiveQueryClient.js +2 -1
- package/src/live-query/SubscriptionChannel.js +4 -3
- package/src/remult-proxy.js +43 -29
- package/src/remult3/Fields.d.ts +140 -21
- package/src/remult3/Fields.js +32 -32
- package/src/remult3/RepositoryImplementation.d.ts +10 -16
- package/src/remult3/RepositoryImplementation.js +286 -163
- package/src/remult3/entity.d.ts +1 -1
- package/src/remult3/entity.js +0 -1
- package/src/remult3/getEntityRef.d.ts +1 -1
- package/src/remult3/getEntityRef.js +2 -1
- package/src/remult3/relation-loader.js +4 -1
- package/src/remult3/remult3.d.ts +132 -7
- package/src/remult3/remult3.js +30 -0
- package/src/remult3/repository-internals.d.ts +14 -0
- package/src/remult3/repository-internals.js +11 -0
- package/src/server-action.js +1 -1
- package/src/sort.d.ts +3 -3
- package/src/sort.js +43 -11
|
@@ -23,11 +23,56 @@ export interface EntityRef<entityType> extends Subscribable {
|
|
|
23
23
|
metadata: EntityMetadata<entityType>;
|
|
24
24
|
toApiJson(): any;
|
|
25
25
|
validate(): Promise<ErrorInfo<entityType> | undefined>;
|
|
26
|
+
relations: RepositoryRelations<entityType>;
|
|
26
27
|
readonly apiUpdateAllowed: boolean;
|
|
27
28
|
readonly apiDeleteAllowed: boolean;
|
|
28
29
|
readonly apiInsertAllowed: boolean;
|
|
29
30
|
readonly isLoading: boolean;
|
|
30
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Represents a lifecycle event associated with an entity instance. These events
|
|
34
|
+
* are triggered during various stages of the entity's lifecycle, such as validation,
|
|
35
|
+
* saving, saved, deleting, and deleted.
|
|
36
|
+
*
|
|
37
|
+
* @template entityType The type of the entity associated with the event.
|
|
38
|
+
* @see [Entity Lifecycle Hooks](http://remult.dev/docs/lifecycle-hooks)
|
|
39
|
+
*/
|
|
40
|
+
export interface LifecycleEvent<entityType> {
|
|
41
|
+
/**
|
|
42
|
+
* Indicates whether the entity is new or existing.
|
|
43
|
+
*/
|
|
44
|
+
isNew: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* A reference to the fields of the entity, providing access to its properties.
|
|
47
|
+
*/
|
|
48
|
+
fields: FieldsRef<entityType>;
|
|
49
|
+
/**
|
|
50
|
+
* The ID of the entity.
|
|
51
|
+
*/
|
|
52
|
+
id: idType<entityType>;
|
|
53
|
+
/**
|
|
54
|
+
* The original ID of the entity, useful for tracking changes.
|
|
55
|
+
*/
|
|
56
|
+
originalId: idType<entityType>;
|
|
57
|
+
/**
|
|
58
|
+
* The repository associated with the entity, providing access to repository methods.
|
|
59
|
+
*/
|
|
60
|
+
repository: Repository<entityType>;
|
|
61
|
+
/**
|
|
62
|
+
* Metadata describing the entity's structure and configuration.
|
|
63
|
+
*/
|
|
64
|
+
metadata: EntityMetadata<entityType>;
|
|
65
|
+
/**
|
|
66
|
+
* A function that can be used to prevent the default behavior associated with
|
|
67
|
+
* the lifecycle event.
|
|
68
|
+
*/
|
|
69
|
+
preventDefault: VoidFunction;
|
|
70
|
+
/**
|
|
71
|
+
* A reference to the repository relations associated with the entity, providing
|
|
72
|
+
* access to related entities and their data.
|
|
73
|
+
*/
|
|
74
|
+
relations: RepositoryRelations<entityType>;
|
|
75
|
+
}
|
|
31
76
|
export interface ControllerRef<entityType> extends Subscribable {
|
|
32
77
|
hasErrors(): boolean;
|
|
33
78
|
fields: FieldsRef<entityType>;
|
|
@@ -44,7 +89,7 @@ export interface Subscribable {
|
|
|
44
89
|
subscribe(listener: RefSubscriber): Unsubscribe;
|
|
45
90
|
}
|
|
46
91
|
export type FieldsRef<entityType> = {
|
|
47
|
-
[Properties in keyof OmitEB<entityType>]: entityType[Properties] extends {
|
|
92
|
+
[Properties in keyof OmitEB<entityType>]: NonNullable<entityType[Properties]> extends {
|
|
48
93
|
id?: number | string;
|
|
49
94
|
} ? IdFieldRef<entityType, entityType[Properties]> : FieldRef<entityType, entityType[Properties]>;
|
|
50
95
|
} & {
|
|
@@ -301,7 +346,7 @@ export declare type EntityOrderBy<entityType> = {
|
|
|
301
346
|
export declare type EntityFilter<entityType> = {
|
|
302
347
|
[Properties in keyof Partial<OmitEB<entityType>>]?: (Partial<OmitEB<entityType>>[Properties] extends number | Date | undefined ? ComparisonValueFilter<Partial<OmitEB<entityType>>[Properties]> : Partial<OmitEB<entityType>>[Properties] extends string | undefined ? ContainsStringValueFilter & ComparisonValueFilter<string> : Partial<OmitEB<entityType>>[Properties] extends boolean | undefined ? ValueFilter<boolean> : Partial<OmitEB<entityType>>[Properties] extends {
|
|
303
348
|
id?: string | number;
|
|
304
|
-
} | undefined ? IdFilter<Partial<OmitEB<entityType>>[Properties]> : ValueFilter<Partial<OmitEB<entityType>>[Properties]>)
|
|
349
|
+
} | undefined ? IdFilter<Partial<OmitEB<entityType>>[Properties]> : ValueFilter<Partial<OmitEB<entityType>>[Properties]>) | ContainsStringValueFilter;
|
|
305
350
|
} & {
|
|
306
351
|
$or?: EntityFilter<entityType>[];
|
|
307
352
|
$and?: EntityFilter<entityType>[];
|
|
@@ -331,7 +376,46 @@ export type IdFilter<valueType> = ValueFilter<valueType> | {
|
|
|
331
376
|
} ? number : string>;
|
|
332
377
|
};
|
|
333
378
|
export interface LoadOptions<entityType> {
|
|
379
|
+
/**
|
|
380
|
+
* @deprecated The 'load' option is deprecated and will be removed in future versions.
|
|
381
|
+
* Use 'Relations.toOne' along with the 'include' option instead.
|
|
382
|
+
*
|
|
383
|
+
* Example usage:
|
|
384
|
+
* ```
|
|
385
|
+
* // Deprecated usage with 'load' option
|
|
386
|
+
* await remult.repo(Order).find({
|
|
387
|
+
* load: (o) => [o.customer],
|
|
388
|
+
* });
|
|
389
|
+
*
|
|
390
|
+
*
|
|
391
|
+
* // Preferred usage with 'Relations.toOne' and 'include' option
|
|
392
|
+
* await remult.repo(Order).find({
|
|
393
|
+
* include: { customer: true },
|
|
394
|
+
* });
|
|
395
|
+
* ```
|
|
396
|
+
*/
|
|
334
397
|
load?: (entity: FieldsMetadata<entityType>) => FieldMetadata[];
|
|
398
|
+
/**
|
|
399
|
+
* An option used in the `find` and `findFirst` methods to specify which related entities should be included
|
|
400
|
+
* when querying the source entity. It allows you to eagerly load related data to avoid N+1 query problems.
|
|
401
|
+
*
|
|
402
|
+
* @param include An object specifying the related entities to include, their options, and filtering criteria.
|
|
403
|
+
*
|
|
404
|
+
* Example usage:
|
|
405
|
+
* ```
|
|
406
|
+
* const orders = await customerRepo.find({
|
|
407
|
+
* include: {
|
|
408
|
+
* // Include the 'tags' relation for each customer.
|
|
409
|
+
* tags: true,
|
|
410
|
+
* },
|
|
411
|
+
* });
|
|
412
|
+
* ```
|
|
413
|
+
* In this example, the `tags` relation for each customer will be loaded and included in the query result.
|
|
414
|
+
*
|
|
415
|
+
* @see {@link Relations.toMany}
|
|
416
|
+
* @see {@link Relations.toOne}
|
|
417
|
+
* @see {@link RelationOptions}
|
|
418
|
+
*/
|
|
335
419
|
include?: MembersToInclude<entityType>;
|
|
336
420
|
}
|
|
337
421
|
export interface FindOptionsBase<entityType> extends LoadOptions<entityType> {
|
|
@@ -402,26 +486,67 @@ export interface RelationInfo {
|
|
|
402
486
|
toType: () => any;
|
|
403
487
|
type: 'reference' | 'toOne' | 'toMany';
|
|
404
488
|
}
|
|
489
|
+
/**
|
|
490
|
+
* Options for configuring a relation between entities.
|
|
491
|
+
*
|
|
492
|
+
* @template fromEntity The type of the source entity (the entity defining the relation).
|
|
493
|
+
* @template toEntity The type of the target entity (the related entity).
|
|
494
|
+
* @template matchIdEntity The type used for matching IDs in the relation.
|
|
495
|
+
* @template optionsType The type of find options to apply to the relation (default is FindOptionsBase<toEntity>).
|
|
496
|
+
*/
|
|
405
497
|
export type RelationOptions<fromEntity, toEntity, matchIdEntity, optionsType extends FindOptionsBase<toEntity> = FindOptionsBase<toEntity>> = {
|
|
498
|
+
/**
|
|
499
|
+
* An object specifying custom field names for the relation.
|
|
500
|
+
* Each key represents a field in the related entity, and its value is the corresponding field in the source entity.
|
|
501
|
+
* For example, `{ customerId: 'id' }` maps the 'customerId' field in the related entity to the 'id' field in the source entity.
|
|
502
|
+
* This is useful when you want to define custom field mappings for the relation.
|
|
503
|
+
*/
|
|
406
504
|
fields?: {
|
|
407
505
|
[K in keyof toEntity]?: keyof fromEntity;
|
|
408
506
|
};
|
|
507
|
+
/**
|
|
508
|
+
* The name of the field for this relation.
|
|
509
|
+
*/
|
|
409
510
|
field?: keyof matchIdEntity;
|
|
410
|
-
|
|
411
|
-
|
|
511
|
+
/**
|
|
512
|
+
* Find options to apply to the relation when fetching related entities.
|
|
513
|
+
* You can specify a predefined set of find options or provide a function that takes the source entity
|
|
514
|
+
* and returns find options dynamically.
|
|
515
|
+
* These options allow you to customize how related entities are retrieved.
|
|
516
|
+
*/
|
|
412
517
|
findOptions?: optionsType | ((entity: fromEntity) => optionsType);
|
|
518
|
+
/**
|
|
519
|
+
* Determines whether the relation should be included by default when querying the source entity.
|
|
520
|
+
* When set to true, related entities will be automatically included when querying the source entity.
|
|
521
|
+
* If false or not specified, related entities will need to be explicitly included using the `include` option.
|
|
522
|
+
*/
|
|
413
523
|
defaultIncluded?: boolean;
|
|
414
|
-
} & FieldOptions
|
|
524
|
+
} & Pick<FieldOptions, 'caption'>;
|
|
415
525
|
export type ObjectMembersOnly<T> = {
|
|
416
526
|
[K in keyof Pick<T, {
|
|
417
527
|
[K in keyof T]: T[K] extends object | undefined | null ? T[K] extends Date | undefined | null ? never : K : never;
|
|
418
528
|
}[keyof T]>]: T[K];
|
|
419
529
|
};
|
|
420
530
|
export type MembersToInclude<T> = {
|
|
421
|
-
[K in keyof ObjectMembersOnly<T>]?:
|
|
531
|
+
[K in keyof ObjectMembersOnly<T>]?: boolean | (NonNullable<T[K]> extends Array<any> ? FindOptions<NonNullable<T[K]>[number]> : FindFirstOptions<NonNullable<T[K]>>);
|
|
422
532
|
};
|
|
423
533
|
export type RepositoryRelations<entityType> = {
|
|
424
|
-
[K in keyof ObjectMembersOnly<entityType>]
|
|
534
|
+
[K in keyof ObjectMembersOnly<entityType>]-?: NonNullable<entityType[K]> extends Array<infer R> ? Repository<R> : entityType[K] extends infer R ? {
|
|
425
535
|
findOne: (options?: FindOptionsBase<R>) => Promise<R>;
|
|
426
536
|
} : never;
|
|
427
537
|
};
|
|
538
|
+
export declare type EntityIdFields<entityType> = {
|
|
539
|
+
[Properties in keyof Partial<OmitEB<entityType>>]?: true;
|
|
540
|
+
};
|
|
541
|
+
export interface ClassFieldDecoratorContextStub<entityType, valueType> {
|
|
542
|
+
readonly access: {
|
|
543
|
+
set(object: entityType, value: valueType): void;
|
|
544
|
+
};
|
|
545
|
+
readonly name: string;
|
|
546
|
+
}
|
|
547
|
+
export interface ClassDecoratorContextStub<Class extends new (...args: any) => any = new (...args: any) => any> {
|
|
548
|
+
readonly kind: 'class';
|
|
549
|
+
readonly name: string | undefined;
|
|
550
|
+
addInitializer(initializer: (this: Class) => void): void;
|
|
551
|
+
}
|
|
552
|
+
export type ClassFieldDecorator<entityType, valueType> = (target: any, context: string | ClassFieldDecoratorContextStub<entityType, valueType | undefined>, c?: any) => void;
|
|
@@ -1 +1,31 @@
|
|
|
1
1
|
export {};
|
|
2
|
+
//p1 - include relations in the api docs
|
|
3
|
+
//p1 - include Relation options in the api docs
|
|
4
|
+
//p1 - fix { allowApiRead: r => r.user.name === 'superman' } } in allowed for instace docs
|
|
5
|
+
//p1 - fix seeallowed in ref_entity
|
|
6
|
+
//p1 - write doc about controlling updates of rows...
|
|
7
|
+
//p1 - 'eventId' autocomplete in task app did not work
|
|
8
|
+
//p1 - need a way to extract the fields from the relation - for generating relation based sql
|
|
9
|
+
//p1 - remult object was used outside context
|
|
10
|
+
// ```
|
|
11
|
+
// sqlExpression: async (e) => {
|
|
12
|
+
// const v = await dbNamesOf(volunteerInTask)
|
|
13
|
+
// return `select true from ${v} where ${
|
|
14
|
+
// v.task
|
|
15
|
+
// }=${await e.getDbName()}.${await e.fields.id.getDbName()} and ${SqlDatabase.filterToRaw<volunteerInTask>(
|
|
16
|
+
// repo(volunteerInTask),
|
|
17
|
+
// {
|
|
18
|
+
// canceled: false,
|
|
19
|
+
// }
|
|
20
|
+
// )}`
|
|
21
|
+
// },
|
|
22
|
+
// })
|
|
23
|
+
// ```
|
|
24
|
+
//p2 - consider includeInApi as AllowedForInstance
|
|
25
|
+
//p1 - why didn't this._.relations.statusChanges.insert({})work?
|
|
26
|
+
//p1 - active record with include thinks that the row was change!
|
|
27
|
+
//p1 - add docs for apply changes
|
|
28
|
+
//p1 - update related field with null should respect it's allowed null - otherwise we get a null error for that field.
|
|
29
|
+
//p1 - when the include doesn't find the many to one - it deletes the id!!!
|
|
30
|
+
//y1 - discuss a default date formatter
|
|
31
|
+
//p1 - consider using this in saving etc...
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { EntityDataProviderFindOptions } from '../data-interfaces';
|
|
2
|
+
import type { Filter } from '../filter/filter-interfaces';
|
|
3
|
+
import type { EntityFilter, EntityOrderBy, FindOptions, LoadOptions, Repository } from './remult3';
|
|
4
|
+
export interface RepositoryInternal<entityType> {
|
|
5
|
+
createAfterFilter(orderBy: EntityOrderBy<entityType>, lastRow: entityType): Promise<EntityFilter<entityType>>;
|
|
6
|
+
fromJsonArray(jsonItems: any[], loadOptions: LoadOptions<entityType>): Promise<entityType[]>;
|
|
7
|
+
buildEntityDataProviderFindOptions(options: FindOptions<entityType>): Promise<EntityDataProviderFindOptions>;
|
|
8
|
+
translateWhereToFilter(where: EntityFilter<entityType>): Promise<Filter>;
|
|
9
|
+
getCachedById(id: any, doNotLoadIfNotFound: boolean): entityType;
|
|
10
|
+
getCachedByIdAsync(id: any, doNotLoadIfNotFound: boolean): Promise<entityType>;
|
|
11
|
+
addToCache(item: entityType): any;
|
|
12
|
+
}
|
|
13
|
+
export declare function getRepositoryInternals<entityType>(repo: Repository<entityType>): RepositoryInternal<entityType>;
|
|
14
|
+
export declare const getInternalKey = "getInternal";
|
package/esm/src/server-action.js
CHANGED
|
@@ -268,7 +268,7 @@ export function BackendMethod(options) {
|
|
|
268
268
|
id: defs.getOriginalId(),
|
|
269
269
|
},
|
|
270
270
|
}, baseUrl, http);
|
|
271
|
-
await defs._updateEntityBasedOnApi(r.rowInfo.data);
|
|
271
|
+
await defs._updateEntityBasedOnApi(r.rowInfo.data, true);
|
|
272
272
|
return r.result;
|
|
273
273
|
}
|
|
274
274
|
catch (err) {
|
package/esm/src/sort.d.ts
CHANGED
|
@@ -6,9 +6,9 @@ export declare class Sort {
|
|
|
6
6
|
Segments: SortSegment[];
|
|
7
7
|
reverse(): Sort;
|
|
8
8
|
compare(a: any, b: any, getFieldKey?: (field: FieldMetadata) => string): number;
|
|
9
|
-
static translateOrderByToSort<T>(entityDefs: EntityMetadata<T>, orderBy
|
|
10
|
-
static createUniqueSort<T>(entityMetadata: EntityMetadata<T>, orderBy
|
|
11
|
-
static createUniqueEntityOrderBy<T>(entityMetadata: EntityMetadata<T>, orderBy
|
|
9
|
+
static translateOrderByToSort<T>(entityDefs: EntityMetadata<T>, orderBy?: EntityOrderBy<T>): Sort;
|
|
10
|
+
static createUniqueSort<T>(entityMetadata: EntityMetadata<T>, orderBy?: Sort): Sort;
|
|
11
|
+
static createUniqueEntityOrderBy<T>(entityMetadata: EntityMetadata<T>, orderBy?: EntityOrderBy<T>): EntityOrderBy<T>;
|
|
12
12
|
}
|
|
13
13
|
export interface SortSegment {
|
|
14
14
|
field: FieldMetadata;
|
package/esm/src/sort.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getRelationInfo } from '../internals';
|
|
1
2
|
import { CompoundIdField } from './CompoundIdField';
|
|
2
3
|
export class Sort {
|
|
3
4
|
toEntityOrderBy() {
|
|
@@ -28,8 +29,8 @@ export class Sort {
|
|
|
28
29
|
let r = 0;
|
|
29
30
|
for (let i = 0; i < this.Segments.length; i++) {
|
|
30
31
|
let seg = this.Segments[i];
|
|
31
|
-
let left = a[getFieldKey(seg.field)];
|
|
32
|
-
let right = b[getFieldKey(seg.field)];
|
|
32
|
+
let left = fixValueForSort(a[getFieldKey(seg.field)]);
|
|
33
|
+
let right = fixValueForSort(b[getFieldKey(seg.field)]);
|
|
33
34
|
if (left > right)
|
|
34
35
|
r = 1;
|
|
35
36
|
else if (left < right)
|
|
@@ -45,14 +46,13 @@ export class Sort {
|
|
|
45
46
|
static translateOrderByToSort(entityDefs, orderBy) {
|
|
46
47
|
if (!orderBy)
|
|
47
48
|
return undefined;
|
|
48
|
-
let sort;
|
|
49
|
-
if (orderBy)
|
|
50
|
-
sort = new Sort();
|
|
49
|
+
let sort = new Sort();
|
|
50
|
+
if (orderBy)
|
|
51
51
|
for (const key in orderBy) {
|
|
52
52
|
if (Object.prototype.hasOwnProperty.call(orderBy, key)) {
|
|
53
53
|
const element = orderBy[key];
|
|
54
54
|
let field = entityDefs.fields.find(key);
|
|
55
|
-
|
|
55
|
+
const addSegment = (field) => {
|
|
56
56
|
switch (element) {
|
|
57
57
|
case 'desc':
|
|
58
58
|
sort.Segments.push({ field, isDescending: true });
|
|
@@ -60,14 +60,35 @@ export class Sort {
|
|
|
60
60
|
case 'asc':
|
|
61
61
|
sort.Segments.push({ field });
|
|
62
62
|
}
|
|
63
|
+
};
|
|
64
|
+
if (field) {
|
|
65
|
+
const rel = getRelationInfo(field.options);
|
|
66
|
+
const op = field.options;
|
|
67
|
+
if (rel?.type === 'toOne') {
|
|
68
|
+
if (typeof op.field === 'string') {
|
|
69
|
+
addSegment(entityDefs.fields.find(op.field));
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
if (op.fields) {
|
|
73
|
+
for (const key in op.fields) {
|
|
74
|
+
if (Object.prototype.hasOwnProperty.call(op.fields, key)) {
|
|
75
|
+
const keyInMyEntity = op.fields[key];
|
|
76
|
+
addSegment(entityDefs.fields.find(keyInMyEntity.toString()));
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
else
|
|
83
|
+
addSegment(field);
|
|
63
84
|
}
|
|
64
85
|
}
|
|
65
86
|
}
|
|
66
|
-
}
|
|
67
87
|
return sort;
|
|
68
88
|
}
|
|
69
89
|
static createUniqueSort(entityMetadata, orderBy) {
|
|
70
|
-
if (!orderBy || Object.keys(orderBy).length === 0)
|
|
90
|
+
if ((!orderBy || Object.keys(orderBy).length === 0) &&
|
|
91
|
+
entityMetadata.options.defaultOrderBy)
|
|
71
92
|
orderBy = Sort.translateOrderByToSort(entityMetadata, entityMetadata.options.defaultOrderBy);
|
|
72
93
|
if (!orderBy)
|
|
73
94
|
orderBy = new Sort({ field: entityMetadata.idMetadata.field });
|
|
@@ -105,3 +126,10 @@ export class Sort {
|
|
|
105
126
|
return orderBy;
|
|
106
127
|
}
|
|
107
128
|
}
|
|
129
|
+
function fixValueForSort(a) {
|
|
130
|
+
if (a == undefined || a == null)
|
|
131
|
+
return a;
|
|
132
|
+
if (a.id !== undefined)
|
|
133
|
+
return a.id;
|
|
134
|
+
return a;
|
|
135
|
+
}
|
package/graphql.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.translateWhereToRestBody = exports.remultGraphql = void 0;
|
|
4
4
|
var tslib_1 = require("tslib");
|
|
5
|
+
var internals_1 = require("./internals");
|
|
5
6
|
var index_1 = require("./index");
|
|
6
7
|
var data_api_1 = require("./src/data-api");
|
|
7
8
|
var v2ConnectionAndPagination = false;
|
|
@@ -522,6 +523,11 @@ function remultGraphql(options) {
|
|
|
522
523
|
}
|
|
523
524
|
var whereTypeFields = [];
|
|
524
525
|
var _loop_2 = function (f) {
|
|
526
|
+
var ri = (0, internals_1.getRelationInfo)(f.options);
|
|
527
|
+
// let's not consider toMany relations for now
|
|
528
|
+
if ((ri === null || ri === void 0 ? void 0 : ri.type) === 'toMany') {
|
|
529
|
+
return "break";
|
|
530
|
+
}
|
|
525
531
|
if (f.options.includeInApi === false)
|
|
526
532
|
return "continue";
|
|
527
533
|
var type = 'String';
|
|
@@ -634,7 +640,9 @@ function remultGraphql(options) {
|
|
|
634
640
|
try {
|
|
635
641
|
for (var _s = (e_6 = void 0, tslib_1.__values(meta.fields)), _t = _s.next(); !_t.done; _t = _s.next()) {
|
|
636
642
|
var f = _t.value;
|
|
637
|
-
_loop_2(f);
|
|
643
|
+
var state_1 = _loop_2(f);
|
|
644
|
+
if (state_1 === "break")
|
|
645
|
+
break;
|
|
638
646
|
}
|
|
639
647
|
}
|
|
640
648
|
catch (e_6_1) { e_6 = { error: e_6_1 }; }
|
|
@@ -900,7 +908,7 @@ function translateWhereToRestBody(fields, _a) {
|
|
|
900
908
|
var result = {};
|
|
901
909
|
var _loop_3 = function (field) {
|
|
902
910
|
var e_8, _c;
|
|
903
|
-
if (field.
|
|
911
|
+
if (field.options.includeInApi === false)
|
|
904
912
|
return "continue";
|
|
905
913
|
var condition = where[field.key];
|
|
906
914
|
if (condition) {
|
package/index.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
import type { ClassType } from './classType';
|
|
2
|
+
export { OmitEB, FieldsMetadata, FieldRef, IdFieldRef, FieldsRef, EntityMetadata, EntityOrderBy, EntityFilter, FindOptions, QueryResult, QueryOptions, Repository, FindFirstOptions, ComparisonValueFilter, ValueFilter, IdFilter, ContainsStringValueFilter, EntityRef, SortSegments, Paginator, LiveQuery, LiveQueryChangeInfo, Subscribable, RefSubscriber, RefSubscriberBase, RelationOptions, ObjectMembersOnly, MembersToInclude, RepositoryRelations, EntityIdFields, ClassFieldDecorator as MemberDecorator, ClassFieldDecoratorContextStub, } from './src/remult3/remult3';
|
|
2
3
|
export { EntityBase, ControllerBase, FieldType, getFields, ValueListFieldType, getValueList, ValueListFieldOptions, ValueListInfo, CaptionTransformer, } from './src/remult3/RepositoryImplementation';
|
|
3
4
|
export { Entity } from './src/remult3/entity';
|
|
4
5
|
export { getEntityRef } from './src/remult3/getEntityRef';
|
|
5
|
-
export { Field, Fields, StringFieldOptions } from './src/remult3/Fields';
|
|
6
|
+
export { Field, Fields, StringFieldOptions, Relations, } from './src/remult3/Fields';
|
|
6
7
|
export { IdEntity } from './src/remult3/IdEntity';
|
|
7
8
|
export { describeClass } from './src/remult3/DecoratorReplacer';
|
|
8
9
|
export { EntityOptions } from './src/entity';
|
|
@@ -21,7 +22,6 @@ export { Controller, BackendMethodOptions, BackendMethod, ProgressListener, } fr
|
|
|
21
22
|
export { Allowed, Allow, Remult, RemultContext, ApiClient, isBackend, AllowedForInstance, EventDispatcher, EventSource, UserInfo, } from './src/context';
|
|
22
23
|
export { ExternalHttpProvider } from './src/buildRestDataProvider';
|
|
23
24
|
export { SortSegment, Sort } from './src/sort';
|
|
24
|
-
export { OneToMany } from './src/column';
|
|
25
25
|
export { CompoundIdField } from './src/CompoundIdField';
|
|
26
26
|
export { Filter } from './src/filter/filter-interfaces';
|
|
27
27
|
export { UrlBuilder } from './urlBuilder';
|
|
@@ -30,3 +30,16 @@ export { ValueConverters } from './src/valueConverters';
|
|
|
30
30
|
export { remult } from './src/remult-proxy';
|
|
31
31
|
export { SubscriptionServer, LiveQueryStorage, StoredQuery, InMemoryLiveQueryStorage, } from './src/live-query/SubscriptionServer';
|
|
32
32
|
export { SubscriptionListener, SubscriptionClientConnection, SubscriptionClient, SubscriptionChannel, LiveQueryChange, Unsubscribe, } from './src/live-query/SubscriptionChannel';
|
|
33
|
+
/**
|
|
34
|
+
* A convenient shortcut function to quickly obtain a repository for a specific entity type in Remult.
|
|
35
|
+
*
|
|
36
|
+
* @param entity The entity class type for which you want to get a repository.
|
|
37
|
+
* @returns A repository instance for the specified entity type.
|
|
38
|
+
*
|
|
39
|
+
* Example usage:
|
|
40
|
+
* ```ts
|
|
41
|
+
* await repo(Task).find()
|
|
42
|
+
* await repo(Customer).insert()
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export declare function repo<entityType>(entity: ClassType<entityType>): import("./src/remult3/remult3").Repository<entityType>;
|
package/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SubscriptionChannel = exports.InMemoryLiveQueryStorage = exports.remult = exports.ValueConverters = exports.Validators = exports.UrlBuilder = exports.Filter = exports.CompoundIdField = exports.
|
|
3
|
+
exports.repo = exports.SubscriptionChannel = exports.InMemoryLiveQueryStorage = exports.remult = exports.ValueConverters = exports.Validators = exports.UrlBuilder = exports.Filter = exports.CompoundIdField = exports.Sort = exports.EventSource = exports.isBackend = exports.Remult = exports.Allow = exports.ProgressListener = exports.BackendMethod = exports.Controller = exports.JsonDataProvider = exports.dbNamesOf = exports.CustomSqlFilterBuilder = exports.SqlDatabase = exports.WebSqlDataProvider = exports.ArrayEntityDataProvider = exports.InMemoryDataProvider = exports.RestDataProvider = exports.describeClass = exports.IdEntity = exports.Relations = exports.Fields = exports.Field = exports.getEntityRef = exports.Entity = exports.CaptionTransformer = exports.ValueListInfo = exports.getValueList = exports.ValueListFieldType = exports.getFields = exports.FieldType = exports.ControllerBase = exports.EntityBase = void 0;
|
|
4
4
|
var RepositoryImplementation_1 = require("./src/remult3/RepositoryImplementation");
|
|
5
5
|
Object.defineProperty(exports, "EntityBase", { enumerable: true, get: function () { return RepositoryImplementation_1.EntityBase; } });
|
|
6
6
|
Object.defineProperty(exports, "ControllerBase", { enumerable: true, get: function () { return RepositoryImplementation_1.ControllerBase; } });
|
|
@@ -17,6 +17,7 @@ Object.defineProperty(exports, "getEntityRef", { enumerable: true, get: function
|
|
|
17
17
|
var Fields_1 = require("./src/remult3/Fields");
|
|
18
18
|
Object.defineProperty(exports, "Field", { enumerable: true, get: function () { return Fields_1.Field; } });
|
|
19
19
|
Object.defineProperty(exports, "Fields", { enumerable: true, get: function () { return Fields_1.Fields; } });
|
|
20
|
+
Object.defineProperty(exports, "Relations", { enumerable: true, get: function () { return Fields_1.Relations; } });
|
|
20
21
|
var IdEntity_1 = require("./src/remult3/IdEntity");
|
|
21
22
|
Object.defineProperty(exports, "IdEntity", { enumerable: true, get: function () { return IdEntity_1.IdEntity; } });
|
|
22
23
|
var DecoratorReplacer_1 = require("./src/remult3/DecoratorReplacer");
|
|
@@ -48,8 +49,6 @@ Object.defineProperty(exports, "isBackend", { enumerable: true, get: function ()
|
|
|
48
49
|
Object.defineProperty(exports, "EventSource", { enumerable: true, get: function () { return context_1.EventSource; } });
|
|
49
50
|
var sort_1 = require("./src/sort");
|
|
50
51
|
Object.defineProperty(exports, "Sort", { enumerable: true, get: function () { return sort_1.Sort; } });
|
|
51
|
-
var column_1 = require("./src/column");
|
|
52
|
-
Object.defineProperty(exports, "OneToMany", { enumerable: true, get: function () { return column_1.OneToMany; } });
|
|
53
52
|
var CompoundIdField_1 = require("./src/CompoundIdField");
|
|
54
53
|
Object.defineProperty(exports, "CompoundIdField", { enumerable: true, get: function () { return CompoundIdField_1.CompoundIdField; } });
|
|
55
54
|
var filter_interfaces_1 = require("./src/filter/filter-interfaces");
|
|
@@ -62,8 +61,25 @@ var valueConverters_1 = require("./src/valueConverters");
|
|
|
62
61
|
Object.defineProperty(exports, "ValueConverters", { enumerable: true, get: function () { return valueConverters_1.ValueConverters; } });
|
|
63
62
|
var remult_proxy_1 = require("./src/remult-proxy");
|
|
64
63
|
Object.defineProperty(exports, "remult", { enumerable: true, get: function () { return remult_proxy_1.remult; } });
|
|
64
|
+
var remult_proxy_2 = require("./src/remult-proxy");
|
|
65
65
|
//export { getId } from './src/remult3/getId';
|
|
66
66
|
var SubscriptionServer_1 = require("./src/live-query/SubscriptionServer");
|
|
67
67
|
Object.defineProperty(exports, "InMemoryLiveQueryStorage", { enumerable: true, get: function () { return SubscriptionServer_1.InMemoryLiveQueryStorage; } });
|
|
68
68
|
var SubscriptionChannel_1 = require("./src/live-query/SubscriptionChannel");
|
|
69
69
|
Object.defineProperty(exports, "SubscriptionChannel", { enumerable: true, get: function () { return SubscriptionChannel_1.SubscriptionChannel; } });
|
|
70
|
+
/**
|
|
71
|
+
* A convenient shortcut function to quickly obtain a repository for a specific entity type in Remult.
|
|
72
|
+
*
|
|
73
|
+
* @param entity The entity class type for which you want to get a repository.
|
|
74
|
+
* @returns A repository instance for the specified entity type.
|
|
75
|
+
*
|
|
76
|
+
* Example usage:
|
|
77
|
+
* ```ts
|
|
78
|
+
* await repo(Task).find()
|
|
79
|
+
* await repo(Customer).insert()
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
function repo(entity) {
|
|
83
|
+
return remult_proxy_2.remult.repo(entity);
|
|
84
|
+
}
|
|
85
|
+
exports.repo = repo;
|
package/internals.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { getRelationInfo } from './src/remult3/relationInfoMember';
|
|
2
|
-
export { decorateColumnSettings } from './src/remult3/RepositoryImplementation';
|
|
2
|
+
export { decorateColumnSettings, controllerRefImpl, getControllerRef, } from './src/remult3/RepositoryImplementation';
|
|
3
3
|
export { getEntitySettings } from './src/remult3/getEntityRef';
|
|
4
4
|
export { __updateEntityBasedOnWhere } from './src/filter/filter-interfaces';
|
|
5
5
|
export { actionInfo } from './src/server-action-info';
|
|
6
6
|
export { RelationInfo } from './src/remult3/remult3';
|
|
7
|
+
export { ClassType } from './classType';
|
package/internals.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.actionInfo = exports.__updateEntityBasedOnWhere = exports.getEntitySettings = exports.decorateColumnSettings = exports.getRelationInfo = void 0;
|
|
3
|
+
exports.actionInfo = exports.__updateEntityBasedOnWhere = exports.getEntitySettings = exports.getControllerRef = exports.controllerRefImpl = exports.decorateColumnSettings = exports.getRelationInfo = void 0;
|
|
4
4
|
var relationInfoMember_1 = require("./src/remult3/relationInfoMember");
|
|
5
5
|
Object.defineProperty(exports, "getRelationInfo", { enumerable: true, get: function () { return relationInfoMember_1.getRelationInfo; } });
|
|
6
6
|
var RepositoryImplementation_1 = require("./src/remult3/RepositoryImplementation");
|
|
7
7
|
Object.defineProperty(exports, "decorateColumnSettings", { enumerable: true, get: function () { return RepositoryImplementation_1.decorateColumnSettings; } });
|
|
8
|
+
Object.defineProperty(exports, "controllerRefImpl", { enumerable: true, get: function () { return RepositoryImplementation_1.controllerRefImpl; } });
|
|
9
|
+
Object.defineProperty(exports, "getControllerRef", { enumerable: true, get: function () { return RepositoryImplementation_1.getControllerRef; } });
|
|
8
10
|
var getEntityRef_1 = require("./src/remult3/getEntityRef");
|
|
9
11
|
Object.defineProperty(exports, "getEntitySettings", { enumerable: true, get: function () { return getEntityRef_1.getEntitySettings; } });
|
|
10
12
|
var filter_interfaces_1 = require("./src/filter/filter-interfaces");
|
package/package.json
CHANGED
package/remult-express.js
CHANGED
|
@@ -28,7 +28,7 @@ function remultExpress(options) {
|
|
|
28
28
|
getRemult: function (req) { return server.getRemult(req); },
|
|
29
29
|
openApiDoc: function (options) { return server.openApiDoc(options); },
|
|
30
30
|
withRemult: function (req, res, next) { return server.withRemult(req, res, next); },
|
|
31
|
-
// [ ]
|
|
31
|
+
// [ ] V1.5 add with remult promise
|
|
32
32
|
});
|
|
33
33
|
}
|
|
34
34
|
exports.remultExpress = remultExpress;
|
package/remult-knex/index.js
CHANGED
|
@@ -11,6 +11,7 @@ var RepositoryImplementation_1 = require("../src/remult3/RepositoryImplementatio
|
|
|
11
11
|
var sort_1 = require("../src/sort");
|
|
12
12
|
var valueConverters_1 = require("../src/valueConverters");
|
|
13
13
|
var resultCompoundIdFilter_1 = require("../src/resultCompoundIdFilter");
|
|
14
|
+
var repository_internals_1 = require("../src/remult3/repository-internals");
|
|
14
15
|
var KnexDataProvider = /** @class */ (function () {
|
|
15
16
|
function KnexDataProvider(knex) {
|
|
16
17
|
this.knex = knex;
|
|
@@ -91,7 +92,7 @@ var KnexDataProvider = /** @class */ (function () {
|
|
|
91
92
|
case 1:
|
|
92
93
|
b = new (_a.apply(FilterConsumerBridgeToKnexRequest, [void 0, _b.sent()]))();
|
|
93
94
|
b._addWhere = false;
|
|
94
|
-
return [4 /*yield*/, repo.translateWhereToFilter(condition)];
|
|
95
|
+
return [4 /*yield*/, (0, repository_internals_1.getRepositoryInternals)(repo).translateWhereToFilter(condition)];
|
|
95
96
|
case 2: return [4 /*yield*/, (_b.sent()).__applyToConsumer(b)];
|
|
96
97
|
case 3:
|
|
97
98
|
_b.sent();
|
package/remult-mongo.js
CHANGED
|
@@ -7,6 +7,7 @@ var filter_consumer_bridge_to_sql_request_1 = require("./src/filter/filter-consu
|
|
|
7
7
|
var remult_proxy_1 = require("./src/remult-proxy");
|
|
8
8
|
var RepositoryImplementation_1 = require("./src/remult3/RepositoryImplementation");
|
|
9
9
|
var resultCompoundIdFilter_1 = require("./src/resultCompoundIdFilter");
|
|
10
|
+
var repository_internals_1 = require("./src/remult3/repository-internals");
|
|
10
11
|
var MongoDataProvider = /** @class */ (function () {
|
|
11
12
|
function MongoDataProvider(db, client, options) {
|
|
12
13
|
this.db = db;
|
|
@@ -80,7 +81,7 @@ var MongoDataProvider = /** @class */ (function () {
|
|
|
80
81
|
case 1:
|
|
81
82
|
b = new (_a.apply(FilterConsumerBridgeToMongo, [void 0, _b.sent()]))();
|
|
82
83
|
b._addWhere = false;
|
|
83
|
-
return [4 /*yield*/, repo.translateWhereToFilter(condition)];
|
|
84
|
+
return [4 /*yield*/, (0, repository_internals_1.getRepositoryInternals)(repo).translateWhereToFilter(condition)];
|
|
84
85
|
case 2: return [4 /*yield*/, (_b.sent()).__applyToConsumer(b)];
|
|
85
86
|
case 3:
|
|
86
87
|
_b.sent();
|
|
@@ -14,7 +14,7 @@ var JsonEntityFileStorage = /** @class */ (function () {
|
|
|
14
14
|
if (fs.existsSync(fn)) {
|
|
15
15
|
return fs.readFileSync(fn).toString();
|
|
16
16
|
}
|
|
17
|
-
return
|
|
17
|
+
return null;
|
|
18
18
|
};
|
|
19
19
|
JsonEntityFileStorage.prototype.setItem = function (entityDbName, json) {
|
|
20
20
|
if (!fs.existsSync(this.folderPath)) {
|
package/server/expressBridge.js
CHANGED
|
@@ -255,7 +255,7 @@ var RemultServerImplementation = /** @class */ (function () {
|
|
|
255
255
|
});
|
|
256
256
|
};
|
|
257
257
|
RemultServerImplementation.prototype.getEntities = function () {
|
|
258
|
-
//TODO - consider using entitiesMetaData - but it may require making it all awaitable
|
|
258
|
+
//TODO V2 - consider using entitiesMetaData - but it may require making it all awaitable
|
|
259
259
|
var r = new context_1.Remult();
|
|
260
260
|
return this.options.entities.map(function (x) { return r.repo(x).metadata; });
|
|
261
261
|
};
|
package/src/CompoundIdField.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ export declare class CompoundIdField implements FieldMetadata<string> {
|
|
|
6
6
|
constructor(...columns: FieldMetadata[]);
|
|
7
7
|
apiUpdateAllowed(item: any): boolean;
|
|
8
8
|
displayValue(item: any): string;
|
|
9
|
-
includedInApi: boolean;
|
|
9
|
+
includedInApi(item: any): boolean;
|
|
10
10
|
toInput(value: string, inputType?: string): string;
|
|
11
11
|
fromInput(inputValue: string, inputType?: string): string;
|
|
12
12
|
getDbName(): Promise<string>;
|
package/src/CompoundIdField.js
CHANGED
|
@@ -15,6 +15,9 @@ var CompoundIdField = /** @class */ (function () {
|
|
|
15
15
|
CompoundIdField.prototype.displayValue = function (item) {
|
|
16
16
|
throw new Error('Method not implemented.');
|
|
17
17
|
};
|
|
18
|
+
CompoundIdField.prototype.includedInApi = function (item) {
|
|
19
|
+
throw new Error('Method not implemented.');
|
|
20
|
+
};
|
|
18
21
|
CompoundIdField.prototype.toInput = function (value, inputType) {
|
|
19
22
|
throw new Error('Method not implemented.');
|
|
20
23
|
};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { RestDataProviderHttpProvider } from './data-interfaces';
|
|
2
|
-
|
|
3
|
-
export declare function buildRestDataProvider(provider: ExternalHttpProvider | typeof fetch): RestDataProviderHttpProviderUsingFetch | RestDataProviderHttpProvider;
|
|
2
|
+
export declare function buildRestDataProvider(provider: ExternalHttpProvider | typeof fetch): RestDataProviderHttpProvider;
|
|
4
3
|
export declare function isExternalHttpProvider(item: any): boolean;
|
|
5
4
|
export declare class HttpProviderBridgeToRestDataProviderHttpProvider implements RestDataProviderHttpProvider {
|
|
6
5
|
private http;
|