ts-auto-guard
Advanced tools
Comparing version 4.2.0 to 5.0.0
@@ -6,2 +6,1 @@ #!/usr/bin/env node | ||
export {}; | ||
//# sourceMappingURL=cli.d.ts.map |
170
lib/cli.js
#!/usr/bin/env node | ||
"use strict"; | ||
var __assign = (this && this.__assign) || function () { | ||
__assign = Object.assign || function(t) { | ||
for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
s = arguments[i]; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) | ||
t[p] = s[p]; | ||
} | ||
return t; | ||
}; | ||
return __assign.apply(this, arguments); | ||
}; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
@@ -37,38 +26,2 @@ if (k2 === undefined) k2 = k; | ||
}; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
@@ -78,8 +31,8 @@ return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var ts_morph_1 = require("ts-morph"); | ||
var command_line_args_1 = __importDefault(require("command-line-args")); | ||
var command_line_usage_1 = __importDefault(require("command-line-usage")); | ||
var TsConfig = __importStar(require("tsconfig")); | ||
var index_1 = require("./index"); | ||
var optionList = [ | ||
const ts_morph_1 = require("ts-morph"); | ||
const command_line_args_1 = __importDefault(require("command-line-args")); | ||
const command_line_usage_1 = __importDefault(require("command-line-usage")); | ||
const TsConfig = __importStar(require("tsconfig")); | ||
const index_1 = require("./index"); | ||
const optionList = [ | ||
{ | ||
@@ -146,68 +99,55 @@ description: 'A JavaScript condition used to automatically return `true` from guard functions, bypassing checks. eg. `process.env.DEBUG === "production"`.', | ||
]; | ||
var options = __assign({ paths: [], help: false }, (0, command_line_args_1.default)(optionList)); | ||
function run() { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var project, error_1; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, TsConfig.resolve(process.cwd(), options.project)]; | ||
case 1: | ||
project = _a.sent(); | ||
if (project === undefined) { | ||
console.error('Could not find tsconfig'); | ||
return [2 /*return*/]; | ||
} | ||
if ('import-guards' in options) { | ||
/** Checks if valid name passed as argument or replace with default if empty */ | ||
if (!options['import-guards']) { | ||
options['import-guards'] = 'TypeGuards'; | ||
} | ||
try { | ||
eval("const ".concat(options['import-guards'], " = true")); | ||
} | ||
catch (error) { | ||
console.log('Please pass a valid import alias'); | ||
throw error; | ||
} | ||
} | ||
_a.label = 2; | ||
case 2: | ||
_a.trys.push([2, 4, , 5]); | ||
return [4 /*yield*/, (0, index_1.generate)({ | ||
paths: options.paths, | ||
processOptions: { | ||
debug: options.debug, | ||
exportAll: options['export-all'], | ||
importGuards: options['import-guards'], | ||
importExtension: options['import-extension'], | ||
preventExportImported: options['prevent-export-imported'], | ||
shortCircuitCondition: options.shortcircuit, | ||
guardFileName: options['guard-file-name'], | ||
}, | ||
project: project, | ||
})]; | ||
case 3: | ||
_a.sent(); | ||
console.log('Done!'); | ||
return [3 /*break*/, 5]; | ||
case 4: | ||
error_1 = _a.sent(); | ||
if (error_1 instanceof ts_morph_1.FileNotFoundError) { | ||
console.error(error_1.message); | ||
} | ||
else { | ||
throw error_1; | ||
} | ||
return [3 /*break*/, 5]; | ||
case 5: return [2 /*return*/]; | ||
} | ||
const options = { | ||
paths: [], | ||
help: false, | ||
...(0, command_line_args_1.default)(optionList), | ||
}; | ||
async function run() { | ||
const project = await TsConfig.resolve(process.cwd(), options.project); | ||
if (project === undefined) { | ||
console.error('Could not find tsconfig'); | ||
return; | ||
} | ||
if ('import-guards' in options) { | ||
if (!options['import-guards']) { | ||
options['import-guards'] = 'TypeGuards'; | ||
} | ||
try { | ||
eval(`const ${options['import-guards']} = true`); | ||
} | ||
catch (error) { | ||
console.log('Please pass a valid import alias'); | ||
throw error; | ||
} | ||
} | ||
try { | ||
await (0, index_1.generate)({ | ||
paths: options.paths, | ||
processOptions: { | ||
debug: options.debug, | ||
exportAll: options['export-all'], | ||
importGuards: options['import-guards'], | ||
importExtension: options['import-extension'], | ||
preventExportImported: options['prevent-export-imported'], | ||
shortCircuitCondition: options.shortcircuit, | ||
guardFileName: options['guard-file-name'], | ||
}, | ||
project, | ||
}); | ||
}); | ||
console.log('Done!'); | ||
} | ||
catch (error) { | ||
if (error instanceof ts_morph_1.FileNotFoundError) { | ||
console.error(error.message); | ||
} | ||
else { | ||
throw error; | ||
} | ||
} | ||
} | ||
if (options.help) { | ||
// eslint-disable-next-line @typescript-eslint/no-var-requires | ||
var _a = require('../package.json'), name = _a.name, version = _a.version, description = _a.description; | ||
const { name, version, description } = require('../package.json'); | ||
console.log((0, command_line_usage_1.default)([ | ||
{ | ||
header: "".concat(name, " ").concat(version), | ||
header: `${name} ${version}`, | ||
content: description, | ||
@@ -217,3 +157,3 @@ }, | ||
header: 'Options', | ||
optionList: optionList, | ||
optionList, | ||
}, | ||
@@ -220,0 +160,0 @@ ])); |
@@ -19,2 +19,1 @@ import { Project } from 'ts-morph'; | ||
export declare function processProject(project: Project, options?: Readonly<IProcessOptions>): void; | ||
//# sourceMappingURL=index.d.ts.map |
685
lib/index.js
"use strict"; | ||
/* eslint-disable @typescript-eslint/no-non-null-assertion */ | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
var __read = (this && this.__read) || function (o, n) { | ||
var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
if (!m) return o; | ||
var i = m.call(o), r, ar = [], e; | ||
try { | ||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); | ||
} | ||
catch (error) { e = { error: error }; } | ||
finally { | ||
try { | ||
if (r && !r.done && (m = i["return"])) m.call(i); | ||
} | ||
finally { if (e) throw e.error; } | ||
} | ||
return ar; | ||
}; | ||
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { | ||
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { | ||
if (ar || !(i in from)) { | ||
if (!ar) ar = Array.prototype.slice.call(from, 0, i); | ||
ar[i] = from[i]; | ||
} | ||
} | ||
return to.concat(ar || Array.prototype.slice.call(from)); | ||
}; | ||
var __values = (this && this.__values) || function(o) { | ||
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; | ||
if (m) return m.call(o); | ||
if (o && typeof o.length === "number") return { | ||
next: function () { | ||
if (o && i >= o.length) o = void 0; | ||
return { value: o && o[i++], done: !o }; | ||
} | ||
}; | ||
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.processProject = exports.generate = exports.assertNever = void 0; | ||
var common_1 = require("@ts-morph/common"); | ||
var ts_morph_1 = require("ts-morph"); | ||
var GENERATED_WARNING = 'WARNING: Do not manually change this file.'; | ||
// -- Helpers -- | ||
function reportError(message) { | ||
var args = []; | ||
for (var _i = 1; _i < arguments.length; _i++) { | ||
args[_i - 1] = arguments[_i]; | ||
} | ||
console.error.apply(console, __spreadArray(["ERROR: ".concat(message)], __read(args), false)); | ||
const common_1 = require("@ts-morph/common"); | ||
const ts_morph_1 = require("ts-morph"); | ||
const GENERATED_WARNING = 'WARNING: Do not manually change this file.'; | ||
const fileExtensionRegex = /\.(ts|mts|cts|tsx|d\.ts)$/iu; | ||
function reportError(message, ...args) { | ||
console.error(`ERROR: ${message}`, ...args); | ||
} | ||
function lowerFirst(s) { | ||
var first_code_point = s.codePointAt(0); | ||
const first_code_point = s.codePointAt(0); | ||
if (first_code_point === undefined) | ||
return s; | ||
var first_letter = String.fromCodePoint(first_code_point); | ||
const first_letter = String.fromCodePoint(first_code_point); | ||
return first_letter.toLowerCase() + s.substr(first_letter.length); | ||
} | ||
function findExportableNode(type) { | ||
var symbol = type.getSymbol(); | ||
const symbol = type.getSymbol(); | ||
if (symbol === undefined) { | ||
@@ -102,20 +25,20 @@ return null; | ||
.getDeclarations() | ||
.reduce(function (acc, node) { return __spreadArray(__spreadArray(__spreadArray([], __read(acc), false), [node], false), __read(node.getAncestors()), false); }, []) | ||
.reduce((acc, node) => [...acc, node, ...node.getAncestors()], []) | ||
.filter(ts_morph_1.Node.isExportable) | ||
.find(function (n) { return n.isExported(); }) || null); | ||
.find(n => n.isExported()) || null); | ||
} | ||
function propertyName(signature) { | ||
var _a, _b; | ||
return ((_b = (_a = signature.getNameNode().getSymbol()) === null || _a === void 0 ? void 0 : _a.compilerSymbol.escapedName) !== null && _b !== void 0 ? _b : signature.getName()); | ||
return (signature.getNameNode().getSymbol()?.compilerSymbol.escapedName ?? | ||
signature.getName()); | ||
} | ||
function typeToDependency(type, addDependency) { | ||
var exportable = findExportableNode(type); | ||
const exportable = findExportableNode(type); | ||
if (exportable === null) { | ||
return; | ||
} | ||
var sourceFile = exportable.getSourceFile(); | ||
var name = exportable.getSymbol().getName(); | ||
var isDefault = exportable.isDefaultExport(); | ||
const sourceFile = exportable.getSourceFile(); | ||
const name = exportable.getSymbol().getName(); | ||
const isDefault = exportable.isDefaultExport(); | ||
if (!exportable.isExported()) { | ||
reportError("".concat(name, " is not exported from ").concat(sourceFile.getFilePath())); | ||
reportError(`${name} is not exported from ${sourceFile.getFilePath()}`); | ||
} | ||
@@ -125,5 +48,8 @@ addDependency(sourceFile, name, isDefault); | ||
function outFilePath(sourcePath, guardFileName) { | ||
var outPath = sourcePath.replace(/\.(ts|tsx|d\.ts)$/, ".".concat(guardFileName, ".ts")); | ||
if (outPath === sourcePath) | ||
const cjsModuleMode = sourcePath.endsWith('cts'); | ||
const esmModuleMode = sourcePath.endsWith('mts'); | ||
const outPath = sourcePath.replace(fileExtensionRegex, `.${guardFileName}.${cjsModuleMode ? 'cts' : esmModuleMode ? 'mts' : 'ts'}`); | ||
if (outPath === sourcePath) { | ||
throw new Error('Internal Error: sourcePath and outFilePath are identical: ' + outPath); | ||
} | ||
return outPath; | ||
@@ -136,33 +62,21 @@ } | ||
else { | ||
console.warn("".concat(sourceFile.getFilePath(), " is named like a guard file, but does not contain the generated header. Consider removing or renaming the file, or change the guardFileName setting.")); | ||
console.warn(`${sourceFile.getFilePath()} is named like a guard file, but does not contain the generated header. Consider removing or renaming the file, or change the guardFileName setting.`); | ||
} | ||
} | ||
// https://github.com/dsherret/ts-simple-ast/issues/108#issuecomment-342665874 | ||
function isClassType(type) { | ||
var e_1, _a; | ||
if (type.getConstructSignatures().length > 0) { | ||
return true; | ||
} | ||
var symbol = type.getSymbol(); | ||
const symbol = type.getSymbol(); | ||
if (symbol == null) { | ||
return false; | ||
} | ||
try { | ||
for (var _b = __values(symbol.getDeclarations()), _c = _b.next(); !_c.done; _c = _b.next()) { | ||
var declaration = _c.value; | ||
if (ts_morph_1.Node.isClassDeclaration(declaration)) { | ||
return true; | ||
} | ||
if (ts_morph_1.Node.isVariableDeclaration(declaration) && | ||
declaration.getType().getConstructSignatures().length > 0) { | ||
return true; | ||
} | ||
for (const declaration of symbol.getDeclarations()) { | ||
if (ts_morph_1.Node.isClassDeclaration(declaration)) { | ||
return true; | ||
} | ||
} | ||
catch (e_1_1) { e_1 = { error: e_1_1 }; } | ||
finally { | ||
try { | ||
if (_c && !_c.done && (_a = _b.return)) _a.call(_b); | ||
if (ts_morph_1.Node.isVariableDeclaration(declaration) && | ||
declaration.getType().getConstructSignatures().length > 0) { | ||
return true; | ||
} | ||
finally { if (e_1) throw e_1.error; } | ||
} | ||
@@ -172,3 +86,3 @@ return false; | ||
function isReadonlyArrayType(type) { | ||
var symbol = type.getSymbol(); | ||
const symbol = type.getSymbol(); | ||
if (symbol === undefined) { | ||
@@ -183,46 +97,24 @@ return false; | ||
function getTypeGuardName(child, options) { | ||
var e_2, _a, e_3, _b; | ||
var _c; | ||
var jsDocs = child.getJsDocs(); | ||
try { | ||
for (var jsDocs_1 = __values(jsDocs), jsDocs_1_1 = jsDocs_1.next(); !jsDocs_1_1.done; jsDocs_1_1 = jsDocs_1.next()) { | ||
var doc = jsDocs_1_1.value; | ||
try { | ||
for (var _d = (e_3 = void 0, __values(doc.getInnerText().split('\n'))), _e = _d.next(); !_e.done; _e = _d.next()) { | ||
var line = _e.value; | ||
var match = line | ||
.trim() | ||
.match(/@see\s+(?:{\s*(@link\s*)?(\w+)\s*}\s+)?ts-auto-guard:([^\s]*)/); | ||
if (match !== null) { | ||
var _f = __read(match, 4), typeGuardName = _f[2], command = _f[3]; | ||
if (command !== 'type-guard') { | ||
reportError("command ".concat(command, " is not supported!")); | ||
return null; | ||
} | ||
return typeGuardName; | ||
} | ||
const jsDocs = child.getJsDocs(); | ||
for (const doc of jsDocs) { | ||
for (const line of doc.getInnerText().split('\n')) { | ||
const match = line | ||
.trim() | ||
.match(/@see\s+(?:{\s*(@link\s*)?(\w+)\s*}\s+)?ts-auto-guard:([^\s]*)/); | ||
if (match !== null) { | ||
const [, , typeGuardName, command] = match; | ||
if (command !== 'type-guard') { | ||
reportError(`command ${command} is not supported!`); | ||
return null; | ||
} | ||
return typeGuardName; | ||
} | ||
catch (e_3_1) { e_3 = { error: e_3_1 }; } | ||
finally { | ||
try { | ||
if (_e && !_e.done && (_b = _d.return)) _b.call(_d); | ||
} | ||
finally { if (e_3) throw e_3.error; } | ||
} | ||
} | ||
} | ||
catch (e_2_1) { e_2 = { error: e_2_1 }; } | ||
finally { | ||
try { | ||
if (jsDocs_1_1 && !jsDocs_1_1.done && (_a = jsDocs_1.return)) _a.call(jsDocs_1); | ||
} | ||
finally { if (e_2) throw e_2.error; } | ||
} | ||
if (options.exportAll) { | ||
var t = child.getType(); | ||
var symbols = [child, t.getSymbol(), t.getAliasSymbol()]; | ||
// type aliases have type __type sometimes | ||
var name = (_c = symbols | ||
.filter(function (x) { return x && x.getName() !== '__type'; })[0]) === null || _c === void 0 ? void 0 : _c.getName(); | ||
const t = child.getType(); | ||
const symbols = [child, t.getSymbol(), t.getAliasSymbol()]; | ||
const name = symbols | ||
.filter(x => x && x.getName() !== '__type')[0] | ||
?.getName(); | ||
if (name) { | ||
@@ -234,63 +126,48 @@ return 'is' + name; | ||
} | ||
// -- Main program -- | ||
function ors() { | ||
var statements = []; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
statements[_i] = arguments[_i]; | ||
} | ||
function ors(...statements) { | ||
return parens(statements.join(' || \n')); | ||
} | ||
function ands() { | ||
var statements = []; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
statements[_i] = arguments[_i]; | ||
} | ||
function ands(...statements) { | ||
return statements.join(' && \n'); | ||
} | ||
function eq(a, b) { | ||
return "".concat(a, " === ").concat(b); | ||
return `${a} === ${b}`; | ||
} | ||
function ne(a, b) { | ||
return "".concat(a, " !== ").concat(b); | ||
return `${a} !== ${b}`; | ||
} | ||
function typeOf(varName, type) { | ||
return eq("typeof ".concat(varName), "\"".concat(type, "\"")); | ||
return eq(`typeof ${varName}`, `"${type}"`); | ||
} | ||
function typeUnionConditions(varName, types, addDependency, project, path, arrayDepth, records, outFile, options) { | ||
var conditions = []; | ||
conditions.push.apply(conditions, __spreadArray([], __read(types | ||
.map(function (type) { | ||
return typeConditions(varName, type, addDependency, project, path, arrayDepth, true, records, outFile, options); | ||
}) | ||
.filter(function (v) { return v !== null; })), false)); | ||
return ors.apply(void 0, __spreadArray([], __read(conditions), false)); | ||
const conditions = []; | ||
conditions.push(...types | ||
.map(type => typeConditions(varName, type, addDependency, project, path, arrayDepth, true, records, outFile, options)) | ||
.filter(v => v !== null)); | ||
return ors(...conditions); | ||
} | ||
function typeIntersectionConditions(varName, types, addDependency, project, path, arrayDepth, records, outFile, options) { | ||
var conditions = []; | ||
conditions.push.apply(conditions, __spreadArray([], __read(types | ||
.map(function (type) { | ||
return typeConditions(varName, type, addDependency, project, path, arrayDepth, true, records, outFile, options); | ||
}) | ||
.filter(function (v) { return v !== null; })), false)); | ||
return ands.apply(void 0, __spreadArray([], __read(conditions), false)); | ||
const conditions = []; | ||
conditions.push(...types | ||
.map(type => typeConditions(varName, type, addDependency, project, path, arrayDepth, true, records, outFile, options)) | ||
.filter(v => v !== null)); | ||
return ands(...conditions); | ||
} | ||
function parens(code) { | ||
return "(".concat(code, ")"); | ||
return `(${code})`; | ||
} | ||
function arrayCondition(varName, arrayType, addDependency, project, path, arrayDepth, records, outFile, options) { | ||
if (arrayType.getText() === 'never') { | ||
return ands("Array.isArray(".concat(varName, ")"), eq("".concat(varName, ".length"), '0')); | ||
return ands(`Array.isArray(${varName})`, eq(`${varName}.length`, '0')); | ||
} | ||
var indexIdentifier = "i".concat(arrayDepth); | ||
var elementPath = "".concat(path, "[${").concat(indexIdentifier, "}]"); | ||
var conditions = typeConditions('e', arrayType, addDependency, project, elementPath, arrayDepth + 1, true, records, outFile, options); | ||
const indexIdentifier = `i${arrayDepth}`; | ||
const elementPath = `${path}[\${${indexIdentifier}}]`; | ||
const conditions = typeConditions('e', arrayType, addDependency, project, elementPath, arrayDepth + 1, true, records, outFile, options); | ||
if (conditions === null) { | ||
return "Array.isArray(".concat(varName, ")"); | ||
return `Array.isArray(${varName})`; | ||
} | ||
// Bit of a hack, just check if the second argument is used before actually | ||
// creating it. This avoids unused parameter errors. | ||
var secondArg = conditions.includes(elementPath) | ||
? ", ".concat(indexIdentifier, ": number") | ||
const secondArg = conditions.includes(elementPath) | ||
? `, ${indexIdentifier}: number` | ||
: ''; | ||
return ands("Array.isArray(".concat(varName, ")"), "".concat(varName, ".every((e: any").concat(secondArg, ") =>\n").concat(conditions, "\n)")); | ||
return ands(`Array.isArray(${varName})`, `${varName}.every((e: any${secondArg}) =>\n${conditions}\n)`); | ||
} | ||
@@ -311,31 +188,30 @@ function objectTypeCondition(varName, callable) { | ||
default: | ||
throw new Error("Invalid type for index key: ".concat(type.getText(), ". Only string or number are expected.")); | ||
throw new Error(`Invalid type for index key: ${type.getText()}. Only string or number are expected.`); | ||
} | ||
} | ||
function objectCondition(varName, type, addDependency, project, path, arrayDepth, records, outFile, options) { | ||
var _a; | ||
var conditions = []; | ||
var symbol = type.getSymbol(); | ||
const conditions = []; | ||
const symbol = type.getSymbol(); | ||
if (symbol === undefined) { | ||
// I think this is happening when the type is declare in a node module. | ||
// tslint:disable-next-line:no-console | ||
console.error("Unable to get symbol for type ".concat(type.getText())); | ||
console.error(`Unable to get symbol for type ${type.getText()}`); | ||
return typeOf(varName, 'object'); | ||
} | ||
var declarations = symbol.getDeclarations(); | ||
// TODO: https://github.com/rhys-vdw/ts-auto-guard/issues/29 | ||
var declaration = declarations[0]; | ||
const declarations = symbol.getDeclarations(); | ||
const declaration = declarations[0]; | ||
if (declaration === undefined) { | ||
reportError("Couldn't find declaration for type ".concat(type.getText())); | ||
reportError(`Couldn't find declaration for type ${type.getText()}`); | ||
return null; | ||
} | ||
var callable = type.getCallSignatures().length !== 0; | ||
const callable = type.getCallSignatures().length !== 0; | ||
if (callable) { | ||
// emit warning | ||
var suppressComment = 'ts-auto-guard-suppress function-type'; | ||
var commentsBefore = declaration.getLeadingCommentRanges(); | ||
var commentBefore = commentsBefore[commentsBefore.length - 1]; | ||
const suppressComment = 'ts-auto-guard-suppress function-type'; | ||
const commentsBefore = declaration.getLeadingCommentRanges(); | ||
const commentBefore = commentsBefore[commentsBefore.length - 1]; | ||
if (commentBefore === undefined || | ||
!commentBefore.getText().includes(suppressComment)) { | ||
console.warn("\nIt seems that ".concat(varName, " has a function type.\nNote that it is impossible to check if a function has the correct signature and return type at runtime.\nTo disable this warning, put comment \"").concat(suppressComment, "\" before the declaration.\n")); | ||
console.warn(` | ||
It seems that ${varName} has a function type. | ||
Note that it is impossible to check if a function has the correct signature and return type at runtime. | ||
To disable this warning, put comment "${suppressComment}" before the declaration. | ||
`); | ||
} | ||
@@ -347,4 +223,4 @@ } | ||
} | ||
declaration.getBaseTypes().forEach(function (baseType) { | ||
var condition = typeConditions(varName, baseType, addDependency, project, path, arrayDepth, true, records, outFile, options); | ||
declaration.getBaseTypes().forEach(baseType => { | ||
const condition = typeConditions(varName, baseType, addDependency, project, path, arrayDepth, true, records, outFile, options); | ||
if (condition !== null) { | ||
@@ -357,16 +233,18 @@ conditions.push(condition); | ||
} | ||
// getProperties does not include methods like `foo(): void` | ||
var properties = __spreadArray(__spreadArray([], __read(declaration.getProperties()), false), __read(declaration.getMethods()), false).map(function (p) { return ({ | ||
const properties = [ | ||
...declaration.getProperties(), | ||
...declaration.getMethods(), | ||
].map(p => ({ | ||
name: propertyName(p), | ||
type: p.getType(), | ||
}); }); | ||
conditions.push.apply(conditions, __spreadArray([], __read(propertiesConditions(varName, properties, addDependency, project, path, arrayDepth, records, outFile, options)), false)); | ||
var indexSignatures = declaration | ||
})); | ||
conditions.push(...propertiesConditions(varName, properties, addDependency, project, path, arrayDepth, records, outFile, options)); | ||
const indexSignatures = declaration | ||
.getIndexSignatures() | ||
.map(function (p) { return ({ keyType: p.getKeyType(), type: p.getReturnType() }); }); | ||
.map(p => ({ keyType: p.getKeyType(), type: p.getReturnType() })); | ||
if (indexSignatures.length) { | ||
conditions.push(indexSignaturesCondition(varName, indexSignatures.map(function (x) { return ({ | ||
conditions.push(indexSignaturesCondition(varName, indexSignatures.map(x => ({ | ||
keyType: indexKeyTypeToString(x.keyType), | ||
type: x.type, | ||
}); }), properties, addDependency, project, path, arrayDepth, records, outFile, options)); | ||
})), properties, addDependency, project, path, arrayDepth, records, outFile, options)); | ||
} | ||
@@ -376,11 +254,10 @@ } | ||
conditions.push(objectTypeCondition(varName, callable)); | ||
// Get object literal properties... | ||
try { | ||
var properties = type.getProperties(); | ||
var typeDeclarations_1 = (_a = type.getSymbol()) === null || _a === void 0 ? void 0 : _a.getDeclarations(); | ||
var propertySignatures = properties.map(function (p) { | ||
var propertyDeclarations = p.getDeclarations(); | ||
var typeAtLocation = propertyDeclarations.length !== 0 | ||
const properties = type.getProperties(); | ||
const typeDeclarations = type.getSymbol()?.getDeclarations(); | ||
const propertySignatures = properties.map(p => { | ||
const propertyDeclarations = p.getDeclarations(); | ||
const typeAtLocation = propertyDeclarations.length !== 0 | ||
? p.getTypeAtLocation(propertyDeclarations[0]) | ||
: p.getTypeAtLocation((typeDeclarations_1 || [])[0]); | ||
: p.getTypeAtLocation((typeDeclarations || [])[0]); | ||
return { | ||
@@ -391,8 +268,8 @@ name: p.getName(), | ||
}); | ||
conditions.push.apply(conditions, __spreadArray([], __read(propertiesConditions(varName, propertySignatures, addDependency, project, path, arrayDepth, records, outFile, options)), false)); | ||
var stringIndexType = type.getStringIndexType(); | ||
conditions.push(...propertiesConditions(varName, propertySignatures, addDependency, project, path, arrayDepth, records, outFile, options)); | ||
const stringIndexType = type.getStringIndexType(); | ||
if (stringIndexType) { | ||
conditions.push(indexSignaturesCondition(varName, [{ keyType: 'string', type: stringIndexType }], propertySignatures, addDependency, project, path, arrayDepth, records, outFile, options)); | ||
} | ||
var numberIndexType = type.getNumberIndexType(); | ||
const numberIndexType = type.getNumberIndexType(); | ||
if (numberIndexType) { | ||
@@ -404,13 +281,12 @@ conditions.push(indexSignaturesCondition(varName, [{ keyType: 'number', type: numberIndexType }], propertySignatures, addDependency, project, path, arrayDepth, records, outFile, options)); | ||
if (error instanceof TypeError) { | ||
// see https://github.com/dsherret/ts-simple-ast/issues/397 | ||
reportError("Internal ts-simple-ast error for ".concat(type.getText()), error); | ||
reportError(`Internal ts-simple-ast error for ${type.getText()}`, error); | ||
} | ||
} | ||
} | ||
return ands.apply(void 0, __spreadArray([], __read(conditions), false)); | ||
return ands(...conditions); | ||
} | ||
function tupleCondition(varName, type, addDependency, project, path, arrayDepth, records, outFile, options) { | ||
var types = type.getTupleElements(); | ||
var conditions = types.reduce(function (acc, elementType, i) { | ||
var condition = typeConditions("".concat(varName, "[").concat(i, "]"), elementType, addDependency, project, path, arrayDepth, true, records, outFile, options); | ||
const types = type.getTupleElements(); | ||
const conditions = types.reduce((acc, elementType, i) => { | ||
const condition = typeConditions(`${varName}[${i}]`, elementType, addDependency, project, path, arrayDepth, true, records, outFile, options); | ||
if (condition !== null) { | ||
@@ -420,8 +296,8 @@ acc.push(condition); | ||
return acc; | ||
}, ["Array.isArray(".concat(varName, ")")]); | ||
return ands.apply(void 0, __spreadArray([], __read(conditions), false)); | ||
}, [`Array.isArray(${varName})`]); | ||
return ands(...conditions); | ||
} | ||
function literalCondition(varName, type, addDependency) { | ||
if (type.isEnumLiteral()) { | ||
var node = type | ||
const node = type | ||
.getSymbol() | ||
@@ -440,4 +316,3 @@ .getDeclarations() | ||
typeToDependency(type, addDependency); | ||
// type.getText() returns incorrect module name for some reason | ||
return eq(varName, "".concat(node.getSymbol().getName(), ".").concat(type.getSymbol().getName())); | ||
return eq(varName, `${node.getSymbol().getName()}.${type.getSymbol().getName()}`); | ||
} | ||
@@ -447,3 +322,3 @@ return eq(varName, type.getText()); | ||
function reusedCondition(type, records, outFile, addDependency, varName) { | ||
var record = records.find(function (x) { return x.typeDeclaration.getType() === type; }); | ||
const record = records.find(x => x.typeDeclaration.getType() === type); | ||
if (record) { | ||
@@ -453,3 +328,3 @@ if (record.outFile !== outFile) { | ||
} | ||
return "".concat(record.guardName, "(").concat(varName, ") as boolean"); | ||
return `${record.guardName}(${varName}) as boolean`; | ||
} | ||
@@ -459,3 +334,3 @@ return null; | ||
function typeConditions(varName, type, addDependency, project, path, arrayDepth, useGuard, records, outFile, options) { | ||
var reused = reusedCondition(type, records, outFile, addDependency, varName); | ||
const reused = reusedCondition(type, records, outFile, addDependency, varName); | ||
if (useGuard && reused) { | ||
@@ -477,4 +352,2 @@ return reused; | ||
if (type.isUnion()) { | ||
// Seems to be bug here where enums can only be detected with enum | ||
// literal + union check... odd. | ||
if (type.isEnumLiteral()) { | ||
@@ -496,3 +369,3 @@ typeToDependency(type, addDependency); | ||
typeToDependency(type, addDependency); | ||
return "".concat(varName, " instanceof ").concat(type.getSymbol().getName()); | ||
return `${varName} instanceof ${type.getSymbol().getName()}`; | ||
} | ||
@@ -511,16 +384,16 @@ if (type.isTuple()) { | ||
function propertyConditions(objName, property, addDependency, project, path, arrayDepth, records, outFile, options) { | ||
var debug = options.debug; | ||
var propertyName = property.name; | ||
var strippedName = propertyName.replace(/"/g, ''); | ||
var varName = "".concat(objName, "[\"").concat(strippedName, "\"]"); | ||
var propertyPath = "".concat(path, "[\"").concat(strippedName, "\"]"); | ||
var expectedType = property.type.getText(); | ||
var conditions = typeConditions(varName, property.type, addDependency, project, propertyPath, arrayDepth, true, records, outFile, options); | ||
const { debug } = options; | ||
const propertyName = property.name; | ||
const strippedName = propertyName.replace(/"/g, ''); | ||
const varName = `${objName}["${strippedName}"]`; | ||
const propertyPath = `${path}["${strippedName}"]`; | ||
let expectedType = property.type.getText(); | ||
const conditions = typeConditions(varName, property.type, addDependency, project, propertyPath, arrayDepth, true, records, outFile, options); | ||
if (debug) { | ||
if (expectedType.indexOf('import') > -1) { | ||
var standardizedCwd = common_1.FileUtils.standardizeSlashes(process.cwd()); | ||
const standardizedCwd = common_1.FileUtils.standardizeSlashes(process.cwd()); | ||
expectedType = expectedType.replace(standardizedCwd, '.'); | ||
} | ||
return (conditions && | ||
"evaluate(".concat(conditions, ", `").concat(propertyPath, "`, ").concat(JSON.stringify(expectedType), ", ").concat(varName, ")")); | ||
`evaluate(${conditions}, \`${propertyPath}\`, ${JSON.stringify(expectedType)}, ${varName})`); | ||
} | ||
@@ -531,8 +404,5 @@ return conditions; | ||
return properties | ||
.map(function (prop) { | ||
return propertyConditions(varName, prop, addDependency, project, path, arrayDepth, records, outFile, options); | ||
}) | ||
.filter(function (v) { return v !== null; }); | ||
.map(prop => propertyConditions(varName, prop, addDependency, project, path, arrayDepth, records, outFile, options)) | ||
.filter(v => v !== null); | ||
} | ||
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
function assertNever(_) { | ||
@@ -547,3 +417,3 @@ throw new Error('should be unreachable.'); | ||
else if (keyType === 'number') { | ||
return "(+".concat(varName, ").toString() === ").concat(varName); | ||
return `(+${varName}).toString() === ${varName}`; | ||
} | ||
@@ -558,6 +428,6 @@ else if (keyType === 'any') { | ||
function indexSignatureConditions(objName, keyName, valueUsed, keyUsed, index, addDependency, project, path, arrayDepth, records, outFile, options) { | ||
var debug = options.debug; | ||
var expectedType = index.type.getText(); | ||
var conditions = typeConditions(objName, index.type, addDependency, project, "".concat(path, " ").concat(objName), arrayDepth, true, records, outFile, options); | ||
var keyConditions = signatureKeyConditions(index.keyType, keyName); | ||
const { debug } = options; | ||
const expectedType = index.type.getText(); | ||
const conditions = typeConditions(objName, index.type, addDependency, project, `${path} ${objName}`, arrayDepth, true, records, outFile, options); | ||
const keyConditions = signatureKeyConditions(index.keyType, keyName); | ||
if (conditions) { | ||
@@ -570,7 +440,7 @@ valueUsed(); | ||
if (debug) { | ||
var cleanKeyReplacer = '${key.toString().replace(/"/g, \'\\\\"\')}'; | ||
var evaluation = conditions && | ||
"evaluate(".concat(conditions, ", `").concat(path, "[\"").concat(cleanKeyReplacer, "\"]`, ").concat(JSON.stringify(expectedType), ", ").concat(objName, ")"); | ||
var keyEvaluation = keyConditions && | ||
"evaluate(".concat(keyConditions, ", `").concat(path, " (key: \"").concat(cleanKeyReplacer, "\")`, ").concat(JSON.stringify(index.keyType), ", ").concat(keyName, ")"); | ||
const cleanKeyReplacer = '${key.toString().replace(/"/g, \'\\\\"\')}'; | ||
const evaluation = conditions && | ||
`evaluate(${conditions}, \`${path}["${cleanKeyReplacer}"]\`, ${JSON.stringify(expectedType)}, ${objName})`; | ||
const keyEvaluation = keyConditions && | ||
`evaluate(${keyConditions}, \`${path} (key: "${cleanKeyReplacer}")\`, ${JSON.stringify(index.keyType)}, ${keyName})`; | ||
if (evaluation || keyEvaluation) { | ||
@@ -587,45 +457,40 @@ keyUsed(); | ||
} | ||
// If we don't have both try and return one, or null if neither | ||
return conditions || keyConditions; | ||
} | ||
function indexSignaturesCondition(varName, indexSignatures, properties, addDependency, project, path, arrayDepth, records, outFile, options) { | ||
var valuePrefix = '_'; | ||
var valueUsed = function () { | ||
let valuePrefix = '_'; | ||
const valueUsed = () => { | ||
valuePrefix = ''; | ||
}; | ||
var keyPrefix = '_'; | ||
var keyUsed = function () { | ||
let keyPrefix = '_'; | ||
const keyUsed = () => { | ||
keyPrefix = ''; | ||
}; | ||
var conditions = ors.apply(void 0, __spreadArray([], __read(indexSignatures | ||
.map(function (indexSignature) { | ||
return indexSignatureConditions('value', 'key', valueUsed, keyUsed, indexSignature, addDependency, project, path, arrayDepth, records, outFile, options); | ||
}) | ||
.filter(function (v) { return v !== null; })), false)); | ||
var staticKeysFilter = properties.length | ||
? "\n .filter(([key]) => ![".concat(properties | ||
.map(function (_a) { | ||
var name = _a.name; | ||
return "\"".concat(name, "\""); | ||
}) | ||
.join(','), "].includes(key))") | ||
const conditions = ors(...indexSignatures | ||
.map(indexSignature => indexSignatureConditions('value', 'key', valueUsed, keyUsed, indexSignature, addDependency, project, path, arrayDepth, records, outFile, options)) | ||
.filter(v => v !== null)); | ||
const staticKeysFilter = properties.length | ||
? ` | ||
.filter(([key]) => ![${properties | ||
.map(({ name }) => `"${name}"`) | ||
.join(',')}].includes(key))` | ||
: ''; | ||
return "Object.entries<any>(".concat(varName, ")").concat(staticKeysFilter, "\n .every(([").concat(keyPrefix, "key, ").concat(valuePrefix, "value]) => ").concat(conditions, ")"); | ||
return `Object.entries<any>(${varName})${staticKeysFilter} | ||
.every(([${keyPrefix}key, ${valuePrefix}value]) => ${conditions})`; | ||
} | ||
function generateTypeGuard(functionName, typeDeclaration, addDependency, project, records, outFile, options) { | ||
var debug = options.debug, shortCircuitCondition = options.shortCircuitCondition; | ||
var typeName = typeDeclaration.getName(); | ||
var defaultArgumentName = lowerFirst(typeName); | ||
var signatureObjName = 'obj'; | ||
var innerObjName = 'typedObj'; | ||
var conditions = typeConditions(innerObjName, typeDeclaration.getType(), addDependency, project, '${argumentName}', // tslint:disable-line:no-invalid-template-strings | ||
0, false, records, outFile, options); | ||
var secondArgument = debug | ||
? ", argumentName: string = \"".concat(defaultArgumentName, "\"") | ||
const { debug, shortCircuitCondition } = options; | ||
const typeName = typeDeclaration.getName(); | ||
const defaultArgumentName = lowerFirst(typeName); | ||
const signatureObjName = 'obj'; | ||
const innerObjName = 'typedObj'; | ||
const conditions = typeConditions(innerObjName, typeDeclaration.getType(), addDependency, project, '${argumentName}', 0, false, records, outFile, options); | ||
const secondArgument = debug | ||
? `, argumentName: string = "${defaultArgumentName}"` | ||
: ''; | ||
var signature = "export function ".concat(functionName, "(").concat(signatureObjName, ": unknown").concat(secondArgument, "): ").concat(signatureObjName, " is ").concat(typeName, " {\n"); | ||
var shortCircuit = shortCircuitCondition | ||
? "if (".concat(shortCircuitCondition, ") return true\n") | ||
const signature = `export function ${functionName}(${signatureObjName}: unknown${secondArgument}): ${signatureObjName} is ${typeName} {\n`; | ||
const shortCircuit = shortCircuitCondition | ||
? `if (${shortCircuitCondition}) return true\n` | ||
: ''; | ||
var functionBody = "const ".concat(innerObjName, " = ").concat(signatureObjName, " as ").concat(typeName, "\nreturn (\n").concat(conditions || true, "\n)\n}\n"); | ||
const functionBody = `const ${innerObjName} = ${signatureObjName} as ${typeName}\nreturn (\n${conditions || true}\n)\n}\n`; | ||
return [signature, shortCircuit, functionBody].join(''); | ||
@@ -635,7 +500,7 @@ } | ||
return function addDependency(sourceFile, name, isDefault) { | ||
var alias = name; | ||
const alias = name; | ||
if (isDefault) { | ||
name = 'default'; | ||
} | ||
var imports = dependencies.get(sourceFile); | ||
let imports = dependencies.get(sourceFile); | ||
if (imports === undefined) { | ||
@@ -645,5 +510,5 @@ imports = {}; | ||
} | ||
var previousAlias = imports[name]; | ||
const previousAlias = imports[name]; | ||
if (previousAlias !== undefined && previousAlias !== alias) { | ||
reportError("Conflicting export alias for \"".concat(sourceFile.getFilePath(), "\": \"").concat(alias, "\" vs \"").concat(previousAlias, "\"")); | ||
reportError(`Conflicting export alias for "${sourceFile.getFilePath()}": "${alias}" vs "${previousAlias}"`); | ||
} | ||
@@ -653,17 +518,24 @@ imports[name] = alias; | ||
} | ||
var evaluateFunction = "function evaluate(\n isCorrect: boolean,\n varName: string,\n expected: string,\n actual: any\n): boolean {\n if (!isCorrect) {\n console.error(\n `${varName} type mismatch, expected: ${expected}, found:`,\n actual\n )\n }\n return isCorrect\n}\n"; | ||
function generate(_a) { | ||
var _b = _a.paths, paths = _b === void 0 ? [] : _b, tsConfigFilePath = _a.project, processOptions = _a.processOptions; | ||
return __awaiter(this, void 0, void 0, function () { | ||
var project; | ||
return __generator(this, function (_c) { | ||
project = new ts_morph_1.Project({ | ||
skipAddingFilesFromTsConfig: paths.length !== 0, | ||
tsConfigFilePath: tsConfigFilePath, | ||
}); | ||
project.addSourceFilesAtPaths(paths); | ||
processProject(project, processOptions); | ||
return [2 /*return*/, project.save()]; | ||
}); | ||
const evaluateFunction = `function evaluate( | ||
isCorrect: boolean, | ||
varName: string, | ||
expected: string, | ||
actual: any | ||
): boolean { | ||
if (!isCorrect) { | ||
console.error( | ||
\`\${varName} type mismatch, expected: \${expected}, found:\`, | ||
actual | ||
) | ||
} | ||
return isCorrect | ||
}\n`; | ||
async function generate({ paths = [], project: tsConfigFilePath, processOptions, }) { | ||
const project = new ts_morph_1.Project({ | ||
skipAddingFilesFromTsConfig: paths.length !== 0, | ||
tsConfigFilePath, | ||
}); | ||
project.addSourceFilesAtPaths(paths); | ||
processProject(project, processOptions); | ||
return project.save(); | ||
} | ||
@@ -676,20 +548,15 @@ exports.generate = generate; | ||
} | ||
function processProject(project, options) { | ||
if (options === void 0) { options = { debug: false }; } | ||
var importExtension = options.importExtension | ||
? ".".concat(options.importExtension) | ||
function processProject(project, options = { debug: false }) { | ||
const importExtension = options.importExtension | ||
? `.${options.importExtension}` | ||
: ''; | ||
var guardFileName = options.guardFileName || 'guard'; | ||
const guardFileName = options.guardFileName || 'guard'; | ||
if (guardFileName.match(/[*/]/)) | ||
throw new Error('guardFileName must not contain special characters'); | ||
// Delete previously generated guard. | ||
project | ||
.getSourceFiles("./**/*.".concat(guardFileName, ".ts")) | ||
.forEach(function (sourceFile) { return deleteGuardFile(sourceFile); }); | ||
var sourceFiles = project.getSourceFiles(); | ||
// Sort source files by dependencies - dependencies before dependants | ||
var orderedSourceFiles = []; | ||
var orderSourceFileByDependencies = function (sourceFile, visitedFiles) { | ||
if (visitedFiles === void 0) { visitedFiles = []; } | ||
// Ignore if already added as a dependency of another, or if we hit a cyclical import | ||
.getSourceFiles(`./**/*.${guardFileName}.ts`) | ||
.forEach(sourceFile => deleteGuardFile(sourceFile)); | ||
const sourceFiles = project.getSourceFiles(); | ||
const orderedSourceFiles = []; | ||
const orderSourceFileByDependencies = (sourceFile, visitedFiles = []) => { | ||
if (orderedSourceFiles.includes(sourceFile) || | ||
@@ -699,6 +566,5 @@ visitedFiles.includes(sourceFile)) { | ||
} | ||
var childVisitedFiles = __spreadArray(__spreadArray([], __read(visitedFiles), false), [sourceFile], false); | ||
// Add all dependencies to the ordered list first (if they have beeen specified and have not already been added) | ||
sourceFile.getImportDeclarations().forEach(function (importDeclaration) { | ||
var importSourceFile = importDeclaration.getModuleSpecifierSourceFile(); | ||
const childVisitedFiles = [...visitedFiles, sourceFile]; | ||
sourceFile.getImportDeclarations().forEach(importDeclaration => { | ||
const importSourceFile = importDeclaration.getModuleSpecifierSourceFile(); | ||
if (importSourceFile && | ||
@@ -710,51 +576,28 @@ sourceFiles.includes(importSourceFile) && | ||
}); | ||
// Add this one to the ordered list | ||
orderedSourceFiles.push(sourceFile); | ||
}; | ||
sourceFiles.forEach(function (sourceFile) { return orderSourceFileByDependencies(sourceFile); }); | ||
// Generate new guard files. | ||
var records = []; | ||
orderedSourceFiles.forEach(function (sourceFile) { | ||
var e_4, _a, e_5, _b, e_6, _c; | ||
var dependencies = new Map(); | ||
var addDependency = createAddDependency(dependencies); | ||
var functions = []; | ||
var exports = Array.from(sourceFile.getExportedDeclarations().values()) | ||
sourceFiles.forEach(sourceFile => orderSourceFileByDependencies(sourceFile)); | ||
const records = []; | ||
orderedSourceFiles.forEach(sourceFile => { | ||
const dependencies = new Map(); | ||
const addDependency = createAddDependency(dependencies); | ||
const functions = []; | ||
const exports = Array.from(sourceFile.getExportedDeclarations().values()) | ||
.flat() | ||
.filter(function (ex) { return ex.getSourceFile() === sourceFile; }); | ||
var allTypesDeclarations = exports.filter(isGuardable); | ||
var outFile = project.createSourceFile(outFilePath(sourceFile.getFilePath(), guardFileName), '', { overwrite: true }); | ||
try { | ||
for (var allTypesDeclarations_1 = __values(allTypesDeclarations), allTypesDeclarations_1_1 = allTypesDeclarations_1.next(); !allTypesDeclarations_1_1.done; allTypesDeclarations_1_1 = allTypesDeclarations_1.next()) { | ||
var typeDeclaration = allTypesDeclarations_1_1.value; | ||
var typeGuardName = getTypeGuardName(typeDeclaration, options); | ||
if (typeGuardName !== null) { | ||
records.push({ guardName: typeGuardName, typeDeclaration: typeDeclaration, outFile: outFile }); | ||
} | ||
.filter(ex => ex.getSourceFile() === sourceFile); | ||
const allTypesDeclarations = exports.filter(isGuardable); | ||
const outFile = project.createSourceFile(outFilePath(sourceFile.getFilePath(), guardFileName), '', { overwrite: true }); | ||
for (const typeDeclaration of allTypesDeclarations) { | ||
const typeGuardName = getTypeGuardName(typeDeclaration, options); | ||
if (typeGuardName !== null) { | ||
records.push({ guardName: typeGuardName, typeDeclaration, outFile }); | ||
} | ||
} | ||
catch (e_4_1) { e_4 = { error: e_4_1 }; } | ||
finally { | ||
try { | ||
if (allTypesDeclarations_1_1 && !allTypesDeclarations_1_1.done && (_a = allTypesDeclarations_1.return)) _a.call(allTypesDeclarations_1); | ||
for (const typeDeclaration of allTypesDeclarations) { | ||
const typeGuardName = getTypeGuardName(typeDeclaration, options); | ||
if (typeGuardName !== null) { | ||
functions.push(generateTypeGuard(typeGuardName, typeDeclaration, addDependency, project, records, outFile, options)); | ||
addDependency(sourceFile, typeDeclaration.getName(), typeDeclaration.isDefaultExport()); | ||
} | ||
finally { if (e_4) throw e_4.error; } | ||
} | ||
try { | ||
for (var allTypesDeclarations_2 = __values(allTypesDeclarations), allTypesDeclarations_2_1 = allTypesDeclarations_2.next(); !allTypesDeclarations_2_1.done; allTypesDeclarations_2_1 = allTypesDeclarations_2.next()) { | ||
var typeDeclaration = allTypesDeclarations_2_1.value; | ||
var typeGuardName = getTypeGuardName(typeDeclaration, options); | ||
if (typeGuardName !== null) { | ||
functions.push(generateTypeGuard(typeGuardName, typeDeclaration, addDependency, project, records, outFile, options)); | ||
addDependency(sourceFile, typeDeclaration.getName(), typeDeclaration.isDefaultExport()); | ||
} | ||
} | ||
} | ||
catch (e_5_1) { e_5 = { error: e_5_1 }; } | ||
finally { | ||
try { | ||
if (allTypesDeclarations_2_1 && !allTypesDeclarations_2_1.done && (_b = allTypesDeclarations_2.return)) _b.call(allTypesDeclarations_2); | ||
} | ||
finally { if (e_5) throw e_5.error; } | ||
} | ||
if (functions.length > 0) { | ||
@@ -765,33 +608,17 @@ if (options.debug) { | ||
outFile.addStatements(functions.join('\n')); | ||
// Memoize imports within local source file | ||
var importsMap_1 = new Map(); | ||
var _loop_1 = function (impDeclaration) { | ||
impDeclaration.getNamedImports().forEach(function (impSpecifier) { | ||
importsMap_1.set(impSpecifier.getText(), impDeclaration.getModuleSpecifierValue()); | ||
const importsMap = new Map(); | ||
for (const impDeclaration of sourceFile.getImportDeclarations()) { | ||
impDeclaration.getNamedImports().forEach(impSpecifier => { | ||
importsMap.set(impSpecifier.getText(), impDeclaration.getModuleSpecifierValue()); | ||
}); | ||
}; | ||
try { | ||
for (var _d = __values(sourceFile.getImportDeclarations()), _e = _d.next(); !_e.done; _e = _d.next()) { | ||
var impDeclaration = _e.value; | ||
_loop_1(impDeclaration); | ||
} | ||
} | ||
catch (e_6_1) { e_6 = { error: e_6_1 }; } | ||
finally { | ||
try { | ||
if (_e && !_e.done && (_c = _d.return)) _c.call(_d); | ||
} | ||
finally { if (e_6) throw e_6.error; } | ||
} | ||
outFile.addImportDeclarations(Array.from(dependencies.entries()).reduce(function (structures, _a) { | ||
var _b = __read(_a, 2), importFile = _b[0], imports = _b[1]; | ||
outFile.addImportDeclarations(Array.from(dependencies.entries()).reduce((structures, [importFile, imports]) => { | ||
if (outFile === importFile) { | ||
return structures; | ||
} | ||
var moduleSpecifier = outFile.getRelativePathAsModuleSpecifierTo(importFile) + | ||
let moduleSpecifier = outFile.getRelativePathAsModuleSpecifierTo(importFile) + | ||
importExtension; | ||
if (importFile.isInNodeModules()) { | ||
// Packages within node_modules should not be referenced via relative path | ||
for (var im in imports) { | ||
var importDeclaration = importsMap_1.get(im); | ||
for (const im in imports) { | ||
const importDeclaration = importsMap.get(im); | ||
if (importDeclaration) { | ||
@@ -802,25 +629,22 @@ moduleSpecifier = importDeclaration; | ||
} | ||
var defaultImport = imports.default; | ||
const defaultImport = imports.default; | ||
delete imports.default; | ||
var namedImports = Object.entries(imports).map(function (_a) { | ||
var _b = __read(_a, 2), alias = _b[0], name = _b[1]; | ||
return alias === name ? name : { name: name, alias: alias }; | ||
}); | ||
const namedImports = Object.entries(imports).map(([alias, name]) => alias === name ? name : { name, alias }); | ||
structures.push({ | ||
defaultImport: defaultImport, | ||
defaultImport, | ||
kind: ts_morph_1.StructureKind.ImportDeclaration, | ||
moduleSpecifier: moduleSpecifier, | ||
namedImports: namedImports, | ||
moduleSpecifier, | ||
namedImports, | ||
}); | ||
return structures; | ||
}, [])); | ||
var path = outFile.getRelativePathTo(sourceFile); | ||
const path = outFile.getRelativePathTo(sourceFile); | ||
outFile.insertStatements(0, [ | ||
"/*", | ||
" * Generated type guards for \"".concat(path, "\"."), | ||
" * ".concat(GENERATED_WARNING), | ||
" */", | ||
`/*`, | ||
` * Generated type guards for "${path}".`, | ||
` * ${GENERATED_WARNING}`, | ||
` */`, | ||
].join('\n')); | ||
if (options.importGuards) { | ||
var relativeOutPath = './' + | ||
const relativeOutPath = './' + | ||
outFile | ||
@@ -830,14 +654,14 @@ .getFilePath() | ||
.reverse()[0] | ||
.replace(/\.(ts|tsx|d\.ts)$/, ''); | ||
var importStatement = "import * as ".concat(options.importGuards, " from \"").concat(relativeOutPath).concat(importExtension, "\";"); | ||
var exportStatement = "export { ".concat(options.importGuards, " };"); | ||
var _f = sourceFile | ||
.replace(fileExtensionRegex, ''); | ||
const importStatement = `import * as ${options.importGuards} from "${relativeOutPath}${importExtension}";`; | ||
const exportStatement = `export { ${options.importGuards} };`; | ||
const { hasImport, hasExport, statements } = sourceFile | ||
.getStatements() | ||
.reduce(function (reduced, node) { | ||
var nodeText = node.getText().replace(/\s{2,}/g, ' '); | ||
reduced.hasImport || (reduced.hasImport = nodeText.includes("import * as ".concat(options.importGuards).concat(importExtension))); | ||
reduced.hasExport || (reduced.hasExport = nodeText.includes("export { ".concat(options.importGuards, " }"))); | ||
.reduce((reduced, node) => { | ||
const nodeText = node.getText().replace(/\s{2,}/g, ' '); | ||
reduced.hasImport ||= nodeText.includes(`import * as ${options.importGuards}${importExtension}`); | ||
reduced.hasExport ||= nodeText.includes(`export { ${options.importGuards} }`); | ||
reduced.statements += 1; | ||
return reduced; | ||
}, { hasImport: false, hasExport: false, statements: 0 }), hasImport = _f.hasImport, hasExport = _f.hasExport, statements = _f.statements; | ||
}, { hasImport: false, hasExport: false, statements: 0 }); | ||
if (!hasImport) { | ||
@@ -853,3 +677,2 @@ sourceFile.insertStatements(0, importStatement); | ||
else { | ||
// This guard file is empty. We did not know that until after the file was created, but at least we can clean it up. | ||
outFile.delete(); | ||
@@ -856,0 +679,0 @@ } |
{ | ||
"name": "ts-auto-guard", | ||
"version": "4.2.0", | ||
"version": "5.0.0", | ||
"description": "Generate type guard functions from TypeScript interfaces", | ||
@@ -9,8 +9,10 @@ "homepage": "https://github.com/rhys-vdw/ts-auto-guard", | ||
"scripts": { | ||
"test": "cross-env NODE_ENV=test && npm run lint && npm run format:check && tape -r ts-node/register tests/**/*.test.ts | tap-diff", | ||
"pretest": "npm run-script lint && npm run-script format:check", | ||
"test": "tape -r ts-node/register tests/**/*.test.ts | tap-diff", | ||
"build": "tsc", | ||
"prepare": "npm run build", | ||
"build:prod": "tsc --sourceMap false", | ||
"lint": "eslint .", | ||
"format": "eslint --fix --ext ts && prettier --write *.json *.js *.yml src/**/*.ts tests/**/*.ts .github/**/*.yml", | ||
"format:check": "prettier --list-different *.json *.js *.yml src/**/*.ts tests/**/*.ts .github/**/*.yml" | ||
"preformat": "eslint --fix", | ||
"format": "prettier --write **/*.yml src/**/*.ts tests/**/*.ts", | ||
"format:check": "prettier --list-different **/*.yml src/**/*.ts tests/**/*.ts" | ||
}, | ||
@@ -23,5 +25,5 @@ "bin": { | ||
"dependencies": { | ||
"command-line-args": "^5.1.1", | ||
"command-line-usage": "^6.1.0", | ||
"ts-morph": "^16.0.0", | ||
"command-line-args": "^5.2.1", | ||
"command-line-usage": "^7.0.1", | ||
"ts-morph": "^22.0.0", | ||
"tsconfig": "^7.0.0" | ||
@@ -31,17 +33,15 @@ }, | ||
"@detools/tap-diff": "^0.2.2", | ||
"@types/command-line-args": "^5.0.0", | ||
"@types/command-line-usage": "^5.0.1", | ||
"@types/node": "^18.11.9", | ||
"@types/tape": "^4.13.0", | ||
"@types/uglify-js": "^3.11.1", | ||
"@typescript-eslint/eslint-plugin": "^5.42.1", | ||
"@typescript-eslint/parser": "^5.42.1", | ||
"cross-env": "^7.0.2", | ||
"eslint": "~8.27.0", | ||
"prettier": "^2.7.1", | ||
"tape": "^5.0.1", | ||
"ts-node": "^10.9.1", | ||
"typescript": "^4.8.4", | ||
"uglify-js": "^3.11.4" | ||
"@types/command-line-args": "^5.2.3", | ||
"@types/command-line-usage": "^5.0.4", | ||
"@types/node": "^20.14.2", | ||
"@types/tape": "^5.6.4", | ||
"@types/uglify-js": "^3.17.5", | ||
"eslint": "^8.57.0", | ||
"prettier": "^3.3.1", | ||
"tape": "^5.7.5", | ||
"ts-node": "^10.9.2", | ||
"typescript": "^5.4.5", | ||
"typescript-eslint": "^7.12.0", | ||
"uglify-js": "^3.17.4" | ||
} | ||
} |
# ts-auto-guard | ||
[![Greenkeeper badge](https://badges.greenkeeper.io/usabilityhub/ts-auto-guard.svg)](https://greenkeeper.io/) | ||
[![NPM Version](https://img.shields.io/npm/v/ts-auto-guard)](https://www.npmjs.com/package/ts-auto-guard) [![Test](https://github.com/rhys-vdw/ts-auto-guard/actions/workflows/test.yml/badge.svg)](https://github.com/rhys-vdw/ts-auto-guard/actions/workflows/test.yml) | ||
@@ -209,2 +209,1 @@ > Generate type guard functions from TypeScript interfaces | ||
``` | ||
{ | ||
"compilerOptions": { | ||
/* Basic Options */ | ||
"target": "es5" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */, | ||
"module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */, | ||
"lib": [ | ||
"ES2019.Array" | ||
] /* Specify library files to be included in the compilation. */, | ||
// "allowJs": true, /* Allow javascript files to be compiled. */ | ||
// "checkJs": true, /* Report errors in .js files. */ | ||
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ | ||
"declaration": true /* Generates corresponding '.d.ts' file. */, | ||
"declarationMap": true /* Generates a sourcemap for each corresponding '.d.ts' file. */, | ||
"sourceMap": true /* Generates corresponding '.map' file. */, | ||
// "outFile": "./", /* Concatenate and emit output to single file. */ | ||
"outDir": "./lib" /* Redirect output structure to the directory. */, | ||
"rootDirs": [ | ||
"./src" | ||
] /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */, | ||
// "composite": true, /* Enable project compilation */ | ||
// "removeComments": true, /* Do not emit comments to output. */ | ||
// "noEmit": true, /* Do not emit outputs. */ | ||
// "importHelpers": true, /* Import emit helpers from 'tslib'. */ | ||
"downlevelIteration": true /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */, | ||
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ | ||
/* Visit https://aka.ms/tsconfig to read more about this file */ | ||
/* Strict Type-Checking Options */ | ||
"strict": true /* Enable all strict type-checking options. */, | ||
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ | ||
// "strictNullChecks": true, /* Enable strict null checks. */ | ||
// "strictFunctionTypes": true, /* Enable strict checking of function types. */ | ||
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ | ||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ | ||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ | ||
/* Projects */ | ||
// "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ | ||
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ | ||
// "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ | ||
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ | ||
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ | ||
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ | ||
/* Additional Checks */ | ||
"noUnusedLocals": true /* Report errors on unused locals. */, | ||
"noUnusedParameters": true /* Report errors on unused parameters. */, | ||
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ | ||
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ | ||
/* Language and Environment */ | ||
"target": "ES2022", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ | ||
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ | ||
// "jsx": "preserve", /* Specify what JSX code is generated. */ | ||
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ | ||
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ | ||
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ | ||
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ | ||
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ | ||
// "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ | ||
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ | ||
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ | ||
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ | ||
/* Module Resolution Options */ | ||
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ | ||
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ | ||
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ | ||
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ | ||
// "typeRoots": [], /* List of folders to include type definitions from. */ | ||
// "types": [], /* Type declaration files to be included in compilation. */ | ||
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ | ||
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ | ||
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ | ||
/* Modules */ | ||
"module": "commonjs", /* Specify what module code is generated. */ | ||
"rootDir": "./src", /* Specify the root folder within your source files. */ | ||
// "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ | ||
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ | ||
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ | ||
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ | ||
// "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ | ||
// "types": [], /* Specify type package names to be included without being referenced in a source file. */ | ||
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ | ||
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ | ||
// "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ | ||
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ | ||
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ | ||
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ | ||
// "resolveJsonModule": true, /* Enable importing .json files. */ | ||
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ | ||
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */ | ||
/* Source Map Options */ | ||
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ | ||
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ | ||
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ | ||
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ | ||
/* JavaScript Support */ | ||
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ | ||
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ | ||
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ | ||
/* Experimental Options */ | ||
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ | ||
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ | ||
/* Emit */ | ||
"declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ | ||
// "declarationMap": true, /* Create sourcemaps for d.ts files. */ | ||
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ | ||
"sourceMap": true, /* Create source map files for emitted JavaScript files. */ | ||
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ | ||
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ | ||
"outDir": "./lib", /* Specify an output folder for all emitted files. */ | ||
"removeComments": true, /* Disable emitting comments. */ | ||
// "noEmit": true, /* Disable emitting files from a compilation. */ | ||
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ | ||
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ | ||
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ | ||
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ | ||
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ | ||
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ | ||
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ | ||
// "newLine": "crlf", /* Set the newline character for emitting files. */ | ||
// "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ | ||
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ | ||
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ | ||
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ | ||
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */ | ||
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ | ||
/* Interop Constraints */ | ||
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ | ||
// "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ | ||
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ | ||
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ | ||
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ | ||
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ | ||
/* Type Checking */ | ||
"strict": true, /* Enable all strict type-checking options. */ | ||
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ | ||
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ | ||
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ | ||
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ | ||
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ | ||
// "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ | ||
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ | ||
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ | ||
"noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ | ||
"noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ | ||
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ | ||
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ | ||
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ | ||
// "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ | ||
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ | ||
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ | ||
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ | ||
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ | ||
/* Completeness */ | ||
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ | ||
"skipLibCheck": true /* Skip type checking all .d.ts files. */ | ||
}, | ||
@@ -63,0 +109,0 @@ "exclude": ["./tests"], |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
13
83924
10
933
209
2
+ Added@ts-morph/common@0.23.0(transitive)
+ Addedansi-styles@4.3.0(transitive)
+ Addedarray-back@6.2.2(transitive)
+ Addedchalk@4.1.2(transitive)
+ Addedchalk-template@0.4.0(transitive)
+ Addedcode-block-writer@13.0.3(transitive)
+ Addedcolor-convert@2.0.1(transitive)
+ Addedcolor-name@1.1.4(transitive)
+ Addedcommand-line-usage@7.0.3(transitive)
+ Addedhas-flag@4.0.0(transitive)
+ Addedminimatch@9.0.5(transitive)
+ Addedmkdirp@3.0.1(transitive)
+ Addedsupports-color@7.2.0(transitive)
+ Addedtable-layout@4.1.1(transitive)
+ Addedts-morph@22.0.0(transitive)
+ Addedtypical@7.3.0(transitive)
+ Addedwordwrapjs@5.1.0(transitive)
- Removed@ts-morph/common@0.17.0(transitive)
- Removedansi-styles@3.2.1(transitive)
- Removedarray-back@4.0.2(transitive)
- Removedchalk@2.4.2(transitive)
- Removedcode-block-writer@11.0.3(transitive)
- Removedcolor-convert@1.9.3(transitive)
- Removedcolor-name@1.1.3(transitive)
- Removedcommand-line-usage@6.1.3(transitive)
- Removeddeep-extend@0.6.0(transitive)
- Removedescape-string-regexp@1.0.5(transitive)
- Removedhas-flag@3.0.0(transitive)
- Removedminimatch@5.1.6(transitive)
- Removedmkdirp@1.0.4(transitive)
- Removedreduce-flatten@2.0.0(transitive)
- Removedsupports-color@5.5.0(transitive)
- Removedtable-layout@1.0.2(transitive)
- Removedts-morph@16.0.0(transitive)
- Removedtypical@5.2.0(transitive)
- Removedwordwrapjs@4.0.1(transitive)
Updatedcommand-line-args@^5.2.1
Updatedcommand-line-usage@^7.0.1
Updatedts-morph@^22.0.0