remult 0.23.0-exp.8 → 0.23.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/README.md +1 -0
- package/esm/graphql.js +19 -2
- package/esm/index.d.ts +18 -4
- package/esm/index.js +13 -1
- package/esm/internals.d.ts +1 -1
- package/esm/internals.js +1 -1
- package/esm/postgres/schema-builder.d.ts +1 -0
- package/esm/postgres/schema-builder.js +13 -1
- package/esm/remult-express.js +1 -1
- package/esm/remult-hapi.d.ts +6 -0
- package/esm/remult-hapi.js +112 -0
- package/esm/remult-knex/index.js +4 -2
- package/esm/remult-mongo.d.ts +1 -1
- package/esm/remult-mongo.js +17 -5
- package/esm/remult-sveltekit.d.ts +3 -1
- package/esm/remult-sveltekit.js +3 -0
- package/esm/server/expressBridge.d.ts +8 -0
- package/esm/server/expressBridge.js +12 -7
- package/esm/src/CompoundIdField.d.ts +1 -1
- package/esm/src/CompoundIdField.js +3 -1
- package/esm/src/column-interfaces.d.ts +21 -9
- package/esm/src/column.d.ts +3 -3
- package/esm/src/column.js +19 -5
- package/esm/src/context.js +2 -0
- package/esm/src/data-api.js +4 -1
- package/esm/src/data-interfaces.d.ts +2 -2
- package/esm/src/data-providers/array-entity-data-provider.d.ts +0 -21
- package/esm/src/data-providers/array-entity-data-provider.js +8 -0
- package/esm/src/data-providers/sql-database.js +2 -1
- package/esm/src/entity.d.ts +47 -16
- package/esm/src/entity.js +0 -1
- package/esm/src/filter/filter-consumer-bridge-to-sql-request.d.ts +2 -2
- package/esm/src/filter/filter-interfaces.js +4 -0
- package/esm/src/live-query/LiveQueryClient.js +2 -1
- package/esm/src/live-query/SubscriptionChannel.js +3 -2
- package/esm/src/remult-proxy.js +9 -6
- package/esm/src/remult3/DecoratorReplacer.d.ts +1 -2
- package/esm/src/remult3/Fields.d.ts +105 -19
- package/esm/src/remult3/Fields.js +48 -8
- package/esm/src/remult3/RepositoryImplementation.d.ts +21 -29
- package/esm/src/remult3/RepositoryImplementation.js +125 -54
- package/esm/src/remult3/entity.d.ts +1 -1
- package/esm/src/remult3/entity.js +0 -1
- package/esm/src/remult3/remult3.d.ts +195 -33
- package/esm/src/remult3/remult3.js +63 -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.js +13 -3
- package/graphql.js +19 -3
- package/index.d.ts +18 -4
- package/index.js +12 -0
- package/internals.d.ts +1 -1
- package/internals.js +3 -1
- package/package.json +9 -1
- package/postgres/schema-builder.d.ts +1 -0
- package/postgres/schema-builder.js +12 -2
- package/remult-express.js +1 -1
- package/remult-hapi.d.ts +6 -0
- package/remult-hapi.js +124 -0
- package/remult-knex/index.js +13 -7
- package/remult-mongo.d.ts +1 -1
- package/remult-mongo.js +17 -5
- package/remult-sveltekit.d.ts +3 -1
- package/remult-sveltekit.js +3 -0
- package/server/expressBridge.d.ts +8 -0
- package/server/expressBridge.js +13 -7
- package/src/CompoundIdField.d.ts +1 -1
- package/src/CompoundIdField.js +3 -0
- package/src/column-interfaces.d.ts +21 -9
- package/src/column.d.ts +3 -3
- package/src/column.js +18 -5
- package/src/context.js +2 -0
- package/src/data-api.js +4 -1
- package/src/data-interfaces.d.ts +2 -2
- package/src/data-providers/array-entity-data-provider.d.ts +0 -21
- package/src/data-providers/array-entity-data-provider.js +6 -0
- package/src/data-providers/sql-database.js +2 -1
- package/src/entity.d.ts +47 -16
- package/src/entity.js +0 -1
- package/src/filter/filter-consumer-bridge-to-sql-request.d.ts +2 -2
- package/src/filter/filter-interfaces.js +4 -0
- package/src/live-query/LiveQueryClient.js +2 -1
- package/src/live-query/SubscriptionChannel.js +3 -2
- package/src/remult-proxy.js +46 -35
- package/src/remult3/DecoratorReplacer.d.ts +1 -2
- package/src/remult3/Fields.d.ts +105 -19
- package/src/remult3/Fields.js +47 -7
- package/src/remult3/RepositoryImplementation.d.ts +21 -29
- package/src/remult3/RepositoryImplementation.js +143 -75
- package/src/remult3/entity.d.ts +1 -1
- package/src/remult3/entity.js +0 -1
- package/src/remult3/remult3.d.ts +195 -33
- package/src/remult3/remult3.js +63 -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.js +13 -3
package/README.md
CHANGED
|
@@ -277,6 +277,7 @@ with a Node.js Express backend.
|
|
|
277
277
|
- [Tutorial with Angular](https://remult.dev/tutorials/angular/)
|
|
278
278
|
- [Tutorial with Vue](https://remult.dev/tutorials/vue/)
|
|
279
279
|
- [Tutorial with Next.js](https://remult.dev/tutorials/react-next/)
|
|
280
|
+
- [Tutorial with Sveltekit](https://remult.dev/tutorials/sveltekit/)
|
|
280
281
|
|
|
281
282
|
## Documentation
|
|
282
283
|
|
package/esm/graphql.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getRelationInfo } from './internals';
|
|
1
2
|
import { Remult, remult } from './index';
|
|
2
3
|
import { DataApi } from './src/data-api';
|
|
3
4
|
const v2ConnectionAndPagination = false;
|
|
@@ -219,6 +220,14 @@ _Side note: \`Math.ceil(totalCount / limit)\` to determine how many pages there
|
|
|
219
220
|
comment: `
|
|
220
221
|
For **page by page** pagination.
|
|
221
222
|
Select a dedicated page.`,
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
key: 'offset',
|
|
226
|
+
value: 'Int',
|
|
227
|
+
comment: `
|
|
228
|
+
For **page by page** pagination.
|
|
229
|
+
Set the offset needed.
|
|
230
|
+
_Side node: if \`page\` arg is set, \`offset\` will be ignored._`,
|
|
222
231
|
},
|
|
223
232
|
{
|
|
224
233
|
key: 'orderBy',
|
|
@@ -447,6 +456,11 @@ Select a dedicated page.`,
|
|
|
447
456
|
}
|
|
448
457
|
const whereTypeFields = [];
|
|
449
458
|
for (const f of meta.fields) {
|
|
459
|
+
const ri = getRelationInfo(f.options);
|
|
460
|
+
// let's not consider toMany relations for now
|
|
461
|
+
if (ri?.type === 'toMany') {
|
|
462
|
+
break;
|
|
463
|
+
}
|
|
450
464
|
if (f.options.includeInApi === false)
|
|
451
465
|
continue;
|
|
452
466
|
let type = 'String';
|
|
@@ -751,7 +765,10 @@ function toCamelCase(str) {
|
|
|
751
765
|
.join('');
|
|
752
766
|
}
|
|
753
767
|
function bridgeQueryOptionsToDataApiGet(arg1) {
|
|
754
|
-
|
|
768
|
+
let { limit, page, orderBy, where, offset } = arg1;
|
|
769
|
+
if (!page && offset) {
|
|
770
|
+
page = Math.floor(offset / limit) + 1;
|
|
771
|
+
}
|
|
755
772
|
return (key) => {
|
|
756
773
|
if (limit && key === '_limit') {
|
|
757
774
|
return limit;
|
|
@@ -788,7 +805,7 @@ export function translateWhereToRestBody(fields, { where }) {
|
|
|
788
805
|
return undefined;
|
|
789
806
|
const result = {};
|
|
790
807
|
for (const field of fields) {
|
|
791
|
-
if (field.
|
|
808
|
+
if (field.options.includeInApi === false)
|
|
792
809
|
continue;
|
|
793
810
|
const condition = where[field.key];
|
|
794
811
|
if (condition) {
|
package/esm/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { ClassType } from './classType';
|
|
2
|
-
export {
|
|
2
|
+
export type { ClassType } from './classType';
|
|
3
|
+
export { MembersOnly, FieldsMetadata, FieldRef, IdFieldRef, FieldsRef, EntityMetadata, EntityOrderBy, EntityFilter, FindOptions, FindOptionsBase, QueryResult, QueryOptions, Repository, FindFirstOptions, ComparisonValueFilter, ValueFilter, IdFilter, ContainsStringValueFilter, EntityRef, SortSegments, Paginator, LiveQuery, LiveQueryChangeInfo, Subscribable, RefSubscriber, RefSubscriberBase, RelationOptions, ObjectMembersOnly, MembersToInclude, RepositoryRelations, EntityIdFields, ClassFieldDecorator, ClassFieldDecoratorContextStub, //n1 consider removing in ts5
|
|
4
|
+
LifecycleEvent, FieldsRefBase, FieldsRefForEntityBase, RepositoryRelationsForEntityBase, ControllerRefForControllerBase, ControllerRefBase, ControllerRef, EntityRefForEntityBase, IdMetadata, FindFirstOptionsBase, } from './src/remult3/remult3';
|
|
3
5
|
export { EntityBase, ControllerBase, FieldType, getFields, ValueListFieldType, getValueList, ValueListFieldOptions, ValueListInfo, CaptionTransformer, } from './src/remult3/RepositoryImplementation';
|
|
4
6
|
export { Entity } from './src/remult3/entity';
|
|
5
7
|
export { getEntityRef } from './src/remult3/getEntityRef';
|
|
@@ -8,7 +10,7 @@ export { IdEntity } from './src/remult3/IdEntity';
|
|
|
8
10
|
export { describeClass } from './src/remult3/DecoratorReplacer';
|
|
9
11
|
export { EntityOptions } from './src/entity';
|
|
10
12
|
export { DataProvider, EntityDataProvider, EntityDataProviderFindOptions, ErrorInfo, RestDataProviderHttpProvider, } from './src/data-interfaces';
|
|
11
|
-
export { SqlCommand, SqlImplementation, SqlResult } from './src/sql-command';
|
|
13
|
+
export { SqlCommand, SqlCommandWithParameters, SqlImplementation, SqlResult, } from './src/sql-command';
|
|
12
14
|
export { FieldMetadata, FieldOptions, FieldValidator, ValueConverter, ValueListItem, // reconsider, maybe it should go to remult angular as the abstraction ?
|
|
13
15
|
ValueOrExpression, } from './src/column-interfaces';
|
|
14
16
|
export { RestDataProvider } from './src/data-providers/rest-data-provider';
|
|
@@ -16,18 +18,30 @@ export { InMemoryDataProvider } from './src/data-providers/in-memory-database';
|
|
|
16
18
|
export { ArrayEntityDataProvider } from './src/data-providers/array-entity-data-provider';
|
|
17
19
|
export { WebSqlDataProvider } from './src/data-providers/web-sql-data-provider';
|
|
18
20
|
export { SqlDatabase } from './src/data-providers/sql-database';
|
|
19
|
-
export { CustomSqlFilterObject, CustomSqlFilterBuilder, dbNamesOf, } from './src/filter/filter-consumer-bridge-to-sql-request';
|
|
21
|
+
export { CustomSqlFilterObject, CustomSqlFilterBuilder, dbNamesOf, CustomSqlFilterBuilderFunction, EntityDbNames, } from './src/filter/filter-consumer-bridge-to-sql-request';
|
|
20
22
|
export { JsonDataProvider, JsonEntityStorage, } from './src/data-providers/json-data-provider';
|
|
21
23
|
export { Controller, BackendMethodOptions, BackendMethod, ProgressListener, } from './src/server-action';
|
|
22
24
|
export { Allowed, Allow, Remult, RemultContext, ApiClient, isBackend, AllowedForInstance, EventDispatcher, EventSource, UserInfo, } from './src/context';
|
|
23
25
|
export { ExternalHttpProvider } from './src/buildRestDataProvider';
|
|
24
26
|
export { SortSegment, Sort } from './src/sort';
|
|
25
27
|
export { CompoundIdField } from './src/CompoundIdField';
|
|
26
|
-
export { Filter } from './src/filter/filter-interfaces';
|
|
28
|
+
export { Filter, FilterConsumer, customFilterInfo, } from './src/filter/filter-interfaces';
|
|
27
29
|
export { UrlBuilder } from './urlBuilder';
|
|
28
30
|
export { Validators } from './src/validators';
|
|
29
31
|
export { ValueConverters } from './src/valueConverters';
|
|
30
32
|
export { remult } from './src/remult-proxy';
|
|
31
33
|
export { SubscriptionServer, LiveQueryStorage, StoredQuery, InMemoryLiveQueryStorage, } from './src/live-query/SubscriptionServer';
|
|
32
34
|
export { SubscriptionListener, SubscriptionClientConnection, SubscriptionClient, SubscriptionChannel, LiveQueryChange, Unsubscribe, } from './src/live-query/SubscriptionChannel';
|
|
35
|
+
/**
|
|
36
|
+
* A convenient shortcut function to quickly obtain a repository for a specific entity type in Remult.
|
|
37
|
+
*
|
|
38
|
+
* @param entity The entity class type for which you want to get a repository.
|
|
39
|
+
* @returns A repository instance for the specified entity type.
|
|
40
|
+
*
|
|
41
|
+
* Example usage:
|
|
42
|
+
* ```ts
|
|
43
|
+
* await repo(Task).find()
|
|
44
|
+
* await repo(Customer).insert()
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
33
47
|
export declare function repo<entityType>(entity: ClassType<entityType>): import("./src/remult3/remult3").Repository<entityType>;
|
package/esm/index.js
CHANGED
|
@@ -16,7 +16,7 @@ export { Controller, BackendMethod, ProgressListener, } from './src/server-actio
|
|
|
16
16
|
export { Allow, Remult, isBackend, EventSource, } from './src/context';
|
|
17
17
|
export { Sort } from './src/sort';
|
|
18
18
|
export { CompoundIdField } from './src/CompoundIdField';
|
|
19
|
-
export { Filter } from './src/filter/filter-interfaces';
|
|
19
|
+
export { Filter, } from './src/filter/filter-interfaces';
|
|
20
20
|
export { UrlBuilder } from './urlBuilder';
|
|
21
21
|
export { Validators } from './src/validators';
|
|
22
22
|
export { ValueConverters } from './src/valueConverters';
|
|
@@ -25,6 +25,18 @@ import { remult } from './src/remult-proxy';
|
|
|
25
25
|
//export { getId } from './src/remult3/getId';
|
|
26
26
|
export { InMemoryLiveQueryStorage, } from './src/live-query/SubscriptionServer';
|
|
27
27
|
export { SubscriptionChannel, } from './src/live-query/SubscriptionChannel';
|
|
28
|
+
/**
|
|
29
|
+
* A convenient shortcut function to quickly obtain a repository for a specific entity type in Remult.
|
|
30
|
+
*
|
|
31
|
+
* @param entity The entity class type for which you want to get a repository.
|
|
32
|
+
* @returns A repository instance for the specified entity type.
|
|
33
|
+
*
|
|
34
|
+
* Example usage:
|
|
35
|
+
* ```ts
|
|
36
|
+
* await repo(Task).find()
|
|
37
|
+
* await repo(Customer).insert()
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
28
40
|
export function repo(entity) {
|
|
29
41
|
return remult.repo(entity);
|
|
30
42
|
}
|
package/esm/internals.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
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';
|
package/esm/internals.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
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';
|
|
@@ -9,6 +9,7 @@ export declare class PostgresSchemaBuilder {
|
|
|
9
9
|
private removeQuotes;
|
|
10
10
|
private whereTableAndSchema;
|
|
11
11
|
private schemaAndName;
|
|
12
|
+
private schemaOnly;
|
|
12
13
|
verifyStructureOfAllEntities(remult?: Remult): Promise<void>;
|
|
13
14
|
ensureSchema(entities: EntityMetadata<any>[]): Promise<void>;
|
|
14
15
|
createIfNotExist(entity: EntityMetadata): Promise<void>;
|
|
@@ -79,6 +79,16 @@ export class PostgresSchemaBuilder {
|
|
|
79
79
|
}
|
|
80
80
|
return e.$entityName;
|
|
81
81
|
}
|
|
82
|
+
schemaOnly(e) {
|
|
83
|
+
if (e.$entityName.includes('.')) {
|
|
84
|
+
return e.$entityName.split('.')[0];
|
|
85
|
+
}
|
|
86
|
+
if (this.specifiedSchema) {
|
|
87
|
+
return this.specifiedSchema;
|
|
88
|
+
}
|
|
89
|
+
// Should default to `public`
|
|
90
|
+
return 'public';
|
|
91
|
+
}
|
|
82
92
|
async verifyStructureOfAllEntities(remult) {
|
|
83
93
|
if (!remult) {
|
|
84
94
|
remult = defaultRemult;
|
|
@@ -108,6 +118,7 @@ export class PostgresSchemaBuilder {
|
|
|
108
118
|
}
|
|
109
119
|
catch (err) {
|
|
110
120
|
console.error('failed verify structure of ' + e.$entityName + ' ', err);
|
|
121
|
+
throw err;
|
|
111
122
|
}
|
|
112
123
|
}
|
|
113
124
|
}
|
|
@@ -134,7 +145,8 @@ export class PostgresSchemaBuilder {
|
|
|
134
145
|
result += ' primary key';
|
|
135
146
|
}
|
|
136
147
|
}
|
|
137
|
-
let sql = `CREATE
|
|
148
|
+
let sql = `CREATE SCHEMA IF NOT EXISTS ${this.schemaOnly(e)};
|
|
149
|
+
CREATE table ${this.schemaAndName(e)} (${result}\r\n)`;
|
|
138
150
|
if (PostgresSchemaBuilder.logToConsole)
|
|
139
151
|
console.info(sql);
|
|
140
152
|
await this.pool.execute(sql);
|
package/esm/remult-express.js
CHANGED
|
@@ -21,6 +21,6 @@ export function remultExpress(options) {
|
|
|
21
21
|
getRemult: (req) => server.getRemult(req),
|
|
22
22
|
openApiDoc: (options) => server.openApiDoc(options),
|
|
23
23
|
withRemult: (req, res, next) => server.withRemult(req, res, next),
|
|
24
|
-
// [ ]
|
|
24
|
+
// [ ] V1.5 add with remult promise
|
|
25
25
|
});
|
|
26
26
|
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Request, Plugin } from '@hapi/hapi';
|
|
2
|
+
import { type RemultServerCore, type RemultServerOptions } from './server';
|
|
3
|
+
export declare function remultHapi(options: RemultServerOptions<Request>): RemultHapiServer;
|
|
4
|
+
export type RemultHapiServer = Plugin<any, any> & RemultServerCore<Request> & {
|
|
5
|
+
withRemult<T>(req: Request, what: () => Promise<T>): Promise<T>;
|
|
6
|
+
};
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { createRemultServer, } from './server';
|
|
2
|
+
import { PassThrough } from 'stream';
|
|
3
|
+
export function remultHapi(options) {
|
|
4
|
+
const api = createRemultServer(options, {
|
|
5
|
+
buildGenericRequestInfo: (req) => ({
|
|
6
|
+
method: req.method,
|
|
7
|
+
params: req.params,
|
|
8
|
+
query: req.query,
|
|
9
|
+
url: req.url.pathname,
|
|
10
|
+
on: (e, do1) => {
|
|
11
|
+
req.raw.req.on('close', do1);
|
|
12
|
+
},
|
|
13
|
+
}),
|
|
14
|
+
getRequestBody: async (req) => req.payload,
|
|
15
|
+
});
|
|
16
|
+
const routesPlugin = {
|
|
17
|
+
name: 'remultPlugin',
|
|
18
|
+
register: async (server) => {
|
|
19
|
+
function hapiHandler(handler) {
|
|
20
|
+
return (request, h) => {
|
|
21
|
+
return new Promise((res, rej) => {
|
|
22
|
+
let status = 200;
|
|
23
|
+
let stream;
|
|
24
|
+
let r = {
|
|
25
|
+
status(statusCode) {
|
|
26
|
+
status = statusCode;
|
|
27
|
+
console.log(statusCode);
|
|
28
|
+
return r;
|
|
29
|
+
},
|
|
30
|
+
end() {
|
|
31
|
+
res(h.response().code(status));
|
|
32
|
+
},
|
|
33
|
+
json(data) {
|
|
34
|
+
res(h.response(data).code(status));
|
|
35
|
+
},
|
|
36
|
+
write(data) {
|
|
37
|
+
stream.write(data);
|
|
38
|
+
},
|
|
39
|
+
writeHead(status, headers) {
|
|
40
|
+
stream = new PassThrough();
|
|
41
|
+
res(h
|
|
42
|
+
.response(stream)
|
|
43
|
+
.header('content-type', 'text/event-stream')
|
|
44
|
+
.header('content-encoding', 'identity'));
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
try {
|
|
48
|
+
Object.assign(request, {
|
|
49
|
+
on(event, listener) {
|
|
50
|
+
request.raw.req.on('close', () => {
|
|
51
|
+
listener();
|
|
52
|
+
console.log('Connection closed');
|
|
53
|
+
});
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
handler(request, r, () => { });
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
rej(err);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
let hapiRouter = {
|
|
65
|
+
route(path) {
|
|
66
|
+
path = path.replace(/:id\b/g, '{id}');
|
|
67
|
+
let r = {
|
|
68
|
+
get(handler) {
|
|
69
|
+
server.route({
|
|
70
|
+
method: 'GET',
|
|
71
|
+
path,
|
|
72
|
+
handler: hapiHandler(handler),
|
|
73
|
+
});
|
|
74
|
+
return r;
|
|
75
|
+
},
|
|
76
|
+
post(handler) {
|
|
77
|
+
server.route({
|
|
78
|
+
method: 'POST',
|
|
79
|
+
path,
|
|
80
|
+
handler: hapiHandler(handler),
|
|
81
|
+
});
|
|
82
|
+
return r;
|
|
83
|
+
},
|
|
84
|
+
put(handler) {
|
|
85
|
+
server.route({
|
|
86
|
+
method: 'PUT',
|
|
87
|
+
path,
|
|
88
|
+
handler: hapiHandler(handler),
|
|
89
|
+
});
|
|
90
|
+
return r;
|
|
91
|
+
},
|
|
92
|
+
delete(handler) {
|
|
93
|
+
server.route({
|
|
94
|
+
method: 'DELETE',
|
|
95
|
+
path,
|
|
96
|
+
handler: hapiHandler(handler),
|
|
97
|
+
});
|
|
98
|
+
return r;
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
return r;
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
api.registerRouter(hapiRouter);
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
return Object.assign(routesPlugin, {
|
|
108
|
+
getRemult: (x) => api.getRemult(x),
|
|
109
|
+
openApiDoc: (x) => api.openApiDoc(x),
|
|
110
|
+
withRemult: (req, what) => api.withRemultPromise(req, what),
|
|
111
|
+
});
|
|
112
|
+
}
|
package/esm/remult-knex/index.js
CHANGED
|
@@ -7,6 +7,7 @@ import { getRepository, isAutoIncrement, } from '../src/remult3/RepositoryImplem
|
|
|
7
7
|
import { Sort } from '../src/sort';
|
|
8
8
|
import { ValueConverters } from '../src/valueConverters';
|
|
9
9
|
import { resultCompoundIdFilter as resultCompoundIdFilter } from '../src/resultCompoundIdFilter';
|
|
10
|
+
import { getRepositoryInternals } from '../src/remult3/repository-internals';
|
|
10
11
|
export class KnexDataProvider {
|
|
11
12
|
knex;
|
|
12
13
|
constructor(knex) {
|
|
@@ -54,7 +55,7 @@ export class KnexDataProvider {
|
|
|
54
55
|
const repo = getRepository(entity);
|
|
55
56
|
var b = new FilterConsumerBridgeToKnexRequest(await dbNamesOf(repo.metadata));
|
|
56
57
|
b._addWhere = false;
|
|
57
|
-
await (await repo.translateWhereToFilter(condition)).__applyToConsumer(b);
|
|
58
|
+
await (await getRepositoryInternals(repo).translateWhereToFilter(condition)).__applyToConsumer(b);
|
|
58
59
|
let r = await b.resolveWhere();
|
|
59
60
|
return (knex) => r.forEach((y) => y(knex));
|
|
60
61
|
}
|
|
@@ -314,7 +315,7 @@ export class KnexSchemaBuilder {
|
|
|
314
315
|
if (!remult)
|
|
315
316
|
remult = remultContext;
|
|
316
317
|
const entities = allEntities.map((x) => remult.repo(x).metadata);
|
|
317
|
-
this.ensureSchema(entities);
|
|
318
|
+
await this.ensureSchema(entities);
|
|
318
319
|
}
|
|
319
320
|
async ensureSchema(entities) {
|
|
320
321
|
for (const entity of entities) {
|
|
@@ -329,6 +330,7 @@ export class KnexSchemaBuilder {
|
|
|
329
330
|
}
|
|
330
331
|
catch (err) {
|
|
331
332
|
console.error('failed ensure schema of ' + e.$entityName + ' ', err);
|
|
333
|
+
throw err;
|
|
332
334
|
}
|
|
333
335
|
}
|
|
334
336
|
}
|
package/esm/remult-mongo.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ClientSession, type Db, type MongoClient } from 'mongodb';
|
|
2
2
|
import type { DataProvider, EntityDataProvider, EntityFilter, EntityMetadata, Remult } from '.';
|
|
3
3
|
import type { RepositoryOverloads } from './src/remult3/RepositoryImplementation';
|
|
4
4
|
export declare class MongoDataProvider implements DataProvider {
|
package/esm/remult-mongo.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { ObjectId, } from 'mongodb';
|
|
1
2
|
import { CompoundIdField, Filter } from '.';
|
|
2
3
|
import { dbNamesOf } from './src/filter/filter-consumer-bridge-to-sql-request';
|
|
3
4
|
import { remult as remultContext } from './src/remult-proxy';
|
|
4
5
|
import { getRepository } from './src/remult3/RepositoryImplementation';
|
|
5
6
|
import { resultCompoundIdFilter } from './src/resultCompoundIdFilter';
|
|
7
|
+
import { getRepositoryInternals } from './src/remult3/repository-internals';
|
|
6
8
|
export class MongoDataProvider {
|
|
7
9
|
db;
|
|
8
10
|
client;
|
|
@@ -50,7 +52,7 @@ export class MongoDataProvider {
|
|
|
50
52
|
const repo = getRepository(entity);
|
|
51
53
|
var b = new FilterConsumerBridgeToMongo(await dbNamesOf(repo.metadata));
|
|
52
54
|
b._addWhere = false;
|
|
53
|
-
await (await repo.translateWhereToFilter(condition)).__applyToConsumer(b);
|
|
55
|
+
await (await getRepositoryInternals(repo).translateWhereToFilter(condition)).__applyToConsumer(b);
|
|
54
56
|
let r = await b.resolveWhere();
|
|
55
57
|
return r;
|
|
56
58
|
}
|
|
@@ -74,14 +76,14 @@ class MongoEntityDataProvider {
|
|
|
74
76
|
let val = row[nameProvider.$dbNameOf(col)];
|
|
75
77
|
if (isNull(val))
|
|
76
78
|
val = null;
|
|
77
|
-
result[col.key] =
|
|
79
|
+
result[col.key] = fromDb(col, val);
|
|
78
80
|
}
|
|
79
81
|
return result;
|
|
80
82
|
}
|
|
81
83
|
translateToDb(row, nameProvider) {
|
|
82
84
|
let result = {};
|
|
83
85
|
for (const col of this.entity.fields) {
|
|
84
|
-
let val =
|
|
86
|
+
let val = toDb(col, row[col.key]);
|
|
85
87
|
if (val === null)
|
|
86
88
|
val = NULL;
|
|
87
89
|
result[nameProvider.$dbNameOf(col)] = val;
|
|
@@ -220,7 +222,7 @@ class FilterConsumerBridgeToMongo {
|
|
|
220
222
|
isIn(col, val) {
|
|
221
223
|
this.result.push(() => ({
|
|
222
224
|
[this.nameProvider.$dbNameOf(col)]: {
|
|
223
|
-
$in: val.map((x) =>
|
|
225
|
+
$in: val.map((x) => toDb(col, x)),
|
|
224
226
|
},
|
|
225
227
|
}));
|
|
226
228
|
}
|
|
@@ -252,7 +254,7 @@ class FilterConsumerBridgeToMongo {
|
|
|
252
254
|
add(col, val, operator) {
|
|
253
255
|
this.result.push(() => ({
|
|
254
256
|
[this.nameProvider.$dbNameOf(col)]: {
|
|
255
|
-
[operator]: isNull(val) ? val :
|
|
257
|
+
[operator]: isNull(val) ? val : toDb(col, val),
|
|
256
258
|
},
|
|
257
259
|
}));
|
|
258
260
|
}
|
|
@@ -269,3 +271,13 @@ class FilterConsumerBridgeToMongo {
|
|
|
269
271
|
// })());
|
|
270
272
|
}
|
|
271
273
|
}
|
|
274
|
+
function toDb(col, val) {
|
|
275
|
+
if (col.valueConverter.fieldTypeInDb == 'dbid')
|
|
276
|
+
return val ? new ObjectId(val) : val === null ? null : undefined;
|
|
277
|
+
return col.valueConverter.toDb(val);
|
|
278
|
+
}
|
|
279
|
+
function fromDb(col, val) {
|
|
280
|
+
if (col.valueConverter.fieldTypeInDb == 'dbid')
|
|
281
|
+
return val ? val.toHexString() : val === null ? null : undefined;
|
|
282
|
+
return col.valueConverter.fromDb(val);
|
|
283
|
+
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { Handle, RequestEvent } from '@sveltejs/kit';
|
|
2
2
|
import type { RemultServerCore, RemultServerOptions } from './server';
|
|
3
3
|
export declare function remultSveltekit(options?: RemultServerOptions<RequestEvent>): RemultSveltekitServer;
|
|
4
|
-
export type RemultSveltekitServer = RemultServerCore<RequestEvent> & Handle
|
|
4
|
+
export type RemultSveltekitServer = RemultServerCore<RequestEvent> & Handle & {
|
|
5
|
+
withRemult<T>(request: RequestEvent, what: () => Promise<T>): Promise<T>;
|
|
6
|
+
};
|
package/esm/remult-sveltekit.js
CHANGED
|
@@ -67,5 +67,8 @@ export function remultSveltekit(options) {
|
|
|
67
67
|
return Object.assign(handler, {
|
|
68
68
|
getRemult: (req) => result.getRemult(req),
|
|
69
69
|
openApiDoc: (options) => result.openApiDoc(options),
|
|
70
|
+
withRemult(request, what) {
|
|
71
|
+
return result.withRemultPromise(request, what);
|
|
72
|
+
},
|
|
70
73
|
});
|
|
71
74
|
}
|
|
@@ -112,6 +112,14 @@ export declare class EntityQueueStorage implements QueueStorage {
|
|
|
112
112
|
getJobInfo(queuedJobId: string): Promise<queuedJobInfo>;
|
|
113
113
|
createJob(url: string, userId: string): Promise<string>;
|
|
114
114
|
}
|
|
115
|
+
export declare class RouteImplementation<RequestType> {
|
|
116
|
+
private coreOptions;
|
|
117
|
+
constructor(coreOptions: ServerCoreOptions<RequestType>);
|
|
118
|
+
map: Map<string, Map<string, GenericRequestHandler>>;
|
|
119
|
+
route(path: string): SpecificRoute;
|
|
120
|
+
handle(req: RequestType, gRes?: GenericResponse): Promise<ServerHandleResponse | undefined>;
|
|
121
|
+
middleware(origReq: RequestType, res: GenericResponse, next: VoidFunction): void;
|
|
122
|
+
}
|
|
115
123
|
export declare class JobsInQueueEntity extends IdEntity {
|
|
116
124
|
userId: string;
|
|
117
125
|
url: string;
|
|
@@ -116,7 +116,7 @@ export class RemultServerImplementation {
|
|
|
116
116
|
});
|
|
117
117
|
}
|
|
118
118
|
getEntities() {
|
|
119
|
-
//TODO - consider using entitiesMetaData - but it may require making it all awaitable
|
|
119
|
+
//TODO V2 - consider using entitiesMetaData - but it may require making it all awaitable
|
|
120
120
|
var r = new Remult();
|
|
121
121
|
return this.options.entities.map((x) => r.repo(x).metadata);
|
|
122
122
|
}
|
|
@@ -763,7 +763,7 @@ export class EntityQueueStorage {
|
|
|
763
763
|
return (this.sync = this.sync.then(() => what()));
|
|
764
764
|
}
|
|
765
765
|
async getJobInfo(queuedJobId) {
|
|
766
|
-
let q = await this.repo.findId(queuedJobId
|
|
766
|
+
let q = await this.repo.findId(queuedJobId);
|
|
767
767
|
let lastProgress = undefined;
|
|
768
768
|
return {
|
|
769
769
|
userId: q.userId,
|
|
@@ -811,7 +811,7 @@ export class EntityQueueStorage {
|
|
|
811
811
|
return q.id;
|
|
812
812
|
}
|
|
813
813
|
}
|
|
814
|
-
class RouteImplementation {
|
|
814
|
+
export class RouteImplementation {
|
|
815
815
|
coreOptions;
|
|
816
816
|
constructor(coreOptions) {
|
|
817
817
|
this.coreOptions = coreOptions;
|
|
@@ -845,7 +845,7 @@ class RouteImplementation {
|
|
|
845
845
|
return route;
|
|
846
846
|
}
|
|
847
847
|
async handle(req, gRes) {
|
|
848
|
-
return new Promise((res) => {
|
|
848
|
+
return new Promise((res, rej) => {
|
|
849
849
|
const response = new (class {
|
|
850
850
|
write(data) {
|
|
851
851
|
;
|
|
@@ -881,7 +881,12 @@ class RouteImplementation {
|
|
|
881
881
|
});
|
|
882
882
|
}
|
|
883
883
|
})();
|
|
884
|
-
|
|
884
|
+
try {
|
|
885
|
+
this.middleware(req, response, () => res(undefined));
|
|
886
|
+
}
|
|
887
|
+
catch (err) {
|
|
888
|
+
rej(err);
|
|
889
|
+
}
|
|
885
890
|
});
|
|
886
891
|
}
|
|
887
892
|
middleware(origReq, res, next) {
|
|
@@ -920,7 +925,7 @@ class RouteImplementation {
|
|
|
920
925
|
}
|
|
921
926
|
let idPosition = path.lastIndexOf('/');
|
|
922
927
|
if (idPosition >= 0) {
|
|
923
|
-
lowerPath =
|
|
928
|
+
lowerPath = lowerPath.substring(0, idPosition) + '/:id';
|
|
924
929
|
m = this.map.get(lowerPath);
|
|
925
930
|
if (m) {
|
|
926
931
|
let h = m.get(req.method.toLowerCase());
|
|
@@ -929,7 +934,7 @@ class RouteImplementation {
|
|
|
929
934
|
req.params = {};
|
|
930
935
|
origReq['_tempParams'] = req.params;
|
|
931
936
|
}
|
|
932
|
-
req.params.id = path.substring(idPosition + 1);
|
|
937
|
+
req.params.id = path.substring(idPosition + 1).replace(/%2C/g, ',');
|
|
933
938
|
h(origReq, res, next);
|
|
934
939
|
return;
|
|
935
940
|
}
|
|
@@ -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>;
|
|
@@ -9,7 +9,9 @@ export class CompoundIdField {
|
|
|
9
9
|
displayValue(item) {
|
|
10
10
|
throw new Error('Method not implemented.');
|
|
11
11
|
}
|
|
12
|
-
includedInApi
|
|
12
|
+
includedInApi(item) {
|
|
13
|
+
throw new Error('Method not implemented.');
|
|
14
|
+
}
|
|
13
15
|
toInput(value, inputType) {
|
|
14
16
|
throw new Error('Method not implemented.');
|
|
15
17
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ClassType } from '../classType';
|
|
2
|
-
import type {
|
|
3
|
-
import type { EntityMetadata, FieldRef,
|
|
2
|
+
import type { AllowedForInstance } from './context';
|
|
3
|
+
import type { EntityMetadata, FieldRef, LifecycleEvent } from './remult3/remult3';
|
|
4
4
|
export interface FieldOptions<entityType = any, valueType = any> {
|
|
5
5
|
/** A human readable name for the field. Can be used to achieve a consistent caption for a field throughout the app
|
|
6
6
|
* @example
|
|
@@ -11,7 +11,7 @@ export interface FieldOptions<entityType = any, valueType = any> {
|
|
|
11
11
|
allowNull?: boolean;
|
|
12
12
|
/** If this field data is included in the api.
|
|
13
13
|
* @see [allowed](http://remult.dev/docs/allowed.html)*/
|
|
14
|
-
includeInApi?:
|
|
14
|
+
includeInApi?: AllowedForInstance<entityType>;
|
|
15
15
|
/** If this field data can be updated in the api.
|
|
16
16
|
* @see [allowed](http://remult.dev/docs/allowed.html)*/
|
|
17
17
|
allowApiUpdate?: AllowedForInstance<entityType>;
|
|
@@ -37,7 +37,7 @@ export interface FieldOptions<entityType = any, valueType = any> {
|
|
|
37
37
|
*/
|
|
38
38
|
validate?: ((entity: entityType, fieldRef: FieldRef<entityType, valueType>) => any | Promise<any>) | ((entity: entityType, fieldRef: FieldRef<entityType, valueType>) => any | Promise<any>)[];
|
|
39
39
|
/** Will be fired before this field is saved to the server/database */
|
|
40
|
-
saving?: (entity: entityType,
|
|
40
|
+
saving?: (entity: entityType, fieldRef: FieldRef<entityType, valueType>, e: LifecycleEvent<entityType>) => any | Promise<any>;
|
|
41
41
|
/** An expression that will determine this fields value on the backend and be provided to the front end*/
|
|
42
42
|
serverExpression?: (entity: entityType) => valueType | Promise<valueType>;
|
|
43
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.
|
|
@@ -69,8 +69,20 @@ export interface FieldOptions<entityType = any, valueType = any> {
|
|
|
69
69
|
defaultValue?: (entity: entityType) => valueType | Promise<valueType>;
|
|
70
70
|
/** The html input type for this field */
|
|
71
71
|
inputType?: string;
|
|
72
|
-
/**
|
|
73
|
-
* @
|
|
72
|
+
/**
|
|
73
|
+
* @deprecated The 'lazy' option is deprecated and will be removed in future versions.
|
|
74
|
+
* Use 'Relations.toOne' instead.
|
|
75
|
+
*
|
|
76
|
+
* Example usage:
|
|
77
|
+
* ```
|
|
78
|
+
* // Deprecated usage with 'lazy' option
|
|
79
|
+
* @Field(() => Customer, { lazy: true })
|
|
80
|
+
* customer?: Customer;
|
|
81
|
+
*
|
|
82
|
+
* // Preferred usage with 'Relations.toOne'
|
|
83
|
+
* @Relations.toOne(() => Customer)
|
|
84
|
+
* customer?: Customer;
|
|
85
|
+
* ```
|
|
74
86
|
*/
|
|
75
87
|
lazy?: boolean;
|
|
76
88
|
/** The value type for this field */
|
|
@@ -120,9 +132,9 @@ export interface FieldMetadata<valueType = any, entityType = any> {
|
|
|
120
132
|
* @example
|
|
121
133
|
* repo.fields.createDate.displayValue(task) //will display the date as defined in the `displayValue` option defined for it.
|
|
122
134
|
*/
|
|
123
|
-
displayValue(item: Partial<
|
|
124
|
-
apiUpdateAllowed(item?: Partial<
|
|
125
|
-
|
|
135
|
+
displayValue(item: Partial<entityType>): string;
|
|
136
|
+
apiUpdateAllowed(item?: Partial<entityType>): boolean;
|
|
137
|
+
includedInApi(item?: Partial<entityType>): boolean;
|
|
126
138
|
/** Adapts the value for usage with html input
|
|
127
139
|
* @example
|
|
128
140
|
* @Fields.dateOnly()
|
package/esm/src/column.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { idType } from './remult3/remult3';
|
|
2
|
-
import type { RepositoryImplementation } from './remult3/RepositoryImplementation';
|
|
1
|
+
import type { idType, Repository } from './remult3/remult3';
|
|
3
2
|
export declare function makeTitle(name: string): string;
|
|
4
3
|
export declare class LookupColumn<T> {
|
|
5
4
|
private repository;
|
|
6
5
|
private isReferenceRelation;
|
|
6
|
+
private allowNull;
|
|
7
7
|
toJson(): any;
|
|
8
8
|
setId(val: any): void;
|
|
9
9
|
waitLoadOf(id: any): Promise<T>;
|
|
@@ -13,7 +13,7 @@ export declare class LookupColumn<T> {
|
|
|
13
13
|
};
|
|
14
14
|
set(item: T): void;
|
|
15
15
|
id: idType<T>;
|
|
16
|
-
constructor(repository:
|
|
16
|
+
constructor(repository: Repository<T>, isReferenceRelation: any, allowNull: any);
|
|
17
17
|
get item(): T;
|
|
18
18
|
waitLoad(): Promise<T>;
|
|
19
19
|
}
|