@clairejs/server 3.21.9 → 3.22.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.
package/README.md CHANGED
@@ -1,5 +1,10 @@
1
1
  ## Change Log
2
2
 
3
+ #### 3.22.0:
4
+
5
+ - remove support of uri mapper for locale fields
6
+ - support uri mapper for nested array field
7
+
3
8
  #### 3.21.9:
4
9
 
5
10
  - fix express wrapper parse multipart form data
@@ -2,7 +2,10 @@ 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?: UriMapperHandler;
5
+ uriMapper?: {
6
+ mapper: UriMapperHandler;
7
+ subkeys: string[];
8
+ };
6
9
  userResolver?: (principal: IPrincipal) => any;
7
10
  }
8
11
  export interface ServerModelMetadata extends ModelMetadata {
@@ -1,4 +1,4 @@
1
- import { type Constructor, AbstractModel, HttpMethod } from "@clairejs/core";
1
+ import { type Constructor, HttpMethod, RecursiveKeys, AbstractModel } 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: keyof T) => void;
24
+ export declare const UriMapper: (mapper: UriMapperHandler) => <T extends AbstractModel>(prototype: T, propertyKey: RecursiveKeys<T>) => void;
25
25
  /**
26
26
  * Current User decorator only has effect when being used with ICrudRepository.
27
27
  * */
@@ -61,8 +61,9 @@ 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 field = initFieldMetadata(prototype, propertyKey);
65
- field.uriMapper = mapper;
64
+ const [rootKey, ...keys] = propertyKey.split(".");
65
+ const field = initFieldMetadata(prototype, rootKey);
66
+ field.uriMapper = { mapper, subkeys: keys };
66
67
  };
67
68
  /**
68
69
  * Current User decorator only has effect when being used with ICrudRepository.
@@ -4,6 +4,32 @@ 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]];
13
+ };
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
+ }
32
+ };
7
33
  export class ModelRepository extends AbstractRepository {
8
34
  model;
9
35
  db;
@@ -129,17 +155,14 @@ export class ModelRepository extends AbstractRepository {
129
155
  //-- move from currentUri to newUri
130
156
  await fileUploadHandler.copyFile(tmpUri, newUri);
131
157
  //-- update record value and not persist yet
132
- // newUriCb(newUri);
133
158
  return newUri;
134
159
  };
135
160
  if (fileUploadHandler) {
136
161
  for (const field of this.modelMetadata.fields) {
137
162
  for (const record of records) {
138
163
  if (field.uriMapper && record[field.name]) {
139
- const mapper = field.uriMapper;
140
- const tmpUris = field.vectorProps
141
- ? record[field.name]
142
- : [record[field.name]];
164
+ const { subkeys, mapper } = field.uriMapper;
165
+ const tmpUris = resolveUris(record, field, subkeys);
143
166
  if (!tmpUris.length) {
144
167
  continue;
145
168
  }
@@ -148,34 +171,9 @@ export class ModelRepository extends AbstractRepository {
148
171
  }
149
172
  operations.push((async () => {
150
173
  const urls = await Promise.all(tmpUris.map((uri, index) => uriHandler(uri, index, mapper, getSystemLocale())));
151
- record[field.name] = field.vectorProps ? urls : urls[0];
174
+ assignUrls(record, field, subkeys, urls);
152
175
  })());
153
176
  }
154
- else if (field.multiLocaleColumn) {
155
- const targetField = this.modelMetadata.fields.find((f) => f.name === field.multiLocaleColumn);
156
- if (targetField?.uriMapper && record[field.name]) {
157
- const mapper = targetField.uriMapper;
158
- //-- this field is locale for targetField, which has uri mapper
159
- const localeUris = Object.keys(record[field.name]).map((lang) => [
160
- lang,
161
- targetField.vectorProps
162
- ? record[field.name][lang]
163
- : [record[field.name][lang]],
164
- ]);
165
- //-- for each pair or locale and tmp uri, invoke handle logic
166
- for (const localeUri of localeUris) {
167
- if (!targetField.mimeProps?.keepOnRemove) {
168
- modified.push(...localeUri[1]);
169
- }
170
- operations.push((async () => {
171
- const urls = await Promise.all(localeUri[1].map((uri, index) => uriHandler(uri, index, mapper, localeUri[0])));
172
- record[field.name][localeUri[0]] = targetField.vectorProps
173
- ? urls
174
- : urls[0];
175
- })());
176
- }
177
- }
178
- }
179
177
  }
180
178
  }
181
179
  }
@@ -196,44 +194,18 @@ export class ModelRepository extends AbstractRepository {
196
194
  const mappingOperations = [];
197
195
  for (const record of records) {
198
196
  for (const field of this.modelMetadata.fields) {
199
- if (field.uriMapper) {
200
- const uri = record[field.name];
201
- if (!uri) {
202
- continue;
203
- }
204
- const uris = field.vectorProps ? uri : [uri];
197
+ if (field.uriMapper && record[field.name]) {
198
+ const { subkeys } = field.uriMapper;
199
+ const uris = resolveUris(record, field, subkeys);
205
200
  mappingOperations.push((async () => {
206
201
  const urls = await Promise.all(uris.map(async (uri) => {
207
202
  return field.mimeProps?.public
208
203
  ? await fileUploadHandler.resolvePublicUrl(uri)
209
204
  : await fileUploadHandler.resolvePrivateUrl(uri);
210
205
  }));
211
- record[field.name] = field.vectorProps ? urls : urls[0];
206
+ assignUrls(record, field, subkeys, urls);
212
207
  })());
213
208
  }
214
- else if (field.multiLocaleColumn) {
215
- const targetField = this.modelMetadata.fields.find((f) => f.name === field.multiLocaleColumn);
216
- if (targetField?.uriMapper) {
217
- const localeObject = record[field.name];
218
- if (!localeObject) {
219
- continue;
220
- }
221
- for (const locale of Object.keys(localeObject)) {
222
- mappingOperations.push((async () => {
223
- const uri = localeObject[locale];
224
- if (!uri)
225
- return;
226
- const uris = targetField.vectorProps ? uri : [uri];
227
- const urls = await Promise.all(uris.map(async (uri) => {
228
- return targetField.mimeProps?.public
229
- ? await fileUploadHandler.resolvePublicUrl(uri)
230
- : await fileUploadHandler.resolvePrivateUrl(uri);
231
- }));
232
- localeObject[locale] = targetField.vectorProps ? urls : urls[0];
233
- })());
234
- }
235
- }
236
- }
237
209
  }
238
210
  }
239
211
  await Promise.all(mappingOperations);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clairejs/server",
3
- "version": "3.21.9",
3
+ "version": "3.22.0",
4
4
  "description": "Claire server NodeJs framework written in Typescript.",
5
5
  "types": "dist/index.d.ts",
6
6
  "main": "dist/index.js",
@@ -33,9 +33,9 @@
33
33
  "ws": "^7.5.5"
34
34
  },
35
35
  "peerDependencies": {
36
- "@clairejs/client": "^3.4.1",
37
- "@clairejs/core": "^3.8.8",
38
- "@clairejs/orm": "^3.16.7"
36
+ "@clairejs/client": "^3.4.4",
37
+ "@clairejs/core": "^3.8.9",
38
+ "@clairejs/orm": "^3.16.10"
39
39
  },
40
40
  "devDependencies": {
41
41
  "@types/cookie-parser": "^1.4.3",