New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

ts-auto-guard

Package Overview
Dependencies
Maintainers
2
Versions
48
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ts-auto-guard - npm Package Compare versions

Comparing version 4.2.0 to 5.0.0

1

lib/cli.d.ts

@@ -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
"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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc