type-crafter 0.12.1 → 0.13.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 +223 -64
- package/dist/templates/index.d.ts +1 -0
- package/dist/templates/rust/allOf-syntax.hbs +26 -0
- package/dist/templates/rust/enum-syntax.hbs +17 -0
- package/dist/templates/rust/exporter-module-syntax.hbs +3 -0
- package/dist/templates/rust/index.d.ts +2 -0
- package/dist/templates/rust/object-syntax.hbs +23 -0
- package/dist/templates/rust/oneOf-syntax.hbs +25 -0
- package/dist/templates/rust/types-file-syntax.hbs +8 -0
- package/dist/types/index.d.ts +14 -0
- package/dist/utils/file-system.d.ts +1 -1
- package/dist/utils/index.d.ts +4 -1
- package/package.json +7 -7
package/dist/index.js
CHANGED
|
@@ -20548,23 +20548,29 @@ var YAML = /*#__PURE__*/Object.freeze({
|
|
|
20548
20548
|
});
|
|
20549
20549
|
|
|
20550
20550
|
function hasColorSupport() {
|
|
20551
|
-
if (process.env.NO_COLOR !== undefined)
|
|
20551
|
+
if (typeof process.env.NO_COLOR !== 'undefined') {
|
|
20552
20552
|
return false;
|
|
20553
|
-
|
|
20553
|
+
}
|
|
20554
|
+
if (typeof process.env.FORCE_COLOR !== 'undefined') {
|
|
20554
20555
|
return true;
|
|
20555
|
-
|
|
20556
|
+
}
|
|
20557
|
+
if (process.env.COLORTERM === 'truecolor' || process.env.COLORTERM === '24bit') {
|
|
20556
20558
|
return true;
|
|
20557
|
-
|
|
20559
|
+
}
|
|
20560
|
+
if (typeof process.env.CI !== 'undefined') {
|
|
20558
20561
|
return true;
|
|
20562
|
+
}
|
|
20559
20563
|
const term = process.env.TERM ?? '';
|
|
20560
|
-
if (term === 'dumb')
|
|
20564
|
+
if (term === 'dumb') {
|
|
20561
20565
|
return false;
|
|
20566
|
+
}
|
|
20562
20567
|
if (term.includes('256color') ||
|
|
20563
20568
|
term.includes('color') ||
|
|
20564
20569
|
term.includes('xterm') ||
|
|
20565
20570
|
term.includes('screen') ||
|
|
20566
|
-
term.includes('vt100'))
|
|
20571
|
+
term.includes('vt100')) {
|
|
20567
20572
|
return true;
|
|
20573
|
+
}
|
|
20568
20574
|
return process.stdout.isTTY ?? false;
|
|
20569
20575
|
}
|
|
20570
20576
|
const isColorSupported = hasColorSupport();
|
|
@@ -20579,8 +20585,9 @@ function bgRgb(r, g, b) {
|
|
|
20579
20585
|
return `\x1b[48;2;${r};${g};${b}m`;
|
|
20580
20586
|
}
|
|
20581
20587
|
function colorize$2(text, ...codes) {
|
|
20582
|
-
if (!isColorSupported)
|
|
20588
|
+
if (!isColorSupported) {
|
|
20583
20589
|
return text;
|
|
20590
|
+
}
|
|
20584
20591
|
return codes.join('') + text + RESET;
|
|
20585
20592
|
}
|
|
20586
20593
|
const BRAND$2 = {
|
|
@@ -20629,14 +20636,16 @@ function interpolateColor(start, end, t) {
|
|
|
20629
20636
|
};
|
|
20630
20637
|
}
|
|
20631
20638
|
function gradientText(text, startColor, endColor) {
|
|
20632
|
-
if (!isColorSupported)
|
|
20639
|
+
if (!isColorSupported) {
|
|
20633
20640
|
return text;
|
|
20641
|
+
}
|
|
20634
20642
|
// eslint-disable-next-line @typescript-eslint/no-misused-spread -- character-by-character gradient
|
|
20635
20643
|
const chars = [...text];
|
|
20636
20644
|
return chars
|
|
20637
20645
|
.map((char, i) => {
|
|
20638
|
-
if (char === ' ' || char === '\n')
|
|
20646
|
+
if (char === ' ' || char === '\n') {
|
|
20639
20647
|
return char;
|
|
20648
|
+
}
|
|
20640
20649
|
const t = chars.length > 1 ? i / (chars.length - 1) : 0;
|
|
20641
20650
|
const color = interpolateColor(startColor, endColor, t);
|
|
20642
20651
|
return rgb(color.r, color.g, color.b) + char;
|
|
@@ -20699,8 +20708,9 @@ function createSpinner(message) {
|
|
|
20699
20708
|
spinnerFrame = 0;
|
|
20700
20709
|
return {
|
|
20701
20710
|
start: () => {
|
|
20702
|
-
if (activeSpinner)
|
|
20711
|
+
if (activeSpinner) {
|
|
20703
20712
|
clearInterval(activeSpinner);
|
|
20713
|
+
}
|
|
20704
20714
|
const render = () => {
|
|
20705
20715
|
clearSpinnerLine();
|
|
20706
20716
|
const frame = isColorSupported
|
|
@@ -20749,8 +20759,9 @@ function createSpinner(message) {
|
|
|
20749
20759
|
};
|
|
20750
20760
|
}
|
|
20751
20761
|
function badge(text, bgColor, fgColor = FG.white) {
|
|
20752
|
-
if (!isColorSupported)
|
|
20762
|
+
if (!isColorSupported) {
|
|
20753
20763
|
return `[${text}]`;
|
|
20764
|
+
}
|
|
20754
20765
|
return `${bgColor}${fgColor}${BOLD} ${text} ${RESET}`;
|
|
20755
20766
|
}
|
|
20756
20767
|
function logError(header, message = null) {
|
|
@@ -20883,12 +20894,26 @@ async function getExpectedWrittenPath(basePath, fileName) {
|
|
|
20883
20894
|
: path.join(process.cwd(), basePath, fileName);
|
|
20884
20895
|
return filePath;
|
|
20885
20896
|
}
|
|
20886
|
-
async function
|
|
20897
|
+
async function safeReadContent(filePath) {
|
|
20898
|
+
try {
|
|
20899
|
+
return await fs.readFile(filePath, 'utf-8');
|
|
20900
|
+
}
|
|
20901
|
+
catch (e) {
|
|
20902
|
+
return '';
|
|
20903
|
+
}
|
|
20904
|
+
}
|
|
20905
|
+
async function writeFile(basePath, fileName, content, append = false) {
|
|
20887
20906
|
const isAbsolutePath = path.isAbsolute(basePath);
|
|
20888
20907
|
const filePath = isAbsolutePath
|
|
20889
20908
|
? path.join(basePath, fileName)
|
|
20890
20909
|
: path.join(process.cwd(), basePath, fileName);
|
|
20891
|
-
|
|
20910
|
+
if (append) {
|
|
20911
|
+
const existingData = await safeReadContent(filePath);
|
|
20912
|
+
await fs.writeFile(filePath, content + existingData);
|
|
20913
|
+
}
|
|
20914
|
+
else {
|
|
20915
|
+
await fs.writeFile(filePath, content);
|
|
20916
|
+
}
|
|
20892
20917
|
}
|
|
20893
20918
|
async function readYaml(filePath) {
|
|
20894
20919
|
const fileData = await readFile(filePath, true, true);
|
|
@@ -20986,7 +21011,7 @@ function handleErrors(error) {
|
|
|
20986
21011
|
}
|
|
20987
21012
|
}
|
|
20988
21013
|
|
|
20989
|
-
let config$
|
|
21014
|
+
let config$3 = null;
|
|
20990
21015
|
let specFileData = null;
|
|
20991
21016
|
let objectSyntaxTemplate = null;
|
|
20992
21017
|
let exporterModuleSyntaxTemplate = null;
|
|
@@ -20997,13 +21022,13 @@ let allOfSyntaxTemplate = null;
|
|
|
20997
21022
|
const cachedReferencedTypes = new Map();
|
|
20998
21023
|
let expectedOutputFiles = null;
|
|
20999
21024
|
function setConfig(newConfig) {
|
|
21000
|
-
config$
|
|
21025
|
+
config$3 = newConfig;
|
|
21001
21026
|
}
|
|
21002
21027
|
function getConfig() {
|
|
21003
|
-
if (config$
|
|
21028
|
+
if (config$3 === null) {
|
|
21004
21029
|
throw new RuntimeError('Failed to load configuration!');
|
|
21005
21030
|
}
|
|
21006
|
-
return config$
|
|
21031
|
+
return config$3;
|
|
21007
21032
|
}
|
|
21008
21033
|
function setSpecFileData(newSpecFileData) {
|
|
21009
21034
|
specFileData = newSpecFileData;
|
|
@@ -21072,10 +21097,10 @@ function cacheReferenceType(referencePath, generatedData) {
|
|
|
21072
21097
|
cachedReferencedTypes.set(referencePath, generatedData);
|
|
21073
21098
|
}
|
|
21074
21099
|
function getInputFilePath(absolutePath = true) {
|
|
21075
|
-
if (config$
|
|
21100
|
+
if (config$3 === null) {
|
|
21076
21101
|
throw new RuntimeError('Spec file path not set!');
|
|
21077
21102
|
}
|
|
21078
|
-
return absolutePath ? resolveFilePath(config$
|
|
21103
|
+
return absolutePath ? resolveFilePath(config$3.input) : config$3.input;
|
|
21079
21104
|
}
|
|
21080
21105
|
function getAllOfTemplate() {
|
|
21081
21106
|
if (allOfSyntaxTemplate === null) {
|
|
@@ -21155,16 +21180,19 @@ function getReferencedTypeModules(_referencedTypes, _writtenAt) {
|
|
|
21155
21180
|
return [];
|
|
21156
21181
|
}
|
|
21157
21182
|
const expectedOutputFiles = Runtime.getExpectedOutputFiles();
|
|
21183
|
+
const modulePathConfig = Runtime.getConfig().language.modulePathConfig;
|
|
21158
21184
|
const referencedTypeModules = {};
|
|
21159
21185
|
for (const referenceType of referencedTypes) {
|
|
21160
21186
|
const outputFile = expectedOutputFiles.get(referenceType);
|
|
21161
21187
|
if (typeof outputFile !== 'undefined' &&
|
|
21162
21188
|
resolveFilePath(outputFile.filePath) !== resolveFilePath(writtenAt)) {
|
|
21163
21189
|
if (typeof referencedTypeModules[outputFile.modulePath] === 'undefined') {
|
|
21190
|
+
const rawRelativePath = generateRelativePath(writtenAt, outputFile.modulePath);
|
|
21164
21191
|
referencedTypeModules[outputFile.modulePath] = {
|
|
21165
21192
|
modulePath: outputFile.modulePath,
|
|
21166
|
-
moduleRelativePath:
|
|
21167
|
-
referencedTypes: [referenceType]
|
|
21193
|
+
moduleRelativePath: formatModulePath(rawRelativePath, writtenAt, modulePathConfig),
|
|
21194
|
+
referencedTypes: [referenceType],
|
|
21195
|
+
moduleName: outputFile.modulePath.split('/').pop() ?? ''
|
|
21168
21196
|
};
|
|
21169
21197
|
}
|
|
21170
21198
|
else {
|
|
@@ -21191,6 +21219,21 @@ function toPascalCaseHelper(input) {
|
|
|
21191
21219
|
}
|
|
21192
21220
|
return toPascalCase(inputString);
|
|
21193
21221
|
}
|
|
21222
|
+
function toSnakeCase(input) {
|
|
21223
|
+
return input
|
|
21224
|
+
.replace(/[-]/g, '_')
|
|
21225
|
+
.replace(/(?<upper>[A-Z]+)(?<next>[A-Z][a-z])/g, '$1_$2')
|
|
21226
|
+
.replace(/(?<lower>[a-z\d])(?<cap>[A-Z])/g, '$1_$2')
|
|
21227
|
+
.toLowerCase()
|
|
21228
|
+
.replace(/__+/g, '_');
|
|
21229
|
+
}
|
|
21230
|
+
function toSnakeCaseHelper(input) {
|
|
21231
|
+
const inputString = decodeString(input);
|
|
21232
|
+
if (inputString === null) {
|
|
21233
|
+
return input;
|
|
21234
|
+
}
|
|
21235
|
+
return toSnakeCase(inputString);
|
|
21236
|
+
}
|
|
21194
21237
|
function refineJSONKey(input) {
|
|
21195
21238
|
if (typeof input === 'string' && input.includes('-')) {
|
|
21196
21239
|
return `'${input}'`;
|
|
@@ -21216,6 +21259,7 @@ function registerTemplateHelpers() {
|
|
|
21216
21259
|
Handlebars.registerHelper('getReferencedTypes', getReferencedTypes);
|
|
21217
21260
|
Handlebars.registerHelper('getReferencedTypeModules', getReferencedTypeModules);
|
|
21218
21261
|
Handlebars.registerHelper('toPascalCase', toPascalCaseHelper);
|
|
21262
|
+
Handlebars.registerHelper('toSnakeCase', toSnakeCaseHelper);
|
|
21219
21263
|
Handlebars.registerHelper('isNonEmptyArray', (value) => Array.isArray(value) && value.length === 0);
|
|
21220
21264
|
Handlebars.registerHelper('eq', (value1, value2) => value1 === value2);
|
|
21221
21265
|
Handlebars.registerHelper('notEq', (value1, value2) => value1 !== value2);
|
|
@@ -21223,6 +21267,7 @@ function registerTemplateHelpers() {
|
|
|
21223
21267
|
Handlebars.registerHelper('jsonKey', refineJSONKey);
|
|
21224
21268
|
Handlebars.registerHelper('variableName', refineVariableName);
|
|
21225
21269
|
Handlebars.registerHelper('indexKey', refineIndexKey);
|
|
21270
|
+
Handlebars.registerHelper('stringify', (value) => JSON.stringify(value));
|
|
21226
21271
|
Handlebars.registerHelper('not', (value) => {
|
|
21227
21272
|
if (typeof value === 'boolean') {
|
|
21228
21273
|
return !value;
|
|
@@ -21265,6 +21310,30 @@ function generateRelativePath(fromPath, toPath) {
|
|
|
21265
21310
|
pathPrefix = pathPrefix === '' ? './' : pathPrefix;
|
|
21266
21311
|
return pathPrefix + toPathArray.slice(diffIndex).join('/');
|
|
21267
21312
|
}
|
|
21313
|
+
function formatModulePath(relativePath, writtenAt, config) {
|
|
21314
|
+
let path = relativePath.replace(/^\.\//, '');
|
|
21315
|
+
const isModuleFile = writtenAt.endsWith('/' + config.moduleFileName) ||
|
|
21316
|
+
writtenAt.endsWith('\\' + config.moduleFileName);
|
|
21317
|
+
let parentCount = config.fileBasedModules && !isModuleFile ? 1 : 0;
|
|
21318
|
+
while (path.startsWith('../')) {
|
|
21319
|
+
parentCount++;
|
|
21320
|
+
path = path.slice(3);
|
|
21321
|
+
}
|
|
21322
|
+
const moduleFileRegex = new RegExp(`\\/?${config.moduleFileName}$`);
|
|
21323
|
+
path = path.replace(moduleFileRegex, '').replace(/\/$/, '');
|
|
21324
|
+
const parentPart = parentCount > 0 ? Array(parentCount).fill(config.parentRef).join(config.separator) : '';
|
|
21325
|
+
if (path === '' && parentPart === '') {
|
|
21326
|
+
return config.selfRef;
|
|
21327
|
+
}
|
|
21328
|
+
if (path === '') {
|
|
21329
|
+
return parentPart;
|
|
21330
|
+
}
|
|
21331
|
+
const formattedPath = path.replace(/\//g, config.separator);
|
|
21332
|
+
if (parentPart === '') {
|
|
21333
|
+
return formattedPath;
|
|
21334
|
+
}
|
|
21335
|
+
return parentPart + config.separator + formattedPath;
|
|
21336
|
+
}
|
|
21268
21337
|
// #region string utils
|
|
21269
21338
|
function stripPrefix(value, prefix) {
|
|
21270
21339
|
return value.startsWith(prefix) ? value.slice(prefix.length) : value;
|
|
@@ -21417,21 +21486,23 @@ function getPrimitiveType(typeName, typeInfo) {
|
|
|
21417
21486
|
return result;
|
|
21418
21487
|
}
|
|
21419
21488
|
async function generateAdditionalPropertiesType(typeName, typeInfo, parentTypes) {
|
|
21420
|
-
let result = null;
|
|
21421
21489
|
const stringKeyType = getPrimitiveType(typeName, {
|
|
21422
21490
|
...placeholderTypeInfo,
|
|
21423
21491
|
type: 'string'
|
|
21424
21492
|
}).templateInput.type;
|
|
21425
21493
|
if (typeof typeInfo.additionalProperties === 'boolean') {
|
|
21426
|
-
|
|
21427
|
-
|
|
21428
|
-
|
|
21429
|
-
|
|
21430
|
-
|
|
21431
|
-
|
|
21432
|
-
|
|
21433
|
-
|
|
21434
|
-
|
|
21494
|
+
return {
|
|
21495
|
+
templateInput: {
|
|
21496
|
+
keyType: stringKeyType,
|
|
21497
|
+
valueType: getPrimitiveType(typeName, {
|
|
21498
|
+
...placeholderTypeInfo,
|
|
21499
|
+
type: 'unknown'
|
|
21500
|
+
}).templateInput.type,
|
|
21501
|
+
valueTypeReferenced: false,
|
|
21502
|
+
valuePrimitiveType: 'unknown',
|
|
21503
|
+
valueComposerType: null
|
|
21504
|
+
},
|
|
21505
|
+
primitives: new Set()
|
|
21435
21506
|
};
|
|
21436
21507
|
}
|
|
21437
21508
|
else if (valueIsKeyedAdditionalProperties(typeInfo.additionalProperties)) {
|
|
@@ -21439,17 +21510,20 @@ async function generateAdditionalPropertiesType(typeName, typeInfo, parentTypes)
|
|
|
21439
21510
|
const generatedValueType = await generateType(typeName + 'ValueType', valueTypeInfo, parentTypes);
|
|
21440
21511
|
const isReferenced = valueTypeInfo.$ref !== null;
|
|
21441
21512
|
const isArray = valueTypeInfo.type === 'array';
|
|
21442
|
-
|
|
21443
|
-
|
|
21444
|
-
|
|
21445
|
-
|
|
21446
|
-
|
|
21447
|
-
|
|
21448
|
-
|
|
21449
|
-
|
|
21450
|
-
|
|
21451
|
-
|
|
21452
|
-
|
|
21513
|
+
return {
|
|
21514
|
+
templateInput: {
|
|
21515
|
+
keyType: getPrimitiveType(typeName, {
|
|
21516
|
+
...placeholderTypeInfo,
|
|
21517
|
+
type: typeInfo.additionalProperties.keyType
|
|
21518
|
+
}).templateInput.type,
|
|
21519
|
+
valueType: generatedValueType.templateInput.type,
|
|
21520
|
+
valueTypeReferenced: isReferenced,
|
|
21521
|
+
valuePrimitiveType: isArray ? 'array' : (valueTypeInfo.type ?? 'object'),
|
|
21522
|
+
valueComposerType: 'composerType' in generatedValueType.templateInput
|
|
21523
|
+
? (generatedValueType.templateInput.composerType ?? null)
|
|
21524
|
+
: null
|
|
21525
|
+
},
|
|
21526
|
+
primitives: generatedValueType.primitives
|
|
21453
21527
|
};
|
|
21454
21528
|
}
|
|
21455
21529
|
else if (valueIsTypeInfo(typeInfo.additionalProperties)) {
|
|
@@ -21457,17 +21531,20 @@ async function generateAdditionalPropertiesType(typeName, typeInfo, parentTypes)
|
|
|
21457
21531
|
const generatedValueType = await generateType(typeName + 'ValueType', valueTypeInfo, parentTypes);
|
|
21458
21532
|
const isReferenced = valueTypeInfo.$ref !== null;
|
|
21459
21533
|
const isArray = valueTypeInfo.type === 'array';
|
|
21460
|
-
|
|
21461
|
-
|
|
21462
|
-
|
|
21463
|
-
|
|
21464
|
-
|
|
21465
|
-
|
|
21466
|
-
|
|
21467
|
-
|
|
21534
|
+
return {
|
|
21535
|
+
templateInput: {
|
|
21536
|
+
keyType: stringKeyType,
|
|
21537
|
+
valueType: generatedValueType.templateInput.type,
|
|
21538
|
+
valueTypeReferenced: isReferenced,
|
|
21539
|
+
valuePrimitiveType: isArray ? 'array' : (valueTypeInfo.type ?? 'object'),
|
|
21540
|
+
valueComposerType: 'composerType' in generatedValueType.templateInput
|
|
21541
|
+
? (generatedValueType.templateInput.composerType ?? null)
|
|
21542
|
+
: null
|
|
21543
|
+
},
|
|
21544
|
+
primitives: generatedValueType.primitives
|
|
21468
21545
|
};
|
|
21469
21546
|
}
|
|
21470
|
-
return
|
|
21547
|
+
return null;
|
|
21471
21548
|
}
|
|
21472
21549
|
async function generateObjectType(typeName, typeInfo, parentTypes) {
|
|
21473
21550
|
const templateInput = {
|
|
@@ -21556,9 +21633,10 @@ async function generateObjectType(typeName, typeInfo, parentTypes) {
|
|
|
21556
21633
|
};
|
|
21557
21634
|
}
|
|
21558
21635
|
// Generating additional property types
|
|
21559
|
-
const
|
|
21560
|
-
if (
|
|
21561
|
-
templateInput.additionalProperties =
|
|
21636
|
+
const additionalPropertiesResult = await generateAdditionalPropertiesType(typeName + 'AdditionalProperty', typeInfo, parentTypes);
|
|
21637
|
+
if (additionalPropertiesResult !== null) {
|
|
21638
|
+
templateInput.additionalProperties = additionalPropertiesResult.templateInput;
|
|
21639
|
+
primitives.push(...additionalPropertiesResult.primitives);
|
|
21562
21640
|
}
|
|
21563
21641
|
const result = {
|
|
21564
21642
|
content: Runtime.getObjectTemplate()(templateInput) +
|
|
@@ -21926,7 +22004,8 @@ function generateExpectedOutputFile() {
|
|
|
21926
22004
|
// Generating expect writing types for referenced types
|
|
21927
22005
|
let referredGroups = {};
|
|
21928
22006
|
for (const generatedRefData of Runtime.getCachedReferencedTypes().values()) {
|
|
21929
|
-
if (
|
|
22007
|
+
if (generatedRefData.type !== 'local' &&
|
|
22008
|
+
typeof generatedRefData.sourceFile !== 'undefined' &&
|
|
21930
22009
|
generatedRefData.completeSource !== Runtime.getInputFilePath() // Preventing new file creation for remote references from base file
|
|
21931
22010
|
) {
|
|
21932
22011
|
const groupName = toPascalCase(generatedRefData.sourceFile.replace('.yaml', ''));
|
|
@@ -21981,7 +22060,7 @@ async function writeTypesToFiles(config, types, folderName = '') {
|
|
|
21981
22060
|
}
|
|
21982
22061
|
return result;
|
|
21983
22062
|
}
|
|
21984
|
-
async function writeTypesToFile(config, types, fileName
|
|
22063
|
+
async function writeTypesToFile(config, types, fileName) {
|
|
21985
22064
|
const templateInput = {
|
|
21986
22065
|
referencedTypes: [],
|
|
21987
22066
|
primitives: [],
|
|
@@ -22011,7 +22090,13 @@ async function writeExporterModules(files, folder) {
|
|
|
22011
22090
|
const exporterModuleContent = Runtime.getExporterModuleTemplate()({
|
|
22012
22091
|
modules: [...files].map((file) => file.replace(Runtime.getConfig().output.fileExtension, ''))
|
|
22013
22092
|
});
|
|
22014
|
-
|
|
22093
|
+
const config = Runtime.getConfig();
|
|
22094
|
+
// Merging the contents of exporter module & types file in case their names are same.
|
|
22095
|
+
const typesFileName = Runtime.getConfig().output.typesFileName;
|
|
22096
|
+
const moduleExporterFileName = Runtime.getConfig().language.exporterModuleName;
|
|
22097
|
+
const writingTypesFile = files.has(typesFileName + config.output.fileExtension);
|
|
22098
|
+
const appendContent = writingTypesFile && typesFileName === moduleExporterFileName;
|
|
22099
|
+
await writeFile(folder, Runtime.getConfig().language.exporterModuleName + Runtime.getConfig().output.fileExtension, exporterModuleContent, appendContent);
|
|
22015
22100
|
}
|
|
22016
22101
|
async function writeOutput(generationResult) {
|
|
22017
22102
|
const config = Runtime.getConfig();
|
|
@@ -22022,20 +22107,21 @@ async function writeOutput(generationResult) {
|
|
|
22022
22107
|
const writtenFiles = new Map();
|
|
22023
22108
|
// pre compute all the folders and files that will be written
|
|
22024
22109
|
Runtime.setExpectedOutputFiles(generateExpectedOutputFile());
|
|
22025
|
-
// writing types to output directory
|
|
22110
|
+
// #region writing types to output directory
|
|
22026
22111
|
let typesFilesWritten = null;
|
|
22027
22112
|
if (Object.keys(generationResult.types).length > 0) {
|
|
22028
22113
|
if (config.output.writerMode.types === 'Files') {
|
|
22029
22114
|
typesFilesWritten = await writeTypesToFiles(config, generationResult.types);
|
|
22030
22115
|
}
|
|
22031
22116
|
else if (config.output.writerMode.types === 'SingleFile') {
|
|
22032
|
-
typesFilesWritten = await writeTypesToFile(config, generationResult.types);
|
|
22117
|
+
typesFilesWritten = await writeTypesToFile(config, generationResult.types, Runtime.getConfig().output.typesFileName);
|
|
22033
22118
|
}
|
|
22034
22119
|
}
|
|
22035
22120
|
if (typesFilesWritten !== null) {
|
|
22036
22121
|
addValuesToMappedSet(writtenFiles, await getCompleteFolderPath(typesFilesWritten.folderName), typesFilesWritten.files);
|
|
22037
22122
|
}
|
|
22038
|
-
//
|
|
22123
|
+
// #endregion
|
|
22124
|
+
// #region writing grouped types to output directory
|
|
22039
22125
|
if (config.output.writerMode.groupedTypes === 'FolderWithFiles') {
|
|
22040
22126
|
for (const groupName in generationResult.groupedTypes) {
|
|
22041
22127
|
let groupFilesWritten = null;
|
|
@@ -22058,12 +22144,13 @@ async function writeOutput(generationResult) {
|
|
|
22058
22144
|
}
|
|
22059
22145
|
}
|
|
22060
22146
|
}
|
|
22147
|
+
// #endregion
|
|
22061
22148
|
writtenFiles.forEach((files, folder) => {
|
|
22062
22149
|
void writeExporterModules(files, folder);
|
|
22063
22150
|
});
|
|
22064
22151
|
}
|
|
22065
22152
|
|
|
22066
|
-
async function config$
|
|
22153
|
+
async function config$2(inputFilePath, outputDirectory, typesWriterMode, groupedTypesWriterMode) {
|
|
22067
22154
|
const devMode = 'PRODUCTION'.includes('DEVELOPMENT');
|
|
22068
22155
|
// PRODUCTION will be replaced with PRODUCTION when package is built.
|
|
22069
22156
|
const directoryPrefix = devMode ? 'src/' : './';
|
|
@@ -22079,6 +22166,7 @@ async function config$1(inputFilePath, outputDirectory, typesWriterMode, grouped
|
|
|
22079
22166
|
cleanWrite: true,
|
|
22080
22167
|
fileExtension: '.ts',
|
|
22081
22168
|
directory: outputDirectory,
|
|
22169
|
+
typesFileName: 'types',
|
|
22082
22170
|
writerMode: {
|
|
22083
22171
|
groupedTypes: groupedTypesWriterMode,
|
|
22084
22172
|
types: typesWriterMode
|
|
@@ -22102,13 +22190,20 @@ async function config$1(inputFilePath, outputDirectory, typesWriterMode, grouped
|
|
|
22102
22190
|
array: '~ItemType~[]',
|
|
22103
22191
|
object: 'type',
|
|
22104
22192
|
unknown: 'unknown'
|
|
22193
|
+
},
|
|
22194
|
+
modulePathConfig: {
|
|
22195
|
+
separator: '/',
|
|
22196
|
+
parentRef: '..',
|
|
22197
|
+
selfRef: '.',
|
|
22198
|
+
moduleFileName: 'index',
|
|
22199
|
+
fileBasedModules: false
|
|
22105
22200
|
}
|
|
22106
22201
|
}
|
|
22107
22202
|
};
|
|
22108
22203
|
return config;
|
|
22109
22204
|
}
|
|
22110
22205
|
|
|
22111
|
-
async function config(inputFilePath, outputDirectory, typesWriterMode, groupedTypesWriterMode) {
|
|
22206
|
+
async function config$1(inputFilePath, outputDirectory, typesWriterMode, groupedTypesWriterMode) {
|
|
22112
22207
|
const devMode = 'PRODUCTION'.includes('DEVELOPMENT');
|
|
22113
22208
|
const directoryPrefix = devMode ? 'src/' : './';
|
|
22114
22209
|
const objectSyntax = await readFile(directoryPrefix + 'templates/typescript-with-decoders/object-syntax.hbs', devMode);
|
|
@@ -22123,6 +22218,7 @@ async function config(inputFilePath, outputDirectory, typesWriterMode, groupedTy
|
|
|
22123
22218
|
cleanWrite: true,
|
|
22124
22219
|
fileExtension: '.ts',
|
|
22125
22220
|
directory: outputDirectory,
|
|
22221
|
+
typesFileName: 'types',
|
|
22126
22222
|
writerMode: {
|
|
22127
22223
|
groupedTypes: groupedTypesWriterMode,
|
|
22128
22224
|
types: typesWriterMode
|
|
@@ -22146,6 +22242,66 @@ async function config(inputFilePath, outputDirectory, typesWriterMode, groupedTy
|
|
|
22146
22242
|
array: '~ItemType~[]',
|
|
22147
22243
|
object: 'type',
|
|
22148
22244
|
unknown: 'unknown'
|
|
22245
|
+
},
|
|
22246
|
+
modulePathConfig: {
|
|
22247
|
+
separator: '/',
|
|
22248
|
+
parentRef: '..',
|
|
22249
|
+
selfRef: '.',
|
|
22250
|
+
moduleFileName: 'index',
|
|
22251
|
+
fileBasedModules: false
|
|
22252
|
+
}
|
|
22253
|
+
}
|
|
22254
|
+
};
|
|
22255
|
+
return config;
|
|
22256
|
+
}
|
|
22257
|
+
|
|
22258
|
+
async function config(inputFilePath, outputDirectory, typesWriterMode, groupedTypesWriterMode) {
|
|
22259
|
+
const devMode = 'PRODUCTION'.includes('DEVELOPMENT');
|
|
22260
|
+
// PRODUCTION will be replaced with PRODUCTION when package is built.
|
|
22261
|
+
const directoryPrefix = devMode ? 'src/' : './';
|
|
22262
|
+
const objectSyntax = await readFile(directoryPrefix + 'templates/rust/object-syntax.hbs', devMode);
|
|
22263
|
+
const exporterModuleSyntax = await readFile(directoryPrefix + 'templates/rust/exporter-module-syntax.hbs', devMode);
|
|
22264
|
+
const typesFileSyntax = await readFile(directoryPrefix + 'templates/rust/types-file-syntax.hbs', devMode);
|
|
22265
|
+
const enumSyntax = await readFile(directoryPrefix + 'templates/rust/enum-syntax.hbs', devMode);
|
|
22266
|
+
const oneOfSyntax = await readFile(directoryPrefix + 'templates/rust/oneOf-syntax.hbs', devMode);
|
|
22267
|
+
const allOfSyntax = await readFile(directoryPrefix + 'templates/rust/allOf-syntax.hbs', devMode);
|
|
22268
|
+
const config = {
|
|
22269
|
+
input: inputFilePath,
|
|
22270
|
+
output: {
|
|
22271
|
+
cleanWrite: true,
|
|
22272
|
+
fileExtension: '.rs',
|
|
22273
|
+
directory: outputDirectory,
|
|
22274
|
+
typesFileName: 'mod',
|
|
22275
|
+
writerMode: {
|
|
22276
|
+
groupedTypes: groupedTypesWriterMode,
|
|
22277
|
+
types: typesWriterMode
|
|
22278
|
+
}
|
|
22279
|
+
},
|
|
22280
|
+
template: {
|
|
22281
|
+
objectSyntax,
|
|
22282
|
+
exporterModuleSyntax,
|
|
22283
|
+
typesFileSyntax,
|
|
22284
|
+
enumSyntax,
|
|
22285
|
+
oneOfSyntax,
|
|
22286
|
+
allOfSyntax
|
|
22287
|
+
},
|
|
22288
|
+
language: {
|
|
22289
|
+
exporterModuleName: 'mod',
|
|
22290
|
+
typeMapper: {
|
|
22291
|
+
string: { default: 'String' },
|
|
22292
|
+
number: { default: 'i32' },
|
|
22293
|
+
integer: { default: 'i32' },
|
|
22294
|
+
boolean: 'bool',
|
|
22295
|
+
array: 'Vec<~ItemType~>',
|
|
22296
|
+
object: 'type',
|
|
22297
|
+
unknown: 'String'
|
|
22298
|
+
},
|
|
22299
|
+
modulePathConfig: {
|
|
22300
|
+
separator: '::',
|
|
22301
|
+
parentRef: 'super',
|
|
22302
|
+
selfRef: 'self',
|
|
22303
|
+
moduleFileName: 'mod',
|
|
22304
|
+
fileBasedModules: true
|
|
22149
22305
|
}
|
|
22150
22306
|
}
|
|
22151
22307
|
};
|
|
@@ -22183,9 +22339,12 @@ async function runner(language, inputFilePath, outputDirectory, _typesWriterMode
|
|
|
22183
22339
|
let generatorConfig = null;
|
|
22184
22340
|
switch (language.toLowerCase()) {
|
|
22185
22341
|
case 'typescript':
|
|
22186
|
-
generatorConfig = await config$
|
|
22342
|
+
generatorConfig = await config$2(inputFilePath, outputDirectory, typesWriterMode, groupedTypesWriterMode);
|
|
22187
22343
|
break;
|
|
22188
22344
|
case 'typescript-with-decoders':
|
|
22345
|
+
generatorConfig = await config$1(inputFilePath, outputDirectory, typesWriterMode, groupedTypesWriterMode);
|
|
22346
|
+
break;
|
|
22347
|
+
case 'rust':
|
|
22189
22348
|
generatorConfig = await config(inputFilePath, outputDirectory, typesWriterMode, groupedTypesWriterMode);
|
|
22190
22349
|
break;
|
|
22191
22350
|
default:
|
|
@@ -22215,7 +22374,7 @@ async function runner(language, inputFilePath, outputDirectory, _typesWriterMode
|
|
|
22215
22374
|
}
|
|
22216
22375
|
}
|
|
22217
22376
|
greeting();
|
|
22218
|
-
const program = new Command().version('0.
|
|
22377
|
+
const program = new Command().version('0.13.0');
|
|
22219
22378
|
program
|
|
22220
22379
|
.command('generate')
|
|
22221
22380
|
.description('Generate types for your language from a type spec file')
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{{#if description}}
|
|
2
|
+
/// {{{description}}}
|
|
3
|
+
{{/if}}
|
|
4
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
5
|
+
pub struct {{typeName}} {
|
|
6
|
+
{{#each compositions}}
|
|
7
|
+
{{#if (eq this.source 'referenced')}}
|
|
8
|
+
#[serde(flatten)]
|
|
9
|
+
pub {{toSnakeCase this.referencedType}}: {{this.referencedType}},
|
|
10
|
+
{{else if (eq this.source 'inline')}}
|
|
11
|
+
{{#if (eq this.dataType 'object')}}
|
|
12
|
+
#[serde(flatten)]
|
|
13
|
+
pub {{toSnakeCase this.templateInput.typeName}}: {{this.templateInput.typeName}},
|
|
14
|
+
{{else}}
|
|
15
|
+
pub {{toSnakeCase this.templateInput.typeName}}: {{{this.templateInput.type}}},
|
|
16
|
+
{{/if}}
|
|
17
|
+
{{/if}}
|
|
18
|
+
{{/each}}
|
|
19
|
+
}
|
|
20
|
+
{{#each compositions}}
|
|
21
|
+
{{#if (eq this.source 'inline')}}
|
|
22
|
+
{{#if (eq this.dataType 'object')}}
|
|
23
|
+
{{{this.content}}}
|
|
24
|
+
{{/if}}
|
|
25
|
+
{{/if}}
|
|
26
|
+
{{/each}}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{{#if description}}
|
|
2
|
+
/// {{{description}}}
|
|
3
|
+
{{/if}}
|
|
4
|
+
{{#if example}}
|
|
5
|
+
/// Example: {{{example}}}
|
|
6
|
+
{{/if}}
|
|
7
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
8
|
+
pub enum {{typeName}} {
|
|
9
|
+
{{#each values}}
|
|
10
|
+
{{#if (eq ../type 'string')}}
|
|
11
|
+
#[serde(rename = "{{this}}")]
|
|
12
|
+
{{{toPascalCase this}}},
|
|
13
|
+
{{else}}
|
|
14
|
+
Value{{{this}}},
|
|
15
|
+
{{/if}}
|
|
16
|
+
{{/each}}
|
|
17
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{{#if description}}
|
|
2
|
+
/// {{{description}}}
|
|
3
|
+
{{/if}}
|
|
4
|
+
{{#if example}}
|
|
5
|
+
/// Example: {{{example}}}
|
|
6
|
+
{{/if}}
|
|
7
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
8
|
+
pub struct {{typeName}} {
|
|
9
|
+
{{#each properties}}
|
|
10
|
+
{{#if this.description}}
|
|
11
|
+
/// {{{this.description}}}
|
|
12
|
+
{{/if}}
|
|
13
|
+
#[serde(rename = "{{@key}}")]
|
|
14
|
+
{{#unless this.required}}
|
|
15
|
+
#[serde(skip_serializing_if = "Option::is_none")]
|
|
16
|
+
{{/unless}}
|
|
17
|
+
pub {{toSnakeCase @key}}: {{#unless this.required}}Option<{{/unless}}{{{this.type}}}{{#unless this.required}}>{{/unless}},
|
|
18
|
+
{{/each}}
|
|
19
|
+
{{#if additionalProperties}}
|
|
20
|
+
#[serde(flatten)]
|
|
21
|
+
pub additional_properties: std::collections::HashMap<{{{additionalProperties.keyType}}}, {{{additionalProperties.valueType}}}>,
|
|
22
|
+
{{/if}}
|
|
23
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{{#if description}}
|
|
2
|
+
/// {{{description}}}
|
|
3
|
+
{{/if}}
|
|
4
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
5
|
+
#[serde(untagged)]
|
|
6
|
+
pub enum {{typeName}} {
|
|
7
|
+
{{#each compositions}}
|
|
8
|
+
{{#if (eq this.source 'referenced')}}
|
|
9
|
+
{{this.referencedType}}({{this.referencedType}}),
|
|
10
|
+
{{else if (eq this.source 'inline')}}
|
|
11
|
+
{{#if this.templateInput.values}}
|
|
12
|
+
{{this.templateInput.typeName}}({{this.templateInput.typeName}}),
|
|
13
|
+
{{else if (eq this.dataType 'object')}}
|
|
14
|
+
{{this.templateInput.typeName}}({{this.templateInput.typeName}}),
|
|
15
|
+
{{else}}
|
|
16
|
+
{{this.templateInput.typeName}}({{{this.templateInput.type}}}),
|
|
17
|
+
{{/if}}
|
|
18
|
+
{{/if}}
|
|
19
|
+
{{/each}}
|
|
20
|
+
}
|
|
21
|
+
{{#each compositions}}
|
|
22
|
+
{{#if (eq this.source 'inline')}}
|
|
23
|
+
{{{this.content}}}
|
|
24
|
+
{{/if}}
|
|
25
|
+
{{/each}}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export type OutputConfig = {
|
|
|
9
9
|
cleanWrite: boolean;
|
|
10
10
|
fileExtension: string;
|
|
11
11
|
directory: string;
|
|
12
|
+
typesFileName: string;
|
|
12
13
|
writerMode: {
|
|
13
14
|
groupedTypes: GroupedTypesWriterMode;
|
|
14
15
|
types: TypesWriterMode;
|
|
@@ -24,9 +25,17 @@ export type Template = {
|
|
|
24
25
|
oneOfSyntax: string;
|
|
25
26
|
allOfSyntax: string;
|
|
26
27
|
};
|
|
28
|
+
export type ModulePathConfig = {
|
|
29
|
+
separator: string;
|
|
30
|
+
parentRef: string;
|
|
31
|
+
selfRef: string;
|
|
32
|
+
moduleFileName: string;
|
|
33
|
+
fileBasedModules: boolean;
|
|
34
|
+
};
|
|
27
35
|
export type LanguageConfig = {
|
|
28
36
|
exporterModuleName: string;
|
|
29
37
|
typeMapper: LanguageTypeMapper;
|
|
38
|
+
modulePathConfig: ModulePathConfig;
|
|
30
39
|
};
|
|
31
40
|
/**
|
|
32
41
|
* @description Mappers for all the types supported by OpenAPI 3.0.0
|
|
@@ -122,6 +131,10 @@ export type AdditionalPropertiesTemplateInput = {
|
|
|
122
131
|
valuePrimitiveType: string;
|
|
123
132
|
valueComposerType: string | null;
|
|
124
133
|
};
|
|
134
|
+
export type AdditionalPropertiesGenerationResult = {
|
|
135
|
+
templateInput: AdditionalPropertiesTemplateInput;
|
|
136
|
+
primitives: Set<string>;
|
|
137
|
+
};
|
|
125
138
|
export type ExporterModuleTemplateInput = {
|
|
126
139
|
modules: string[];
|
|
127
140
|
};
|
|
@@ -135,6 +148,7 @@ export type ReferencedModule = {
|
|
|
135
148
|
modulePath: string;
|
|
136
149
|
moduleRelativePath: string;
|
|
137
150
|
referencedTypes: string[];
|
|
151
|
+
moduleName: string;
|
|
138
152
|
};
|
|
139
153
|
export type EnumTemplateInput = TypeDescriptors & {
|
|
140
154
|
typeName: string;
|
|
@@ -5,5 +5,5 @@ export declare function createFolder(folderPath: string): Promise<void>;
|
|
|
5
5
|
export declare function deleteFolder(folderPath: string): Promise<void>;
|
|
6
6
|
export declare function getCompleteFolderPath(folderName: string): Promise<string>;
|
|
7
7
|
export declare function getExpectedWrittenPath(basePath: string, fileName: string): Promise<string>;
|
|
8
|
-
export declare function writeFile(basePath: string, fileName: string, content: string): Promise<void>;
|
|
8
|
+
export declare function writeFile(basePath: string, fileName: string, content: string, append?: boolean): Promise<void>;
|
|
9
9
|
export declare function readYaml(filePath: string): Promise<unknown>;
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type TypeInfo, type TypeDataType } from '$types';
|
|
1
|
+
import { type ModulePathConfig, type TypeInfo, type TypeDataType } from '$types';
|
|
2
2
|
import { type JSONObject } from 'type-decoder';
|
|
3
3
|
export * from './file-system';
|
|
4
4
|
export * from './logger';
|
|
@@ -9,12 +9,15 @@ export declare function getReferencedTypes(object: unknown): string[];
|
|
|
9
9
|
export declare function getReferencedTypeModules(_referencedTypes: unknown, _writtenAt: string): unknown[];
|
|
10
10
|
export declare function toPascalCase(input: string): string;
|
|
11
11
|
export declare function toPascalCaseHelper(input: unknown): string | unknown;
|
|
12
|
+
export declare function toSnakeCase(input: string): string;
|
|
13
|
+
export declare function toSnakeCaseHelper(input: unknown): string | unknown;
|
|
12
14
|
export declare function refineJSONKey(input: unknown): unknown;
|
|
13
15
|
export declare function refineVariableName(input: unknown): unknown;
|
|
14
16
|
export declare function refineIndexKey(input: unknown): unknown;
|
|
15
17
|
export declare function registerTemplateHelpers(): void;
|
|
16
18
|
export declare function readNestedValue(json: unknown, keyPath: string[]): JSONObject;
|
|
17
19
|
export declare function generateRelativePath(fromPath: string, toPath: string): string;
|
|
20
|
+
export declare function formatModulePath(relativePath: string, writtenAt: string, config: ModulePathConfig): string;
|
|
18
21
|
export declare function stripPrefix(value: string, prefix: string): string;
|
|
19
22
|
export declare function isPrimitiveType(typeInfo: TypeInfo): boolean;
|
|
20
23
|
export declare function isSimplePrimitiveType(type: TypeDataType | null): boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "type-crafter",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.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",
|
|
@@ -49,12 +49,12 @@
|
|
|
49
49
|
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
50
50
|
"@rollup/plugin-replace": "^6.0.3",
|
|
51
51
|
"@rollup/plugin-typescript": "^12.3.0",
|
|
52
|
-
"@types/node": "^25.2.
|
|
53
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
54
|
-
"@typescript-eslint/parser": "^8.
|
|
52
|
+
"@types/node": "^25.2.3",
|
|
53
|
+
"@typescript-eslint/eslint-plugin": "^8.55.0",
|
|
54
|
+
"@typescript-eslint/parser": "^8.55.0",
|
|
55
55
|
"commander": "^14.0.3",
|
|
56
|
-
"eslint": "^
|
|
57
|
-
"eslint-config-love": "^
|
|
56
|
+
"eslint": "^10.0.0",
|
|
57
|
+
"eslint-config-love": "^150.0.0",
|
|
58
58
|
"eslint-config-prettier": "^10.1.8",
|
|
59
59
|
"handlebars": "^4.7.8",
|
|
60
60
|
"husky": "^9.1.7",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"rollup": "^4.57.1",
|
|
63
63
|
"rollup-plugin-copy": "^3.5.0",
|
|
64
64
|
"tslib": "^2.8.1",
|
|
65
|
-
"type-decoder": "^2.
|
|
65
|
+
"type-decoder": "^2.3.0",
|
|
66
66
|
"typescript": "^5.9.3",
|
|
67
67
|
"yaml": "^2.8.2"
|
|
68
68
|
}
|