cddl2py 0.2.1 → 0.3.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/build/index.js +121 -36
  2. package/package.json +3 -3
package/build/index.js CHANGED
@@ -416,30 +416,6 @@ function getExtraItemsType(props, ctx) {
416
416
  ctx.typingImports.add('Union');
417
417
  return `Union[${uniqueTypes.join(', ')}]`;
418
418
  }
419
- function stringifyPythonLiteral(value) {
420
- return JSON.stringify(value);
421
- }
422
- function getTemplateAnnotatedPattern(regexpPattern) {
423
- const wildcard = '.+';
424
- if (!regexpPattern.includes(wildcard) || /[\\()[\]{}|?*^$]/.test(regexpPattern.replaceAll(wildcard, ''))) {
425
- return;
426
- }
427
- const segments = regexpPattern.split(wildcard);
428
- const parts = [];
429
- for (let i = 0; i < segments.length; i++) {
430
- const segment = segments[i];
431
- if (segment.length > 0) {
432
- parts.push(stringifyPythonLiteral(segment));
433
- }
434
- if (i < segments.length - 1) {
435
- parts.push('str');
436
- }
437
- }
438
- if (parts.length === 0 || !parts.includes('str')) {
439
- return;
440
- }
441
- return `Annotated[str, ${parts.join(' + ')}]`;
442
- }
443
419
  function resolveNativeTypeWithOperator(t, ctx) {
444
420
  if (typeof t.Type !== 'string') {
445
421
  return;
@@ -455,19 +431,12 @@ function resolveNativeTypeWithOperator(t, ctx) {
455
431
  }
456
432
  return mapped;
457
433
  }
458
- const templateAnnotatedPattern = getTemplateAnnotatedPattern(regexpPattern);
459
- if (!templateAnnotatedPattern) {
460
- if (mapped === 'Any') {
461
- ctx.typingImports.add('Any');
462
- }
463
- return mapped;
464
- }
465
434
  ctx.typingImports.add('Annotated');
466
435
  if (ctx.pydantic) {
467
436
  ctx.pydanticImports.add('StringConstraints');
468
437
  return `Annotated[${mapped}, StringConstraints(pattern=${JSON.stringify(regexpPattern)})]`;
469
438
  }
470
- return templateAnnotatedPattern;
439
+ return `Annotated[${mapped}, ${JSON.stringify(regexpPattern)}]`;
471
440
  }
472
441
  // ---------------------------------------------------------------------------
473
442
  // Type resolution
@@ -504,7 +473,8 @@ function resolveType(t, ctx, options = {}) {
504
473
  }
505
474
  return mapped;
506
475
  }
507
- if (isPropertyReference(t) && t.Value === 'null') {
476
+ if (isPropertyReference(t) && t.Value === 'null' && !isLiteralWithValue(t)) {
477
+ // a bare `null` reference is the null type; a quoted "null" is a string literal
508
478
  return 'None';
509
479
  }
510
480
  if (isGroup(t)) {
@@ -692,13 +662,47 @@ function orderAssignments(assignments) {
692
662
  return ordered;
693
663
  }
694
664
  function getHardDependencies(assignment, assignmentsByName) {
665
+ if (isVariable(assignment)) {
666
+ const propTypes = Array.isArray(assignment.PropertyType)
667
+ ? assignment.PropertyType
668
+ : [assignment.PropertyType];
669
+ const deps = new Set();
670
+ for (const t of propTypes) {
671
+ for (const ref of getTypeReferences(t)) {
672
+ if (assignmentsByName.has(ref)) {
673
+ deps.add(ref);
674
+ }
675
+ }
676
+ }
677
+ return [...deps];
678
+ }
679
+ if (isCDDLArray(assignment)) {
680
+ const arr = assignment;
681
+ const deps = new Set();
682
+ for (const val of arr.Values) {
683
+ const properties = Array.isArray(val) ? val : [val];
684
+ for (const prop of properties) {
685
+ const types = Array.isArray(prop.Type) ? prop.Type : [prop.Type];
686
+ for (const t of types) {
687
+ for (const ref of getTypeReferences(t)) {
688
+ if (assignmentsByName.has(ref)) {
689
+ deps.add(ref);
690
+ }
691
+ }
692
+ }
693
+ }
694
+ }
695
+ return [...deps];
696
+ }
695
697
  if (!isGroup(assignment)) {
696
698
  return [];
697
699
  }
698
700
  const deps = new Set();
699
- for (const propertyOrChoice of assignment.Properties) {
700
- const properties = Array.isArray(propertyOrChoice) ? propertyOrChoice : [propertyOrChoice];
701
- for (const property of properties) {
701
+ const properties = assignment.Properties;
702
+ const hasChoices = properties.some(p => Array.isArray(p));
703
+ for (const propertyOrChoice of properties) {
704
+ const props = Array.isArray(propertyOrChoice) ? propertyOrChoice : [propertyOrChoice];
705
+ for (const property of props) {
702
706
  if (!isUnNamedProperty(property)) {
703
707
  continue;
704
708
  }
@@ -707,8 +711,89 @@ function getHardDependencies(assignment, assignmentsByName) {
707
711
  }
708
712
  }
709
713
  }
714
+ if (!hasChoices) {
715
+ const props = properties;
716
+ if (props.length === 1 && Object.keys(NATIVE_TYPE_MAP).includes(props[0].Name)) {
717
+ const propType = Array.isArray(props[0].Type) ? props[0].Type : [props[0].Type];
718
+ for (const t of propType) {
719
+ for (const ref of getTypeReferences(t)) {
720
+ if (assignmentsByName.has(ref)) {
721
+ deps.add(ref);
722
+ }
723
+ }
724
+ }
725
+ }
726
+ for (const prop of props) {
727
+ if (isExtensibleRecordProperty(prop)) {
728
+ const cddlTypes = Array.isArray(prop.Type) ? prop.Type : [prop.Type];
729
+ for (const t of cddlTypes) {
730
+ for (const ref of getTypeReferences(t)) {
731
+ if (assignmentsByName.has(ref)) {
732
+ deps.add(ref);
733
+ }
734
+ }
735
+ }
736
+ }
737
+ }
738
+ }
710
739
  return [...deps];
711
740
  }
741
+ function getTypeReferences(t) {
742
+ if (typeof t === 'string') {
743
+ return [];
744
+ }
745
+ if (isNamedGroupReference(t)) {
746
+ return [pascalCase(t.Value)];
747
+ }
748
+ if (isPropertyReference(t)) {
749
+ const ref = t;
750
+ if ((ref.Type === 'group' || ref.Type === 'group_array') && typeof ref.Value === 'string') {
751
+ return [pascalCase(ref.Value)];
752
+ }
753
+ if (ref.Type === 'tag') {
754
+ const tag = ref.Value;
755
+ if (!NATIVE_TYPE_MAP[tag.TypePart]) {
756
+ return [pascalCase(tag.TypePart)];
757
+ }
758
+ }
759
+ return [];
760
+ }
761
+ if (isNativeTypeWithOperator(t)) {
762
+ if (isNamedGroupReference(t.Type)) {
763
+ return [pascalCase(t.Type.Value)];
764
+ }
765
+ return [];
766
+ }
767
+ if (isGroup(t) && !isNamedGroupReference(t) && t.Properties) {
768
+ const refs = [];
769
+ const group = t;
770
+ for (const prop of group.Properties) {
771
+ const subProps = Array.isArray(prop) ? prop : [prop];
772
+ for (const p of subProps) {
773
+ const types = Array.isArray(p.Type) ? p.Type : [p.Type];
774
+ for (const subType of types) {
775
+ refs.push(...getTypeReferences(subType));
776
+ }
777
+ }
778
+ }
779
+ return refs;
780
+ }
781
+ if (isCDDLArray(t)) {
782
+ const refs = [];
783
+ const arr = t;
784
+ for (const val of arr.Values) {
785
+ const subProps = Array.isArray(val) ? val : [val];
786
+ for (const prop of subProps) {
787
+ const types = Array.isArray(prop.Type) ? prop.Type : [prop.Type];
788
+ for (const subType of types) {
789
+ refs.push(...getTypeReferences(subType));
790
+ }
791
+ }
792
+ }
793
+ return refs;
794
+ }
795
+ return [];
796
+ }
712
797
  function getMixinDependencies(type, assignmentsByName) {
713
798
  const deps = new Set();
714
799
  const values = Array.isArray(type) ? type : [type];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cddl2py",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "A Node.js package that can generate Python type definitions (with optional Pydantic support) based on a CDDL file",
5
5
  "author": "Christian Bromann <mail@bromann.dev>",
6
6
  "license": "MIT",
@@ -30,11 +30,11 @@
30
30
  },
31
31
  "devDependencies": {
32
32
  "@types/yargs": "^17.0.35",
33
- "@types/node": "^25.5.0"
33
+ "@types/node": "^26.0.1"
34
34
  },
35
35
  "dependencies": {
36
36
  "yargs": "^18.0.0",
37
- "cddl": "0.20.1"
37
+ "cddl": "0.21.0"
38
38
  },
39
39
  "scripts": {
40
40
  "release": "release-it --config .release-it.ts --VV",