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

@heliosgraphics/utils

Package Overview
Dependencies
Maintainers
1
Versions
23
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@heliosgraphics/utils - npm Package Compare versions

Comparing version 4.0.0-alpha-5 to 4.1.0

clipboard.spec.ts

17

clipboard.ts

@@ -1,10 +0,11 @@

export const copyValue = (text: string) => {
const inp = document.createElement('input');
// copies the given value to the clipboard.
export const copyValue = (text: string): void => {
const input: HTMLInputElement = document.createElement("input")
document.body.appendChild(inp);
inp.value = text;
inp.select();
document.execCommand('copy', false);
document.body.appendChild(input)
input.value = text
input.select()
document.execCommand("copy", false)
return inp.remove();
};
return input.remove()
}

@@ -1,11 +0,26 @@

import { rgbToHex } from './colors'
import { it, describe, expect } from 'vitest';
import { it, describe, expect } from "vitest"
import { rgbToHex, hexToRgb, DEFAULT_PROFILE_RGB } from "./colors"
describe('colors', () => {
describe('rgbToHex', () => {
it('converts rgb to hex', () => expect(rgbToHex(12, 44, 120)).toEqual('#0c2c78'));
it('converts strings to hex', () => expect(rgbToHex('12' as any as number, '44' as any as number, '120' as any as number)).toEqual('#ffffff'));
it('converts even with a null input to hex', () => expect(rgbToHex(null as any, 44, 120)).toEqual('#ff2c78'));
it('converts undefined to hex', () => expect(rgbToHex(12, undefined as any, 120)).toEqual('#0cff78'));
});
});
describe("colors", () => {
describe("hexToRgb", () => {
it("converts hex to rgb", () =>
expect(hexToRgb("#0c2c78")).toEqual([12, 44, 120]))
it("returns default for 0", () =>
expect(hexToRgb(<any>0)).toEqual(DEFAULT_PROFILE_RGB))
it("returns default for undefined", () =>
expect(hexToRgb(<any>undefined)).toEqual(DEFAULT_PROFILE_RGB))
})
describe("rgbToHex", () => {
it("converts rgb to hex", () =>
expect(rgbToHex(12, 44, 120)).toEqual("#0c2c78"))
it("converts string to hex", () =>
expect(rgbToHex(<any>"12", <any>"44", <any>"120")).toEqual(
"#0c2c78",
))
it("converts null to hex", () =>
expect(rgbToHex(<any>null, 44, 120)).toEqual("#002c78"))
it("returns undefined to hex", () =>
expect(rgbToHex(12, <any>undefined, 120)).toEqual("#0cff78"))
})
})

@@ -1,39 +0,39 @@

import type { TypeRGB } from '@heliosgraphics/library/types/colors'
import type { TypeRGB } from "@heliosgraphics/library/types/colors"
const DEFAULT_PROFILE_RGB: TypeRGB = [199, 201, 209];
export const DEFAULT_PROFILE_RGB: TypeRGB = [199, 201, 209] as const
// converts a hex value to a TypeRGB.
export const hexToRgb = (hex?: string | null): TypeRGB => {
const isString: boolean = !!hex && typeof hex === 'string';
const isValid: boolean = !!hex && typeof hex === "string"
if (!isString) return DEFAULT_PROFILE_RGB
if (!isValid) return DEFAULT_PROFILE_RGB
hex = hex!.replace(/^#/, '');
hex = hex!.replace(/^#/, "")
const bigint = parseInt(hex, 16);
const r: number = (bigint >> 16) & 255;
const g: number = (bigint >> 8) & 255;
const b: number = bigint & 255;
const bigint = parseInt(hex, 16)
const r: number = (bigint >> 16) & 255
const g: number = (bigint >> 8) & 255
const b: number = bigint & 255
return [r, g, b];
return [r, g, b]
}
export const rgbToHex = (r: number = 255, g: number = 255, b: number = 255): string => {
const _toHex = (c: number): string => {
const hex = c.toString(16);
return hex.length === 1 ? '0' + hex : hex;
};
// converts an rgb value to a hex string (#0cd0cd).
export const rgbToHex = (
r: number | string = 255,
g: number | string = 255,
b: number | string = 255,
): string => {
const _toHex = (c: unknown): string => {
const value = Number(c)
const isValid: boolean = isNaN(value) || value < 0 || value > 255
const isRNumber: boolean = typeof r === 'number';
const isGNumber: boolean = typeof g === 'number';
const isBNumber: boolean = typeof b === 'number';
if (isValid) return "FF"
const RR: number = isRNumber ? r : 255;
const GG: number = isGNumber ? g : 255;
const BB: number = isBNumber ? b : 255;
const hex = value.toString(16)
const hexR: string = _toHex(RR);
const hexG: string = _toHex(GG);
const hexB: string = _toHex(BB);
return hex.length === 1 ? `0${hex}` : hex
}
return `#${hexR}${hexG}${hexB}`;
}
return `#${_toHex(r)}${_toHex(g)}${_toHex(b)}`
}

@@ -1,11 +0,17 @@

export const debounce = (callback: Function, wait: number) => {
let timeoutId: any;
export type CallbackFunction = (...args: Array<unknown>) => void
return (...args: any) => {
globalThis.clearTimeout(timeoutId);
// debounces the function with wait time passed.
export const debounce = (
callback: CallbackFunction,
wait: number,
): CallbackFunction => {
let timeoutId: any
timeoutId = globalThis.setTimeout(() => {
callback.apply(null, args);
}, wait);
};
return (...args: Array<unknown>) => {
globalThis.clearTimeout(timeoutId)
timeoutId = globalThis.setTimeout(() => {
callback.apply(null, args)
}, wait)
}
}
The MIT License (MIT)
Copyright (c) 2015 Chris Puska
Copyright (c) 2015 Helios Graphics

@@ -5,0 +5,0 @@ Permission is hereby granted, free of charge, to any person obtaining a copy

{
"name": "@heliosgraphics/utils",
"version": "4.0.0-alpha-5",
"version": "4.1.0",
"private": false,
"type": "module",
"author": "Chris Puska <03b8@helios.graphics>",
"author": "03b8 <03b8@helios.graphics>",
"description": "Helios Utils",
"dependencies": {

@@ -13,4 +14,4 @@ "@heliosgraphics/library": "latest",

"devDependencies": {
"@types/uuid": "9.0.7"
"@types/uuid": "latest"
}
}

@@ -1,15 +0,23 @@

import { getSlug } from "./slug";
import { it, describe, expect } from 'vitest';
import { it, describe, expect } from "vitest"
import { getSlug } from "./slug"
describe('slug', () => {
describe('getSlug', () => {
// Good
it('Gets a lowercase subdomain from case 1', () => expect(getSlug('--BuRn--')).toEqual('-burn-'));
it('Gets a lowercase subdomain from case 2', () => expect(getSlug('#$%^B#uR#n-')).toEqual('burn-'));
it('Gets a nice slug for a category', () => expect(getSlug('Gaussian Blur')).toEqual('gaussian-blur'));
// Empty
it('Gets empty string if subdomain is undefined', () => expect(getSlug(undefined)).toEqual(''));
});
});
describe("slug", () => {
describe("getSlug", () => {
it("returns valid from string with dashes", () =>
expect(getSlug("--B—uRn--")).toEqual("-burn-"))
it("returns valid from special string", () =>
expect(getSlug("#$%^B#uR#n-")).toEqual("burn-"))
it("returns valid from parens string", () =>
expect(getSlug("Gaussian Blur [1](2){3}")).toEqual(
"gaussian-blur-123",
))
it("replaces àáäâèéëêìíïîòóöôùúüûñç", () =>
expect(getSlug("àáäâèéëêìíïîòóöôùúüûñç")).toEqual(
"aaaaeeeeiiiioooouuuunc",
))
it("fails silently from undefined", () =>
expect(getSlug(undefined)).toEqual(""))
it("fails silently from null", () =>
expect(getSlug(<any>null)).toEqual(""))
})
})

@@ -1,20 +0,24 @@

export const getSlug = (subdomain: string | undefined): string => {
if (!subdomain) return ''
// gets a valid slug from the given string.
export const getSlug = (text?: string): string => {
const isValid: boolean = Boolean(text && typeof text == "string")
let str = subdomain;
if (!isValid) return ""
str = str.replace(/^\s+|\s+$/g, '')
str = str.toLowerCase()
var from = "àáäâèéëêìíïîòóöôùúüûñç·/_,:;"
var to = "aaaaeeeeiiiioooouuuunc------"
for (var i = 0, l = from.length; i < l; i++) {
str = str.replace(new RegExp(from.charAt(i), 'g'), to.charAt(i))
}
str = str.replace(/[^a-z0-9 -]/g, '')
.replace(/\s+/g, '-')
.replace(/-+/g, '-')
return str
return (
text!
// normalize characters to their base characters and diacritics
.normalize("NFD")
// remove diacritic marks
.replace(/[\u0300-\u036f]/g, "")
// remove leading and trailing whitespace
.trim()
// convert to lowercase
.toLowerCase()
// remove invalid characters
.replace(/[^a-z0-9 -]/g, "")
// replace spaces with hyphens
.replace(/\s+/g, "-")
// replace multiple hyphens with a single hyphen
.replace(/-+/g, "-")
)
}

@@ -1,52 +0,77 @@

import xss from 'xss';
import xss from "xss"
export const sanitizeText = (input: string = ''): string => {
const clean: string = xss(input);
// sanitizes a given input. you're trusting the `xss` package here.
export const sanitizeText = (input: string = ""): string => {
const clean: string = xss(input)
return clean;
return clean
}
export const middleEllipsis = (str: string = '', length: number = 19): string => {
const diff: number = Math.floor((length - 3) / 2);
// removes markdown formatting.
export const removeMarkdown = (markdownText: string): string => {
const patternsToRemove: Array<{ pattern: RegExp; replacement: string }> = [
// ![alt text](url)
{ pattern: /!\[.*?\]\(.*?\)/g, replacement: "" },
// [text](url)
{ pattern: /\[(.*?)\]\(.*?\)/g, replacement: "$1" },
// #, ##, etc.
{ pattern: /#{1,6}\s/g, replacement: "" },
// **bold**
{ pattern: /\*\*(.*?)\*\*/g, replacement: "$1" },
// __bold__
{ pattern: /__(.*?)__/g, replacement: "$1" },
// *emphasized*
{ pattern: /\*(.*?)\*/g, replacement: "$1" },
// _emphasized_
{ pattern: /_(.*?)_/g, replacement: "$1" },
// ~~strikethrough~~
{ pattern: /~~(.*?)~~/g, replacement: "$1" },
// >
{ pattern: />/g, replacement: "" },
// ---
{ pattern: /-{3,}/g, replacement: "" },
// ```
{ pattern: /`{3}.*?`{3}/gs, replacement: "" },
// `code`
{ pattern: /`{1,2}(.*?)`{1,2}/g, replacement: "$1" },
]
if (str.length > length) {
return str.substring(0, diff) + '...' + str.substring(str.length - diff, str.length);
}
let cleanText = markdownText
return str;
for (const { pattern, replacement } of patternsToRemove) {
cleanText = cleanText.replace(pattern, replacement)
}
return cleanText
}
// TODO @chrispuska Make this account for possible markdown parts in `text` add tests.
export const removeNewlines = (text?: string | null, limit?: number): string => {
if (!text) return '';
// adds a middle ellipsis, eg.: (ellipsis, 6) gets "ell...sis".
export const middleEllipsis = (
text: string = "",
length: number = 64,
): string => {
const diff: number = Math.floor((length - 3) / 2)
const isValid: boolean = Boolean(
!!text && typeof text === "string" && text.length > length,
)
const length: number = text?.length;
const trimmedString = text.substring(0, limit ?? length);
if (!isValid) return ""
return sanitizeText(trimmedString.replace(/(?:\r\n|\r|\n)/g, ' '));
return (
text.substring(0, diff) +
"..." +
text.substring(text.length - diff, text.length)
)
}
// TODO @chrispuska This should only touch semantics, not ui
export const formatRawText = (inputText: string = '', pattern?: RegExp, match?: string): string => {
// Links
const URL_PATTERN = /\b(?:https?|ftp):\/\/[a-z0-9-+&@#\/%?=~_|!:,.;]*[a-z0-9-+&@#\/%=~_|]/gim;
const URL_PSEUDO_PATTERN = /(^|[^\/])(www\.[\S]+(\b|$))/gim;
const URL_EMAIL_PATTERN = /(([a-zA-Z0-9_\-\.]+)@[a-zA-Z_]+?(?:\.[a-zA-Z]{2,6}))+/gim;
export const removeNewlines = (
text?: string | null,
limit?: number,
): string => {
if (!text) return ""
// New lines
const NEW_LINES_PATTERN = /(?:\r\n|\r|\n)/gim;
const length: number = text?.length
const trimmedString: string = text.substring(0, limit ?? length ?? 0)
let formattedText: string = inputText
// Links
.replace(URL_PATTERN, '<a class="underline medium" href="$&">$&</a>')
.replace(URL_PSEUDO_PATTERN, '$1<a class="underline medium" href="http://$2">$2</a>')
.replace(URL_EMAIL_PATTERN, '<a class="underline medium" href="mailto:$1">$1</a>')
// New lines
.replace(NEW_LINES_PATTERN, '<br/>')
// Replace a custom one
// TODO @chrispuska Make this multi pattern instead.
if (!pattern) formattedText.replace(pattern!, `<a class=" medium" href="${match}">$&</a>`)
return sanitizeText(formattedText);
return sanitizeText(trimmedString.replace(/(?:\r\n|\r|\n)/g, " "))
}

@@ -1,11 +0,17 @@

export const throttle = (fn, delay: number) => {
let lastCall = 0;
export type CallbackFunction = (...args: Array<unknown>) => void
return (...args) => {
const now = new Date().getTime();
if (now - lastCall < delay) return;
// throttles the passed function with wait.
export const throttle = (callbackFunction: CallbackFunction, wait: number) => {
let lastCall = 0
lastCall = now;
return fn(...args);
};
};
return (...args: Array<unknown>) => {
const now: number = new Date().getTime()
const isInvalid: boolean = Boolean(now - lastCall < wait)
if (isInvalid) return
lastCall = now
return callbackFunction(...args)
}
}

@@ -1,11 +0,24 @@

import { getUUID, TEST_UUID } from './uuid'
import { it, describe, expect } from 'vitest';
import { it, describe, expect } from "vitest"
import { getUUID, isUUID, TEST_UUID } from "./uuid"
describe('validations', () => {
describe('getUUID', () => {
const MOCK_UUID = getUUID()
describe("validations", () => {
describe("getUUID", () => {
const MOCK_UUID = getUUID()
it('returns something', () => expect(MOCK_UUID).toEqual(TEST_UUID));
it('return any string', () => expect(getUUID('any-string')).toEqual('any-string'));
});
});
it("returns test uuid", () =>
expect(getUUID(MOCK_UUID)).toEqual(TEST_UUID))
it("returns any string", () =>
expect(getUUID("any-string")).toEqual("any-string"))
})
describe("isUUID", () => {
it("validates test uuid", () => expect(isUUID(TEST_UUID)).toEqual(true))
it("validates a random uuid", () =>
expect(isUUID("101bfe56-8c16-4f94-9b45-759ea5e67cea")).toEqual(
true,
))
it("catches empty string", () => expect(isUUID("")).toEqual(false))
it("catches undefined", () =>
expect(isUUID(<any>undefined)).toEqual(false))
})
})

@@ -1,25 +0,23 @@

import { v4 as uuidv4 } from 'uuid';
import { v4 as uuidv4 } from "uuid"
export const IS_TEST: boolean = process.env.NODE_ENV === 'test' as const;
export const TEST_UUID: string = '00000000-0000-0000-000000000000' as const;
export const IS_TEST: boolean = process.env.NODE_ENV === ("test" as const)
export const TEST_UUID: string = "00000000-0000-0000-0000-000000000000" as const
export const getUUID = (id?: string) => {
// Do not generate if given
if (!!id) return id;
export const getUUID = (id?: unknown) => {
if (!!id) return id
// Do not generate in test env
if (IS_TEST) return TEST_UUID
// this is necessary for snapshot tests, but should be dynamic.
if (IS_TEST) return TEST_UUID
return uuidv4();
return uuidv4()
}
export const isUUID = (uuid): boolean => {
let s: any = "" + uuid;
s = s.match('^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$');
export const isUUID = (uuid?: unknown): boolean => {
const uuidRegex =
/^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/
const isValid = typeof uuid === "string"
if (s === null) {
return false;
}
if (!isValid) return false
return true;
return uuidRegex.test(uuid)
}

@@ -1,23 +0,44 @@

import { validateHttpUrl, validateEmail } from './validations'
import { it, describe, expect } from 'vitest';
import { validateHttpUrl, validateEmail } from "./validations"
import { it, describe, expect } from "vitest"
describe('validations', () => {
describe('validateEmail', () => {
it('Valid email', () => expect(validateEmail('x@x.com')).toEqual(true));
it('Valid email +', () => expect(validateEmail('x+x@x.com')).toEqual(true));
it('Valid email weird', () => expect(validateEmail('0@space.city')).toEqual(true));
it('Invalid email', () => expect(validateEmail('@space.city')).toEqual(false));
it('Invalid email', () => expect(validateEmail('')).toEqual(false));
it('Invalid email', () => expect(validateEmail(undefined as any as string)).toEqual(false));
});
describe("validations", () => {
describe("validateEmail", () => {
it("validates email", () =>
expect(validateEmail("x@x.com")).toEqual(true))
it("validates email with +", () =>
expect(validateEmail("x+x@x.com")).toEqual(true))
it("validates email with long tld", () =>
expect(validateEmail("0@helios.graphics")).toEqual(true))
it("catches long invalid string", () =>
expect(validateEmail("@space.city")).toEqual(false))
it("catches empty string", () =>
expect(validateEmail("")).toEqual(false))
it("catches undefined", () =>
expect(validateEmail(<any>undefined)).toEqual(false))
it("catches multi @", () =>
expect(validateEmail("x@@x.com")).toEqual(false))
it("catches a weird one", () =>
expect(validateEmail("x@@@x.com@/@x.com")).toEqual(false))
})
describe('validateHttpUrl', () => {
it('Valid http url', () => expect(validateHttpUrl('https://x.com')).toEqual(true));
it('Valid http url long', () => expect(validateHttpUrl('http://x.city')).toEqual(true));
it('Valid subdomain', () => expect(validateHttpUrl('https://0.x.x.com')).toEqual(true));
it('Invalid ftp', () => expect(validateHttpUrl('ftp://x.com')).toEqual(false));
it('Invalid string', () => expect(validateHttpUrl('lorem ipsum https://x.com')).toEqual(false));
it('Invalid empty string', () => expect(validateHttpUrl('')).toEqual(false));
it('Invalid null', () => expect(validateHttpUrl(null as any as string)).toEqual(false));
});
});
describe("validateHttpUrl", () => {
it("validates url", () =>
expect(validateHttpUrl("https://x.com")).toEqual(true))
it("validates url with long tld", () =>
expect(validateHttpUrl("https://lorem-ipsum.graphics")).toEqual(
true,
))
it("validates url with double subdomain", () =>
expect(validateHttpUrl("https://0.x.x.com")).toEqual(true))
it("catches ftp", () =>
expect(validateHttpUrl("ftp://x.com")).toEqual(false))
it("catches string containing url", () =>
expect(validateHttpUrl("lorem ipsum https://x.com")).toEqual(false))
it("catches unsafe http", () =>
expect(validateHttpUrl("http://x.com")).toEqual(false))
it("catches empty string", () =>
expect(validateHttpUrl("")).toEqual(false))
it("catches undefined", () =>
expect(validateHttpUrl(<any>undefined)).toEqual(false))
})
})

@@ -0,17 +1,22 @@

// validates a URL.
export const validateHttpUrl = (text?: string | null): boolean => {
let url;
let url: URL
try {
url = new URL(text as string);
} catch (_) {
return false;
}
try {
url = new URL(text as string)
} catch (_) {
return false
}
return Boolean(url.protocol === "http:" || url.protocol === "https:");
// "http" is unsafe.
const isValid: boolean = Boolean(url.protocol === "https:")
return isValid
}
export const validateEmail = (email: string): boolean => {
const re: RegExp = /\S+@\S+\.\S+/;
// validates an email.
export const validateEmail = (email: string = ""): boolean => {
const re: RegExp = /^[a-zA-Z0-9._+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
return re.test(email);
};
return re.test(email)
}
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