remult 0.27.25-next.0 → 0.30.0-next.1
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 +0 -2
- package/SseSubscriptionServer.d.ts +4 -3
- package/assign.js +2 -1
- package/esm/graphql.js +3 -3
- package/esm/index.js +1 -2
- package/esm/internals.js +1 -2
- package/esm/live-query/data-provider-live-query-storage.js +2 -0
- package/esm/migrations/migrate.js +11 -6
- package/esm/postgres/postgres-data-provider.js +1 -1
- package/esm/postgres/schema-builder.js +41 -0
- package/esm/remult-hapi.js +1 -1
- package/esm/remult-hono.js +1 -3
- package/esm/remult-knex/index.js +17 -52
- package/esm/remult-mongo.js +3 -145
- package/esm/remult-nuxt.js +1 -1
- package/esm/remult-sqlite-core.js +9 -39
- package/esm/remult-sqlite3.js +1 -9
- package/esm/remult-sveltekit.js +11 -4
- package/esm/server/get-remult-admin-html.js +1 -1
- package/esm/server/index.js +2 -4
- package/esm/server/initAsyncHooks.js +51 -3
- package/esm/server/remult-admin.js +29 -39
- package/esm/server/remult-api-server.js +79 -105
- package/esm/src/CompoundIdField.js +9 -9
- package/esm/src/buildRestDataProvider.js +2 -2
- package/esm/src/column.js +4 -3
- package/esm/src/context.js +3 -21
- package/esm/src/data-api.js +72 -194
- package/esm/src/data-interfaces.js +0 -10
- package/esm/src/data-providers/array-entity-data-provider.js +11 -224
- package/esm/src/data-providers/in-memory-database.js +1 -1
- package/esm/src/data-providers/json-data-provider.js +2 -7
- package/esm/src/data-providers/json-entity-opfs-storage.js +5 -9
- package/esm/src/data-providers/rest-data-provider.js +13 -66
- package/esm/src/data-providers/sql-database.js +57 -191
- package/esm/src/data-providers/web-sql-data-provider.js +140 -0
- package/esm/src/filter/filter-consumer-bridge-to-sql-request.js +15 -51
- package/esm/src/filter/filter-interfaces.js +1 -104
- package/esm/src/live-query/LiveQueryClient.js +1 -0
- package/esm/src/live-query/SubscriptionServer.js +2 -2
- package/esm/src/remult-proxy.js +5 -23
- package/esm/src/remult-static.js +0 -2
- package/esm/src/remult3/Fields.js +6 -26
- package/esm/src/remult3/RepositoryImplementation.js +292 -436
- package/esm/src/remult3/__updateEntityBasedOnWhere.js +0 -3
- package/esm/src/remult3/entity.js +6 -10
- package/esm/src/remult3/relation-loader.js +2 -2
- package/esm/src/remult3/relationInfoMember.js +2 -4
- package/esm/src/remult3/remult3.js +47 -74
- package/esm/src/server-action.js +15 -43
- package/esm/src/sort.js +13 -18
- package/esm/src/validators.js +4 -74
- package/esm/src/valueConverters.js +2 -2
- package/graphql.js +6 -5
- package/index.d.ts +3 -3
- package/index.js +4 -6
- package/internals.d.ts +3 -4
- package/internals.js +1 -5
- package/live-query/data-provider-live-query-storage.js +8 -6
- package/migrations/compare-migration-snapshots.js +49 -48
- package/migrations/generate-migrations.js +2 -1
- package/migrations/migrate.js +10 -5
- package/migrations/migration-types.d.ts +1 -1
- package/migrations/migration-types.js +4 -4
- package/migrations/update-migrations-ts-file.js +2 -1
- package/myLog.js +2 -1
- package/package.json +1 -6
- package/postgres/postgres-data-provider.d.ts +2 -2
- package/postgres/postgres-data-provider.js +6 -6
- package/postgres/schema-builder.d.ts +5 -1
- package/postgres/schema-builder.js +120 -17
- package/remult-express.js +3 -4
- package/remult-fastify.js +3 -4
- package/remult-fresh.js +2 -1
- package/remult-hapi.js +4 -5
- package/remult-hono.js +3 -6
- package/remult-knex/index.d.ts +5 -4
- package/remult-knex/index.js +31 -87
- package/remult-mongo.d.ts +2 -3
- package/remult-mongo.js +26 -312
- package/remult-next.d.ts +6 -5
- package/remult-next.js +6 -11
- package/remult-nuxt.js +3 -2
- package/remult-solid-start.js +2 -1
- package/remult-sqlite-core.d.ts +3 -6
- package/remult-sqlite-core.js +33 -122
- package/remult-sqlite3.d.ts +0 -2
- package/remult-sqlite3.js +1 -20
- package/remult-sveltekit.d.ts +1 -1
- package/remult-sveltekit.js +36 -15
- package/remult-turso.d.ts +1 -1
- package/server/JsonEntityFileStorage.d.ts +1 -1
- package/server/get-remult-admin-html.js +3 -2
- package/server/index.d.ts +0 -1
- package/server/index.js +3 -6
- package/server/initAsyncHooks.d.ts +13 -7
- package/server/initAsyncHooks.js +73 -5
- package/server/initDataProvider.js +2 -1
- package/server/initDataProviderOrJson.d.ts +1 -1
- package/server/initDataProviderOrJson.js +2 -1
- package/server/remult-admin.d.ts +1 -12
- package/server/remult-admin.js +30 -39
- package/server/remult-api-server.d.ts +22 -23
- package/server/remult-api-server.js +95 -138
- package/src/CompoundIdField.d.ts +2 -2
- package/src/CompoundIdField.js +0 -9
- package/src/buildRestDataProvider.d.ts +1 -1
- package/src/buildRestDataProvider.js +10 -10
- package/src/column-interfaces.d.ts +7 -6
- package/src/column-interfaces.js +2 -1
- package/src/column.d.ts +4 -4
- package/src/column.js +6 -5
- package/src/context.d.ts +4 -25
- package/src/context.js +8 -36
- package/src/data-api.d.ts +9 -16
- package/src/data-api.js +121 -365
- package/src/data-interfaces.d.ts +3 -34
- package/src/data-interfaces.js +2 -13
- package/src/data-providers/array-entity-data-provider.d.ts +2 -3
- package/src/data-providers/array-entity-data-provider.js +51 -399
- package/src/data-providers/in-memory-database.js +1 -1
- package/src/data-providers/json-data-provider.d.ts +2 -3
- package/src/data-providers/json-data-provider.js +2 -10
- package/src/data-providers/json-entity-opfs-storage.js +16 -30
- package/src/data-providers/rest-data-provider.d.ts +5 -17
- package/src/data-providers/rest-data-provider.js +29 -115
- package/src/data-providers/sql-database.d.ts +3 -54
- package/src/data-providers/sql-database.js +164 -380
- package/src/data-providers/web-sql-data-provider.d.ts +20 -0
- package/src/data-providers/web-sql-data-provider.js +228 -0
- package/src/entity.d.ts +5 -5
- package/src/filter/filter-consumer-bridge-to-sql-request.d.ts +4 -8
- package/src/filter/filter-consumer-bridge-to-sql-request.js +32 -96
- package/src/filter/filter-interfaces.d.ts +2 -13
- package/src/filter/filter-interfaces.js +24 -175
- package/src/isOfType.js +3 -2
- package/src/live-query/SubscriptionServer.js +97 -95
- package/src/remult-proxy.js +12 -39
- package/src/remult-static.d.ts +2 -3
- package/src/remult-static.js +4 -8
- package/src/remult3/Fields.d.ts +18 -18
- package/src/remult3/Fields.js +12 -33
- package/src/remult3/RepositoryImplementation.d.ts +52 -71
- package/src/remult3/RepositoryImplementation.js +803 -972
- package/src/remult3/__updateEntityBasedOnWhere.js +2 -4
- package/src/remult3/addValidator.d.ts +1 -1
- package/src/remult3/addValidator.js +2 -1
- package/src/remult3/classDescribers.d.ts +4 -4
- package/src/remult3/classDescribers.js +4 -3
- package/src/remult3/columnInfo.d.ts +1 -1
- package/src/remult3/entity.js +9 -11
- package/src/remult3/getEntityRef.js +4 -4
- package/src/remult3/relation-loader.d.ts +1 -1
- package/src/remult3/relationInfoMember.d.ts +5 -5
- package/src/remult3/relationInfoMember.js +7 -8
- package/src/remult3/remult3.d.ts +42 -535
- package/src/remult3/remult3.js +48 -75
- package/src/remult3/repository-internals.d.ts +3 -3
- package/src/remult3/repository-internals.js +2 -2
- package/src/server-action.d.ts +3 -27
- package/src/server-action.js +61 -103
- package/src/sort.d.ts +1 -3
- package/src/sort.js +12 -19
- package/src/sql-command.d.ts +1 -2
- package/src/validators.d.ts +2 -87
- package/src/validators.js +14 -94
- package/src/valueConverters.js +2 -3
- package/esm/remult-duckdb.js +0 -111
- package/esm/server/test-api-data-provider.js +0 -83
- package/esm/src/data-providers/json-entity-indexed-db-data-provider.js +0 -55
- package/esm/src/data-providers/sql-relations.js +0 -125
- package/esm/src/remult3/QueryResultImpl.js +0 -147
- package/remult-duckdb.d.ts +0 -9
- package/remult-duckdb.js +0 -150
- package/server/test-api-data-provider.d.ts +0 -3
- package/server/test-api-data-provider.js +0 -130
- package/src/data-providers/json-entity-indexed-db-data-provider.d.ts +0 -9
- package/src/data-providers/json-entity-indexed-db-data-provider.js +0 -97
- package/src/data-providers/sql-relations.d.ts +0 -40
- package/src/data-providers/sql-relations.js +0 -167
- package/src/remult3/QueryResultImpl.d.ts +0 -16
- package/src/remult3/QueryResultImpl.js +0 -268
package/README.md
CHANGED
|
@@ -41,8 +41,6 @@ Remult uses **TypeScript entities** as a single source of truth for: ✅ CRUD +
|
|
|
41
41
|
|
|
42
42
|
**Remult is frontend and backend framework agnostic** and comes with adapters for Express, Fastify, Next.js, Nuxt, SvelteKit, SolidStart, Nest, Koa, Hapi and Hono.
|
|
43
43
|
|
|
44
|
-
> **Want to experience Remult firsthand? [Try our interactive online tutorial](https://learn.remult.dev/).**
|
|
45
|
-
|
|
46
44
|
Remult promotes a **consistent query syntax for both frontend and Backend code**:
|
|
47
45
|
|
|
48
46
|
```ts
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
1
2
|
import type { GenericResponse } from './server/index.js';
|
|
2
3
|
import type { Remult } from './src/context.js';
|
|
3
4
|
import type { SubscriptionServer } from './src/live-query/SubscriptionServer.js';
|
|
4
5
|
export declare class SseSubscriptionServer implements SubscriptionServer {
|
|
5
6
|
private canUserConnectToChannel?;
|
|
6
|
-
constructor(canUserConnectToChannel?: (
|
|
7
|
+
constructor(canUserConnectToChannel?: (channel: string, remult: Remult) => boolean);
|
|
7
8
|
publishMessage<T>(channel: string, message: any): Promise<void>;
|
|
8
9
|
}
|
|
9
10
|
export interface ResponseRequiredForSSE {
|
|
@@ -14,11 +15,11 @@ export interface ResponseRequiredForSSE {
|
|
|
14
15
|
export declare class clientConnection {
|
|
15
16
|
response: GenericResponse & ResponseRequiredForSSE;
|
|
16
17
|
channels: Record<string, boolean>;
|
|
17
|
-
timeOutRef
|
|
18
|
+
timeOutRef: NodeJS.Timeout;
|
|
18
19
|
close(): void;
|
|
19
20
|
closed: boolean;
|
|
20
21
|
write(eventData: string, eventType?: string): void;
|
|
21
|
-
connectionId:
|
|
22
|
+
connectionId: any;
|
|
22
23
|
constructor(response: GenericResponse & ResponseRequiredForSSE);
|
|
23
24
|
sendLiveMessage(): void;
|
|
24
25
|
}
|
package/assign.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.assign =
|
|
3
|
+
exports.assign = void 0;
|
|
4
4
|
function assign(item, valuesToSet) {
|
|
5
5
|
if (valuesToSet)
|
|
6
6
|
Object.assign(item, valuesToSet);
|
|
7
7
|
return item;
|
|
8
8
|
}
|
|
9
|
+
exports.assign = assign;
|
package/esm/graphql.js
CHANGED
|
@@ -315,7 +315,7 @@ export function remultGraphql(options) {
|
|
|
315
315
|
value: getMetaType(meta),
|
|
316
316
|
}, argErrorDetail, argClientMutationId);
|
|
317
317
|
root[createResolverKey] = handleMutationWithErrors(async (dApi, response, setResult, arg1, req) => {
|
|
318
|
-
await dApi.
|
|
318
|
+
await dApi.post({
|
|
319
319
|
...response,
|
|
320
320
|
created: (y) => {
|
|
321
321
|
const orig = { ...y };
|
|
@@ -324,7 +324,7 @@ export function remultGraphql(options) {
|
|
|
324
324
|
[toCamelCase(getMetaType(meta))]: y,
|
|
325
325
|
});
|
|
326
326
|
},
|
|
327
|
-
},
|
|
327
|
+
}, arg1.input);
|
|
328
328
|
});
|
|
329
329
|
resolversMutation[createResolverKey] = (origItem, args, req, gqlInfo) => root[createResolverKey](args, req, gqlInfo);
|
|
330
330
|
}
|
|
@@ -976,7 +976,7 @@ export function translateWhereToRestBody(fields, { where }) {
|
|
|
976
976
|
}
|
|
977
977
|
}
|
|
978
978
|
if (where.OR) {
|
|
979
|
-
result.OR = where.OR.map((where) => translateWhereToRestBody(fields, { where })
|
|
979
|
+
result.OR = where.OR.map((where) => translateWhereToRestBody(fields, { where }).where);
|
|
980
980
|
}
|
|
981
981
|
return { where: result };
|
|
982
982
|
}
|
package/esm/index.js
CHANGED
|
@@ -5,14 +5,13 @@ export { getEntityRef } from './src/remult3/getEntityRef.js';
|
|
|
5
5
|
export { Field, Fields, Relations, } from './src/remult3/Fields.js';
|
|
6
6
|
export { IdEntity } from './src/remult3/IdEntity.js';
|
|
7
7
|
export { describeClass, describeBackendMethods, describeEntity, } from './src/remult3/classDescribers.js';
|
|
8
|
-
export { EntityError, } from './src/data-interfaces.js'; //V
|
|
9
8
|
export { RestDataProvider } from './src/data-providers/rest-data-provider.js'; //V
|
|
10
9
|
export { InMemoryDataProvider } from './src/data-providers/in-memory-database.js'; //V
|
|
10
|
+
export { WebSqlDataProvider } from './src/data-providers/web-sql-data-provider.js'; //V
|
|
11
11
|
export { SqlDatabase } from './src/data-providers/sql-database.js'; //V
|
|
12
12
|
export { CustomSqlFilterBuilder, dbNamesOf, } from './src/filter/filter-consumer-bridge-to-sql-request.js';
|
|
13
13
|
export { JsonDataProvider, } from './src/data-providers/json-data-provider.js'; //V
|
|
14
14
|
export { JsonEntityOpfsStorage } from './src/data-providers/json-entity-opfs-storage.js';
|
|
15
|
-
export { JsonEntityIndexedDbStorage } from './src/data-providers/json-entity-indexed-db-data-provider.js';
|
|
16
15
|
//export * from './src/data-api'; //reconsider if to make internal
|
|
17
16
|
export { Controller, BackendMethod, ProgressListener, ForbiddenError, } from './src/server-action.js';
|
|
18
17
|
export { Allow, Remult, withRemult, isBackend, EventSource, } from './src/context.js';
|
package/esm/internals.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { remultStatic } from './src/remult-static.js';
|
|
2
|
-
export { sqlRelations, sqlRelationsFilter, } from './src/data-providers/sql-relations.js';
|
|
3
2
|
export { getRelationInfo, getRelationFieldInfo, } from './src/remult3/relationInfoMember.js';
|
|
4
|
-
export { decorateColumnSettings, controllerRefImpl, getControllerRef,
|
|
3
|
+
export { decorateColumnSettings, controllerRefImpl, getControllerRef, } from './src/remult3/RepositoryImplementation.js';
|
|
5
4
|
export { getEntitySettings } from './src/remult3/getEntityRef.js';
|
|
6
5
|
export { __updateEntityBasedOnWhere } from './src/filter/filter-interfaces.js';
|
|
7
6
|
export const actionInfo = remultStatic.actionInfo;
|
|
@@ -3,6 +3,7 @@ import { Remult } from '../src/context.js';
|
|
|
3
3
|
import { EntityBase } from '../src/remult3/RepositoryImplementation.js';
|
|
4
4
|
import { Fields } from '../src/remult3/Fields.js';
|
|
5
5
|
import { Entity } from '../src/remult3/entity.js';
|
|
6
|
+
import { remultStatic } from '../src/remult-static.js';
|
|
6
7
|
import { initDataProviderOrJson } from '../server/initDataProviderOrJson.js';
|
|
7
8
|
export class DataProviderLiveQueryStorage {
|
|
8
9
|
repo;
|
|
@@ -89,3 +90,4 @@ LiveQueryStorageEntity = __decorate([
|
|
|
89
90
|
/*@internal */
|
|
90
91
|
], LiveQueryStorageEntity);
|
|
91
92
|
export { LiveQueryStorageEntity };
|
|
93
|
+
remultStatic.allEntities.splice(remultStatic.allEntities.indexOf(LiveQueryStorageEntity), 1);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { __decorate, __metadata } from "tslib";
|
|
2
|
+
import { Entity, IdEntity, Fields, remult, Remult, } from '../index.js';
|
|
2
3
|
import { initDataProviderOrJson } from '../server/initDataProviderOrJson.js';
|
|
3
4
|
import { doTransaction } from '../src/context.js';
|
|
4
5
|
import { cast, isOfType } from '../src/isOfType.js';
|
|
@@ -20,12 +21,16 @@ export async function migrate(options) {
|
|
|
20
21
|
const prev = remult.dataProvider;
|
|
21
22
|
remult.dataProvider = dataProvider;
|
|
22
23
|
try {
|
|
23
|
-
class VersionInfo extends IdEntity {
|
|
24
|
+
let VersionInfo = class VersionInfo extends IdEntity {
|
|
24
25
|
version = -1;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
};
|
|
27
|
+
__decorate([
|
|
28
|
+
Fields.number(),
|
|
29
|
+
__metadata("design:type", Object)
|
|
30
|
+
], VersionInfo.prototype, "version", void 0);
|
|
31
|
+
VersionInfo = __decorate([
|
|
32
|
+
Entity(migrationTableName)
|
|
33
|
+
], VersionInfo);
|
|
29
34
|
const steps = Object.entries(options.migrations).sort(([a], [b]) => parseInt(a) - parseInt(b));
|
|
30
35
|
if (dataProvider.ensureSchema) {
|
|
31
36
|
await dataProvider.ensureSchema([
|
|
@@ -32,7 +32,7 @@ export class PostgresDataProvider {
|
|
|
32
32
|
this.wrapIdentifier = options.wrapIdentifier;
|
|
33
33
|
if (!options?.wrapIdentifier && options?.caseInsensitiveIdentifiers)
|
|
34
34
|
this.wrapIdentifier = (name) => name;
|
|
35
|
-
if (options
|
|
35
|
+
if (options.orderByNullsFirst)
|
|
36
36
|
this.orderByNullsFirst = options.orderByNullsFirst;
|
|
37
37
|
if (options?.schema) {
|
|
38
38
|
this.pool = new PostgresSchemaWrapper(pool, options.schema);
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { dbNamesOf, shouldCreateEntity, shouldNotCreateField, } from '../src/filter/filter-consumer-bridge-to-sql-request.js';
|
|
2
|
+
import { remult as defaultRemult } from '../src/remult-proxy.js';
|
|
3
|
+
import { remultStatic } from '../src/remult-static.js';
|
|
2
4
|
import { isAutoIncrement } from '../src/remult3/RepositoryImplementation.js';
|
|
3
5
|
import { ValueConverters } from '../src/valueConverters.js';
|
|
4
6
|
export function postgresColumnSyntax(x, dbName) {
|
|
@@ -33,6 +35,9 @@ export function postgresColumnSyntax(x, dbName) {
|
|
|
33
35
|
result += ' varchar' + (x.allowNull ? '' : " default '' not null");
|
|
34
36
|
return result;
|
|
35
37
|
}
|
|
38
|
+
export async function verifyStructureOfAllEntities(db, remult) {
|
|
39
|
+
return await new PostgresSchemaBuilder(db).verifyStructureOfAllEntities(remult);
|
|
40
|
+
}
|
|
36
41
|
export class PostgresSchemaBuilder {
|
|
37
42
|
pool;
|
|
38
43
|
//@internal
|
|
@@ -84,6 +89,22 @@ export class PostgresSchemaBuilder {
|
|
|
84
89
|
// Should default to `public`
|
|
85
90
|
return 'public';
|
|
86
91
|
}
|
|
92
|
+
async verifyStructureOfAllEntities(remult) {
|
|
93
|
+
if (!remult) {
|
|
94
|
+
remult = defaultRemult;
|
|
95
|
+
}
|
|
96
|
+
const completed = new Set();
|
|
97
|
+
const entities = [];
|
|
98
|
+
for (const entityClass of [...remultStatic.allEntities].reverse()) {
|
|
99
|
+
let entity = remult.repo(entityClass).metadata;
|
|
100
|
+
let e = await dbNamesOf(entity, this.pool.wrapIdentifier);
|
|
101
|
+
if (completed.has(e.$entityName))
|
|
102
|
+
continue;
|
|
103
|
+
completed.add(e.$entityName);
|
|
104
|
+
entities.push(entity);
|
|
105
|
+
}
|
|
106
|
+
await this.ensureSchema(entities);
|
|
107
|
+
}
|
|
87
108
|
async ensureSchema(entities) {
|
|
88
109
|
for (const entity of entities) {
|
|
89
110
|
let e = await dbNamesOf(entity, this.pool.wrapIdentifier);
|
|
@@ -143,6 +164,26 @@ export class PostgresSchemaBuilder {
|
|
|
143
164
|
CREATE table ${this.schemaAndName(e)} (${result}\r\n)`;
|
|
144
165
|
return sql;
|
|
145
166
|
}
|
|
167
|
+
async addColumnIfNotExist(entity, c) {
|
|
168
|
+
let e = await dbNamesOf(entity, this.pool.wrapIdentifier);
|
|
169
|
+
if (shouldNotCreateField(c(entity), e))
|
|
170
|
+
return;
|
|
171
|
+
try {
|
|
172
|
+
let cmd = this.pool.createCommand();
|
|
173
|
+
const colName = e.$dbNameOf(c(entity));
|
|
174
|
+
if ((await cmd.execute(`SELECT 1 FROM information_schema.columns WHERE ` +
|
|
175
|
+
`${this.whereTableAndSchema(cmd, e)} ` +
|
|
176
|
+
`AND column_name=${cmd.param(colName.toLocaleLowerCase())}`)).rows.length == 0) {
|
|
177
|
+
let sql = await this.getAddColumnScript(entity, c(entity));
|
|
178
|
+
if (PostgresSchemaBuilder.logToConsole)
|
|
179
|
+
console.info(sql);
|
|
180
|
+
await this.pool.execute(sql);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
catch (err) {
|
|
184
|
+
console.error(err);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
146
187
|
async verifyAllColumns(entity) {
|
|
147
188
|
try {
|
|
148
189
|
let cmd = this.pool.createCommand();
|
package/esm/remult-hapi.js
CHANGED
package/esm/remult-hono.js
CHANGED
|
@@ -18,7 +18,6 @@ export function remultHono(options) {
|
|
|
18
18
|
}),
|
|
19
19
|
url: c.req.url,
|
|
20
20
|
on: (e, do1) => {
|
|
21
|
-
;
|
|
22
21
|
c['_tempOnClose'](() => do1());
|
|
23
22
|
// c.req.on('close', do1)
|
|
24
23
|
},
|
|
@@ -79,8 +78,7 @@ export function remultHono(options) {
|
|
|
79
78
|
res(streamSSE(c, (s) => {
|
|
80
79
|
sse = s;
|
|
81
80
|
return new Promise((res) => {
|
|
82
|
-
;
|
|
83
|
-
c['_tempOnClose'] = (x) => sse.onAbort(() => x());
|
|
81
|
+
c['_tempOnClose'] = (x) => sse.onAbort(() => x);
|
|
84
82
|
});
|
|
85
83
|
}));
|
|
86
84
|
},
|
package/esm/remult-knex/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CustomSqlFilterBuilder,
|
|
1
|
+
import { CustomSqlFilterBuilder, } from '../src/filter/filter-consumer-bridge-to-sql-request.js';
|
|
2
2
|
import { dbNamesOf, isDbReadonly, shouldCreateEntity, shouldNotCreateField, } from '../src/filter/filter-consumer-bridge-to-sql-request.js';
|
|
3
3
|
import { customDatabaseFilterToken, Filter, } from '../src/filter/filter-interfaces.js';
|
|
4
4
|
import { remult as remultContext } from '../src/remult-proxy.js';
|
|
@@ -6,7 +6,8 @@ import { getRepository, isAutoIncrement, } from '../src/remult3/RepositoryImplem
|
|
|
6
6
|
import { Sort } from '../src/sort.js';
|
|
7
7
|
import { ValueConverters } from '../src/valueConverters.js';
|
|
8
8
|
import { getRepositoryInternals } from '../src/remult3/repository-internals.js';
|
|
9
|
-
import {
|
|
9
|
+
import { remultStatic } from '../src/remult-static.js';
|
|
10
|
+
import { getRowAfterUpdate } from '../src/data-providers/sql-database.js';
|
|
10
11
|
export class KnexDataProvider {
|
|
11
12
|
knex;
|
|
12
13
|
constructor(knex) {
|
|
@@ -15,6 +16,7 @@ export class KnexDataProvider {
|
|
|
15
16
|
end() {
|
|
16
17
|
return this.knex.destroy();
|
|
17
18
|
}
|
|
19
|
+
/* @internal */
|
|
18
20
|
provideMigrationBuilder(builder) {
|
|
19
21
|
var sb = new KnexSchemaBuilder(this.knex);
|
|
20
22
|
return {
|
|
@@ -69,7 +71,7 @@ export class KnexDataProvider {
|
|
|
69
71
|
}
|
|
70
72
|
}
|
|
71
73
|
}
|
|
72
|
-
return new KnexEntityDataProvider(entity, this.knex, this.wrapIdentifier
|
|
74
|
+
return new KnexEntityDataProvider(entity, this.knex, this.wrapIdentifier);
|
|
73
75
|
}
|
|
74
76
|
async transaction(action) {
|
|
75
77
|
let t = await this.knex.transaction();
|
|
@@ -90,10 +92,8 @@ export class KnexDataProvider {
|
|
|
90
92
|
};
|
|
91
93
|
}
|
|
92
94
|
static async filterToRaw(entity, condition, wrapIdentifier) {
|
|
93
|
-
if (!wrapIdentifier)
|
|
94
|
-
wrapIdentifier = (x) => x;
|
|
95
95
|
const repo = getRepository(entity);
|
|
96
|
-
var b = new FilterConsumerBridgeToKnexRequest(await
|
|
96
|
+
var b = new FilterConsumerBridgeToKnexRequest(await dbNamesOf(repo.metadata, (x) => x), wrapIdentifier);
|
|
97
97
|
b._addWhere = false;
|
|
98
98
|
await (await getRepositoryInternals(repo)._translateWhereToFilter(condition)).__applyToConsumer(b);
|
|
99
99
|
let r = await b.resolveWhere();
|
|
@@ -109,15 +109,10 @@ class KnexEntityDataProvider {
|
|
|
109
109
|
entity;
|
|
110
110
|
knex;
|
|
111
111
|
rawSqlWrapIdentifier;
|
|
112
|
-
|
|
113
|
-
constructor(entity, knex, rawSqlWrapIdentifier, dp) {
|
|
112
|
+
constructor(entity, knex, rawSqlWrapIdentifier) {
|
|
114
113
|
this.entity = entity;
|
|
115
114
|
this.knex = knex;
|
|
116
115
|
this.rawSqlWrapIdentifier = rawSqlWrapIdentifier;
|
|
117
|
-
this.dp = dp;
|
|
118
|
-
}
|
|
119
|
-
async groupBy(options) {
|
|
120
|
-
return groupByImpl(options, await dbNamesOf(this.entity, this.dp.wrapIdentifier), this.dp.createCommand(), false, (limit, offset) => ' limit ' + limit + ' offset ' + offset);
|
|
121
116
|
}
|
|
122
117
|
async count(where) {
|
|
123
118
|
const e = await this.init();
|
|
@@ -144,10 +139,7 @@ class KnexEntityDataProvider {
|
|
|
144
139
|
if (x.isServerExpression) {
|
|
145
140
|
}
|
|
146
141
|
else {
|
|
147
|
-
|
|
148
|
-
if (x.options.sqlExpression)
|
|
149
|
-
name = this.knex.raw('?? as ' + x.key, [name]);
|
|
150
|
-
cols.push(name);
|
|
142
|
+
cols.push(e.$dbNameOf(x));
|
|
151
143
|
colKeys.push(x);
|
|
152
144
|
}
|
|
153
145
|
}
|
|
@@ -189,7 +181,7 @@ class KnexEntityDataProvider {
|
|
|
189
181
|
});
|
|
190
182
|
}
|
|
191
183
|
async init() {
|
|
192
|
-
const r = (await
|
|
184
|
+
const r = (await dbNamesOf(this.entity, (x) => x));
|
|
193
185
|
return {
|
|
194
186
|
$dbNameOf: (f) => {
|
|
195
187
|
let fm = f;
|
|
@@ -255,8 +247,8 @@ class KnexEntityDataProvider {
|
|
|
255
247
|
newId = result[0];
|
|
256
248
|
}
|
|
257
249
|
else {
|
|
258
|
-
let result = await insert.returning(this.entity.idMetadata.field.
|
|
259
|
-
newId = result[0]
|
|
250
|
+
let result = await insert.returning(this.entity.idMetadata.field.key);
|
|
251
|
+
newId = result[0].id;
|
|
260
252
|
}
|
|
261
253
|
return this.find({
|
|
262
254
|
where: new Filter((x) => x.isEqualTo(this.entity.idMetadata.field, newId)),
|
|
@@ -313,23 +305,6 @@ class FilterConsumerBridgeToKnexRequest {
|
|
|
313
305
|
}
|
|
314
306
|
})());
|
|
315
307
|
}
|
|
316
|
-
not(element) {
|
|
317
|
-
this.promises.push((async () => {
|
|
318
|
-
let f = new FilterConsumerBridgeToKnexRequest(this.innerNameProvider, this.rawSqlWrapIdentifier);
|
|
319
|
-
f._addWhere = false;
|
|
320
|
-
element.__applyToConsumer(f);
|
|
321
|
-
let where = await f.resolveWhere();
|
|
322
|
-
if (where.length > 0) {
|
|
323
|
-
this.result.push((b) => {
|
|
324
|
-
b.whereNot((b) => {
|
|
325
|
-
where.forEach((x) => x(b));
|
|
326
|
-
});
|
|
327
|
-
});
|
|
328
|
-
}
|
|
329
|
-
else
|
|
330
|
-
return; //empty or means all rows
|
|
331
|
-
})());
|
|
332
|
-
}
|
|
333
308
|
isNull(col) {
|
|
334
309
|
this.result.push((b) => b.whereNull(this.innerNameProvider.$dbNameOf(col)));
|
|
335
310
|
}
|
|
@@ -373,22 +348,6 @@ class FilterConsumerBridgeToKnexRequest {
|
|
|
373
348
|
"%')"));
|
|
374
349
|
this.promises.push((async () => { })());
|
|
375
350
|
}
|
|
376
|
-
startsWithCaseInsensitive(col, val) {
|
|
377
|
-
this.result.push((b) => b.whereRaw('lower (' +
|
|
378
|
-
b.client.ref(this.innerNameProvider.$dbNameOf(col)) +
|
|
379
|
-
") like lower ('" +
|
|
380
|
-
val.replace(/'/g, "''") +
|
|
381
|
-
"%')"));
|
|
382
|
-
this.promises.push((async () => { })());
|
|
383
|
-
}
|
|
384
|
-
endsWithCaseInsensitive(col, val) {
|
|
385
|
-
this.result.push((b) => b.whereRaw('lower (' +
|
|
386
|
-
b.client.ref(this.innerNameProvider.$dbNameOf(col)) +
|
|
387
|
-
") like lower ('%" +
|
|
388
|
-
val.replace(/'/g, "''") +
|
|
389
|
-
"')"));
|
|
390
|
-
this.promises.push((async () => { })());
|
|
391
|
-
}
|
|
392
351
|
add(col, val, operator) {
|
|
393
352
|
this.result.push((b) => b.where(this.innerNameProvider.$dbNameOf(col), operator, translateValueAndHandleArrayAndHandleArray(col, val)));
|
|
394
353
|
}
|
|
@@ -414,6 +373,12 @@ export class KnexSchemaBuilder {
|
|
|
414
373
|
knex;
|
|
415
374
|
//@internal
|
|
416
375
|
static logToConsole = true;
|
|
376
|
+
async verifyStructureOfAllEntities(remult) {
|
|
377
|
+
if (!remult)
|
|
378
|
+
remult = remultContext;
|
|
379
|
+
const entities = remultStatic.allEntities.map((x) => remult.repo(x).metadata);
|
|
380
|
+
await this.ensureSchema(entities);
|
|
381
|
+
}
|
|
417
382
|
async ensureSchema(entities) {
|
|
418
383
|
for (const entity of entities) {
|
|
419
384
|
let e = await dbNamesOf(entity, (x) => x);
|
package/esm/remult-mongo.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { ObjectId, } from 'mongodb';
|
|
2
2
|
import { Filter } from './index.js';
|
|
3
|
-
import { dbNamesOf
|
|
3
|
+
import { dbNamesOf } from './src/filter/filter-consumer-bridge-to-sql-request.js';
|
|
4
4
|
import { remult as remultContext } from './src/remult-proxy.js';
|
|
5
5
|
import { getRepository } from './src/remult3/RepositoryImplementation.js';
|
|
6
6
|
import { getRepositoryInternals } from './src/remult3/repository-internals.js';
|
|
7
7
|
import { getRowAfterUpdate } from './src/data-providers/sql-database.js';
|
|
8
|
-
import { GroupByCountMember, GroupByOperators } from './src/remult3/remult3.js';
|
|
9
8
|
export class MongoDataProvider {
|
|
10
9
|
db;
|
|
11
10
|
client;
|
|
@@ -23,12 +22,6 @@ export class MongoDataProvider {
|
|
|
23
22
|
throw 'the data provider is not a MongoDataProvider';
|
|
24
23
|
return { db: r.db, session: r.session };
|
|
25
24
|
}
|
|
26
|
-
async ensureSchema(entities) {
|
|
27
|
-
for (const entity of entities) {
|
|
28
|
-
const m = new MongoEntityDataProvider(this.db, entity, this.session);
|
|
29
|
-
await m.ensureSchema();
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
25
|
getEntityDataProvider(entity) {
|
|
33
26
|
return new MongoEntityDataProvider(this.db, entity, this.session);
|
|
34
27
|
}
|
|
@@ -57,7 +50,7 @@ export class MongoDataProvider {
|
|
|
57
50
|
}
|
|
58
51
|
static async filterToRaw(entity, condition) {
|
|
59
52
|
const repo = getRepository(entity);
|
|
60
|
-
var b = new FilterConsumerBridgeToMongo(await
|
|
53
|
+
var b = new FilterConsumerBridgeToMongo(await dbNamesOf(repo.metadata));
|
|
61
54
|
b._addWhere = false;
|
|
62
55
|
await (await getRepositoryInternals(repo)._translateWhereToFilter(condition)).__applyToConsumer(b);
|
|
63
56
|
let r = await b.resolveWhere();
|
|
@@ -72,25 +65,6 @@ class MongoEntityDataProvider {
|
|
|
72
65
|
db;
|
|
73
66
|
entity;
|
|
74
67
|
session;
|
|
75
|
-
async ensureSchema() {
|
|
76
|
-
const { collection, e } = await this.collection();
|
|
77
|
-
if (!(await this.db.collections()).find((x) => x.collectionName == e.$entityName)) {
|
|
78
|
-
await this.db.createCollection(e.$entityName);
|
|
79
|
-
if (this.entity.idMetadata.field &&
|
|
80
|
-
e.$dbNameOf(this.entity.idMetadata.field) != '_id') {
|
|
81
|
-
const index = {};
|
|
82
|
-
for (const f of this.entity.idMetadata.fields) {
|
|
83
|
-
index[e.$dbNameOf(f)] = 1;
|
|
84
|
-
}
|
|
85
|
-
try {
|
|
86
|
-
await collection.createIndex(index, { unique: true });
|
|
87
|
-
}
|
|
88
|
-
catch (err) {
|
|
89
|
-
throw err;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
68
|
constructor(db, entity, session) {
|
|
95
69
|
this.db = db;
|
|
96
70
|
this.entity = entity;
|
|
@@ -100,14 +74,6 @@ class MongoEntityDataProvider {
|
|
|
100
74
|
let result = {};
|
|
101
75
|
for (const col of this.entity.fields) {
|
|
102
76
|
let val = row[nameProvider.$dbNameOf(col)];
|
|
103
|
-
if (val === undefined) {
|
|
104
|
-
if (!col.allowNull) {
|
|
105
|
-
if (col.valueType === String)
|
|
106
|
-
val = '';
|
|
107
|
-
}
|
|
108
|
-
else
|
|
109
|
-
val = null;
|
|
110
|
-
}
|
|
111
77
|
if (isNull(val))
|
|
112
78
|
val = null;
|
|
113
79
|
result[col.key] = fromDb(col, val);
|
|
@@ -131,93 +97,6 @@ class MongoEntityDataProvider {
|
|
|
131
97
|
let w = await x.resolveWhere();
|
|
132
98
|
return await collection.countDocuments(w, { session: this.session });
|
|
133
99
|
}
|
|
134
|
-
async groupBy(options) {
|
|
135
|
-
let { collection, e } = await this.collection();
|
|
136
|
-
let x = new FilterConsumerBridgeToMongo(e);
|
|
137
|
-
const pipeLine = [];
|
|
138
|
-
if (options?.where) {
|
|
139
|
-
options.where.__applyToConsumer(x);
|
|
140
|
-
let where = await x.resolveWhere();
|
|
141
|
-
pipeLine.push({ $match: where });
|
|
142
|
-
}
|
|
143
|
-
const processResultRow = [];
|
|
144
|
-
const $group = {
|
|
145
|
-
__count: { $sum: 1 },
|
|
146
|
-
};
|
|
147
|
-
processResultRow.push((mongoRow, resultRow) => {
|
|
148
|
-
resultRow[GroupByCountMember] = mongoRow.__count;
|
|
149
|
-
});
|
|
150
|
-
pipeLine.push({ $group });
|
|
151
|
-
const $addFields = {};
|
|
152
|
-
pipeLine.push({ $addFields });
|
|
153
|
-
if (options?.group) {
|
|
154
|
-
$group._id = {};
|
|
155
|
-
for (const element of options.group) {
|
|
156
|
-
const name = e.$dbNameOf(element);
|
|
157
|
-
$group._id[name] = `$${name}`;
|
|
158
|
-
processResultRow.push((mongoRow, resultRow) => {
|
|
159
|
-
resultRow[element.key] = element.valueConverter.fromDb(mongoRow._id[name]);
|
|
160
|
-
});
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
else {
|
|
164
|
-
$group._id = null;
|
|
165
|
-
}
|
|
166
|
-
for (const operator of GroupByOperators) {
|
|
167
|
-
if (options?.[operator]) {
|
|
168
|
-
for (const element of options[operator]) {
|
|
169
|
-
const name = e.$dbNameOf(element) + '_' + operator;
|
|
170
|
-
if (operator === 'distinctCount') {
|
|
171
|
-
$group[name + '_temp'] = { $addToSet: `$${e.$dbNameOf(element)}` };
|
|
172
|
-
$addFields[name] = { $size: `$${name + '_temp'}` };
|
|
173
|
-
}
|
|
174
|
-
else
|
|
175
|
-
$group[name] = { ['$' + operator]: `$${e.$dbNameOf(element)}` };
|
|
176
|
-
processResultRow.push((mongoRow, resultRow) => {
|
|
177
|
-
resultRow[element.key] = {
|
|
178
|
-
...resultRow[element.key],
|
|
179
|
-
[operator]: mongoRow[name],
|
|
180
|
-
};
|
|
181
|
-
});
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
if (options?.orderBy) {
|
|
186
|
-
let sort = {};
|
|
187
|
-
for (const x of options.orderBy) {
|
|
188
|
-
const direction = x.isDescending ? -1 : 1;
|
|
189
|
-
switch (x.operation) {
|
|
190
|
-
case 'count':
|
|
191
|
-
sort['__count'] = direction;
|
|
192
|
-
break;
|
|
193
|
-
case undefined:
|
|
194
|
-
sort['_id.' + e.$dbNameOf(x.field)] = direction;
|
|
195
|
-
break;
|
|
196
|
-
default:
|
|
197
|
-
sort[e.$dbNameOf(x.field) + '_' + x.operation] = direction;
|
|
198
|
-
break;
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
pipeLine.push({ $sort: sort });
|
|
202
|
-
}
|
|
203
|
-
if (options?.limit) {
|
|
204
|
-
pipeLine.push({ $limit: options.limit });
|
|
205
|
-
if (options.page) {
|
|
206
|
-
pipeLine.push({ $skip: (options.page - 1) * options.limit });
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
const r = await collection
|
|
210
|
-
.aggregate(pipeLine, { session: this.session })
|
|
211
|
-
.toArray();
|
|
212
|
-
const r2 = r.map((x) => {
|
|
213
|
-
let resultRow = {};
|
|
214
|
-
for (const f of processResultRow) {
|
|
215
|
-
f(x, resultRow);
|
|
216
|
-
}
|
|
217
|
-
return resultRow;
|
|
218
|
-
});
|
|
219
|
-
return r2;
|
|
220
|
-
}
|
|
221
100
|
async find(options) {
|
|
222
101
|
let { collection, e } = await this.collection();
|
|
223
102
|
let x = new FilterConsumerBridgeToMongo(e);
|
|
@@ -266,9 +145,7 @@ class MongoEntityDataProvider {
|
|
|
266
145
|
const { e, collection } = await this.collection();
|
|
267
146
|
let f = new FilterConsumerBridgeToMongo(e);
|
|
268
147
|
Filter.fromEntityFilter(this.entity, this.entity.idMetadata.getIdFilter(id)).__applyToConsumer(f);
|
|
269
|
-
|
|
270
|
-
session: this.session,
|
|
271
|
-
});
|
|
148
|
+
collection.deleteOne(await f.resolveWhere(), { session: this.session });
|
|
272
149
|
}
|
|
273
150
|
async insert(data) {
|
|
274
151
|
let { collection, e } = await this.collection();
|
|
@@ -326,19 +203,6 @@ class FilterConsumerBridgeToMongo {
|
|
|
326
203
|
}));
|
|
327
204
|
})());
|
|
328
205
|
}
|
|
329
|
-
not(element) {
|
|
330
|
-
this.promises.push((async () => {
|
|
331
|
-
let f = new FilterConsumerBridgeToMongo(this.nameProvider);
|
|
332
|
-
f._addWhere = false;
|
|
333
|
-
element.__applyToConsumer(f);
|
|
334
|
-
let where = await f.resolveWhere();
|
|
335
|
-
if (where) {
|
|
336
|
-
this.result.push(() => ({
|
|
337
|
-
$nor: [where],
|
|
338
|
-
}));
|
|
339
|
-
}
|
|
340
|
-
})());
|
|
341
|
-
}
|
|
342
206
|
isNull(col) {
|
|
343
207
|
this.add(col, NULL, '$eq');
|
|
344
208
|
}
|
|
@@ -383,12 +247,6 @@ class FilterConsumerBridgeToMongo {
|
|
|
383
247
|
},
|
|
384
248
|
}));
|
|
385
249
|
}
|
|
386
|
-
startsWithCaseInsensitive(col, val) {
|
|
387
|
-
this.add(col, `^${val}`, '$regex', { $options: 'i' });
|
|
388
|
-
}
|
|
389
|
-
endsWithCaseInsensitive(col, val) {
|
|
390
|
-
this.add(col, `${val}$`, '$regex', { $options: 'i' });
|
|
391
|
-
}
|
|
392
250
|
add(col, val, operator, moreOptions) {
|
|
393
251
|
this.result.push(() => ({
|
|
394
252
|
[this.nameProvider.$dbNameOf(col)]: {
|