@clairejs/server 3.22.0 → 3.22.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.
package/README.md CHANGED
@@ -1,7 +1,8 @@
1
1
  ## Change Log
2
2
 
3
- #### 3.22.0:
3
+ #### 3.22.1:
4
4
 
5
+ - fix uri mapper to map Identifiable classes
5
6
  - remove support of uri mapper for locale fields
6
7
  - support uri mapper for nested array field
7
8
 
@@ -2,10 +2,7 @@ import { ModelFieldMetadata, ModelMetadata } from "@clairejs/core";
2
2
  import { IPrincipal } from "./auth/IPrincipal";
3
3
  import { UriMapperHandler } from "../http/file-upload/types";
4
4
  export interface ServerModelFieldMetadata extends ModelFieldMetadata {
5
- uriMapper?: {
6
- mapper: UriMapperHandler;
7
- subkeys: string[];
8
- };
5
+ uriMapper?: UriMapperHandler;
9
6
  userResolver?: (principal: IPrincipal) => any;
10
7
  }
11
8
  export interface ServerModelMetadata extends ModelMetadata {
@@ -1,4 +1,4 @@
1
- import { type Constructor, HttpMethod, RecursiveKeys, AbstractModel } from "@clairejs/core";
1
+ import { type Constructor, HttpMethod, Identifiable } from "@clairejs/core";
2
2
  import { type UriMapperHandler } from "./file-upload/types";
3
3
  import { type HttpResponse } from "./common/HttpResponse";
4
4
  import { type IPrincipal } from "../common/auth/IPrincipal";
@@ -21,7 +21,7 @@ export declare const Queries: () => (prototype: AbstractHttpController, property
21
21
  export declare const Headers: () => (prototype: AbstractHttpController, propertyKey: string, paramIndex: number) => void;
22
22
  export declare const Socket: () => (prototype: AbstractHttpController, propertyKey: string, paramIndex: number) => void;
23
23
  export declare const Raw: () => (prototype: AbstractHttpController, propertyKey: string, paramIndex: number) => void;
24
- export declare const UriMapper: (mapper: UriMapperHandler) => <T extends AbstractModel>(prototype: T, propertyKey: RecursiveKeys<T>) => void;
24
+ export declare const UriMapper: (mapper: UriMapperHandler) => <T extends Identifiable>(prototype: T, propertyKey: keyof T) => void;
25
25
  /**
26
26
  * Current User decorator only has effect when being used with ICrudRepository.
27
27
  * */
@@ -61,9 +61,8 @@ export const Headers = () => RequestDeco("headers");
61
61
  export const Socket = () => RequestDeco("socket");
62
62
  export const Raw = () => RequestDeco("raw");
63
63
  export const UriMapper = (mapper) => (prototype, propertyKey) => {
64
- const [rootKey, ...keys] = propertyKey.split(".");
65
- const field = initFieldMetadata(prototype, rootKey);
66
- field.uriMapper = { mapper, subkeys: keys };
64
+ const field = initFieldMetadata(prototype, propertyKey);
65
+ field.uriMapper = mapper;
67
66
  };
68
67
  /**
69
68
  * Current User decorator only has effect when being used with ICrudRepository.
@@ -4,31 +4,11 @@ import { AbstractFileUploadHandler } from "../file-upload/AbstractFileUploadHand
4
4
  import { AbstractRepository } from "./AbstractRepository";
5
5
  import { LocaleTranslation } from "../../system/locale/LocaleTranslation";
6
6
  import { LocaleEntry } from "../../system/locale/LocaleEntry";
7
- const resolveUris = (record, field, subkeys) => {
8
- return field.vectorProps
9
- ? field.vectorProps.elementDataType === DataType.STRING
10
- ? record[field.name]
11
- : record[field.name].map((obj) => subkeys.reduce((value, key) => value[key], obj))
12
- : [record[field.name]];
7
+ const resolveUris = (record, field) => {
8
+ return field.vectorProps?.elementDataType === DataType.STRING ? record[field.name] : [record[field.name]];
13
9
  };
14
- const assignUrls = (record, field, subkeys, urls) => {
15
- if (field.vectorProps) {
16
- if (field.vectorProps.elementDataType === DataType.STRING) {
17
- record[field.name] = urls;
18
- }
19
- else {
20
- record[field.name].forEach((obj, index) => {
21
- let currentObj = obj;
22
- for (let i = 0; i < subkeys.length - 1; i++) {
23
- currentObj = currentObj[subkeys[i]];
24
- }
25
- currentObj[subkeys[subkeys.length - 1]] = urls[index];
26
- });
27
- }
28
- }
29
- else {
30
- record[field.name] = urls[0];
31
- }
10
+ const assignUrls = (record, field, urls) => {
11
+ record[field.name] = field.vectorProps?.elementDataType === DataType.STRING ? urls : urls[0];
32
12
  };
33
13
  export class ModelRepository extends AbstractRepository {
34
14
  model;
@@ -157,12 +137,18 @@ export class ModelRepository extends AbstractRepository {
157
137
  //-- update record value and not persist yet
158
138
  return newUri;
159
139
  };
160
- if (fileUploadHandler) {
161
- for (const field of this.modelMetadata.fields) {
140
+ const mapRecords = (records, modelMetadata) => {
141
+ for (const field of modelMetadata.fields) {
162
142
  for (const record of records) {
163
- if (field.uriMapper && record[field.name]) {
164
- const { subkeys, mapper } = field.uriMapper;
165
- const tmpUris = resolveUris(record, field, subkeys);
143
+ const value = record[field.name];
144
+ if (!value)
145
+ continue;
146
+ if (field.elementDto) {
147
+ mapRecords(field.vectorProps ? value : [value], field.elementDto);
148
+ }
149
+ else if (field.uriMapper) {
150
+ const mapper = field.uriMapper;
151
+ const tmpUris = resolveUris(record, field);
166
152
  if (!tmpUris.length) {
167
153
  continue;
168
154
  }
@@ -171,11 +157,14 @@ export class ModelRepository extends AbstractRepository {
171
157
  }
172
158
  operations.push((async () => {
173
159
  const urls = await Promise.all(tmpUris.map((uri, index) => uriHandler(uri, index, mapper, getSystemLocale())));
174
- assignUrls(record, field, subkeys, urls);
160
+ assignUrls(record, field, urls);
175
161
  })());
176
162
  }
177
163
  }
178
164
  }
165
+ };
166
+ if (fileUploadHandler) {
167
+ mapRecords(records, this.modelMetadata);
179
168
  }
180
169
  //-- await all operations once to save time
181
170
  await Promise.all(operations);
@@ -192,22 +181,30 @@ export class ModelRepository extends AbstractRepository {
192
181
  return;
193
182
  }
194
183
  const mappingOperations = [];
195
- for (const record of records) {
196
- for (const field of this.modelMetadata.fields) {
197
- if (field.uriMapper && record[field.name]) {
198
- const { subkeys } = field.uriMapper;
199
- const uris = resolveUris(record, field, subkeys);
200
- mappingOperations.push((async () => {
201
- const urls = await Promise.all(uris.map(async (uri) => {
202
- return field.mimeProps?.public
203
- ? await fileUploadHandler.resolvePublicUrl(uri)
204
- : await fileUploadHandler.resolvePrivateUrl(uri);
205
- }));
206
- assignUrls(record, field, subkeys, urls);
207
- })());
184
+ const mapRecords = (records, modelMetadata) => {
185
+ for (const record of records) {
186
+ for (const field of modelMetadata.fields) {
187
+ const value = record[field.name];
188
+ if (!value)
189
+ continue;
190
+ if (field.elementDto && value) {
191
+ mapRecords(field.vectorProps ? value : [value], field.elementDto);
192
+ }
193
+ else if (field.uriMapper) {
194
+ const uris = resolveUris(record, field);
195
+ mappingOperations.push((async () => {
196
+ const urls = await Promise.all(uris.map(async (uri) => {
197
+ return field.mimeProps?.public
198
+ ? await fileUploadHandler.resolvePublicUrl(uri)
199
+ : await fileUploadHandler.resolvePrivateUrl(uri);
200
+ }));
201
+ assignUrls(record, field, urls);
202
+ })());
203
+ }
208
204
  }
209
205
  }
210
- }
206
+ };
207
+ mapRecords(records, this.modelMetadata);
211
208
  await Promise.all(mappingOperations);
212
209
  }
213
210
  async createMany({ principal, body, tx, logger, }) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clairejs/server",
3
- "version": "3.22.0",
3
+ "version": "3.22.1",
4
4
  "description": "Claire server NodeJs framework written in Typescript.",
5
5
  "types": "dist/index.d.ts",
6
6
  "main": "dist/index.js",