Socket
Socket
Sign inDemoInstall

@poppinss/utils

Package Overview
Dependencies
Maintainers
3
Versions
89
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@poppinss/utils - npm Package Compare versions

Comparing version 6.6.0 to 6.7.0

build/src/secret.d.ts

6

build/index.d.ts
/// <reference types="node" resolution-mode="require"/>
export { Secret } from './src/secret.js';
export { base64 } from './src/base64.js';

@@ -27,4 +28,5 @@ export { compose } from './src/compose.js';

/**
* Joins the given URL or string with additional path segments.
* Join paths to a URL instance or a URL string. The return
* value will be a file path without the `file:///` protocol.
*/
export declare function join(url: string | URL, ...str: string[]): string;
export declare function joinToURL(url: string | URL, ...str: string[]): string;

@@ -13,2 +13,42 @@ import {

// src/secret.ts
var REDACTED = "[redacted]";
var Secret = class _Secret {
/** The secret value */
#value;
#keyword;
constructor(value, redactedKeyword) {
this.#value = value;
this.#keyword = redactedKeyword || REDACTED;
}
toJSON() {
return this.#keyword;
}
valueOf() {
return this.#keyword;
}
[Symbol.for("nodejs.util.inspect.custom")]() {
return this.#keyword;
}
toLocaleString() {
return this.#keyword;
}
toString() {
return this.#keyword;
}
/**
* Returns the original value
*/
release() {
return this.#value;
}
/**
* Transform the original value and create a new
* secret from it.
*/
map(transformFunc) {
return new _Secret(transformFunc(this.#value));
}
};
// src/compose.ts

@@ -354,3 +394,3 @@ function compose(superclass, ...mixins) {

}
function join2(url, ...str) {
function joinToURL(url, ...str) {
return pathJoin(getDirname(url), ...str);

@@ -364,2 +404,3 @@ }

RuntimeException,
Secret,
base64,

@@ -376,3 +417,3 @@ compose,

isScriptFile,
join2 as join,
joinToURL,
naturalSort,

@@ -379,0 +420,0 @@ safeEqual,

@@ -0,3 +1,22 @@

/**
* @alias "assertExists"
*/
export declare function assert(value: unknown, message?: string): asserts value;
/**
* Assert the value is turthy or raise an exception.
*
* Truthy value excludes, undefined, null, and false values.
*/
export declare function assertExists(value: unknown, message?: string): asserts value;
/**
* Throws error when method is called
*/
export declare function assertUnreachable(x?: never): never;
export declare function assertNotNull<T>(value: T | null): asserts value is Exclude<T, null>;
/**
* Assert the value is not null.
*/
export declare function assertNotNull<T>(value: T | null, message?: string): asserts value is Exclude<T, null>;
/**
* Assert the value is not undefined.
*/
export declare function assertIsDefined<T>(value: T | undefined, message?: string): asserts value is Exclude<T, undefined>;
// src/assert.ts
import { inspect } from "node:util";
import { AssertionError } from "node:assert";
function assert(value, message) {
return assertExists(value, message);
}
function assertExists(value, message) {
if (!value) {
throw new Error(message ?? "value is falsy");
throw new AssertionError({ message: message ?? "value is falsy" });
}
}
function assertUnreachable(x) {
throw new Error(`unreachable code executed: ${String(x)}`);
throw new AssertionError({ message: `unreachable code executed: ${inspect(x)}` });
}
function assertNotNull(value) {
function assertNotNull(value, message) {
if (value === null) {
throw new Error("unexpected null value");
throw new AssertionError({ message: message ?? "unexpected null value" });
}
}
function assertIsDefined(value, message) {
if (value === void 0) {
throw new AssertionError({ message: message ?? "unexpected undefined value" });
}
}
export {
assert,
assertExists,
assertIsDefined,
assertNotNull,

@@ -18,0 +30,0 @@ assertUnreachable

{
"name": "@poppinss/utils",
"version": "6.6.0",
"version": "6.7.0",
"description": "Handy utilities for repetitive work",

@@ -53,5 +53,6 @@ "main": "build/index.js",

"devDependencies": {
"@adonisjs/eslint-config": "^1.1.9",
"@adonisjs/prettier-config": "^1.1.9",
"@adonisjs/tsconfig": "^1.1.9",
"@adonisjs/eslint-config": "^1.2.0",
"@adonisjs/logger": "^5.4.2-7",
"@adonisjs/prettier-config": "^1.2.0",
"@adonisjs/tsconfig": "^1.2.0",
"@commitlint/cli": "^18.4.3",

@@ -62,9 +63,9 @@ "@commitlint/config-conventional": "^18.4.3",

"@japa/runner": "^3.1.0",
"@swc/core": "^1.3.99",
"@swc/core": "^1.3.100",
"@types/fs-extra": "^11.0.4",
"@types/node": "^20.10.0",
"@types/node": "^20.10.4",
"c8": "^8.0.1",
"del-cli": "^5.1.0",
"eslint": "^8.54.0",
"fs-extra": "^11.1.1",
"eslint": "^8.55.0",
"fs-extra": "^11.2.0",
"github-label-sync": "^2.3.1",

@@ -75,10 +76,10 @@ "husky": "^8.0.3",

"move-file-cli": "^3.0.0",
"np": "^8.0.4",
"prettier": "^3.1.0",
"ts-node": "^10.9.1",
"np": "^9.2.0",
"prettier": "^3.1.1",
"ts-node": "^10.9.2",
"tsup": "^8.0.1",
"typescript": "~5.2.2"
"typescript": "^5.3.3"
},
"dependencies": {
"@lukeed/ms": "^2.0.1",
"@lukeed/ms": "^2.0.2",
"@types/bytes": "^3.1.4",

@@ -85,0 +86,0 @@ "@types/pluralize": "^0.0.33",

@@ -647,2 +647,49 @@ # @poppinss/utils

### Assertion helpers
The following assertion methods offers type-safe approach for writing conditionals and throwing error when the variable has unexpected values.
#### assertExists(message?: string)
Throws [AssertionError](https://nodejs.org/api/assert.html#new-assertassertionerroroptions) when the value is `false`, `null`, or `undefined`.
```ts
import { assertExists } from '@poppinss/utils/assert'
const value = false as string | false
assertExists(value)
// value is string
```
#### assertNotNull(value: unknown, message?: string)
Throws [AssertionError](https://nodejs.org/api/assert.html#new-assertassertionerroroptions) when the value is `null`.
```ts
import { assertNotNull } from '@poppinss/utils/assert'
const value = null as string | null
assertNotNull(value)
// value is string
```
#### assertIsDefined(value: unknown, message?: string)
Throws [AssertionError](https://nodejs.org/api/assert.html#new-assertassertionerroroptions) when the value is `undefined`.
```ts
import { assertIsDefined } from '@poppinss/utils/assert'
const value = undefined as string | undefined
assertIsDefined(value)
// value is string
```
#### assertUnreachable(value: unknown)
Throws [AssertionError](https://nodejs.org/api/assert.html#new-assertassertionerroroptions) when the method is invoked. In other words, this method always throws an exception.
```ts
import { assertUnreachable } from '@poppinss/utils/assert'
assertUnreachable()
```
### All other helpers

@@ -944,3 +991,3 @@

if (file.endsWith('.json')) {
return import(file, { assert: { type: 'json' } })
return import(file, { with: { type: 'json' } })
}

@@ -1102,2 +1149,75 @@

#### Secret
Creates a secret value that prevents itself from getting logged inside `console.log` statements, during JSON serialization, and string concatenation.
To understand why you need a special `Secret` object, you need to understand the root of the problem. Let's start with an example.
Given that you have a `Token` class that generates an opaque token for a user and persists its hash inside the database. The plain token (aka raw value) is shared with the user and it should only be visible once (for security reasons). Here is a dummy implementation of the same.
```ts
class Token {
generate() {
return {
value: 'opaque_raw_token',
hash: 'hash_of_raw_token_inside_db',
}
}
}
const token = new Token().generate()
return response.send(token)
```
At the same time, you want to drop a log statement inside your application that you can later use to debug the flow of the application, and this is how you log the token.
```ts
const token = new Token().generate()
logger.log('token generated %O', token)
// token generated {"value":"opaque_raw_token","hash":"hash_of_raw_token_inside_db"}
return response.send(token)
```
BOOM! You have weakened the security of your app. Now, anyone monitoring the logs can grab raw token values from the log and use them to perform the actions on behalf of the user.
Now, to prevent this from happening, you **should work with a branded data type**. Our [old friend PHP has it](https://www.php.net/manual/en/class.sensitiveparametervalue.php), so we need it as well.
This is what exactly the `Secret` utility class does for you. Create values that prevent themselves from leaking inside logs or during JSON serialization.
```ts
import { Secret } from '@poppinss/utils'
class Token {
generate() {
return {
// THIS LINE 👇
value: new Secret('opaque_raw_token'),
hash: 'hash_of_raw_token_inside_db',
}
}
}
const token = new Token().generate()
logger.log('token generated %O', token)
// AND THIS LOG 👇
// token generated {"value":"[redacted]","hash":"hash_of_raw_token_inside_db"}
return response.send(token)
```
**Need the original value back?**
You can call the `release` method to get the secret value back. Again, the idea is not to prevent your code from accessing the raw value. It's to stop the logging and serialization layer from reading it.
```ts
const secret = new Secret('opaque_raw_token')
const rawValue = secret.release()
rawValue === opaque_raw_token // true
```
> Shoutout to [https://transcend.io/blog/keep-sensitive-values-out-of-your-logs-with-types](transcend.io's article) to helping me design the API. In fact, I have ripped their implementation for my personal use.
#### dirname/filename

@@ -1114,2 +1234,17 @@

#### joinToURL
Similar to the Node.js `path.join`, but instead expects the first parameter to be a URL instance or a string with the `file:///` protocol.
The return value is an absolute file system path without the `file:///` protocol.
```ts
import { joinToURL } from '@poppinss/utils'
// With URL as a string
const APP_PATH = joinToURL(import.meta.url, 'app')
// With URL instance
const APP_PATH = joinToURL(new URL('./', import.meta.url), 'app')
```
[gh-workflow-image]: https://img.shields.io/github/actions/workflow/status/poppinss/utils/checks.yml?style=for-the-badge

@@ -1116,0 +1251,0 @@ [gh-workflow-url]: https://github.com/poppinss/utils/actions/workflows/checks.yml 'Github action'

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