remult 3.0.6 → 3.0.7-next.0

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;
@@ -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: () => (options?.allowNull ? null : idFactory()),
101
129
  saving: (_, r) => {
102
- if (!r.value)
103
- r.value = createId();
130
+ if (!r.value && !options?.allowNull)
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.
@@ -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 = '';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "remult",
3
- "version": "3.0.6",
3
+ "version": "3.0.7-next.0",
4
4
  "description": "A CRUD framework for full-stack TypeScript",
5
5
  "homepage": "https://remult.dev",
6
6
  "repository": {
@@ -17,11 +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
27
  "reflect-metadata": "^0.1.13",
26
28
  "tslib": "^2.3.1"
27
29
  },
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
  }); }); },