@loomcore/api 0.0.37 → 0.0.39
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.
|
@@ -32,10 +32,12 @@ export interface IProduct extends IEntity, IAuditable {
|
|
|
32
32
|
category?: ICategory;
|
|
33
33
|
}
|
|
34
34
|
export declare const CategorySchema: import("@sinclair/typebox").TObject<{
|
|
35
|
+
_id: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
35
36
|
name: import("@sinclair/typebox").TString;
|
|
36
37
|
}>;
|
|
37
38
|
export declare const CategorySpec: import("@loomcore/common/models").IModelSpec<import("@sinclair/typebox").TSchema>;
|
|
38
39
|
export declare const ProductSchema: import("@sinclair/typebox").TObject<{
|
|
40
|
+
_id: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
39
41
|
name: import("@sinclair/typebox").TString;
|
|
40
42
|
description: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
41
43
|
internalNumber: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
@@ -2,6 +2,7 @@ import { ObjectId } from 'mongodb';
|
|
|
2
2
|
import crypto from 'crypto';
|
|
3
3
|
import jwt from 'jsonwebtoken';
|
|
4
4
|
import { Type } from '@sinclair/typebox';
|
|
5
|
+
import { TypeboxObjectId } from '@loomcore/common/validation';
|
|
5
6
|
import { JwtService } from '../services/jwt.service.js';
|
|
6
7
|
import { passwordUtils } from '../utils/password.utils.js';
|
|
7
8
|
import { AuthService } from '../services/auth.service.js';
|
|
@@ -174,14 +175,16 @@ function verifyToken(token) {
|
|
|
174
175
|
return JwtService.verify(token, JWT_SECRET);
|
|
175
176
|
}
|
|
176
177
|
export const CategorySchema = Type.Object({
|
|
178
|
+
_id: Type.Optional(TypeboxObjectId()),
|
|
177
179
|
name: Type.String(),
|
|
178
180
|
});
|
|
179
181
|
export const CategorySpec = entityUtils.getModelSpec(CategorySchema);
|
|
180
182
|
export const ProductSchema = Type.Object({
|
|
183
|
+
_id: Type.Optional(TypeboxObjectId()),
|
|
181
184
|
name: Type.String(),
|
|
182
185
|
description: Type.Optional(Type.String()),
|
|
183
186
|
internalNumber: Type.Optional(Type.String()),
|
|
184
|
-
categoryId:
|
|
187
|
+
categoryId: TypeboxObjectId({ title: 'Category ID' }),
|
|
185
188
|
});
|
|
186
189
|
export const ProductSpec = entityUtils.getModelSpec(ProductSchema, { isAuditable: true });
|
|
187
190
|
export const PublicProductSchema = Type.Omit(ProductSpec.fullSchema, ['internalNumber']);
|
|
@@ -195,6 +195,16 @@ export class GenericApiService {
|
|
|
195
195
|
const entities = await this.onBeforeUpdate(userContext, preparedEntities);
|
|
196
196
|
const operations = [];
|
|
197
197
|
const entityIds = [];
|
|
198
|
+
console.log('--- DIAGNOSTICS: Entities received in batchUpdate ---');
|
|
199
|
+
entities.forEach((entity, index) => {
|
|
200
|
+
const entityWithId = entity;
|
|
201
|
+
if (entityWithId && entityWithId._id) {
|
|
202
|
+
console.log(` [${index}]: ID is ${entityWithId._id.toString()}, Type is ${entityWithId._id.constructor.name}`);
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
console.log(` [${index}]: Entity has no _id or is null.`);
|
|
206
|
+
}
|
|
207
|
+
});
|
|
198
208
|
for (const entity of entities) {
|
|
199
209
|
const { _id, ...updateData } = entity;
|
|
200
210
|
if (!_id || !(_id instanceof ObjectId)) {
|
|
@@ -407,12 +417,29 @@ export class GenericApiService {
|
|
|
407
417
|
}
|
|
408
418
|
let cleanedEntity = preparedEntity;
|
|
409
419
|
if (this.modelSpec) {
|
|
420
|
+
let entityId = null;
|
|
421
|
+
if (allowId) {
|
|
422
|
+
console.log(`_id is present and equals ${preparedEntity._id}`);
|
|
423
|
+
entityId = preparedEntity._id;
|
|
424
|
+
}
|
|
410
425
|
cleanedEntity = this.modelSpec.decode(preparedEntity);
|
|
426
|
+
if (allowId && entityId) {
|
|
427
|
+
console.log(`after decode, restoring _id to ${entityId}`);
|
|
428
|
+
cleanedEntity._id = entityId;
|
|
429
|
+
}
|
|
411
430
|
}
|
|
412
431
|
if (!this.modelSpec?.fullSchema) {
|
|
413
432
|
throw new ServerError(`Cannot prepare entity: No model specification with schema provided for ${this.pluralResourceName}`);
|
|
414
433
|
}
|
|
415
|
-
|
|
434
|
+
const finalEntity = dbUtils.convertStringsToObjectIds(cleanedEntity, this.modelSpec.fullSchema);
|
|
435
|
+
const finalEntityWithId = finalEntity;
|
|
436
|
+
if (finalEntityWithId && finalEntityWithId._id) {
|
|
437
|
+
console.log(`--- DIAGNOSTICS: In prepareEntity, after conversion, ID is ${finalEntityWithId._id.toString()}, Type is ${finalEntityWithId._id.constructor.name} ---`);
|
|
438
|
+
}
|
|
439
|
+
else {
|
|
440
|
+
console.log('--- DIAGNOSTICS: In prepareEntity, after conversion, entity has no _id or is null. ---');
|
|
441
|
+
}
|
|
442
|
+
return finalEntity;
|
|
416
443
|
}
|
|
417
444
|
prepareQuery(userContext, query) {
|
|
418
445
|
return query;
|