Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

kmore-types

Package Overview
Dependencies
Maintainers
1
Versions
175
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

kmore-types - npm Package Compare versions

Comparing version 0.3.0 to 0.4.0

2

CHANGELOG.md

@@ -5,2 +5,4 @@ # Changelog

## [0.4.0](https://github.com/waitingsong/kmore-types/compare/v0.3.0...v0.4.0) (2019-08-13)
## [0.3.0](https://github.com/waitingsong/kmore-types/compare/v0.2.0...v0.3.0) (2019-08-12)

@@ -7,0 +9,0 @@

117

dist/index.cjs.js

@@ -5,3 +5,3 @@ /**

*
* @version 0.3.0
* @version 0.4.0
* @author waiting

@@ -23,16 +23,8 @@ * @license MIT

const initOptions = {
callerFuncNames: ['genTbListFromType', 'kmore'],
exportVarPrefix: 'tbs',
forceLoadTbListJs: false,
forceLoadTbListJsPathReplaceRules: null,
outputBanner: '/* eslint-disable */',
outputFileNameSuffix: '__built-tables',
refTablesPrefix: 'reftb_',
const globalCallerFuncNameSet = new Set(['genTbListFromType', 'kmore']);
const initGenTbListFromTypeOpts = {
callerDistance: 0,
};
const initOptions = Object.assign({}, initGenTbListFromTypeOpts, { exportVarPrefix: 'tbs', forceLoadTbListJs: false, forceLoadTbListJsPathReplaceRules: null, outputBanner: '/* eslint-disable */', outputFileNameSuffix: '__built-tables', refTablesPrefix: 'reftb_' });
const initBuildSrcOpts = Object.assign({}, initOptions, { path: [], concurrent: 5 });
const initGenTbListFromTypeOpts = {
callerFuncNames: initOptions.callerFuncNames,
stackDepth: 1,
};
const reservedTbListKeys = [

@@ -61,2 +53,3 @@ 'constructor',

/** Allow empty Object */
function validateParamTables(tbs) {

@@ -119,3 +112,4 @@ if (tbs === null) {

*/
function getCallerStack(depth = 1) {
function getCallerStack(callerDistance = 0) {
const depth = callerDistance + 2;
// Save original Error.prepareStackTrace

@@ -134,3 +128,3 @@ const origPrepareStackTrace = Error.prepareStackTrace;

Error.prepareStackTrace = function (_err, stack) {
const target = stack[depth + 1];
const target = stack[depth];
// @ts-ignore

@@ -140,3 +134,3 @@ return patchedPrepareStackTrace(_err, [target]);

const limit = Error.stackTraceLimit;
Error.stackTraceLimit = depth + 2;
Error.stackTraceLimit = depth + 3;
const err = new Error();

@@ -186,12 +180,15 @@ const { stack } = err;

}
function isCallerNameMatched(name, matchFuncName) {
function isCallerNameMatched(name, matchFuncNameSet) {
if (!name) {
return false;
}
else if (typeof matchFuncName === 'string' && matchFuncName === name) {
else if (matchFuncNameSet.has(name)) {
return true;
}
else if (Array.isArray(matchFuncName) && matchFuncName.includes(name)) {
return true;
}
// else if (typeof matchFuncNameSet === 'string' && matchFuncNameSet === name) {
// return true
// }
// else if (Array.isArray(matchFuncNameSet) && matchFuncNameSet.includes(name)) {
// return true
// }
else {

@@ -241,3 +238,3 @@ return false;

const opts = Object.assign({}, initBuildSrcOpts, options);
const { path: baseDir } = opts;
const { path: basePath } = opts;
const maxDepth = 99;

@@ -247,7 +244,8 @@ const concurrent = opts.concurrent && opts.concurrent > 0

: 5;
const matchFuncNameSet = new Set(globalCallerFuncNameSet);
const dir$ = rxjs.iif(() => {
if (typeof baseDir === 'string') {
if (typeof basePath === 'string') {
return true;
}
else if (Array.isArray(baseDir)) {
else if (Array.isArray(basePath)) {
return false;

@@ -258,7 +256,7 @@ }

}
}, rxjs.of(baseDir), rxjs.from(baseDir));
}, rxjs.of(basePath), rxjs.from(basePath));
const path$ = dir$.pipe(operators.mergeMap(path => rxwalker.walk(path, { maxDepth }), concurrent), operators.filter(ev => ev.type === "file" /* file */
&& ev.path.endsWith('.ts')
&& !ev.path.endsWith('.d.ts')), operators.map(ev => ev.path), operators.mergeMap((path) => {
const flag$ = ifFileContainsCallerFuncNames(path, opts.callerFuncNames);
const flag$ = ifFileContainsCallerFuncNames(matchFuncNameSet, path);
return flag$.pipe(operators.map((contains) => {

@@ -270,3 +268,3 @@ return contains ? path : '';

}
function ifFileContainsCallerFuncNames(path, callerFuncNames) {
function ifFileContainsCallerFuncNames(matchFuncNameSet, path) {
const file$ = rxjs.defer(() => sharedCore.readFileAsync(path));

@@ -276,24 +274,34 @@ const ret$ = file$.pipe(operators.map((buf) => {

return ret;
}), operators.filter((buf) => {
}), operators.map((buf) => {
const code = buf.toString();
return isContainsCallerFuncNames(code, callerFuncNames);
}), operators.mapTo(true), operators.catchError(() => rxjs.of(false)));
return hasContainsCallerFuncNames(matchFuncNameSet, code);
}), operators.catchError(() => rxjs.of(false)));
return ret$;
}
function isContainsCallerFuncNames(content, callerFuncNames) {
if (!content) {
return false;
}
else if (typeof callerFuncNames === 'string') {
return content.includes(callerFuncNames);
}
else {
for (const name of callerFuncNames) {
if (content.includes(name)) {
function hasContainsCallerFuncNames(matchFuncNameSet, content) {
if (content) {
for (const key of matchFuncNameSet.keys()) {
if (content.includes(key)) {
return true;
}
}
return false;
}
return false;
}
function parseCallerFuncNames(callerFuncNameSet, names) {
const st = new Set(callerFuncNameSet);
if (!names) {
return st;
}
else if (typeof names === 'string') {
st.add(names);
}
else if (Array.isArray(names) && names.length) {
names.forEach(name => st.add(name));
}
else {
throw new TypeError('Value of param invalid.');
}
return st;
}

@@ -409,2 +417,3 @@ // eslint-disable-next-line import/no-extraneous-dependencies

}
/** Retrieve node with specified position from caller */
function walkNodeWithPosition(options) {

@@ -419,6 +428,3 @@ const visit = (node, opts) => {

if (expression) {
const matched = isCallerNameMatched(expression.getText(), options.matchFuncName);
if (matched) {
return node;
}
return node;
}

@@ -437,2 +443,3 @@ return; // stop walk

}
/** Retrieve node with specified matchFuncName */
function walkNode(options) {

@@ -447,3 +454,3 @@ const ret = new Set();

/* istanbul ignore else */
if (isCallerNameMatched(expression.getText(), options.matchFuncName)) {
if (isCallerNameMatched(expression.getText(), options.matchFuncNameSet)) {
ret.add(node);

@@ -494,3 +501,3 @@ return;

sourceFile,
matchFuncName: initOptions.callerFuncNames,
matchFuncNameSet: globalCallerFuncNameSet,
});

@@ -537,5 +544,5 @@ const callerTypeMap = genCallerTypeMapFromNodeSet(nodeSet, checker, sourceFile, path);

? Object.assign({}, initGenTbListFromTypeOpts, options) : Object.assign({}, initGenTbListFromTypeOpts);
const depth = typeof opts.stackDepth === 'number' && opts.stackDepth > 0
? opts.stackDepth
: 1;
const depth = typeof opts.callerDistance === 'number' && opts.callerDistance > 0
? opts.callerDistance
: 0;
const caller = getCallerStack(depth);

@@ -550,3 +557,3 @@ if (isTsFile(caller.path)) {

function genTbListFromCaller(caller, options) {
const opts = Object.assign({ callerFuncNames: initOptions.callerFuncNames }, options ? options : {}, { caller, cacheMap: cacheMap });
const opts = Object.assign({ callerDistance: initOptions.callerDistance }, options ? options : {}, { caller, cacheMap: cacheMap });
const callerId = `${caller.path}:${caller.line}:${caller.column}`;

@@ -605,3 +612,3 @@ const localTypeId = opts.cacheMap.callerIdToLocalTypeIdMap.get(callerId);

const retMap = new Map();
const { cacheMap, sourceFile, checker, caller, callerFuncNames: callerFuncName, } = options;
const { cacheMap, sourceFile, checker, caller, } = options;
const node = walkNodeWithPosition({

@@ -611,3 +618,3 @@ sourceFile,

matchColumn: caller.column,
matchFuncName: callerFuncName,
matchFuncNameSet: globalCallerFuncNameSet,
});

@@ -668,2 +675,4 @@ /* istanbul ignore else */

exports.getCallerStack = getCallerStack;
exports.globalCallerFuncNameSet = globalCallerFuncNameSet;
exports.hasContainsCallerFuncNames = hasContainsCallerFuncNames;
exports.ifFileContainsCallerFuncNames = ifFileContainsCallerFuncNames;

@@ -674,3 +683,2 @@ exports.initBuildSrcOpts = initBuildSrcOpts;

exports.isCallerNameMatched = isCallerNameMatched;
exports.isContainsCallerFuncNames = isContainsCallerFuncNames;
exports.isTsFile = isTsFile;

@@ -680,2 +688,3 @@ exports.loadFile = loadFile;

exports.matchSourceFileWithFilePath = matchSourceFileWithFilePath;
exports.parseCallerFuncNames = parseCallerFuncNames;
exports.pickInfoFromCallerTypeId = pickInfoFromCallerTypeId;

@@ -682,0 +691,0 @@ exports.reWriteLoadingPath = reWriteLoadingPath;

@@ -5,3 +5,3 @@ import { pathResolve, writeFileAsync } from '@waiting/shared-core';

import { buildTbListParam, genTbListTsFilePath, genVarName, walkDirForCallerFuncTsFiles, } from './util';
import { initOptions, initBuildSrcOpts } from './config';
import { initBuildSrcOpts, globalCallerFuncNameSet } from './config';
import { pickInfoFromCallerTypeId, genCallerTypeMapFromNodeSet, matchSourceFileWithFilePath, walkNode, } from './ts-util';

@@ -39,3 +39,3 @@ export function buildSource(options) {

sourceFile,
matchFuncName: initOptions.callerFuncNames,
matchFuncNameSet: globalCallerFuncNameSet,
});

@@ -42,0 +42,0 @@ const callerTypeMap = genCallerTypeMapFromNodeSet(nodeSet, checker, sourceFile, path);

import { buildTbListParam, isTsFile, getCallerStack } from './util';
import { genTbListTagMapFromSymbol, retrieveGenericsIdentifierFromTypeArguments, matchSourceFileWithFilePath, walkNodeWithPosition, } from './ts-util';
import { cacheMap as cacheMapTop, initOptions, initGenTbListFromTypeOpts } from './config';
import { cacheMap as cacheMapTop, initOptions, initGenTbListFromTypeOpts, globalCallerFuncNameSet } from './config';
/**

@@ -10,5 +10,5 @@ * Generate DbTables from generics type T

? Object.assign({}, initGenTbListFromTypeOpts, options) : Object.assign({}, initGenTbListFromTypeOpts);
const depth = typeof opts.stackDepth === 'number' && opts.stackDepth > 0
? opts.stackDepth
: 1;
const depth = typeof opts.callerDistance === 'number' && opts.callerDistance > 0
? opts.callerDistance
: 0;
const caller = getCallerStack(depth);

@@ -23,3 +23,3 @@ if (isTsFile(caller.path)) {

export function genTbListFromCaller(caller, options) {
const opts = Object.assign({ callerFuncNames: initOptions.callerFuncNames }, options ? options : {}, { caller, cacheMap: cacheMapTop });
const opts = Object.assign({ callerDistance: initOptions.callerDistance }, options ? options : {}, { caller, cacheMap: cacheMapTop });
const callerId = `${caller.path}:${caller.line}:${caller.column}`;

@@ -78,3 +78,3 @@ const localTypeId = opts.cacheMap.callerIdToLocalTypeIdMap.get(callerId);

const retMap = new Map();
const { cacheMap, sourceFile, checker, caller, callerFuncNames: callerFuncName, } = options;
const { cacheMap, sourceFile, checker, caller, } = options;
const node = walkNodeWithPosition({

@@ -84,3 +84,3 @@ sourceFile,

matchColumn: caller.column,
matchFuncName: callerFuncName,
matchFuncNameSet: globalCallerFuncNameSet,
});

@@ -87,0 +87,0 @@ /* istanbul ignore else */

@@ -1,5 +0,6 @@

import { CacheMap, Options, GenTbListFromTypeOpts, BuildSrcOpts } from './model';
import { BuildSrcOpts, CacheMap, CallerFuncNameSet, GenTbListFromTypeOpts, Options } from './model';
export declare const globalCallerFuncNameSet: CallerFuncNameSet;
export declare const initGenTbListFromTypeOpts: GenTbListFromTypeOpts;
export declare const initOptions: Options;
export declare const initBuildSrcOpts: Required<BuildSrcOpts>;
export declare const initGenTbListFromTypeOpts: GenTbListFromTypeOpts;
export declare const reservedTbListKeys: string[];

@@ -6,0 +7,0 @@ export declare enum DbPropKeys {

@@ -1,15 +0,7 @@

export const initOptions = {
callerFuncNames: ['genTbListFromType', 'kmore'],
exportVarPrefix: 'tbs',
forceLoadTbListJs: false,
forceLoadTbListJsPathReplaceRules: null,
outputBanner: '/* eslint-disable */',
outputFileNameSuffix: '__built-tables',
refTablesPrefix: 'reftb_',
export const globalCallerFuncNameSet = new Set(['genTbListFromType', 'kmore']);
export const initGenTbListFromTypeOpts = {
callerDistance: 0,
};
export const initOptions = Object.assign({}, initGenTbListFromTypeOpts, { exportVarPrefix: 'tbs', forceLoadTbListJs: false, forceLoadTbListJsPathReplaceRules: null, outputBanner: '/* eslint-disable */', outputFileNameSuffix: '__built-tables', refTablesPrefix: 'reftb_' });
export const initBuildSrcOpts = Object.assign({}, initOptions, { path: [], concurrent: 5 });
export const initGenTbListFromTypeOpts = {
callerFuncNames: initOptions.callerFuncNames,
stackDepth: 1,
};
export const reservedTbListKeys = [

@@ -16,0 +8,0 @@ 'constructor',

import * as ts from 'typescript';
export interface Options {
callerFuncNames: CallerFuncName | CallerFuncName[];
export interface Options extends GenTbListFromTypeOpts {
/** Exported vaiable name preifx. Default is "tbs", result will be "tbs_m_n" */

@@ -32,2 +31,8 @@ exportVarPrefix: string;

}
export declare type CallerFuncNameSet = Set<CallerFuncName>;
/**
* Name of the function
* calling genTbListFromType() or kmore() and pass with generics type
*/
export declare type CallerFuncName = string;
export declare type TTableListModel = object;

@@ -87,11 +92,8 @@ /**

}
export interface GenTbListFromFileOpts {
path: string;
typeName: string;
includePathKeyWords?: string | string[];
}
export interface GenTbListFromTypeOpts {
callerFuncNames: CallerFuncName | CallerFuncName[];
/** Default: 1 */
stackDepth?: number;
/**
* Distance from genTbListFromType() or kmore(),
* Default: 1
*/
callerDistance: number;
}

@@ -102,3 +104,2 @@ export interface RetrieveInfoFromTypeOpts extends GenTbListFromTypeOpts {

}
export declare type CallerFuncName = string;
export interface GenGenericsArgMapOpts extends RetrieveInfoFromTypeOpts {

@@ -124,3 +125,3 @@ checker: ts.TypeChecker;

sourceFile: ts.SourceFile;
matchFuncName: CallerFuncName | CallerFuncName[];
matchFuncNameSet: CallerFuncNameSet;
}

@@ -127,0 +128,0 @@ export interface WalkNodeWithPositionOps extends WalkNodeOps {

@@ -12,3 +12,5 @@ import * as ts from 'typescript';

export declare function matchSourceFileWithFilePath(path: string): MatchedSourceFile;
/** Retrieve node with specified position from caller */
export declare function walkNodeWithPosition(options: WalkNodeWithPositionOps): ts.CallExpression | void;
/** Retrieve node with specified matchFuncName */
export declare function walkNode(options: WalkNodeOps): Set<ts.CallExpression>;

@@ -113,2 +113,3 @@ // eslint-disable-next-line import/no-extraneous-dependencies

}
/** Retrieve node with specified position from caller */
export function walkNodeWithPosition(options) {

@@ -123,6 +124,3 @@ const visit = (node, opts) => {

if (expression) {
const matched = isCallerNameMatched(expression.getText(), options.matchFuncName);
if (matched) {
return node;
}
return node;
}

@@ -141,2 +139,3 @@ return; // stop walk

}
/** Retrieve node with specified matchFuncName */
export function walkNode(options) {

@@ -151,3 +150,3 @@ const ret = new Set();

/* istanbul ignore else */
if (isCallerNameMatched(expression.getText(), options.matchFuncName)) {
if (isCallerNameMatched(expression.getText(), options.matchFuncNameSet)) {
ret.add(node);

@@ -154,0 +153,0 @@ return;

import { Observable } from 'rxjs';
import { BuildSrcOpts, CallerInfo, CallerFuncName, DbTables, FilePath, Options, TbListTagMap, TTableListModel } from './model';
import { BuildSrcOpts, CallerInfo, CallerFuncName, DbTables, FilePath, Options, TbListTagMap, TTableListModel, CallerFuncNameSet } from './model';
/** Allow empty Object */
export declare function validateParamTables(tbs: unknown): void;

@@ -9,7 +10,7 @@ export declare function validateTbName(tb: string): void;

*/
export declare function getCallerStack(depth?: number): CallerInfo;
export declare function getCallerStack(callerDistance?: number): CallerInfo;
export declare function isTsFile(path: string): boolean;
/** Build DbTables from TableListTagMap */
export declare function buildTbListParam<T extends TTableListModel>(tagMap: TbListTagMap): DbTables<T>;
export declare function isCallerNameMatched(name: string, matchFuncName: CallerFuncName | CallerFuncName[]): boolean;
export declare function isCallerNameMatched(name: string, matchFuncNameSet: CallerFuncNameSet): boolean;
export declare function createNullObject(): any;

@@ -25,3 +26,4 @@ export declare function genTbListTsFilePath(path: string, outputFileNameSuffix: Options['outputFileNameSuffix']): FilePath;

export declare function walkDirForCallerFuncTsFiles(options: BuildSrcOpts): Observable<FilePath>;
export declare function ifFileContainsCallerFuncNames(path: FilePath, callerFuncNames: Options['callerFuncNames']): Observable<boolean>;
export declare function isContainsCallerFuncNames(content: string, callerFuncNames: Options['callerFuncNames']): boolean;
export declare function ifFileContainsCallerFuncNames(matchFuncNameSet: CallerFuncNameSet, path: FilePath): Observable<boolean>;
export declare function hasContainsCallerFuncNames(matchFuncNameSet: CallerFuncNameSet, content: string): boolean;
export declare function parseCallerFuncNames(callerFuncNameSet: CallerFuncNameSet, names: CallerFuncName | CallerFuncName[]): CallerFuncNameSet;
import * as sourceMapSupport from 'source-map-support';
import { walk } from 'rxwalker';
import { from as ofrom, defer, of, iif } from 'rxjs';
import { map, filter, mergeMap, catchError, mapTo } from 'rxjs/operators';
import { map, filter, mergeMap, catchError } from 'rxjs/operators';
import { readFileAsync } from '@waiting/shared-core';
import { defaultPropDescriptor, reservedTbListKeys, initBuildSrcOpts } from './config';
import { defaultPropDescriptor, reservedTbListKeys, initBuildSrcOpts, globalCallerFuncNameSet, } from './config';
/** Allow empty Object */
export function validateParamTables(tbs) {

@@ -64,3 +65,4 @@ if (tbs === null) {

*/
export function getCallerStack(depth = 1) {
export function getCallerStack(callerDistance = 0) {
const depth = callerDistance + 2;
// Save original Error.prepareStackTrace

@@ -79,3 +81,3 @@ const origPrepareStackTrace = Error.prepareStackTrace;

Error.prepareStackTrace = function (_err, stack) {
const target = stack[depth + 1];
const target = stack[depth];
// @ts-ignore

@@ -85,3 +87,3 @@ return patchedPrepareStackTrace(_err, [target]);

const limit = Error.stackTraceLimit;
Error.stackTraceLimit = depth + 2;
Error.stackTraceLimit = depth + 3;
const err = new Error();

@@ -131,12 +133,15 @@ const { stack } = err;

}
export function isCallerNameMatched(name, matchFuncName) {
export function isCallerNameMatched(name, matchFuncNameSet) {
if (!name) {
return false;
}
else if (typeof matchFuncName === 'string' && matchFuncName === name) {
else if (matchFuncNameSet.has(name)) {
return true;
}
else if (Array.isArray(matchFuncName) && matchFuncName.includes(name)) {
return true;
}
// else if (typeof matchFuncNameSet === 'string' && matchFuncNameSet === name) {
// return true
// }
// else if (Array.isArray(matchFuncNameSet) && matchFuncNameSet.includes(name)) {
// return true
// }
else {

@@ -186,3 +191,3 @@ return false;

const opts = Object.assign({}, initBuildSrcOpts, options);
const { path: baseDir } = opts;
const { path: basePath } = opts;
const maxDepth = 99;

@@ -192,7 +197,8 @@ const concurrent = opts.concurrent && opts.concurrent > 0

: 5;
const matchFuncNameSet = new Set(globalCallerFuncNameSet);
const dir$ = iif(() => {
if (typeof baseDir === 'string') {
if (typeof basePath === 'string') {
return true;
}
else if (Array.isArray(baseDir)) {
else if (Array.isArray(basePath)) {
return false;

@@ -203,7 +209,7 @@ }

}
}, of(baseDir), ofrom(baseDir));
}, of(basePath), ofrom(basePath));
const path$ = dir$.pipe(mergeMap(path => walk(path, { maxDepth }), concurrent), filter(ev => ev.type === "file" /* file */
&& ev.path.endsWith('.ts')
&& !ev.path.endsWith('.d.ts')), map(ev => ev.path), mergeMap((path) => {
const flag$ = ifFileContainsCallerFuncNames(path, opts.callerFuncNames);
const flag$ = ifFileContainsCallerFuncNames(matchFuncNameSet, path);
return flag$.pipe(map((contains) => {

@@ -215,3 +221,3 @@ return contains ? path : '';

}
export function ifFileContainsCallerFuncNames(path, callerFuncNames) {
export function ifFileContainsCallerFuncNames(matchFuncNameSet, path) {
const file$ = defer(() => readFileAsync(path));

@@ -221,23 +227,33 @@ const ret$ = file$.pipe(map((buf) => {

return ret;
}), filter((buf) => {
}), map((buf) => {
const code = buf.toString();
return isContainsCallerFuncNames(code, callerFuncNames);
}), mapTo(true), catchError(() => of(false)));
return hasContainsCallerFuncNames(matchFuncNameSet, code);
}), catchError(() => of(false)));
return ret$;
}
export function isContainsCallerFuncNames(content, callerFuncNames) {
if (!content) {
return false;
}
else if (typeof callerFuncNames === 'string') {
return content.includes(callerFuncNames);
}
else {
for (const name of callerFuncNames) {
if (content.includes(name)) {
export function hasContainsCallerFuncNames(matchFuncNameSet, content) {
if (content) {
for (const key of matchFuncNameSet.keys()) {
if (content.includes(key)) {
return true;
}
}
return false;
}
return false;
}
export function parseCallerFuncNames(callerFuncNameSet, names) {
const st = new Set(callerFuncNameSet);
if (!names) {
return st;
}
else if (typeof names === 'string') {
st.add(names);
}
else if (Array.isArray(names) && names.length) {
names.forEach(name => st.add(name));
}
else {
throw new TypeError('Value of param invalid.');
}
return st;
}
{
"name": "kmore-types",
"author": "waiting",
"version": "0.3.0",
"version": "0.4.0",
"description": "Retrieve types info from ts file",

@@ -6,0 +6,0 @@ "keywords": [

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