@smartsoft001/crud-shell-nestjs 2.126.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.
- package/index.js +55 -82
- 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
|
|
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
|
-
|
|
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
|
-
|
|
1283
|
-
else if (op === "
|
|
1284
|
-
|
|
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
|
-
|
|
1342
|
-
if (
|
|
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
|
-
|
|
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.
|
|
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.
|
|
20
|
+
"@smartsoft001/crud-shell-app-services": "2.128.0",
|
|
21
21
|
"@smartsoft001/crud-shell-dto": "*",
|
|
22
|
-
"@smartsoft001/domain-core": "2.
|
|
22
|
+
"@smartsoft001/domain-core": "2.128.0"
|
|
23
23
|
},
|
|
24
24
|
"homepage": "https://github.com/emiljuchnikowski/smartsoft#readme"
|
|
25
25
|
}
|