cddl2py 0.1.0 → 0.1.2
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/build/index.d.ts.map +1 -1
- package/build/index.js +45 -14
- package/package.json +2 -2
package/build/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAIH,KAAK,UAAU,EAGlB,MAAM,MAAM,CAAA;AAKb,MAAM,WAAW,gBAAgB;IAC7B,QAAQ,CAAC,EAAE,OAAO,CAAA;CACrB;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAIH,KAAK,UAAU,EAGlB,MAAM,MAAM,CAAA;AAKb,MAAM,WAAW,gBAAgB;IAC7B,QAAQ,CAAC,EAAE,OAAO,CAAA;CACrB;AAkBD,wBAAgB,SAAS,CAAE,WAAW,EAAE,UAAU,EAAE,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,MAAM,CAuBxF"}
|
package/build/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { isCDDLArray, isGroup, isNamedGroupReference, isLiteralWithValue, isNativeTypeWithOperator, isUnNamedProperty, isPropertyReference, isRange, isVariable, pascalCase } from 'cddl';
|
|
2
2
|
import { snakeCase } from './utils.js';
|
|
3
3
|
import { pkg, NATIVE_TYPE_MAP } from './constants.js';
|
|
4
|
+
const STRING_RECORD_KEY_TYPES = new Set(['str', 'text', 'tstr']);
|
|
4
5
|
export function transform(assignments, options) {
|
|
5
6
|
const ctx = {
|
|
6
7
|
pydantic: options?.pydantic ?? false,
|
|
@@ -88,6 +89,7 @@ function generateGroup(group, ctx) {
|
|
|
88
89
|
return comments + generateGroupWithChoices(name, properties, ctx);
|
|
89
90
|
}
|
|
90
91
|
const props = properties;
|
|
92
|
+
const extraItemsType = getExtraItemsType(props, ctx);
|
|
91
93
|
if (props.length === 1) {
|
|
92
94
|
const prop = props[0];
|
|
93
95
|
const propType = Array.isArray(prop.Type) ? prop.Type : [prop.Type];
|
|
@@ -101,7 +103,7 @@ function generateGroup(group, ctx) {
|
|
|
101
103
|
}
|
|
102
104
|
}
|
|
103
105
|
const mixins = props.filter(isUnNamedProperty);
|
|
104
|
-
const ownProps = props.filter(p => !isUnNamedProperty(p));
|
|
106
|
+
const ownProps = props.filter(p => !isUnNamedProperty(p) && !isExtensibleRecordProperty(p));
|
|
105
107
|
const simpleMixinBases = [];
|
|
106
108
|
const unionMixinGroups = [];
|
|
107
109
|
for (const mixin of mixins) {
|
|
@@ -137,9 +139,9 @@ function generateGroup(group, ctx) {
|
|
|
137
139
|
}
|
|
138
140
|
}
|
|
139
141
|
if (unionMixinGroups.length > 0) {
|
|
140
|
-
return comments + generateGroupWithUnionMixins(name, simpleMixinBases, unionMixinGroups, ownProps, ctx);
|
|
142
|
+
return comments + generateGroupWithUnionMixins(name, simpleMixinBases, unionMixinGroups, ownProps, extraItemsType, ctx);
|
|
141
143
|
}
|
|
142
|
-
return comments + generateClass(name, simpleMixinBases, ownProps, ctx);
|
|
144
|
+
return comments + generateClass(name, simpleMixinBases, ownProps, ctx, extraItemsType);
|
|
143
145
|
}
|
|
144
146
|
function generateGroupWithChoices(name, properties, ctx) {
|
|
145
147
|
const blocks = [];
|
|
@@ -203,7 +205,7 @@ function generateGroupWithChoices(name, properties, ctx) {
|
|
|
203
205
|
}
|
|
204
206
|
return blocks.join('\n\n');
|
|
205
207
|
}
|
|
206
|
-
function generateGroupWithUnionMixins(name, simpleBases, unionGroups, ownProps, ctx) {
|
|
208
|
+
function generateGroupWithUnionMixins(name, simpleBases, unionGroups, ownProps, extraItemsType, ctx) {
|
|
207
209
|
if (ownProps.length === 0 && simpleBases.length === 0) {
|
|
208
210
|
const allTypes = unionGroups.flat();
|
|
209
211
|
if (allTypes.length === 1) {
|
|
@@ -218,7 +220,7 @@ function generateGroupWithUnionMixins(name, simpleBases, unionGroups, ownProps,
|
|
|
218
220
|
const unionTypes = unionGroups[0];
|
|
219
221
|
if (ownProps.length > 0) {
|
|
220
222
|
const baseName = `_${name}Fields`;
|
|
221
|
-
blocks.push(generateClass(baseName, [], ownProps, ctx));
|
|
223
|
+
blocks.push(generateClass(baseName, [], ownProps, ctx, extraItemsType));
|
|
222
224
|
for (let i = 0; i < unionTypes.length; i++) {
|
|
223
225
|
const variantName = `_${name}Variant${i}`;
|
|
224
226
|
variantNames.push(variantName);
|
|
@@ -231,7 +233,7 @@ function generateGroupWithUnionMixins(name, simpleBases, unionGroups, ownProps,
|
|
|
231
233
|
const variantName = `_${name}Variant${i}`;
|
|
232
234
|
variantNames.push(variantName);
|
|
233
235
|
const bases = [unionTypes[i], ...simpleBases];
|
|
234
|
-
blocks.push(generateClass(variantName, bases, [], ctx));
|
|
236
|
+
blocks.push(generateClass(variantName, bases, [], ctx, extraItemsType));
|
|
235
237
|
}
|
|
236
238
|
}
|
|
237
239
|
}
|
|
@@ -292,7 +294,7 @@ function generateArrayAssignment(arr, ctx) {
|
|
|
292
294
|
// ---------------------------------------------------------------------------
|
|
293
295
|
// Class generation (TypedDict or Pydantic BaseModel)
|
|
294
296
|
// ---------------------------------------------------------------------------
|
|
295
|
-
function generateClass(name, bases, props, ctx) {
|
|
297
|
+
function generateClass(name, bases, props, ctx, extraItemsType) {
|
|
296
298
|
const lines = [];
|
|
297
299
|
let classDecl;
|
|
298
300
|
if (ctx.pydantic) {
|
|
@@ -308,16 +310,22 @@ function generateClass(name, bases, props, ctx) {
|
|
|
308
310
|
else {
|
|
309
311
|
ctx.typingExtensionsImports.add('TypedDict');
|
|
310
312
|
const typedDictBases = bases.filter((base) => isModelCompatibleBase(base, ctx));
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
classDecl = `class ${name}(TypedDict):`;
|
|
316
|
-
}
|
|
313
|
+
const baseList = typedDictBases.length > 0 ? typedDictBases.join(', ') : 'TypedDict';
|
|
314
|
+
classDecl = extraItemsType
|
|
315
|
+
? `class ${name}(${baseList}, extra_items=${extraItemsType}):`
|
|
316
|
+
: `class ${name}(${baseList}):`;
|
|
317
317
|
}
|
|
318
318
|
lines.push(classDecl);
|
|
319
|
+
if (ctx.pydantic && extraItemsType) {
|
|
320
|
+
ctx.pydanticImports.add('ConfigDict');
|
|
321
|
+
ctx.pydanticImports.add('Field');
|
|
322
|
+
lines.push(` __pydantic_extra__: dict[str, ${extraItemsType}] = Field(init=False)`);
|
|
323
|
+
lines.push(` model_config = ConfigDict(extra='allow')`);
|
|
324
|
+
}
|
|
319
325
|
if (props.length === 0) {
|
|
320
|
-
lines.
|
|
326
|
+
if (lines.length === 1) {
|
|
327
|
+
lines.push(' pass');
|
|
328
|
+
}
|
|
321
329
|
return lines.join('\n');
|
|
322
330
|
}
|
|
323
331
|
for (const prop of props) {
|
|
@@ -385,6 +393,29 @@ function generateField(prop, ctx) {
|
|
|
385
393
|
}
|
|
386
394
|
return ` ${propName}: ${typeStr}${commentSuffix}`;
|
|
387
395
|
}
|
|
396
|
+
function isExtensibleRecordProperty(prop) {
|
|
397
|
+
return !isUnNamedProperty(prop) &&
|
|
398
|
+
prop.Occurrence.m === Infinity &&
|
|
399
|
+
!prop.HasCut &&
|
|
400
|
+
STRING_RECORD_KEY_TYPES.has(prop.Name);
|
|
401
|
+
}
|
|
402
|
+
function getExtraItemsType(props, ctx) {
|
|
403
|
+
const types = props
|
|
404
|
+
.filter(isExtensibleRecordProperty)
|
|
405
|
+
.flatMap((prop) => {
|
|
406
|
+
const cddlTypes = Array.isArray(prop.Type) ? prop.Type : [prop.Type];
|
|
407
|
+
return cddlTypes.map((type) => resolveType(type, ctx));
|
|
408
|
+
});
|
|
409
|
+
if (types.length === 0) {
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
const uniqueTypes = [...new Set(types)];
|
|
413
|
+
if (uniqueTypes.length === 1) {
|
|
414
|
+
return uniqueTypes[0];
|
|
415
|
+
}
|
|
416
|
+
ctx.typingImports.add('Union');
|
|
417
|
+
return `Union[${uniqueTypes.join(', ')}]`;
|
|
418
|
+
}
|
|
388
419
|
// ---------------------------------------------------------------------------
|
|
389
420
|
// Type resolution
|
|
390
421
|
// ---------------------------------------------------------------------------
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cddl2py",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
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",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"yargs": "^18.0.0",
|
|
37
|
-
"cddl": "0.19.
|
|
37
|
+
"cddl": "0.19.2"
|
|
38
38
|
},
|
|
39
39
|
"scripts": {
|
|
40
40
|
"release": "release-it --config .release-it.ts --VV",
|