dilswer
Version:
Blazingly fast data validation library with TypeScript integration.
390 lines (388 loc) • 15.8 kB
JavaScript
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
// src/ts-type-generator/to-ts-type.ts
var to_ts_type_exports = {};
__export(to_ts_type_exports, {
ExternalTypeImportProxy: () => ExternalTypeImportProxy,
toTsType: () => toTsType
});
module.exports = __toCommonJS(to_ts_type_exports);
var import_base_type = require("../data-types/base-type.cjs");
var import_type_kind_names = require("../data-types/type-kind-names.cjs");
var import_enum = require("../data-types/types/enum.cjs");
var import_enum_member = require("../data-types/types/enum-member.cjs");
var import_string_matching = require("../data-types/types/string-matching.cjs");
var import_file_scope = require("./file-scope.cjs");
var import_name_generator = require("./name-generator.cjs");
var import_array_builder = require("./type-builders/array-builder.cjs");
var import_dictionary_builder = require("./type-builders/dictionary-builder.cjs");
var import_enum_builder = require("./type-builders/enum-builder.cjs");
var import_enum_member_builder = require("./type-builders/enum-member-builder.cjs");
var import_external_type_reference = require("./type-builders/external-type-reference.cjs");
var import_instanceof_builder = require("./type-builders/instanceof-builder.cjs");
var import_intersection_builder = require("./type-builders/intersection-builder.cjs");
var import_literal_builder = require("./type-builders/literal-builder.cjs");
var import_record_builder = require("./type-builders/record-builder.cjs");
var import_set_builder = require("./type-builders/set-builder.cjs");
var import_boolean_builder = require("./type-builders/simple-types/boolean-builder.cjs");
var import_function_builder = require("./type-builders/simple-types/function-builder.cjs");
var import_null_builder = require("./type-builders/simple-types/null-builder.cjs");
var import_number_builder = require("./type-builders/simple-types/number-builder.cjs");
var import_string_builder = require("./type-builders/simple-types/string-builder.cjs");
var import_symbol_builder = require("./type-builders/simple-types/symbol-builder.cjs");
var import_undefined_builder = require("./type-builders/simple-types/undefined-builder.cjs");
var import_unknown_builder = require("./type-builders/simple-types/unknown-builder.cjs");
var import_string_matching_builder = require("./type-builders/string-matching-builder.cjs");
var import_tuple_builder = require("./type-builders/tuple-builder.cjs");
var import_type_reference = require("./type-builders/type-reference.cjs");
var import_union_builder = require("./type-builders/union-builder.cjs");
var import_capitalize = require("../utilities/capitalize.cjs");
var ExternalTypeImportProxy = class {
constructor(ext) {
this.ext = ext;
__publicField(this, "_resolvedName");
__publicField(this, "_importName");
if (ext.valueImport == true) {
this._resolvedName = `typeof ${ext.typeName}`;
} else {
this._resolvedName = ext.typeName;
}
if (ext.originalName && ext.originalName !== ext.typeName) {
this._importName = `${ext.originalName} as ${ext.typeName}`;
} else {
this._importName = ext.typeName;
}
}
get path() {
return this.ext.path;
}
get typeName() {
return this._resolvedName;
}
get originalName() {
return this.ext.originalName;
}
get valueImport() {
return this.ext.valueImport;
}
get importName() {
return this._importName;
}
};
var DataTypeTsGenerator = class {
constructor(options) {
this.options = options;
__publicField(this, "fileScope");
__publicField(this, "getExternalTypeImport", function(_) {
return void 0;
});
/**
* Adds the given builder to the exports of the file scope if
* the builder meets the criteria, and returns the given
* builder or the Reference builder, if the builder was added
* to the exports.
*/
__publicField(this, "addFileExportAndResolveBuilder", function(builder) {
return builder;
});
__publicField(this, "circulars", /* @__PURE__ */ new Map());
this.fileScope = new import_file_scope.TsFileScope(options);
if (options.getExternalTypeImport) {
this.getExternalTypeImport = (type) => {
const ext = options.getExternalTypeImport(type);
if (ext) {
return new ExternalTypeImportProxy(ext);
}
};
}
switch (options.mode) {
case "fully-expanded":
this.addFileExportAndResolveBuilder = function(builder) {
return this.fileScope.addTypeExport(builder);
};
break;
case "named-expanded":
this.addFileExportAndResolveBuilder = function(builder) {
if (builder.isTitled) {
return this.fileScope.addTypeExport(builder);
}
return builder;
};
break;
}
}
tsAddMetadataToBuilder(builder, type) {
const metadata = import_base_type.BaseType.getOriginalMetadata(type);
if (metadata.title) {
builder.setIsTitled(true);
builder.setName(metadata.title);
}
if (metadata.description) {
builder.setDescription(metadata.description);
}
return metadata;
}
parseFunctionType(type) {
const externalImport = this.getExternalTypeImport(type);
if (externalImport) {
this.fileScope.addTypeImport(externalImport);
const builder2 = new import_external_type_reference.TsExternalTypeReference(externalImport.typeName);
this.tsAddMetadataToBuilder(builder2, type);
return this.addFileExportAndResolveBuilder(builder2);
}
const builder = new import_function_builder.TsFunctionBuilder();
this.tsAddMetadataToBuilder(builder, type);
return builder;
}
parsePrimitive(type) {
let builder;
switch (type.simpleType) {
case "string":
case "stringinteger":
case "stringnumeral":
builder = new import_string_builder.TsStringBuilder();
break;
case "number":
case "integer":
builder = new import_number_builder.TsNumberBuilder();
break;
case "boolean":
builder = new import_boolean_builder.TsBooleanBuilder();
break;
case "symbol":
builder = new import_symbol_builder.TsSymbolBuilder();
break;
case "undefined":
builder = new import_undefined_builder.TsUndefinedBuilder();
break;
case "unknown":
builder = new import_unknown_builder.TsUnknownBuilder();
break;
case "null":
builder = new import_null_builder.TsNullBuilder();
break;
case "function":
return this.parseFunctionType(type);
}
this.tsAddMetadataToBuilder(builder, type);
return builder;
}
parseArrayOf(type, children = []) {
const builder = new import_array_builder.TsArrayBuilder();
this.tsAddMetadataToBuilder(builder, type);
builder.setTypes(children);
return this.addFileExportAndResolveBuilder(builder);
}
parseTuple(type, children = []) {
const builder = new import_tuple_builder.TsTupleBuilder();
this.tsAddMetadataToBuilder(builder, type);
builder.setTypes(children);
return this.addFileExportAndResolveBuilder(builder);
}
parseRecordOf(type, children = []) {
const builder = new import_record_builder.TsRecordBuilder();
this.tsAddMetadataToBuilder(builder, type);
for (let i = 0; i < (children == null ? void 0 : children.length); i++) {
const child = children[i];
builder.addProperty(child.propertyName, child.child, child.required);
}
return this.addFileExportAndResolveBuilder(builder);
}
parseDict(type, children = []) {
const builder = new import_dictionary_builder.TsDictBuilder();
this.tsAddMetadataToBuilder(builder, type);
builder.setTypes(children);
return this.addFileExportAndResolveBuilder(builder);
}
parseSetOf(type, children = []) {
const builder = new import_set_builder.TsSetBuilder();
this.tsAddMetadataToBuilder(builder, type);
builder.setTypes(children);
return this.addFileExportAndResolveBuilder(builder);
}
parseOneOf(type, children) {
const builder = new import_union_builder.TsUnionBuilder();
this.tsAddMetadataToBuilder(builder, type);
builder.setTypes(children);
return this.addFileExportAndResolveBuilder(builder);
}
parseAllOf(type, children) {
const builder = new import_intersection_builder.TsIntersectionBuilder();
this.tsAddMetadataToBuilder(builder, type);
builder.setTypes(children);
return this.addFileExportAndResolveBuilder(builder);
}
parseLiteral(type) {
const builder = new import_literal_builder.TsLiteralBuilder(type.literal);
this.tsAddMetadataToBuilder(builder, type);
return builder;
}
parseEnum(type) {
const metadata = import_enum.EnumType.getOriginalMetadata(type);
let typeName = metadata.enumName;
const externalImport = this.getExternalTypeImport(type);
if (externalImport) {
this.fileScope.addTypeImport(externalImport);
typeName = externalImport.typeName;
}
if (!typeName) {
throw new Error(
"Enum name is not defined. To be able to parse an Enum DataType `enumName` must be defined."
);
}
const builder = new import_enum_builder.TsEnumBuilder(typeName);
this.tsAddMetadataToBuilder(builder, type);
return builder;
}
parseEnumMember(type) {
var _a;
const metadata = import_enum_member.EnumMemberType.getOriginalMetadata(type);
const externalImport = this.getExternalTypeImport(type);
const typeName = (_a = metadata.enumName) != null ? _a : externalImport == null ? void 0 : externalImport.typeName;
if (!typeName || !metadata.memberName) {
throw new Error(
"Enum name, or enum member name is not defined. To be able to parse an EnumMember DataType into Typescript definition `memberName` and `enumName` must be defined."
);
}
if (externalImport) {
this.fileScope.addTypeImport(externalImport);
}
const builder = new import_enum_member_builder.TsEnumMemberBuilder(typeName, metadata.memberName);
this.tsAddMetadataToBuilder(builder, type);
return builder;
}
parseInstanceOf(type) {
const constructor = type.instanceOf;
let typeName = constructor.name;
const externalImport = this.getExternalTypeImport(type);
if (externalImport) {
this.fileScope.addTypeImport(externalImport);
typeName = externalImport.typeName;
}
const builder = new import_instanceof_builder.TsInstanceOfBuilder(typeName);
this.tsAddMetadataToBuilder(builder, type);
if (builder.getName() === typeName) {
builder.setName(`Alias${(0, import_capitalize.capitalize)(builder.getName())}`);
}
return this.addFileExportAndResolveBuilder(builder);
}
parseCustom(type) {
const externalImport = this.getExternalTypeImport(type);
if (externalImport) {
this.fileScope.addTypeImport(externalImport);
const builder2 = new import_external_type_reference.TsExternalTypeReference(externalImport.typeName);
this.tsAddMetadataToBuilder(builder2, type);
return this.addFileExportAndResolveBuilder(builder2);
}
const builder = new import_unknown_builder.TsUnknownBuilder();
this.tsAddMetadataToBuilder(builder, type);
return builder;
}
parseStringMatching(type) {
const { tsPattern } = import_string_matching.StringMatchingType.getOriginalMetadata(type);
const builder = new import_string_matching_builder.TsStringMatchingBuilder(tsPattern);
this.tsAddMetadataToBuilder(builder, type);
return this.addFileExportAndResolveBuilder(builder);
}
parseCircular(type, children) {
const childType = type.type;
const [actualType] = children;
if (this.circulars.has(childType)) {
const name = this.circulars.get(childType);
actualType.setName(name);
return this.fileScope.addTypeExport(actualType, name);
}
return actualType;
}
parseCircularRef(type) {
var _a;
const referencedType = type._getReferencedType();
const metadata = import_base_type.BaseType.getOriginalMetadata(referencedType);
const title = metadata.title;
if (this.circulars.has(referencedType)) {
return new import_type_reference.TsNamedReference(this.circulars.get(referencedType));
}
if (title) {
const typeName2 = import_name_generator.NameGenerator.generate(title);
this.circulars.set(referencedType, typeName2);
return new import_type_reference.TsNamedReference(typeName2);
}
const typeName = import_name_generator.NameGenerator.generate(
(_a = import_type_kind_names.TypeKindNames.get(referencedType.kind)) != null ? _a : "Circular"
);
this.circulars.set(referencedType, typeName);
return new import_type_reference.TsNamedReference(typeName);
}
visit(type, children) {
switch (type.kind) {
case "simple":
return this.parsePrimitive(type);
case "array":
return this.parseArrayOf(type, children);
case "tuple":
return this.parseTuple(type, children);
case "record":
return this.parseRecordOf(type, children);
case "dictionary":
return this.parseDict(type, children);
case "set":
return this.parseSetOf(type, children);
case "union":
return this.parseOneOf(type, children);
case "intersection":
return this.parseAllOf(type, children);
case "literal":
return this.parseLiteral(type);
case "enumUnion":
return this.parseEnum(type);
case "enumMember":
return this.parseEnumMember(type);
case "instanceOf":
return this.parseInstanceOf(type);
case "custom":
return this.parseCustom(type);
case "stringMatching":
return this.parseStringMatching(type);
case "circular":
return this.parseCircular(type, children);
case "circularRef":
return this.parseCircularRef(type);
}
}
};
var toTsType = (dataType, options) => {
var _a, _b, _c, _d;
try {
const opt = {
mode: (_a = options == null ? void 0 : options.mode) != null ? _a : "compact",
exports: (_b = options == null ? void 0 : options.exports) != null ? _b : "main",
declaration: (_c = options == null ? void 0 : options.declaration) != null ? _c : false,
onDuplicateName: (_d = options == null ? void 0 : options.onDuplicateName) != null ? _d : "error",
getExternalTypeImport: options == null ? void 0 : options.getExternalTypeImport
};
const generator = new DataTypeTsGenerator(opt);
const rootBuilder = dataType._acceptVisitor(generator);
generator.fileScope.addRootType(rootBuilder);
return generator.fileScope.build();
} finally {
import_name_generator.NameGenerator.clear();
}
};