remult 3.0.6 → 3.1.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.
@@ -2,31 +2,6 @@ import { AsyncLocalStorage } from 'async_hooks';
2
2
  import { RemultAsyncLocalStorage, } from '../src/context.js';
3
3
  import { remultStatic } from '../src/remult-static.js';
4
4
  let init = false;
5
- /**
6
- * Initializes async context tracking for the server.
7
- *
8
- * This should be called before handling any incoming requests or calling `withRemult()`.
9
- * @example
10
- * import { remult, repo, withRemult } from 'remult';
11
- * import { initAsyncHooks } from 'remult/async-hooks';
12
- *
13
- * import { Task } from './entities/Task.js';
14
- *
15
- * initAsyncHooks();
16
- *
17
- * // Thx to the `initAsyncHooks` above,
18
- * // we have isolated async contexts with multiple `withRemult()`,
19
- * // without needing to initialize a `remultApi` all the time!
20
- * withRemult(async () => {
21
- * remult.user = { id: '42' };
22
- * repo(Task).find()
23
- * });
24
- *
25
- * withRemult(async () => {
26
- * remult.user = { id: '21' };
27
- * repo(Task).find()
28
- * });
29
- */
30
5
  export function initAsyncHooks() {
31
6
  if (init)
32
7
  return;
@@ -1,4 +1,3 @@
1
- import { v4 as uuid } from 'uuid';
2
1
  import { Sort } from '../sort.js';
3
2
  import { remult as defaultRemult } from '../remult-proxy.js';
4
3
  import { getRepositoryInternals } from '../remult3/repository-internals.js';
@@ -92,7 +91,7 @@ export class LiveQuerySubscriber {
92
91
  }
93
92
  defaultQueryState = [];
94
93
  listeners = [];
95
- id = uuid();
94
+ id = String(crypto.randomUUID());
96
95
  constructor(repo, query, userId) {
97
96
  this.repo = repo;
98
97
  this.query = query;
@@ -20,6 +20,7 @@ let x = {
20
20
  },
21
21
  fieldOptionsEnricher: undefined,
22
22
  labelTransformer: undefined,
23
+ defaultIdFactory: undefined,
23
24
  defaultDataProvider: () => undefined,
24
25
  };
25
26
  if ((typeof process !== 'undefined' &&
@@ -1,5 +1,3 @@
1
- import { createId } from '@paralleldrive/cuid2';
2
- import { v4 as uuid } from 'uuid';
3
1
  import { ValueConverters } from '../valueConverters.js';
4
2
  import { buildOptions, fieldOptionalValuesFunctionKey, } from './RepositoryImplementation.js';
5
3
  import { Validators, createValueValidator, getEnumValues, } from '../validators.js';
@@ -79,43 +77,62 @@ export class Fields {
79
77
  },
80
78
  }, ...options);
81
79
  }
80
+ /** @deprecated use `@Fields.id()` instead */
82
81
  static uuid(...options) {
83
- return Field(() => String, {
84
- allowApiUpdate: false,
85
- defaultValue: () => uuid(),
86
- saving: (_, r) => {
87
- if (!r.value)
88
- r.value = uuid();
89
- },
90
- }, ...options);
82
+ return Fields.id({
83
+ idFactory: () => crypto.randomUUID(),
84
+ ...options,
85
+ });
86
+ }
87
+ static _defaultIdFactory = () => crypto.randomUUID();
88
+ static get defaultIdFactory() {
89
+ return this._defaultIdFactory;
90
+ }
91
+ static set defaultIdFactory(value) {
92
+ this._defaultIdFactory = value;
93
+ remultStatic.defaultIdFactory = value;
91
94
  }
92
95
  /**
93
- * A CUID (Collision Resistant Unique Identifier) field.
94
- * This id value is determined on the backend on insert, and can't be updated through the API.
95
- * The CUID is generated using the `@paralleldrive/cuid2` npm package.
96
+ * Defines a field that will be used as the id of the entity.
97
+ * By default it will use `crypto.randomUUID` to generate the id.
98
+ *
99
+ * You can change the algorithm used to generate the id by setting the `Fields.defaultIdFactory`
100
+ * to a different function like:
101
+ *
102
+ * This needs to be done in a shared file to be accessible frontend and backend.
103
+ *
104
+ * ```ts
105
+ * import { createId } from '@paralleldrive/cuid2'
106
+ * Fields.defaultIdFactory = () => createId()
107
+ * ```
108
+ *
109
+ * You can also pass an id factory as an option to the `@Fields.id` to have a different value locally.
110
+ * @example
111
+ * ```ts
112
+ * import { createId } from '@paralleldrive/cuid2'
113
+ * // import { v4 as uuid } from 'uuid'
114
+ *
115
+ * class MyEntity {
116
+ * \@Fields.id({
117
+ * idFactory: () => createId()
118
+ * // idFactory: () => uuid()
119
+ * })
120
+ * id: string = '';
121
+ * }
122
+ * ```
96
123
  */
97
- static cuid(...options) {
124
+ static id(options) {
125
+ let idFactory = options?.idFactory ?? remultStatic.defaultIdFactory;
98
126
  return Field(() => String, {
99
127
  allowApiUpdate: false,
100
- defaultValue: () => createId(),
128
+ defaultValue: () => idFactory(),
101
129
  saving: (_, r) => {
102
130
  if (!r.value)
103
- r.value = createId();
131
+ r.value = idFactory();
104
132
  },
105
- }, ...options);
133
+ ...options,
134
+ });
106
135
  }
107
- // static id<entityType = unknown>(
108
- // options?: FieldOptions<entityType, string> & { idFactory?: () => string },
109
- // ): ClassFieldDecorator<entityType, string | undefined> {
110
- // let buildId = options?.idFactory ?? createId
111
- // return Field(() => String, {
112
- // allowApiUpdate: false,
113
- // defaultValue: () => buildId(),
114
- // saving: (_, r) => {
115
- // if (!r.value) r.value = buildId()
116
- // },
117
- // })
118
- // }
119
136
  /**
120
137
  * Defines a field that can hold a value from a specified set of string literals.
121
138
  * @param {() => readonly valueType[]} optionalValues - A function that returns an array of allowed string literals.
@@ -185,6 +202,8 @@ export class Fields {
185
202
  return Field(() => Boolean, ...options);
186
203
  }
187
204
  }
205
+ // Initialize remultStatic.defaultIdFactory with the default value
206
+ remultStatic.defaultIdFactory = Fields.defaultIdFactory;
188
207
  export class Relations {
189
208
  /**
190
209
  * Define a to-one relation between entities, indicating a one-to-one relationship.
@@ -302,10 +321,12 @@ export function Field(valueType, ...options) {
302
321
  r.dbName = r.key;
303
322
  let type = r.valueType;
304
323
  if (!type) {
305
- type =
306
- typeof Reflect.getMetadata == 'function'
307
- ? Reflect.getMetadata('design:type', target, key)
308
- : [];
324
+ // removing import 'reflect-metadata' from server-action.ts, so we return an empty array
325
+ type = undefined;
326
+ // type =
327
+ // typeof Reflect.getMetadata == 'function'
328
+ // ? Reflect.getMetadata('design:type', target, key)
329
+ // : []
309
330
  r.valueType = type;
310
331
  }
311
332
  if (!r.target)
@@ -5,6 +5,6 @@ export class IdEntity extends EntityBase {
5
5
  id;
6
6
  }
7
7
  __decorate([
8
- Fields.uuid(),
8
+ Fields.id(),
9
9
  __metadata("design:type", String)
10
10
  ], IdEntity.prototype, "id", void 0);
@@ -9,7 +9,7 @@ import { remultStatic } from '../remult-static.js';
9
9
  * allowApiCrud: true
10
10
  * })
11
11
  * export class Task {
12
- * @Fields.uuid()
12
+ * @Fields.id()
13
13
  * id!: string;
14
14
  * @Fields.string()
15
15
  * title = '';
@@ -1,4 +1,3 @@
1
- import 'reflect-metadata';
2
1
  import { buildRestDataProvider } from './buildRestDataProvider.js';
3
2
  import { ClassHelper, Remult, doTransaction, isBackend, setControllerSettings, } from './context.js';
4
3
  import { SqlDatabase } from './data-providers/sql-database.js';
@@ -137,9 +136,11 @@ export function BackendMethod(options) {
137
136
  let result = originalMethod;
138
137
  checkTarget(target);
139
138
  function getTypes() {
140
- var types = typeof Reflect.getMetadata == 'function'
141
- ? Reflect.getMetadata('design:paramtypes', target, key)
142
- : [];
139
+ // removing import 'reflect-metadata' from server-action.ts, so we return an empty array
140
+ var types = [];
141
+ // typeof Reflect.getMetadata == 'function'
142
+ // ? Reflect.getMetadata('design:paramtypes', target, key)
143
+ // : []
143
144
  if (options.paramTypes)
144
145
  types =
145
146
  typeof options.paramTypes === 'function'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "remult",
3
- "version": "3.0.6",
3
+ "version": "3.1.0-next.1",
4
4
  "description": "A CRUD framework for full-stack TypeScript",
5
5
  "homepage": "https://remult.dev",
6
6
  "repository": {
@@ -17,12 +17,13 @@
17
17
  {
18
18
  "name": "Yoni Rapoport",
19
19
  "email": "yoni.rapoport@gmail.com"
20
+ },
21
+ {
22
+ "name": "Jean-Yves COUËT",
23
+ "email": "jycouet@gmail.com"
20
24
  }
21
25
  ],
22
26
  "dependencies": {
23
- "@paralleldrive/cuid2": "^2.2.1",
24
- "uuid": "^8.3.2",
25
- "reflect-metadata": "^0.1.13",
26
27
  "tslib": "^2.3.1"
27
28
  },
28
29
  "exports": {
package/remult-express.js CHANGED
@@ -14,15 +14,24 @@ function remultApi(options) {
14
14
  if (options.bodySizeLimit === undefined) {
15
15
  options.bodySizeLimit = '10mb';
16
16
  }
17
+ var expressVersion = typeof app.del === 'function' ? 4 : 5;
17
18
  if ((options === null || options === void 0 ? void 0 : options.bodyParser) !== false) {
18
19
  app.use(express.json({ limit: options.bodySizeLimit }));
19
20
  app.use(express.urlencoded({ extended: true, limit: options.bodySizeLimit }));
20
21
  }
21
22
  var server = (0, index_js_1.createRemultServer)(options, {
22
- buildGenericRequestInfo: function (req) { return ({
23
- internal: tslib_1.__assign(tslib_1.__assign({}, req), { on: req.on }),
24
- public: { headers: new Headers(req.headers) },
25
- }); },
23
+ buildGenericRequestInfo: function (req) {
24
+ var internal = tslib_1.__assign(tslib_1.__assign({}, req), { on: req.on });
25
+ if (expressVersion === 5) {
26
+ if (!internal.query) {
27
+ internal.query = req.query;
28
+ }
29
+ }
30
+ return {
31
+ internal: internal,
32
+ public: { headers: new Headers(req.headers) },
33
+ };
34
+ },
26
35
  getRequestBody: function (req) { return tslib_1.__awaiter(_this, void 0, void 0, function () { return tslib_1.__generator(this, function (_a) {
27
36
  return [2 /*return*/, req.body];
28
37
  }); }); },