Skip to content

Instantly share code, notes, and snippets.

View safareli's full-sized avatar

Irakli Safareli safareli

View GitHub Profile
@safareli
safareli / GE2EN.coffee
Last active February 21, 2024 14:08
convert Georgian characters to English
GE2EN = ((set)->
(string)->
(Array::map.call string, (char)->
set[char] || char).join('')
)({"ა":"a","ბ":"b","გ":"g","დ":"d","ე":"e","ვ":"v","ზ":"z","თ":"t","ი":"i","კ":"k'","ლ":"l","მ":"m","ნ":"n","ო":"o","პ":"p'","ჟ":"zh","რ":"r","ს":"s","ტ":"t'","უ":"u","ფ":"p","ქ":"k","ღ":"gh","ყ":"q","შ":"sh","ჩ":"ch","ც":"ts","ძ":"dz","წ":"ts'","ჭ":"ch'","ხ":"kh","ჯ":"j","ჰ":"h"})
export {};
// https://gist.github.com/rattrayalex/b85d99d4428ee9c1f51661af324c767b
type SchemaPrimitive =
| {
type: "integer";
}
| {
type: "string";
};
var keywords_color_regex = /^[a-z]*$/;
var hex_color_regex = /^#[0-9a-f]{3}([0-9a-f]{3})?$/;
var rgb_color_regex = /^rgb\(\s*(0|[1-9]\d?|1\d\d?|2[0-4]\d|25[0-5])%?\s*,\s*(0|[1-9]\d?|1\d\d?|2[0-4]\d|25[0-5])%?\s*,\s*(0|[1-9]\d?|1\d\d?|2[0-4]\d|25[0-5])%?\s*\)$/;
var rgba_color_regex = /^rgba\(\s*(0|[1-9]\d?|1\d\d?|2[0-4]\d|25[0-5])%?\s*,\s*(0|[1-9]\d?|1\d\d?|2[0-4]\d|25[0-5])%?\s*,\s*(0|[1-9]\d?|1\d\d?|2[0-4]\d|25[0-5])%?\s*,\s*((0.[1-9])|[01])\s*\)$/;
var hsl_color_regex = /^hsl\(\s*(0|[1-9]\d?|[12]\d\d|3[0-5]\d)\s*,\s*((0|[1-9]\d?|100)%)\s*,\s*((0|[1-9]\d?|100)%)\s*\)$/;
@safareli
safareli / assertRecordIsEmpty.ts
Created May 4, 2022 07:45
Check that type of record is an empty record in typescript type level
declare const test1: {}
declare const test2: {foo: 1}
declare const test3: {foo: 1,asda:11}
declare const assertRecordIsEmpty:(input: Record<keyof any,never>) => void
assertRecordIsEmpty(test1)
assertRecordIsEmpty(test2)
assertRecordIsEmpty(test3)
@safareli
safareli / type-guard-composition.ts
Last active January 14, 2022 14:16
Composing TypeScript type guards
/**
* Type representing a guard function accepting Input and some other arguments
* while refining type of input as `Output`
*/
export type TypeGuard<
Input,
Output extends Input,
Args extends unknown[] = []
> = (value: Input, ...args: Args) => value is Output;
const pascalCaseToKebabCase = (x: string) =>
x.replace(
/[A-Z]/g,
(match, offset) => (offset > 0 ? "-" : "") + match.toLowerCase()
);
const kebabCaseToPascalCase = (x: string) =>
x
.replace(/(^[a-z])|(-[a-z])/g, (match) => match.toUpperCase())
sum(1, 2, 3, 4) == 10 // true
sum(1, 2, 3, 4)(1, 2, 3, 4) == 20 // true
sum(1)(2)(3)(4)(1)(2)(3)(4) == 20 // true
function sum(...args) {
function res(...args2) {
return sum(_sum(args), _sum(args2))
}
// https://javascript.info/object-toprimitive
res[Symbol.toPrimitive] = () => _sum(args)
@safareli
safareli / decoder.ts
Last active June 9, 2021 19:03
Mini decoder library in 60 lines.
type Decoder<I,O> = (_:I) => O
type TypeOf<D> = D extends Decoder<any, infer R> ? R: never
type InputOf<D> = D extends Decoder<infer R, any> ? R: never
const string: Decoder<unknown, string> = (x) => {
if (typeof x === "string") return x;
throw new Error("Expected string");
}
const number: Decoder<unknown, number> = (x) => {
@safareli
safareli / transformBy.ts
Last active June 9, 2021 17:03
Transformer by async generator (this might not work)
import { Duplex, ReadableOptions } from "stream";
export const createDeferredPromise = <T>() => {
const res = {
resolve: (_val: T) => {},
reject: (_reason?: unknown) => {},
promise: new Promise<T>((resolve, reject) => {
res.resolve = resolve;
res.reject = reject;
}),
};