type-crafter 0.5.0 → 0.6.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/dist/generators/helpers.d.ts +3 -2
- package/dist/index.js +206 -60
- package/dist/runtime.d.ts +2 -0
- package/dist/templates/typescript/object-syntax.hbs +1 -1
- package/dist/templates/typescript/oneOf-syntax.hbs +1 -1
- package/dist/templates/typescript-with-decoders/object-syntax.hbs +4 -4
- package/dist/templates/typescript-with-decoders/oneOf-syntax.hbs +4 -4
- package/dist/types/decoders.d.ts +3 -1
- package/dist/types/index.d.ts +18 -5
- package/dist/utils/index.d.ts +3 -0
- package/dist/writer/helpers.d.ts +1 -1
- package/package.json +1 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
export declare function
|
|
1
|
+
import { type ResolvedTypeReferenceData, type ResolvedGroupReferenceData } from '$types';
|
|
2
|
+
export declare function resolveTypeReference(reference: string): Promise<ResolvedTypeReferenceData>;
|
|
3
|
+
export declare function resolveGroupReference(reference: string): Promise<ResolvedGroupReferenceData>;
|
|
3
4
|
export declare function fillPatterns(input: string, patterns: Array<{
|
|
4
5
|
regex: RegExp;
|
|
5
6
|
value: string;
|
package/dist/index.js
CHANGED
|
@@ -3488,7 +3488,9 @@ function decodeGroupedTypes(rawInput) {
|
|
|
3488
3488
|
const result = {};
|
|
3489
3489
|
for (const key in rawInput) {
|
|
3490
3490
|
const value = rawInput[key];
|
|
3491
|
-
const
|
|
3491
|
+
const decodedRefValue = decodeGroupRef(value);
|
|
3492
|
+
const decodedTypes = decodeTypes(value);
|
|
3493
|
+
const decodedValue = decodedRefValue ?? decodedTypes;
|
|
3492
3494
|
if (decodedValue !== null) {
|
|
3493
3495
|
result[key] = decodedValue;
|
|
3494
3496
|
}
|
|
@@ -3500,6 +3502,20 @@ function decodeGroupedTypes(rawInput) {
|
|
|
3500
3502
|
}
|
|
3501
3503
|
return null;
|
|
3502
3504
|
}
|
|
3505
|
+
function valueIsGroupRef(value) {
|
|
3506
|
+
return isJSON(value) && typeof value.$ref === 'string';
|
|
3507
|
+
}
|
|
3508
|
+
function decodeGroupRef(rawInput) {
|
|
3509
|
+
if (isJSON(rawInput)) {
|
|
3510
|
+
const ref = decodeString(rawInput.$ref);
|
|
3511
|
+
if (ref !== null) {
|
|
3512
|
+
return {
|
|
3513
|
+
$ref: ref
|
|
3514
|
+
};
|
|
3515
|
+
}
|
|
3516
|
+
}
|
|
3517
|
+
return null;
|
|
3518
|
+
}
|
|
3503
3519
|
function decodeTypes(rawInput) {
|
|
3504
3520
|
if (isJSON(rawInput)) {
|
|
3505
3521
|
const result = {};
|
|
@@ -12008,6 +12024,12 @@ function getCachedReferenceType(referencePath) {
|
|
|
12008
12024
|
function cacheReferenceType(referencePath, generatedData) {
|
|
12009
12025
|
cachedReferencedTypes.set(referencePath, generatedData);
|
|
12010
12026
|
}
|
|
12027
|
+
function getInputFilePath(absolutePath = true) {
|
|
12028
|
+
if (config$2 === null) {
|
|
12029
|
+
throw new RuntimeError('Spec file path not set!');
|
|
12030
|
+
}
|
|
12031
|
+
return absolutePath ? resolveFilePath(config$2.input) : config$2.input;
|
|
12032
|
+
}
|
|
12011
12033
|
var Runtime = {
|
|
12012
12034
|
getConfig,
|
|
12013
12035
|
setConfig,
|
|
@@ -12023,7 +12045,8 @@ var Runtime = {
|
|
|
12023
12045
|
getOneOfTemplate,
|
|
12024
12046
|
getCachedReferencedTypes,
|
|
12025
12047
|
getCachedReferenceType,
|
|
12026
|
-
cacheReferenceType
|
|
12048
|
+
cacheReferenceType,
|
|
12049
|
+
getInputFilePath
|
|
12027
12050
|
};
|
|
12028
12051
|
|
|
12029
12052
|
const ALIAS = Symbol.for('yaml.alias');
|
|
@@ -19479,6 +19502,24 @@ function toPascalCaseHelper(input) {
|
|
|
19479
19502
|
}
|
|
19480
19503
|
return toPascalCase(inputString);
|
|
19481
19504
|
}
|
|
19505
|
+
function refineJSONKey(input) {
|
|
19506
|
+
if (typeof input === 'string' && input.includes('-')) {
|
|
19507
|
+
return `'${input}'`;
|
|
19508
|
+
}
|
|
19509
|
+
return input;
|
|
19510
|
+
}
|
|
19511
|
+
function refineVariableName(input) {
|
|
19512
|
+
if (typeof input === 'string') {
|
|
19513
|
+
return toPascalCase(input);
|
|
19514
|
+
}
|
|
19515
|
+
return input;
|
|
19516
|
+
}
|
|
19517
|
+
function refineIndexKey(input) {
|
|
19518
|
+
if (typeof input === 'string') {
|
|
19519
|
+
return `'${input}'`;
|
|
19520
|
+
}
|
|
19521
|
+
return input;
|
|
19522
|
+
}
|
|
19482
19523
|
function registerTemplateHelpers() {
|
|
19483
19524
|
Handlebars.registerHelper('getOptionalKeys', getOptionalKeys);
|
|
19484
19525
|
Handlebars.registerHelper('getRequiredKeys', getRequiredKeys);
|
|
@@ -19488,6 +19529,9 @@ function registerTemplateHelpers() {
|
|
|
19488
19529
|
Handlebars.registerHelper('toPascalCase', toPascalCaseHelper);
|
|
19489
19530
|
Handlebars.registerHelper('isNonEmptyArray', (value) => Array.isArray(value) && value.length === 0);
|
|
19490
19531
|
Handlebars.registerHelper('eq', (value1, value2) => value1 === value2);
|
|
19532
|
+
Handlebars.registerHelper('jsonKey', refineJSONKey);
|
|
19533
|
+
Handlebars.registerHelper('variableName', refineVariableName);
|
|
19534
|
+
Handlebars.registerHelper('indexKey', refineIndexKey);
|
|
19491
19535
|
}
|
|
19492
19536
|
function readNestedValue(json, keyPath) {
|
|
19493
19537
|
if (!isJSON(json)) {
|
|
@@ -19526,10 +19570,10 @@ function stripPrefix(value, prefix) {
|
|
|
19526
19570
|
}
|
|
19527
19571
|
// #endregion
|
|
19528
19572
|
|
|
19529
|
-
|
|
19530
|
-
|
|
19531
|
-
const
|
|
19532
|
-
|
|
19573
|
+
function getReferenceMeta(reference) {
|
|
19574
|
+
const slashedParts = reference.split('/');
|
|
19575
|
+
const hashSlashParts = reference.split('#');
|
|
19576
|
+
let referenceType;
|
|
19533
19577
|
if (reference.startsWith('#')) {
|
|
19534
19578
|
referenceType = 'local';
|
|
19535
19579
|
}
|
|
@@ -19539,32 +19583,61 @@ async function resolveReference(reference) {
|
|
|
19539
19583
|
else {
|
|
19540
19584
|
referenceType = 'remote';
|
|
19541
19585
|
}
|
|
19542
|
-
let
|
|
19543
|
-
|
|
19544
|
-
|
|
19545
|
-
|
|
19546
|
-
|
|
19547
|
-
|
|
19586
|
+
let completeSource = hashSlashParts.at(0);
|
|
19587
|
+
const sourceFile = hashSlashParts.at(0)?.split('/').at(-1);
|
|
19588
|
+
const path = hashSlashParts.at(1)?.slice(1);
|
|
19589
|
+
const name = slashedParts[slashedParts.length - 1];
|
|
19590
|
+
if (typeof completeSource === 'undefined' ||
|
|
19591
|
+
typeof path === 'undefined' ||
|
|
19592
|
+
typeof sourceFile === 'undefined') {
|
|
19593
|
+
throw new InvalidSpecFileError('Invalid reference at: ' + reference);
|
|
19548
19594
|
}
|
|
19549
|
-
|
|
19550
|
-
|
|
19595
|
+
if (referenceType === 'remote' &&
|
|
19596
|
+
resolveFilePath(completeSource) === Runtime.getInputFilePath()) {
|
|
19597
|
+
completeSource = resolveFilePath(completeSource);
|
|
19598
|
+
referenceType = 'local';
|
|
19551
19599
|
}
|
|
19552
|
-
|
|
19553
|
-
|
|
19554
|
-
|
|
19555
|
-
|
|
19556
|
-
|
|
19557
|
-
|
|
19558
|
-
|
|
19559
|
-
|
|
19600
|
+
return {
|
|
19601
|
+
completeSource,
|
|
19602
|
+
sourceFile,
|
|
19603
|
+
path,
|
|
19604
|
+
type: referenceType,
|
|
19605
|
+
name
|
|
19606
|
+
};
|
|
19607
|
+
}
|
|
19608
|
+
async function getReferencedData(refMeta) {
|
|
19609
|
+
let refFileData;
|
|
19610
|
+
if (refMeta.type === 'local') {
|
|
19611
|
+
refFileData = Runtime.getSpecFileData();
|
|
19612
|
+
}
|
|
19613
|
+
else if (refMeta.type === 'remote') {
|
|
19614
|
+
refFileData = await readYaml(refMeta.completeSource);
|
|
19560
19615
|
}
|
|
19561
19616
|
else {
|
|
19617
|
+
throw new UnsupportedFeatureError('URL references are not supported yet');
|
|
19618
|
+
}
|
|
19619
|
+
if (typeof refFileData === 'undefined') {
|
|
19620
|
+
throw new InvalidSpecFileError('Invalid reference at: ' + refMeta.completeSource);
|
|
19621
|
+
}
|
|
19622
|
+
return readNestedValue(refFileData, refMeta.path.split('/'));
|
|
19623
|
+
}
|
|
19624
|
+
async function resolveTypeReference(reference) {
|
|
19625
|
+
const refMeta = getReferenceMeta(reference);
|
|
19626
|
+
const refData = await getReferencedData(refMeta);
|
|
19627
|
+
const result = decodeTypeInfo(refData);
|
|
19628
|
+
if (result === null) {
|
|
19562
19629
|
throw new InvalidSpecFileError('Invalid reference at: ' + reference);
|
|
19563
19630
|
}
|
|
19631
|
+
return { typeInfo: result, ...refMeta };
|
|
19632
|
+
}
|
|
19633
|
+
async function resolveGroupReference(reference) {
|
|
19634
|
+
const refMeta = getReferenceMeta(reference);
|
|
19635
|
+
const refData = await getReferencedData(refMeta);
|
|
19636
|
+
const result = decodeTypes(refData);
|
|
19564
19637
|
if (result === null) {
|
|
19565
19638
|
throw new InvalidSpecFileError('Invalid reference at: ' + reference);
|
|
19566
19639
|
}
|
|
19567
|
-
return {
|
|
19640
|
+
return { groupedTypes: result, ...refMeta };
|
|
19568
19641
|
}
|
|
19569
19642
|
function fillPatterns(input, patterns) {
|
|
19570
19643
|
let result = input;
|
|
@@ -19574,6 +19647,12 @@ function fillPatterns(input, patterns) {
|
|
|
19574
19647
|
return result;
|
|
19575
19648
|
}
|
|
19576
19649
|
|
|
19650
|
+
/**
|
|
19651
|
+
* @description Generates the primitive type for the unit attribute in the spec.
|
|
19652
|
+
* @param typeName { string }
|
|
19653
|
+
* @param typeInfo { TypeInfo }
|
|
19654
|
+
* @returns {GeneratedType<VariableTemplateInput>}
|
|
19655
|
+
*/
|
|
19577
19656
|
function getPrimitiveType(typeName, typeInfo) {
|
|
19578
19657
|
if (typeInfo.type === null) {
|
|
19579
19658
|
throw new InvalidSpecFileError('Invalid type for: ' + typeName);
|
|
@@ -19609,7 +19688,7 @@ function getPrimitiveType(typeName, typeInfo) {
|
|
|
19609
19688
|
result.primitives.add(languageDataType);
|
|
19610
19689
|
return result;
|
|
19611
19690
|
}
|
|
19612
|
-
async function generateObjectType(typeName, typeInfo) {
|
|
19691
|
+
async function generateObjectType(typeName, typeInfo, parentTypes) {
|
|
19613
19692
|
const templateInput = {
|
|
19614
19693
|
typeName,
|
|
19615
19694
|
type: typeName,
|
|
@@ -19622,13 +19701,14 @@ async function generateObjectType(typeName, typeInfo) {
|
|
|
19622
19701
|
let dynamicGeneratedType = '';
|
|
19623
19702
|
const primitives = [];
|
|
19624
19703
|
const references = [];
|
|
19704
|
+
// Generating types for properties
|
|
19625
19705
|
for (const propertyName in typeInfo.properties) {
|
|
19626
19706
|
const propertyDetails = typeInfo.properties[propertyName];
|
|
19627
19707
|
const propertyType = propertyDetails.type;
|
|
19628
19708
|
const reference = propertyDetails.$ref ?? null;
|
|
19629
19709
|
const enumValues = propertyDetails.enum ?? null;
|
|
19630
19710
|
// Throwing error in case neither property type nor reference to a different type is present
|
|
19631
|
-
if (propertyType === null && reference === null) {
|
|
19711
|
+
if (propertyType === null && reference === null && propertyDetails.oneOf === null) {
|
|
19632
19712
|
throw new InvalidSpecFileError('Invalid property type for: ' + typeName + '.' + propertyName);
|
|
19633
19713
|
}
|
|
19634
19714
|
const primitiveType = propertyType ?? 'object';
|
|
@@ -19637,7 +19717,7 @@ async function generateObjectType(typeName, typeInfo) {
|
|
|
19637
19717
|
let languageDataType = null;
|
|
19638
19718
|
let isReferenced = false;
|
|
19639
19719
|
if (reference !== null) {
|
|
19640
|
-
const referencedType = await generateReferencedType(propertyName, propertyDetails);
|
|
19720
|
+
const referencedType = await generateReferencedType(propertyName, propertyDetails, parentTypes);
|
|
19641
19721
|
recursivePropertyName = referencedType.templateInput.typeName;
|
|
19642
19722
|
languageDataType = recursivePropertyName;
|
|
19643
19723
|
references.push(...referencedType.references);
|
|
@@ -19650,7 +19730,7 @@ async function generateObjectType(typeName, typeInfo) {
|
|
|
19650
19730
|
languageDataType = enumName;
|
|
19651
19731
|
}
|
|
19652
19732
|
else if (propertyType === 'array') {
|
|
19653
|
-
const arrayDataGenOutput = await generateArrayType(propertyName, propertyDetails);
|
|
19733
|
+
const arrayDataGenOutput = await generateArrayType(propertyName, propertyDetails, parentTypes);
|
|
19654
19734
|
primitives.push(...arrayDataGenOutput.primitives);
|
|
19655
19735
|
references.push(...arrayDataGenOutput.references);
|
|
19656
19736
|
languageDataType = arrayDataGenOutput.templateInput.type;
|
|
@@ -19658,16 +19738,17 @@ async function generateObjectType(typeName, typeInfo) {
|
|
|
19658
19738
|
}
|
|
19659
19739
|
else if (propertyType === 'object') {
|
|
19660
19740
|
recursivePropertyName = toPascalCase(propertyName);
|
|
19661
|
-
recursiveTypeGenOutput = await generateObjectType(recursivePropertyName, typeInfo.properties[propertyName]);
|
|
19741
|
+
recursiveTypeGenOutput = await generateObjectType(recursivePropertyName, typeInfo.properties[propertyName], parentTypes);
|
|
19662
19742
|
languageDataType = recursivePropertyName;
|
|
19663
19743
|
references.push(...recursiveTypeGenOutput.references);
|
|
19664
19744
|
primitives.push(...recursiveTypeGenOutput.primitives);
|
|
19665
19745
|
}
|
|
19666
19746
|
else {
|
|
19667
|
-
const primitiveTypeGenOutput =
|
|
19747
|
+
const primitiveTypeGenOutput = await generateType(typeName + toPascalCase(propertyName), propertyDetails, parentTypes);
|
|
19668
19748
|
languageDataType = primitiveTypeGenOutput.templateInput.type;
|
|
19669
19749
|
primitives.push(...primitiveTypeGenOutput.primitives);
|
|
19670
19750
|
references.push(...primitiveTypeGenOutput.references);
|
|
19751
|
+
dynamicGeneratedType = primitiveTypeGenOutput.content;
|
|
19671
19752
|
}
|
|
19672
19753
|
if (languageDataType === null) {
|
|
19673
19754
|
throw new InvalidSpecFileError(`Invalid language data type for: ${typeName}.${propertyName}`);
|
|
@@ -19696,6 +19777,12 @@ async function generateObjectType(typeName, typeInfo) {
|
|
|
19696
19777
|
};
|
|
19697
19778
|
return result;
|
|
19698
19779
|
}
|
|
19780
|
+
/**
|
|
19781
|
+
* @description Generated ENUM type for the unit attribute in the spec.
|
|
19782
|
+
* @param typeName
|
|
19783
|
+
* @param typeInfo
|
|
19784
|
+
* @returns {GeneratedType<EnumTemplateInput>}
|
|
19785
|
+
*/
|
|
19699
19786
|
function generateEnumType(typeName, typeInfo) {
|
|
19700
19787
|
if (typeInfo.enum === null || typeInfo.enum.length === 0 || typeInfo.type === null) {
|
|
19701
19788
|
throw new InvalidSpecFileError('Invalid enum type for: ' + typeName);
|
|
@@ -19717,11 +19804,11 @@ function generateEnumType(typeName, typeInfo) {
|
|
|
19717
19804
|
result.content = Runtime.getEnumTemplate()(templateInput);
|
|
19718
19805
|
return result;
|
|
19719
19806
|
}
|
|
19720
|
-
async function generateArrayType(typeName, typeInfo) {
|
|
19807
|
+
async function generateArrayType(typeName, typeInfo, parentTypes) {
|
|
19721
19808
|
if (typeInfo.items === null) {
|
|
19722
19809
|
throw new InvalidSpecFileError('Invalid array type for: ' + typeName);
|
|
19723
19810
|
}
|
|
19724
|
-
const arrayItemsType = await generateType(typeName, typeInfo.items);
|
|
19811
|
+
const arrayItemsType = await generateType(typeName + 'Item', typeInfo.items, parentTypes);
|
|
19725
19812
|
if (typeof arrayItemsType.templateInput?.type === 'undefined') {
|
|
19726
19813
|
throw new InvalidSpecFileError('Invalid array type for: ' + typeName);
|
|
19727
19814
|
}
|
|
@@ -19766,7 +19853,7 @@ function generateVariableType(typeName, typeInfo) {
|
|
|
19766
19853
|
templateInput
|
|
19767
19854
|
};
|
|
19768
19855
|
}
|
|
19769
|
-
async function generateReferencedType(typeName, typeInfo) {
|
|
19856
|
+
async function generateReferencedType(typeName, typeInfo, parentTypes) {
|
|
19770
19857
|
if (typeInfo.$ref === null) {
|
|
19771
19858
|
throw new InvalidSpecFileError('Invalid referenced type for: ' + typeName);
|
|
19772
19859
|
}
|
|
@@ -19774,18 +19861,18 @@ async function generateReferencedType(typeName, typeInfo) {
|
|
|
19774
19861
|
if (cachedReferencedType !== null) {
|
|
19775
19862
|
return cachedReferencedType.templateData;
|
|
19776
19863
|
}
|
|
19777
|
-
const referencedTypeInfo = await
|
|
19778
|
-
const referencedGeneratedType = await generateType(referencedTypeInfo.
|
|
19864
|
+
const referencedTypeInfo = await resolveTypeReference(typeInfo.$ref);
|
|
19865
|
+
const referencedGeneratedType = await generateType(referencedTypeInfo.name, referencedTypeInfo.typeInfo, parentTypes);
|
|
19779
19866
|
const result = {
|
|
19780
19867
|
content: referencedGeneratedType.content,
|
|
19781
|
-
references: new Set([...referencedGeneratedType.references, referencedTypeInfo.
|
|
19868
|
+
references: new Set([...referencedGeneratedType.references, referencedTypeInfo.name]),
|
|
19782
19869
|
primitives: referencedGeneratedType.primitives,
|
|
19783
19870
|
templateInput: referencedGeneratedType.templateInput
|
|
19784
19871
|
};
|
|
19785
19872
|
Runtime.cacheReferenceType(typeInfo.$ref, { ...referencedTypeInfo, templateData: result });
|
|
19786
19873
|
return result;
|
|
19787
19874
|
}
|
|
19788
|
-
async function generateOneOfTypes(typeName, typeInfo) {
|
|
19875
|
+
async function generateOneOfTypes(typeName, typeInfo, parentTypes) {
|
|
19789
19876
|
if (typeInfo.oneOf === null || typeInfo.oneOf.length === 0) {
|
|
19790
19877
|
throw new InvalidSpecFileError('Invalid oneOf type for: ' + typeName);
|
|
19791
19878
|
}
|
|
@@ -19806,16 +19893,16 @@ async function generateOneOfTypes(typeName, typeInfo) {
|
|
|
19806
19893
|
for (let index = 0; index < typeInfo.oneOf.length; index++) {
|
|
19807
19894
|
const oneOfItem = typeInfo.oneOf[index];
|
|
19808
19895
|
if (oneOfItem.$ref !== null) {
|
|
19809
|
-
const referenceData = await
|
|
19896
|
+
const referenceData = await resolveTypeReference(oneOfItem.$ref);
|
|
19810
19897
|
const composition = {
|
|
19811
19898
|
source: 'referenced',
|
|
19812
|
-
referencedType: referenceData.
|
|
19899
|
+
referencedType: referenceData.name
|
|
19813
19900
|
};
|
|
19814
19901
|
templateInput.compositions.push(composition);
|
|
19815
|
-
result.references.add(referenceData.
|
|
19902
|
+
result.references.add(referenceData.name);
|
|
19816
19903
|
}
|
|
19817
19904
|
else {
|
|
19818
|
-
const generatedType = await generateType(typeName + (index + 1), oneOfItem);
|
|
19905
|
+
const generatedType = await generateType(typeName + (index + 1), oneOfItem, parentTypes);
|
|
19819
19906
|
if (generatedType === null) {
|
|
19820
19907
|
throw new InvalidSpecFileError('Invalid oneOf type for: ' + typeName);
|
|
19821
19908
|
}
|
|
@@ -19837,21 +19924,41 @@ async function generateOneOfTypes(typeName, typeInfo) {
|
|
|
19837
19924
|
result.content = Runtime.getOneOfTemplate()(templateInput);
|
|
19838
19925
|
return result;
|
|
19839
19926
|
}
|
|
19840
|
-
|
|
19927
|
+
function returnCyclicReference(typeName) {
|
|
19928
|
+
const templateInput = {
|
|
19929
|
+
typeName,
|
|
19930
|
+
type: typeName,
|
|
19931
|
+
composerType: typeName,
|
|
19932
|
+
description: '',
|
|
19933
|
+
example: '',
|
|
19934
|
+
summary: ''
|
|
19935
|
+
};
|
|
19936
|
+
return {
|
|
19937
|
+
content: '',
|
|
19938
|
+
references: new Set(),
|
|
19939
|
+
primitives: new Set(),
|
|
19940
|
+
templateInput
|
|
19941
|
+
};
|
|
19942
|
+
}
|
|
19943
|
+
async function generateType(typeName, typeInfo, parentTypes) {
|
|
19944
|
+
if (parentTypes.includes(typeName)) {
|
|
19945
|
+
return returnCyclicReference(typeName);
|
|
19946
|
+
}
|
|
19947
|
+
parentTypes = [...parentTypes, typeName];
|
|
19841
19948
|
if (typeInfo.type === 'object') {
|
|
19842
|
-
return await generateObjectType(typeName, typeInfo);
|
|
19949
|
+
return await generateObjectType(typeName, typeInfo, parentTypes);
|
|
19843
19950
|
}
|
|
19844
19951
|
if (typeInfo.enum !== null) {
|
|
19845
19952
|
return generateEnumType(typeName, typeInfo);
|
|
19846
19953
|
}
|
|
19847
19954
|
if (typeInfo.oneOf !== null) {
|
|
19848
|
-
return await generateOneOfTypes(typeName, typeInfo);
|
|
19955
|
+
return await generateOneOfTypes(typeName, typeInfo, parentTypes);
|
|
19849
19956
|
}
|
|
19850
19957
|
if (typeInfo.type === 'array') {
|
|
19851
|
-
return await generateArrayType(typeName, typeInfo);
|
|
19958
|
+
return await generateArrayType(typeName, typeInfo, parentTypes);
|
|
19852
19959
|
}
|
|
19853
19960
|
if (typeInfo.$ref !== null) {
|
|
19854
|
-
return await generateReferencedType(typeName, typeInfo);
|
|
19961
|
+
return await generateReferencedType(typeName, typeInfo, parentTypes);
|
|
19855
19962
|
}
|
|
19856
19963
|
return generateVariableType(typeName, typeInfo);
|
|
19857
19964
|
}
|
|
@@ -19859,7 +19966,11 @@ async function generateTypes(types) {
|
|
|
19859
19966
|
const result = {};
|
|
19860
19967
|
for (const type in types) {
|
|
19861
19968
|
const typeInfo = types[type];
|
|
19862
|
-
|
|
19969
|
+
const generatedData = await generateType(type, typeInfo, []);
|
|
19970
|
+
// Not storing top level referenced types as they are already generated somewhere else
|
|
19971
|
+
if (typeInfo.$ref === null) {
|
|
19972
|
+
result[type] = generatedData;
|
|
19973
|
+
}
|
|
19863
19974
|
}
|
|
19864
19975
|
return result;
|
|
19865
19976
|
}
|
|
@@ -19872,18 +19983,34 @@ async function generator(specFileData) {
|
|
|
19872
19983
|
if (specFileData.types !== null) {
|
|
19873
19984
|
result.types = await generateTypes(specFileData.types);
|
|
19874
19985
|
}
|
|
19986
|
+
// remove self references
|
|
19987
|
+
for (const typeName in result.types) {
|
|
19988
|
+
const typeData = result.types[typeName];
|
|
19989
|
+
typeData.references.delete(typeName);
|
|
19990
|
+
}
|
|
19875
19991
|
// generating grouped types
|
|
19876
19992
|
const groupedTypes = {};
|
|
19993
|
+
const referencedGroups = [];
|
|
19877
19994
|
for (const groupName in specFileData.groupedTypes) {
|
|
19878
|
-
|
|
19995
|
+
const groupData = specFileData.groupedTypes[groupName];
|
|
19996
|
+
if (!valueIsGroupRef(groupData)) {
|
|
19997
|
+
groupedTypes[groupName] = await generateTypes(groupData);
|
|
19998
|
+
}
|
|
19999
|
+
else {
|
|
20000
|
+
const groupRefData = await resolveGroupReference(groupData.$ref);
|
|
20001
|
+
referencedGroups.push(groupRefData);
|
|
20002
|
+
}
|
|
20003
|
+
}
|
|
20004
|
+
for (const refGroup of referencedGroups) {
|
|
20005
|
+
groupedTypes[refGroup.name] = await generateTypes(refGroup.groupedTypes);
|
|
19879
20006
|
}
|
|
19880
20007
|
// storing remote referenced to output
|
|
19881
20008
|
for (const generatedRefData of Runtime.getCachedReferencedTypes().values()) {
|
|
19882
|
-
if (typeof generatedRefData.sourceFile === 'string') {
|
|
20009
|
+
if (typeof generatedRefData.sourceFile === 'string' && generatedRefData.type !== 'local') {
|
|
19883
20010
|
const refGroupName = toPascalCase(generatedRefData.sourceFile.replace('.yaml', ''));
|
|
19884
20011
|
groupedTypes[refGroupName] = {
|
|
19885
20012
|
...groupedTypes[refGroupName],
|
|
19886
|
-
[generatedRefData.
|
|
20013
|
+
[generatedRefData.name]: generatedRefData.templateData
|
|
19887
20014
|
};
|
|
19888
20015
|
}
|
|
19889
20016
|
}
|
|
@@ -19922,25 +20049,33 @@ function generateExpectedOutputFile() {
|
|
|
19922
20049
|
result = new Map([...generateTypesOutputFiles(specData.types)]);
|
|
19923
20050
|
for (const groupName in specData.groupedTypes) {
|
|
19924
20051
|
const group = specData.groupedTypes[groupName];
|
|
19925
|
-
|
|
20052
|
+
// No File/Folder will be created for referenced groups
|
|
20053
|
+
if (!valueIsGroupRef(group)) {
|
|
20054
|
+
result = new Map([...result, ...generateTypesOutputFiles(group, groupName)]);
|
|
20055
|
+
}
|
|
19926
20056
|
}
|
|
19927
20057
|
// Generating expect writing types for referenced types
|
|
19928
20058
|
let referredGroups = {};
|
|
19929
20059
|
for (const generatedRefData of Runtime.getCachedReferencedTypes().values()) {
|
|
19930
|
-
if (typeof generatedRefData.sourceFile !== 'undefined'
|
|
20060
|
+
if (typeof generatedRefData.sourceFile !== 'undefined' &&
|
|
20061
|
+
generatedRefData.completeSource !== Runtime.getInputFilePath() // Preventing new file creation for remote references from base file
|
|
20062
|
+
) {
|
|
19931
20063
|
const groupName = toPascalCase(generatedRefData.sourceFile.replace('.yaml', ''));
|
|
19932
20064
|
referredGroups = {
|
|
19933
20065
|
...referredGroups,
|
|
19934
20066
|
[groupName]: {
|
|
19935
20067
|
...referredGroups[groupName],
|
|
19936
|
-
[generatedRefData.
|
|
20068
|
+
[generatedRefData.name]: generatedRefData.typeInfo
|
|
19937
20069
|
}
|
|
19938
20070
|
};
|
|
19939
20071
|
}
|
|
19940
20072
|
}
|
|
19941
20073
|
for (const groupName in referredGroups) {
|
|
19942
20074
|
const group = referredGroups[groupName];
|
|
19943
|
-
|
|
20075
|
+
// No File/Folder will be created for referenced groups
|
|
20076
|
+
if (!valueIsGroupRef(group)) {
|
|
20077
|
+
result = new Map([...result, ...generateTypesOutputFiles(group, groupName)]);
|
|
20078
|
+
}
|
|
19944
20079
|
}
|
|
19945
20080
|
return result;
|
|
19946
20081
|
}
|
|
@@ -19951,11 +20086,19 @@ async function writeTypesToFiles(config, types, folderName = '') {
|
|
|
19951
20086
|
folderName: config.output.directory + '/' + folderName,
|
|
19952
20087
|
files: []
|
|
19953
20088
|
};
|
|
20089
|
+
// Filtering references for writing types to files; Done for types.writerMode: Files
|
|
20090
|
+
// Maybe a hack. But it works for now
|
|
20091
|
+
// Fix this later
|
|
20092
|
+
const filterReferences = folderName !== '';
|
|
20093
|
+
const typeNames = Object.keys(types);
|
|
19954
20094
|
for (const typeName in types) {
|
|
19955
20095
|
const typeData = types[typeName];
|
|
19956
20096
|
const file = typeName + config.output.fileExtension;
|
|
20097
|
+
const references = filterReferences
|
|
20098
|
+
? [...types[typeName].references].filter((x) => !typeNames.includes(x))
|
|
20099
|
+
: [...types[typeName].references];
|
|
19957
20100
|
const templateInput = {
|
|
19958
|
-
referencedTypes:
|
|
20101
|
+
referencedTypes: references,
|
|
19959
20102
|
primitives: [...typeData.primitives],
|
|
19960
20103
|
typesContent: typeData.content,
|
|
19961
20104
|
writtenAt: await getExpectedWrittenPath(result.folderName, file)
|
|
@@ -19976,9 +20119,12 @@ async function writeTypesToFile(config, types, fileName = 'types') {
|
|
|
19976
20119
|
typesContent: '',
|
|
19977
20120
|
writtenAt: ''
|
|
19978
20121
|
};
|
|
20122
|
+
const typeNames = Object.keys(types);
|
|
19979
20123
|
for (const typeName in types) {
|
|
19980
20124
|
templateInput.primitives.push(...types[typeName].primitives);
|
|
19981
|
-
|
|
20125
|
+
// Removing references that are already written to file
|
|
20126
|
+
const _references = [...types[typeName].references].filter((x) => !typeNames.includes(x));
|
|
20127
|
+
templateInput.referencedTypes.push(..._references);
|
|
19982
20128
|
templateInput.typesContent += types[typeName].content + '\n';
|
|
19983
20129
|
}
|
|
19984
20130
|
// remove duplicates
|
|
@@ -20080,7 +20226,7 @@ async function config$1(inputFilePath, outputDirectory, typesWriterMode, grouped
|
|
|
20080
20226
|
typeMapper: {
|
|
20081
20227
|
string: { default: 'string', date: 'Date' },
|
|
20082
20228
|
number: { default: 'number' },
|
|
20083
|
-
integer: { default: '
|
|
20229
|
+
integer: { default: 'number' },
|
|
20084
20230
|
boolean: 'boolean',
|
|
20085
20231
|
array: '~ItemType~[]',
|
|
20086
20232
|
object: 'type',
|
|
@@ -20122,7 +20268,7 @@ async function config(inputFilePath, outputDirectory, typesWriterMode, groupedTy
|
|
|
20122
20268
|
typeMapper: {
|
|
20123
20269
|
string: { default: 'string', date: 'Date' },
|
|
20124
20270
|
number: { default: 'number' },
|
|
20125
|
-
integer: { default: '
|
|
20271
|
+
integer: { default: 'number' },
|
|
20126
20272
|
boolean: 'boolean',
|
|
20127
20273
|
array: '~ItemType~[]',
|
|
20128
20274
|
object: 'type',
|
|
@@ -20179,15 +20325,15 @@ async function runner(language, inputFilePath, outputDirectory, _typesWriterMode
|
|
|
20179
20325
|
}
|
|
20180
20326
|
}
|
|
20181
20327
|
greeting();
|
|
20182
|
-
const program = new Command().version('0.
|
|
20328
|
+
const program = new Command().version('0.6.0');
|
|
20183
20329
|
program
|
|
20184
20330
|
.command('generate')
|
|
20185
20331
|
.description('Generate types for your language from a type spec file')
|
|
20186
20332
|
.argument('<outputLanguage>', 'Language to generate types for')
|
|
20187
20333
|
.argument('<inputFilePath>', 'Path to the input spec file')
|
|
20188
20334
|
.argument('<outputDirectory>', 'Path to the output file')
|
|
20189
|
-
.argument('[typesWriterMode]', 'Writer mode for types', '
|
|
20190
|
-
.argument('[groupedTypesWriterMode]', 'Writer mode for grouped types', '
|
|
20335
|
+
.argument('[typesWriterMode]', 'Writer mode for types', 'Files')
|
|
20336
|
+
.argument('[groupedTypesWriterMode]', 'Writer mode for grouped types', 'FolderWithFiles')
|
|
20191
20337
|
.action(runner);
|
|
20192
20338
|
program.parse();
|
|
20193
20339
|
|
package/dist/runtime.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ declare function getExpectedOutputFiles(): Map<string, TypeFilePath>;
|
|
|
14
14
|
declare function getCachedReferencedTypes(): Map<string, GeneratedReferencedType>;
|
|
15
15
|
declare function getCachedReferenceType(referencePath: string): GeneratedReferencedType | null;
|
|
16
16
|
declare function cacheReferenceType(referencePath: string, generatedData: GeneratedReferencedType): void;
|
|
17
|
+
declare function getInputFilePath(absolutePath?: boolean): string;
|
|
17
18
|
declare const _default: {
|
|
18
19
|
getConfig: typeof getConfig;
|
|
19
20
|
setConfig: typeof setConfig;
|
|
@@ -30,5 +31,6 @@ declare const _default: {
|
|
|
30
31
|
getCachedReferencedTypes: typeof getCachedReferencedTypes;
|
|
31
32
|
getCachedReferenceType: typeof getCachedReferenceType;
|
|
32
33
|
cacheReferenceType: typeof cacheReferenceType;
|
|
34
|
+
getInputFilePath: typeof getInputFilePath;
|
|
33
35
|
};
|
|
34
36
|
export default _default;
|
|
@@ -19,20 +19,20 @@ export type {{typeName}} = {
|
|
|
19
19
|
* @example {{{this.example}}}
|
|
20
20
|
{{/if}}
|
|
21
21
|
*/
|
|
22
|
-
{{@key}}: {{{this.type}}}{{#unless this.required}} | null{{/unless}};
|
|
22
|
+
{{{jsonKey @key}}}: {{{this.type}}}{{#unless this.required}} | null{{/unless}};
|
|
23
23
|
{{/each}}
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
export function decode{{typeName}}(rawInput: unknown): {{typeName}} | null {
|
|
27
27
|
if (isJSON(rawInput)) {
|
|
28
28
|
{{#each properties}}
|
|
29
|
-
const {{@key}} = {{#if (eq this.primitiveType 'array') }} decodeArray(rawInput
|
|
29
|
+
const decoded{{variableName @key}} = {{#if (eq this.primitiveType 'array') }} decodeArray(rawInput[{{{indexKey @key}}}], decode{{{toPascalCase this.composerType}}}){{else}} decode{{{toPascalCase this.type}}}(rawInput[{{{indexKey @key}}}]){{/if}};
|
|
30
30
|
{{/each}}
|
|
31
31
|
|
|
32
32
|
{{#if (areRequiredKeysPresent properties)}}
|
|
33
33
|
if (
|
|
34
34
|
{{#each (getRequiredKeys properties)}}
|
|
35
|
-
{{this}} === null{{#unless @last}} ||{{/unless}}
|
|
35
|
+
decoded{{toPascalCase this}} === null{{#unless @last}} ||{{/unless}}
|
|
36
36
|
{{/each}}
|
|
37
37
|
) {
|
|
38
38
|
return null;
|
|
@@ -41,7 +41,7 @@ export function decode{{typeName}}(rawInput: unknown): {{typeName}} | null {
|
|
|
41
41
|
|
|
42
42
|
return {
|
|
43
43
|
{{#each properties}}
|
|
44
|
-
{{@key}},
|
|
44
|
+
{{{jsonKey @key}}}: decoded{{{variableName @key}}},
|
|
45
45
|
{{/each}}
|
|
46
46
|
};
|
|
47
47
|
}
|
|
@@ -7,7 +7,7 @@ export type {{typeName}} =
|
|
|
7
7
|
{{else if (eq this.dataType 'object')}}
|
|
8
8
|
C{{this.templateInput.typeName}}
|
|
9
9
|
{{else}}
|
|
10
|
-
{{this.templateInput.
|
|
10
|
+
{{this.templateInput.type}}
|
|
11
11
|
{{/if}}
|
|
12
12
|
{{/if}}
|
|
13
13
|
{{/each}};
|
|
@@ -19,12 +19,12 @@ export function decode{{typeName}}(rawInput: unknown): {{typeName}} | null {
|
|
|
19
19
|
decodeC{{referencedType}}(rawInput)
|
|
20
20
|
{{else if (eq this.dataType 'object')}}
|
|
21
21
|
decodeC{{this.templateInput.typeName}}(rawInput)
|
|
22
|
-
{{else if (eq this.
|
|
23
|
-
decodeArray(rawInput, decode{{{toPascalCase this.templateInput.
|
|
22
|
+
{{else if (eq this.dataType 'array')}}
|
|
23
|
+
decodeArray(rawInput, decode{{{toPascalCase this.templateInput.composerType}}})
|
|
24
24
|
{{else if this.templateInput.values}}
|
|
25
25
|
decode{{this.templateInput.typeName}}(rawInput)
|
|
26
26
|
{{else}}
|
|
27
|
-
decode{{{toPascalCase this.templateInput.
|
|
27
|
+
decode{{{toPascalCase this.templateInput.type}}}(rawInput)
|
|
28
28
|
{{/if}}{{#unless @last}}??{{/unless}}
|
|
29
29
|
{{/each}};
|
|
30
30
|
return result;
|
package/dist/types/decoders.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import type { EnumTemplateInput, GroupedTypesWriterMode, ObjectTemplateInputProperties, SpecFileData, TypeInfo, TypesWriterMode } from '.';
|
|
1
|
+
import type { GroupRef, EnumTemplateInput, GroupedTypesWriterMode, ObjectTemplateInputProperties, SpecFileData, TypeInfo, Types, TypesWriterMode, GroupTypesData } from '.';
|
|
2
2
|
export declare function decodeGroupedTypesWriterMode(rawInput: unknown): GroupedTypesWriterMode | null;
|
|
3
3
|
export declare function decodeTypesWriterMode(rawInput: unknown): TypesWriterMode | null;
|
|
4
4
|
export declare function decodeSpecFileData(rawInput: unknown): SpecFileData | null;
|
|
5
|
+
export declare function valueIsGroupRef(value: GroupTypesData): value is GroupRef;
|
|
6
|
+
export declare function decodeTypes(rawInput: unknown): Types | null;
|
|
5
7
|
export declare function decodeTypeInfo(rawInput: unknown): TypeInfo | null;
|
|
6
8
|
export declare function decodeObjectTemplateInputProperties(rawInput: unknown): ObjectTemplateInputProperties | null;
|
|
7
9
|
export declare function decodeEnumTemplateInput(rawInput: unknown): EnumTemplateInput | null;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -36,12 +36,21 @@ export type FormatType = {
|
|
|
36
36
|
default: string;
|
|
37
37
|
[format: string]: string | undefined;
|
|
38
38
|
};
|
|
39
|
-
export type
|
|
39
|
+
export type ReferenceType = 'local' | 'remote' | 'url';
|
|
40
|
+
export type ReferenceMeta = {
|
|
41
|
+
completeSource: string;
|
|
42
|
+
sourceFile: string;
|
|
43
|
+
path: string;
|
|
44
|
+
type: ReferenceType;
|
|
45
|
+
name: string;
|
|
46
|
+
};
|
|
47
|
+
export type ResolvedTypeReferenceData = ReferenceMeta & {
|
|
40
48
|
typeInfo: TypeInfo;
|
|
41
|
-
referenceName: string;
|
|
42
|
-
sourceFile?: string;
|
|
43
49
|
};
|
|
44
|
-
export type
|
|
50
|
+
export type ResolvedGroupReferenceData = ReferenceMeta & {
|
|
51
|
+
groupedTypes: Types;
|
|
52
|
+
};
|
|
53
|
+
export type GeneratedReferencedType = ResolvedTypeReferenceData & {
|
|
45
54
|
templateData: GeneratedType<TemplateInput>;
|
|
46
55
|
};
|
|
47
56
|
export type SpecFileData = {
|
|
@@ -54,7 +63,11 @@ export type SpecInfo = {
|
|
|
54
63
|
title: string;
|
|
55
64
|
};
|
|
56
65
|
type GroupName = string;
|
|
57
|
-
export type GroupedTypes = Record<GroupName,
|
|
66
|
+
export type GroupedTypes = Record<GroupName, GroupTypesData>;
|
|
67
|
+
export type GroupTypesData = Types | GroupRef;
|
|
68
|
+
export type GroupRef = {
|
|
69
|
+
$ref: string;
|
|
70
|
+
};
|
|
58
71
|
type TypeName = string;
|
|
59
72
|
export type Types = Record<TypeName, TypeInfo>;
|
|
60
73
|
export type TypeInfo = TypeDescriptors & {
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -8,6 +8,9 @@ export declare function getReferencedTypes(object: unknown): string[];
|
|
|
8
8
|
export declare function getReferencedTypeModules(_referencedTypes: unknown, _writtenAt: string): unknown[];
|
|
9
9
|
export declare function toPascalCase(input: string): string;
|
|
10
10
|
export declare function toPascalCaseHelper(input: unknown): string | unknown;
|
|
11
|
+
export declare function refineJSONKey(input: unknown): unknown;
|
|
12
|
+
export declare function refineVariableName(input: unknown): unknown;
|
|
13
|
+
export declare function refineIndexKey(input: unknown): unknown;
|
|
11
14
|
export declare function registerTemplateHelpers(): void;
|
|
12
15
|
export declare function readNestedValue(json: unknown, keyPath: string[]): JSONObject;
|
|
13
16
|
export declare function generateRelativePath(fromPath: string, toPath: string): string;
|
package/dist/writer/helpers.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type TypeFilePath, type Types } from '$types';
|
|
2
2
|
export declare function generateTypesOutputFiles(types: Types | null, groupName?: string | null): Map<string, TypeFilePath>;
|
|
3
3
|
export declare function generateExpectedOutputFile(): Map<string, TypeFilePath>;
|