remult 0.17.2 → 0.18.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 +23 -0
- package/SseSubscriptionServer.js +143 -0
- package/ably.d.ts +13 -0
- package/ably.js +59 -0
- package/esm/SseSubscriptionServer.d.ts +23 -0
- package/esm/SseSubscriptionServer.js +102 -0
- package/esm/ably.d.ts +13 -0
- package/esm/ably.js +28 -0
- package/esm/graphql.js +0 -1
- package/esm/index.d.ts +7 -4
- package/esm/index.js +4 -2
- package/esm/live-query/data-provider-live-query-storage.d.ts +23 -0
- package/esm/live-query/data-provider-live-query-storage.js +78 -0
- package/esm/myLog.d.ts +1 -0
- package/esm/myLog.js +5 -0
- package/esm/postgres/postgres-data-provider.d.ts +4 -2
- package/esm/postgres/postgres-data-provider.js +18 -6
- package/esm/postgres/schema-builder.d.ts +2 -1
- package/esm/postgres/schema-builder.js +49 -29
- package/esm/remult-knex/index.d.ts +10 -32
- package/esm/remult-knex/index.js +75 -51
- package/esm/remult-mongo.d.ts +9 -2
- package/esm/remult-mongo.js +24 -8
- package/esm/remult-next.d.ts +11 -0
- package/esm/remult-next.js +27 -0
- package/esm/server/core.d.ts +2 -0
- package/esm/server/core.js +2 -0
- package/esm/server/expressBridge.d.ts +19 -7
- package/esm/server/expressBridge.js +135 -31
- package/esm/server/index.d.ts +2 -1
- package/esm/server/index.js +2 -1
- package/esm/server/initDataProvider.d.ts +2 -0
- package/esm/server/initDataProvider.js +14 -0
- package/esm/src/buildRestDataProvider.d.ts +31 -0
- package/esm/src/buildRestDataProvider.js +110 -0
- package/esm/src/column-interfaces.d.ts +44 -8
- package/esm/src/column.d.ts +3 -3
- package/esm/src/context.d.ts +39 -36
- package/esm/src/context.js +87 -117
- package/esm/src/data-api.d.ts +9 -3
- package/esm/src/data-api.js +130 -63
- package/esm/src/data-interfaces.d.ts +5 -1
- package/esm/src/data-providers/array-entity-data-provider.d.ts +1 -1
- package/esm/src/data-providers/array-entity-data-provider.js +2 -17
- package/esm/src/data-providers/rest-data-provider.d.ts +4 -3
- package/esm/src/data-providers/rest-data-provider.js +64 -23
- package/esm/src/data-providers/sql-database.d.ts +7 -3
- package/esm/src/data-providers/sql-database.js +60 -17
- package/esm/src/data-providers/web-sql-data-provider.d.ts +3 -0
- package/esm/src/data-providers/web-sql-data-provider.js +23 -9
- package/esm/src/entity.d.ts +2 -2
- package/esm/src/filter/filter-consumer-bridge-to-sql-request.d.ts +16 -16
- package/esm/src/filter/filter-consumer-bridge-to-sql-request.js +29 -21
- package/esm/src/filter/filter-interfaces.d.ts +5 -5
- package/esm/src/filter/filter-interfaces.js +31 -26
- package/esm/src/live-query/LiveQueryClient.d.ts +1 -0
- package/esm/src/live-query/LiveQueryClient.js +184 -0
- package/esm/src/live-query/SseSubscriptionClient.d.ts +5 -0
- package/esm/src/live-query/SseSubscriptionClient.js +86 -0
- package/esm/src/live-query/SubscriptionChannel.d.ts +41 -0
- package/esm/src/live-query/SubscriptionChannel.js +121 -0
- package/esm/src/live-query/SubscriptionServer.d.ts +38 -0
- package/esm/src/live-query/SubscriptionServer.js +108 -0
- package/esm/src/remult-proxy.d.ts +1 -1
- package/esm/src/remult-proxy.js +52 -7
- package/esm/src/remult3/RepositoryImplementation.d.ts +14 -5
- package/esm/src/remult3/RepositoryImplementation.js +124 -44
- package/esm/src/remult3/getId.d.ts +2 -0
- package/esm/src/remult3/getId.js +7 -0
- package/esm/src/remult3/remult3.d.ts +67 -10
- package/esm/src/remult3/remult3.js +1 -0
- package/esm/src/server-action.d.ts +5 -1
- package/esm/src/server-action.js +11 -12
- package/esm/src/shared-tests/db-tests-setup.d.ts +12 -5
- package/esm/src/shared-tests/db-tests-setup.js +14 -6
- package/esm/src/shared-tests/db-tests.db-tests.js +71 -10
- package/esm/src/sort.d.ts +1 -0
- package/esm/src/sort.js +18 -0
- package/esm/src/sql-command.d.ts +5 -2
- package/esm/src/tests/entityForCustomFilter.d.ts +6 -6
- package/esm/src/tests/entityForCustomFilter.js +20 -21
- package/esm/src/tests/frontend-database-tests-setup.spec.js +3 -4
- package/esm/src/tests/testHelper.spec.d.ts +3 -1
- package/esm/src/tests/testHelper.spec.js +63 -60
- package/esm/src/valueConverters.js +15 -7
- package/graphql.js +0 -1
- package/index.d.ts +7 -4
- package/index.js +7 -3
- package/live-query/data-provider-live-query-storage.d.ts +23 -0
- package/live-query/data-provider-live-query-storage.js +236 -0
- package/myLog.d.ts +1 -0
- package/myLog.js +20 -0
- package/package.json +18 -1
- package/postgres/postgres-data-provider.d.ts +4 -2
- package/postgres/postgres-data-provider.js +54 -39
- package/postgres/schema-builder.d.ts +2 -1
- package/postgres/schema-builder.js +118 -70
- package/remult-express.js +1 -1
- package/remult-knex/index.d.ts +10 -32
- package/remult-knex/index.js +134 -87
- package/remult-mongo.d.ts +9 -2
- package/remult-mongo.js +39 -7
- package/remult-next.d.ts +11 -0
- package/remult-next.js +73 -0
- package/server/JsonEntityFileStorage.js +2 -2
- package/server/core.d.ts +2 -0
- package/server/core.js +5 -1
- package/server/expressBridge.d.ts +19 -7
- package/server/expressBridge.js +283 -69
- package/server/index.d.ts +2 -1
- package/server/index.js +3 -1
- package/server/initDataProvider.d.ts +2 -0
- package/server/initDataProvider.js +26 -0
- package/src/buildRestDataProvider.d.ts +31 -0
- package/src/buildRestDataProvider.js +162 -0
- package/src/column-interfaces.d.ts +44 -8
- package/src/column.d.ts +3 -3
- package/src/context.d.ts +39 -36
- package/src/context.js +171 -166
- package/src/data-api.d.ts +9 -3
- package/src/data-api.js +233 -88
- package/src/data-interfaces.d.ts +5 -1
- package/src/data-providers/array-entity-data-provider.d.ts +1 -1
- package/src/data-providers/array-entity-data-provider.js +2 -17
- package/src/data-providers/rest-data-provider.d.ts +4 -3
- package/src/data-providers/rest-data-provider.js +105 -39
- package/src/data-providers/sql-database.d.ts +7 -3
- package/src/data-providers/sql-database.js +89 -16
- package/src/data-providers/web-sql-data-provider.d.ts +3 -0
- package/src/data-providers/web-sql-data-provider.js +56 -11
- package/src/entity.d.ts +2 -2
- package/src/filter/filter-consumer-bridge-to-sql-request.d.ts +16 -16
- package/src/filter/filter-consumer-bridge-to-sql-request.js +59 -50
- package/src/filter/filter-interfaces.d.ts +5 -5
- package/src/filter/filter-interfaces.js +31 -26
- package/src/live-query/LiveQueryClient.d.ts +1 -0
- package/src/live-query/LiveQueryClient.js +283 -0
- package/src/live-query/SseSubscriptionClient.d.ts +5 -0
- package/src/live-query/SseSubscriptionClient.js +150 -0
- package/src/live-query/SubscriptionChannel.d.ts +41 -0
- package/src/live-query/SubscriptionChannel.js +209 -0
- package/src/live-query/SubscriptionServer.d.ts +38 -0
- package/src/live-query/SubscriptionServer.js +258 -0
- package/src/remult-proxy.d.ts +1 -1
- package/src/remult-proxy.js +153 -8
- package/src/remult3/RepositoryImplementation.d.ts +14 -5
- package/src/remult3/RepositoryImplementation.js +200 -85
- package/src/remult3/getId.d.ts +2 -0
- package/src/remult3/getId.js +11 -0
- package/src/remult3/remult3.d.ts +67 -10
- package/src/remult3/remult3.js +1 -0
- package/src/server-action.d.ts +5 -1
- package/src/server-action.js +11 -11
- package/src/shared-tests/db-tests-setup.d.ts +12 -5
- package/src/shared-tests/db-tests-setup.js +17 -8
- package/src/shared-tests/db-tests.db-tests.js +140 -8
- package/src/sort.d.ts +1 -0
- package/src/sort.js +18 -0
- package/src/sql-command.d.ts +5 -2
- package/src/tests/entityForCustomFilter.d.ts +6 -6
- package/src/tests/entityForCustomFilter.js +30 -31
- package/src/tests/frontend-database-tests-setup.spec.js +5 -6
- package/src/tests/testHelper.spec.d.ts +3 -1
- package/src/tests/testHelper.spec.js +104 -100
- package/src/valueConverters.js +15 -7
|
@@ -2,7 +2,10 @@ import { ClassType } from '../classType';
|
|
|
2
2
|
import { Allowed, AllowedForInstance } from './context';
|
|
3
3
|
import { EntityMetadata, FieldRef } from './remult3';
|
|
4
4
|
export interface FieldOptions<entityType = any, valueType = any> {
|
|
5
|
-
/**A human readable name for the field
|
|
5
|
+
/** A human readable name for the field. Can be used to achieve a consistent caption for a field throughout the app
|
|
6
|
+
* @example
|
|
7
|
+
* <input placeholder={taskRepo.metadata.fields.title.caption}/>
|
|
8
|
+
*/
|
|
6
9
|
caption?: string;
|
|
7
10
|
/** If it can store null in the database */
|
|
8
11
|
allowNull?: boolean;
|
|
@@ -32,14 +35,23 @@ export interface FieldOptions<entityType = any, valueType = any> {
|
|
|
32
35
|
* }
|
|
33
36
|
* })
|
|
34
37
|
*/
|
|
35
|
-
validate?: ((entity: entityType,
|
|
38
|
+
validate?: ((entity: entityType, fieldRef: FieldRef<entityType, valueType>) => (any | Promise<any>)) | ((entity: entityType, fieldRef: FieldRef<entityType, valueType>) => (any | Promise<any>))[];
|
|
36
39
|
/** Will be fired before this field is saved to the server/database */
|
|
37
|
-
saving?: ((entity: entityType,
|
|
40
|
+
saving?: ((entity: entityType, fieldRef: FieldRef<entityType, valueType>) => (any | Promise<any>));
|
|
38
41
|
/** An expression that will determine this fields value on the backend and be provided to the front end*/
|
|
39
42
|
serverExpression?: (entity: entityType) => valueType | Promise<valueType>;
|
|
40
43
|
/** The name of the column in the database that holds the data for this field. If no name is set, the key will be used instead. */
|
|
41
44
|
dbName?: string;
|
|
42
|
-
/** Used or fields that are based on an sql expressions, instead of a physical table column
|
|
45
|
+
/** Used or fields that are based on an sql expressions, instead of a physical table column
|
|
46
|
+
* @example
|
|
47
|
+
*
|
|
48
|
+
* @Fields.integer({
|
|
49
|
+
* sqlExpression:e=> 'length(title)'
|
|
50
|
+
* })
|
|
51
|
+
* titleLength = 0;
|
|
52
|
+
* @Fields.string()
|
|
53
|
+
* title='';
|
|
54
|
+
*/
|
|
43
55
|
sqlExpression?: string | ((entity: EntityMetadata<entityType>) => string | Promise<string>);
|
|
44
56
|
/** For fields that shouldn't be part of an update or insert statement */
|
|
45
57
|
dbReadOnly?: boolean;
|
|
@@ -62,18 +74,42 @@ export interface FieldOptions<entityType = any, valueType = any> {
|
|
|
62
74
|
/** The key to be used for this field */
|
|
63
75
|
key?: string;
|
|
64
76
|
}
|
|
77
|
+
/**Metadata for a `Field`, this metadata can be used in the user interface to provide a richer UI experience */
|
|
65
78
|
export interface FieldMetadata<valueType = any> {
|
|
79
|
+
/** The field's member name in an object.
|
|
80
|
+
* @example
|
|
81
|
+
* const taskRepo = remult.repo(Task);
|
|
82
|
+
* console.log(taskRepo.metadata.fields.title.key);
|
|
83
|
+
* // result: title
|
|
84
|
+
*/
|
|
66
85
|
readonly key: string;
|
|
67
|
-
|
|
68
|
-
|
|
86
|
+
/** A human readable caption for the field. Can be used to achieve a consistent caption for a field throughout the app
|
|
87
|
+
* @example
|
|
88
|
+
* <input placeholder={taskRepo.metadata.fields.title.caption}/>
|
|
89
|
+
*/
|
|
69
90
|
readonly caption: string;
|
|
91
|
+
/** The field's value type (number,string etc...) */
|
|
92
|
+
readonly valueType: any;
|
|
93
|
+
/** The options sent to this field's decorator */
|
|
94
|
+
readonly options: FieldOptions;
|
|
95
|
+
/** The `inputType` relevant for this field, determined by the options sent to it's decorator and the valueConverter in these options */
|
|
70
96
|
readonly inputType: string;
|
|
97
|
+
/** if null is allowed for this field */
|
|
71
98
|
readonly allowNull: boolean;
|
|
99
|
+
/** The class that contains this field
|
|
100
|
+
* @example
|
|
101
|
+
* const taskRepo = remult.repo(Task);
|
|
102
|
+
* Task == taskRepo.metadata.fields.title.target //will return true
|
|
103
|
+
*/
|
|
104
|
+
readonly target: ClassType<valueType>;
|
|
105
|
+
/** Returns the dbName - based on it's `dbName` option and it's `sqlExpression` option */
|
|
72
106
|
getDbName(): Promise<string>;
|
|
107
|
+
/** Indicates if this field is based on a server express */
|
|
73
108
|
readonly isServerExpression: boolean;
|
|
109
|
+
/** indicates that this field should only be included in select statement, and excluded from update or insert. useful for db generated ids etc... */
|
|
74
110
|
readonly dbReadOnly: boolean;
|
|
111
|
+
/** the Value converter for this field */
|
|
75
112
|
readonly valueConverter: ValueConverter<valueType>;
|
|
76
|
-
readonly options: FieldOptions;
|
|
77
113
|
}
|
|
78
114
|
export interface ValueConverter<valueType> {
|
|
79
115
|
fromJson?(val: any): valueType;
|
|
@@ -86,7 +122,7 @@ export interface ValueConverter<valueType> {
|
|
|
86
122
|
readonly fieldTypeInDb?: string;
|
|
87
123
|
readonly inputType?: string;
|
|
88
124
|
}
|
|
89
|
-
export declare type FieldValidator<entityType = any, valueType = any> = (entity: entityType,
|
|
125
|
+
export declare type FieldValidator<entityType = any, valueType = any> = (entity: entityType, fieldRef: FieldRef<entityType, valueType>) => void | Promise<void>;
|
|
90
126
|
export declare type ValueOrExpression<valueType> = valueType | (() => valueType);
|
|
91
127
|
export declare function valueOrExpressionToValue<valueType>(f: ValueOrExpression<valueType>): valueType;
|
|
92
128
|
export interface ValueListItem {
|
package/esm/src/column.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ClassType } from '../classType';
|
|
2
2
|
import { FieldMetadata, FieldOptions, ValueConverter } from './column-interfaces';
|
|
3
3
|
import { Filter } from './filter/filter-interfaces';
|
|
4
|
-
import { EntityFilter, FindOptions, Repository, RepositoryImplementation } from './remult3';
|
|
4
|
+
import { EntityFilter, FindOptions, idType, Repository, RepositoryImplementation } from './remult3';
|
|
5
5
|
export declare function makeTitle(name: string): string;
|
|
6
6
|
export declare class CompoundIdField implements FieldMetadata<string> {
|
|
7
7
|
fields: FieldMetadata[];
|
|
@@ -25,12 +25,12 @@ export declare class CompoundIdField implements FieldMetadata<string> {
|
|
|
25
25
|
}
|
|
26
26
|
export declare class LookupColumn<T> {
|
|
27
27
|
private repository;
|
|
28
|
-
id:
|
|
28
|
+
id: idType<T>;
|
|
29
29
|
setId(val: any): void;
|
|
30
30
|
waitLoadOf(id: any): Promise<T>;
|
|
31
31
|
get(id: any): any;
|
|
32
32
|
set(item: T): void;
|
|
33
|
-
constructor(repository: RepositoryImplementation<T>, id:
|
|
33
|
+
constructor(repository: RepositoryImplementation<T>, id: idType<T>);
|
|
34
34
|
get item(): T;
|
|
35
35
|
waitLoad(): Promise<T>;
|
|
36
36
|
}
|
package/esm/src/context.d.ts
CHANGED
|
@@ -1,43 +1,20 @@
|
|
|
1
|
-
import { DataProvider
|
|
2
|
-
import { RestDataProviderHttpProviderUsingFetch } from './data-providers/rest-data-provider';
|
|
1
|
+
import { DataProvider } from "./data-interfaces";
|
|
3
2
|
import { EntityMetadata, EntityRef, FindOptions, Repository } from "./remult3";
|
|
4
3
|
import { ClassType } from "../classType";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
};
|
|
9
|
-
delete(url: string): Promise<void> | {
|
|
10
|
-
toPromise(): Promise<void>;
|
|
11
|
-
};
|
|
12
|
-
put(url: string, data: any): Promise<any> | {
|
|
13
|
-
toPromise(): Promise<any>;
|
|
14
|
-
};
|
|
15
|
-
get(url: string): Promise<any> | {
|
|
16
|
-
toPromise(): Promise<any>;
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
export declare class HttpProviderBridgeToRestDataProviderHttpProvider implements RestDataProviderHttpProvider {
|
|
20
|
-
private http;
|
|
21
|
-
constructor(http: ExternalHttpProvider);
|
|
22
|
-
post(url: string, data: any): Promise<any>;
|
|
23
|
-
delete(url: string): Promise<void>;
|
|
24
|
-
put(url: string, data: any): Promise<any>;
|
|
25
|
-
get(url: string): Promise<any>;
|
|
26
|
-
}
|
|
27
|
-
export declare function retry<T>(what: () => Promise<T>): Promise<T>;
|
|
28
|
-
export declare function toPromise<T>(p: Promise<T> | {
|
|
29
|
-
toPromise(): Promise<T>;
|
|
30
|
-
}): Promise<any>;
|
|
31
|
-
export declare function processHttpException(ex: any): Promise<any>;
|
|
4
|
+
import type { SubscriptionServer } from "./live-query/SubscriptionServer";
|
|
5
|
+
import { ExternalHttpProvider } from "./buildRestDataProvider";
|
|
6
|
+
import { SubscriptionClient } from "./live-query/SubscriptionChannel";
|
|
32
7
|
export declare function isBackend(): boolean;
|
|
33
8
|
export declare class Remult {
|
|
34
9
|
/**Return's a `Repository` of the specific entity type
|
|
35
10
|
* @example
|
|
36
11
|
* const taskRepo = remult.repo(Task);
|
|
37
12
|
* @see [Repository](https://remult.dev/docs/ref_repository.html)
|
|
38
|
-
*
|
|
13
|
+
* @param entity - the entity to use
|
|
14
|
+
* @param dataProvider - an optional alternative data provider to use. Useful for writing to offline storage or an alternative data provider
|
|
39
15
|
*/
|
|
40
16
|
repo<T>(entity: ClassType<T>, dataProvider?: DataProvider): Repository<T>;
|
|
17
|
+
/** Returns the current user's info */
|
|
41
18
|
user?: UserInfo;
|
|
42
19
|
/** Checks if a user was authenticated */
|
|
43
20
|
authenticated(): boolean;
|
|
@@ -53,6 +30,8 @@ export declare class Remult {
|
|
|
53
30
|
* [Allowed](https://remult.dev/docs/allowed.html)
|
|
54
31
|
*/
|
|
55
32
|
isAllowedForInstance(instance: any, allowed?: AllowedForInstance<any>): boolean;
|
|
33
|
+
/** The current data provider */
|
|
34
|
+
dataProvider: DataProvider;
|
|
56
35
|
/** Creates a new instance of the `remult` object.
|
|
57
36
|
*
|
|
58
37
|
* Can receive either an HttpProvider or a DataProvider as a parameter - which will be used to fetch data from.
|
|
@@ -62,23 +41,42 @@ export declare class Remult {
|
|
|
62
41
|
constructor(http: ExternalHttpProvider | typeof fetch | ApiClient);
|
|
63
42
|
constructor(p: DataProvider);
|
|
64
43
|
constructor();
|
|
44
|
+
subscriptionServer?: SubscriptionServer;
|
|
45
|
+
/** Used to call a `backendMethod` using a specific `remult` object
|
|
46
|
+
* @example
|
|
47
|
+
* await remult.call(TasksController.setAll, undefined, true);
|
|
48
|
+
* @param backendMethod - the backend method to call
|
|
49
|
+
* @param classInstance - the class instance of the backend method, for static backend methods use undefined
|
|
50
|
+
* @param args - the arguments to send to the backend method
|
|
51
|
+
*/
|
|
65
52
|
call<T extends ((...args: any[]) => Promise<any>)>(backendMethod: T, classInstance?: any, ...args: GetArguments<T>): ReturnType<T>;
|
|
66
|
-
/** The current data provider */
|
|
67
|
-
dataProvider: DataProvider;
|
|
68
53
|
/** A helper callback that can be used to debug and trace all find operations. Useful in debugging scenarios */
|
|
69
54
|
static onFind: (metadata: EntityMetadata, options: FindOptions<any>) => void;
|
|
70
55
|
clearAllCache(): any;
|
|
71
56
|
/** A helper callback that is called whenever an entity is created. */
|
|
72
57
|
static entityRefInit?: (ref: EntityRef<any>, row: any) => void;
|
|
58
|
+
/** context information that can be used to store custom information that will be disposed as part of the `remult` object */
|
|
73
59
|
readonly context: RemultContext;
|
|
60
|
+
/** The api client that will be used by `remult` to perform calls to the `api` */
|
|
74
61
|
apiClient: ApiClient;
|
|
75
62
|
}
|
|
76
63
|
export declare type GetArguments<T> = T extends (...args: infer FirstArgument) => any ? FirstArgument : never;
|
|
77
64
|
export interface RemultContext {
|
|
78
65
|
}
|
|
79
66
|
export interface ApiClient {
|
|
67
|
+
/** The http client to use when making api calls.
|
|
68
|
+
* @example
|
|
69
|
+
* remult.apiClient.httpClient = axios;
|
|
70
|
+
* @example
|
|
71
|
+
* remult.apiClient.httpClient = httpClient;//angular http client
|
|
72
|
+
* @example
|
|
73
|
+
* remult.apiClient.httpClient = fetch; //this is the default
|
|
74
|
+
*/
|
|
80
75
|
httpClient?: ExternalHttpProvider | typeof fetch;
|
|
76
|
+
/** The base url to for making api calls */
|
|
81
77
|
url?: string;
|
|
78
|
+
subscriptionClient?: SubscriptionClient;
|
|
79
|
+
wrapMessageHandling?: (x: VoidFunction) => void;
|
|
82
80
|
}
|
|
83
81
|
export declare const allEntities: ClassType<any>[];
|
|
84
82
|
export interface ControllerOptions {
|
|
@@ -88,18 +86,17 @@ export declare const classHelpers: Map<any, ClassHelper>;
|
|
|
88
86
|
export declare class ClassHelper {
|
|
89
87
|
classes: Map<any, ControllerOptions>;
|
|
90
88
|
}
|
|
91
|
-
export declare function buildRestDataProvider(provider: ExternalHttpProvider | typeof fetch): RestDataProviderHttpProvider | RestDataProviderHttpProviderUsingFetch;
|
|
92
89
|
export declare function setControllerSettings(target: any, options: ControllerOptions): void;
|
|
93
90
|
export interface UserInfo {
|
|
94
91
|
id: string;
|
|
95
92
|
name?: string;
|
|
96
93
|
roles?: string[];
|
|
97
94
|
}
|
|
98
|
-
export declare type Allowed = boolean | string | string[] | ((c
|
|
99
|
-
export declare type AllowedForInstance<T> = boolean | string | string[] | ((
|
|
95
|
+
export declare type Allowed = boolean | string | string[] | ((c?: Remult) => boolean);
|
|
96
|
+
export declare type AllowedForInstance<T> = boolean | string | string[] | ((entity?: T, c?: Remult) => boolean);
|
|
100
97
|
export declare class Allow {
|
|
101
98
|
static everyone: () => boolean;
|
|
102
|
-
static authenticated: (
|
|
99
|
+
static authenticated: (...args: any[]) => any;
|
|
103
100
|
}
|
|
104
101
|
export declare const queryConfig: {
|
|
105
102
|
defaultPageSize: number;
|
|
@@ -113,3 +110,9 @@ export declare class EventSource {
|
|
|
113
110
|
fire(): Promise<void>;
|
|
114
111
|
dispatcher: EventDispatcher;
|
|
115
112
|
}
|
|
113
|
+
export interface itemChange {
|
|
114
|
+
id: any;
|
|
115
|
+
oldId: any;
|
|
116
|
+
deleted: boolean;
|
|
117
|
+
}
|
|
118
|
+
export declare function doTransaction(remult: Remult, what: () => Promise<void>): Promise<void>;
|
package/esm/src/context.js
CHANGED
|
@@ -1,105 +1,31 @@
|
|
|
1
1
|
import { actionInfo, serverActionField } from './server-action';
|
|
2
|
-
import { RestDataProvider
|
|
2
|
+
import { RestDataProvider } from './data-providers/rest-data-provider';
|
|
3
3
|
import { RepositoryImplementation } from "./remult3/RepositoryImplementation";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
async post(url, data) {
|
|
9
|
-
return await retry(() => toPromise(this.http.post(url, data)));
|
|
10
|
-
}
|
|
11
|
-
delete(url) {
|
|
12
|
-
return toPromise(this.http.delete(url));
|
|
13
|
-
}
|
|
14
|
-
put(url, data) {
|
|
15
|
-
return toPromise(this.http.put(url, data));
|
|
16
|
-
}
|
|
17
|
-
async get(url) {
|
|
18
|
-
return await retry(() => toPromise(this.http.get(url)));
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
export async function retry(what) {
|
|
22
|
-
while (true) {
|
|
23
|
-
try {
|
|
24
|
-
return await what();
|
|
25
|
-
}
|
|
26
|
-
catch (err) {
|
|
27
|
-
if (err.message?.startsWith("Error occurred while trying to proxy") ||
|
|
28
|
-
err.message?.startsWith("Error occured while trying to proxy") ||
|
|
29
|
-
err.message?.includes("http proxy error") ||
|
|
30
|
-
err.message?.startsWith("Gateway Timeout")) {
|
|
31
|
-
await new Promise((res, req) => {
|
|
32
|
-
setTimeout(() => {
|
|
33
|
-
res({});
|
|
34
|
-
}, 250);
|
|
35
|
-
});
|
|
36
|
-
continue;
|
|
37
|
-
}
|
|
38
|
-
throw err;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
export function toPromise(p) {
|
|
43
|
-
let r;
|
|
44
|
-
if (p["toPromise"] !== undefined) {
|
|
45
|
-
r = p["toPromise"]();
|
|
46
|
-
}
|
|
47
|
-
//@ts-ignore
|
|
48
|
-
else
|
|
49
|
-
r = p;
|
|
50
|
-
return r.then((x) => {
|
|
51
|
-
if (x && (x.status == 200 || x.status == 201) && x.headers && x.request && x.data) //for axios
|
|
52
|
-
return x.data;
|
|
53
|
-
return x;
|
|
54
|
-
}).catch(async (ex) => {
|
|
55
|
-
throw await processHttpException(ex);
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
export async function processHttpException(ex) {
|
|
59
|
-
let z = await ex;
|
|
60
|
-
var error;
|
|
61
|
-
if (z.error)
|
|
62
|
-
error = z.error;
|
|
63
|
-
else if (z.isAxiosError) {
|
|
64
|
-
if (typeof z.response?.data === "string")
|
|
65
|
-
error = z.response.data;
|
|
66
|
-
else
|
|
67
|
-
error = z?.response?.data;
|
|
68
|
-
}
|
|
69
|
-
if (!error)
|
|
70
|
-
error = z.message;
|
|
71
|
-
if (z.status == 0 && z.error.isTrusted)
|
|
72
|
-
error = "Network Error";
|
|
73
|
-
if (typeof error === 'string') {
|
|
74
|
-
error = {
|
|
75
|
-
message: error,
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
if (z.modelState)
|
|
79
|
-
error.modelState = z.modelState;
|
|
80
|
-
let httpStatusCode = z.status;
|
|
81
|
-
if (httpStatusCode === undefined)
|
|
82
|
-
httpStatusCode = z.response?.status;
|
|
83
|
-
if (httpStatusCode !== undefined && httpStatusCode !== null) {
|
|
84
|
-
error.httpStatusCode = httpStatusCode;
|
|
85
|
-
}
|
|
86
|
-
var result = Object.assign(error, {
|
|
87
|
-
// exception: ex disabled for now because JSON.stringify crashed with this
|
|
88
|
-
});
|
|
89
|
-
return result;
|
|
90
|
-
}
|
|
4
|
+
import { LiveQueryClient } from "./live-query/LiveQueryClient";
|
|
5
|
+
import { SseSubscriptionClient } from "./live-query/SseSubscriptionClient";
|
|
6
|
+
import { RemultProxy } from "./remult-proxy";
|
|
7
|
+
import { buildRestDataProvider, isExternalHttpProvider } from "./buildRestDataProvider";
|
|
91
8
|
export function isBackend() {
|
|
92
9
|
return actionInfo.runningOnServer;
|
|
93
10
|
}
|
|
94
11
|
export class Remult {
|
|
95
12
|
constructor(provider) {
|
|
96
|
-
/* @internal */
|
|
97
|
-
this.repCache = new Map();
|
|
98
13
|
/** The current data provider */
|
|
99
14
|
this.dataProvider = new RestDataProvider(() => this.apiClient);
|
|
15
|
+
/* @internal */
|
|
16
|
+
this.repCache = new Map();
|
|
17
|
+
/* @internal*/
|
|
18
|
+
this.liveQueryPublisher = {
|
|
19
|
+
itemChanged: async () => { }
|
|
20
|
+
};
|
|
21
|
+
/* @internal*/
|
|
22
|
+
this.liveQuerySubscriber = new LiveQueryClient(() => this.apiClient, () => this.user?.id);
|
|
23
|
+
/** context information that can be used to store custom information that will be disposed as part of the `remult` object */
|
|
100
24
|
this.context = {};
|
|
25
|
+
/** The api client that will be used by `remult` to perform calls to the `api` */
|
|
101
26
|
this.apiClient = {
|
|
102
|
-
url: '/api'
|
|
27
|
+
url: '/api',
|
|
28
|
+
subscriptionClient: new SseSubscriptionClient()
|
|
103
29
|
};
|
|
104
30
|
if (provider && provider.getEntityDataProvider) {
|
|
105
31
|
this.dataProvider = provider;
|
|
@@ -116,13 +42,18 @@ export class Remult {
|
|
|
116
42
|
this.apiClient.httpClient = apiClient.httpClient;
|
|
117
43
|
if (apiClient.url)
|
|
118
44
|
this.apiClient.url = apiClient.url;
|
|
45
|
+
if (apiClient.subscriptionClient)
|
|
46
|
+
this.apiClient.subscriptionClient = apiClient.subscriptionClient;
|
|
47
|
+
if (apiClient.wrapMessageHandling)
|
|
48
|
+
this.apiClient.wrapMessageHandling = apiClient.wrapMessageHandling;
|
|
119
49
|
}
|
|
120
50
|
}
|
|
121
51
|
/**Return's a `Repository` of the specific entity type
|
|
122
52
|
* @example
|
|
123
53
|
* const taskRepo = remult.repo(Task);
|
|
124
54
|
* @see [Repository](https://remult.dev/docs/ref_repository.html)
|
|
125
|
-
*
|
|
55
|
+
* @param entity - the entity to use
|
|
56
|
+
* @param dataProvider - an optional alternative data provider to use. Useful for writing to offline storage or an alternative data provider
|
|
126
57
|
*/
|
|
127
58
|
repo(entity, dataProvider) {
|
|
128
59
|
if (dataProvider === undefined)
|
|
@@ -136,7 +67,6 @@ export class Remult {
|
|
|
136
67
|
}
|
|
137
68
|
return r;
|
|
138
69
|
}
|
|
139
|
-
/* delete me */
|
|
140
70
|
/** Checks if a user was authenticated */
|
|
141
71
|
authenticated() {
|
|
142
72
|
return this.user?.id !== undefined;
|
|
@@ -182,11 +112,19 @@ export class Remult {
|
|
|
182
112
|
}
|
|
183
113
|
}
|
|
184
114
|
else if (typeof (allowed) === "function") {
|
|
185
|
-
return allowed(
|
|
115
|
+
return allowed(instance, this);
|
|
186
116
|
}
|
|
187
117
|
else
|
|
188
118
|
return this.isAllowed(allowed);
|
|
189
119
|
}
|
|
120
|
+
//@ts-ignore // type error of typescript regarding args that doesn't appear in my normal development
|
|
121
|
+
/** Used to call a `backendMethod` using a specific `remult` object
|
|
122
|
+
* @example
|
|
123
|
+
* await remult.call(TasksController.setAll, undefined, true);
|
|
124
|
+
* @param backendMethod - the backend method to call
|
|
125
|
+
* @param classInstance - the class instance of the backend method, for static backend methods use undefined
|
|
126
|
+
* @param args - the arguments to send to the backend method
|
|
127
|
+
*/
|
|
190
128
|
call(backendMethod, classInstance, ...args) {
|
|
191
129
|
const z = (backendMethod[serverActionField]);
|
|
192
130
|
if (!z.doWork)
|
|
@@ -200,6 +138,7 @@ export class Remult {
|
|
|
200
138
|
}
|
|
201
139
|
/** A helper callback that can be used to debug and trace all find operations. Useful in debugging scenarios */
|
|
202
140
|
Remult.onFind = (metadata, options) => { };
|
|
141
|
+
RemultProxy.defaultRemult = new Remult();
|
|
203
142
|
;
|
|
204
143
|
export const allEntities = [];
|
|
205
144
|
export const classHelpers = new Map();
|
|
@@ -208,28 +147,6 @@ export class ClassHelper {
|
|
|
208
147
|
this.classes = new Map();
|
|
209
148
|
}
|
|
210
149
|
}
|
|
211
|
-
function isExternalHttpProvider(item) {
|
|
212
|
-
let http = item;
|
|
213
|
-
if (http && http.get && http.put && http.post && http.delete)
|
|
214
|
-
return true;
|
|
215
|
-
return false;
|
|
216
|
-
}
|
|
217
|
-
export function buildRestDataProvider(provider) {
|
|
218
|
-
if (!provider)
|
|
219
|
-
return new RestDataProviderHttpProviderUsingFetch();
|
|
220
|
-
let httpDataProvider;
|
|
221
|
-
if (!httpDataProvider) {
|
|
222
|
-
if (isExternalHttpProvider(provider)) {
|
|
223
|
-
httpDataProvider = new HttpProviderBridgeToRestDataProviderHttpProvider(provider);
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
if (!httpDataProvider) {
|
|
227
|
-
if (typeof provider === "function") {
|
|
228
|
-
httpDataProvider = new RestDataProviderHttpProviderUsingFetch(provider);
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
return httpDataProvider;
|
|
232
|
-
}
|
|
233
150
|
export function setControllerSettings(target, options) {
|
|
234
151
|
let r = target;
|
|
235
152
|
while (true) {
|
|
@@ -246,7 +163,16 @@ export function setControllerSettings(target, options) {
|
|
|
246
163
|
export class Allow {
|
|
247
164
|
}
|
|
248
165
|
Allow.everyone = () => true;
|
|
249
|
-
Allow.authenticated = (
|
|
166
|
+
Allow.authenticated = (...args) => {
|
|
167
|
+
if (args.length > 1) {
|
|
168
|
+
return args[1].authenticated();
|
|
169
|
+
}
|
|
170
|
+
else if (args.length == 1) {
|
|
171
|
+
if (args[0].authenticated)
|
|
172
|
+
return args[0].authenticated();
|
|
173
|
+
}
|
|
174
|
+
return RemultProxy.defaultRemult.authenticated();
|
|
175
|
+
};
|
|
250
176
|
export const queryConfig = {
|
|
251
177
|
defaultPageSize: 200
|
|
252
178
|
};
|
|
@@ -269,3 +195,47 @@ export class EventSource {
|
|
|
269
195
|
}
|
|
270
196
|
}
|
|
271
197
|
}
|
|
198
|
+
export async function doTransaction(remult, what) {
|
|
199
|
+
const trans = new transactionLiveQueryPublisher(remult.liveQueryPublisher);
|
|
200
|
+
let ok = true;
|
|
201
|
+
const result = await remult.dataProvider.transaction(async (ds) => {
|
|
202
|
+
remult.dataProvider = (ds);
|
|
203
|
+
remult.liveQueryPublisher = trans;
|
|
204
|
+
await what();
|
|
205
|
+
ok = true;
|
|
206
|
+
});
|
|
207
|
+
if (ok)
|
|
208
|
+
await trans.flush();
|
|
209
|
+
}
|
|
210
|
+
class transactionLiveQueryPublisher {
|
|
211
|
+
constructor(orig) {
|
|
212
|
+
this.orig = orig;
|
|
213
|
+
this.transactionItems = new Map();
|
|
214
|
+
}
|
|
215
|
+
async itemChanged(entityKey, changes) {
|
|
216
|
+
let items = this.transactionItems.get(entityKey);
|
|
217
|
+
if (!items) {
|
|
218
|
+
this.transactionItems.set(entityKey, items = []);
|
|
219
|
+
}
|
|
220
|
+
for (const c of changes) {
|
|
221
|
+
if (c.oldId !== undefined) {
|
|
222
|
+
const item = items.find(y => y.id === c.oldId);
|
|
223
|
+
if (item !== undefined) {
|
|
224
|
+
if (c.deleted)
|
|
225
|
+
item.deleted = true;
|
|
226
|
+
if (c.id != item.id)
|
|
227
|
+
item.id = c.id;
|
|
228
|
+
}
|
|
229
|
+
else
|
|
230
|
+
items.push(c);
|
|
231
|
+
}
|
|
232
|
+
else
|
|
233
|
+
items.push(c);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
async flush() {
|
|
237
|
+
for (const key of this.transactionItems.keys()) {
|
|
238
|
+
await this.orig.itemChanged(key, this.transactionItems.get(key));
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
package/esm/src/data-api.d.ts
CHANGED
|
@@ -1,16 +1,21 @@
|
|
|
1
1
|
import { Remult } from './context';
|
|
2
|
-
import { Repository } from './remult3';
|
|
2
|
+
import { FindOptions, Repository } from './remult3';
|
|
3
3
|
import { ErrorInfo } from './data-interfaces';
|
|
4
4
|
export declare class DataApi<T = any> {
|
|
5
5
|
private repository;
|
|
6
6
|
private remult;
|
|
7
7
|
constructor(repository: Repository<T>, remult: Remult);
|
|
8
|
-
httpGet(res: DataApiResponse, req: DataApiRequest): Promise<void>;
|
|
9
|
-
httpPost(res: DataApiResponse, req: DataApiRequest, body: any): Promise<void>;
|
|
8
|
+
httpGet(res: DataApiResponse, req: DataApiRequest, serializeRequest: () => any): Promise<void>;
|
|
9
|
+
httpPost(res: DataApiResponse, req: DataApiRequest, body: any, serializeRequest: () => any): Promise<void>;
|
|
10
10
|
static defaultGetLimit: number;
|
|
11
11
|
get(response: DataApiResponse, id: any): Promise<void>;
|
|
12
12
|
count(response: DataApiResponse, request: DataApiRequest, filterBody?: any): Promise<void>;
|
|
13
|
+
getArrayImpl(response: DataApiResponse, request: DataApiRequest, filterBody: any): Promise<{
|
|
14
|
+
r: any[];
|
|
15
|
+
findOptions: FindOptions<T>;
|
|
16
|
+
}>;
|
|
13
17
|
getArray(response: DataApiResponse, request: DataApiRequest, filterBody?: any): Promise<void>;
|
|
18
|
+
liveQuery(response: DataApiResponse, request: DataApiRequest, filterBody: any, serializeRequest: () => any, queryChannel: string): Promise<void>;
|
|
14
19
|
private buildWhere;
|
|
15
20
|
private doOnId;
|
|
16
21
|
put(response: DataApiResponse, id: any, body: any): Promise<void>;
|
|
@@ -31,3 +36,4 @@ export interface DataApiRequest {
|
|
|
31
36
|
}
|
|
32
37
|
export declare function determineSort(sortUrlParm: string, dirUrlParam: string): any;
|
|
33
38
|
export declare function serializeError(data: ErrorInfo): ErrorInfo<any>;
|
|
39
|
+
export declare function getLiveQueryChannel(queryId: string, userId: string): string;
|