@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
|
@@ -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?:
|
|
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,
|
|
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:
|
|
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
|
* */
|
package/dist/http/decorators.js
CHANGED
|
@@ -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
|
|
65
|
-
field
|
|
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
|
|
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
|
|
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
|
|
201
|
-
|
|
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
|
|
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.
|
|
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.
|
|
37
|
-
"@clairejs/core": "^3.8.
|
|
38
|
-
"@clairejs/orm": "^3.16.
|
|
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",
|