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

typed-path

Package Overview
Dependencies
Maintainers
1
Versions
14
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

typed-path - npm Package Compare versions

Comparing version 2.2.1 to 2.2.2

dist/index.d.ts

107

index.ts

@@ -0,20 +1,26 @@

export type TypedPathKey = string | symbol | number;
function appendStringPathChunk(path: string, chunk: TypedPathKey): string {
if (typeof chunk === 'number') {
return path + `[${chunk}]`;
} else {
return appendStringSymbolChunkToPath(path, chunk);
}
}
function appendStringSymbolChunkToPath(path: string, chunk: string | symbol) {
return path + (path === '' ? chunk.toString() : `.${chunk.toString()}`);
}
function pathToString(path: TypedPathKey[]): string {
return path.reduce<string>((current, next) => {
if (typeof next === 'number') {
current += `[${next}]`;
} else {
current += current === '' ? next.toString() : `.${next.toString()}`;
}
return current;
return appendStringPathChunk(current, next);
}, '');
}
export type TypedPathKey = string | symbol | number;
export type TypedPathFunction<ResultType> = (...args: any[]) => ResultType;
export type TypedPathFunction<T> = (...args: any[]) => T;
export type TypedPathHandlersConfig = Record<
string,
<T extends TypedPathHandlersConfig = Record<never, never>>(path: TypedPathKey[], additionalHandlers?: T) => any
<T extends TypedPathHandlersConfig>(path: TypedPathKey[], additionalHandlers?: T) => any
>;

@@ -35,53 +41,64 @@

export type TypedPathHandlers<T extends TypedPathHandlersConfig> = {
[key in keyof T]: ReturnType<T[key]>;
type DefaultHandlers = typeof defaultHandlersConfig;
export type TypedPathHandlers<ConfigType extends TypedPathHandlersConfig> = {
[key in keyof ConfigType]: ReturnType<ConfigType[key]>;
};
export type TypedPathWrapper<T, TPH extends TypedPathHandlers<Record<never, never>>> = (T extends Array<infer Z>
export type TypedPathWrapper<
OriginalType,
HandlersType extends TypedPathHandlers<Record<never, never>>
> = (OriginalType extends Array<infer OriginalArrayItemType>
? {
[index: number]: TypedPathWrapper<Z, TPH>;
[index: number]: TypedPathWrapper<OriginalArrayItemType, HandlersType>;
}
: T extends TypedPathFunction<infer RET>
: OriginalType extends TypedPathFunction<infer OriginalFunctionResultType>
? {
(): TypedPathWrapper<RET, TPH>;
(): TypedPathWrapper<OriginalFunctionResultType, HandlersType>;
} & {
[P in keyof Required<RET>]: TypedPathWrapper<RET[P], TPH>;
[P in keyof Required<OriginalFunctionResultType>]: TypedPathWrapper<
OriginalFunctionResultType[P],
HandlersType
>;
}
: {
[P in keyof Required<T>]: TypedPathWrapper<T[P], TPH>;
[P in keyof Required<OriginalType>]: TypedPathWrapper<OriginalType[P], HandlersType>;
}) &
TypedPathHandlers<TPH>;
TypedPathHandlers<HandlersType>;
const emptyObject = {};
export function typedPath<T, K extends TypedPathHandlersConfig = Record<never, never>>(
additionalHandlers?: K,
path: TypedPathKey[] = [],
defaultsApplied: boolean = false
): TypedPathWrapper<T, K & typeof defaultHandlersConfig> {
return <TypedPathWrapper<T, K & typeof defaultHandlersConfig>>new Proxy(emptyObject, {
get(target: T, name: TypedPathKey) {
let handlersConfig: TypedPathHandlersConfig;
function convertNumericKeyToNumber(key: TypedPathKey): TypedPathKey {
if (typeof key === 'string') {
const keyAsNumber = +key;
if (keyAsNumber === keyAsNumber) {
return keyAsNumber;
}
}
if (defaultsApplied) {
handlersConfig = additionalHandlers!;
} else {
handlersConfig = {...(additionalHandlers ?? {}), ...defaultHandlersConfig};
}
return key;
}
if (handlersConfig.hasOwnProperty(name)) {
return handlersConfig[name as any](path, additionalHandlers);
}
function getHandlerByNameKey<K extends TypedPathHandlersConfig>(name: TypedPathKey, additionalHandlers?: K) {
if (additionalHandlers?.hasOwnProperty(name)) {
return additionalHandlers[name as string];
}
let newChunk = name;
if (defaultHandlersConfig[name as keyof typeof defaultHandlersConfig]) {
return defaultHandlersConfig[name as keyof typeof defaultHandlersConfig];
}
}
if (typeof newChunk === 'string') {
const nameAsNumber = +newChunk;
if (nameAsNumber === nameAsNumber) {
newChunk = nameAsNumber;
}
}
const emptyObject = {};
export function typedPath<OriginalObjectType, HandlersType extends TypedPathHandlersConfig = Record<never, never>>(
additionalHandlers?: HandlersType,
path: TypedPathKey[] = []
): TypedPathWrapper<OriginalObjectType, HandlersType & DefaultHandlers> {
return <TypedPathWrapper<OriginalObjectType, HandlersType & DefaultHandlers>>new Proxy(emptyObject, {
get(target: unknown, name: TypedPathKey) {
const handler = getHandlerByNameKey(name, additionalHandlers);
return typedPath(handlersConfig, [...path, newChunk], true);
return handler
? handler(path, additionalHandlers)
: typedPath(additionalHandlers, [...path, convertNumericKeyToNumber(name)]);
}
});
}
{
"name": "typed-path",
"version": "2.2.1",
"version": "2.2.2",
"description": "Type safe object string paths for typescript.",
"main": "index.js",
"main": "dist/index.js",
"repository": {

@@ -27,13 +27,15 @@ "type": "git",

"index.ts",
"index.js",
"index.js.map",
"index.d.ts"
"dist/index.js",
"dist/index.js.map",
"dist/index.d.ts"
],
"types": "dist/index.d.ts",
"scripts": {
"test": "jest index.spec.ts",
"test": "yarn tsdlint && jest index.spec.ts",
"lint": "tslint 'src/**/*.ts' 'src/**/*.tsx'",
"tsdlint": "yarn build && tsd",
"format": "prettier --parser typescript --write index.ts index.spec.ts",
"prepush": "yarn lint && yarn build && git diff --exit-code",
"prepush": "yarn prepare",
"prepare": "yarn test && yarn build",
"build": "tsc"
"build": "tsc -p tsconfig.dist.json"
},

@@ -46,5 +48,9 @@ "devDependencies": {

"ts-node": "^9.0.0",
"tsd": "^0.13.1",
"tslint": "^4.4.2",
"typescript": "^4.0.5"
},
"tsd": {
"directory": "dist"
}
}

@@ -6,3 +6,3 @@ # Typed Path

[![Travis](https://img.shields.io/travis/bsalex/typed-path)](https://travis-ci.org/github/bsalex/typed-path)
[![HitCount](http://hits.dwyl.com/bsalex/typed-path.svg)](http://hits.dwyl.com/bsalex/typed-path)
[![Hits](https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https%3A%2F%2Fgithub.com%2Fbsalex%2Ftyped-path&count_bg=%2379C83D&title_bg=%23555555&icon=&icon_color=%23E7E7E7&title=hits&edge_flat=false)](https://hits.seeyoufarm.com)
[![Contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/bsalex/typed-path/issues)

@@ -14,19 +14,46 @@ ![GitHub top language](https://img.shields.io/github/languages/top/bsalex/typed-path)

![Snyk Vulnerabilities for GitHub Repo](https://img.shields.io/snyk/vulnerabilities/github/bsalex/typed-path)
![GitHub issues](https://img.shields.io/github/issues/bsalex/typed-path)
![Code Climate maintainability](https://img.shields.io/codeclimate/maintainability-percentage/bsalex/typed-path)
![Code Climate technical debt](https://img.shields.io/codeclimate/tech-debt/bsalex/typed-path)
[![GitHub issues](https://img.shields.io/github/issues/bsalex/typed-path)](https://github.com/bsalex/typed-path/issues)
[![Code Climate maintainability](https://img.shields.io/codeclimate/maintainability-percentage/bsalex/typed-path)](https://codeclimate.com/github/bsalex/typed-path/)
[![Code Climate technical debt](https://img.shields.io/codeclimate/tech-debt/bsalex/typed-path)](https://codeclimate.com/github/bsalex/typed-path/)
[![codecov](https://codecov.io/gh/bsalex/typed-path/branch/master/graph/badge.svg?token=uzpVtSWKbv)](https://codecov.io/gh/bsalex/typed-path)
---
## Overview
## Problem
This small utility helps to extract type information from a TypeScript class, interface or type to use it in your code.
Types are lost when string paths are used in typescript.
I.e., `_.get, _.map, _.set, R.pluck` from libraries like [lodash](https://lodash.com), [ramda](http://ramdajs.com/).
It makes those methods dangerous in case of refactoring, the same as JavaScript.
Example:
![](https://res.cloudinary.com/daren64mz/image/upload/v1487457505/string-refactoring_x2tubt.gif)
```js
import {typedPath} from 'typed-path';
type TestType = {
a: {
testFunc: () => {result: string};
b: {
arrayOfArrays: string[][];
c: {
d: number;
};
}[];
};
};
console.log(typedPath<TestType>().a.b[5].c.d.$rawPath);
/*
Outputs
["a", "b", 5, "c", "d"]
*/
```
Please see other path access methods and how to add custom path access methods below.
The utility might also be used to add type protection to such methods as `_.get, _.map, _.set, R.pluck` from libraries like [lodash](https://lodash.com), [ramda](http://ramdajs.com/).
**It is recommended, though, to use [optional chaining](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#optional-chaining) instead.**
---
## Solution
## Features

@@ -85,3 +112,3 @@ ### Errors

const testAdditionalHandlers = {
$url: (path: string[]) => path.join('/')
$url: (path: TypedPathKey[]) => path.join('/')
}

@@ -96,4 +123,5 @@

const testAdditionalHandlers = {
$abs: (path: string[]) => typedPath<TestType, typeof testAdditionalHandlers>(testAdditionalHandlers, ['', ...path]),
$url: (path: string[]) => path.join('/')
$abs: (path: TypedPathKey[]) => typedPath<TestType, typeof testAdditionalHandlers>(testAdditionalHandlers, ['', ...path]),
$url: (path: TypedPathKey[]) => path.join('/'),
$length: (path: TypedPathKey[]) => path.length
}

@@ -114,3 +142,3 @@

Copyright (c) 2020 Oleksandr Beshchuk <[bs.alex.mail@gmail.com](mailto:bs.alex.mail@gmail.com)>
Copyright (c) 2021 Oleksandr Beshchuk <[bs.alex.mail@gmail.com](mailto:bs.alex.mail@gmail.com)>
Licensed under the [Apache License](http://www.apache.org/licenses/LICENSE-2.0).

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