remult 0.23.0-exp.3 → 0.23.0-exp.30

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 (104) hide show
  1. package/README.md +27 -27
  2. package/esm/graphql.js +19 -2
  3. package/esm/index.d.ts +13 -1
  4. package/esm/index.js +12 -0
  5. package/esm/internals.d.ts +2 -1
  6. package/esm/internals.js +1 -1
  7. package/esm/postgres/schema-builder.d.ts +1 -0
  8. package/esm/postgres/schema-builder.js +13 -1
  9. package/esm/remult-express.js +1 -1
  10. package/esm/remult-knex/index.js +4 -2
  11. package/esm/remult-mongo.d.ts +1 -1
  12. package/esm/remult-mongo.js +17 -5
  13. package/esm/remult-sveltekit.d.ts +3 -1
  14. package/esm/remult-sveltekit.js +3 -0
  15. package/esm/server/JsonEntityFileStorage.js +1 -1
  16. package/esm/server/expressBridge.d.ts +8 -0
  17. package/esm/server/expressBridge.js +12 -6
  18. package/esm/src/CompoundIdField.d.ts +1 -1
  19. package/esm/src/CompoundIdField.js +3 -1
  20. package/esm/src/buildRestDataProvider.d.ts +1 -2
  21. package/esm/src/column-interfaces.d.ts +19 -7
  22. package/esm/src/column.d.ts +3 -4
  23. package/esm/src/column.js +4 -3
  24. package/esm/src/context.d.ts +1 -1
  25. package/esm/src/context.js +6 -1
  26. package/esm/src/data-api.js +4 -1
  27. package/esm/src/data-interfaces.js +1 -2
  28. package/esm/src/data-providers/array-entity-data-provider.d.ts +1 -1
  29. package/esm/src/data-providers/array-entity-data-provider.js +6 -6
  30. package/esm/src/data-providers/sql-database.js +2 -1
  31. package/esm/src/data-providers/web-sql-data-provider.js +3 -3
  32. package/esm/src/entity.d.ts +47 -16
  33. package/esm/src/filter/filter-interfaces.d.ts +2 -2
  34. package/esm/src/filter/filter-interfaces.js +4 -3
  35. package/esm/src/live-query/LiveQueryClient.js +2 -1
  36. package/esm/src/live-query/SubscriptionChannel.js +4 -3
  37. package/esm/src/remult-proxy.js +9 -6
  38. package/esm/src/remult3/Fields.d.ts +118 -20
  39. package/esm/src/remult3/Fields.js +1 -2
  40. package/esm/src/remult3/RepositoryImplementation.d.ts +9 -17
  41. package/esm/src/remult3/RepositoryImplementation.js +110 -37
  42. package/esm/src/remult3/entity.d.ts +1 -1
  43. package/esm/src/remult3/entity.js +0 -1
  44. package/esm/src/remult3/getEntityRef.d.ts +1 -1
  45. package/esm/src/remult3/getEntityRef.js +1 -1
  46. package/esm/src/remult3/remult3.d.ts +136 -5
  47. package/esm/src/remult3/remult3.js +58 -0
  48. package/esm/src/remult3/repository-internals.d.ts +14 -0
  49. package/esm/src/remult3/repository-internals.js +7 -0
  50. package/esm/src/server-action.js +1 -1
  51. package/esm/src/sort.d.ts +3 -3
  52. package/esm/src/sort.js +13 -7
  53. package/graphql.js +19 -3
  54. package/index.d.ts +13 -1
  55. package/index.js +12 -0
  56. package/internals.d.ts +2 -1
  57. package/internals.js +3 -1
  58. package/package.json +1 -1
  59. package/postgres/schema-builder.d.ts +1 -0
  60. package/postgres/schema-builder.js +12 -2
  61. package/remult-express.js +1 -1
  62. package/remult-knex/index.js +13 -7
  63. package/remult-mongo.d.ts +1 -1
  64. package/remult-mongo.js +17 -5
  65. package/remult-sveltekit.d.ts +3 -1
  66. package/remult-sveltekit.js +3 -0
  67. package/server/JsonEntityFileStorage.js +1 -1
  68. package/server/expressBridge.d.ts +8 -0
  69. package/server/expressBridge.js +13 -6
  70. package/src/CompoundIdField.d.ts +1 -1
  71. package/src/CompoundIdField.js +3 -0
  72. package/src/buildRestDataProvider.d.ts +1 -2
  73. package/src/column-interfaces.d.ts +19 -7
  74. package/src/column.d.ts +3 -4
  75. package/src/column.js +4 -3
  76. package/src/context.d.ts +1 -1
  77. package/src/context.js +6 -1
  78. package/src/data-api.js +4 -1
  79. package/src/data-interfaces.js +1 -2
  80. package/src/data-providers/array-entity-data-provider.d.ts +1 -1
  81. package/src/data-providers/array-entity-data-provider.js +5 -6
  82. package/src/data-providers/sql-database.js +2 -1
  83. package/src/data-providers/web-sql-data-provider.js +3 -3
  84. package/src/entity.d.ts +47 -16
  85. package/src/filter/filter-interfaces.d.ts +2 -2
  86. package/src/filter/filter-interfaces.js +4 -3
  87. package/src/live-query/LiveQueryClient.js +2 -1
  88. package/src/live-query/SubscriptionChannel.js +4 -3
  89. package/src/remult-proxy.js +46 -35
  90. package/src/remult3/Fields.d.ts +118 -20
  91. package/src/remult3/Fields.js +0 -1
  92. package/src/remult3/RepositoryImplementation.d.ts +9 -17
  93. package/src/remult3/RepositoryImplementation.js +217 -143
  94. package/src/remult3/entity.d.ts +1 -1
  95. package/src/remult3/entity.js +0 -1
  96. package/src/remult3/getEntityRef.d.ts +1 -1
  97. package/src/remult3/getEntityRef.js +2 -1
  98. package/src/remult3/remult3.d.ts +136 -5
  99. package/src/remult3/remult3.js +58 -0
  100. package/src/remult3/repository-internals.d.ts +14 -0
  101. package/src/remult3/repository-internals.js +11 -0
  102. package/src/server-action.js +1 -1
  103. package/src/sort.d.ts +3 -3
  104. package/src/sort.js +12 -5
package/README.md CHANGED
@@ -22,7 +22,6 @@
22
22
  <a href="https://discord.gg/GXHk7ZfuG5" rel="nofollow">
23
23
  <img alt="Join Discord" src="https://badgen.net/discord/online-members/GXHk7ZfuG5?icon=discord&label=Discord"/>
24
24
  </a>
25
- </a>
26
25
  </div>
27
26
 
28
27
  <br/>
@@ -101,14 +100,14 @@ npm i remult
101
100
  ```ts
102
101
  // shared/product.ts
103
102
 
104
- import { Entity, Fields } from "remult"
103
+ import { Entity, Fields } from 'remult'
105
104
 
106
- @Entity("products", {
107
- allowApiCrud: true
105
+ @Entity('products', {
106
+ allowApiCrud: true,
108
107
  })
109
108
  export class Product {
110
109
  @Fields.string()
111
- name = ""
110
+ name = ''
112
111
 
113
112
  @Fields.number()
114
113
  unitPrice = 0
@@ -120,17 +119,17 @@ export class Product {
120
119
  ```ts
121
120
  // backend/index.ts
122
121
 
123
- import express from "express"
124
- import { remultExpress } from "remult/remult-express"
125
- import { Product } from "../shared/product"
122
+ import express from 'express'
123
+ import { remultExpress } from 'remult/remult-express'
124
+ import { Product } from '../shared/product'
126
125
 
127
126
  const port = 3001
128
127
  const app = express()
129
128
 
130
129
  app.use(
131
130
  remultExpress({
132
- entities: [Product]
133
- })
131
+ entities: [Product],
132
+ }),
134
133
  )
135
134
 
136
135
  app.listen(port, () => {
@@ -151,13 +150,13 @@ app.listen(port, () => {
151
150
  ```ts
152
151
  // frontend/code.ts
153
152
 
154
- import { remult } from "remult"
155
- import { Product } from "../shared/product"
153
+ import { remult } from 'remult'
154
+ import { Product } from '../shared/product'
156
155
 
157
156
  async function increasePriceOfTofu(priceIncrease: number) {
158
157
  const productsRepo = remult.repo(Product)
159
158
 
160
- const product = await productsRepo.findFirst({ name: "Tofu" }) // filter is passed through API request all the way to the db
159
+ const product = await productsRepo.findFirst({ name: 'Tofu' }) // filter is passed through API request all the way to the db
161
160
  product.unitPrice += priceIncrease
162
161
  productsRepo.save(product) // mutation request updates the db with no boilerplate code
163
162
  }
@@ -179,32 +178,32 @@ static async increasePriceOfTofu(priceIncrease: number) {
179
178
  ### :ballot_box_with_check: Data validation and constraints - defined once
180
179
 
181
180
  ```ts
182
- import { Entity, Fields, Validators } from "remult"
181
+ import { Entity, Fields, Validators } from 'remult'
183
182
 
184
- @Entity("products", {
185
- allowApiCrud: true
183
+ @Entity('products', {
184
+ allowApiCrud: true,
186
185
  })
187
186
  export class Product {
188
187
  @Fields.string({
189
- validate: Validators.required
188
+ validate: Validators.required,
190
189
  })
191
- name = ""
190
+ name = ''
192
191
 
193
192
  @Fields.string<Product>({
194
193
  validate: (product) => {
195
194
  if (product.description.trim().length < 50) {
196
- throw "too short"
195
+ throw 'too short'
197
196
  }
198
- }
197
+ },
199
198
  })
200
- description = ""
199
+ description = ''
201
200
 
202
201
  @Fields.number({
203
202
  validate: (_, field) => {
204
203
  if (field.value < 0) {
205
- field.error = "must not be less than 0" // or: throw "must not be less than 0";
204
+ field.error = 'must not be less than 0' // or: throw "must not be less than 0";
206
205
  }
207
- }
206
+ },
208
207
  })
209
208
  unitPrice = 0
210
209
  }
@@ -233,20 +232,20 @@ try {
233
232
  ### :lock: Secure the API with fine-grained authorization
234
233
 
235
234
  ```ts
236
- @Entity<Article>("Articles", {
235
+ @Entity<Article>('Articles', {
237
236
  allowApiRead: true,
238
237
  allowApiInsert: (_, remult) => remult.authenticated(),
239
- allowApiUpdate: (article, remult) => article.author.id == remult.user.id
238
+ allowApiUpdate: (article, remult) => article.author.id == remult.user.id,
240
239
  })
241
240
  export class Article {
242
241
  @Fields.string({ allowApiUpdate: false })
243
- slug = ""
242
+ slug = ''
244
243
 
245
244
  @Field(() => Profile, { allowApiUpdate: false })
246
245
  author!: Profile
247
246
 
248
247
  @Fields.string()
249
- content = ""
248
+ content = ''
250
249
  }
251
250
  ```
252
251
 
@@ -278,6 +277,7 @@ with a Node.js Express backend.
278
277
  - [Tutorial with Angular](https://remult.dev/tutorials/angular/)
279
278
  - [Tutorial with Vue](https://remult.dev/tutorials/vue/)
280
279
  - [Tutorial with Next.js](https://remult.dev/tutorials/react-next/)
280
+ - [Tutorial with Sveltekit](https://remult.dev/tutorials/sveltekit/)
281
281
 
282
282
  ## Documentation
283
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
- const { limit, page, orderBy, where } = arg1;
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.includedInApi === false)
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,5 @@
1
1
  import type { ClassType } from './classType';
2
- export { OmitEB, FieldsMetadata, FieldRef, IdFieldRef, FieldsRef, EntityMetadata, EntityOrderBy, EntityFilter, FindOptions, QueryResult, QueryOptions, Repository, FindFirstOptions, ComparisonValueFilter, ValueFilter, IdFilter, ContainsStringValueFilter, EntityRef, SortSegments, Paginator, LiveQuery, LiveQueryChangeInfo, Subscribable, RefSubscriber, RefSubscriberBase, RelationOptions, RelationOptionsBase, ObjectMembersOnly, MembersToInclude, RepositoryRelations, EntityIdFields, } from './src/remult3/remult3';
2
+ export { OmitEB, FieldsMetadata, FieldRef, IdFieldRef, FieldsRef, EntityMetadata, EntityOrderBy, EntityFilter, FindOptions, QueryResult, QueryOptions, Repository, FindFirstOptions, ComparisonValueFilter, ValueFilter, IdFilter, ContainsStringValueFilter, EntityRef, SortSegments, Paginator, LiveQuery, LiveQueryChangeInfo, Subscribable, RefSubscriber, RefSubscriberBase, RelationOptions, ObjectMembersOnly, MembersToInclude, RepositoryRelations, EntityIdFields, ClassFieldDecorator as MemberDecorator, ClassFieldDecoratorContextStub, } from './src/remult3/remult3';
3
3
  export { EntityBase, ControllerBase, FieldType, getFields, ValueListFieldType, getValueList, ValueListFieldOptions, ValueListInfo, CaptionTransformer, } from './src/remult3/RepositoryImplementation';
4
4
  export { Entity } from './src/remult3/entity';
5
5
  export { getEntityRef } from './src/remult3/getEntityRef';
@@ -30,4 +30,16 @@ export { ValueConverters } from './src/valueConverters';
30
30
  export { remult } from './src/remult-proxy';
31
31
  export { SubscriptionServer, LiveQueryStorage, StoredQuery, InMemoryLiveQueryStorage, } from './src/live-query/SubscriptionServer';
32
32
  export { SubscriptionListener, SubscriptionClientConnection, SubscriptionClient, SubscriptionChannel, LiveQueryChange, Unsubscribe, } from './src/live-query/SubscriptionChannel';
33
+ /**
34
+ * A convenient shortcut function to quickly obtain a repository for a specific entity type in Remult.
35
+ *
36
+ * @param entity The entity class type for which you want to get a repository.
37
+ * @returns A repository instance for the specified entity type.
38
+ *
39
+ * Example usage:
40
+ * ```ts
41
+ * await repo(Task).find()
42
+ * await repo(Customer).insert()
43
+ * ```
44
+ */
33
45
  export declare function repo<entityType>(entity: ClassType<entityType>): import("./src/remult3/remult3").Repository<entityType>;
package/esm/index.js CHANGED
@@ -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
  }
@@ -1,6 +1,7 @@
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';
6
6
  export { RelationInfo } from './src/remult3/remult3';
7
+ export { ClassType } from './classType';
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 table ${this.schemaAndName(e)} (${result}\r\n)`;
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);
@@ -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
- // [ ]- add with remult promise
24
+ // [ ] V1.5 add with remult promise
25
25
  });
26
26
  }
@@ -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
  }
@@ -1,4 +1,4 @@
1
- import type { ClientSession, Db, MongoClient } from 'mongodb';
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 {
@@ -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] = col.valueConverter.fromDb(val);
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 = col.valueConverter.toDb(row[col.key]);
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) => col.valueConverter.toDb(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 : col.valueConverter.toDb(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
+ };
@@ -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
  }
@@ -8,7 +8,7 @@ export class JsonEntityFileStorage {
8
8
  if (fs.existsSync(fn)) {
9
9
  return fs.readFileSync(fn).toString();
10
10
  }
11
- return undefined;
11
+ return null;
12
12
  }
13
13
  setItem(entityDbName, json) {
14
14
  if (!fs.existsSync(this.folderPath)) {
@@ -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
  }
@@ -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
- this.middleware(req, response, () => res(undefined));
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 = path.substring(0, idPosition) + '/:id';
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
  }
@@ -987,3 +992,4 @@ JobsInQueueEntity = __decorate([
987
992
  ], JobsInQueueEntity);
988
993
  export { JobsInQueueEntity };
989
994
  allEntities.splice(allEntities.indexOf(JobsInQueueEntity), 1);
995
+ //p1 - implement dbname based on related field https://codesandbox.io/p/sandbox/fervent-yalow-66m78n?file=%2Fsrc%2Findex.ts%3A35%2C93
@@ -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,5 @@
1
1
  import type { RestDataProviderHttpProvider } from './data-interfaces';
2
- import { RestDataProviderHttpProviderUsingFetch } from './data-providers/rest-data-provider';
3
- export declare function buildRestDataProvider(provider: ExternalHttpProvider | typeof fetch): RestDataProviderHttpProviderUsingFetch | RestDataProviderHttpProvider;
2
+ export declare function buildRestDataProvider(provider: ExternalHttpProvider | typeof fetch): RestDataProviderHttpProvider;
4
3
  export declare function isExternalHttpProvider(item: any): boolean;
5
4
  export declare class HttpProviderBridgeToRestDataProviderHttpProvider implements RestDataProviderHttpProvider {
6
5
  private http;
@@ -1,6 +1,6 @@
1
1
  import type { ClassType } from '../classType';
2
- import type { Allowed, AllowedForInstance } from './context';
3
- import type { EntityMetadata, FieldRef, LifeCycleEvent, OmitEB } from './remult3/remult3';
2
+ import type { AllowedForInstance } from './context';
3
+ import type { EntityMetadata, FieldRef, LifecycleEvent, OmitEB } 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?: Allowed;
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, e: LifeCycleEvent<entityType>, fieldRef: FieldRef<entityType, valueType>) => any | Promise<any>;
40
+ saving?: (entity: entityType, e: LifecycleEvent<entityType>, fieldRef: FieldRef<entityType, valueType>) => 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
- /** Determines if the referenced entity will be loaded immediately or on demand.
73
- * @see[Lazy loading of related entities](http://remult.dev/docs/lazy-loading-of-related-entities.html)
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 */
@@ -122,7 +134,7 @@ export interface FieldMetadata<valueType = any, entityType = any> {
122
134
  */
123
135
  displayValue(item: Partial<OmitEB<entityType>>): string;
124
136
  apiUpdateAllowed(item?: Partial<OmitEB<entityType>>): boolean;
125
- readonly includedInApi: boolean;
137
+ includedInApi(item?: Partial<OmitEB<entityType>>): boolean;
126
138
  /** Adapts the value for usage with html input
127
139
  * @example
128
140
  * @Fields.dateOnly()
@@ -1,5 +1,4 @@
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;
@@ -8,12 +7,12 @@ export declare class LookupColumn<T> {
8
7
  setId(val: any): void;
9
8
  waitLoadOf(id: any): Promise<T>;
10
9
  get(id: any): any;
11
- storedItem: {
10
+ storedItem?: {
12
11
  item: T;
13
12
  };
14
13
  set(item: T): void;
15
14
  id: idType<T>;
16
- constructor(repository: RepositoryImplementation<T>, isReferenceRelation: any);
15
+ constructor(repository: Repository<T>, isReferenceRelation: any);
17
16
  get item(): T;
18
17
  waitLoad(): Promise<T>;
19
18
  }