nicot 1.1.33 → 1.1.35

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
@@ -192,7 +192,7 @@ RestfulFactory 处理 Entity 类的时候,会以这些装饰器为依据,裁
192
192
  nickname: string;
193
193
 
194
194
  @BoolColumn()
195
- @QueryEqual()
195
+ @QueryMatchBoolean()
196
196
  isActive: boolean;
197
197
  ```
198
198
 
@@ -209,6 +209,7 @@ NICOT 提供了一套查询装饰器,用于在 Entity 字段上声明支持的
209
209
  | `@QueryEqual()` | 精确匹配:`WHERE field = :value` |
210
210
  | `@QueryLike()` | 前缀模糊匹配:`WHERE field LIKE :value%` |
211
211
  | `@QuerySearch()` | 宽泛模糊搜索:`WHERE field LIKE %:value%` |
212
+ | `@QueryMatchBoolean()` | `true/false/1/0` 转换为布尔类型查询 |
212
213
  | `@QueryEqualZeroNullable()` | `0 → IS NULL`,否则 `= :value`(适合 nullable) |
213
214
  | `@QueryGreater(field)` | 大于查询:`WHERE field > :value` |
214
215
  | `@QueryLess(field)` | 小于查询:`WHERE field < :value` |
@@ -286,7 +287,7 @@ views: number;
286
287
  title: string;
287
288
 
288
289
  @BoolColumn()
289
- @QueryEqual()
290
+ @QueryMatchBoolean()
290
291
  isPublished: boolean;
291
292
 
292
293
  @NotWritable()
@@ -473,7 +474,7 @@ NICOT 提供了 `RestfulFactory(Entity)` 工厂函数,自动为实体生成标
473
474
  name: string;
474
475
 
475
476
  @BoolColumn()
476
- @QueryEqual()
477
+ @QueryMatchBoolean()
477
478
  isActive: boolean;
478
479
  ```
479
480
 
package/dist/index.cjs CHANGED
@@ -75,18 +75,23 @@ __export(index_exports, {
75
75
  QueryLessEqual: () => QueryLessEqual,
76
76
  QueryLike: () => QueryLike,
77
77
  QueryMatchBoolean: () => QueryMatchBoolean,
78
+ QueryMatchBooleanMySQL: () => QueryMatchBooleanMySQL,
78
79
  QueryNotEqual: () => QueryNotEqual,
79
80
  QueryOperator: () => QueryOperator,
80
81
  QuerySearch: () => QuerySearch,
81
82
  Relation: () => Relation,
82
83
  RelationComputed: () => RelationComputed,
83
84
  RestfulFactory: () => RestfulFactory,
85
+ SimpleJsonColumn: () => SimpleJsonColumn,
84
86
  StringColumn: () => StringColumn,
85
87
  StringIdBase: () => StringIdBase,
88
+ StringJsonColumn: () => StringJsonColumn,
89
+ TextColumn: () => TextColumn,
86
90
  TimeBase: () => TimeBase,
87
91
  UpdatePipe: () => UpdatePipe,
88
92
  UuidColumn: () => UuidColumn,
89
93
  applyQueryMatchBoolean: () => applyQueryMatchBoolean,
94
+ applyQueryMatchBooleanMySQL: () => applyQueryMatchBooleanMySQL,
90
95
  applyQueryProperty: () => applyQueryProperty,
91
96
  applyQueryPropertyLike: () => applyQueryPropertyLike,
92
97
  applyQueryPropertySearch: () => applyQueryPropertySearch,
@@ -273,10 +278,52 @@ var TypeTransformer = class {
273
278
  return entValue;
274
279
  }
275
280
  };
281
+ var TypeTransformerString = class extends TypeTransformer {
282
+ from(dbValue) {
283
+ if (dbValue == null) {
284
+ return dbValue;
285
+ }
286
+ return super.from(JSON.parse(dbValue));
287
+ }
288
+ to(entValue) {
289
+ if (entValue == null) {
290
+ return entValue;
291
+ }
292
+ return JSON.stringify(super.to(entValue));
293
+ }
294
+ };
295
+
296
+ // src/utility/parse-bool.ts
297
+ var parseBool = (value) => {
298
+ const trueValues = ["true", "1", "yes", "on", true, 1];
299
+ const falseValues = ["false", "0", "no", "off", false, 0];
300
+ if (trueValues.indexOf(value) !== -1) return true;
301
+ if (falseValues.indexOf(value) !== -1) return false;
302
+ if (!!value) {
303
+ return true;
304
+ }
305
+ return void 0;
306
+ };
307
+ var parseBoolObject = (obj, boolFields) => {
308
+ const newObj = { ...obj };
309
+ for (const field of boolFields) {
310
+ newObj[field] = parseBool(newObj[field]);
311
+ }
312
+ return newObj;
313
+ };
314
+ var ParseBoolObjectPipe = class {
315
+ constructor(boolFields) {
316
+ this.boolFields = boolFields;
317
+ }
318
+ transform(obj) {
319
+ return parseBoolObject(obj, this.boolFields);
320
+ }
321
+ };
276
322
 
277
323
  // src/decorators/property.ts
278
324
  function swaggerDecorator(options, injected = {}) {
279
- return (0, import_swagger2.ApiProperty)({
325
+ const notRequiredButHasDefault = options.required == null && options.default != null;
326
+ const apiPropertyDec = (0, import_swagger2.ApiProperty)({
280
327
  default: options.default,
281
328
  required: !!(options.required && options.default == null),
282
329
  example: options.default,
@@ -284,6 +331,18 @@ function swaggerDecorator(options, injected = {}) {
284
331
  ...injected,
285
332
  ...options.propertyExtras || {}
286
333
  });
334
+ if (notRequiredButHasDefault) {
335
+ return (0, import_nesties3.MergePropertyDecorators)([
336
+ apiPropertyDec,
337
+ Metadata.set(
338
+ "notRequiredButHasDefault",
339
+ true,
340
+ "notRequiredButHasDefaultFields"
341
+ )
342
+ ]);
343
+ } else {
344
+ return apiPropertyDec;
345
+ }
287
346
  }
288
347
  function validatorDecorator(options) {
289
348
  const decs = [];
@@ -302,13 +361,24 @@ function columnDecoratorOptions(options) {
302
361
  }
303
362
  var StringColumn = (length, options = {}) => {
304
363
  return (0, import_nesties3.MergePropertyDecorators)([
305
- (0, import_typeorm.Column)("varchar", { length, ...columnDecoratorOptions(options) }),
364
+ (0, import_typeorm.Column)(options.columnType || "varchar", {
365
+ length,
366
+ ...columnDecoratorOptions(options)
367
+ }),
306
368
  (0, import_class_validator3.IsString)(),
307
369
  (0, import_class_validator3.MaxLength)(length),
308
370
  validatorDecorator(options),
309
371
  swaggerDecorator(options, { type: String, maxLength: length })
310
372
  ]);
311
373
  };
374
+ var TextColumn = (options = {}) => {
375
+ return (0, import_nesties3.MergePropertyDecorators)([
376
+ (0, import_typeorm.Column)(options.columnType || "text", columnDecoratorOptions(options)),
377
+ (0, import_class_validator3.IsString)(),
378
+ validatorDecorator(options),
379
+ swaggerDecorator(options, { type: String })
380
+ ]);
381
+ };
312
382
  var UuidColumn = (options = {}) => {
313
383
  return (0, import_nesties3.MergePropertyDecorators)([
314
384
  (0, import_typeorm.Column)("uuid", {
@@ -327,8 +397,28 @@ var UuidColumn = (options = {}) => {
327
397
  })
328
398
  ]);
329
399
  };
400
+ var intMaxList = {
401
+ tinyint: 127,
402
+ smallint: 32767,
403
+ mediumint: 8388607,
404
+ int: 2147483647,
405
+ bigint: Number.MAX_SAFE_INTEGER
406
+ };
330
407
  var IntColumn = (type, options = {}) => {
331
- const decs = [
408
+ let max = intMaxList[type] || Number.MAX_SAFE_INTEGER;
409
+ if (max !== Number.MAX_SAFE_INTEGER && options.unsigned) {
410
+ max = max * 2 + 1;
411
+ }
412
+ let min = options.unsigned ? 0 : -max - 1;
413
+ if (options.range) {
414
+ if (typeof options.range.min === "number" && options.range.min > min) {
415
+ min = options.range.min;
416
+ }
417
+ if (typeof options.range.max === "number" && options.range.max < max) {
418
+ max = options.range.max;
419
+ }
420
+ }
421
+ return (0, import_nesties3.MergePropertyDecorators)([
332
422
  (0, import_typeorm.Column)(type, {
333
423
  default: options.default,
334
424
  unsigned: options.unsigned,
@@ -336,39 +426,53 @@ var IntColumn = (type, options = {}) => {
336
426
  ...columnDecoratorOptions(options)
337
427
  }),
338
428
  (0, import_class_validator3.IsInt)(),
429
+ ...min > Number.MIN_SAFE_INTEGER ? [(0, import_class_validator3.Min)(min)] : [],
430
+ ...max < Number.MAX_SAFE_INTEGER ? [(0, import_class_validator3.Max)(max)] : [],
339
431
  validatorDecorator(options),
340
432
  swaggerDecorator(options, {
341
433
  type: Number,
342
- minimum: options.unsigned ? 0 : void 0
434
+ minimum: min > Number.MIN_SAFE_INTEGER ? min : void 0,
435
+ maximum: max < Number.MAX_SAFE_INTEGER ? max : void 0
343
436
  })
344
- ];
345
- if (options.unsigned) {
346
- decs.push((0, import_class_validator3.Min)(0));
347
- }
348
- return (0, import_nesties3.MergePropertyDecorators)(decs);
437
+ ]);
349
438
  };
350
439
  var FloatColumn = (type, options = {}) => {
351
- const decs = [
440
+ let min = options.unsigned ? 0 : Number.MIN_SAFE_INTEGER;
441
+ let max = Number.MAX_SAFE_INTEGER;
442
+ if (options.columnExtras?.precision != null && options.columnExtras?.scale != null) {
443
+ const precision = options.columnExtras.precision;
444
+ const scale = options.columnExtras.scale;
445
+ const intDigits = precision - scale;
446
+ if (intDigits > 0) {
447
+ const maxIntPart = Math.pow(10, intDigits) - 1;
448
+ const maxDecimalPart = scale > 0 ? (Math.pow(10, scale) - 1) / Math.pow(10, scale) : 0;
449
+ max = maxIntPart + maxDecimalPart;
450
+ min = options.unsigned ? 0 : -max;
451
+ }
452
+ }
453
+ return (0, import_nesties3.MergePropertyDecorators)([
352
454
  (0, import_typeorm.Column)(type, {
353
455
  default: options.default,
354
456
  unsigned: options.unsigned,
355
457
  ...columnDecoratorOptions(options)
356
458
  }),
357
459
  (0, import_class_validator3.IsNumber)(),
460
+ ...min > Number.MIN_SAFE_INTEGER ? [(0, import_class_validator3.Min)(min)] : [],
461
+ ...max < Number.MAX_SAFE_INTEGER ? [(0, import_class_validator3.Max)(max)] : [],
358
462
  validatorDecorator(options),
359
463
  swaggerDecorator(options, {
360
464
  type: Number,
361
- minimum: options.unsigned ? 0 : void 0
465
+ minimum: min > Number.MIN_SAFE_INTEGER ? min : void 0,
466
+ maximum: max < Number.MAX_SAFE_INTEGER ? max : void 0
362
467
  })
363
- ];
364
- if (options.unsigned) {
365
- decs.push((0, import_class_validator3.Min)(0));
366
- }
367
- return (0, import_nesties3.MergePropertyDecorators)(decs);
468
+ ]);
368
469
  };
369
470
  var DateColumn = (options = {}) => {
370
471
  return (0, import_nesties3.MergePropertyDecorators)([
371
- (0, import_typeorm.Column)("timestamp", columnDecoratorOptions(options)),
472
+ (0, import_typeorm.Column)(
473
+ options.columnType || "timestamp",
474
+ columnDecoratorOptions(options)
475
+ ),
372
476
  (0, import_class_validator3.IsDate)(),
373
477
  (0, import_class_transformer3.Transform)(
374
478
  (v) => {
@@ -408,31 +512,33 @@ var EnumColumn = (targetEnum, options = {}) => {
408
512
  var BoolColumn = (options = {}) => (0, import_nesties3.MergePropertyDecorators)([
409
513
  (0, import_typeorm.Index)(),
410
514
  (0, import_class_transformer3.Transform)((v) => {
411
- const trueValues = ["true", "1", "yes", "on", true, 1];
412
- const falseValues = ["false", "0", "no", "off", false, 0];
413
- if (trueValues.indexOf(v.value) !== -1) return true;
414
- if (falseValues.indexOf(v.value) !== -1) return false;
415
- return void 0;
515
+ return parseBool(v.value);
416
516
  }),
417
517
  (0, import_typeorm.Column)("boolean", columnDecoratorOptions(options)),
418
518
  validatorDecorator(options),
419
519
  swaggerDecorator(options, { type: Boolean }),
420
520
  Metadata.set("boolColumn", true, "boolColumnFields")
421
521
  ]);
422
- var JsonColumn = (definition, options = {}) => {
522
+ var createJsonColumnDef = (columnType = "jsonb", typeTransformerClass = TypeTransformer) => (definition, options = {}) => {
423
523
  const cl = (0, import_nesties4.getClassFromClassOrArray)(definition);
424
524
  return (0, import_nesties3.MergePropertyDecorators)([
425
525
  NotQueryable(),
426
526
  (0, import_class_transformer3.Type)(() => cl),
427
527
  (0, import_class_validator3.ValidateNested)(),
428
- (0, import_typeorm.Column)("jsonb", {
528
+ (0, import_typeorm.Column)(options.columnType || columnType, {
429
529
  ...columnDecoratorOptions(options),
430
- transformer: new TypeTransformer(definition)
530
+ transformer: new typeTransformerClass(definition)
431
531
  }),
432
532
  validatorDecorator(options),
433
533
  swaggerDecorator(options, { type: definition })
434
534
  ]);
435
535
  };
536
+ var JsonColumn = createJsonColumnDef();
537
+ var SimpleJsonColumn = createJsonColumnDef("json");
538
+ var StringJsonColumn = createJsonColumnDef(
539
+ "text",
540
+ TypeTransformerString
541
+ );
436
542
  var NotColumn = (options = {}, specials = {}) => (0, import_nesties3.MergePropertyDecorators)([
437
543
  (0, import_class_transformer3.Exclude)(),
438
544
  swaggerDecorator({
@@ -527,15 +633,26 @@ var applyQueryPropertyZeroNullable = createQueryCondition(
527
633
  );
528
634
  var applyQueryMatchBoolean = createQueryCondition(
529
635
  (obj, qb, entityName, field) => {
530
- const value = obj[field];
531
- if (value === true || value === "true" || value === 1 || value === "1") {
636
+ const value = parseBool(obj[field]);
637
+ if (value === true) {
532
638
  qb.andWhere(`${entityName}.${field} = TRUE`);
533
639
  }
534
- if (value === false || value === "false" || value === 0 || value === "0") {
640
+ if (value === false) {
535
641
  qb.andWhere(`${entityName}.${field} = FALSE`);
536
642
  }
537
643
  }
538
644
  );
645
+ var applyQueryMatchBooleanMySQL = createQueryCondition(
646
+ (obj, qb, entityName, field) => {
647
+ const value = parseBool(obj[field]);
648
+ if (value === true) {
649
+ qb.andWhere(`${entityName}.${field} = 1`);
650
+ }
651
+ if (value === false) {
652
+ qb.andWhere(`${entityName}.${field} = 0`);
653
+ }
654
+ }
655
+ );
539
656
 
540
657
  // src/decorators/query.ts
541
658
  var import_nesties5 = require("nesties");
@@ -580,6 +697,7 @@ var QueryLike = () => QueryCondition(applyQueryPropertyLike);
580
697
  var QuerySearch = () => QueryCondition(applyQueryPropertySearch);
581
698
  var QueryEqualZeroNullable = () => QueryCondition(applyQueryPropertyZeroNullable);
582
699
  var QueryMatchBoolean = () => QueryCondition(applyQueryMatchBoolean);
700
+ var QueryMatchBooleanMySQL = () => QueryCondition(applyQueryMatchBooleanMySQL);
583
701
  var QueryOperator = (operator, field) => QueryCondition((obj, qb, entityName, key) => {
584
702
  if (obj[key] == null) return;
585
703
  const fieldName = field || key;
@@ -1811,8 +1929,8 @@ var PatchColumnsInGet = (cl, originalCl = cl, fieldsToOmit = []) => {
1811
1929
  ...originalApiProp,
1812
1930
  type: String,
1813
1931
  required: false,
1814
- enum: ["", "1"],
1815
- default: originalApiProp?.default === true ? "1" : originalApiProp?.default === false ? "" : void 0
1932
+ enum: ["0", "1"],
1933
+ default: originalApiProp?.default === true ? "1" : originalApiProp?.default === false ? "0" : void 0
1816
1934
  })(cl.prototype, field);
1817
1935
  }
1818
1936
  return cl;
@@ -1977,6 +2095,17 @@ var RestfulFactory = class _RestfulFactory {
1977
2095
  }
1978
2096
  }
1979
2097
  }
2098
+ const notRequiredButHasDefaultFields = getSpecificFields(
2099
+ this.entityClass,
2100
+ "notRequiredButHasDefault"
2101
+ ).filter((f) => !outputFieldsToOmit.has(f));
2102
+ for (const field of notRequiredButHasDefaultFields) {
2103
+ const oldApiProperty = (0, import_nesties10.getApiProperty)(resultDto, field);
2104
+ (0, import_swagger7.ApiProperty)({
2105
+ ...oldApiProperty,
2106
+ required: true
2107
+ })(resultDto.prototype, field);
2108
+ }
1980
2109
  const res = (0, import_nesties11.RenameClass)(
1981
2110
  resultDto,
1982
2111
  `${this.getEntityClassName()}ResultDto`
@@ -2063,8 +2192,17 @@ var RestfulFactory = class _RestfulFactory {
2063
2192
  (0, import_swagger7.ApiOkResponse)({ type: this.entityCursorPaginationReturnMessageDto })
2064
2193
  ]);
2065
2194
  }
2195
+ getBoolColumns() {
2196
+ const boolColumns = getSpecificFields(this.entityClass, "boolColumn");
2197
+ return import_lodash4.default.difference(boolColumns, this.fieldsInGetToOmit);
2198
+ }
2066
2199
  findAllParam() {
2067
- return (0, import_common3.Query)(GetPipe());
2200
+ const boolColumns = this.getBoolColumns();
2201
+ if (boolColumns.length) {
2202
+ return (0, import_common3.Query)(new ParseBoolObjectPipe(boolColumns), GetPipe());
2203
+ } else {
2204
+ return (0, import_common3.Query)(GetPipe());
2205
+ }
2068
2206
  }
2069
2207
  update(extras = {}) {
2070
2208
  return (0, import_nesties10.MergeMethodDecorators)([
@@ -2289,18 +2427,23 @@ var RestfulFactory = class _RestfulFactory {
2289
2427
  QueryLessEqual,
2290
2428
  QueryLike,
2291
2429
  QueryMatchBoolean,
2430
+ QueryMatchBooleanMySQL,
2292
2431
  QueryNotEqual,
2293
2432
  QueryOperator,
2294
2433
  QuerySearch,
2295
2434
  Relation,
2296
2435
  RelationComputed,
2297
2436
  RestfulFactory,
2437
+ SimpleJsonColumn,
2298
2438
  StringColumn,
2299
2439
  StringIdBase,
2440
+ StringJsonColumn,
2441
+ TextColumn,
2300
2442
  TimeBase,
2301
2443
  UpdatePipe,
2302
2444
  UuidColumn,
2303
2445
  applyQueryMatchBoolean,
2446
+ applyQueryMatchBooleanMySQL,
2304
2447
  applyQueryProperty,
2305
2448
  applyQueryPropertyLike,
2306
2449
  applyQueryPropertySearch,