@twin.org/ts-to-openapi 0.0.1-next.8 → 0.0.1
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/bin/index.js +0 -0
- package/dist/cjs/index.cjs +86 -14
- package/dist/esm/index.mjs +87 -15
- package/dist/locales/en.json +302 -277
- package/dist/types/models/IJsonSchema.d.ts +5 -0
- package/dist/types/models/IOpenApi.d.ts +2 -2
- package/dist/types/models/IOpenApiPathMethod.d.ts +4 -3
- package/dist/types/models/jsonTypeName.d.ts +5 -0
- package/docs/changelog.md +195 -1
- package/docs/reference/classes/CLI.md +17 -9
- package/docs/reference/functions/actionCommandTsToOpenApi.md +9 -3
- package/docs/reference/functions/buildCommandTsToOpenApi.md +3 -1
- package/docs/reference/functions/tsToOpenApi.md +9 -3
- package/docs/reference/interfaces/ITsToOpenApiConfig.md +25 -1
- package/package.json +13 -13
package/bin/index.js
CHANGED
|
File without changes
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -659,8 +659,13 @@ async function finaliseOutput(usedCommonResponseTypes, schemas, openApi, securit
|
|
|
659
659
|
}
|
|
660
660
|
}
|
|
661
661
|
}
|
|
662
|
-
|
|
663
|
-
|
|
662
|
+
// Remove standard types that we don't want in the final output
|
|
663
|
+
const removeTypes = ["HttpStatusCode", "Uint8Array", "ArrayBuffer"];
|
|
664
|
+
for (const type of removeTypes) {
|
|
665
|
+
delete finalSchemas[type];
|
|
666
|
+
}
|
|
667
|
+
for (const type in finalSchemas) {
|
|
668
|
+
processArrays(finalSchemas[type]);
|
|
664
669
|
}
|
|
665
670
|
const schemaKeys = Object.keys(finalSchemas);
|
|
666
671
|
schemaKeys.sort();
|
|
@@ -672,7 +677,7 @@ async function finaliseOutput(usedCommonResponseTypes, schemas, openApi, securit
|
|
|
672
677
|
schemas: sortedSchemas,
|
|
673
678
|
securitySchemes
|
|
674
679
|
};
|
|
675
|
-
let json = JSON.stringify(openApi, undefined, "
|
|
680
|
+
let json = JSON.stringify(openApi, undefined, "\t");
|
|
676
681
|
// Remove the reference only schemas, repeating until no more substitutions
|
|
677
682
|
let performedSubstitution;
|
|
678
683
|
do {
|
|
@@ -693,10 +698,7 @@ async function finaliseOutput(usedCommonResponseTypes, schemas, openApi, securit
|
|
|
693
698
|
// Remove the array [] from the type names
|
|
694
699
|
// eslint-disable-next-line unicorn/better-regex
|
|
695
700
|
json = json.replace(/#\/components\/schemas\/(.*)\[\]/g, "#/components/schemas/ListOf$1");
|
|
696
|
-
|
|
697
|
-
json = json.replace(/Partial%3CI(.*?)%3E/g, "$1");
|
|
698
|
-
// Cleanup the generic markers
|
|
699
|
-
json = json.replace(/%3Cunknown%3E/g, "");
|
|
701
|
+
json = normaliseTypeName(json);
|
|
700
702
|
// Remove external references
|
|
701
703
|
for (const finalExternal in finalExternals) {
|
|
702
704
|
json = json.replace(new RegExp(`"#/components/schemas/${core.StringHelper.stripPrefix(finalExternal)}"`, "g"), `"${finalExternals[finalExternal]}"`);
|
|
@@ -706,7 +708,7 @@ async function finaliseOutput(usedCommonResponseTypes, schemas, openApi, securit
|
|
|
706
708
|
await promises.mkdir(path.dirname(outputFile), { recursive: true });
|
|
707
709
|
}
|
|
708
710
|
catch { }
|
|
709
|
-
await promises.writeFile(outputFile, json);
|
|
711
|
+
await promises.writeFile(outputFile, `${json}\n`);
|
|
710
712
|
}
|
|
711
713
|
/**
|
|
712
714
|
* Build the security schemas from the config.
|
|
@@ -850,10 +852,7 @@ async function generateSchemas(modelDirWildcards, types, outputWorkingDir) {
|
|
|
850
852
|
const schema = generator.createSchema("*");
|
|
851
853
|
if (schema.definitions) {
|
|
852
854
|
for (const def in schema.definitions) {
|
|
853
|
-
|
|
854
|
-
let defSub = def.replace(/^Partial<(.*?)>/g, "$1");
|
|
855
|
-
// Cleanup the generic markers
|
|
856
|
-
defSub = defSub.replace(/</g, "%3C").replace(/>/g, "%3E");
|
|
855
|
+
const defSub = normaliseTypeName(def);
|
|
857
856
|
allSchemas[defSub] = schema.definitions[def];
|
|
858
857
|
}
|
|
859
858
|
}
|
|
@@ -895,7 +894,7 @@ function extractTypes(allSchemas, requiredTypes, referencedSchemas) {
|
|
|
895
894
|
function extractTypesFromSchema(allTypes, schema, output) {
|
|
896
895
|
const additionalTypes = [];
|
|
897
896
|
if (core.Is.stringValue(schema.$ref)) {
|
|
898
|
-
additionalTypes.push(schema.$ref.replace("#/definitions/", "")
|
|
897
|
+
additionalTypes.push(normaliseTypeName(schema.$ref).replace("#/definitions/", ""));
|
|
899
898
|
}
|
|
900
899
|
else if (core.Is.object(schema.items)) {
|
|
901
900
|
if (core.Is.arrayValue(schema.items)) {
|
|
@@ -1088,6 +1087,79 @@ async function loadPackages(tsToOpenApiConfig, outputWorkingDir, typeRoots) {
|
|
|
1088
1087
|
}
|
|
1089
1088
|
return restRoutes;
|
|
1090
1089
|
}
|
|
1090
|
+
/**
|
|
1091
|
+
* Process arrays in the schema object.
|
|
1092
|
+
* @param schemaObject The schema object to process.
|
|
1093
|
+
*/
|
|
1094
|
+
function processArrays(schemaObject) {
|
|
1095
|
+
if (core.Is.object(schemaObject)) {
|
|
1096
|
+
// latest specs have singular items in `items` property
|
|
1097
|
+
// and multiple items in prefixItems, so update the schema accordingly
|
|
1098
|
+
// https://www.learnjsonschema.com/2020-12/applicator/items/
|
|
1099
|
+
// https://www.learnjsonschema.com/2020-12/applicator/prefixitems/
|
|
1100
|
+
const schemaItems = schemaObject.items;
|
|
1101
|
+
if (core.Is.array(schemaItems) || core.Is.object(schemaItems)) {
|
|
1102
|
+
schemaObject.prefixItems = core.ArrayHelper.fromObjectOrArray(schemaItems);
|
|
1103
|
+
delete schemaObject.items;
|
|
1104
|
+
}
|
|
1105
|
+
const additionalItems = schemaObject.additionalItems;
|
|
1106
|
+
if (core.Is.array(additionalItems) || core.Is.object(additionalItems)) {
|
|
1107
|
+
schemaObject.items = core.ArrayHelper.fromObjectOrArray(additionalItems)[0];
|
|
1108
|
+
delete schemaObject.additionalItems;
|
|
1109
|
+
}
|
|
1110
|
+
processSchemaDictionary(schemaObject.properties);
|
|
1111
|
+
processArrays(schemaObject.additionalProperties);
|
|
1112
|
+
processSchemaArray(schemaObject.allOf);
|
|
1113
|
+
processSchemaArray(schemaObject.anyOf);
|
|
1114
|
+
processSchemaArray(schemaObject.oneOf);
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
/**
|
|
1118
|
+
* Process arrays in the schema object.
|
|
1119
|
+
* @param schemaDictionary The schema object to process.
|
|
1120
|
+
*/
|
|
1121
|
+
function processSchemaDictionary(schemaDictionary) {
|
|
1122
|
+
if (core.Is.object(schemaDictionary)) {
|
|
1123
|
+
for (const item of Object.values(schemaDictionary)) {
|
|
1124
|
+
if (core.Is.object(item)) {
|
|
1125
|
+
processArrays(item);
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
/**
|
|
1131
|
+
* Process arrays in the schema object.
|
|
1132
|
+
* @param schemaArray The schema object to process.
|
|
1133
|
+
*/
|
|
1134
|
+
function processSchemaArray(schemaArray) {
|
|
1135
|
+
if (core.Is.arrayValue(schemaArray)) {
|
|
1136
|
+
for (const item of schemaArray) {
|
|
1137
|
+
if (core.Is.object(item)) {
|
|
1138
|
+
processArrays(item);
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1143
|
+
/**
|
|
1144
|
+
* Cleanup TypeScript markers from the type name.
|
|
1145
|
+
* @param typeName The definition string to clean up.
|
|
1146
|
+
* @returns The cleaned up definition string.
|
|
1147
|
+
*/
|
|
1148
|
+
function normaliseTypeName(typeName) {
|
|
1149
|
+
// Remove the partial markers
|
|
1150
|
+
let sTypeName = typeName.replace(/^Partial<(.*?)>/g, "$1");
|
|
1151
|
+
sTypeName = sTypeName.replace(/Partial%3CI(.*?)%3E/g, "$1");
|
|
1152
|
+
// Remove the omit markers
|
|
1153
|
+
sTypeName = sTypeName.replace(/^Omit<(.*?),.*>/g, "$1");
|
|
1154
|
+
sTypeName = sTypeName.replace(/Omit%3CI(.*?)%2C.*%3E/g, "$1");
|
|
1155
|
+
// Remove the pick markers
|
|
1156
|
+
sTypeName = sTypeName.replace(/^Pick<(.*?),.*>/g, "$1");
|
|
1157
|
+
sTypeName = sTypeName.replace(/Pick%3CI(.*?)%2C.*%3E/g, "$1");
|
|
1158
|
+
// Cleanup the generic markers
|
|
1159
|
+
sTypeName = sTypeName.replace(/</g, "%3C").replace(/>/g, "%3E");
|
|
1160
|
+
sTypeName = sTypeName.replace(/%3Cunknown%3E/g, "");
|
|
1161
|
+
return sTypeName;
|
|
1162
|
+
}
|
|
1091
1163
|
|
|
1092
1164
|
// Copyright 2024 IOTA Stiftung.
|
|
1093
1165
|
// SPDX-License-Identifier: Apache-2.0.
|
|
@@ -1107,7 +1179,7 @@ class CLI extends cliCore.CLIBase {
|
|
|
1107
1179
|
return this.execute({
|
|
1108
1180
|
title: "TWIN TypeScript To OpenAPI",
|
|
1109
1181
|
appName: "ts-to-openapi",
|
|
1110
|
-
version: "0.0.1
|
|
1182
|
+
version: "0.0.1", // x-release-please-version
|
|
1111
1183
|
icon: "⚙️ ",
|
|
1112
1184
|
supportsEnvFiles: false,
|
|
1113
1185
|
overrideOutputWidth: options?.overrideOutputWidth
|
package/dist/esm/index.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import path from 'node:path';
|
|
|
2
2
|
import { fileURLToPath } from 'node:url';
|
|
3
3
|
import { CLIDisplay, CLIUtils, CLIBase } from '@twin.org/cli-core';
|
|
4
4
|
import { mkdir, rm, writeFile } from 'node:fs/promises';
|
|
5
|
-
import { I18n, GeneralError, Is, StringHelper, ObjectHelper } from '@twin.org/core';
|
|
5
|
+
import { I18n, GeneralError, Is, StringHelper, ObjectHelper, ArrayHelper } from '@twin.org/core';
|
|
6
6
|
import { HttpStatusCode, MimeTypes } from '@twin.org/web';
|
|
7
7
|
import { createGenerator } from 'ts-json-schema-generator';
|
|
8
8
|
|
|
@@ -656,8 +656,13 @@ async function finaliseOutput(usedCommonResponseTypes, schemas, openApi, securit
|
|
|
656
656
|
}
|
|
657
657
|
}
|
|
658
658
|
}
|
|
659
|
-
|
|
660
|
-
|
|
659
|
+
// Remove standard types that we don't want in the final output
|
|
660
|
+
const removeTypes = ["HttpStatusCode", "Uint8Array", "ArrayBuffer"];
|
|
661
|
+
for (const type of removeTypes) {
|
|
662
|
+
delete finalSchemas[type];
|
|
663
|
+
}
|
|
664
|
+
for (const type in finalSchemas) {
|
|
665
|
+
processArrays(finalSchemas[type]);
|
|
661
666
|
}
|
|
662
667
|
const schemaKeys = Object.keys(finalSchemas);
|
|
663
668
|
schemaKeys.sort();
|
|
@@ -669,7 +674,7 @@ async function finaliseOutput(usedCommonResponseTypes, schemas, openApi, securit
|
|
|
669
674
|
schemas: sortedSchemas,
|
|
670
675
|
securitySchemes
|
|
671
676
|
};
|
|
672
|
-
let json = JSON.stringify(openApi, undefined, "
|
|
677
|
+
let json = JSON.stringify(openApi, undefined, "\t");
|
|
673
678
|
// Remove the reference only schemas, repeating until no more substitutions
|
|
674
679
|
let performedSubstitution;
|
|
675
680
|
do {
|
|
@@ -690,10 +695,7 @@ async function finaliseOutput(usedCommonResponseTypes, schemas, openApi, securit
|
|
|
690
695
|
// Remove the array [] from the type names
|
|
691
696
|
// eslint-disable-next-line unicorn/better-regex
|
|
692
697
|
json = json.replace(/#\/components\/schemas\/(.*)\[\]/g, "#/components/schemas/ListOf$1");
|
|
693
|
-
|
|
694
|
-
json = json.replace(/Partial%3CI(.*?)%3E/g, "$1");
|
|
695
|
-
// Cleanup the generic markers
|
|
696
|
-
json = json.replace(/%3Cunknown%3E/g, "");
|
|
698
|
+
json = normaliseTypeName(json);
|
|
697
699
|
// Remove external references
|
|
698
700
|
for (const finalExternal in finalExternals) {
|
|
699
701
|
json = json.replace(new RegExp(`"#/components/schemas/${StringHelper.stripPrefix(finalExternal)}"`, "g"), `"${finalExternals[finalExternal]}"`);
|
|
@@ -703,7 +705,7 @@ async function finaliseOutput(usedCommonResponseTypes, schemas, openApi, securit
|
|
|
703
705
|
await mkdir(path.dirname(outputFile), { recursive: true });
|
|
704
706
|
}
|
|
705
707
|
catch { }
|
|
706
|
-
await writeFile(outputFile, json);
|
|
708
|
+
await writeFile(outputFile, `${json}\n`);
|
|
707
709
|
}
|
|
708
710
|
/**
|
|
709
711
|
* Build the security schemas from the config.
|
|
@@ -847,10 +849,7 @@ async function generateSchemas(modelDirWildcards, types, outputWorkingDir) {
|
|
|
847
849
|
const schema = generator.createSchema("*");
|
|
848
850
|
if (schema.definitions) {
|
|
849
851
|
for (const def in schema.definitions) {
|
|
850
|
-
|
|
851
|
-
let defSub = def.replace(/^Partial<(.*?)>/g, "$1");
|
|
852
|
-
// Cleanup the generic markers
|
|
853
|
-
defSub = defSub.replace(/</g, "%3C").replace(/>/g, "%3E");
|
|
852
|
+
const defSub = normaliseTypeName(def);
|
|
854
853
|
allSchemas[defSub] = schema.definitions[def];
|
|
855
854
|
}
|
|
856
855
|
}
|
|
@@ -892,7 +891,7 @@ function extractTypes(allSchemas, requiredTypes, referencedSchemas) {
|
|
|
892
891
|
function extractTypesFromSchema(allTypes, schema, output) {
|
|
893
892
|
const additionalTypes = [];
|
|
894
893
|
if (Is.stringValue(schema.$ref)) {
|
|
895
|
-
additionalTypes.push(schema.$ref.replace("#/definitions/", "")
|
|
894
|
+
additionalTypes.push(normaliseTypeName(schema.$ref).replace("#/definitions/", ""));
|
|
896
895
|
}
|
|
897
896
|
else if (Is.object(schema.items)) {
|
|
898
897
|
if (Is.arrayValue(schema.items)) {
|
|
@@ -1085,6 +1084,79 @@ async function loadPackages(tsToOpenApiConfig, outputWorkingDir, typeRoots) {
|
|
|
1085
1084
|
}
|
|
1086
1085
|
return restRoutes;
|
|
1087
1086
|
}
|
|
1087
|
+
/**
|
|
1088
|
+
* Process arrays in the schema object.
|
|
1089
|
+
* @param schemaObject The schema object to process.
|
|
1090
|
+
*/
|
|
1091
|
+
function processArrays(schemaObject) {
|
|
1092
|
+
if (Is.object(schemaObject)) {
|
|
1093
|
+
// latest specs have singular items in `items` property
|
|
1094
|
+
// and multiple items in prefixItems, so update the schema accordingly
|
|
1095
|
+
// https://www.learnjsonschema.com/2020-12/applicator/items/
|
|
1096
|
+
// https://www.learnjsonschema.com/2020-12/applicator/prefixitems/
|
|
1097
|
+
const schemaItems = schemaObject.items;
|
|
1098
|
+
if (Is.array(schemaItems) || Is.object(schemaItems)) {
|
|
1099
|
+
schemaObject.prefixItems = ArrayHelper.fromObjectOrArray(schemaItems);
|
|
1100
|
+
delete schemaObject.items;
|
|
1101
|
+
}
|
|
1102
|
+
const additionalItems = schemaObject.additionalItems;
|
|
1103
|
+
if (Is.array(additionalItems) || Is.object(additionalItems)) {
|
|
1104
|
+
schemaObject.items = ArrayHelper.fromObjectOrArray(additionalItems)[0];
|
|
1105
|
+
delete schemaObject.additionalItems;
|
|
1106
|
+
}
|
|
1107
|
+
processSchemaDictionary(schemaObject.properties);
|
|
1108
|
+
processArrays(schemaObject.additionalProperties);
|
|
1109
|
+
processSchemaArray(schemaObject.allOf);
|
|
1110
|
+
processSchemaArray(schemaObject.anyOf);
|
|
1111
|
+
processSchemaArray(schemaObject.oneOf);
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
/**
|
|
1115
|
+
* Process arrays in the schema object.
|
|
1116
|
+
* @param schemaDictionary The schema object to process.
|
|
1117
|
+
*/
|
|
1118
|
+
function processSchemaDictionary(schemaDictionary) {
|
|
1119
|
+
if (Is.object(schemaDictionary)) {
|
|
1120
|
+
for (const item of Object.values(schemaDictionary)) {
|
|
1121
|
+
if (Is.object(item)) {
|
|
1122
|
+
processArrays(item);
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
/**
|
|
1128
|
+
* Process arrays in the schema object.
|
|
1129
|
+
* @param schemaArray The schema object to process.
|
|
1130
|
+
*/
|
|
1131
|
+
function processSchemaArray(schemaArray) {
|
|
1132
|
+
if (Is.arrayValue(schemaArray)) {
|
|
1133
|
+
for (const item of schemaArray) {
|
|
1134
|
+
if (Is.object(item)) {
|
|
1135
|
+
processArrays(item);
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
1140
|
+
/**
|
|
1141
|
+
* Cleanup TypeScript markers from the type name.
|
|
1142
|
+
* @param typeName The definition string to clean up.
|
|
1143
|
+
* @returns The cleaned up definition string.
|
|
1144
|
+
*/
|
|
1145
|
+
function normaliseTypeName(typeName) {
|
|
1146
|
+
// Remove the partial markers
|
|
1147
|
+
let sTypeName = typeName.replace(/^Partial<(.*?)>/g, "$1");
|
|
1148
|
+
sTypeName = sTypeName.replace(/Partial%3CI(.*?)%3E/g, "$1");
|
|
1149
|
+
// Remove the omit markers
|
|
1150
|
+
sTypeName = sTypeName.replace(/^Omit<(.*?),.*>/g, "$1");
|
|
1151
|
+
sTypeName = sTypeName.replace(/Omit%3CI(.*?)%2C.*%3E/g, "$1");
|
|
1152
|
+
// Remove the pick markers
|
|
1153
|
+
sTypeName = sTypeName.replace(/^Pick<(.*?),.*>/g, "$1");
|
|
1154
|
+
sTypeName = sTypeName.replace(/Pick%3CI(.*?)%2C.*%3E/g, "$1");
|
|
1155
|
+
// Cleanup the generic markers
|
|
1156
|
+
sTypeName = sTypeName.replace(/</g, "%3C").replace(/>/g, "%3E");
|
|
1157
|
+
sTypeName = sTypeName.replace(/%3Cunknown%3E/g, "");
|
|
1158
|
+
return sTypeName;
|
|
1159
|
+
}
|
|
1088
1160
|
|
|
1089
1161
|
// Copyright 2024 IOTA Stiftung.
|
|
1090
1162
|
// SPDX-License-Identifier: Apache-2.0.
|
|
@@ -1104,7 +1176,7 @@ class CLI extends CLIBase {
|
|
|
1104
1176
|
return this.execute({
|
|
1105
1177
|
title: "TWIN TypeScript To OpenAPI",
|
|
1106
1178
|
appName: "ts-to-openapi",
|
|
1107
|
-
version: "0.0.1
|
|
1179
|
+
version: "0.0.1", // x-release-please-version
|
|
1108
1180
|
icon: "⚙️ ",
|
|
1109
1181
|
supportsEnvFiles: false,
|
|
1110
1182
|
overrideOutputWidth: options?.overrideOutputWidth
|