Skip to content

vbrajon/cutjs

Repository files navigation

Cut JS

A shortcut utility JS library for rapidly interacting with objects, dates, and functions.

// Normal use
import { map } from "cut"
map({ a: 1 }, (v) => v + 1) //= {"a":2}

// Proxy use, access .data or .error
import cut from "cut"
cut({ a: 1 }).map((v) => v + 1).data //= {"a":2}
cut({ a: 1 }).x.y.error //= new Error()

// Prototype use, call directly on the object
import "cut?window+prototype"
({ a: 1 }).map((v) => v + 1) //= {"a":2}

// Format a Date
new Date("2000").format("YYYY-QQ") //= "2000-Q1"
new Date("2000").format("day, month, year", "en") //= "January 1, 2000"
new Date("2000T00:00").format("long, short", "ja") //= "2000年1月1日 0:00"

// Format a String
"hello_world".format() //= "Hello World"
"hello_world".format("camel") //= "helloWorld"
"{}_{}".format(["hello", "world"]) //= "hello_world"

// Format a Number
0.30000000000000004.format() //= "0.3"
0.111.format("+0.##%") //= "+11.1%"
123456.789.format(2) //= "120k"
123456.789.format(".") //= "123,457"
123456.789.format("CNÂ¥") //= "CNÂ¥123,456.79"

// Parse a Date
new Date("2000T00:00").parse("tomorrow") //= new Date("2000-01-02T00:00:00+01:00")
new Date("2000T00:00").parse("yesterday at 3pm") //= new Date("1999-12-31T15:00:00+01:00")
new Date("2000T00:00").parse("in one hour, two minutes and thirty-four seconds") //= new Date("2000-01-01T01:02:34+01:00")
new Date("2000T00:00").parse("6:30pm in three days") //= new Date("2000-01-04T18:30:00+01:00")

// Manipulate a Date
new Date("2000").plus("1 month").end("month").format("YYYY-MM-DD hh:mm") //= "2000-02-29 23:59"
new Date("2000").minus({ years: 1, months: 2 }).plus("1 year, 2 months").toISOString().slice(0, 10) //= "2000-01-01"

// Manipulate an Object or Array
const users = [
  { name: "John", age: 30, city: "London" },
  { name: "Jane", age: 14, city: "New York" },
  { name: "Jean", age: 35, city: "Paris" },
]
const usersByCity = users.sort("-age").group("city") //~ {"Paris":[{"name":"Jean","age":35...}
const avgAgeByCity = usersByCity.map((g) => g.mean("age")) //~ {"Paris":35...}

// Add a Function
cut(Array, "transpose", (arr) => arr[0].map((_, i) => arr.map((row) => row[i])))

// Add a shortcut
cut("shortcut", "transpose", (fn, arr) => {
  if (arr.some((row) => row.length !== arr[0].length)) throw new Error("Not a matrix")
  return fn(arr)
})

// Add an alias
cut(Array, "swap", cut.Array.transpose)

// And use it
const matrix = [[1, 2, 3], [4, 5, 6]]
matrix.swap() //= [[1,4],[2,5],[3,6]]
const invalid = [[1], [2, 3]]
invalid.transpose() //! Error: Not a matrix

Functions

Generic Object Array Function String Number Date RegExp
is keys map decorate lower duration relative escape
equal values reduce promisify upper format getWeek plus
access entries filter partial capitalize getQuarter minus
transform fromEntries find memoize words getLastDate
map findIndex every format getTimezone
reduce sort wait format
filter group debounce modify
find unique throttle parse
findIndex min plus
max minus
sum start
mean end
median

Development

bun i @js-temporal/polyfill lodash-es
bun test --watch --coverage

Roadmap

  • Interactive Docs & Tests: https://raw.githack.com/vbrajon/rawjs/cut/index.html
  • Replace cutest by bun test
  • Iterator or AsyncIterator
  • Additional Fn (forEach, findIndex, findLastIndex, some, every, flat, flatMap, reduceRight, concat, slice)
  • Fuzzy tests
  • Typescript / TSDoc
  • Monaco Editor
  • Collaboration / Multiplayer / CTRL-S to PR
  • Blog Post / Hacker News / Product Hunt

About

🔪 Shortcut Utils

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published