@smartsoft001/crud-shell-nestjs 2.127.0 → 2.128.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.
Files changed (2) hide show
  1. package/index.js +55 -82
  2. package/package.json +3 -3
package/index.js CHANGED
@@ -5,8 +5,7 @@ var __decorateClass = (decorators, target, key, kind) => {
5
5
  for (var i = decorators.length - 1, decorator; i >= 0; i--)
6
6
  if (decorator = decorators[i])
7
7
  result = (kind ? decorator(target, key, result) : decorator(result)) || result;
8
- if (kind && result)
9
- __defProp(target, key, result);
8
+ if (kind && result) __defProp(target, key, result);
10
9
  return result;
11
10
  };
12
11
  var __decorateParam = (index, decorator) => (target, key) => decorator(target, key, index);
@@ -23,8 +22,8 @@ import { Guid as Guid2 } from "guid-typescript";
23
22
  import { Memoize } from "lodash-decorators";
24
23
 
25
24
  // packages/shared/models/src/lib/symbols.ts
26
- var SYMBOL_MODEL = Symbol.for("smartsoft:model");
27
- var SYMBOL_FIELD = Symbol.for("smartsoft:field");
25
+ var SYMBOL_MODEL = /* @__PURE__ */ Symbol.for("smartsoft:model");
26
+ var SYMBOL_FIELD = /* @__PURE__ */ Symbol.for("smartsoft:field");
28
27
 
29
28
  // packages/shared/models/src/lib/decorators/model/model.decorator.ts
30
29
  import "reflect-metadata";
@@ -56,11 +55,9 @@ var ObjectService = class {
56
55
  * @return - new type object
57
56
  */
58
57
  static createByType(data, type) {
59
- if (!data)
60
- return data;
58
+ if (!data) return data;
61
59
  try {
62
- if (data instanceof type)
63
- return data;
60
+ if (data instanceof type) return data;
64
61
  } catch (e) {
65
62
  console.warn(e);
66
63
  }
@@ -76,8 +73,7 @@ var ObjectService = class {
76
73
  * @return - object without type
77
74
  */
78
75
  static removeTypes(obj) {
79
- if (!obj)
80
- return obj;
76
+ if (!obj) return obj;
81
77
  const result = {};
82
78
  Object.keys(obj).forEach((key) => {
83
79
  if (obj[key] && obj[key].constructor && !(obj[key] instanceof Date)) {
@@ -121,8 +117,7 @@ var PasswordService = class _PasswordService {
121
117
 
122
118
  // packages/shared/models/src/lib/utils.ts
123
119
  function getModelFieldKeys(type) {
124
- if (!type["__fields"])
125
- return [];
120
+ if (!type["__fields"]) return [];
126
121
  return Object.keys(type["__fields"]);
127
122
  }
128
123
  function getModelFieldOptions(instance, fieldKey) {
@@ -138,8 +133,7 @@ function getModelFieldsWithOptions(instance) {
138
133
  });
139
134
  }
140
135
  function isModel(instance) {
141
- if (!instance || !instance.constructor)
142
- return false;
136
+ if (!instance || !instance.constructor) return false;
143
137
  return Reflect.hasMetadata(SYMBOL_MODEL, instance.constructor);
144
138
  }
145
139
  function getInvalidFields(instance, mode, permissions) {
@@ -160,8 +154,7 @@ function getInvalidFields(instance, mode, permissions) {
160
154
  return result;
161
155
  }
162
156
  function castModel(instance, mode, permissions) {
163
- if (!isModel(instance))
164
- return;
157
+ if (!isModel(instance)) return;
165
158
  const fieldsWithOptions = getModelFieldsWithOptions(instance);
166
159
  Object.keys(instance).filter((key) => key !== "id").forEach((key) => {
167
160
  const fieldWidthOptions = fieldsWithOptions.find((f) => f.key === key);
@@ -208,6 +201,9 @@ var CrudService = class {
208
201
  this.repository = repository;
209
202
  this.attachmentRepository = attachmentRepository;
210
203
  }
204
+ permissionService;
205
+ repository;
206
+ attachmentRepository;
211
207
  _logger = new Logger(CrudService.name, { timestamp: true });
212
208
  async create(data, user) {
213
209
  data.id = Guid2.raw();
@@ -345,8 +341,7 @@ var CrudService = class {
345
341
  data.id = GuidService.create();
346
342
  }
347
343
  this.attachmentRepository.upload(data, options);
348
- if (oldId)
349
- await this.attachmentRepository.delete(data.id);
344
+ if (oldId) await this.attachmentRepository.delete(data.id);
350
345
  return data.id;
351
346
  }
352
347
  getAttachmentInfo(id) {
@@ -374,8 +369,7 @@ var CrudService = class {
374
369
  }
375
370
  }
376
371
  checkValidUpdatePartial(item, permissions) {
377
- if (!isModel(item))
378
- return;
372
+ if (!isModel(item)) return;
379
373
  const keys = Object.keys(item);
380
374
  const array = getInvalidFields(item, "update", permissions)?.filter(
381
375
  (invalidField) => keys.some((key) => key === invalidField)
@@ -416,8 +410,7 @@ function getMongoUrl(config) {
416
410
  let url;
417
411
  if (config.username && config.password)
418
412
  url = `mongodb://${config.username}:${config.password}@${config.host}:${config.port}`;
419
- else
420
- url = `mongodb://${config.host}:${config.port}`;
413
+ else url = `mongodb://${config.host}:${config.port}`;
421
414
  url = url + "?authSource=" + config.database;
422
415
  if (config.host.indexOf("ondigitalocean.com") > -1) {
423
416
  url = url.replace("mongodb://", "mongodb+srv://");
@@ -432,6 +425,7 @@ var MongoUnitOfWork = class extends IUnitOfWork {
432
425
  super();
433
426
  this.config = config;
434
427
  }
428
+ config;
435
429
  async scope(definition) {
436
430
  const client = await MongoClient.connect(this.getUrl());
437
431
  const session = client.startSession();
@@ -454,8 +448,7 @@ var MongoUnitOfWork = class extends IUnitOfWork {
454
448
  await session.endSession();
455
449
  await client.close();
456
450
  }
457
- if (error)
458
- throw error;
451
+ if (error) throw error;
459
452
  }
460
453
  getUrl() {
461
454
  return getMongoUrl(this.config);
@@ -474,6 +467,7 @@ var MongoAttachmentRepository = class extends IAttachmentRepository {
474
467
  super();
475
468
  this.config = config;
476
469
  }
470
+ config;
477
471
  async upload(data, options) {
478
472
  const client = await MongoClient2.connect(this.getUrl());
479
473
  return await new Promise((res, rej) => {
@@ -485,11 +479,10 @@ var MongoAttachmentRepository = class extends IAttachmentRepository {
485
479
  data.id,
486
480
  data.fileName,
487
481
  {
488
- contentType: data.mimeType
482
+ metadata: { contentType: data.mimeType }
489
483
  }
490
484
  );
491
- if (options?.streamCallback)
492
- options.streamCallback(writeStream);
485
+ if (options?.streamCallback) options.streamCallback(writeStream);
493
486
  data.stream.pipe(writeStream);
494
487
  writeStream.on("error", (error) => {
495
488
  rej(error);
@@ -508,11 +501,12 @@ var MongoAttachmentRepository = class extends IAttachmentRepository {
508
501
  const items = await bucket.find({
509
502
  _id: id
510
503
  }).toArray();
511
- if (!items || items.length === 0)
512
- return null;
504
+ if (!items || items.length === 0) return null;
513
505
  return {
514
506
  fileName: items[0].filename,
515
- contentType: items[0].contentType,
507
+ // mongodb 7 removed the deprecated top-level contentType - files written
508
+ // by older driver versions still carry it, so fall back to it
509
+ contentType: items[0].metadata?.["contentType"] ?? items[0].contentType,
516
510
  length: items[0].length
517
511
  };
518
512
  }
@@ -553,6 +547,7 @@ var MongoItemRepository = class extends IItemRepository {
553
547
  super();
554
548
  this.config = config;
555
549
  }
550
+ config;
556
551
  async create(item, user, repoOptions) {
557
552
  await this.collectionContext(async (collection) => {
558
553
  try {
@@ -868,8 +863,7 @@ var MongoItemRepository = class extends IItemRepository {
868
863
  return result;
869
864
  }
870
865
  getModelToResult(item) {
871
- if (!item)
872
- return null;
866
+ if (!item) return null;
873
867
  const result = ObjectService.removeTypes(item);
874
868
  result["id"] = result._id;
875
869
  delete result._id;
@@ -899,8 +893,7 @@ var MongoItemRepository = class extends IItemRepository {
899
893
  }
900
894
  }
901
895
  generateSearch(criteria) {
902
- if (!criteria["$search"])
903
- return;
896
+ if (!criteria["$search"]) return;
904
897
  if (this.config.type) {
905
898
  const modelFields = getModelFieldsWithOptions(
906
899
  new this.config.type()
@@ -915,8 +908,7 @@ var MongoItemRepository = class extends IItemRepository {
915
908
  };
916
909
  searchArray.push(res);
917
910
  });
918
- if (!criteria["$or"])
919
- criteria["$or"] = searchArray;
911
+ if (!criteria["$or"]) criteria["$or"] = searchArray;
920
912
  else if (criteria["$or"] && !criteria["$and"]) {
921
913
  criteria["$and"] = [{ $or: criteria["$or"] }, { $or: searchArray }];
922
914
  delete criteria["$or"];
@@ -1003,6 +995,7 @@ var JwtStrategy = class extends PassportStrategy(Strategy) {
1003
995
  });
1004
996
  this.config = config;
1005
997
  }
998
+ config;
1006
999
  async validate(payload) {
1007
1000
  return {
1008
1001
  ...payload,
@@ -1021,6 +1014,7 @@ var PermissionService = class {
1021
1014
  constructor(config) {
1022
1015
  this.config = config;
1023
1016
  }
1017
+ config;
1024
1018
  /**
1025
1019
  * Validates if the user has the required permissions for a given type.
1026
1020
  * @param {PermissionType} type - The type of permission to validate.
@@ -1028,13 +1022,10 @@ var PermissionService = class {
1028
1022
  * @throws {DomainForbiddenError} If the user does not have the required permissions.
1029
1023
  */
1030
1024
  valid(type, user) {
1031
- if (!this.config.permissions)
1032
- return;
1025
+ if (!this.config.permissions) return;
1033
1026
  const typeConfig = this.config.permissions[type];
1034
- if (!typeConfig)
1035
- return;
1036
- if (!user.permissions)
1037
- throw new DomainForbiddenError(`Context forbidden`);
1027
+ if (!typeConfig) return;
1028
+ if (!user.permissions) throw new DomainForbiddenError(`Context forbidden`);
1038
1029
  if (!typeConfig.some((tc) => user.permissions.some((up) => tc === up)))
1039
1030
  throw new DomainForbiddenError(`Context forbidden`);
1040
1031
  }
@@ -1172,8 +1163,7 @@ import { Readable } from "stream";
1172
1163
  import * as querystring from "querystring";
1173
1164
  var iso8601 = /^\d{4}(-(0[1-9]|1[0-2])(-(0[1-9]|[12][0-9]|3[01]))?)?(T([01][0-9]|2[0-3]):[0-5]\d(:[0-5]\d(\.\d+)?)?(Z|[+-]\d{2}:\d{2}))?$/;
1174
1165
  function fieldsToMongo(fields) {
1175
- if (!fields)
1176
- return null;
1166
+ if (!fields) return null;
1177
1167
  const hash = {};
1178
1168
  fields.split(",").forEach(function(field) {
1179
1169
  hash[field.trim()] = 1;
@@ -1184,8 +1174,7 @@ function convertRegex(val) {
1184
1174
  return val.toString().replace(/\*/g, "[*]");
1185
1175
  }
1186
1176
  function omitFieldsToMongo(omitFields) {
1187
- if (!omitFields)
1188
- return null;
1177
+ if (!omitFields) return null;
1189
1178
  const hash = {};
1190
1179
  omitFields.split(",").forEach(function(omitField) {
1191
1180
  hash[omitField.trim()] = 0;
@@ -1193,21 +1182,18 @@ function omitFieldsToMongo(omitFields) {
1193
1182
  return hash;
1194
1183
  }
1195
1184
  function sortToMongo(sort) {
1196
- if (!sort)
1197
- return null;
1185
+ if (!sort) return null;
1198
1186
  const hash = {};
1199
1187
  let c;
1200
1188
  sort.split(",").forEach(function(field) {
1201
1189
  c = field.charAt(0);
1202
- if (c === "-")
1203
- field = field.substr(1);
1190
+ if (c === "-") field = field.substr(1);
1204
1191
  hash[field.trim()] = c === "-" ? -1 : 1;
1205
1192
  });
1206
1193
  return hash;
1207
1194
  }
1208
1195
  function typedValue(value) {
1209
- if (value[0] === "!")
1210
- value = value.substr(1);
1196
+ if (value[0] === "!") value = value.substr(1);
1211
1197
  const regex = value.match(/^\/(.*)\/(i?)$/);
1212
1198
  const quotedString = value.match(/(["'])(?:\\\1|.)*?\1/);
1213
1199
  if (regex) {
@@ -1238,13 +1224,11 @@ function comparisonToMongo(key, value) {
1238
1224
  const parts = join.match(/^(!?[^><~!=:]+)(?:=?([><]=?|~?=|!?=|:.+=)(.+))?$/);
1239
1225
  let op;
1240
1226
  const hash = {};
1241
- if (!parts)
1242
- return null;
1227
+ if (!parts) return null;
1243
1228
  key = parts[1];
1244
1229
  op = parts[2];
1245
1230
  if (!op) {
1246
- if (key[0] !== "!")
1247
- value = { $exists: true };
1231
+ if (key[0] !== "!") value = { $exists: true };
1248
1232
  else {
1249
1233
  key = key.substr(1);
1250
1234
  value = { $exists: false };
@@ -1252,8 +1236,7 @@ function comparisonToMongo(key, value) {
1252
1236
  } else if (op === "=" && parts[3] === "!") {
1253
1237
  value = { $exists: false };
1254
1238
  } else if (op === "=" || op === "!=") {
1255
- if (op === "=" && parts[3][0] === "!")
1256
- op = "!=";
1239
+ if (op === "=" && parts[3][0] === "!") op = "!=";
1257
1240
  const array = typedValues(parts[3]);
1258
1241
  if (array.length > 1) {
1259
1242
  value = {};
@@ -1278,14 +1261,10 @@ function comparisonToMongo(key, value) {
1278
1261
  value[op] = array.length === 1 ? array[0] : array;
1279
1262
  } else {
1280
1263
  value = typedValue(parts[3]);
1281
- if (op === ">")
1282
- value = { $gt: value };
1283
- else if (op === ">=")
1284
- value = { $gte: value };
1285
- else if (op === "<")
1286
- value = { $lt: value };
1287
- else if (op === "<=")
1288
- value = { $lte: value };
1264
+ if (op === ">") value = { $gt: value };
1265
+ else if (op === ">=") value = { $gte: value };
1266
+ else if (op === "<") value = { $lt: value };
1267
+ else if (op === "<=") value = { $lte: value };
1289
1268
  else if (op === "~=")
1290
1269
  value = {
1291
1270
  $regex: value ? convertRegex(value) : "",
@@ -1299,8 +1278,7 @@ function comparisonToMongo(key, value) {
1299
1278
  function hasOrdinalKeys(obj) {
1300
1279
  let c = 0;
1301
1280
  for (const key in obj) {
1302
- if (Number(key) !== c++)
1303
- return false;
1281
+ if (Number(key) !== c++) return false;
1304
1282
  }
1305
1283
  return true;
1306
1284
  }
@@ -1337,12 +1315,9 @@ function queryCriteriaToMongo(query, options = null) {
1337
1315
  function queryOptionsToMongo(query, options) {
1338
1316
  const hash = {}, fields = fieldsToMongo(query[options.keywords.fields]), omitFields = omitFieldsToMongo(query[options.keywords.omit]), sort = sortToMongo(query[options.keywords.sort]), maxLimit = options.maxLimit || 9007199254740992;
1339
1317
  let limit = options.maxLimit || 0;
1340
- if (fields)
1341
- hash.fields = fields;
1342
- if (omitFields)
1343
- hash.fields = omitFields;
1344
- if (sort)
1345
- hash.sort = sort;
1318
+ if (fields) hash.fields = fields;
1319
+ if (omitFields) hash.fields = omitFields;
1320
+ if (sort) hash.sort = sort;
1346
1321
  if (query[options.keywords.offset])
1347
1322
  hash.skip = Number(query[options.keywords.offset]);
1348
1323
  if (query[options.keywords.limit])
@@ -1379,10 +1354,8 @@ function q2m(query = null, options = null) {
1379
1354
  options.ignore = typeof options.ignore === "string" ? [options.ignore] : options.ignore;
1380
1355
  }
1381
1356
  options.ignore = options.ignore.concat(ignoreKeywords);
1382
- if (!options.parser)
1383
- options.parser = querystring;
1384
- if (typeof query === "string")
1385
- query = options.parser.parse(query);
1357
+ if (!options.parser) options.parser = querystring;
1358
+ if (typeof query === "string") query = options.parser.parse(query);
1386
1359
  return {
1387
1360
  criteria: queryCriteriaToMongo(query, options),
1388
1361
  options: queryOptionsToMongo(query, options),
@@ -1391,8 +1364,7 @@ function q2m(query = null, options = null) {
1391
1364
  const limit = Math.min(this.options.limit || 0, totalCount);
1392
1365
  const links = {};
1393
1366
  const last = {};
1394
- if (!limit)
1395
- return null;
1367
+ if (!limit) return null;
1396
1368
  options = options || {};
1397
1369
  if (offset > 0) {
1398
1370
  query[options.keywords.offset] = Math.max(offset - limit, 0);
@@ -1443,6 +1415,7 @@ var CrudController = class {
1443
1415
  constructor(service) {
1444
1416
  this.service = service;
1445
1417
  }
1418
+ service;
1446
1419
  static getLink(req) {
1447
1420
  return req.protocol + "://" + req.headers.host + req.url;
1448
1421
  }
@@ -1629,8 +1602,7 @@ var CrudController = class {
1629
1602
  if (!fields.some((f) => f === baseKey + key))
1630
1603
  fields.push(baseKey + key);
1631
1604
  } else {
1632
- if (!fields.some((f) => f === key))
1633
- fields.push(key);
1605
+ if (!fields.some((f) => f === key)) fields.push(key);
1634
1606
  }
1635
1607
  });
1636
1608
  };
@@ -1730,6 +1702,7 @@ var CrudGateway = class {
1730
1702
  constructor(service) {
1731
1703
  this.service = service;
1732
1704
  }
1705
+ service;
1733
1706
  _clientsSubscriptions;
1734
1707
  handleFilter(data, client) {
1735
1708
  const event = "changes";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smartsoft001/crud-shell-nestjs",
3
- "version": "2.127.0",
3
+ "version": "2.128.0",
4
4
  "description": "Utils to crud",
5
5
  "repository": {
6
6
  "type": "git",
@@ -17,9 +17,9 @@
17
17
  "url": "https://github.com/emiljuchnikowski/smartsoft/issues"
18
18
  },
19
19
  "peerDependencies": {
20
- "@smartsoft001/crud-shell-app-services": "2.127.0",
20
+ "@smartsoft001/crud-shell-app-services": "2.128.0",
21
21
  "@smartsoft001/crud-shell-dto": "*",
22
- "@smartsoft001/domain-core": "2.127.0"
22
+ "@smartsoft001/domain-core": "2.128.0"
23
23
  },
24
24
  "homepage": "https://github.com/emiljuchnikowski/smartsoft#readme"
25
25
  }