type-crafter 0.3.0 → 0.4.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/index.js CHANGED
@@ -10828,6 +10828,9 @@ function decodeTypeInfo(rawInput) {
10828
10828
  items: decodeTypeInfo(rawInput.items),
10829
10829
  format: decodeString(rawInput.format),
10830
10830
  $ref: decodeString(rawInput.$ref),
10831
+ description: decodeString(rawInput.description),
10832
+ example: decodeString(rawInput.example) ?? decodeNumber(rawInput.example),
10833
+ oneOf: decodeArray(rawInput.oneOf, decodeTypeInfo),
10831
10834
  enum: _type === 'string'
10832
10835
  ? decodeArray(rawInput.enum, decodeString)
10833
10836
  : _type === 'number'
@@ -10877,13 +10880,17 @@ function decodeObjectTemplateInputProperty(rawInput) {
10877
10880
  const referenced = decodeBoolean(rawInput.referenced);
10878
10881
  const primitiveType = decodeString(rawInput.primitiveType);
10879
10882
  const composerType = decodeString(rawInput.composerType);
10883
+ const example = decodeString(rawInput.example) ?? decodeNumber(rawInput.example);
10884
+ const description = decodeString(rawInput.description);
10880
10885
  if (required !== null && _type !== null && referenced !== null && primitiveType !== null) {
10881
10886
  return {
10882
10887
  type: _type,
10883
10888
  required,
10884
10889
  referenced,
10885
10890
  primitiveType,
10886
- composerType
10891
+ composerType,
10892
+ example,
10893
+ description
10887
10894
  };
10888
10895
  }
10889
10896
  }
@@ -19221,6 +19228,7 @@ let specFileData = null;
19221
19228
  let objectSyntaxTemplate = null;
19222
19229
  let exporterModuleSyntaxTemplate = null;
19223
19230
  let typesFileSyntaxTemplate = null;
19231
+ let oneOfSyntaxTemplate = null;
19224
19232
  let enumSyntaxTemplate = null;
19225
19233
  let expectedOutputFiles = null;
19226
19234
  function setConfig(newConfig) {
@@ -19247,6 +19255,7 @@ function compileTemplates() {
19247
19255
  exporterModuleSyntaxTemplate = Handlebars.compile(config.template.exporterModuleSyntax);
19248
19256
  typesFileSyntaxTemplate = Handlebars.compile(config.template.typesFileSyntax);
19249
19257
  enumSyntaxTemplate = Handlebars.compile(config.template.enumSyntax);
19258
+ oneOfSyntaxTemplate = Handlebars.compile(config.template.oneOfSyntax);
19250
19259
  }
19251
19260
  function getObjectTemplate() {
19252
19261
  if (objectSyntaxTemplate === null) {
@@ -19272,6 +19281,12 @@ function getEnumTemplate() {
19272
19281
  }
19273
19282
  return enumSyntaxTemplate;
19274
19283
  }
19284
+ function getOneOfTemplate() {
19285
+ if (oneOfSyntaxTemplate === null) {
19286
+ throw new RuntimeError('OneOf template not compiled!');
19287
+ }
19288
+ return oneOfSyntaxTemplate;
19289
+ }
19275
19290
  function setExpectedOutputFiles(newExpectedOutputFiles) {
19276
19291
  expectedOutputFiles = newExpectedOutputFiles;
19277
19292
  }
@@ -19292,7 +19307,8 @@ var Runtime = {
19292
19307
  getTypesFileTemplate,
19293
19308
  getEnumTemplate,
19294
19309
  getExpectedOutputFiles,
19295
- compileTemplates
19310
+ compileTemplates,
19311
+ getOneOfTemplate
19296
19312
  };
19297
19313
 
19298
19314
  function getSourceFileDirectory() {
@@ -19432,13 +19448,20 @@ function toPascalCase(input) {
19432
19448
  .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
19433
19449
  .join('');
19434
19450
  }
19451
+ function toPascalCaseHelper(input) {
19452
+ const inputString = decodeString(input);
19453
+ if (inputString === null) {
19454
+ return input;
19455
+ }
19456
+ return toPascalCase(inputString);
19457
+ }
19435
19458
  function registerTemplateHelpers() {
19436
19459
  Handlebars.registerHelper('getOptionalKeys', getOptionalKeys);
19437
19460
  Handlebars.registerHelper('getRequiredKeys', getRequiredKeys);
19438
19461
  Handlebars.registerHelper('areRequiredKeysPresent', (object) => getRequiredKeys(object).length > 0);
19439
19462
  Handlebars.registerHelper('getReferencedTypes', getReferencedTypes);
19440
19463
  Handlebars.registerHelper('getReferencedTypeModules', getReferencedTypeModules);
19441
- Handlebars.registerHelper('toPascalCase', toPascalCase);
19464
+ Handlebars.registerHelper('toPascalCase', toPascalCaseHelper);
19442
19465
  Handlebars.registerHelper('isNonEmptyArray', (value) => Array.isArray(value) && value.length === 0);
19443
19466
  Handlebars.registerHelper('eq', (value1, value2) => value1 === value2);
19444
19467
  }
@@ -19520,43 +19543,85 @@ function resolveAndGetReferenceName(reference) {
19520
19543
  return getReferenceName(reference);
19521
19544
  }
19522
19545
  function getLanguageDataType(dataType, format, items) {
19546
+ const result = {
19547
+ dataType,
19548
+ references: new Set(),
19549
+ primitives: new Set()
19550
+ };
19523
19551
  const typeMapper = Runtime.getConfig().language.typeMapper ?? null;
19524
19552
  const mappedType = typeMapper !== null ? typeMapper[dataType] : null;
19553
+ const itemReference =
19554
+ // eslint-disable-next-line @typescript-eslint/prefer-optional-chain
19555
+ items !== null && items.$ref !== null ? resolveAndGetReferenceName(items.$ref) : null;
19525
19556
  const itemsType =
19526
19557
  // eslint-disable-next-line
19527
19558
  items !== null
19528
19559
  ? items.type !== null
19529
19560
  ? getLanguageDataType(items.type, items.format, items.items)
19530
- : items.$ref !== null
19531
- ? resolveAndGetReferenceName(items.$ref)
19561
+ : itemReference !== null
19562
+ ? {
19563
+ dataType: itemReference,
19564
+ references: new Set([itemReference]),
19565
+ primitives: new Set()
19566
+ }
19532
19567
  : null
19533
19568
  : null;
19534
19569
  const fillerPatterns = [];
19535
19570
  if (itemsType !== null) {
19536
- fillerPatterns.push({ regex: /~ItemType~/g, value: itemsType });
19571
+ fillerPatterns.push({ regex: /~ItemType~/g, value: itemsType.dataType });
19537
19572
  }
19573
+ let mappedTypeWithFormat = null;
19574
+ let defaultType = null;
19538
19575
  if (typeof mappedType === 'string') {
19539
- return fillPatterns(mappedType, fillerPatterns);
19576
+ result.dataType = fillPatterns(mappedType, fillerPatterns);
19540
19577
  }
19541
19578
  else if (isJSON(mappedType)) {
19542
- const defaultType = mappedType.default;
19543
- const mappedTypeWithFormat = mappedType[format ?? ''] ?? defaultType;
19579
+ defaultType = mappedType.default;
19580
+ mappedTypeWithFormat = mappedType[format ?? ''] ?? defaultType;
19544
19581
  if (typeof mappedTypeWithFormat === 'string') {
19545
- return fillPatterns(mappedTypeWithFormat, fillerPatterns);
19582
+ result.dataType = fillPatterns(mappedTypeWithFormat, fillerPatterns);
19546
19583
  }
19547
19584
  }
19548
- return dataType;
19585
+ /**
19586
+ * @todo: Segregate array & variable type generation
19587
+ */
19588
+ const primitiveElementType = items?.$ref !== null
19589
+ ? null
19590
+ : mappedTypeWithFormat === null
19591
+ ? itemsType !== null
19592
+ ? itemsType.dataType
19593
+ : result.dataType
19594
+ : typeof mappedType === 'string' && items?.$ref !== null
19595
+ ? mappedType
19596
+ : null;
19597
+ if (itemsType !== null && primitiveElementType !== null) {
19598
+ result.itemType = primitiveElementType;
19599
+ }
19600
+ else if (itemsType !== null && itemReference !== null) {
19601
+ result.itemType = itemReference;
19602
+ }
19603
+ if (itemsType !== null) {
19604
+ result.references = new Set([...result.references, ...itemsType.references]);
19605
+ result.primitives =
19606
+ primitiveElementType !== null
19607
+ ? new Set([...result.primitives, primitiveElementType])
19608
+ : result.primitives;
19609
+ }
19610
+ return result;
19549
19611
  }
19550
19612
  function generateObjectType(typeName, typeInfo) {
19551
- const result = {
19552
- content: '',
19553
- references: new Set(),
19554
- primitives: new Set()
19555
- };
19556
19613
  const templateInput = {
19557
19614
  typeName,
19615
+ description: typeInfo.description,
19616
+ example: typeInfo.example,
19558
19617
  properties: {}
19559
19618
  };
19619
+ const result = {
19620
+ content: '',
19621
+ references: new Set(),
19622
+ primitives: new Set(),
19623
+ templateInput
19624
+ };
19560
19625
  let recursiveTypeGenOutput = null;
19561
19626
  let dynamicGeneratedType = '';
19562
19627
  for (const propertyName in typeInfo.properties) {
@@ -19599,7 +19664,7 @@ function generateObjectType(typeName, typeInfo) {
19599
19664
  }
19600
19665
  }
19601
19666
  else if (propertyType !== null) {
19602
- languageDataType = getLanguageDataType(propertyType, propertyFormat, propertyItems);
19667
+ languageDataType = getLanguageDataType(propertyType, propertyFormat, propertyItems).dataType;
19603
19668
  result.primitives.add(propertyItems !== null ? 'Array' : languageDataType);
19604
19669
  if (propertyItems !== null) {
19605
19670
  const itemsType = propertyItems.type ?? getReferenceName(propertyItems.$ref ?? '');
@@ -19617,7 +19682,9 @@ function generateObjectType(typeName, typeInfo) {
19617
19682
  required: typeInfo.required?.includes(propertyName) ?? false,
19618
19683
  referenced: isReferenced,
19619
19684
  primitiveType,
19620
- composerType
19685
+ composerType,
19686
+ example: propertyDetails.example,
19687
+ description: propertyDetails.description
19621
19688
  }
19622
19689
  };
19623
19690
  }
@@ -19628,31 +19695,113 @@ function generateObjectType(typeName, typeInfo) {
19628
19695
  return result;
19629
19696
  }
19630
19697
  function generateEnumType(typeName, typeInfo) {
19698
+ if (typeInfo.enum === null || typeInfo.enum.length === 0 || typeInfo.type === null) {
19699
+ throw new InvalidSpecFileError('Invalid enum type for: ' + typeName);
19700
+ }
19701
+ const templateInput = {
19702
+ typeName,
19703
+ enumType: typeInfo.type,
19704
+ values: typeInfo.enum,
19705
+ example: typeInfo.example,
19706
+ description: typeInfo.description
19707
+ };
19708
+ const result = {
19709
+ content: '',
19710
+ references: new Set(),
19711
+ primitives: new Set(),
19712
+ templateInput
19713
+ };
19714
+ result.content = Runtime.getEnumTemplate()(templateInput);
19715
+ return result;
19716
+ }
19717
+ function generateOneOfTypes(typeName, typeInfo) {
19631
19718
  const result = {
19632
19719
  content: '',
19633
19720
  references: new Set(),
19634
19721
  primitives: new Set()
19635
19722
  };
19636
- if (typeInfo.enum === null || typeInfo.enum.length === 0 || typeInfo.type === null) {
19637
- throw new InvalidSpecFileError('Invalid enum type for: ' + typeName);
19723
+ if (typeInfo.oneOf === null || typeInfo.oneOf.length === 0) {
19724
+ throw new InvalidSpecFileError('Invalid oneOf type for: ' + typeName);
19638
19725
  }
19639
19726
  const templateInput = {
19640
- enumName: typeName,
19641
- enumType: typeInfo.type,
19642
- values: typeInfo.enum
19727
+ typeName,
19728
+ compositions: []
19643
19729
  };
19644
- result.content = Runtime.getEnumTemplate()(templateInput);
19730
+ for (let index = 0; index < typeInfo.oneOf.length; index++) {
19731
+ const oneOfItem = typeInfo.oneOf[index];
19732
+ if (oneOfItem.$ref !== null) {
19733
+ const referenceName = resolveAndGetReferenceName(oneOfItem.$ref);
19734
+ const composition = {
19735
+ source: 'referenced',
19736
+ referencedType: referenceName
19737
+ };
19738
+ templateInput.compositions.push(composition);
19739
+ result.references.add(referenceName);
19740
+ }
19741
+ else {
19742
+ const generatedType = generateType(typeName + (index + 1), oneOfItem);
19743
+ if (generatedType === null) {
19744
+ throw new InvalidSpecFileError('Invalid oneOf type for: ' + typeName);
19745
+ }
19746
+ const composition = {
19747
+ dataType: oneOfItem.type,
19748
+ templateInput: generatedType.templateInput,
19749
+ source: 'inline',
19750
+ content: generatedType.content
19751
+ };
19752
+ templateInput.compositions.push(composition);
19753
+ for (const reference of generatedType.references.values()) {
19754
+ result.references.add(reference);
19755
+ }
19756
+ for (const primitive of generatedType.primitives.values()) {
19757
+ result.primitives.add(primitive);
19758
+ }
19759
+ }
19760
+ }
19761
+ result.content = Runtime.getOneOfTemplate()(templateInput);
19645
19762
  return result;
19646
19763
  }
19764
+ function generateVariableType(typeName, typeInfo) {
19765
+ if (typeInfo.type === null) {
19766
+ return null;
19767
+ }
19768
+ const dataType = getLanguageDataType(typeInfo.type, typeInfo.format, typeInfo.items);
19769
+ const _primitives = [...dataType.primitives];
19770
+ if (typeInfo.type === 'array' && dataType.references.size !== 0) {
19771
+ _primitives.push('Array');
19772
+ }
19773
+ else if (typeInfo.type !== 'array' && typeInfo.$ref === null) {
19774
+ _primitives.push(dataType.dataType);
19775
+ }
19776
+ return {
19777
+ content: '',
19778
+ references: dataType.references,
19779
+ primitives: new Set(_primitives),
19780
+ templateInput: {
19781
+ typeName,
19782
+ dataType: dataType.dataType,
19783
+ itemType: dataType.itemType,
19784
+ primitiveType: typeInfo.type
19785
+ }
19786
+ };
19787
+ }
19788
+ function generateType(typeName, typeInfo) {
19789
+ if (typeInfo.type === 'object') {
19790
+ return generateObjectType(typeName, typeInfo);
19791
+ }
19792
+ if (typeInfo.enum !== null) {
19793
+ return generateEnumType(typeName, typeInfo);
19794
+ }
19795
+ if (typeInfo.oneOf !== null) {
19796
+ return generateOneOfTypes(typeName, typeInfo);
19797
+ }
19798
+ return generateVariableType(typeName, typeInfo);
19799
+ }
19647
19800
  function generateTypes(types) {
19648
19801
  const result = {};
19649
19802
  for (const type in types) {
19650
19803
  const typeInfo = types[type];
19651
- const genType = typeInfo.type === 'object'
19652
- ? generateObjectType(type, typeInfo)
19653
- : typeInfo.enum !== null
19654
- ? generateEnumType(type, typeInfo)
19655
- : null;
19804
+ const genType = generateType(type, typeInfo);
19656
19805
  if (genType !== null) {
19657
19806
  result[type] = genType;
19658
19807
  }
@@ -19822,6 +19971,7 @@ async function config$1(inputFilePath, outputDirectory, typesWriterMode, grouped
19822
19971
  const exporterModuleSyntax = await readFile(directoryPrefix + 'templates/typescript/exporter-module-syntax.hbs', devMode);
19823
19972
  const typesFileSyntax = await readFile(directoryPrefix + 'templates/typescript/types-file-syntax.hbs', devMode);
19824
19973
  const enumSyntax = await readFile(directoryPrefix + 'templates/typescript/enum-syntax.hbs', devMode);
19974
+ const oneOfSyntax = await readFile(directoryPrefix + 'templates/typescript/oneOf-syntax.hbs', devMode);
19825
19975
  const config = {
19826
19976
  input: inputFilePath,
19827
19977
  output: {
@@ -19837,7 +19987,8 @@ async function config$1(inputFilePath, outputDirectory, typesWriterMode, grouped
19837
19987
  objectSyntax,
19838
19988
  exporterModuleSyntax,
19839
19989
  typesFileSyntax,
19840
- enumSyntax
19990
+ enumSyntax,
19991
+ oneOfSyntax
19841
19992
  },
19842
19993
  language: {
19843
19994
  exporterModuleName: 'index',
@@ -19862,6 +20013,7 @@ async function config(inputFilePath, outputDirectory, typesWriterMode, groupedTy
19862
20013
  const exporterModuleSyntax = await readFile(directoryPrefix + 'templates/typescript/exporter-module-syntax.hbs', devMode);
19863
20014
  const typesFileSyntax = await readFile(directoryPrefix + 'templates/typescript-with-decoders/types-file-syntax.hbs', devMode);
19864
20015
  const enumSyntax = await readFile(directoryPrefix + 'templates/typescript-with-decoders/enum-syntax.hbs', devMode);
20016
+ const oneOfSyntax = await readFile(directoryPrefix + 'templates/typescript-with-decoders/oneOf-syntax.hbs', devMode);
19865
20017
  const config = {
19866
20018
  input: inputFilePath,
19867
20019
  output: {
@@ -19877,7 +20029,8 @@ async function config(inputFilePath, outputDirectory, typesWriterMode, groupedTy
19877
20029
  objectSyntax,
19878
20030
  exporterModuleSyntax,
19879
20031
  typesFileSyntax,
19880
- enumSyntax
20032
+ enumSyntax,
20033
+ oneOfSyntax
19881
20034
  },
19882
20035
  language: {
19883
20036
  exporterModuleName: 'index',
@@ -19942,7 +20095,7 @@ async function runner(language, inputFilePath, outputDirectory, _typesWriterMode
19942
20095
  }
19943
20096
  }
19944
20097
  greeting();
19945
- const program = new Command().version('0.3.0');
20098
+ const program = new Command().version('0.4.0');
19946
20099
  program
19947
20100
  .command('generate')
19948
20101
  .description('Generate types for your language from a type spec file')
package/dist/runtime.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { Configuration, EnumTemplateInput, ExporterModuleTemplateInput, ObjectTemplateInput, SpecFileData, TypeFilePath, TypesFileTemplateInput } from '$types';
1
+ import type { Configuration, EnumTemplateInput, ExporterModuleTemplateInput, ObjectTemplateInput, OneOfTemplateInput, SpecFileData, TypeFilePath, TypesFileTemplateInput } from '$types';
2
2
  declare function setConfig(newConfig: Configuration): void;
3
3
  declare function getConfig(): Configuration;
4
4
  declare function setSpecFileData(newSpecFileData: SpecFileData): void;
@@ -8,6 +8,7 @@ declare function getObjectTemplate(): HandlebarsTemplateDelegate<ObjectTemplateI
8
8
  declare function getExporterModuleTemplate(): HandlebarsTemplateDelegate<ExporterModuleTemplateInput>;
9
9
  declare function getTypesFileTemplate(): HandlebarsTemplateDelegate<TypesFileTemplateInput>;
10
10
  declare function getEnumTemplate(): HandlebarsTemplateDelegate<EnumTemplateInput>;
11
+ declare function getOneOfTemplate(): HandlebarsTemplateDelegate<OneOfTemplateInput>;
11
12
  declare function setExpectedOutputFiles(newExpectedOutputFiles: Map<string, TypeFilePath>): void;
12
13
  declare function getExpectedOutputFiles(): Map<string, TypeFilePath>;
13
14
  declare const _default: {
@@ -22,5 +23,6 @@ declare const _default: {
22
23
  getEnumTemplate: typeof getEnumTemplate;
23
24
  getExpectedOutputFiles: typeof getExpectedOutputFiles;
24
25
  compileTemplates: typeof compileTemplates;
26
+ getOneOfTemplate: typeof getOneOfTemplate;
25
27
  };
26
28
  export default _default;
@@ -1,4 +1,13 @@
1
- export type {{enumName}} =
1
+ /**
2
+ * @type { {{typeName}} }
3
+ {{#if description}}
4
+ * @description {{{description}}}
5
+ {{/if}}
6
+ {{#if example}}
7
+ * @example {{{example}}}
8
+ {{/if}}
9
+ */
10
+ export type {{typeName}} =
2
11
  {{#each values}}
3
12
  | {{#if (eq ../enumType 'string') }}'{{/if}}{{{this}}}{{#if (eq ../enumType 'string')}}'{{/if}}
4
13
  {{/each}};
@@ -1,5 +1,24 @@
1
+ /**
2
+ * @type { {{typeName}} }
3
+ {{#if description}}
4
+ * @description {{{description}}}
5
+ {{/if}}
6
+ {{#if example}}
7
+ * @example {{{example}}}
8
+ {{/if}}
9
+ */
1
10
  export type {{typeName}} = {
2
11
  {{#each properties}}
12
+ /**
13
+ {{#if this.description}}
14
+ * @description {{{this.description}}}
15
+ {{/if}}
16
+ * @type { {{this.type}} }
17
+ * @memberof {{../typeName}}
18
+ {{#if this.example}}
19
+ * @example {{{this.example}}}
20
+ {{/if}}
21
+ */
3
22
  {{@key}}: {{{this.type}}}{{#unless this.required}} | null{{/unless}};
4
23
  {{/each}}
5
24
  };
@@ -0,0 +1,19 @@
1
+ export type {{typeName}} =
2
+ {{#each compositions}}
3
+ | {{#if (eq this.source 'referenced')}}{{referencedType}}
4
+ {{else if (eq this.source 'inline')}}
5
+ {{#if this.templateInput.values}}
6
+ {{#each this.templateInput.values}}
7
+ {{#unless @first}}|{{/unless}} {{#if (eq ../this.templateInput.enumType 'string') }}'{{/if}}{{{this}}}{{#if (eq ../this.templateInput/enumType 'string')}}'{{/if}}
8
+ {{/each}}
9
+ {{else if (eq this.dataType 'object')}}
10
+ {
11
+ {{#each this.templateInput.properties}}
12
+ {{@key}}: {{{this.type}}}{{#unless this.required}} | null{{/unless}};
13
+ {{/each}}
14
+ }
15
+ {{else}}
16
+ {{this.templateInput.dataType}}
17
+ {{/if}}
18
+ {{/if}}
19
+ {{/each}};
@@ -1,10 +1,18 @@
1
- export type {{enumName}} =
1
+ /**
2
+ * @type { {{typeName}} }
3
+ {{#if description}}
4
+ * @description {{{description}}}
5
+ {{/if}}
6
+ {{#if example}}
7
+ * @example {{{example}}}
8
+ {{/if}}
9
+ */
10
+ export type {{typeName}} =
2
11
  {{#each values}}
3
12
  | {{#if (eq ../enumType 'string') }}'{{/if}}{{{this}}}{{#if (eq ../enumType 'string')}}'{{/if}}
4
13
  {{/each}};
5
14
 
6
-
7
- export function decode{{enumName}}(rawInput: unknown): {{enumName}} | null {
15
+ export function decode{{typeName}}(rawInput: unknown): {{typeName}} | null {
8
16
  switch (rawInput) {
9
17
  {{#each values}}
10
18
  case {{#if (eq ../enumType 'string') }}'{{/if}}{{this}}{{#if (eq ../enumType 'string')}}'{{/if}}:
@@ -1,5 +1,24 @@
1
+ /**
2
+ * @type { {{typeName}} }
3
+ {{#if description}}
4
+ * @description {{{description}}}
5
+ {{/if}}
6
+ {{#if example}}
7
+ * @example {{{example}}}
8
+ {{/if}}
9
+ */
1
10
  export type {{typeName}} = {
2
11
  {{#each properties}}
12
+ /**
13
+ {{#if this.description}}
14
+ * @description {{{this.description}}}
15
+ {{/if}}
16
+ * @type { {{this.type}} }
17
+ * @memberof {{../typeName}}
18
+ {{#if this.example}}
19
+ * @example {{{this.example}}}
20
+ {{/if}}
21
+ */
3
22
  {{@key}}: {{{this.type}}}{{#unless this.required}} | null{{/unless}};
4
23
  {{/each}}
5
24
  };
@@ -0,0 +1,74 @@
1
+ export type {{typeName}} =
2
+ {{#each compositions}}
3
+ | {{#if (eq this.source 'referenced')}}C{{referencedType}}
4
+ {{else if (eq this.source 'inline')}}
5
+ {{#if this.templateInput.values}}
6
+ {{this.templateInput.typeName}}
7
+ {{else if (eq this.dataType 'object')}}
8
+ C{{this.templateInput.typeName}}
9
+ {{else}}
10
+ {{this.templateInput.dataType}}
11
+ {{/if}}
12
+ {{/if}}
13
+ {{/each}};
14
+
15
+ export function decode{{typeName}}(rawInput: unknown): {{typeName}} | null {
16
+ const result: {{typeName}} | null =
17
+ {{#each compositions}}
18
+ {{#if (eq this.source 'referenced')}}
19
+ decodeC{{referencedType}}(rawInput)
20
+ {{else if (eq this.dataType 'object')}}
21
+ decodeC{{this.templateInput.typeName}}(rawInput)
22
+ {{else if (eq this.templateInput.primitiveType 'array')}}
23
+ decodeArray(rawInput, decode{{{toPascalCase this.templateInput.itemType}}})
24
+ {{else if this.templateInput.values}}
25
+ decode{{this.templateInput.typeName}}(rawInput)
26
+ {{else}}
27
+ decode{{{toPascalCase this.templateInput.dataType}}}(rawInput)
28
+ {{/if}}{{#unless @last}}??{{/unless}}
29
+ {{/each}};
30
+ return result;
31
+ }
32
+
33
+
34
+ {{#each compositions}}
35
+
36
+ {{#if this.templateInput.values}}
37
+ {{{this.content}}}
38
+ {{else if (eq this.source 'referenced')}}
39
+ export class C{{referencedType}} {
40
+ data: {{referencedType}};
41
+ constructor(data: {{referencedType}}) {
42
+ this.data = data;
43
+ }
44
+ }
45
+
46
+ export function decodeC{{referencedType}}(rawInput: unknown): C{{referencedType}} | null {
47
+ const result = decode{{referencedType}}(rawInput);
48
+ if (result === null) {
49
+ return null;
50
+ }
51
+ return new C{{referencedType}}(result);
52
+ }
53
+
54
+ {{else if (eq this.dataType 'object')}}
55
+
56
+ {{{this.content}}}
57
+
58
+ export class C{{this.templateInput.typeName}} {
59
+ data: {{this.templateInput.typeName}};
60
+ constructor(data: {{this.templateInput.typeName}}) {
61
+ this.data = data;
62
+ }
63
+ }
64
+
65
+ export function decodeC{{this.templateInput.typeName}}(rawInput: unknown) {
66
+ const result = decode{{this.templateInput.typeName}}(rawInput);
67
+ if (result === null) {
68
+ return null;
69
+ }
70
+ return new C{{this.templateInput.typeName}}(result);
71
+ }
72
+
73
+ {{/if}}
74
+ {{/each}}
@@ -21,6 +21,7 @@ export type Template = {
21
21
  exporterModuleSyntax: string;
22
22
  typesFileSyntax: string;
23
23
  enumSyntax: string;
24
+ oneOfSyntax: string;
24
25
  };
25
26
  export type LanguageConfig = {
26
27
  exporterModuleName: string;
@@ -55,13 +56,18 @@ export type TypeInfo = {
55
56
  items: TypeInfo | null;
56
57
  properties: TypeProperties | null;
57
58
  $ref: string | null;
59
+ oneOf: TypeInfo[] | null;
58
60
  enum: string[] | number[] | null;
61
+ description: string | null;
62
+ example: string | number | null;
59
63
  };
60
64
  type PropertyName = string;
61
65
  export type TypeProperties = Record<PropertyName, TypeInfo>;
62
66
  export type TypeDataType = 'string' | 'number' | 'integer' | 'boolean' | 'array' | 'object' | 'unknown';
63
67
  export type ObjectTemplateInput = {
64
68
  typeName: string;
69
+ example: string | number | null;
70
+ description: string | null;
65
71
  properties: ObjectTemplateInputProperties;
66
72
  };
67
73
  export type ObjectTemplateInputProperties = Record<PropertyName, ObjectTemplateInputProperty>;
@@ -71,6 +77,8 @@ export type ObjectTemplateInputProperty = {
71
77
  referenced: boolean;
72
78
  primitiveType: string;
73
79
  composerType: string | null;
80
+ example: string | number | null;
81
+ description: string | null;
74
82
  };
75
83
  export type ExporterModuleTemplateInput = {
76
84
  modules: string[];
@@ -87,10 +95,30 @@ export type ReferencedModule = {
87
95
  referencedTypes: string[];
88
96
  };
89
97
  export type EnumTemplateInput = {
90
- enumName: string;
98
+ typeName: string;
91
99
  enumType: string;
92
100
  values: string[] | number[];
101
+ example: string | number | null;
102
+ description: string | null;
103
+ };
104
+ export type OneOfTemplateInput = {
105
+ typeName: string;
106
+ compositions: OneOfTemplateInputComposition[];
107
+ };
108
+ export type OneOfTemplateInputComposition = {
109
+ dataType?: TypeDataType | null;
110
+ templateInput?: TemplateInput;
111
+ source: 'inline' | 'referenced';
112
+ referencedType?: string;
113
+ content?: string;
114
+ };
115
+ export type VariableTemplateInput = {
116
+ typeName: string;
117
+ dataType: string;
118
+ primitiveType: string;
119
+ itemType?: string;
93
120
  };
121
+ export type TemplateInput = ObjectTemplateInput | EnumTemplateInput | VariableTemplateInput;
94
122
  export type GenerationResult = {
95
123
  groupedTypes: GroupedTypesOutput;
96
124
  types: GeneratedTypes;
@@ -99,6 +127,7 @@ export type GeneratedType = {
99
127
  content: string;
100
128
  references: Set<string>;
101
129
  primitives: Set<string>;
130
+ templateInput?: TemplateInput;
102
131
  };
103
132
  export type GroupedTypesOutput = Record<GroupName, GeneratedTypes>;
104
133
  export type GeneratedTypes = Record<TypeName, GeneratedType>;
@@ -7,6 +7,7 @@ export declare function getRequiredKeys(object: unknown): string[];
7
7
  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
+ export declare function toPascalCaseHelper(input: unknown): string | unknown;
10
11
  export declare function registerTemplateHelpers(): void;
11
12
  export declare function readNestedValue(json: JSONObject, keyPath: string[]): JSONObject;
12
13
  export declare function generateRelativePath(fromPath: string, toPath: string): string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "type-crafter",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "A tool to generate types from a yaml schema for any language",
5
5
  "main": "./dist/index.js",
6
6
  "type": "module",