@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
|
@@ -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,
|
|
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
|
|
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
|
* */
|
package/dist/http/decorators.js
CHANGED
|
@@ -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
|
|
65
|
-
|
|
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
|
|
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,
|
|
15
|
-
|
|
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
|
-
|
|
161
|
-
for (const field of
|
|
140
|
+
const mapRecords = (records, modelMetadata) => {
|
|
141
|
+
for (const field of modelMetadata.fields) {
|
|
162
142
|
for (const record of records) {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
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,
|
|
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
|
-
|
|
196
|
-
for (const
|
|
197
|
-
|
|
198
|
-
const
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
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, }) {
|