remult 0.27.11 → 0.27.13

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 (45) hide show
  1. package/esm/index.js +0 -1
  2. package/esm/live-query/data-provider-live-query-storage.js +0 -2
  3. package/esm/postgres/schema-builder.js +0 -41
  4. package/esm/remult-duckdb.js +7 -12
  5. package/esm/remult-knex/index.js +0 -7
  6. package/esm/remult-mongo.js +33 -0
  7. package/esm/remult-sqlite-core.js +33 -5
  8. package/esm/server/get-remult-admin-html.js +1 -1
  9. package/esm/server/remult-admin.js +2 -0
  10. package/esm/server/remult-api-server.js +4 -5
  11. package/esm/src/data-providers/array-entity-data-provider.js +26 -11
  12. package/esm/src/data-providers/in-memory-database.js +1 -1
  13. package/esm/src/data-providers/sql-database.js +2 -25
  14. package/esm/src/filter/filter-interfaces.js +1 -0
  15. package/esm/src/remult3/RepositoryImplementation.js +15 -4
  16. package/esm/src/remult3/remult3.js +0 -3
  17. package/index.d.ts +0 -1
  18. package/index.js +1 -3
  19. package/live-query/data-provider-live-query-storage.js +0 -2
  20. package/package.json +1 -1
  21. package/postgres/schema-builder.d.ts +0 -4
  22. package/postgres/schema-builder.js +15 -118
  23. package/remult-duckdb.d.ts +1 -1
  24. package/remult-duckdb.js +7 -12
  25. package/remult-knex/index.d.ts +0 -2
  26. package/remult-knex/index.js +0 -18
  27. package/remult-mongo.d.ts +2 -1
  28. package/remult-mongo.js +128 -37
  29. package/remult-sqlite-core.d.ts +2 -1
  30. package/remult-sqlite-core.js +116 -29
  31. package/server/get-remult-admin-html.js +1 -1
  32. package/server/remult-admin.d.ts +4 -0
  33. package/server/remult-admin.js +12 -10
  34. package/server/remult-api-server.js +14 -14
  35. package/src/data-providers/array-entity-data-provider.js +82 -37
  36. package/src/data-providers/in-memory-database.js +1 -1
  37. package/src/data-providers/sql-database.js +10 -69
  38. package/src/entity.d.ts +4 -4
  39. package/src/filter/filter-interfaces.js +1 -0
  40. package/src/remult3/RepositoryImplementation.js +15 -4
  41. package/src/remult3/remult3.d.ts +17 -2
  42. package/src/remult3/remult3.js +0 -3
  43. package/esm/src/data-providers/web-sql-data-provider.js +0 -140
  44. package/src/data-providers/web-sql-data-provider.d.ts +0 -20
  45. package/src/data-providers/web-sql-data-provider.js +0 -228
package/esm/index.js CHANGED
@@ -7,7 +7,6 @@ export { IdEntity } from './src/remult3/IdEntity.js';
7
7
  export { describeClass, describeBackendMethods, describeEntity, } from './src/remult3/classDescribers.js';
8
8
  export { RestDataProvider } from './src/data-providers/rest-data-provider.js'; //V
9
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
10
  export { SqlDatabase } from './src/data-providers/sql-database.js'; //V
12
11
  export { CustomSqlFilterBuilder, dbNamesOf, } from './src/filter/filter-consumer-bridge-to-sql-request.js';
13
12
  export { JsonDataProvider, } from './src/data-providers/json-data-provider.js'; //V
@@ -3,7 +3,6 @@ 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';
7
6
  import { initDataProviderOrJson } from '../server/initDataProviderOrJson.js';
8
7
  export class DataProviderLiveQueryStorage {
9
8
  repo;
@@ -90,4 +89,3 @@ LiveQueryStorageEntity = __decorate([
90
89
  /*@internal */
91
90
  ], LiveQueryStorageEntity);
92
91
  export { LiveQueryStorageEntity };
93
- remultStatic.allEntities.splice(remultStatic.allEntities.indexOf(LiveQueryStorageEntity), 1);
@@ -1,6 +1,4 @@
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';
4
2
  import { isAutoIncrement } from '../src/remult3/RepositoryImplementation.js';
5
3
  import { ValueConverters } from '../src/valueConverters.js';
6
4
  export function postgresColumnSyntax(x, dbName) {
@@ -35,9 +33,6 @@ export function postgresColumnSyntax(x, dbName) {
35
33
  result += ' varchar' + (x.allowNull ? '' : " default '' not null");
36
34
  return result;
37
35
  }
38
- export async function verifyStructureOfAllEntities(db, remult) {
39
- return await new PostgresSchemaBuilder(db).verifyStructureOfAllEntities(remult);
40
- }
41
36
  export class PostgresSchemaBuilder {
42
37
  pool;
43
38
  //@internal
@@ -89,22 +84,6 @@ export class PostgresSchemaBuilder {
89
84
  // Should default to `public`
90
85
  return 'public';
91
86
  }
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
- }
108
87
  async ensureSchema(entities) {
109
88
  for (const entity of entities) {
110
89
  let e = await dbNamesOf(entity, this.pool.wrapIdentifier);
@@ -164,26 +143,6 @@ export class PostgresSchemaBuilder {
164
143
  CREATE table ${this.schemaAndName(e)} (${result}\r\n)`;
165
144
  return sql;
166
145
  }
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
- }
187
146
  async verifyAllColumns(entity) {
188
147
  try {
189
148
  let cmd = this.pool.createCommand();
@@ -33,13 +33,13 @@ export class DuckDBDataProvider extends SqliteCoreDataProvider {
33
33
  .join(',')})`;
34
34
  sql +=
35
35
  'create table if not exists ' + e.$entityName + ' (' + result + '\r\n)';
36
- return sql;
36
+ return [sql];
37
37
  }
38
38
  addColumnSqlSyntax(x, dbName, isAlterColumn) {
39
39
  let result = dbName;
40
40
  var allowNull = x.allowNull;
41
- if (allowNull && isAlterColumn) {
42
- allowNull = false;
41
+ if (!allowNull && isAlterColumn) {
42
+ allowNull = true;
43
43
  console.log('DuckDB does not support altering columns to allow null on existing tables');
44
44
  }
45
45
  if (x.valueType == Number) {
@@ -49,7 +49,7 @@ export class DuckDBDataProvider extends SqliteCoreDataProvider {
49
49
  result +=
50
50
  ' ' +
51
51
  x.valueConverter.fieldTypeInDb +
52
- (x.allowNull || isAlterColumn ? '' : ' default 0 not null');
52
+ (allowNull ? '' : ' default 0 not null');
53
53
  }
54
54
  else if (x.valueType == Date) {
55
55
  if (!x.valueConverter.fieldTypeInDb)
@@ -61,20 +61,15 @@ export class DuckDBDataProvider extends SqliteCoreDataProvider {
61
61
  result += ' ' + x.valueConverter.fieldTypeInDb;
62
62
  }
63
63
  else if (x.valueType == Boolean)
64
- result +=
65
- ' boolean' +
66
- (x.allowNull || isAlterColumn ? '' : ' default false not null');
64
+ result += ' boolean' + (allowNull ? '' : ' default false not null');
67
65
  else if (x.valueConverter.fieldTypeInDb) {
68
66
  result += ' ' + x.valueConverter.fieldTypeInDb;
69
- if (!(x.allowNull || isAlterColumn) &&
70
- x.valueConverter.fieldTypeInDb == 'integer') {
67
+ if (!allowNull && x.valueConverter.fieldTypeInDb == 'integer') {
71
68
  result += ' default 0 not null';
72
69
  }
73
70
  }
74
71
  else
75
- result +=
76
- ' varchar' +
77
- (x.allowNull || isAlterColumn ? '' : " default '' not null");
72
+ result += ' varchar' + (allowNull ? '' : " default '' not null");
78
73
  return result;
79
74
  }
80
75
  }
@@ -6,7 +6,6 @@ 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 { remultStatic } from '../src/remult-static.js';
10
9
  import { groupByImpl, getRowAfterUpdate, } from '../src/data-providers/sql-database.js';
11
10
  export class KnexDataProvider {
12
11
  knex;
@@ -415,12 +414,6 @@ export class KnexSchemaBuilder {
415
414
  knex;
416
415
  //@internal
417
416
  static logToConsole = true;
418
- async verifyStructureOfAllEntities(remult) {
419
- if (!remult)
420
- remult = remultContext;
421
- const entities = remultStatic.allEntities.map((x) => remult.repo(x).metadata);
422
- await this.ensureSchema(entities);
423
- }
424
417
  async ensureSchema(entities) {
425
418
  for (const entity of entities) {
426
419
  let e = await dbNamesOf(entity, (x) => x);
@@ -23,6 +23,12 @@ export class MongoDataProvider {
23
23
  throw 'the data provider is not a MongoDataProvider';
24
24
  return { db: r.db, session: r.session };
25
25
  }
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
+ }
26
32
  getEntityDataProvider(entity) {
27
33
  return new MongoEntityDataProvider(this.db, entity, this.session);
28
34
  }
@@ -66,6 +72,25 @@ class MongoEntityDataProvider {
66
72
  db;
67
73
  entity;
68
74
  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
+ }
69
94
  constructor(db, entity, session) {
70
95
  this.db = db;
71
96
  this.entity = entity;
@@ -75,6 +100,14 @@ class MongoEntityDataProvider {
75
100
  let result = {};
76
101
  for (const col of this.entity.fields) {
77
102
  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
+ }
78
111
  if (isNull(val))
79
112
  val = null;
80
113
  result[col.key] = fromDb(col, val);
@@ -21,7 +21,7 @@ export class SqliteCoreDataProvider {
21
21
  let self = this;
22
22
  return {
23
23
  createTable: async (entity) => {
24
- builder.addSql(await self.getCreateTableSql(entity));
24
+ await (await self.getCreateTableSql(entity)).map(builder.addSql);
25
25
  },
26
26
  addColumn: async (entity, field) => {
27
27
  let e = await dbNamesOf(entity, this.wrapIdentifier);
@@ -45,6 +45,27 @@ export class SqliteCoreDataProvider {
45
45
  async ensureSchema(entities) {
46
46
  for (const entity of entities) {
47
47
  await this.createTableIfNotExist(entity);
48
+ await this.verifyAllColumns(entity);
49
+ }
50
+ }
51
+ async verifyAllColumns(entity) {
52
+ try {
53
+ let cmd = this.createCommand();
54
+ let e = await dbNamesOf(entity, this.wrapIdentifier);
55
+ let cols = (await cmd.execute(`PRAGMA table_info(${e.$entityName})`)).rows.map((x) => this.wrapIdentifier(x.name.toLocaleLowerCase()));
56
+ for (const col of entity.fields) {
57
+ if (!shouldNotCreateField(col, e)) {
58
+ let colName = e.$dbNameOf(col).toLocaleLowerCase();
59
+ if (!cols.includes(colName)) {
60
+ let sql = `ALTER table ${e.$entityName} ` +
61
+ `add column ${this.addColumnSqlSyntax(col, e.$dbNameOf(col), true)}`;
62
+ await this.createCommand().execute(sql);
63
+ }
64
+ }
65
+ }
66
+ }
67
+ catch (err) {
68
+ console.error(err);
48
69
  }
49
70
  }
50
71
  async dropTable(entity) {
@@ -73,9 +94,9 @@ export class SqliteCoreDataProvider {
73
94
  }
74
95
  async createTableIfNotExist(entity) {
75
96
  let sql = await this.getCreateTableSql(entity);
76
- if (SqlDatabase.LogToConsole)
77
- console.log(sql);
78
- await this.createCommand().execute(sql);
97
+ for (const element of sql) {
98
+ await this.createCommand().execute(element);
99
+ }
79
100
  }
80
101
  supportsJsonColumnType;
81
102
  async getCreateTableSql(entity) {
@@ -99,7 +120,14 @@ export class SqliteCoreDataProvider {
99
120
  }
100
121
  }
101
122
  }
102
- let sql = 'create table if not exists ' + e.$entityName + ' (' + result + '\r\n)';
123
+ let sql = [
124
+ 'create table if not exists ' + e.$entityName + ' (' + result + '\r\n)',
125
+ ];
126
+ if (entity.idMetadata.fields.length > 1) {
127
+ sql.push(`create unique index ${this.wrapIdentifier(entity.dbName + '_primary_key')} on ${e.$entityName} (${entity.idMetadata.fields
128
+ .map((x) => e.$dbNameOf(x))
129
+ .join(',')})`);
130
+ }
103
131
  return sql;
104
132
  }
105
133
  wrapIdentifier(name) {