remult 0.27.24 → 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.
Files changed (182) hide show
  1. package/README.md +0 -2
  2. package/SseSubscriptionServer.d.ts +4 -3
  3. package/assign.js +2 -1
  4. package/esm/graphql.js +3 -3
  5. package/esm/index.js +1 -2
  6. package/esm/internals.js +1 -2
  7. package/esm/live-query/data-provider-live-query-storage.js +2 -0
  8. package/esm/migrations/migrate.js +11 -6
  9. package/esm/postgres/postgres-data-provider.js +1 -1
  10. package/esm/postgres/schema-builder.js +41 -0
  11. package/esm/remult-hapi.js +1 -1
  12. package/esm/remult-hono.js +1 -3
  13. package/esm/remult-knex/index.js +17 -52
  14. package/esm/remult-mongo.js +3 -145
  15. package/esm/remult-nuxt.js +1 -1
  16. package/esm/remult-sqlite-core.js +9 -39
  17. package/esm/remult-sqlite3.js +1 -9
  18. package/esm/remult-sveltekit.js +11 -4
  19. package/esm/server/get-remult-admin-html.js +1 -1
  20. package/esm/server/index.js +2 -4
  21. package/esm/server/initAsyncHooks.js +51 -3
  22. package/esm/server/remult-admin.js +28 -38
  23. package/esm/server/remult-api-server.js +68 -84
  24. package/esm/src/CompoundIdField.js +9 -9
  25. package/esm/src/buildRestDataProvider.js +2 -2
  26. package/esm/src/column.js +4 -3
  27. package/esm/src/context.js +3 -21
  28. package/esm/src/data-api.js +72 -194
  29. package/esm/src/data-interfaces.js +0 -10
  30. package/esm/src/data-providers/array-entity-data-provider.js +11 -224
  31. package/esm/src/data-providers/in-memory-database.js +1 -1
  32. package/esm/src/data-providers/json-data-provider.js +2 -7
  33. package/esm/src/data-providers/json-entity-opfs-storage.js +5 -9
  34. package/esm/src/data-providers/rest-data-provider.js +13 -66
  35. package/esm/src/data-providers/sql-database.js +57 -191
  36. package/esm/src/data-providers/web-sql-data-provider.js +140 -0
  37. package/esm/src/filter/filter-consumer-bridge-to-sql-request.js +15 -51
  38. package/esm/src/filter/filter-interfaces.js +1 -104
  39. package/esm/src/live-query/LiveQueryClient.js +1 -0
  40. package/esm/src/live-query/SubscriptionServer.js +2 -2
  41. package/esm/src/remult-proxy.js +5 -23
  42. package/esm/src/remult-static.js +0 -2
  43. package/esm/src/remult3/Fields.js +6 -26
  44. package/esm/src/remult3/RepositoryImplementation.js +292 -436
  45. package/esm/src/remult3/__updateEntityBasedOnWhere.js +0 -3
  46. package/esm/src/remult3/entity.js +6 -10
  47. package/esm/src/remult3/relation-loader.js +2 -2
  48. package/esm/src/remult3/relationInfoMember.js +2 -4
  49. package/esm/src/remult3/remult3.js +47 -74
  50. package/esm/src/server-action.js +15 -43
  51. package/esm/src/sort.js +13 -18
  52. package/esm/src/validators.js +4 -74
  53. package/esm/src/valueConverters.js +2 -2
  54. package/graphql.js +6 -5
  55. package/index.d.ts +3 -3
  56. package/index.js +4 -6
  57. package/internals.d.ts +3 -4
  58. package/internals.js +1 -5
  59. package/live-query/data-provider-live-query-storage.js +8 -6
  60. package/migrations/compare-migration-snapshots.js +49 -48
  61. package/migrations/generate-migrations.js +2 -1
  62. package/migrations/migrate.js +10 -5
  63. package/migrations/migration-types.d.ts +1 -1
  64. package/migrations/migration-types.js +4 -4
  65. package/migrations/update-migrations-ts-file.js +2 -1
  66. package/myLog.js +2 -1
  67. package/package.json +1 -6
  68. package/postgres/postgres-data-provider.d.ts +2 -2
  69. package/postgres/postgres-data-provider.js +6 -6
  70. package/postgres/schema-builder.d.ts +5 -1
  71. package/postgres/schema-builder.js +120 -17
  72. package/remult-express.js +3 -4
  73. package/remult-fastify.js +3 -4
  74. package/remult-fresh.js +2 -1
  75. package/remult-hapi.js +4 -5
  76. package/remult-hono.js +3 -6
  77. package/remult-knex/index.d.ts +5 -4
  78. package/remult-knex/index.js +31 -87
  79. package/remult-mongo.d.ts +2 -3
  80. package/remult-mongo.js +26 -312
  81. package/remult-next.d.ts +6 -5
  82. package/remult-next.js +6 -11
  83. package/remult-nuxt.js +3 -2
  84. package/remult-solid-start.js +2 -1
  85. package/remult-sqlite-core.d.ts +3 -6
  86. package/remult-sqlite-core.js +33 -122
  87. package/remult-sqlite3.d.ts +0 -2
  88. package/remult-sqlite3.js +1 -20
  89. package/remult-sveltekit.d.ts +1 -1
  90. package/remult-sveltekit.js +36 -15
  91. package/remult-turso.d.ts +1 -1
  92. package/server/JsonEntityFileStorage.d.ts +1 -1
  93. package/server/get-remult-admin-html.js +3 -2
  94. package/server/index.d.ts +0 -1
  95. package/server/index.js +3 -6
  96. package/server/initAsyncHooks.d.ts +13 -7
  97. package/server/initAsyncHooks.js +73 -5
  98. package/server/initDataProvider.js +2 -1
  99. package/server/initDataProviderOrJson.d.ts +1 -1
  100. package/server/initDataProviderOrJson.js +2 -1
  101. package/server/remult-admin.d.ts +1 -12
  102. package/server/remult-admin.js +30 -39
  103. package/server/remult-api-server.d.ts +22 -23
  104. package/server/remult-api-server.js +78 -108
  105. package/src/CompoundIdField.d.ts +2 -2
  106. package/src/CompoundIdField.js +0 -9
  107. package/src/buildRestDataProvider.d.ts +1 -1
  108. package/src/buildRestDataProvider.js +10 -10
  109. package/src/column-interfaces.d.ts +7 -6
  110. package/src/column-interfaces.js +2 -1
  111. package/src/column.d.ts +4 -4
  112. package/src/column.js +6 -5
  113. package/src/context.d.ts +4 -25
  114. package/src/context.js +8 -36
  115. package/src/data-api.d.ts +9 -16
  116. package/src/data-api.js +121 -365
  117. package/src/data-interfaces.d.ts +3 -34
  118. package/src/data-interfaces.js +2 -13
  119. package/src/data-providers/array-entity-data-provider.d.ts +2 -3
  120. package/src/data-providers/array-entity-data-provider.js +51 -399
  121. package/src/data-providers/in-memory-database.js +1 -1
  122. package/src/data-providers/json-data-provider.d.ts +2 -3
  123. package/src/data-providers/json-data-provider.js +2 -10
  124. package/src/data-providers/json-entity-opfs-storage.js +16 -30
  125. package/src/data-providers/rest-data-provider.d.ts +5 -17
  126. package/src/data-providers/rest-data-provider.js +29 -115
  127. package/src/data-providers/sql-database.d.ts +3 -54
  128. package/src/data-providers/sql-database.js +164 -380
  129. package/src/data-providers/web-sql-data-provider.d.ts +20 -0
  130. package/src/data-providers/web-sql-data-provider.js +228 -0
  131. package/src/entity.d.ts +5 -5
  132. package/src/filter/filter-consumer-bridge-to-sql-request.d.ts +4 -8
  133. package/src/filter/filter-consumer-bridge-to-sql-request.js +32 -96
  134. package/src/filter/filter-interfaces.d.ts +2 -13
  135. package/src/filter/filter-interfaces.js +24 -175
  136. package/src/isOfType.js +3 -2
  137. package/src/live-query/SubscriptionServer.js +97 -95
  138. package/src/remult-proxy.js +12 -39
  139. package/src/remult-static.d.ts +2 -3
  140. package/src/remult-static.js +4 -8
  141. package/src/remult3/Fields.d.ts +18 -18
  142. package/src/remult3/Fields.js +12 -33
  143. package/src/remult3/RepositoryImplementation.d.ts +52 -71
  144. package/src/remult3/RepositoryImplementation.js +803 -972
  145. package/src/remult3/__updateEntityBasedOnWhere.js +2 -4
  146. package/src/remult3/addValidator.d.ts +1 -1
  147. package/src/remult3/addValidator.js +2 -1
  148. package/src/remult3/classDescribers.d.ts +4 -4
  149. package/src/remult3/classDescribers.js +4 -3
  150. package/src/remult3/columnInfo.d.ts +1 -1
  151. package/src/remult3/entity.js +9 -11
  152. package/src/remult3/getEntityRef.js +4 -4
  153. package/src/remult3/relation-loader.d.ts +1 -1
  154. package/src/remult3/relationInfoMember.d.ts +5 -5
  155. package/src/remult3/relationInfoMember.js +7 -8
  156. package/src/remult3/remult3.d.ts +42 -535
  157. package/src/remult3/remult3.js +48 -75
  158. package/src/remult3/repository-internals.d.ts +3 -3
  159. package/src/remult3/repository-internals.js +2 -2
  160. package/src/server-action.d.ts +3 -27
  161. package/src/server-action.js +61 -103
  162. package/src/sort.d.ts +1 -3
  163. package/src/sort.js +12 -19
  164. package/src/sql-command.d.ts +1 -2
  165. package/src/validators.d.ts +2 -87
  166. package/src/validators.js +14 -94
  167. package/src/valueConverters.js +2 -3
  168. package/esm/remult-duckdb.js +0 -111
  169. package/esm/server/test-api-data-provider.js +0 -83
  170. package/esm/src/data-providers/json-entity-indexed-db-data-provider.js +0 -55
  171. package/esm/src/data-providers/sql-relations.js +0 -125
  172. package/esm/src/remult3/QueryResultImpl.js +0 -147
  173. package/remult-duckdb.d.ts +0 -9
  174. package/remult-duckdb.js +0 -150
  175. package/server/test-api-data-provider.d.ts +0 -3
  176. package/server/test-api-data-provider.js +0 -130
  177. package/src/data-providers/json-entity-indexed-db-data-provider.d.ts +0 -9
  178. package/src/data-providers/json-entity-indexed-db-data-provider.js +0 -97
  179. package/src/data-providers/sql-relations.d.ts +0 -40
  180. package/src/data-providers/sql-relations.js +0 -167
  181. package/src/remult3/QueryResultImpl.d.ts +0 -16
  182. 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?: ((channel: string, remult: Remult) => boolean) | undefined);
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?: NodeJS.Timeout;
18
+ timeOutRef: NodeJS.Timeout;
18
19
  close(): void;
19
20
  closed: boolean;
20
21
  write(eventData: string, eventType?: string): void;
21
- connectionId: string;
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 = 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.httpPost({
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
- }, { get: () => undefined }, arg1.input, undefined);
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 })?.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, fieldOptionsEnricher, } from './src/remult3/RepositoryImplementation.js';
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 { Entity, IdEntity, Fields, remult, Remult, describeClass, } from '../index.js';
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
- describeClass(VersionInfo, Entity(migrationTableName), {
27
- version: Fields.integer(),
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?.orderByNullsFirst)
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();
@@ -33,7 +33,7 @@ export function remultHapi(options) {
33
33
  res(h.response(html).code(status));
34
34
  },
35
35
  json(data) {
36
- res(h.response(data === null ? 'null' : data).code(status));
36
+ res(h.response(data).code(status));
37
37
  },
38
38
  write(data) {
39
39
  stream.write(data);
@@ -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
  },
@@ -1,4 +1,4 @@
1
- import { CustomSqlFilterBuilder, dbNamesOfWithForceSqlExpression, } from '../src/filter/filter-consumer-bridge-to-sql-request.js';
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 { groupByImpl, getRowAfterUpdate, } from '../src/data-providers/sql-database.js';
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, this);
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 dbNamesOfWithForceSqlExpression(repo.metadata, wrapIdentifier), wrapIdentifier ?? wrapIdentifier);
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
- dp;
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
- let name = e.$dbNameOf(x);
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 dbNamesOfWithForceSqlExpression(this.entity, (x) => x));
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.dbName);
259
- newId = result[0][this.entity.idMetadata.field.dbName];
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);
@@ -1,11 +1,10 @@
1
1
  import { ObjectId, } from 'mongodb';
2
2
  import { Filter } from './index.js';
3
- import { dbNamesOf, dbNamesOfWithForceSqlExpression, } from './src/filter/filter-consumer-bridge-to-sql-request.js';
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 dbNamesOfWithForceSqlExpression(repo.metadata));
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
- await collection.deleteOne(await f.resolveWhere(), {
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)]: {
@@ -41,7 +41,7 @@ export function remultNuxt(options) {
41
41
  setResponseStatus(event, r.statusCode);
42
42
  if (r.html)
43
43
  return r.html;
44
- return r.data == null ? 'null' : r.data;
44
+ return r.data;
45
45
  }
46
46
  };
47
47
  return Object.assign(handler, {