dilswer
Version:
Blazingly fast data validation library with TypeScript integration.
140 lines (138 loc) • 4.99 kB
JavaScript
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
// src/ts-type-generator/file-scope.ts
import { NameGenerator } from "./name-generator.mjs";
import { TsTypeReference } from "./type-builders/type-reference.mjs";
var TsFileScope = class {
constructor(options) {
this.options = options;
__publicField(this, "imports", /* @__PURE__ */ new Map());
__publicField(this, "typeDefinitions", /* @__PURE__ */ new Map());
__publicField(this, "exportedNames", /* @__PURE__ */ new Set());
__publicField(this, "definedTypes", /* @__PURE__ */ new Set());
}
exportTypeFor(builder, isRoot = false) {
if (this.options.declaration) {
if (this.options.exports === "none") return "declare";
if (this.options.exports === "main" && !isRoot) return "declare";
if (this.options.exports === "named" && !builder.isTitled) {
return "declare";
}
return "export/declare";
}
if (this.options.exports === "none") return null;
if (this.options.exports === "main" && !isRoot) return null;
if (this.options.exports === "named" && !builder.isTitled) return null;
return "export";
}
addTypeImport(ext) {
if (ext.path) {
let imports = this.imports.get(ext.path);
if (!imports) {
imports = /* @__PURE__ */ new Set();
this.imports.set(ext.path, imports);
}
imports.add(ext.importName);
}
}
appendDef(builder, name, declarationStatement) {
if (this.options.exports === "none" || this.options.exports === "main") {
declarationStatement = declarationStatement.replace(/^export /, "");
}
this.definedTypes.add(name);
this.typeDefinitions.set(builder, declarationStatement);
if (declarationStatement.match(/^\s*export/)) {
this.exportedNames.add(name);
}
}
changeReferenceName(ref, newName) {
const currentName = ref.getName();
if (currentName === newName) return;
if (this.definedTypes.has(newName)) {
throw new Error(`Duplicate type name: ${newName}`);
}
const referencedBuilder = TsTypeReference.resolveReference(ref);
if (currentName) {
this.definedTypes.delete(currentName);
this.typeDefinitions.delete(referencedBuilder);
this.exportedNames.delete(currentName);
}
referencedBuilder.setName(newName);
ref.name = newName;
const declarationStatement = referencedBuilder.buildExport(
this.exportTypeFor(referencedBuilder)
);
if (declarationStatement) {
this.appendDef(referencedBuilder, newName, declarationStatement);
}
}
addTypeExport(builder, forceName) {
let declarationStatement = builder.buildExport(this.exportTypeFor(builder));
let name = forceName != null ? forceName : builder.getName();
if (!name) {
throw new Error(
"Type name is undefined after definition generation. Impossible situation."
);
}
if (!forceName) {
if (this.definedTypes.has(name)) {
switch (this.options.onDuplicateName) {
case "error":
throw new Error(`Duplicate type name: ${name}`);
case "rename": {
name = NameGenerator.generate(name);
builder.setName(name);
declarationStatement = builder.buildExport(
this.exportTypeFor(builder)
);
}
}
}
if (declarationStatement) {
this.appendDef(builder, name, declarationStatement);
}
} else if (declarationStatement && !this.definedTypes.has(name)) {
this.appendDef(builder, name, declarationStatement);
}
builder.isAddedToScope = true;
return new TsTypeReference(this, builder, name);
}
addRootType(builder) {
const referencedBuilder = TsTypeReference.resolveReference(builder);
if (!referencedBuilder.isAddedToScope) {
this.addTypeExport(referencedBuilder);
}
const exportType = this.exportTypeFor(builder, true);
const def = builder.buildExport(exportType);
const name = builder.getName();
if (name && this.exportedNames.has(name)) {
return;
}
if (def) {
this.typeDefinitions.set(builder, def);
} else {
if (name) {
switch (exportType) {
case "export":
case "export/declare":
this.typeDefinitions.set(builder, `export type { ${name} };`);
break;
}
}
}
}
build() {
let imports = "";
for (const [from, types] of this.imports) {
const typesList = Array.from(types).join(", ");
imports += `import type { ${typesList} } from "${from}";
`;
}
const content = [...this.typeDefinitions.values()].join("\n\n");
return (imports + content).trim() + "\n";
}
};
export {
TsFileScope
};