@strapi/typescript-utils 4.18.1-experimental.0 → 4.19.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.
@@ -548,19 +548,27 @@ describe('Attributes', () => {
548
548
  expect(modifiers[0].kind).toBe(ts.SyntaxKind.TypeReference);
549
549
  expect(modifiers[0].typeName.escapedText).toBe('Attribute.SetMinMax');
550
550
 
551
- expect(modifiers[0].typeArguments).toHaveLength(1);
552
- expect(modifiers[0].typeArguments[0].kind).toBe(ts.SyntaxKind.TypeLiteral);
553
- expect(modifiers[0].typeArguments[0].members).toHaveLength(1);
551
+ const [setMinMax] = modifiers;
552
+ const { typeArguments } = setMinMax;
553
+
554
+ expect(typeArguments).toBeDefined();
555
+ expect(typeArguments).toHaveLength(2);
556
+
557
+ const [definition, typeofMinMax] = typeArguments;
554
558
 
555
559
  // Min
556
- expect(modifiers[0].typeArguments[0].members[0].kind).toBe(
557
- ts.SyntaxKind.PropertyDeclaration
558
- );
559
- expect(modifiers[0].typeArguments[0].members[0].name.escapedText).toBe('min');
560
- expect(modifiers[0].typeArguments[0].members[0].type.kind).toBe(
561
- ts.SyntaxKind.NumericLiteral
562
- );
563
- expect(modifiers[0].typeArguments[0].members[0].type.text).toBe('2');
560
+ expect(definition.kind).toBe(ts.SyntaxKind.TypeLiteral);
561
+ expect(definition.members).toHaveLength(1);
562
+
563
+ const [min] = definition.members;
564
+
565
+ expect(min.kind).toBe(ts.SyntaxKind.PropertyDeclaration);
566
+ expect(min.name.escapedText).toBe('min');
567
+ expect(min.type.kind).toBe(ts.SyntaxKind.NumericLiteral);
568
+ expect(min.type.text).toBe('2');
569
+
570
+ // Check for number keyword on the second typeArgument
571
+ expect(typeofMinMax.kind).toBe(ts.SyntaxKind.NumberKeyword);
564
572
  });
565
573
 
566
574
  test('No Min, Max: 3', () => {
@@ -572,19 +580,27 @@ describe('Attributes', () => {
572
580
  expect(modifiers[0].kind).toBe(ts.SyntaxKind.TypeReference);
573
581
  expect(modifiers[0].typeName.escapedText).toBe('Attribute.SetMinMax');
574
582
 
575
- expect(modifiers[0].typeArguments).toHaveLength(1);
576
- expect(modifiers[0].typeArguments[0].kind).toBe(ts.SyntaxKind.TypeLiteral);
577
- expect(modifiers[0].typeArguments[0].members).toHaveLength(1);
583
+ const [setMinMax] = modifiers;
584
+ const { typeArguments } = setMinMax;
578
585
 
579
- // Min
580
- expect(modifiers[0].typeArguments[0].members[0].kind).toBe(
581
- ts.SyntaxKind.PropertyDeclaration
582
- );
583
- expect(modifiers[0].typeArguments[0].members[0].name.escapedText).toBe('max');
584
- expect(modifiers[0].typeArguments[0].members[0].type.kind).toBe(
585
- ts.SyntaxKind.NumericLiteral
586
- );
587
- expect(modifiers[0].typeArguments[0].members[0].type.text).toBe('3');
586
+ expect(typeArguments).toBeDefined();
587
+ expect(typeArguments).toHaveLength(2);
588
+
589
+ const [definition, typeofMinMax] = typeArguments;
590
+
591
+ // Max
592
+ expect(definition.kind).toBe(ts.SyntaxKind.TypeLiteral);
593
+ expect(definition.members).toHaveLength(1);
594
+
595
+ const [max] = definition.members;
596
+
597
+ expect(max.kind).toBe(ts.SyntaxKind.PropertyDeclaration);
598
+ expect(max.name.escapedText).toBe('max');
599
+ expect(max.type.kind).toBe(ts.SyntaxKind.NumericLiteral);
600
+ expect(max.type.text).toBe('3');
601
+
602
+ // Check for number keyword on the second typeArgument
603
+ expect(typeofMinMax.kind).toBe(ts.SyntaxKind.NumberKeyword);
588
604
  });
589
605
 
590
606
  test('Min: 4, Max: 12', () => {
@@ -596,28 +612,64 @@ describe('Attributes', () => {
596
612
  expect(modifiers[0].kind).toBe(ts.SyntaxKind.TypeReference);
597
613
  expect(modifiers[0].typeName.escapedText).toBe('Attribute.SetMinMax');
598
614
 
599
- expect(modifiers[0].typeArguments).toHaveLength(1);
600
- expect(modifiers[0].typeArguments[0].kind).toBe(ts.SyntaxKind.TypeLiteral);
601
- expect(modifiers[0].typeArguments[0].members).toHaveLength(2);
615
+ const [setMinMax] = modifiers;
616
+ const { typeArguments } = setMinMax;
602
617
 
603
- // Min
604
- expect(modifiers[0].typeArguments[0].members[0].kind).toBe(
605
- ts.SyntaxKind.PropertyDeclaration
606
- );
607
- expect(modifiers[0].typeArguments[0].members[0].name.escapedText).toBe('min');
608
- expect(modifiers[0].typeArguments[0].members[0].type.kind).toBe(
609
- ts.SyntaxKind.NumericLiteral
610
- );
611
- expect(modifiers[0].typeArguments[0].members[0].type.text).toBe('4');
618
+ expect(typeArguments).toBeDefined();
619
+ expect(typeArguments).toHaveLength(2);
612
620
 
613
- expect(modifiers[0].typeArguments[0].members[1].kind).toBe(
614
- ts.SyntaxKind.PropertyDeclaration
615
- );
616
- expect(modifiers[0].typeArguments[0].members[1].name.escapedText).toBe('max');
617
- expect(modifiers[0].typeArguments[0].members[1].type.kind).toBe(
618
- ts.SyntaxKind.NumericLiteral
619
- );
620
- expect(modifiers[0].typeArguments[0].members[1].type.text).toBe('12');
621
+ const [definition, typeofMinMax] = typeArguments;
622
+
623
+ // Min/Max
624
+ expect(definition.kind).toBe(ts.SyntaxKind.TypeLiteral);
625
+ expect(definition.members).toHaveLength(2);
626
+
627
+ const [min, max] = definition.members;
628
+
629
+ expect(min.kind).toBe(ts.SyntaxKind.PropertyDeclaration);
630
+ expect(min.name.escapedText).toBe('min');
631
+ expect(min.type.kind).toBe(ts.SyntaxKind.NumericLiteral);
632
+ expect(min.type.text).toBe('4');
633
+
634
+ expect(max.kind).toBe(ts.SyntaxKind.PropertyDeclaration);
635
+ expect(max.name.escapedText).toBe('max');
636
+ expect(max.type.kind).toBe(ts.SyntaxKind.NumericLiteral);
637
+ expect(max.type.text).toBe('12');
638
+
639
+ // Check for number keyword on the second typeArgument
640
+ expect(typeofMinMax.kind).toBe(ts.SyntaxKind.NumberKeyword);
641
+ });
642
+
643
+ test('Min: "1"', () => {
644
+ const attribute = { min: '1' };
645
+ const modifiers = getAttributeModifiers(attribute);
646
+
647
+ expect(modifiers).toHaveLength(1);
648
+
649
+ expect(modifiers[0].kind).toBe(ts.SyntaxKind.TypeReference);
650
+ expect(modifiers[0].typeName.escapedText).toBe('Attribute.SetMinMax');
651
+
652
+ const [setMinMax] = modifiers;
653
+ const { typeArguments } = setMinMax;
654
+
655
+ expect(typeArguments).toBeDefined();
656
+ expect(typeArguments).toHaveLength(2);
657
+
658
+ const [definition, typeofMinMax] = typeArguments;
659
+
660
+ // Min/Max
661
+ expect(definition.kind).toBe(ts.SyntaxKind.TypeLiteral);
662
+ expect(definition.members).toHaveLength(1);
663
+
664
+ const [min] = definition.members;
665
+
666
+ expect(min.kind).toBe(ts.SyntaxKind.PropertyDeclaration);
667
+ expect(min.name.escapedText).toBe('min');
668
+ expect(min.type.kind).toBe(ts.SyntaxKind.StringLiteral);
669
+ expect(min.type.text).toBe('1');
670
+
671
+ // Check for string keyword on the second typeArgument
672
+ expect(typeofMinMax.kind).toBe(ts.SyntaxKind.StringKeyword);
621
673
  });
622
674
  });
623
675
 
@@ -1,12 +1,14 @@
1
1
  'use strict';
2
2
 
3
- const { factory } = require('typescript');
3
+ const ts = require('typescript');
4
4
  const _ = require('lodash/fp');
5
5
 
6
6
  const { addImport } = require('../imports');
7
7
  const { getTypeNode, toTypeLiteral, withAttributeNamespace, NAMESPACES } = require('./utils');
8
8
  const mappers = require('./mappers');
9
9
 
10
+ const { factory } = ts;
11
+
10
12
  /**
11
13
  * Create the base type node for a given attribute
12
14
  *
@@ -100,14 +102,39 @@ const getAttributeModifiers = (attribute) => {
100
102
  }
101
103
 
102
104
  // Min / Max
103
- // TODO: Always provide a second type argument for min/max (ie: resolve the attribute scalar type with a `GetAttributeType<${mappers[attribute][0]}>` (useful for biginter (string values)))
104
105
  if (!_.isNil(attribute.min) || !_.isNil(attribute.max)) {
105
106
  const minMaxProperties = _.pick(['min', 'max'], attribute);
107
+ const { min, max } = minMaxProperties;
108
+
109
+ const typeofMin = typeof min;
110
+ const typeofMax = typeof max;
111
+
112
+ // Throws error if min/max exist but have different types to prevent unexpected behavior
113
+ if (min !== undefined && max !== undefined && typeofMin !== typeofMax) {
114
+ throw new Error('typeof min/max values mismatch');
115
+ }
116
+
117
+ const typeofMinMax = (max && typeofMax) ?? (min && typeofMin);
118
+ let typeKeyword;
119
+
120
+ // Determines type keyword (string/number) based on min/max options, throws error for invalid types
121
+ switch (typeofMinMax) {
122
+ case 'string':
123
+ typeKeyword = ts.SyntaxKind.StringKeyword;
124
+ break;
125
+ case 'number':
126
+ typeKeyword = ts.SyntaxKind.NumberKeyword;
127
+ break;
128
+ default:
129
+ throw new Error(
130
+ `Invalid data type for min/max options. Must be string or number, but found ${typeofMinMax}`
131
+ );
132
+ }
106
133
 
107
134
  modifiers.push(
108
135
  factory.createTypeReferenceNode(
109
136
  factory.createIdentifier(withAttributeNamespace('SetMinMax')),
110
- [toTypeLiteral(minMaxProperties)]
137
+ [toTypeLiteral(minMaxProperties), factory.createKeywordTypeNode(typeKeyword)]
111
138
  )
112
139
  );
113
140
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@strapi/typescript-utils",
3
- "version": "4.18.1-experimental.0",
3
+ "version": "4.19.0",
4
4
  "description": "Typescript support for Strapi",
5
5
  "keywords": [
6
6
  "strapi",
@@ -46,5 +46,5 @@
46
46
  "node": ">=18.0.0 <=20.x.x",
47
47
  "npm": ">=6.0.0"
48
48
  },
49
- "gitHead": "e1ede8c55a0e1e22ce20137bf238fc374bd5dd51"
49
+ "gitHead": "beec78649142fec14b075aa3658c515ea2fa9257"
50
50
  }