├── docs
├── static
│ ├── .nojekyll
│ └── img
│ │ ├── favicon.ico
│ │ ├── hero-logo.png
│ │ ├── background.png
│ │ ├── ts-belt-frame.png
│ │ └── ts-belt-logo.png
├── api
│ ├── generated
│ │ └── _src.mdx
│ ├── function.mdx
│ ├── guards.mdx
│ ├── object.mdx
│ ├── boolean.mdx
│ ├── number.mdx
│ ├── string.mdx
│ ├── array.mdx
│ ├── result.mdx
│ └── option.mdx
├── babel.config.js
├── src
│ ├── pages
│ │ ├── components
│ │ │ ├── Row.module.css
│ │ │ ├── Title.module.css
│ │ │ ├── Column.module.css
│ │ │ ├── Title.js
│ │ │ ├── Feature.js
│ │ │ ├── Columns.module.css
│ │ │ ├── Features.module.css
│ │ │ ├── Feature.module.css
│ │ │ ├── Page.js
│ │ │ ├── Column.js
│ │ │ ├── Card.js
│ │ │ ├── Button.js
│ │ │ ├── Row.js
│ │ │ ├── Features.js
│ │ │ ├── Columns.js
│ │ │ ├── Button.module.css
│ │ │ ├── Card.module.css
│ │ │ └── Hero.js
│ │ └── styles.module.css
│ └── theme
│ │ └── ReactLiveScope
│ │ └── index.js
├── docs
│ └── getting-started
│ │ └── installation.md
├── .gitignore
├── sidebars.api.js
├── sidebars.js
├── sidebars.benchmarks.js
├── package.json
└── benchmarks
│ └── introduction.md
├── benchmarks
├── .gitignore
├── index.js
├── index.markdown.js
├── scripts
│ ├── generate.sh
│ └── run.sh
├── package.json
├── native.js
└── simple
│ └── intersperse.js
├── tools
├── comment-ppx
│ ├── comment-ppx.opam
│ ├── dune-project
│ ├── .gitignore
│ ├── esy.lock
│ │ ├── opam
│ │ │ ├── seq.base
│ │ │ │ ├── files
│ │ │ │ │ ├── seq.install
│ │ │ │ │ └── META.seq
│ │ │ │ └── opam
│ │ │ ├── base-unix.base
│ │ │ │ └── opam
│ │ │ ├── base-threads.base
│ │ │ │ └── opam
│ │ │ ├── result.1.5
│ │ │ │ └── opam
│ │ │ ├── ppx_derivers.1.2.1
│ │ │ │ └── opam
│ │ │ ├── fix.20211125
│ │ │ │ └── opam
│ │ │ ├── ppx_yojson_conv_lib.v0.14.0
│ │ │ │ └── opam
│ │ │ ├── menhir.20211012
│ │ │ │ └── opam
│ │ │ ├── sexplib0.v0.14.0
│ │ │ │ └── opam
│ │ │ ├── menhirLib.20211012
│ │ │ │ └── opam
│ │ │ ├── menhirSdk.20211012
│ │ │ │ └── opam
│ │ │ ├── dot-merlin-reader.4.1
│ │ │ │ └── opam
│ │ │ ├── junit.2.0.2
│ │ │ │ └── opam
│ │ │ ├── ocamlbuild.0.14.0
│ │ │ │ └── opam
│ │ │ ├── merlin-extend.0.6
│ │ │ │ └── opam
│ │ │ ├── uchar.0.0.2
│ │ │ │ └── opam
│ │ │ ├── cppo.1.6.8
│ │ │ │ └── opam
│ │ │ ├── stdlib-shims.0.3.0
│ │ │ │ └── opam
│ │ │ └── ocaml-compiler-libs.v0.12.4
│ │ │ │ └── opam
│ │ ├── .gitignore
│ │ ├── .gitattributes
│ │ └── overrides
│ │ │ ├── opam__s__ocamlbuild_opam__c__0.14.0_opam_override
│ │ │ └── package.json
│ │ │ └── opam__s__ocamlfind_opam__c__1.9.1_opam_override
│ │ │ └── package.json
│ ├── ppx.exe
│ ├── src
│ │ ├── dune
│ │ └── Comment_ppx.re
│ ├── scripts
│ │ └── install.sh
│ └── package.json
├── javascript-codemods
│ ├── pre
│ │ ├── index.ts
│ │ ├── spread-rest-args.ts
│ │ └── rename-identifiers.ts
│ └── post
│ │ └── index.ts
├── typescript-codemods
│ ├── rename-generics.ts
│ ├── make-option.ts
│ ├── make-readonly-array.ts
│ └── make-readonly-tuples.ts
└── rescript-externals
│ └── Externals.res
├── src
├── Array
│ └── index.js
├── Bool
│ ├── index.js
│ └── Bool.res
├── Dict
│ └── index.js
├── Function
│ └── index.js
├── Guards
│ ├── index.js
│ └── Guards.res
├── Number
│ └── index.js
├── String
│ └── index.js
├── AsyncOption
│ └── index.js
├── AsyncResult
│ └── index.js
├── global.d.ts
├── Option
│ └── index.js
├── pipe.js
├── Result
│ └── index.js
├── flow.js
├── AsyncData
│ └── index.js
├── types.ts
├── index.js
├── index.ts
└── AsyncDataResult
│ └── index.js
├── .github
└── FUNDING.yml
├── assets
└── ts-belt-frame.png
├── tsconfig.build.json
├── .prettierrc
├── .gitignore
├── jest.config.js
├── __tests__
├── Function
│ ├── coerce.test.ts
│ ├── tap.test.ts
│ ├── toMutable.test.ts
│ ├── memoizeWithKey.test.ts
│ ├── once.test.ts
│ ├── before.test.ts
│ ├── defaultTo.test.ts
│ └── after.test.ts
├── String
│ ├── trim.test.ts
│ ├── trimEnd.test.ts
│ ├── trimStart.test.ts
│ ├── head.test.ts
│ ├── last.test.ts
│ ├── length.test.ts
│ ├── concat.test.ts
│ ├── getUnsafe.test.ts
│ ├── prepend.test.ts
│ ├── remove.test.ts
│ ├── endsWith.test.ts
│ ├── startsWith.test.ts
│ ├── includes.test.ts
│ ├── isEmpty.test.ts
│ ├── removeAll.test.ts
│ ├── get.test.ts
│ ├── isNotEmpty.test.ts
│ ├── indexOf.test.ts
│ └── lastIndexOf.test.ts
├── Array
│ ├── makeEmpty.test.ts
│ ├── intersperse.test.ts
│ ├── head.test.ts
│ ├── map.test.ts
│ ├── sort.test.ts
│ ├── makeWithIndex.test.ts
│ ├── get.test.ts
│ ├── take.test.ts
│ ├── getBy.test.ts
│ ├── splitAt.test.ts
│ ├── tail.test.ts
│ ├── union.test.ts
│ ├── all.test.ts
│ ├── flatMap.test.ts
│ ├── intersection.test.ts
│ ├── any.test.ts
│ ├── splitEvery.test.ts
│ ├── length.test.ts
│ ├── takeWhile.test.ts
│ ├── unzip.test.ts
│ ├── difference.test.ts
│ ├── removeFirst.test.ts
│ ├── reverse.test.ts
│ ├── isEmpty.test.ts
│ ├── filterMap.test.ts
│ ├── isNotEmpty.test.ts
│ ├── zipWithIndex.test.ts
│ ├── dropWhile.test.ts
│ ├── removeFirstBy.test.ts
│ ├── flip.test.ts
│ └── make.test.ts
├── Result
│ ├── getExn.test.ts
│ ├── isOk.test.ts
│ ├── isError.test.ts
│ ├── tapError.test.ts
│ ├── tap.test.ts
│ ├── getWithDefault.test.ts
│ ├── fromPromise.test.ts
│ ├── fromFalsy.test.ts
│ ├── flip.test.ts
│ ├── mapWithDefault.test.ts
│ ├── fromNullable.test.ts
│ └── fromPredicate.test.ts
├── Number
│ ├── pred.test.ts
│ ├── add.test.ts
│ ├── divide.test.ts
│ ├── multiply.test.ts
│ ├── succ.test.ts
│ ├── modulo.test.ts
│ ├── subtract.test.ts
│ ├── divideWithModulo.test.ts
│ ├── lt.test.ts
│ ├── gt.test.ts
│ ├── clamp.test.ts
│ ├── lte.test.ts
│ └── gte.test.ts
├── Guards
│ ├── isNullable.test.ts
│ ├── isNull.test.ts
│ ├── isUndefined.test.ts
│ ├── isNotNullable.test.ts
│ ├── isDate.test.ts
│ ├── isNumber.test.ts
│ ├── isString.test.ts
│ ├── isBoolean.test.ts
│ ├── isError.test.ts
│ ├── isObject.test.ts
│ ├── isArray.test.ts
│ ├── isFunction.test.ts
│ ├── isPromise.test.ts
│ └── isNot.test.ts
├── Option
│ ├── tap.test.ts
│ ├── fromPromise.test.ts
│ ├── isNone.test.ts
│ ├── isSome.test.ts
│ ├── zip.test.ts
│ ├── getExn.test.ts
│ ├── contains.test.ts
│ ├── fromFalsy.test.ts
│ ├── toNullable.test.ts
│ ├── map.test.ts
│ ├── toUndefined.test.ts
│ ├── fromExecution.test.ts
│ ├── fromNullable.test.ts
│ └── fromPredicate.test.ts
├── Bool
│ ├── inverse.test.ts
│ ├── or.test.ts
│ ├── and.test.ts
│ ├── nor.test.ts
│ ├── xor.test.ts
│ ├── nand.test.ts
│ ├── xnor.test.ts
│ └── implies.test.ts
├── AsyncData
│ └── isInit.test.ts
└── Dict
│ ├── merge.test.ts
│ ├── values.test.ts
│ ├── keys.test.ts
│ ├── isEmpty.test.ts
│ └── getUnsafe.test.ts
├── bsconfig.json
├── tsconfig.json
├── scripts
├── test.ts
└── generate.ts
└── LICENSE
/docs/static/.nojekyll:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/api/generated/_src.mdx:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/benchmarks/.gitignore:
--------------------------------------------------------------------------------
1 | .results/
2 |
--------------------------------------------------------------------------------
/tools/comment-ppx/comment-ppx.opam:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/Array/index.js:
--------------------------------------------------------------------------------
1 | export * from './Array.bs.js'
2 |
--------------------------------------------------------------------------------
/src/Bool/index.js:
--------------------------------------------------------------------------------
1 | export * from './Bool.bs.js'
2 |
--------------------------------------------------------------------------------
/src/Dict/index.js:
--------------------------------------------------------------------------------
1 | export * from './Dict.bs.js'
2 |
--------------------------------------------------------------------------------
/tools/comment-ppx/dune-project:
--------------------------------------------------------------------------------
1 | (lang dune 2.6)
2 |
--------------------------------------------------------------------------------
/src/Function/index.js:
--------------------------------------------------------------------------------
1 | export * from './Function.bs.js'
2 |
--------------------------------------------------------------------------------
/src/Guards/index.js:
--------------------------------------------------------------------------------
1 | export * from './Guards.bs.js'
2 |
--------------------------------------------------------------------------------
/src/Number/index.js:
--------------------------------------------------------------------------------
1 | export * from './Number.bs.js'
2 |
--------------------------------------------------------------------------------
/src/String/index.js:
--------------------------------------------------------------------------------
1 | export * from './String.bs.js'
2 |
--------------------------------------------------------------------------------
/tools/comment-ppx/.gitignore:
--------------------------------------------------------------------------------
1 | _esy
2 | _build
3 | *.install
4 |
--------------------------------------------------------------------------------
/src/AsyncOption/index.js:
--------------------------------------------------------------------------------
1 | export * from './AsyncOption.bs.js'
2 |
--------------------------------------------------------------------------------
/src/AsyncResult/index.js:
--------------------------------------------------------------------------------
1 | export * from './AsyncResult.bs.js'
2 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | custom: ["https://www.buymeacoffee.com/utSC0k7"]
2 |
--------------------------------------------------------------------------------
/assets/ts-belt-frame.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobily/ts-belt/HEAD/assets/ts-belt-frame.png
--------------------------------------------------------------------------------
/tools/comment-ppx/esy.lock/opam/seq.base/files/seq.install:
--------------------------------------------------------------------------------
1 | lib:[
2 | "META.seq" {"META"}
3 | ]
4 |
--------------------------------------------------------------------------------
/tools/comment-ppx/ppx.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobily/ts-belt/HEAD/tools/comment-ppx/ppx.exe
--------------------------------------------------------------------------------
/docs/static/img/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobily/ts-belt/HEAD/docs/static/img/favicon.ico
--------------------------------------------------------------------------------
/docs/static/img/hero-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobily/ts-belt/HEAD/docs/static/img/hero-logo.png
--------------------------------------------------------------------------------
/docs/static/img/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobily/ts-belt/HEAD/docs/static/img/background.png
--------------------------------------------------------------------------------
/docs/static/img/ts-belt-frame.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobily/ts-belt/HEAD/docs/static/img/ts-belt-frame.png
--------------------------------------------------------------------------------
/docs/static/img/ts-belt-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mobily/ts-belt/HEAD/docs/static/img/ts-belt-logo.png
--------------------------------------------------------------------------------
/docs/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
3 | };
4 |
--------------------------------------------------------------------------------
/src/global.d.ts:
--------------------------------------------------------------------------------
1 | export {}
2 |
3 | declare global {
4 | namespace Belt {
5 | type UseMutableArrays = 0
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/tools/comment-ppx/esy.lock/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Reset any possible .gitignore, we want all esy.lock to be un-ignored.
3 | !*
4 |
--------------------------------------------------------------------------------
/src/Option/index.js:
--------------------------------------------------------------------------------
1 | export * from './Option.bs.js'
2 |
3 | export const Some = value => value
4 | export const None = undefined
5 |
--------------------------------------------------------------------------------
/docs/src/pages/components/Row.module.css:
--------------------------------------------------------------------------------
1 | .row {
2 | display: flex;
3 | flex-direction: row;
4 | flex-wrap: wrap;
5 | width: 100%;
6 | }
7 |
--------------------------------------------------------------------------------
/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "exclude": [
4 | "./__tests__/**/*",
5 | "./playground"
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/tools/comment-ppx/esy.lock/.gitattributes:
--------------------------------------------------------------------------------
1 |
2 | # Set eol to LF so files aren't converted to CRLF-eol on Windows.
3 | * text eol=lf linguist-generated
4 |
--------------------------------------------------------------------------------
/docs/src/pages/components/Title.module.css:
--------------------------------------------------------------------------------
1 | .title {
2 | font-size: 1.8rem;
3 | color: var(--ifm-color-gray-900);
4 | text-align: center;
5 | margin-bottom: 0;
6 | }
7 |
--------------------------------------------------------------------------------
/tools/comment-ppx/src/dune:
--------------------------------------------------------------------------------
1 | (library
2 | (name comment_ppx)
3 | (wrapped false)
4 | (public_name comment-ppx.lib)
5 | (kind ppx_rewriter)
6 | (libraries ppxlib)
7 | )
8 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "parser": "typescript",
3 | "semi": false,
4 | "singleQuote": true,
5 | "trailingComma": "all",
6 | "arrowParens": "avoid",
7 | "printWidth": 80
8 | }
9 |
--------------------------------------------------------------------------------
/tools/comment-ppx/scripts/install.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 | set -x
5 | esy install
6 | esy build
7 | find ./_build/default -name '*.exe' -exec cp "{}" ./ \;
8 | exit 0
9 |
--------------------------------------------------------------------------------
/src/pipe.js:
--------------------------------------------------------------------------------
1 | export function pipe() {
2 | let x = arguments[0]
3 |
4 | for (let i = 1, l = arguments.length; i < l; i++) {
5 | x = arguments[i](x)
6 | }
7 |
8 | return x
9 | }
10 |
--------------------------------------------------------------------------------
/docs/src/pages/styles.module.css:
--------------------------------------------------------------------------------
1 | /* stylelint-disable docusaurus/copyright-header */
2 | /**
3 | * CSS files with the .module.css suffix will be treated as CSS modules
4 | * and scoped locally.
5 | */
6 |
--------------------------------------------------------------------------------
/tools/comment-ppx/esy.lock/opam/seq.base/files/META.seq:
--------------------------------------------------------------------------------
1 | name="seq"
2 | version="[distributed with OCaml 4.07 or above]"
3 | description="dummy backward-compatibility package for iterators"
4 | requires=""
5 |
--------------------------------------------------------------------------------
/tools/comment-ppx/esy.lock/opam/base-unix.base/opam:
--------------------------------------------------------------------------------
1 | opam-version: "2.0"
2 | maintainer: "https://github.com/ocaml/opam-repository/issues"
3 | description: """
4 | Unix library distributed with the OCaml compiler
5 | """
6 |
7 |
--------------------------------------------------------------------------------
/docs/api/function.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | id: function
3 | title: Function
4 | ---
5 |
6 | import Function, { toc as functiontoc } from "./generated/_function.mdx"
7 |
8 |
9 |
10 | export const toc = functiontoc
11 |
--------------------------------------------------------------------------------
/tools/comment-ppx/esy.lock/opam/base-threads.base/opam:
--------------------------------------------------------------------------------
1 | opam-version: "2.0"
2 | maintainer: "https://github.com/ocaml/opam-repository/issues"
3 | description: """
4 | Threads library distributed with the OCaml compiler
5 | """
6 |
7 |
--------------------------------------------------------------------------------
/docs/src/theme/ReactLiveScope/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import * as Belt from '../../../..'
3 |
4 | const ReactLiveScope = {
5 | React,
6 | ...Belt,
7 | ...React,
8 | }
9 |
10 | export default ReactLiveScope
11 |
--------------------------------------------------------------------------------
/docs/api/guards.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | id: guards
3 | title: Guards
4 | ---
5 |
6 | import Guards, { toc as guardstoc } from "./generated/_guards.mdx"
7 |
8 | Various TypeScript guards.
9 |
10 |
11 |
12 | export const toc = guardstoc
13 |
--------------------------------------------------------------------------------
/docs/api/object.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | id: object
3 | title: Object (Dict)
4 | ---
5 |
6 | import Dict, { toc as dicttoc } from "./generated/_dict.mdx"
7 |
8 | Utility functions for `Object`.
9 |
10 |
11 |
12 | export const toc = dicttoc
13 |
--------------------------------------------------------------------------------
/docs/api/boolean.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | id: boolean
3 | title: Boolean
4 | ---
5 |
6 | import Boolean, { toc as booltoc } from "./generated/_bool.mdx"
7 |
8 | Utility functions for `Boolean`.
9 |
10 |
11 |
12 | export const toc = booltoc
13 |
--------------------------------------------------------------------------------
/docs/api/number.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | id: number
3 | title: Number
4 | ---
5 |
6 | import Number, { toc as numbertoc } from "./generated/_number.mdx"
7 |
8 | Utility functions for `Number`.
9 |
10 |
11 |
12 | export const toc = numbertoc
13 |
--------------------------------------------------------------------------------
/docs/src/pages/components/Column.module.css:
--------------------------------------------------------------------------------
1 | .column {
2 | display: flex;
3 | flex-direction: column;
4 | flex-basis: 100%;
5 | flex: 1;
6 | }
7 |
8 | @media screen and (max-width: 768px) {
9 | .column {
10 | margin-bottom: 1rem;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/Result/index.js:
--------------------------------------------------------------------------------
1 | export * from './Result.bs.js'
2 |
3 | export const Ok = value => {
4 | return {
5 | TAG: 0,
6 | _0: value,
7 | }
8 | }
9 |
10 | export const Error = value => {
11 | return {
12 | TAG: 1,
13 | _0: value,
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/docs/src/pages/components/Title.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | import styles from './Title.module.css'
4 |
5 | const Title = props => {
6 | const { children } = props
7 | return
{children}
8 | }
9 |
10 | export default Title
11 |
--------------------------------------------------------------------------------
/src/flow.js:
--------------------------------------------------------------------------------
1 | export function flow() {
2 | let fns = arguments
3 |
4 | return function () {
5 | let x = fns[0].apply(null, arguments)
6 |
7 | for (let i = 1, l = fns.length; i < l; i++) {
8 | x = fns[i](x)
9 | }
10 |
11 | return x
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .env
3 |
4 | .idea/
5 | .settings
6 | .vscode/
7 | node_modules/
8 | coverage/
9 |
10 | *.log
11 | *.tsbuildinfo
12 |
13 | dist/
14 | lib/
15 | playground/
16 |
17 | .merlin
18 | .bsb.lock
19 |
20 | *.bs.js
21 | *.gen.tsx
22 |
23 | ./src/**/index.ts
24 |
--------------------------------------------------------------------------------
/docs/docs/getting-started/installation.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: installation
3 | title: Installation
4 | ---
5 |
6 | Use either `npm` or `yarn` to install the package:
7 |
8 | ```shell
9 | yarn add @mobily/ts-belt
10 | ```
11 |
12 | ```shell
13 | npm install @mobily/ts-belt --save
14 | ```
15 |
--------------------------------------------------------------------------------
/benchmarks/index.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs')
2 | const path = require('path')
3 | const Benchr = require('benchr')
4 |
5 | const files = process.argv.slice(2)
6 |
7 | const runner = new Benchr(
8 | {
9 | reporter: 'console',
10 | },
11 | files,
12 | )
13 |
14 | runner.run()
15 |
--------------------------------------------------------------------------------
/docs/src/pages/components/Feature.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | import styles from './Feature.module.css'
4 |
5 | const Feature = props => {
6 | const { children } = props
7 |
8 | return {children}
9 | }
10 |
11 | export default Feature
12 |
--------------------------------------------------------------------------------
/docs/src/pages/components/Columns.module.css:
--------------------------------------------------------------------------------
1 | .columns {
2 | display: flex;
3 | flex-direction: row;
4 | flex-wrap: wrap;
5 | flex: 1;
6 | }
7 |
8 | @media screen and (max-width: 768px) {
9 | .columns {
10 | flex-direction: column;
11 | margin-bottom: 0 !important;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/benchmarks/index.markdown.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs')
2 | const path = require('path')
3 | const Benchr = require('benchr')
4 |
5 | const files = process.argv.slice(2)
6 |
7 | const runner = new Benchr(
8 | {
9 | reporter: './reporter.markdown.js',
10 | },
11 | files,
12 | )
13 |
14 | runner.run()
15 |
--------------------------------------------------------------------------------
/docs/src/pages/components/Features.module.css:
--------------------------------------------------------------------------------
1 | .features {
2 | text-align: center;
3 | max-width: 74vw;
4 | }
5 |
6 | @media screen and (max-width: 768px) {
7 | .features {
8 | max-width: 100vh;
9 | padding: 0 1rem;
10 | }
11 | }
12 |
13 | .dot {
14 | margin: 0 16px;
15 | color: #000;
16 | }
17 |
--------------------------------------------------------------------------------
/docs/src/pages/components/Feature.module.css:
--------------------------------------------------------------------------------
1 | .feature {
2 | font-size: 1.3rem;
3 | line-height: 2rem;
4 | color: var(--ifm-color-gray-700);
5 | }
6 |
7 | @media screen and (max-width: 992px) {
8 | .feature {
9 | font-size: 1.2rem;
10 | }
11 | }
12 |
13 | .feature > strong {
14 | color: #000;
15 | }
16 |
--------------------------------------------------------------------------------
/docs/.gitignore:
--------------------------------------------------------------------------------
1 | # Dependencies
2 | /node_modules
3 |
4 | # Production
5 | /build
6 |
7 | # Generated files
8 | .docusaurus
9 | .cache-loader
10 |
11 | # Misc
12 | .DS_Store
13 | .env.local
14 | .env.development.local
15 | .env.test.local
16 | .env.production.local
17 |
18 | npm-debug.log*
19 | yarn-debug.log*
20 | yarn-error.log*
21 |
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | verbose: true,
3 | // bail: true,
4 | transform: {
5 | '^.+\\.ts': 'ts-jest',
6 | },
7 | testRegex: './__tests__/.+\\.test\\.ts$',
8 | moduleFileExtensions: ['ts', 'js'],
9 | collectCoverage: true,
10 | rootDir: __dirname,
11 | maxWorkers: 2,
12 | testTimeout: 30000,
13 | }
14 |
--------------------------------------------------------------------------------
/src/AsyncData/index.js:
--------------------------------------------------------------------------------
1 | export * from './AsyncData.bs.js'
2 |
3 | export const Init = 0
4 | export const Loading = 1
5 |
6 | export const Reloading = value => {
7 | return {
8 | TAG: 0,
9 | _0: value,
10 | }
11 | }
12 |
13 | export const Complete = value => {
14 | return {
15 | TAG: 1,
16 | _0: value,
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/docs/src/pages/components/Page.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import Layout from '@theme/Layout'
3 |
4 | import styles from './Page.module.css'
5 |
6 | const Page = props => {
7 | const { children } = props
8 |
9 | return (
10 |
11 | {children}
12 |
13 | )
14 | }
15 |
16 | export default Page
17 |
--------------------------------------------------------------------------------
/__tests__/Function/coerce.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { F } from '../..'
4 |
5 | const x = ['x', 'y'] as ReadonlyArray
6 | const y = ['x', 'y'] as const
7 |
8 | describe('coerce', () => {
9 | it('provides correct types', () => {
10 | expectType(F.coerce(x))
11 | expectType<['x', 'z']>(F.coerce<['x', 'z']>(y))
12 | })
13 | })
14 |
--------------------------------------------------------------------------------
/src/types.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | export declare type Array = Belt.UseMutableArrays extends 1
4 | ? T[]
5 | : readonly T[]
6 | export declare type Mutable = { -readonly [P in keyof T]-?: T[P] }
7 | export declare type ExtractValue = Exclude
8 | export declare type UnpackArray = T extends Array
9 | ? UnpackArray
10 | : T
11 |
--------------------------------------------------------------------------------
/docs/sidebars.api.js:
--------------------------------------------------------------------------------
1 | const makeSidebar = names =>
2 | names.map(name => {
3 | return {
4 | type: 'doc',
5 | id: name,
6 | className: `sidebar-api sidebar-api-${name}`,
7 | }
8 | })
9 |
10 | module.exports = {
11 | sidebar: makeSidebar([
12 | 'pipe-flow',
13 | 'array',
14 | 'boolean',
15 | 'function',
16 | 'guards',
17 | 'number',
18 | 'object',
19 | 'option',
20 | 'result',
21 | 'string',
22 | ]),
23 | }
24 |
--------------------------------------------------------------------------------
/__tests__/String/trim.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { S } from '../..'
4 |
5 | describe('trim', () => {
6 | it('provides correct types', () => {
7 | expectType(S.trim('text'))
8 | })
9 |
10 | it('returns a new string with leading and trailing whitespace removed from string', () => {
11 | expect(S.trim(' text')).toEqual('text')
12 | })
13 |
14 | it('*', () => {
15 | expect(S.trim(' text')).toEqual('text')
16 | })
17 | })
18 |
--------------------------------------------------------------------------------
/docs/api/string.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | id: string
3 | title: String
4 | ---
5 |
6 | import String, { toc as stringtoc } from "./generated/_string.mdx"
7 |
8 | Utility functions for `String`.
9 |
10 | ```jsx live
11 | function() {
12 | const value = pipe(
13 | ['hello', 'world', '+ts', '+belt'],
14 | A.filter(S.startsWith('+')),
15 | A.join('-'),
16 | S.removeAll('+'),
17 | )
18 |
19 | return value
20 | }
21 | ```
22 |
23 |
24 |
25 | export const toc = stringtoc
26 |
--------------------------------------------------------------------------------
/__tests__/Array/makeEmpty.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { A } from '../..'
4 |
5 | describe('makeEmpty', () => {
6 | it('provides correct types', () => {
7 | expectType>(A.makeEmpty())
8 | })
9 |
10 | it('creates an empty array', () => {
11 | const result = A.makeEmpty()
12 | expect(result).toEqual([])
13 | })
14 |
15 | it('*', () => {
16 | expect(A.makeEmpty()).toEqual([])
17 | })
18 | })
19 |
--------------------------------------------------------------------------------
/__tests__/String/trimEnd.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { S } from '../..'
4 |
5 | describe('trimEnd', () => {
6 | it('provides correct types', () => {
7 | expectType(S.trim('text'))
8 | })
9 |
10 | it('returns a new string with trailing whitespace removed from string', () => {
11 | expect(S.trimEnd(' text ')).toEqual(' text')
12 | })
13 |
14 | it('*', () => {
15 | expect(S.trimEnd(' text ')).toEqual(' text')
16 | })
17 | })
18 |
--------------------------------------------------------------------------------
/__tests__/String/trimStart.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { S } from '../..'
4 |
5 | describe('trimStart', () => {
6 | it('provides correct types', () => {
7 | expectType(S.trim('text'))
8 | })
9 |
10 | it('returns a new string with leading whitespace removed from string', () => {
11 | expect(S.trimStart(' text ')).toEqual('text ')
12 | })
13 |
14 | it('*', () => {
15 | expect(S.trimStart(' text ')).toEqual('text ')
16 | })
17 | })
18 |
--------------------------------------------------------------------------------
/docs/src/pages/components/Column.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | import { useColumns } from './Columns'
4 |
5 | import styles from './Column.module.css'
6 |
7 | const Column = props => {
8 | const { children } = props
9 | const { space } = useColumns()
10 |
11 | return (
12 |
18 | {children}
19 |
20 | )
21 | }
22 |
23 | export default Column
24 |
--------------------------------------------------------------------------------
/__tests__/Array/intersperse.test.ts:
--------------------------------------------------------------------------------
1 | import { A, pipe } from '../..'
2 |
3 | const xs = [1, 2, 3, 4, 5]
4 |
5 | // TODO: expectTypes
6 | describe('intersperse', () => {
7 | it('happy', () => {
8 | const result = A.intersperse(xs, 0)
9 | expect(result).toEqual([1, 0, 2, 0, 3, 0, 4, 0, 5])
10 | })
11 | })
12 |
13 | describe('intersperse (pipe)', () => {
14 | it('happy', () => {
15 | const result = pipe(xs, A.intersperse(0))
16 | expect(result).toEqual([1, 0, 2, 0, 3, 0, 4, 0, 5])
17 | })
18 | })
19 |
--------------------------------------------------------------------------------
/__tests__/Function/tap.test.ts:
--------------------------------------------------------------------------------
1 | import { pipe, F, N, A } from '../..'
2 |
3 | describe('tap', () => {
4 | it('applies a side-effect', () => {
5 | const spy = jest.fn()
6 |
7 | A.forEach([1, 2, 3], F.tap(spy))
8 |
9 | expect(spy).toBeCalledTimes(3)
10 | })
11 |
12 | it('*', () => {
13 | expect(
14 | pipe(
15 | A.makeWithIndex(3, N.succ),
16 | F.tap(xs => console.log(xs)),
17 | A.map(value => value * 2),
18 | ),
19 | ).toEqual([2, 4, 6])
20 | })
21 | })
22 |
--------------------------------------------------------------------------------
/benchmarks/scripts/generate.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | mkdir -p ./.results
4 |
5 | results_file="./.results/results.md"
6 |
7 | rm -f $results_file
8 |
9 | glob_files=".*"
10 |
11 | complex=($(grep -HRl "$glob_files" ./complex))
12 |
13 | for i in "${complex[@]}"
14 | do
15 | node "./index.markdown.js" "$i" 2>&1 | tee -a $results_file
16 | done
17 |
18 | simple=($(grep -HRl "$glob_files" ./simple))
19 |
20 | for i in "${simple[@]}"
21 | do
22 | node "./index.markdown.js" "$i" 2>&1 | tee -a $results_file
23 | done
24 |
--------------------------------------------------------------------------------
/tools/comment-ppx/esy.lock/opam/seq.base/opam:
--------------------------------------------------------------------------------
1 | opam-version: "2.0"
2 | maintainer: " "
3 | authors: " "
4 | homepage: " "
5 | depends: [
6 | "ocaml" {>= "4.07.0"}
7 | ]
8 | dev-repo: "git+https://github.com/ocaml/ocaml.git"
9 | bug-reports: "https://caml.inria.fr/mantis/main_page.php"
10 | synopsis:
11 | "Compatibility package for OCaml's standard iterator type starting from 4.07."
12 | extra-files: [
13 | ["seq.install" "md5=026b31e1df290373198373d5aaa26e42"]
14 | ["META.seq" "md5=b33c8a1a6c7ed797816ce27df4855107"]
15 | ]
16 |
--------------------------------------------------------------------------------
/__tests__/Array/head.test.ts:
--------------------------------------------------------------------------------
1 | import { A, O } from '../..'
2 |
3 | describe('head', () => {
4 | it('returns None', () => {
5 | expect(A.head([])).toEqual(O.None)
6 | })
7 |
8 | it('returns Some', () => {
9 | expect(A.head([1, 2, 3])).toEqual(O.Some(1))
10 | expect(A.head([0, 2, 3])).toEqual(O.Some(0))
11 | expect(A.head([false, true, true])).toEqual(O.Some(false))
12 | expect(A.head([{ prop: 1 }, { prop: 2 }])).toEqual(O.Some({ prop: 1 }))
13 | expect(A.head([[1], [2]])).toEqual(O.Some([1]))
14 | })
15 | })
16 |
--------------------------------------------------------------------------------
/docs/src/pages/components/Card.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | import Link from '@docusaurus/Link'
4 | import useBaseUrl from '@docusaurus/useBaseUrl'
5 |
6 | import styles from './Card.module.css'
7 |
8 | const Card = props => {
9 | const { children, title, to } = props
10 | const link = useBaseUrl(to)
11 |
12 | return (
13 |
14 | {title}
15 | {children}
16 |
17 | )
18 | }
19 |
20 | export default Card
21 |
--------------------------------------------------------------------------------
/__tests__/Array/map.test.ts:
--------------------------------------------------------------------------------
1 | import { A, pipe } from '../..'
2 |
3 | const xs = [1, 2, 3, 4, 5]
4 |
5 | // TODO: expectType
6 | describe('map', () => {
7 | it('returns correct value', () => {
8 | const result = A.map(xs, value => value * 2)
9 | expect(result).toEqual([2, 4, 6, 8, 10])
10 | })
11 | })
12 |
13 | describe('map (pipe)', () => {
14 | it('returns correct value', () => {
15 | const result = pipe(
16 | xs,
17 | A.map(value => value * 2),
18 | )
19 |
20 | expect(result).toEqual([2, 4, 6, 8, 10])
21 | })
22 | })
23 |
--------------------------------------------------------------------------------
/__tests__/Function/toMutable.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { F } from '../..'
4 |
5 | const arr = ['x', 'y'] as ReadonlyArray
6 | const tuple = ['x', 'y'] as const
7 | const obj = {
8 | prop: '1',
9 | } as {
10 | readonly prop: string
11 | }
12 |
13 | describe('toMutable', () => {
14 | it('provides correct types', () => {
15 | expectType(F.toMutable(arr))
16 | expectType<['x', 'y']>(F.toMutable(tuple))
17 | expectType<{
18 | prop: string
19 | }>(F.toMutable(obj))
20 | })
21 | })
22 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | export { pipe } from './pipe.js'
2 | export { flow } from './flow.js'
3 |
4 | export * as F from './Function'
5 | export * as A from './Array'
6 | export * as R from './Result'
7 | export * as G from './Guards'
8 | export * as O from './Option'
9 | export * as S from './String'
10 | export * as D from './Dict'
11 | export * as B from './Bool'
12 | export * as N from './Number'
13 |
14 | export * as AD from './AsyncData'
15 | export * as ADR from './AsyncDataResult'
16 | export * as AO from './AsyncOption'
17 | export * as AR from './AsyncResult'
18 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | export { pipe } from './pipe'
2 | export { flow } from './flow'
3 |
4 | export * as F from './Function'
5 | export * as A from './Array'
6 | export * as R from './Result'
7 | export * as G from './Guards'
8 | export * as O from './Option'
9 |
10 | export * as S from './String'
11 | export * as D from './Dict'
12 | export * as B from './Bool'
13 | export * as N from './Number'
14 |
15 | export * as AD from './AsyncData'
16 | export * as ADR from './AsyncDataResult'
17 | export * as AO from './AsyncOption'
18 | export * as AR from './AsyncResult'
19 |
--------------------------------------------------------------------------------
/docs/api/array.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | id: array
3 | title: Array
4 | ---
5 |
6 | import Array, { toc as arraytoc } from "./generated/_array.mdx"
7 |
8 | Utility functions for `Array`.
9 |
10 | ```jsx live
11 | function() {
12 | const xs = A.makeWithIndex(5, index => index) // → [0, 1, 2, 3, 4]
13 | const value = pipe(
14 | xs,
15 | A.tailOrEmpty, // → [1, 2, 3, 4]
16 | A.take(2), // → [1, 2]
17 | A.map(value => value * 2), // → [2, 4]
18 | )
19 |
20 | return JSON.stringify(value)
21 | }
22 | ```
23 |
24 |
25 |
26 | export const toc = arraytoc
27 |
--------------------------------------------------------------------------------
/tools/javascript-codemods/pre/index.ts:
--------------------------------------------------------------------------------
1 | import { API, FileInfo } from 'jscodeshift'
2 |
3 | import dataFirst from './make-data-first'
4 | import spreadRest from './spread-rest-args'
5 | import uncurry from './uncurry-functions'
6 | import rename from './rename-identifiers'
7 |
8 | const transform = (file: FileInfo, api: API) => {
9 | const j = api.jscodeshift
10 | const source = [spreadRest, dataFirst, uncurry, rename].reduce((acc, fn) => {
11 | return fn(acc, j)
12 | }, file.source)
13 |
14 | return j(source).toSource()
15 | }
16 |
17 | export default transform
18 |
--------------------------------------------------------------------------------
/benchmarks/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ts-belt-benchmarks",
3 | "private": true,
4 | "version": "0.1.0",
5 | "main": "index.js",
6 | "license": "MIT",
7 | "scripts": {
8 | "test": "NODE_ENV=test node ./ensure-identical-output.js",
9 | "start": "bash ./scripts/run.sh",
10 | "generate": "bash ./scripts/generate.sh"
11 | },
12 | "devDependencies": {
13 | "benchr": "^4.3.0"
14 | },
15 | "dependencies": {
16 | "list": "^2.0.19",
17 | "lodash": "^4.17.21",
18 | "rambda": "^6.9.0",
19 | "ramda": "^0.27.1",
20 | "remeda": "^0.0.32"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/__tests__/Array/sort.test.ts:
--------------------------------------------------------------------------------
1 | import { A, pipe } from '../..'
2 |
3 | const xs = [9, 2, 6, 4, 8, 5, 1, 7, 3]
4 |
5 | // TODO: expectType
6 | describe('sort', () => {
7 | it('returns correctly sorted array', () => {
8 | const result = A.sort(xs, (a, b) => a - b)
9 | expect(result).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9])
10 | })
11 | })
12 |
13 | describe('sort (pipe)', () => {
14 | it('returns correctly sorted array', () => {
15 | const result = pipe(
16 | xs,
17 | A.sort((a, b) => a - b),
18 | )
19 | expect(result).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9])
20 | })
21 | })
22 |
--------------------------------------------------------------------------------
/tools/typescript-codemods/rename-generics.ts:
--------------------------------------------------------------------------------
1 | import { API } from 'jscodeshift'
2 |
3 | const transform = (source: string, j: API['jscodeshift']): string => {
4 | const generics = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I']
5 |
6 | // rename T1, T2, T3… to A, B, C…
7 | return j(source)
8 | .find(j.Identifier)
9 | .filter(p => {
10 | return /^T[0-9]$/.test(p.value.name)
11 | })
12 | .replaceWith(p => {
13 | const [, index] = p.value.name.split('')
14 | return j.identifier(generics[parseInt(index, 10) - 1])
15 | })
16 | .toSource()
17 | }
18 |
19 | export default transform
20 |
--------------------------------------------------------------------------------
/docs/sidebars.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | sidebar: [
3 | {
4 | type: 'doc',
5 | id: 'introduction',
6 | },
7 | {
8 | type: 'category',
9 | label: 'Getting started',
10 | collapsed: false,
11 | items: [
12 | 'getting-started/installation',
13 | 'getting-started/config',
14 | 'getting-started/usage',
15 | ],
16 | },
17 | {
18 | type: 'doc',
19 | id: 'changelog',
20 | },
21 | {
22 | type: 'link',
23 | label: 'Go to API',
24 | href: '/api/array',
25 | className: 'sidebar-api-button',
26 | },
27 | ],
28 | }
29 |
--------------------------------------------------------------------------------
/tools/rescript-externals/Externals.res:
--------------------------------------------------------------------------------
1 | external coerce: 'a => 'b = "%identity"
2 | external raw_comment: string => 'a = "#raw_stmt"
3 |
4 | external unsafeToJsExn: 'a => Js.Exn.t = "%identity"
5 |
6 | @val
7 | external assign: (Js.Dict.t<'a>, Js.Dict.t<'a>) => Js.Dict.t<'a> = "Object.assign"
8 |
9 | @val
10 | external assign2: (Js.Dict.t<'a>, Js.Dict.t<'a>, Js.Dict.t<'a>) => Js.Dict.t<'a> = "Object.assign"
11 |
12 | @val
13 | external entries: Js.Dict.t<'a> => array<(Js.Dict.key, 'a)> = "Object.entries"
14 |
15 | @send
16 | external trimEnd: string => string = "trimEnd"
17 |
18 | @send
19 | external trimStart: string => string = "trimStart"
20 |
--------------------------------------------------------------------------------
/docs/src/pages/components/Button.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import clsx from 'clsx'
3 |
4 | import Link from '@docusaurus/Link'
5 | import useBaseUrl from '@docusaurus/useBaseUrl'
6 |
7 | import styles from './Button.module.css'
8 |
9 | const Button = props => {
10 | const { children, to, variant } = props
11 |
12 | return (
13 |
21 | {children}
22 |
23 | )
24 | }
25 |
26 | export default Button
27 |
--------------------------------------------------------------------------------
/docs/src/pages/components/Row.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | import styles from './Row.module.css'
4 |
5 | const Row = props => {
6 | const {
7 | children,
8 | alignX = 'flex-start',
9 | marginBottom = 0,
10 | padding = 0,
11 | paddingX,
12 | paddingY,
13 | } = props
14 | return (
15 |
23 | {children}
24 |
25 | )
26 | }
27 |
28 | export default Row
29 |
--------------------------------------------------------------------------------
/__tests__/String/head.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { S, O } from '../..'
4 |
5 | describe('head', () => {
6 | it('provides correct types', () => {
7 | expectType>(S.head('text'))
8 | })
9 |
10 | it('returns None if the given string is empty', () => {
11 | expect(S.head('')).toEqual(O.None)
12 | })
13 |
14 | it('Returns Some(value) where value is the first character of the string', () => {
15 | expect(S.head('random-text')).toEqual(O.Some('r'))
16 | })
17 |
18 | it('*', () => {
19 | const { Some } = O
20 | expect(S.head('random-text')).toEqual(Some('r'))
21 | })
22 | })
23 |
--------------------------------------------------------------------------------
/__tests__/String/last.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { S, O } from '../..'
4 |
5 | describe('last', () => {
6 | it('provides correct types', () => {
7 | expectType>(S.last('text'))
8 | })
9 |
10 | it('returns None if the given string is empty', () => {
11 | expect(S.last('')).toEqual(O.None)
12 | })
13 |
14 | it('returns Some(value) where value is the last character of the string', () => {
15 | expect(S.last('random-text')).toEqual(O.Some('t'))
16 | })
17 |
18 | it('*', () => {
19 | const { Some } = O
20 | expect(S.last('random-text')).toEqual(Some('t'))
21 | })
22 | })
23 |
--------------------------------------------------------------------------------
/__tests__/Result/getExn.test.ts:
--------------------------------------------------------------------------------
1 | import { pipe, R } from '../..'
2 |
3 | describe('getExn', () => {
4 | it('should throw an error', () => {
5 | expect(() => {
6 | pipe(R.fromNullable(null, 'this is bad'), R.getExn)
7 | }).toThrow(Object)
8 | })
9 |
10 | it('returns a value', () => {
11 | expect(pipe(R.fromNullable('value', 'this is bad'), R.getExn)).toEqual(
12 | 'value',
13 | )
14 | })
15 |
16 | it('*', () => {
17 | expect(
18 | pipe(
19 | R.fromNullable('hello', 'oops!'),
20 | R.map(value => `${value} world!`),
21 | R.getExn,
22 | ),
23 | ).toEqual('hello world!')
24 | })
25 | })
26 |
--------------------------------------------------------------------------------
/docs/src/pages/components/Features.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | import styles from './Features.module.css'
4 |
5 | const Features = props => {
6 | const { children } = props
7 | const length = React.Children.count(children)
8 |
9 | return (
10 |
11 | {React.Children.map(children, (child, index) => {
12 | return (
13 |
14 | {child}
15 | {index === length - 1 ? null : (
16 | ·
17 | )}
18 |
19 | )
20 | })}
21 |
22 | )
23 | }
24 |
25 | export default Features
26 |
--------------------------------------------------------------------------------
/__tests__/Array/makeWithIndex.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { A } from '../..'
4 |
5 | describe('makeWithIndex', () => {
6 | it('provides correct types', () => {
7 | expectType>(A.makeWithIndex(4, index => `${index}`))
8 | expectType>(A.makeWithIndex(4, index => index * 2))
9 | })
10 |
11 | it('returns a new array of size `n`', () => {
12 | const result = A.makeWithIndex(5, index => index * 2)
13 | expect(result).toEqual([0, 2, 4, 6, 8])
14 | })
15 |
16 | it('*', () => {
17 | expect(A.makeWithIndex(5, index => index * 2)).toEqual([0, 2, 4, 6, 8])
18 | })
19 | })
20 |
--------------------------------------------------------------------------------
/__tests__/Array/get.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 | import { A, O } from '../..'
3 |
4 | describe('get', () => {
5 | it('provides correct types', () => {
6 | expectType>(A.get([1, 2, 3, 4, 5], 0))
7 | })
8 |
9 | it('returns None', () => {
10 | expect(A.get([], 0)).toEqual(O.None)
11 | expect(A.get([1, 2, 3], 3)).toEqual(O.None)
12 | })
13 |
14 | it('returns Some', () => {
15 | expect(A.get([1, 2, 3], 0)).toEqual(O.Some(1))
16 | expect(A.get([0, 2, 3], 0)).toEqual(O.Some(0))
17 | expect(A.get([true, true, false], 2)).toEqual(O.Some(false))
18 | expect(A.get([[1], [2]], 1)).toEqual(O.Some([2]))
19 | })
20 | })
21 |
--------------------------------------------------------------------------------
/benchmarks/native.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | pipe: (...fns) => (arg) => fns.reduce((arg, fn) => fn(arg), arg),
3 | find: (closure) => (array) => array.find(closure),
4 | map: (closure) => (array) => array.map(closure),
5 | filter: (closure) => (array) => array.filter(closure),
6 | flat: (array) => array.flat(),
7 | deepFlat: (array) => array.flat(Infinity),
8 | forEach: (closure) => (array) => array.forEach(closure),
9 | fromEntries: (entries) => Object.fromEntries(entries),
10 | entries: (object) => Object.entries(object),
11 | reduce: (closure, init) => (array) => array.reduce(closure, init),
12 | safeSort: (closure) => (array) => [...array].sort(closure),
13 | }
14 |
--------------------------------------------------------------------------------
/__tests__/Array/take.test.ts:
--------------------------------------------------------------------------------
1 | import { A } from '../..'
2 |
3 | describe('take', () => {
4 | it('returns an empty array', () => {
5 | expect(A.take([1, 2, 3], -1)).toEqual([])
6 | expect(A.take([], 0)).toEqual([])
7 | expect(A.take([1, 2, 3], 0)).toEqual([])
8 | })
9 |
10 | it('returns a new array including the first `n` items', () => {
11 | expect(A.take([1], 1)).toEqual([1])
12 | expect(A.take([1, 2, 3], 1)).toEqual([1])
13 | expect(A.take([[1], [2]], 1)).toEqual([[1]])
14 | expect(A.take([true, true, false], 2)).toEqual([true, true])
15 | expect(A.take([1, 2, 3], 3)).toEqual([1, 2, 3])
16 | expect(A.take([1, 2, 3], 4)).toEqual([1, 2, 3])
17 | })
18 | })
19 |
--------------------------------------------------------------------------------
/docs/src/pages/components/Columns.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | import styles from './Columns.module.css'
4 |
5 | const Context = React.createContext({
6 | space: 0,
7 | })
8 |
9 | export const useColumns = () => React.useContext(Context)
10 |
11 | const Columns = props => {
12 | const { children, space, marginBottom = 0 } = props
13 | return (
14 |
15 |
22 | {children}
23 |
24 |
25 | )
26 | }
27 |
28 | export default Columns
29 |
--------------------------------------------------------------------------------
/benchmarks/scripts/run.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | mkdir -p ./.results
4 |
5 | date_now=$(date "+%F-%H-%M")
6 | results_file="./.results/results-$date_now.txt"
7 |
8 | rm -f $results_file
9 |
10 | glob_files=".*"
11 |
12 | complex=($(grep -HRl "$glob_files" ./complex))
13 |
14 | for i in "${complex[@]}"
15 | do
16 | node "./index.js" "$i" 2>&1 | tee -a $results_file
17 | sed -i '' "s/\\[23m//g" $results_file
18 | sed -i '' "s/\\[3m//g" $results_file
19 | done
20 |
21 | simple=($(grep -HRl "$glob_files" ./simple))
22 |
23 | for i in "${simple[@]}"
24 | do
25 | node "./index.js" "$i" 2>&1 | tee -a $results_file
26 | sed -i '' "s/\\[23m//g" $results_file
27 | sed -i '' "s/\\[3m//g" $results_file
28 | done
29 |
--------------------------------------------------------------------------------
/__tests__/Result/isOk.test.ts:
--------------------------------------------------------------------------------
1 | import { pipe, R } from '../..'
2 |
3 | describe('isOk', () => {
4 | it('returns true', () => {
5 | expect(R.isOk(R.Ok('this is fine'))).toBeTruthy()
6 | expect(pipe(R.fromNullable('value', 'this is bad'), R.isOk)).toBeTruthy()
7 | })
8 |
9 | it('returns false', () => {
10 | expect(R.isOk(R.Error('this is bad'))).toBeFalsy()
11 | expect(pipe(R.fromNullable(null, 'this is bad'), R.isOk)).toBeFalsy()
12 | })
13 |
14 | it('*', () => {
15 | expect(R.isOk(R.Ok('good'))).toEqual(true)
16 | expect(pipe(R.fromNullable(4, 'error'), R.isOk)).toEqual(true)
17 | expect(R.isOk(R.Error('bad'))).toEqual(false)
18 | expect(pipe(R.fromNullable(null, 'error'), R.isOk)).toEqual(false)
19 | })
20 | })
21 |
--------------------------------------------------------------------------------
/__tests__/Number/pred.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { N, pipe } from '../..'
4 |
5 | describe('pred', () => {
6 | it('provides correct types', () => {
7 | expectType(N.pred(2))
8 | })
9 |
10 | it('subtracts 1 from the given number', () => {
11 | expect(N.pred(4)).toEqual(3)
12 | })
13 |
14 | it('*', () => {
15 | expect(N.pred(6)).toEqual(5)
16 | })
17 | })
18 |
19 | describe('pred (pipe)', () => {
20 | it('provides correct types', () => {
21 | expectType(pipe(3, N.pred))
22 | })
23 |
24 | it('subtracts 1 from the given number', () => {
25 | expect(pipe(2, N.pred)).toEqual(1)
26 | })
27 |
28 | it('*', () => {
29 | expect(pipe(5, N.pred)).toEqual(4)
30 | })
31 | })
32 |
--------------------------------------------------------------------------------
/__tests__/Guards/isNullable.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { G, pipe } from '../..'
4 |
5 | describe('isNullable', () => {
6 | it('provides correct types', () => {
7 | const x = '' as unknown as null | string
8 |
9 | if (G.isNullable(x)) {
10 | expectType(x)
11 | }
12 | })
13 |
14 | it('determines whether the provided value is nullable', () => {
15 | expect(G.isNullable(undefined)).toEqual(true)
16 | expect(G.isNullable(null)).toEqual(true)
17 | })
18 |
19 | it('*', () => {
20 | expect(G.isNullable(null)).toEqual(true)
21 | })
22 | })
23 |
24 | describe('isNullable (pipe)', () => {
25 | it('*', () => {
26 | expect(pipe(undefined, G.isNullable)).toEqual(true)
27 | })
28 | })
29 |
--------------------------------------------------------------------------------
/__tests__/Result/isError.test.ts:
--------------------------------------------------------------------------------
1 | import { pipe, R } from '../..'
2 |
3 | describe('isError', () => {
4 | it('returns true', () => {
5 | expect(R.isError(R.Error('bad'))).toBeTruthy()
6 | expect(pipe(R.fromNullable(null, 'this is bad'), R.isError)).toBeTruthy()
7 | })
8 |
9 | it('returns false', () => {
10 | expect(R.isError(R.Ok('good'))).toBeFalsy()
11 | expect(pipe(R.fromNullable('value', 'this is bad'), R.isError)).toBeFalsy()
12 | })
13 |
14 | it('*', () => {
15 | expect(R.isError(R.Error('bad'))).toEqual(true)
16 | expect(pipe(R.fromNullable(null, 'error'), R.isError)).toEqual(true)
17 | expect(R.isError(R.Ok('good'))).toEqual(false)
18 | expect(pipe(R.fromNullable(4, 'error'), R.isError)).toEqual(false)
19 | })
20 | })
21 |
--------------------------------------------------------------------------------
/__tests__/Number/add.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { N, pipe } from '../..'
4 |
5 | describe('add', () => {
6 | it('provides correct types', () => {
7 | expectType(N.add(1, 2))
8 | })
9 |
10 | it('returns the sum of two numbers', () => {
11 | expect(N.add(10, 20)).toEqual(30)
12 | })
13 |
14 | it('*', () => {
15 | expect(N.add(10, 20)).toEqual(30)
16 | })
17 | })
18 |
19 | describe('add (pipe)', () => {
20 | it('provides correct types', () => {
21 | expectType(pipe(1, N.add(2)))
22 | })
23 |
24 | it('returns the sum of two numbers', () => {
25 | expect(pipe(10, N.add(20))).toEqual(30)
26 | })
27 |
28 | it('*', () => {
29 | expect(pipe(5, N.add(10))).toEqual(15)
30 | })
31 | })
32 |
--------------------------------------------------------------------------------
/__tests__/Number/divide.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { N, pipe } from '../..'
4 |
5 | describe('divide', () => {
6 | it('provides correct types', () => {
7 | expectType(N.divide(1, 2))
8 | })
9 |
10 | it('divides two numbers', () => {
11 | expect(N.divide(20, 10)).toEqual(2)
12 | })
13 |
14 | it('*', () => {
15 | expect(N.divide(20, 5)).toEqual(4)
16 | })
17 | })
18 |
19 | describe('divide (pipe)', () => {
20 | it('provides correct types', () => {
21 | expectType(pipe(1, N.divide(2)))
22 | })
23 |
24 | it('divides two numbers', () => {
25 | expect(pipe(20, N.divide(2))).toEqual(10)
26 | })
27 |
28 | it('*', () => {
29 | expect(pipe(40, N.divide(4))).toEqual(10)
30 | })
31 | })
32 |
--------------------------------------------------------------------------------
/tools/comment-ppx/esy.lock/overrides/opam__s__ocamlbuild_opam__c__0.14.0_opam_override/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "build": [
3 | [
4 | "bash",
5 | "-c",
6 | "#{os == 'windows' ? 'patch -p1 < ocamlbuild-0.14.0.patch' : 'true'}"
7 | ],
8 | [
9 | "make",
10 | "-f",
11 | "configure.make",
12 | "all",
13 | "OCAMLBUILD_PREFIX=#{self.install}",
14 | "OCAMLBUILD_BINDIR=#{self.bin}",
15 | "OCAMLBUILD_LIBDIR=#{self.lib}",
16 | "OCAMLBUILD_MANDIR=#{self.man}",
17 | "OCAMLBUILD_NATIVE=true",
18 | "OCAMLBUILD_NATIVE_TOOLS=true"
19 | ],
20 | [
21 | "make",
22 | "check-if-preinstalled",
23 | "all",
24 | "#{os == 'windows' ? 'install' : 'opam-install'}"
25 | ]
26 | ]
27 | }
28 |
--------------------------------------------------------------------------------
/src/AsyncDataResult/index.js:
--------------------------------------------------------------------------------
1 | export * from './AsyncDataResult.bs.js'
2 |
3 | export const Init = 0
4 | export const Loading = 1
5 |
6 | export const ReloadingOk = value => {
7 | return {
8 | TAG: 0,
9 | _0: {
10 | TAG: 0,
11 | _0: value,
12 | },
13 | }
14 | }
15 |
16 | export const ReloadingError = value => {
17 | return {
18 | TAG: 0,
19 | _0: {
20 | TAG: 1,
21 | _0: value,
22 | },
23 | }
24 | }
25 |
26 | export const CompleteOk = value => {
27 | return {
28 | TAG: 1,
29 | _0: {
30 | TAG: 0,
31 | _0: value,
32 | },
33 | }
34 | }
35 |
36 | export const CompleteError = value => {
37 | return {
38 | TAG: 1,
39 | _0: {
40 | TAG: 1,
41 | _0: value,
42 | },
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/__tests__/Number/multiply.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { N, pipe } from '../..'
4 |
5 | describe('multiply', () => {
6 | it('provides correct types', () => {
7 | expectType(N.multiply(2, 2))
8 | })
9 |
10 | it('multiplies two numbers', () => {
11 | expect(N.multiply(2, 4)).toEqual(8)
12 | })
13 |
14 | it('*', () => {
15 | expect(N.multiply(3, 6)).toEqual(18)
16 | })
17 | })
18 |
19 | describe('multiply (pipe)', () => {
20 | it('provides correct types', () => {
21 | expectType(pipe(3, N.multiply(6)))
22 | })
23 |
24 | it('multiplies two numbers', () => {
25 | expect(pipe(2, N.multiply(2))).toEqual(4)
26 | })
27 |
28 | it('*', () => {
29 | expect(pipe(8, N.multiply(4))).toEqual(32)
30 | })
31 | })
32 |
--------------------------------------------------------------------------------
/docs/src/pages/components/Button.module.css:
--------------------------------------------------------------------------------
1 | .button {
2 | height: 56px;
3 | display: flex;
4 | align-items: center;
5 | justify-content: center;
6 | padding: 0 40px;
7 | font-size: 1rem;
8 | text-transform: uppercase;
9 | letter-spacing: 3px;
10 | }
11 |
12 | .buttonOutline {
13 | border: 4px solid var(--ifm-color-gray-900);
14 | color: var(--ifm-color-gray-900);
15 | border-radius: 4px;
16 | }
17 |
18 | .buttonOutline:hover {
19 | border-color: var(--ifm-color-primary);
20 | color: var(--ifm-color-primary);
21 | }
22 |
23 | .buttonFull {
24 | border: none;
25 | background-color: var(--ifm-color-gray-900);
26 | color: var(--ifm-color-white);
27 | border-radius: 4px;
28 | }
29 |
30 | .buttonFull:hover {
31 | background-color: var(--ifm-color-primary);
32 | }
33 |
--------------------------------------------------------------------------------
/__tests__/Array/getBy.test.ts:
--------------------------------------------------------------------------------
1 | import { A, O } from '../..'
2 |
3 | describe('getBy', () => {
4 | it('returns None', () => {
5 | expect(A.getBy([1, 2, 3], n => n === 0)).toEqual(O.None)
6 | expect(A.getBy([false, false, false], state => state)).toEqual(O.None)
7 | expect(
8 | A.getBy([{ prop: null }, { prop: false }, { prop: undefined }], obj => Boolean(obj.prop)),
9 | ).toEqual(O.None)
10 | })
11 |
12 | it('returns Some', () => {
13 | expect(A.getBy(['a', 'ab', 'bc'], str => str.length === 2)).toEqual(O.Some('ab'))
14 | expect(A.getBy([1, 2, 3], value => value === 2)).toEqual(O.Some(2))
15 | expect(
16 | A.getBy([{ prop: 'ab' }, { prop: 'abc' }, { prop: 'bcd' }], obj => obj.prop.length > 2),
17 | ).toEqual(O.Some({ prop: 'abc' }))
18 | })
19 | })
20 |
--------------------------------------------------------------------------------
/__tests__/Array/splitAt.test.ts:
--------------------------------------------------------------------------------
1 | import { A, O } from '../..'
2 |
3 | describe('splitAt', () => {
4 | it('returns None', () => {
5 | expect(A.splitAt([], 1)).toEqual(O.None)
6 | expect(A.splitAt([1, 2, 3], -1)).toEqual(O.None)
7 | expect(A.splitAt([1, 2, 3], 4)).toEqual(O.None)
8 | })
9 |
10 | it('returns Some', () => {
11 | expect(A.splitAt([], 0)).toEqual(O.Some([[], []]))
12 | expect(A.splitAt([1], 1)).toEqual(O.Some([[1], []]))
13 | expect(A.splitAt([1, 2], 1)).toEqual(O.Some([[1], [2]]))
14 | expect(A.splitAt([true, true, false], 2)).toEqual(
15 | O.Some([[true, true], [false]]),
16 | )
17 | expect(A.splitAt([[1], [2], [3], [4]], 2)).toEqual(
18 | O.Some([
19 | [[1], [2]],
20 | [[3], [4]],
21 | ]),
22 | )
23 | })
24 | })
25 |
--------------------------------------------------------------------------------
/__tests__/Array/tail.test.ts:
--------------------------------------------------------------------------------
1 | import { A, O, pipe } from '../..'
2 |
3 | describe('tail', () => {
4 | it('returns None', () => {
5 | expect(A.tail([])).toEqual(O.None)
6 | })
7 |
8 | it('returns Some', () => {
9 | expect(A.tail([1, 2, 3])).toEqual(O.Some([2, 3]))
10 | expect(A.tail([true, true, false])).toEqual(O.Some([true, false]))
11 | expect(A.tail([{ prop: 1 }, { prop: 2 }])).toEqual(O.Some([{ prop: 2 }]))
12 | expect(A.tail([[1], [2], [3]])).toEqual(O.Some([[2], [3]]))
13 | })
14 |
15 | it('*', () => {
16 | const { Some, None } = O
17 |
18 | expect(A.tail([1, 2, 3])).toEqual(Some([2, 3]))
19 | expect(A.tail([1])).toEqual(Some([]))
20 | expect(A.tail([])).toEqual(None)
21 | expect(pipe([1, 2, 3, 4], A.tail)).toEqual(Some([2, 3, 4]))
22 | })
23 | })
24 |
--------------------------------------------------------------------------------
/__tests__/Array/union.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { A, pipe } from '../..'
4 |
5 | describe('difference', () => {
6 | it('provides correct types', () => {
7 | expectType>(A.union(['', 'hello', 'world'], ['']))
8 | })
9 |
10 | it('*', () => {
11 | expect(A.union([1, 2, 3, 4], [3, 4, 5, 6])).toEqual([1, 2, 3, 4, 5, 6])
12 | })
13 | })
14 |
15 | describe('union (pipe)', () => {
16 | it('provides correct types', () => {
17 | expectType>(
18 | pipe([5, 2, 3, 5, 6], A.union([5, 2, 3, 1, 5, 4])),
19 | )
20 | })
21 |
22 | it('*', () => {
23 | expect(pipe([5, 2, 3, 5, 6], A.union([5, 2, 3, 1, 5, 4]))).toEqual(
24 | // prettier-ignore
25 | [5, 2, 3, 6, 1, 4],
26 | )
27 | })
28 | })
29 |
--------------------------------------------------------------------------------
/__tests__/Guards/isNull.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { G, pipe } from '../..'
4 |
5 | describe('isNull', () => {
6 | it('provides correct types', () => {
7 | const x = null
8 |
9 | if (G.isNull(x)) {
10 | expectType(x)
11 | }
12 |
13 | const y: unknown = null
14 |
15 | if (G.isNull(y)) {
16 | expectType(y)
17 | }
18 | })
19 |
20 | it('determines whether the provided value is null', () => {
21 | expect(G.isNull(undefined)).toEqual(false)
22 | expect(G.isNull(null)).toEqual(true)
23 | })
24 |
25 | it('*', () => {
26 | expect(G.isNull(null)).toEqual(true)
27 | })
28 | })
29 |
30 | describe('isNull (pipe)', () => {
31 | it('*', () => {
32 | expect(pipe(null, G.isNull)).toEqual(true)
33 | })
34 | })
35 |
--------------------------------------------------------------------------------
/bsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@mobily/ts-belt",
3 | "version": "3.0.0",
4 | "namespace": false,
5 | "bsc-flags": ["-bs-super-errors", "-bs-no-version-header"],
6 | "gentypeconfig": {
7 | "language": "typescript",
8 | "importPath": "relative",
9 | "debug": {
10 | "all": false
11 | },
12 | "exportInterfaces": false
13 | },
14 | "suffix": ".bs.js",
15 | "package-specs": {
16 | "module": "es6",
17 | "in-source": true
18 | },
19 | "sources": [
20 | {
21 | "dir": "src",
22 | "subdirs": true
23 | },
24 | {
25 | "dir": "tools/rescript-externals"
26 | }
27 | ],
28 | "bs-dependencies": ["@ryyppy/rescript-promise"],
29 | "bs-dev-dependencies": [],
30 | "ppx-flags": [
31 | ["./tools/comment-ppx/ppx.exe -as-ppx"]
32 | ]
33 | }
34 |
--------------------------------------------------------------------------------
/__tests__/Number/succ.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { N, A, pipe } from '../..'
4 |
5 | describe('succ', () => {
6 | it('provides correct types', () => {
7 | expectType(N.succ(2))
8 | })
9 |
10 | it('adds 1 to the given number', () => {
11 | expect(N.succ(4)).toEqual(5)
12 | })
13 |
14 | it('*', () => {
15 | expect(N.succ(0)).toEqual(1)
16 | expect(A.makeWithIndex(4, N.succ)).toEqual([1, 2, 3, 4])
17 | })
18 | })
19 |
20 | describe('succ (pipe)', () => {
21 | it('provides correct types', () => {
22 | expectType(pipe(3, N.succ))
23 | })
24 |
25 | it('adds 1 to the given number', () => {
26 | expect(pipe(2, N.succ)).toEqual(3)
27 | })
28 |
29 | it('*', () => {
30 | expect(pipe(5, N.succ)).toEqual(6)
31 | })
32 | })
33 |
--------------------------------------------------------------------------------
/__tests__/Array/all.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { A, pipe } from '../..'
4 |
5 | describe('all', () => {
6 | it('provides correct types', () => {
7 | expectType(A.all(['hello', 'world'], value => value.length > 0))
8 | })
9 |
10 | it('*', () => {
11 | expect(A.all(['hello', 'world'], value => value.length > 0)).toEqual(true)
12 | })
13 | })
14 |
15 | describe('all (pipe)', () => {
16 | it('provides correct types', () => {
17 | expectType(
18 | pipe(
19 | [1, 2, 3, 4, 5],
20 | A.all(value => value > 0),
21 | ),
22 | )
23 | })
24 |
25 | it('*', () => {
26 | expect(
27 | pipe(
28 | [1, 2, 3, 4, 5],
29 | A.all(value => value > 3),
30 | ),
31 | ).toEqual(false)
32 | })
33 | })
34 |
--------------------------------------------------------------------------------
/__tests__/Number/modulo.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { N, pipe } from '../..'
4 |
5 | describe('modulo', () => {
6 | it('provides correct types', () => {
7 | expectType(N.modulo(30, 6))
8 | })
9 |
10 | it('returns the remainder of a number division', () => {
11 | expect(N.modulo(20, 4)).toEqual(0)
12 | })
13 |
14 | it('*', () => {
15 | expect(N.modulo(20, 6)).toEqual(2)
16 | })
17 | })
18 |
19 | describe('modulo (pipe)', () => {
20 | it('provides correct types', () => {
21 | expectType(pipe(30, N.modulo(6)))
22 | })
23 |
24 | it('returns the remainder of a number division', () => {
25 | expect(pipe(20, N.modulo(2))).toEqual(0)
26 | })
27 |
28 | it('*', () => {
29 | expect(pipe(30, N.modulo(4))).toEqual(2)
30 | })
31 | })
32 |
--------------------------------------------------------------------------------
/docs/sidebars.benchmarks.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | sidebar: [
3 | {
4 | type: 'doc',
5 | id: 'introduction',
6 | },
7 | {
8 | type: 'category',
9 | label: 'v3.12.0',
10 | collapsed: false,
11 | items: ['v3.12.0/macbook-pro-2021'],
12 | },
13 | {
14 | type: 'category',
15 | label: 'v3.7.0',
16 | collapsed: false,
17 | items: ['v3.7.0/macbook-pro-2017', 'v3.7.0/macbook-air-2020'],
18 | },
19 | {
20 | type: 'category',
21 | label: 'v3.0.0',
22 | collapsed: false,
23 | items: [
24 | 'v3.0.0/macbook-pro-2017',
25 | 'v3.0.0/macbook-pro-2019',
26 | 'v3.0.0/macbook-air-2020',
27 | 'v3.0.0/macbook-pro-2021',
28 | 'v3.0.0/windows-10-i7-10700k',
29 | ],
30 | },
31 | ],
32 | }
33 |
--------------------------------------------------------------------------------
/__tests__/Option/tap.test.ts:
--------------------------------------------------------------------------------
1 | import { pipe, O, A } from '../..'
2 |
3 | describe('tap', () => {
4 | it('applies a side-effect', () => {
5 | const spy = jest.fn()
6 | const value = pipe(
7 | O.fromNullable(['hello', 'world']),
8 | O.flatMap(A.head),
9 | O.tap(str => {
10 | spy()
11 | expect(str).toEqual('hello')
12 | }),
13 | O.getWithDefault(''),
14 | )
15 |
16 | expect(spy).toBeCalledTimes(1)
17 | expect(value).toEqual('hello')
18 | })
19 |
20 | it('*', () => {
21 | expect(
22 | pipe(
23 | O.fromNullable(['hello', 'world']),
24 | O.flatMap(A.get(1)),
25 | O.tap(str => {
26 | console.log(str) // ⬅️ 'world'
27 | }),
28 | O.getWithDefault(''),
29 | ),
30 | ).toEqual('world')
31 | })
32 | })
33 |
--------------------------------------------------------------------------------
/__tests__/Number/subtract.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { N, pipe } from '../..'
4 |
5 | describe('subtract', () => {
6 | it('provides correct types', () => {
7 | expectType(N.subtract(2, 1))
8 | })
9 |
10 | it('returns the difference of two numbers', () => {
11 | expect(N.subtract(20, 10)).toEqual(10)
12 | })
13 |
14 | it('*', () => {
15 | expect(N.subtract(20, 10)).toEqual(10)
16 | })
17 | })
18 |
19 | describe('subtract (pipe)', () => {
20 | it('provides correct types', () => {
21 | expectType(pipe(2, N.subtract(1)))
22 | })
23 |
24 | it('returns the difference of two numbers', () => {
25 | expect(pipe(20, N.subtract(10))).toEqual(10)
26 | })
27 |
28 | it('*', () => {
29 | expect(pipe(15, N.subtract(10))).toEqual(5)
30 | })
31 | })
32 |
--------------------------------------------------------------------------------
/tools/javascript-codemods/pre/spread-rest-args.ts:
--------------------------------------------------------------------------------
1 | import { API } from 'jscodeshift'
2 |
3 | const transform = (source: string, j: API['jscodeshift']): string => {
4 | const root = j(source)
5 |
6 | root
7 | .find(j.Identifier, {
8 | name: 'restArgs',
9 | })
10 | .filter(p => {
11 | return p.parent.value.type === 'FunctionExpression'
12 | })
13 | .replaceWith(p => {
14 | return j.restElement(p.value)
15 | })
16 | .toSource()
17 |
18 | root
19 | .find(j.Identifier, {
20 | name: 'restArgs',
21 | })
22 | .filter(p => {
23 | return p.parent.value.type === 'CallExpression'
24 | })
25 | .replaceWith(p => {
26 | return j.spreadElement(p.value)
27 | })
28 | .toSource()
29 |
30 | return root.toSource()
31 | }
32 |
33 | export default transform
34 |
--------------------------------------------------------------------------------
/__tests__/Array/flatMap.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { A, pipe } from '../..'
4 |
5 | const xs = [1, 2, 3]
6 |
7 | describe('flatMap', () => {
8 | it('provides correct types', () => {
9 | expectType>(
10 | A.flatMap(['hello', 'world'], value => {
11 | return [value.length]
12 | }),
13 | )
14 | })
15 |
16 | it('returns correct value', () => {
17 | const result = A.flatMap(xs, value => [value * 2, value * 10])
18 | expect(result).toEqual([2, 10, 4, 20, 6, 30])
19 | })
20 | })
21 |
22 | describe('flatMap (pipe)', () => {
23 | it('returns correct value', () => {
24 | const result = pipe(
25 | xs,
26 | A.flatMap(value => [value, value + 10]),
27 | )
28 |
29 | expect(result).toEqual([1, 11, 2, 12, 3, 13])
30 | })
31 | })
32 |
--------------------------------------------------------------------------------
/__tests__/Array/intersection.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { A, pipe } from '../..'
4 |
5 | describe('intersection', () => {
6 | it('provides correct types', () => {
7 | expectType>(
8 | A.intersection(['', 'hello', 'world'], ['']),
9 | )
10 | })
11 |
12 | it('*', () => {
13 | expect(A.intersection([1, 2, 3, 4], [3, 4, 5, 6])).toEqual([3, 4])
14 | })
15 | })
16 |
17 | describe('intersection (pipe)', () => {
18 | it('provides correct types', () => {
19 | expectType>(
20 | pipe([1, 2, 3, 4, 5], A.intersection([3, 4, 5, 6])),
21 | )
22 | })
23 |
24 | it('*', () => {
25 | expect(pipe([5, 2, 3, 5, 6], A.intersection([5, 2, 3, 1, 5, 4]))).toEqual(
26 | // prettier-ignore
27 | [5, 2, 3],
28 | )
29 | })
30 | })
31 |
--------------------------------------------------------------------------------
/__tests__/Result/tapError.test.ts:
--------------------------------------------------------------------------------
1 | import { pipe, R } from '../..'
2 |
3 | describe('tapError', () => {
4 | it('applies a side-effect', () => {
5 | const spy = jest.fn()
6 | const value = pipe(
7 | R.fromNullable(null, 'value cannot be nullable'),
8 | R.tapError(err => {
9 | spy()
10 | expect(err).toEqual('value cannot be nullable')
11 | }),
12 | R.getWithDefault(false),
13 | )
14 |
15 | expect(spy).toBeCalledTimes(1)
16 | expect(value).toEqual(false)
17 | })
18 |
19 | it('*', () => {
20 | expect(
21 | pipe(
22 | R.fromNullable(null, 'value cannot be nullable'),
23 | R.tapError(err => {
24 | console.log(err) // ⬅️ 'value cannot be nullable'
25 | }),
26 | R.getWithDefault(false),
27 | ),
28 | ).toEqual(false)
29 | })
30 | })
31 |
--------------------------------------------------------------------------------
/__tests__/Array/any.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { A, pipe } from '../..'
4 |
5 | describe('any', () => {
6 | it('provides correct types', () => {
7 | expectType(
8 | A.any(['', 'hello', 'world'], value => value.length > 0),
9 | )
10 | })
11 |
12 | it('*', () => {
13 | expect(A.any(['', 'hello', 'world'], value => value.length > 0)).toEqual(
14 | true,
15 | )
16 | })
17 | })
18 |
19 | describe('any (pipe)', () => {
20 | it('provides correct types', () => {
21 | expectType(
22 | pipe(
23 | [1, 2, 3, 4, 5],
24 | A.any(value => value > 3),
25 | ),
26 | )
27 | })
28 |
29 | it('*', () => {
30 | expect(
31 | pipe(
32 | [1, 2, 3, 4, 5],
33 | A.any(value => value > 5),
34 | ),
35 | ).toEqual(false)
36 | })
37 | })
38 |
--------------------------------------------------------------------------------
/__tests__/Result/tap.test.ts:
--------------------------------------------------------------------------------
1 | import { pipe, R, S } from '../..'
2 |
3 | describe('tap', () => {
4 | it('applies a side-effect', () => {
5 | const spy = jest.fn()
6 | const value = pipe(
7 | R.fromNullable('hello', 'value cannot be nullable'),
8 | R.map(S.isEmpty),
9 | R.tap(isEmpty => {
10 | spy()
11 | expect(isEmpty).toEqual(false)
12 | }),
13 | R.getWithDefault(false),
14 | )
15 |
16 | expect(spy).toBeCalledTimes(1)
17 | expect(value).toEqual(false)
18 | })
19 |
20 | it('*', () => {
21 | expect(
22 | pipe(
23 | R.fromNullable('hello', 'value cannot be nullable'),
24 | R.map(S.isEmpty),
25 | R.tap(isEmpty => {
26 | console.log(isEmpty) // ⬅️ false
27 | }),
28 | R.getWithDefault(false),
29 | ),
30 | ).toEqual(false)
31 | })
32 | })
33 |
--------------------------------------------------------------------------------
/__tests__/Option/fromPromise.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 | import { O } from '../..'
3 |
4 | describe('fromPromise', () => {
5 | it('provides correct types', () => {
6 | expectType>>(O.fromPromise(Promise.resolve(42)))
7 | })
8 |
9 | it('returns None', async () => {
10 | expect(await O.fromPromise(Promise.reject('hello world'))).toEqual(O.None)
11 | })
12 |
13 | it('returns Some', async () => {
14 | expect(await O.fromPromise(Promise.resolve('hello world'))).toEqual(
15 | O.Some('hello world'),
16 | )
17 | })
18 |
19 | it('*', async () => {
20 | const { Some, None } = O
21 |
22 | expect(await O.fromPromise(Promise.resolve('hello world'))).toEqual(
23 | Some('hello world'),
24 | )
25 |
26 | expect(await O.fromPromise(Promise.reject('oops'))).toEqual(None)
27 | })
28 | })
29 |
--------------------------------------------------------------------------------
/tools/javascript-codemods/pre/rename-identifiers.ts:
--------------------------------------------------------------------------------
1 | import { API, Identifier } from 'jscodeshift'
2 |
3 | const transform = (source: string, j: API['jscodeshift']): string => {
4 | const root = j(source)
5 | const literals: [string, string][] = [
6 | ['when_', 'when'],
7 | ['not_', 'not'],
8 | ['or_', 'or'],
9 | ['and_', 'and'],
10 | ]
11 | const equalName =
12 | (p: Identifier) =>
13 | ([search]: [string, string]) => {
14 | return p.name === search
15 | }
16 |
17 | root
18 | .find(j.Identifier)
19 | .filter(p => {
20 | return literals.some(equalName(p.value))
21 | })
22 | .replaceWith(p => {
23 | // @ts-expect-error
24 | const [, value] = literals.find(equalName(p.value))
25 | return j.identifier(value)
26 | })
27 |
28 | return root.toSource()
29 | }
30 |
31 | export default transform
32 |
--------------------------------------------------------------------------------
/tools/comment-ppx/esy.lock/opam/result.1.5/opam:
--------------------------------------------------------------------------------
1 | opam-version: "2.0"
2 | maintainer: "Jane Street developers"
3 | authors: ["Jane Street Group, LLC"]
4 | homepage: "https://github.com/janestreet/result"
5 | dev-repo: "git+https://github.com/janestreet/result.git"
6 | bug-reports: "https://github.com/janestreet/result/issues"
7 | license: "BSD-3-Clause"
8 | build: [["dune" "build" "-p" name "-j" jobs]]
9 | depends: [
10 | "ocaml"
11 | "dune" {>= "1.0"}
12 | ]
13 | synopsis: "Compatibility Result module"
14 | description: """
15 | Projects that want to use the new result type defined in OCaml >= 4.03
16 | while staying compatible with older version of OCaml should use the
17 | Result module defined in this library."""
18 | url {
19 | src:
20 | "https://github.com/janestreet/result/releases/download/1.5/result-1.5.tbz"
21 | checksum: "md5=1b82dec78849680b49ae9a8a365b831b"
22 | }
23 |
--------------------------------------------------------------------------------
/__tests__/Guards/isUndefined.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { G, pipe } from '../..'
4 |
5 | describe('isUndefined', () => {
6 | it('provides correct types', () => {
7 | const x = undefined
8 |
9 | if (G.isUndefined(x)) {
10 | expectType(x)
11 | }
12 |
13 | const y: unknown = undefined
14 |
15 | if (G.isUndefined(y)) {
16 | expectType(y)
17 | }
18 | })
19 |
20 | it('determines whether the provided value is undefined', () => {
21 | expect(G.isUndefined(undefined)).toEqual(true)
22 | expect(G.isUndefined(null)).toEqual(false)
23 | })
24 |
25 | it('*', () => {
26 | expect(G.isUndefined(undefined)).toEqual(true)
27 | })
28 | })
29 |
30 | describe('isUndefined (pipe)', () => {
31 | it('*', () => {
32 | expect(pipe(undefined, G.isUndefined)).toEqual(true)
33 | })
34 | })
35 |
--------------------------------------------------------------------------------
/tools/comment-ppx/esy.lock/opam/ppx_derivers.1.2.1/opam:
--------------------------------------------------------------------------------
1 | opam-version: "2.0"
2 | maintainer: "jeremie@dimino.org"
3 | authors: ["Jérémie Dimino"]
4 | license: "BSD-3-Clause"
5 | homepage: "https://github.com/ocaml-ppx/ppx_derivers"
6 | bug-reports: "https://github.com/ocaml-ppx/ppx_derivers/issues"
7 | dev-repo: "git+https://github.com/ocaml-ppx/ppx_derivers.git"
8 | build: [
9 | ["dune" "build" "-p" name "-j" jobs]
10 | ]
11 | depends: [
12 | "ocaml"
13 | "dune"
14 | ]
15 | synopsis: "Shared [@@deriving] plugin registry"
16 | description: """
17 | Ppx_derivers is a tiny package whose sole purpose is to allow
18 | ppx_deriving and ppx_type_conv to inter-operate gracefully when linked
19 | as part of the same ocaml-migrate-parsetree driver."""
20 | url {
21 | src: "https://github.com/ocaml-ppx/ppx_derivers/archive/1.2.1.tar.gz"
22 | checksum: "md5=5dc2bf130c1db3c731fe0fffc5648b41"
23 | }
24 |
--------------------------------------------------------------------------------
/tools/comment-ppx/esy.lock/opam/fix.20211125/opam:
--------------------------------------------------------------------------------
1 | opam-version: "2.0"
2 | maintainer: "francois.pottier@inria.fr"
3 | authors: [
4 | "François Pottier "
5 | ]
6 | homepage: "https://gitlab.inria.fr/fpottier/fix"
7 | dev-repo: "git+https://gitlab.inria.fr/fpottier/fix.git"
8 | bug-reports: "francois.pottier@inria.fr"
9 | license: "LGPL-2.0-only"
10 | build: [
11 | ["dune" "build" "-p" name "-j" jobs]
12 | ]
13 | depends: [
14 | "ocaml" { >= "4.03" }
15 | "dune" { >= "1.3" }
16 | ]
17 | synopsis: "Facilities for memoization and fixed points"
18 | url {
19 | src:
20 | "https://gitlab.inria.fr/fpottier/fix/-/archive/20211125/archive.tar.gz"
21 | checksum: [
22 | "md5=d3d316080a2fc9a4f56c15040e141364"
23 | "sha512=850cf0d3c6db806ac1d0b9bf39ad82529aecd56af07b2b421f48af15afdeab493f7b73e5d9e7d492e56717a8aeeb61466d87ac8a51fac30e3f77028b5ecd57c4"
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/tools/comment-ppx/src/Comment_ppx.re:
--------------------------------------------------------------------------------
1 | open Ppxlib;
2 |
3 | module Helper = Ast_helper;
4 | module Builder = Ast_builder.Default;
5 |
6 | let string_payload =
7 | Ast_pattern.(
8 | pstr(
9 | pstr_eval(
10 | pexp_constant(pconst_string(__', __, __)),
11 | nil
12 | ) ^:: nil,
13 | ),
14 | );
15 |
16 | let expander = (~loc, ~path as _, payload, _label, _) => {
17 | let str = "/** " ++ payload.txt ++ " */"
18 | let ident = Helper.Exp.ident(~loc, {txt: Lident("raw_comment"), loc});
19 |
20 | Helper.Exp.apply(
21 | ~loc,
22 | ~attrs=[],
23 | ident,
24 | [(Nolabel, Ast_builder.Default.estring(~loc, str))],
25 | );
26 | }
27 |
28 |
29 | let extension =
30 | Ppxlib.Extension.declare("comment", Ppxlib.Extension.Context.Expression, string_payload, expander);
31 |
32 | let () = Driver.register_transformation(~extensions=[extension], "comment-ppx");
33 |
--------------------------------------------------------------------------------
/__tests__/Array/splitEvery.test.ts:
--------------------------------------------------------------------------------
1 | import { A, pipe } from '../..'
2 |
3 | const xs = [1, 2, 3, 4, 5, 6, 7]
4 |
5 | // TODO: expectType
6 | describe('splitEvery', () => {
7 | it('returns an array of arrays, where each of the inner arrays has length equal to `n`', () => {
8 | const result = A.splitEvery(xs, 3)
9 | expect(result).toEqual([[1, 2, 3], [4, 5, 6], [7]])
10 | })
11 |
12 | it('returns the original array inside a new array if n is out of range', () => {
13 | expect(A.splitEvery(xs, 0)).toEqual([[1, 2, 3, 4, 5, 6, 7]])
14 | expect(A.splitEvery(xs, 8)).toEqual([[1, 2, 3, 4, 5, 6, 7]])
15 | })
16 | })
17 |
18 | describe('splitEvery (pipe)', () => {
19 | it('returns an array of arrays, where each of the inner arrays has length equal to `n`', () => {
20 | const result = pipe(xs, A.splitEvery(3))
21 | expect(result).toEqual([[1, 2, 3], [4, 5, 6], [7]])
22 | })
23 | })
24 |
--------------------------------------------------------------------------------
/__tests__/Bool/inverse.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { B, pipe } from '../..'
4 |
5 | describe('inverse', () => {
6 | it('provides correct types', () => {
7 | expectType(B.inverse(true))
8 | })
9 |
10 | it('negates the given boolean', () => {
11 | expect(B.inverse(true)).toEqual(false)
12 | expect(B.inverse(false)).toEqual(true)
13 | })
14 |
15 | it('*', () => {
16 | expect(B.inverse(false)).toEqual(true)
17 | })
18 | })
19 |
20 | describe('inverse (pipe)', () => {
21 | it('provides correct types', () => {
22 | expectType(pipe(true, B.inverse))
23 | })
24 |
25 | it('negates the given boolean', () => {
26 | expect(pipe(true, B.inverse)).toEqual(false)
27 | expect(pipe(false, B.inverse)).toEqual(true)
28 | })
29 |
30 | it('*', () => {
31 | expect(pipe(true, B.inverse)).toEqual(false)
32 | })
33 | })
34 |
--------------------------------------------------------------------------------
/__tests__/Result/getWithDefault.test.ts:
--------------------------------------------------------------------------------
1 | import { pipe, R } from '../..'
2 |
3 | describe('getWithDefault', () => {
4 | it('returns a default value', () => {
5 | expect(
6 | pipe(R.fromNullable(null, 'error'), R.getWithDefault('default value')),
7 | ).toEqual('default value')
8 | })
9 |
10 | it('should skip a default value', () => {
11 | expect(pipe(R.fromNullable(1, 'error'), R.getWithDefault(2))).toEqual(1)
12 | })
13 |
14 | it('*', () => {
15 | expect(
16 | pipe(
17 | R.fromNullable('hello', 'oops!'),
18 | R.map(value => `${value} world!`),
19 | R.getWithDefault('error'),
20 | ),
21 | ).toBe('hello world!')
22 |
23 | expect(
24 | pipe(
25 | R.fromNullable(null, 'oops!'),
26 | R.map(value => `${value} world!`),
27 | R.getWithDefault('error'),
28 | ),
29 | ).toBe('error')
30 | })
31 | })
32 |
--------------------------------------------------------------------------------
/docs/api/result.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | id: result
3 | title: Result
4 | ---
5 |
6 | `Result` type is really useful to describe the result of a certain operation without relying on exceptions.
7 |
8 | import Result, { toc as resulttoc } from "./generated/_result.mdx"
9 |
10 | ```ts
11 | type Result = Ok | Error
12 | ```
13 |
14 | ```jsx live
15 | function() {
16 | const obj = {
17 | // ⬇️ update the value below to either greater than 0 or `null/undefined` in order to see changes
18 | value: 0,
19 | }
20 | const value = pipe(
21 | R.fromNullable(obj.value, 'value cannot be nullable!'),
22 | R.flatMap(value => {
23 | return value === 0 ? R.Error('never divide by zero!') : R.Ok(100 / value)
24 | }),
25 | R.match(value => `100 / ${obj.value} = ${value}`, err => err),
26 | )
27 |
28 | return value
29 | }
30 | ```
31 |
32 |
33 |
34 | export const toc = resulttoc
35 |
--------------------------------------------------------------------------------
/docs/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ts-belt-docs",
3 | "version": "0.0.0",
4 | "private": true,
5 | "scripts": {
6 | "docusaurus": "docusaurus",
7 | "dev": "docusaurus start",
8 | "build": "docusaurus build",
9 | "swizzle": "docusaurus swizzle",
10 | "deploy": "docusaurus deploy",
11 | "serve": "docusaurus serve",
12 | "clear": "docusaurus clear"
13 | },
14 | "dependencies": {
15 | "@docusaurus/core": "^2.0.0-beta.10",
16 | "@docusaurus/preset-classic": "^2.0.0-beta.10",
17 | "@docusaurus/theme-live-codeblock": "^2.0.0-beta.10",
18 | "@easyops-cn/docusaurus-search-local": "^0.20.0",
19 | "@mdx-js/react": "^1.6.21",
20 | "@svgr/webpack": "^5.5.0",
21 | "clsx": "^1.1.1",
22 | "file-loader": "^6.2.0",
23 | "prism-react-renderer": "^1.2.1",
24 | "react": "^17.0.1",
25 | "react-dom": "^17.0.1",
26 | "url-loader": "^4.1.1"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/docs/src/pages/components/Card.module.css:
--------------------------------------------------------------------------------
1 | .card {
2 | border: 1px solid var(--ifm-color-gray-200);
3 | border-radius: 4px;
4 | display: block;
5 | cursor: pointer;
6 | transition: all .5s;
7 | min-height: 175px;
8 | color: #111;
9 | }
10 |
11 | @media screen and (max-width: 768px) {
12 | .card {
13 | min-height: 0;
14 | }
15 | }
16 |
17 | .card:hover {
18 | text-decoration: none;
19 | box-shadow: 0 6px 16px -8px #00000014, 0 9px 28px #0000000d, 0 12px 48px 16px #00000008;
20 | border-color: transparent;
21 | background-color: rgba(255, 255, 255, 0.33);
22 | }
23 |
24 | .title {
25 | padding: 12px;
26 | border-bottom: 1px solid var(--ifm-color-gray-200);
27 | font-size: 1rem;
28 | font-weight: 500;
29 | color: var(--ifm-color-gray-700);
30 | transition: color .5s;
31 | }
32 |
33 | .card:hover > .title {
34 | color: #000;
35 | }
36 |
37 | .body {
38 | padding: 12px;
39 | }
40 |
--------------------------------------------------------------------------------
/__tests__/Option/isNone.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 | import { pipe, O } from '../..'
3 |
4 | describe('isNone', () => {
5 | it('provides correct types', () => {
6 | expectType(O.isNone(O.None))
7 | expectType(O.isNone(O.Some('hello')))
8 | })
9 |
10 | it('returns true', () => {
11 | expect(O.isNone(O.None)).toBeTruthy()
12 | expect(pipe(O.fromNullable(null), O.isNone)).toBeTruthy()
13 | })
14 |
15 | it('returns false', () => {
16 | expect(O.isNone(O.Some('value'))).toBeFalsy()
17 | expect(pipe(O.fromNullable('value'), O.isNone)).toBeFalsy()
18 | })
19 |
20 | it('*', () => {
21 | expect(O.isNone(O.None)).toEqual(true)
22 | expect(pipe(O.fromNullable(null), O.isNone)).toEqual(true)
23 | expect(O.isNone(O.Some('hello world!'))).toEqual(false)
24 | expect(pipe(O.fromNullable('hello world!'), O.isNone)).toEqual(false)
25 | })
26 | })
27 |
--------------------------------------------------------------------------------
/__tests__/Option/isSome.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 | import { pipe, O } from '../..'
3 |
4 | describe('isSome', () => {
5 | it('provides correct types', () => {
6 | expectType(O.isSome(O.None))
7 | expectType(O.isSome(O.Some('hello')))
8 | })
9 |
10 | it('returns true', () => {
11 | expect(O.isSome(O.Some('string'))).toBeTruthy()
12 | expect(pipe(O.fromNullable('value'), O.isSome)).toBeTruthy()
13 | })
14 |
15 | it('returns false', () => {
16 | expect(O.isSome(O.None)).toBeFalsy()
17 | expect(pipe(O.fromNullable(null), O.isSome)).toBeFalsy()
18 | })
19 |
20 | it('*', () => {
21 | expect(O.isSome(O.Some('hello world!'))).toEqual(true)
22 | expect(pipe(O.fromNullable('hello world!'), O.isSome)).toEqual(true)
23 | expect(O.isSome(O.None)).toEqual(false)
24 | expect(pipe(O.fromNullable(null), O.isSome)).toEqual(false)
25 | })
26 | })
27 |
--------------------------------------------------------------------------------
/__tests__/String/length.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { S, pipe } from '../..'
4 |
5 | describe('length', () => {
6 | it('provides correct types', () => {
7 | expectType(S.length('ts-belt'))
8 | })
9 |
10 | it('returns the correct size of the given string', () => {
11 | expect(S.length('hello')).toEqual(5)
12 | expect(S.length('')).toEqual(0)
13 | })
14 |
15 | it('*', () => {
16 | expect(S.length('hello')).toEqual(5)
17 | })
18 | })
19 |
20 | describe('length (pipe)', () => {
21 | it('provides correct types', () => {
22 | expectType(pipe('hello', S.length))
23 | })
24 |
25 | it('returns the correct size of the given string', () => {
26 | expect(pipe('hello', S.length)).toEqual(5)
27 | expect(pipe('', S.length)).toEqual(0)
28 | })
29 |
30 | it('*', () => {
31 | expect(pipe('ts-belt', S.length)).toEqual(7)
32 | })
33 | })
34 |
--------------------------------------------------------------------------------
/__tests__/AsyncData/isInit.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 | import { pipe, AD } from '../..'
3 |
4 | describe('isInit', () => {
5 | it('provides correct types', () => {
6 | expectType(AD.isInit(AD.Init))
7 | expectType(AD.isInit(AD.Complete('hello world')))
8 | })
9 |
10 | it('returns true', () => {
11 | expect(AD.isInit(AD.Init)).toBeTruthy()
12 | expect(pipe(AD.Init, AD.isInit)).toBeTruthy()
13 | })
14 |
15 | it('returns false', () => {
16 | expect(AD.isInit(AD.Loading)).toBeFalsy()
17 | expect(pipe(AD.Complete(0), AD.isInit)).toBeFalsy()
18 | })
19 |
20 | // it('*', () => {
21 | // expect(AD.isInit(AD.Init)).toEqual(true)
22 | // expect(pipe(AD.Init, AD.isInit)).toEqual(true)
23 | // expect(AD.isInit(AD.Reloading('hello world'))).toEqual(false)
24 | // expect(pipe(AD.Complete('hello world'), AD.isInit)).toEqual(false)
25 | // })
26 | })
27 |
--------------------------------------------------------------------------------
/__tests__/Array/length.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { A, pipe } from '../..'
4 |
5 | describe('length', () => {
6 | it('provides correct types', () => {
7 | expectType(A.length([1, 2, 3, 4, 5]))
8 | })
9 |
10 | it('returns the correct size of the given array', () => {
11 | expect(A.length([1, 2, 3, 4, 5])).toEqual(5)
12 | expect(A.length([])).toEqual(0)
13 | })
14 |
15 | it('*', () => {
16 | expect(A.length(['hello', 'world'])).toEqual(2)
17 | })
18 | })
19 |
20 | describe('length (pipe)', () => {
21 | it('provides correct types', () => {
22 | expectType(pipe([1, 2, 3], A.length))
23 | })
24 |
25 | it('returns the correct size of the given array', () => {
26 | expect(pipe([1, 2, 3], A.length)).toEqual(3)
27 | expect(pipe([], A.length)).toEqual(0)
28 | })
29 |
30 | it('*', () => {
31 | expect(pipe([0, 2, 4], A.length)).toEqual(3)
32 | })
33 | })
34 |
--------------------------------------------------------------------------------
/__tests__/Result/fromPromise.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 | import { R } from '../..'
3 |
4 | describe('fromPromise', () => {
5 | it('provides correct types', () => {
6 | expectType>>(
7 | R.fromPromise(Promise.resolve(42)),
8 | )
9 | })
10 |
11 | it('returns Error', async () => {
12 | expect(await R.fromPromise(Promise.reject('hello world'))).toEqual(
13 | R.Error('hello world'),
14 | )
15 | })
16 |
17 | it('returns Some', async () => {
18 | expect(await R.fromPromise(Promise.resolve('hello world'))).toEqual(
19 | R.Ok('hello world'),
20 | )
21 | })
22 |
23 | it('*', async () => {
24 | const { Ok, Error } = R
25 |
26 | expect(await R.fromPromise(Promise.resolve('hello world'))).toEqual(
27 | Ok('hello world'),
28 | )
29 |
30 | expect(await R.fromPromise(Promise.reject('oops'))).toEqual(Error('oops'))
31 | })
32 | })
33 |
--------------------------------------------------------------------------------
/tools/comment-ppx/esy.lock/opam/ppx_yojson_conv_lib.v0.14.0/opam:
--------------------------------------------------------------------------------
1 | opam-version: "2.0"
2 | maintainer: "Jane Street developers"
3 | authors: ["Jane Street Group, LLC"]
4 | homepage: "https://github.com/janestreet/ppx_yojson_conv_lib"
5 | bug-reports: "https://github.com/janestreet/ppx_yojson_conv_lib/issues"
6 | dev-repo: "git+https://github.com/janestreet/ppx_yojson_conv_lib.git"
7 | doc: "https://ocaml.janestreet.com/ocaml-core/latest/doc/ppx_yojson_conv_lib/index.html"
8 | license: "MIT"
9 | build: [
10 | ["dune" "build" "-p" name "-j" jobs]
11 | ]
12 | depends: [
13 | "ocaml" {>= "4.02.3"}
14 | "dune" {>= "2.0.0"}
15 | "yojson" {>= "1.7.0"}
16 | ]
17 | synopsis: "Runtime lib for ppx_yojson_conv"
18 | description: "
19 | Part of the Jane Street's PPX rewriters collection.
20 | "
21 | url {
22 | src: "https://ocaml.janestreet.com/ocaml-core/v0.14/files/ppx_yojson_conv_lib-v0.14.0.tar.gz"
23 | checksum: "md5=e23c5593a7211ad4fb09e26e9a74698a"
24 | }
25 |
--------------------------------------------------------------------------------
/tools/comment-ppx/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "comment-ppx",
3 | "version": "0.1.0",
4 | "esy": {
5 | "buildsInSource": "_build",
6 | "build": "dune build -p comment-ppx",
7 | "buildDev": [
8 | [
9 | "dune",
10 | "build",
11 | "--promote-install-files",
12 | "--root",
13 | "."
14 | ]
15 | ],
16 | "release": {
17 | "bin": [
18 | "bin"
19 | ]
20 | }
21 | },
22 | "devDependencies": {
23 | "ocaml": "~4.10.0",
24 | "@esy-ocaml/reason": "^3.6.2",
25 | "@opam/dune": ">=2.8.4",
26 | "@opam/ppxlib": "0.22.0",
27 | "@reason-native/rely": "^3.2.1",
28 | "@opam/ocaml-lsp-server": "1.4.1"
29 | },
30 | "scripts": {
31 | "build": "esy dune build -p comment-ppx",
32 | "dev": "esy build dune build -p comment-ppx",
33 | "format": "esy dune build @fmt --auto-promote",
34 | "utop": "esy dune utop lib -- -implicit-bindings"
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/tools/typescript-codemods/make-option.ts:
--------------------------------------------------------------------------------
1 | import { API } from 'jscodeshift'
2 |
3 | const transform = (source: string, j: API['jscodeshift']): string => {
4 | // T | null | undefined to Option
5 | return j(source)
6 | .find(j.TSUnionType)
7 | .filter(p => {
8 | return (
9 | p.value.types.some(value => value.type === 'TSNullKeyword') &&
10 | p.value.types.some(value => value.type === 'TSUndefinedKeyword')
11 | )
12 | })
13 | .replaceWith(p => {
14 | const typeReference = p.value.types.find(
15 | value =>
16 | value.type !== 'TSUndefinedKeyword' && value.type !== 'TSNullKeyword',
17 | )
18 |
19 | if (typeReference) {
20 | return j.tsTypeReference(
21 | j.identifier('Option'),
22 | j.tsTypeParameterInstantiation([typeReference]),
23 | )
24 | }
25 |
26 | return p.value
27 | })
28 | .toSource()
29 | }
30 |
31 | export default transform
32 |
--------------------------------------------------------------------------------
/__tests__/Number/divideWithModulo.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { N, pipe } from '../..'
4 |
5 | describe('divideWithModulo', () => {
6 | it('provides correct types', () => {
7 | expectType(N.divideWithModulo(4, 2))
8 | })
9 |
10 | it('returns the quotient and remainder of a number division', () => {
11 | expect(N.divideWithModulo(20, 10)).toEqual([2, 0])
12 | })
13 |
14 | it('*', () => {
15 | expect(N.divideWithModulo(20, 5)).toEqual([4, 0])
16 | })
17 | })
18 |
19 | describe('divideWithModulo (pipe)', () => {
20 | it('provides correct types', () => {
21 | expectType(pipe(4, N.divideWithModulo(2)))
22 | })
23 |
24 | it('returns the quotient and remainder of a number division', () => {
25 | expect(pipe(20, N.divideWithModulo(2))).toEqual([10, 0])
26 | })
27 |
28 | it('*', () => {
29 | expect(pipe(30, N.divideWithModulo(4))).toEqual([7.5, 2])
30 | })
31 | })
32 |
--------------------------------------------------------------------------------
/__tests__/Array/takeWhile.test.ts:
--------------------------------------------------------------------------------
1 | import { A, pipe } from '../..'
2 |
3 | const xs = [1, 2, 3, 4, 5, 6, 7]
4 |
5 | // TODO: expectType
6 | describe('takeWhile', () => {
7 | it('returns a new array, filled with elements from the provided array until an element does not pass the provided predicate', () => {
8 | expect(A.takeWhile(xs, x => x < 4)).toEqual([1, 2, 3])
9 | expect(A.takeWhile([3, 5, 3], x => x < 4)).toEqual([3])
10 | })
11 |
12 | it('returns correct array elements if either true or false', () => {
13 | expect(A.takeWhile(xs, _x => true)).toEqual([1, 2, 3, 4, 5, 6, 7])
14 | expect(A.takeWhile(xs, _x => false)).toEqual([])
15 | })
16 | })
17 |
18 | describe('takeWhile (pipe)', () => {
19 | it('returns a new array, filled with elements from the provided array until an element does not pass the provided predicate', () => {
20 | const result = pipe(
21 | xs,
22 | A.takeWhile(x => x < 4),
23 | )
24 | expect(result).toEqual([1, 2, 3])
25 | })
26 | })
27 |
--------------------------------------------------------------------------------
/__tests__/Bool/or.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { B, pipe } from '../..'
4 |
5 | describe('or', () => {
6 | it('provides correct types', () => {
7 | expectType(B.or(true, true))
8 | })
9 |
10 | it('combines two booleans using OR', () => {
11 | expect(B.or(true, true)).toEqual(true)
12 | expect(B.or(false, false)).toEqual(false)
13 | expect(B.or(true, false)).toEqual(true)
14 | })
15 |
16 | it('*', () => {
17 | expect(B.or(true, false)).toEqual(true)
18 | })
19 | })
20 |
21 | describe('or (pipe)', () => {
22 | it('provides correct types', () => {
23 | expectType(pipe(true, B.or(true)))
24 | })
25 |
26 | it('combines two booleans using OR', () => {
27 | expect(pipe(true, B.or(true))).toEqual(true)
28 | expect(pipe(false, B.or(false))).toEqual(false)
29 | expect(pipe(true, B.or(false))).toEqual(true)
30 | })
31 |
32 | it('*', () => {
33 | expect(pipe(false, B.or(false))).toEqual(false)
34 | })
35 | })
36 |
--------------------------------------------------------------------------------
/__tests__/Guards/isNotNullable.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { G, pipe } from '../..'
4 |
5 | describe('isNotNullable', () => {
6 | it('provides correct types', () => {
7 | const x = '' as unknown as null | string
8 |
9 | if (G.isNotNullable(x)) {
10 | expectType(x)
11 | }
12 | })
13 |
14 | it('determines whether the provided value is not nullable', () => {
15 | expect(G.isNotNullable(undefined)).toEqual(false)
16 | expect(G.isNotNullable(null)).toEqual(false)
17 | expect(G.isNotNullable('ts-belt')).toEqual(true)
18 | expect(G.isNotNullable([])).toEqual(true)
19 | })
20 |
21 | it('*', () => {
22 | expect(G.isNotNullable('ts-belt')).toEqual(true)
23 | expect(G.isNotNullable(null)).toEqual(false)
24 | })
25 | })
26 |
27 | describe('isNotNullable (pipe)', () => {
28 | it('*', () => {
29 | expect(pipe(0, G.isNotNullable)).toEqual(true)
30 | expect(pipe(undefined, G.isNotNullable)).toEqual(false)
31 | })
32 | })
33 |
--------------------------------------------------------------------------------
/__tests__/Bool/and.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { B, pipe } from '../..'
4 |
5 | describe('and', () => {
6 | it('provides correct types', () => {
7 | expectType(B.and(true, true))
8 | })
9 |
10 | it('combines two boolean using AND', () => {
11 | expect(B.and(true, true)).toEqual(true)
12 | expect(B.and(false, false)).toEqual(false)
13 | expect(B.and(true, false)).toEqual(false)
14 | })
15 |
16 | it('*', () => {
17 | expect(B.and(true, true)).toEqual(true)
18 | })
19 | })
20 |
21 | describe('and (pipe)', () => {
22 | it('provides correct types', () => {
23 | expectType(pipe(true, B.and(true)))
24 | })
25 |
26 | it('combines two boolean using AND', () => {
27 | expect(pipe(true, B.and(true))).toEqual(true)
28 | expect(pipe(false, B.and(false))).toEqual(false)
29 | expect(pipe(true, B.and(false))).toEqual(false)
30 | })
31 |
32 | it('*', () => {
33 | expect(pipe(true, B.and(false))).toEqual(false)
34 | })
35 | })
36 |
--------------------------------------------------------------------------------
/__tests__/Bool/nor.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { B, pipe } from '../..'
4 |
5 | describe('nor', () => {
6 | it('provides correct types', () => {
7 | expectType(B.nor(true, true))
8 | })
9 |
10 | it('combines two booleans using NOR', () => {
11 | expect(B.nor(true, true)).toEqual(false)
12 | expect(B.nor(false, false)).toEqual(true)
13 | expect(B.nor(true, false)).toEqual(false)
14 | })
15 |
16 | it('*', () => {
17 | expect(B.nor(true, false)).toEqual(false)
18 | })
19 | })
20 |
21 | describe('nor (pipe)', () => {
22 | it('provides correct types', () => {
23 | expectType(pipe(true, B.nor(true)))
24 | })
25 |
26 | it('combines two booleans using NOR', () => {
27 | expect(pipe(true, B.nor(true))).toEqual(false)
28 | expect(pipe(false, B.nor(false))).toEqual(true)
29 | expect(pipe(true, B.nor(false))).toEqual(false)
30 | })
31 |
32 | it('*', () => {
33 | expect(pipe(false, B.nor(false))).toEqual(true)
34 | })
35 | })
36 |
--------------------------------------------------------------------------------
/__tests__/Bool/xor.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { B, pipe } from '../..'
4 |
5 | describe('xor', () => {
6 | it('provides correct types', () => {
7 | expectType(B.xor(true, true))
8 | })
9 |
10 | it('combines two booleans using XOR', () => {
11 | expect(B.xor(true, true)).toEqual(false)
12 | expect(B.xor(false, false)).toEqual(false)
13 | expect(B.xor(true, false)).toEqual(true)
14 | })
15 |
16 | it('*', () => {
17 | expect(B.xor(true, false)).toEqual(true)
18 | })
19 | })
20 |
21 | describe('xor (pipe)', () => {
22 | it('provides correct types', () => {
23 | expectType(pipe(true, B.xor(true)))
24 | })
25 |
26 | it('combines two booleans using XOR', () => {
27 | expect(pipe(true, B.xor(true))).toEqual(false)
28 | expect(pipe(false, B.xor(false))).toEqual(false)
29 | expect(pipe(true, B.xor(false))).toEqual(true)
30 | })
31 |
32 | it('*', () => {
33 | expect(pipe(false, B.xor(false))).toEqual(false)
34 | })
35 | })
36 |
--------------------------------------------------------------------------------
/benchmarks/simple/intersperse.js:
--------------------------------------------------------------------------------
1 | const { makeBenchmark, addTsBelt, addRambda, addRamda } = require('../utils')
2 |
3 | const input = [1, 2, 3, 4, 5, 6, 7, 8, 9]
4 |
5 | module.exports = makeBenchmark(
6 | 'intersperse',
7 | addTsBelt(tsBelt => {
8 | const { A, pipe } = tsBelt
9 |
10 | return [
11 | () => {
12 | return A.intersperse(input, 0)
13 | },
14 | () => {
15 | return pipe(input, A.intersperse(0))
16 | },
17 | ]
18 | }),
19 | addRamda(ramda => {
20 | const { pipe, intersperse } = ramda
21 |
22 | return [
23 | () => {
24 | return intersperse(0, input)
25 | },
26 | () => {
27 | return pipe(intersperse(0))(input)
28 | },
29 | ]
30 | }),
31 | addRambda(rambda => {
32 | const { pipe, intersperse } = rambda
33 |
34 | return [
35 | () => {
36 | return intersperse(0, input)
37 | },
38 | () => {
39 | return pipe(intersperse(0))(input)
40 | },
41 | ]
42 | }),
43 | )
44 |
--------------------------------------------------------------------------------
/__tests__/Bool/nand.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { B, pipe } from '../..'
4 |
5 | describe('nand', () => {
6 | it('provides correct types', () => {
7 | expectType(B.nand(true, true))
8 | })
9 |
10 | it('combines two booleans using NAND', () => {
11 | expect(B.nand(true, true)).toEqual(false)
12 | expect(B.nand(false, false)).toEqual(true)
13 | expect(B.nand(true, false)).toEqual(true)
14 | })
15 |
16 | it('*', () => {
17 | expect(B.nand(true, false)).toEqual(true)
18 | })
19 | })
20 |
21 | describe('nand (pipe)', () => {
22 | it('provides correct types', () => {
23 | expectType(pipe(true, B.nand(true)))
24 | })
25 |
26 | it('combines two booleans using NAND', () => {
27 | expect(pipe(true, B.nand(true))).toEqual(false)
28 | expect(pipe(false, B.nand(false))).toEqual(true)
29 | expect(pipe(true, B.nand(false))).toEqual(true)
30 | })
31 |
32 | it('*', () => {
33 | expect(pipe(false, B.nand(false))).toEqual(true)
34 | })
35 | })
36 |
--------------------------------------------------------------------------------
/__tests__/Bool/xnor.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { B, pipe } from '../..'
4 |
5 | describe('xnor', () => {
6 | it('provides correct types', () => {
7 | expectType(B.xnor(true, true))
8 | })
9 |
10 | it('combines two booleans using XNOR', () => {
11 | expect(B.xnor(true, true)).toEqual(true)
12 | expect(B.xnor(false, false)).toEqual(true)
13 | expect(B.xnor(true, false)).toEqual(false)
14 | })
15 |
16 | it('*', () => {
17 | expect(B.xnor(true, false)).toEqual(false)
18 | })
19 | })
20 |
21 | describe('xnor (pipe)', () => {
22 | it('provides correct types', () => {
23 | expectType(pipe(true, B.xnor(true)))
24 | })
25 |
26 | it('combines two booleans using XNOR', () => {
27 | expect(pipe(true, B.xnor(true))).toEqual(true)
28 | expect(pipe(false, B.xnor(false))).toEqual(true)
29 | expect(pipe(true, B.xnor(false))).toEqual(false)
30 | })
31 |
32 | it('*', () => {
33 | expect(pipe(false, B.xnor(false))).toEqual(true)
34 | })
35 | })
36 |
--------------------------------------------------------------------------------
/__tests__/Array/unzip.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { A, pipe } from '../..'
4 |
5 | const xs = [
6 | A.toTuple([1, 2]),
7 | A.toTuple([3, 4]),
8 | A.toTuple([5, 6]),
9 | A.toTuple([7, 8]),
10 | ]
11 |
12 | describe('unzip', () => {
13 | it('provides correct types', () => {
14 | expectType, ReadonlyArray]>(
15 | A.unzip(xs),
16 | )
17 | })
18 |
19 | it('returns a pair of arrays', () => {
20 | const result = A.unzip(xs)
21 | expect(result).toEqual([
22 | [1, 3, 5, 7],
23 | [2, 4, 6, 8],
24 | ])
25 | })
26 | })
27 |
28 | describe('unzip (pipe)', () => {
29 | it('provides correct types', () => {
30 | expectType, ReadonlyArray]>(
31 | pipe(xs, A.unzip),
32 | )
33 | })
34 |
35 | it('returns a pair of arrays', () => {
36 | const result = pipe(xs, A.unzip)
37 | expect(result).toEqual([
38 | [1, 3, 5, 7],
39 | [2, 4, 6, 8],
40 | ])
41 | })
42 | })
43 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "forceConsistentCasingInFileNames": true,
4 | "emitDeclarationOnly": true,
5 | "rootDir": "./src",
6 | "baseUrl": ".",
7 | "lib": ["esnext"],
8 | "declaration": true,
9 | "module": "commonjs",
10 | "moduleResolution": "node",
11 | "target": "esnext",
12 | "strict": true,
13 | "sourceMap": false,
14 | "pretty": true,
15 | "skipLibCheck": true,
16 | "noImplicitAny": true,
17 | "allowUnreachableCode": false,
18 | "allowUnusedLabels": false,
19 | "exactOptionalPropertyTypes": true,
20 | "noFallthroughCasesInSwitch": true,
21 | "noImplicitOverride": true,
22 | "noImplicitReturns": true,
23 | "noPropertyAccessFromIndexSignature": true,
24 | "noUncheckedIndexedAccess": true,
25 | "noUnusedLocals": true,
26 | "noUnusedParameters": true
27 | },
28 | "include": [
29 | "./__tests__/**/*",
30 | "./playground/*.ts",
31 | "./src/**/index.ts"
32 | ],
33 | "exclude": [
34 | "./src/**/*.gen.tsx"
35 | ]
36 | }
37 |
--------------------------------------------------------------------------------
/tools/comment-ppx/esy.lock/opam/menhir.20211012/opam:
--------------------------------------------------------------------------------
1 | opam-version: "2.0"
2 | maintainer: "francois.pottier@inria.fr"
3 | authors: [
4 | "François Pottier "
5 | "Yann Régis-Gianas "
6 | ]
7 | homepage: "http://gitlab.inria.fr/fpottier/menhir"
8 | dev-repo: "git+https://gitlab.inria.fr/fpottier/menhir.git"
9 | bug-reports: "https://gitlab.inria.fr/fpottier/menhir/-/issues"
10 | license: "LGPL-2.0-only with OCaml-LGPL-linking-exception"
11 | build: [
12 | ["dune" "build" "-p" name "-j" jobs]
13 | ]
14 | depends: [
15 | "ocaml" {>= "4.02.3"}
16 | "dune" {>= "2.2.0"}
17 | "menhirLib" {= version}
18 | "menhirSdk" {= version}
19 | ]
20 | synopsis: "An LR(1) parser generator"
21 | url {
22 | src:
23 | "https://gitlab.inria.fr/fpottier/menhir/-/archive/20211012/archive.tar.gz"
24 | checksum: [
25 | "md5=f631f4c03859254a7d725f054633ee44"
26 | "sha512=13376d3c07158c36dd9b4617294a7e4d53ba90062ab09fae48c36b76f08133e2ffc4be13a1bc88980617c5d1046631844815c9ee7fd7c821699bacaf245b1ed8"
27 | ]
28 | }
29 |
--------------------------------------------------------------------------------
/tools/comment-ppx/esy.lock/opam/sexplib0.v0.14.0/opam:
--------------------------------------------------------------------------------
1 | opam-version: "2.0"
2 | maintainer: "Jane Street developers"
3 | authors: ["Jane Street Group, LLC"]
4 | homepage: "https://github.com/janestreet/sexplib0"
5 | bug-reports: "https://github.com/janestreet/sexplib0/issues"
6 | dev-repo: "git+https://github.com/janestreet/sexplib0.git"
7 | doc: "https://ocaml.janestreet.com/ocaml-core/latest/doc/sexplib0/index.html"
8 | license: "MIT"
9 | build: [
10 | ["dune" "build" "-p" name "-j" jobs]
11 | ]
12 | depends: [
13 | "ocaml" {>= "4.04.2"}
14 | "dune" {>= "2.0.0"}
15 | ]
16 | synopsis: "Library containing the definition of S-expressions and some base converters"
17 | description: "
18 | Part of Jane Street's Core library
19 | The Core suite of libraries is an industrial strength alternative to
20 | OCaml's standard library that was developed by Jane Street, the
21 | largest industrial user of OCaml.
22 | "
23 | url {
24 | src: "https://ocaml.janestreet.com/ocaml-core/v0.14/files/sexplib0-v0.14.0.tar.gz"
25 | checksum: "md5=37aff0af8f8f6f759249475684aebdc4"
26 | }
27 |
--------------------------------------------------------------------------------
/__tests__/Array/difference.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { A, pipe } from '../..'
4 |
5 | type Obj = {
6 | readonly a?: number
7 | readonly b?: number
8 | readonly c?: number
9 | }
10 |
11 | describe('difference', () => {
12 | it('provides correct types', () => {
13 | expectType>(
14 | A.difference(['', 'hello', 'world'], ['']),
15 | )
16 | })
17 |
18 | it('returns a correct result', () => {
19 | expect(
20 | A.difference([{ a: 1 }, { b: 2 }], [{ a: 1 }, { c: 3 }]),
21 | ).toEqual([{ b: 2 }])
22 | })
23 |
24 | it('*', () => {
25 | expect(A.difference([1, 2, 3, 4], [3, 4, 5, 6])).toEqual([1, 2])
26 | })
27 | })
28 |
29 | describe('difference (pipe)', () => {
30 | it('provides correct types', () => {
31 | expectType>(
32 | pipe([5, 2, 3, 5, 6], A.difference([5, 2, 3, 1, 5, 4])),
33 | )
34 | })
35 |
36 | it('*', () => {
37 | expect(pipe([5, 2, 3, 5, 6], A.difference([5, 2, 3, 1, 5, 4]))).toEqual([6])
38 | })
39 | })
40 |
--------------------------------------------------------------------------------
/__tests__/Array/removeFirst.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { A, pipe } from '../..'
4 |
5 | const xs = [1, 2, 1, 3]
6 |
7 | describe('removeFirst', () => {
8 | it('provides correct types', () => {
9 | expectType>(A.removeFirst(xs, 1))
10 | })
11 |
12 | it('removes the first occurence of the given value', () => {
13 | expect(A.removeFirst(xs, 1)).toEqual([2, 1, 3])
14 | })
15 |
16 | it('*', () => {
17 | expect(A.removeFirst(['hello', 'hello', 'world'], 'hello')).toEqual(
18 | // prettier-ignore
19 | ['hello', 'world'],
20 | )
21 | })
22 | })
23 |
24 | describe('removeFirst (pipe)', () => {
25 | it('provides correct types', () => {
26 | expectType>(pipe(xs, A.removeFirst(1)))
27 | })
28 |
29 | it('removes the first occurence of the given value', () => {
30 | expect(pipe(xs, A.removeFirst(1))).toEqual([2, 1, 3])
31 | })
32 |
33 | it('*', () => {
34 | expect(pipe([4, 5, 2, 1, 3], A.removeFirst(1))).toEqual([4, 5, 2, 3])
35 | })
36 | })
37 |
--------------------------------------------------------------------------------
/__tests__/String/concat.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { S, A, pipe } from '../..'
4 |
5 | describe('concat', () => {
6 | it('provides correct types', () => {
7 | expectType(S.concat('hello', 'world'))
8 | expectType(A.reduce(['hello', 'world'], '', S.concat))
9 | })
10 |
11 | it('returns a new string with append added after str', () => {
12 | expect(S.concat('hello', 'world')).toEqual('helloworld')
13 | })
14 |
15 | it('*', () => {
16 | expect(S.concat('hello', 'world')).toEqual('helloworld')
17 | })
18 | })
19 |
20 | describe('concat (pipe)', () => {
21 | it('provides correct types', () => {
22 | expectType(pipe('hello', S.concat('world')))
23 | expectType(pipe(['hello', 'world'], A.reduce('', S.concat)))
24 | })
25 |
26 | it('returns a new string with append added after str', () => {
27 | expect(pipe('hello', S.concat('world'))).toEqual('helloworld')
28 | })
29 |
30 | it('*', () => {
31 | expect(pipe('ts', S.concat('belt'))).toEqual('tsbelt')
32 | })
33 | })
34 |
--------------------------------------------------------------------------------
/scripts/test.ts:
--------------------------------------------------------------------------------
1 | import { task, desc, option, setGlobalOptions } from 'foy'
2 | import * as globby from 'globby'
3 |
4 | setGlobalOptions({
5 | strict: true,
6 | logCommand: false,
7 | loading: false,
8 | })
9 |
10 | type Options = {
11 | readonly namespace: string
12 | readonly file: string
13 | readonly coverage: boolean
14 | }
15 |
16 | desc('Run tests')
17 | option('-n, --namespace ', 'namespace')
18 | option('-f, --file ', 'file')
19 | option('-c, --coverage', 'coverage')
20 | task('run', async ctx => {
21 | const coverage = ctx.options.coverage ? '--coverage' : ''
22 |
23 | const cmd = ['yarn', 'jest', coverage]
24 |
25 | if (ctx.options.namespace || ctx.options.file) {
26 | const namespace = ctx.options.namespace || '**'
27 | const file = ctx.options.file ? `${ctx.options.file}.test.ts` : '*.test.ts'
28 |
29 | const files = await globby(`__tests__/${namespace}/${file}`)
30 |
31 | cmd.push(...files)
32 |
33 | await ctx.exec(cmd.join(' '))
34 | return
35 | }
36 |
37 | await ctx.exec(cmd.join(' '))
38 | })
39 |
--------------------------------------------------------------------------------
/__tests__/String/getUnsafe.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { S, A, pipe } from '../..'
4 |
5 | describe('getUnsafe', () => {
6 | it('provides correct types', () => {
7 | expectType(S.getUnsafe('hello', 0))
8 | expectType>(A.map(['hello', 'world'], S.getUnsafe(1)))
9 | })
10 |
11 | it('returns the nth element of the given string', () => {
12 | expect(S.getUnsafe('hello', 1)).toEqual('e')
13 | })
14 |
15 | it('*', () => {
16 | expect(S.getUnsafe('hello', 1)).toEqual('e')
17 | })
18 | })
19 |
20 | describe('getUnsafe (pipe)', () => {
21 | it('provides correct types', () => {
22 | expectType(pipe('hello', S.getUnsafe(1)))
23 | expectType>(
24 | pipe(['hello', 'world'], A.map(S.getUnsafe(1))),
25 | )
26 | })
27 |
28 | it('returns the nth element of the given string', () => {
29 | expect(pipe('ts-belt', S.getUnsafe(1))).toEqual('s')
30 | })
31 |
32 | it('*', () => {
33 | expect(pipe('world', S.getUnsafe(1))).toEqual('o')
34 | })
35 | })
36 |
--------------------------------------------------------------------------------
/__tests__/String/prepend.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { S, A, pipe } from '../..'
4 |
5 | describe('prepend', () => {
6 | it('provides correct types', () => {
7 | expectType(S.prepend('hello', 'world'))
8 | expectType(A.reduce(['hello', 'world'], '', S.prepend))
9 | })
10 |
11 | it('returns a new string with append added after str', () => {
12 | expect(S.prepend('hello', 'world')).toEqual('worldhello')
13 | })
14 |
15 | it('*', () => {
16 | expect(S.prepend('hello', 'world')).toEqual('worldhello')
17 | })
18 | })
19 |
20 | describe('prepend (pipe)', () => {
21 | it('provides correct types', () => {
22 | expectType(pipe('hello', S.prepend('world')))
23 | expectType(pipe(['hello', 'world'], A.reduce('', S.prepend)))
24 | })
25 |
26 | it('returns a new string with append added after str', () => {
27 | expect(pipe('hello', S.prepend('world'))).toEqual('worldhello')
28 | })
29 |
30 | it('*', () => {
31 | expect(pipe('ts', S.prepend('belt'))).toEqual('beltts')
32 | })
33 | })
34 |
--------------------------------------------------------------------------------
/__tests__/Bool/implies.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { B, pipe } from '../..'
4 |
5 | describe('implies', () => {
6 | it('provides correct types', () => {
7 | expectType(B.implies(true, true))
8 | })
9 |
10 | it('combines two booleans using an implication', () => {
11 | expect(B.implies(true, true)).toEqual(true)
12 | expect(B.implies(false, false)).toEqual(true)
13 | expect(B.implies(true, false)).toEqual(false)
14 | })
15 |
16 | it('*', () => {
17 | expect(B.implies(false, true)).toEqual(true)
18 | })
19 | })
20 |
21 | describe('implies (pipe)', () => {
22 | it('provides correct types', () => {
23 | expectType(pipe(true, B.implies(true)))
24 | })
25 |
26 | it('combines two booleans using an implication', () => {
27 | expect(pipe(true, B.implies(true))).toEqual(true)
28 | expect(pipe(false, B.implies(false))).toEqual(true)
29 | expect(pipe(true, B.implies(false))).toEqual(false)
30 | })
31 |
32 | it('*', () => {
33 | expect(pipe(true, B.implies(false))).toEqual(false)
34 | })
35 | })
36 |
--------------------------------------------------------------------------------
/__tests__/String/remove.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { S, A, pipe } from '../..'
4 |
5 | describe('remove', () => {
6 | it('provides correct types', () => {
7 | expectType(S.remove('hello', 'h'))
8 | expectType>(A.map(['hello', 'world'], S.remove('o')))
9 | })
10 |
11 | it('returns true if the given string starts with substr', () => {
12 | expect(S.remove('hello', 'o')).toEqual('hell')
13 | })
14 |
15 | it('*', () => {
16 | expect(S.remove('hello', 'l')).toEqual('helo')
17 | })
18 | })
19 |
20 | describe('remove (pipe)', () => {
21 | it('provides correct types', () => {
22 | expectType(pipe('hello', S.remove('h')))
23 | expectType>(
24 | pipe(['hello', 'world'], A.map(S.remove('h'))),
25 | )
26 | })
27 |
28 | it('returns true if the given string ends with substr', () => {
29 | expect(pipe('ts-belt', S.remove('ts'))).toEqual('-belt')
30 | })
31 |
32 | it('*', () => {
33 | expect(pipe('ts-belt', S.remove('ts-'))).toEqual('belt')
34 | })
35 | })
36 |
--------------------------------------------------------------------------------
/tools/comment-ppx/esy.lock/opam/menhirLib.20211012/opam:
--------------------------------------------------------------------------------
1 | opam-version: "2.0"
2 | maintainer: "francois.pottier@inria.fr"
3 | authors: [
4 | "François Pottier "
5 | "Yann Régis-Gianas "
6 | ]
7 | homepage: "http://gitlab.inria.fr/fpottier/menhir"
8 | dev-repo: "git+https://gitlab.inria.fr/fpottier/menhir.git"
9 | bug-reports: "https://gitlab.inria.fr/fpottier/menhir/-/issues"
10 | license: "LGPL-2.0-only with OCaml-LGPL-linking-exception"
11 | build: [
12 | ["dune" "build" "-p" name "-j" jobs]
13 | ]
14 | depends: [
15 | "ocaml" { >= "4.02.3" }
16 | "dune" { >= "2.0.0" }
17 | ]
18 | conflicts: [
19 | "menhir" { != version }
20 | ]
21 | synopsis: "Runtime support library for parsers generated by Menhir"
22 | url {
23 | src:
24 | "https://gitlab.inria.fr/fpottier/menhir/-/archive/20211012/archive.tar.gz"
25 | checksum: [
26 | "md5=f631f4c03859254a7d725f054633ee44"
27 | "sha512=13376d3c07158c36dd9b4617294a7e4d53ba90062ab09fae48c36b76f08133e2ffc4be13a1bc88980617c5d1046631844815c9ee7fd7c821699bacaf245b1ed8"
28 | ]
29 | }
30 |
--------------------------------------------------------------------------------
/tools/comment-ppx/esy.lock/opam/menhirSdk.20211012/opam:
--------------------------------------------------------------------------------
1 | opam-version: "2.0"
2 | maintainer: "francois.pottier@inria.fr"
3 | authors: [
4 | "François Pottier "
5 | "Yann Régis-Gianas "
6 | ]
7 | homepage: "http://gitlab.inria.fr/fpottier/menhir"
8 | dev-repo: "git+https://gitlab.inria.fr/fpottier/menhir.git"
9 | bug-reports: "https://gitlab.inria.fr/fpottier/menhir/-/issues"
10 | license: "LGPL-2.0-only with OCaml-LGPL-linking-exception"
11 | build: [
12 | ["dune" "build" "-p" name "-j" jobs]
13 | ]
14 | depends: [
15 | "ocaml" { >= "4.02.3" }
16 | "dune" { >= "2.0.0" }
17 | ]
18 | conflicts: [
19 | "menhir" { != version }
20 | ]
21 | synopsis: "Compile-time library for auxiliary tools related to Menhir"
22 | url {
23 | src:
24 | "https://gitlab.inria.fr/fpottier/menhir/-/archive/20211012/archive.tar.gz"
25 | checksum: [
26 | "md5=f631f4c03859254a7d725f054633ee44"
27 | "sha512=13376d3c07158c36dd9b4617294a7e4d53ba90062ab09fae48c36b76f08133e2ffc4be13a1bc88980617c5d1046631844815c9ee7fd7c821699bacaf245b1ed8"
28 | ]
29 | }
30 |
--------------------------------------------------------------------------------
/__tests__/Function/memoizeWithKey.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { F, N, A, S } from '../..'
4 |
5 | const fn = (n: number) => {
6 | return `called ${n} times`
7 | }
8 |
9 | describe('memoizeWithKey', () => {
10 | it('provides correct types', () => {
11 | expectType<(n: number) => string>(F.memoizeWithKey(S.make, fn))
12 | expectType<(n: number) => number>(F.memoizeWithKey(S.make, N.add(2)))
13 | })
14 |
15 | it('*', () => {
16 | let calls = 0
17 | const makeArray = F.memoizeWithKey(S.make, (value: number) => {
18 | calls = calls + 1
19 | return A.makeWithIndex(value, index => index * 2)
20 | })
21 |
22 | expect(
23 | /*
24 | let calls = 0
25 | const makeArray = F.memoizeWithKey(S.make, (value: number) => {
26 | calls = calls + 1
27 | return A.makeWithIndex(value, index => index * 2)
28 | })
29 | */
30 | makeArray(4),
31 | ).toEqual([0, 2, 4, 6])
32 | expect(makeArray(4)).toEqual([0, 2, 4, 6])
33 | expect(makeArray(4)).toEqual([0, 2, 4, 6])
34 | expect(calls).toEqual(1)
35 | })
36 | })
37 |
--------------------------------------------------------------------------------
/docs/api/option.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | id: option
3 | title: Option
4 | ---
5 |
6 | import Option, { toc as optiontoc } from "./generated/_option.mdx"
7 |
8 | Belt (ReScript) represents the existence and nonexistence of a value by wrapping it with the `Option` type. TS Belt does the same and provides utility-functions for convenient work with the `Option` type.
9 |
10 | ```ts
11 | type Option = T | undefined | null
12 | ```
13 |
14 | :::warning
15 |
16 | Adding `noUncheckedIndexedAccess` to your `tsconfig.json` is mandatory for the `Option` type!
17 |
18 | :::
19 |
20 | ```jsx live
21 | function() {
22 | // ⬇️ remove all elements in the array below in order to see the default value
23 | const xs = ['hello', 'world', 'ts', 'belt']
24 | const value = pipe(
25 | O.fromNullable(xs), // → Some(['hello', 'world', 'ts', 'belt'])
26 | O.flatMap(A.dropExactly(2)), // → Some(['ts', 'belt'])
27 | O.map(A.join('-')), // → Some('ts-belt')
28 | O.getWithDefault('default value'), // returns `default value` if `None`
29 | )
30 |
31 | return value
32 | }
33 | ```
34 |
35 |
36 |
37 | export const toc = optiontoc
38 |
--------------------------------------------------------------------------------
/__tests__/String/endsWith.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { S, A, pipe } from '../..'
4 |
5 | describe('endsWith', () => {
6 | it('provides correct types', () => {
7 | expectType(S.endsWith('hello', 'o'))
8 | expectType>(
9 | A.filter(['hello', 'world'], S.endsWith('o')),
10 | )
11 | })
12 |
13 | it('returns true if the given string ends with substr', () => {
14 | expect(S.endsWith('hello', 'o')).toEqual(true)
15 | })
16 |
17 | it('*', () => {
18 | expect(S.endsWith('hello', 'o')).toEqual(true)
19 | })
20 | })
21 |
22 | describe('endsWith (pipe)', () => {
23 | it('provides correct types', () => {
24 | expectType(pipe('hello', S.endsWith('o')))
25 | expectType>(
26 | pipe(['hello', 'world'], A.filter(S.endsWith('o'))),
27 | )
28 | })
29 |
30 | it('returns true if the given string ends with substr', () => {
31 | expect(pipe('ts-belt', S.endsWith('o'))).toEqual(false)
32 | })
33 |
34 | it('*', () => {
35 | expect(pipe('ts-belt', S.endsWith('o'))).toEqual(false)
36 | })
37 | })
38 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) Marcin Dziewulski
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/src/Guards/Guards.res:
--------------------------------------------------------------------------------
1 | let is = (value, type_) => Js.typeof(value) === type_
2 |
3 | @gentype
4 | let isString = value => is(value, "string")
5 |
6 | @gentype
7 | let isNumber = value => is(value, "number") && !Js.Float.isNaN(value)
8 |
9 | @gentype
10 | let isBoolean = value => is(value, "boolean")
11 |
12 | @gentype
13 | let isPromise = %raw("value => value instanceof Promise")
14 |
15 | @gentype
16 | let isArray = value => Js.Array2.isArray(value)
17 |
18 | @gentype
19 | let isObject = value => %raw("!!value") && !isArray(value) && is(value, "object")
20 |
21 | @gentype
22 | let isFunction = value => is(value, "function")
23 |
24 | @gentype
25 | let isError = %raw("value => value instanceof Error")
26 |
27 | @gentype
28 | let isDate = %raw("value => value instanceof Date")
29 |
30 | @gentype
31 | let isNullable = value => Js.Nullable.isNullable(value)
32 |
33 | @gentype
34 | let isNotNullable = value => !isNullable(value)
35 |
36 | @gentype
37 | let isNull = %raw("value => value === null")
38 |
39 | @gentype
40 | let isUndefined = %raw("value => value === undefined")
41 |
42 | @gentype
43 | let isNot = (value, predicateFn) => !predicateFn(value)
44 |
--------------------------------------------------------------------------------
/__tests__/String/startsWith.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { S, A, pipe } from '../..'
4 |
5 | describe('startsWith', () => {
6 | it('provides correct types', () => {
7 | expectType(S.startsWith('hello', 'h'))
8 | expectType>(
9 | A.filter(['hello', 'world'], S.startsWith('h')),
10 | )
11 | })
12 |
13 | it('returns true if the given string starts with substr', () => {
14 | expect(S.startsWith('hello', 'o')).toEqual(false)
15 | })
16 |
17 | it('*', () => {
18 | expect(S.startsWith('hello', 'o')).toEqual(false)
19 | })
20 | })
21 |
22 | describe('startsWith (pipe)', () => {
23 | it('provides correct types', () => {
24 | expectType(pipe('hello', S.startsWith('h')))
25 | expectType>(
26 | pipe(['hello', 'world'], A.filter(S.startsWith('h'))),
27 | )
28 | })
29 |
30 | it('returns true if the given string ends with substr', () => {
31 | expect(pipe('ts-belt', S.startsWith('ts'))).toEqual(true)
32 | })
33 |
34 | it('*', () => {
35 | expect(pipe('ts-belt', S.startsWith('ts'))).toEqual(true)
36 | })
37 | })
38 |
--------------------------------------------------------------------------------
/__tests__/String/includes.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { S, A, pipe } from '../..'
4 |
5 | describe('includes', () => {
6 | it('provides correct types', () => {
7 | expectType(S.includes('hello', 'll'))
8 | expectType>(
9 | A.filter(['hello', 'world'], S.includes('o')),
10 | )
11 | })
12 |
13 | it('returns true if searchValue appears anywhere in the given string', () => {
14 | expect(S.includes('hello', 'o')).toEqual(true)
15 | })
16 |
17 | it('*', () => {
18 | expect(S.includes('hello', 'll')).toEqual(true)
19 | })
20 | })
21 |
22 | describe('includes (pipe)', () => {
23 | it('provides correct types', () => {
24 | expectType(pipe('hello', S.includes('o')))
25 | expectType>(
26 | pipe(['hello', 'world'], A.filter(S.includes('o'))),
27 | )
28 | })
29 |
30 | it('returns true if searchValue appears anywhere in the given string', () => {
31 | expect(pipe('ts-belt', S.includes('*'))).toEqual(false)
32 | })
33 |
34 | it('*', () => {
35 | expect(pipe('world', S.includes('ll'))).toEqual(false)
36 | })
37 | })
38 |
--------------------------------------------------------------------------------
/__tests__/Array/reverse.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { A, pipe } from '../..'
4 |
5 | const xs = [1, 2, 3, 4, 5]
6 |
7 | describe('reverse', () => {
8 | it('provides correct types', () => {
9 | expectType>(A.reverse(xs))
10 | expectType>(A.reverse(['hello', 'world']))
11 | })
12 |
13 | it('returns the provided array in reverse order', () => {
14 | const result = A.reverse(xs)
15 | expect(result).toEqual([5, 4, 3, 2, 1])
16 | })
17 |
18 | it('*', () => {
19 | expect(A.reverse([1, 2, 3, 4, 5])).toEqual([5, 4, 3, 2, 1])
20 | })
21 | })
22 |
23 | describe('make (pipe)', () => {
24 | it('provides correct types', () => {
25 | expectType>(pipe(xs, A.reverse))
26 | expectType>(pipe(['hello', 'world'], A.reverse))
27 | })
28 |
29 | it('returns the provided array in reverse order', () => {
30 | const result = pipe(xs, A.reverse)
31 | expect(result).toEqual([5, 4, 3, 2, 1])
32 | })
33 |
34 | it('*', () => {
35 | expect(pipe(['hello', 'world'], A.reverse)).toEqual(['world', 'hello'])
36 | })
37 | })
38 |
--------------------------------------------------------------------------------
/__tests__/Option/zip.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 | import { pipe, O } from '../..'
3 |
4 | describe('zip', () => {
5 | it('provides correct types', () => {
6 | const value = null as unknown as string | null
7 | const fstOption = O.fromNullable(value)
8 | const sndOption = O.fromNullable(3)
9 |
10 | expectType>(O.zip(fstOption, sndOption))
11 | })
12 |
13 | it('returns Some', () => {
14 | expect(pipe(O.fromNullable(1), O.zip(O.fromNullable(2)))).toEqual(
15 | O.Some([1, 2]),
16 | )
17 | expect(
18 | pipe(O.fromNullable('hello'), O.zip(O.fromNullable('world'))),
19 | ).toEqual(O.Some(['hello', 'world']))
20 | })
21 |
22 | it('returns None', () => {
23 | expect(pipe(O.fromNullable(1), O.zip(O.fromNullable(null)))).toEqual(O.None)
24 | expect(pipe(O.fromNullable(''), O.zip(O.fromNullable(undefined)))).toEqual(
25 | O.None,
26 | )
27 | })
28 |
29 | it('*', () => {
30 | const { Some } = O
31 |
32 | expect(
33 | pipe(O.fromNullable('hello'), O.zip(O.fromNullable('world'))),
34 | ).toEqual(Some(['hello', 'world']))
35 | })
36 | })
37 |
--------------------------------------------------------------------------------
/__tests__/String/isEmpty.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { S, pipe } from '../..'
4 |
5 | describe('isEmpty', () => {
6 | it('provides correct types', () => {
7 | expectType(S.isEmpty('hello'))
8 | })
9 |
10 | it('returns `true` if the given string is empty', () => {
11 | expect(S.isEmpty('')).toEqual(true)
12 | })
13 |
14 | it('returns `false` if the given string is not empty', () => {
15 | expect(S.isEmpty('hello')).toEqual(false)
16 | })
17 |
18 | it('*', () => {
19 | expect(S.isEmpty('hello world')).toEqual(false)
20 | expect(S.isEmpty('')).toEqual(true)
21 | })
22 | })
23 |
24 | describe('isEmpty (pipe)', () => {
25 | it('provides correct types', () => {
26 | expectType(pipe('hello', S.isEmpty))
27 | })
28 |
29 | it('returns `true` if the given string is empty', () => {
30 | expect(pipe('', S.isEmpty)).toEqual(true)
31 | })
32 |
33 | it('returns `false` if the given string is not empty', () => {
34 | expect(pipe('ts-belt', S.isEmpty)).toEqual(false)
35 | })
36 |
37 | it('*', () => {
38 | expect(pipe('ts-belt', S.isEmpty)).toEqual(false)
39 | })
40 | })
41 |
--------------------------------------------------------------------------------
/__tests__/String/removeAll.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { S, A, pipe } from '../..'
4 |
5 | describe('removeAll', () => {
6 | it('provides correct types', () => {
7 | expectType(S.removeAll('hello', 'h'))
8 | expectType>(
9 | A.map(['hello', 'world'], S.removeAll('o')),
10 | )
11 | })
12 |
13 | it('returns true if the given string starts with substr', () => {
14 | expect(S.removeAll('hello', 'o')).toEqual('hell')
15 | })
16 |
17 | it('*', () => {
18 | expect(S.removeAll('hello', 'l')).toEqual('heo')
19 | })
20 | })
21 |
22 | describe('removeAll (pipe)', () => {
23 | it('provides correct types', () => {
24 | expectType(pipe('hello', S.removeAll('h')))
25 | expectType>(
26 | pipe(['hello', 'world'], A.map(S.removeAll('h'))),
27 | )
28 | })
29 |
30 | it('returns true if the given string ends with substr', () => {
31 | expect(pipe('hello world', S.removeAll('o'))).toEqual('hell wrld')
32 | })
33 |
34 | it('*', () => {
35 | expect(pipe('hXellXo wXXorXXld', S.removeAll('X'))).toEqual('hello world')
36 | })
37 | })
38 |
--------------------------------------------------------------------------------
/__tests__/Array/isEmpty.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { A, pipe } from '../..'
4 |
5 | describe('isEmpty', () => {
6 | it('provides correct types', () => {
7 | expectType(A.isEmpty([1, 2, 3]))
8 | })
9 |
10 | it('returns `true` if the given array is empty', () => {
11 | expect(A.isEmpty([])).toEqual(true)
12 | })
13 |
14 | it('returns `false` if the given array is not empty', () => {
15 | expect(A.isEmpty([1, 2, 3])).toEqual(false)
16 | })
17 |
18 | it('*', () => {
19 | expect(A.isEmpty(['hello', 'world'])).toEqual(false)
20 | expect(A.isEmpty([])).toEqual(true)
21 | })
22 | })
23 |
24 | describe('isEmpty (pipe)', () => {
25 | it('provides correct types', () => {
26 | expectType(pipe([1, 2, 3], A.isEmpty))
27 | })
28 |
29 | it('returns `true` if the given array is empty', () => {
30 | expect(pipe([], A.isEmpty)).toEqual(true)
31 | })
32 |
33 | it('returns `false` if the given array is not empty', () => {
34 | expect(pipe([1, 2, 3], A.isEmpty)).toEqual(false)
35 | })
36 |
37 | it('*', () => {
38 | expect(pipe([1, 2, 3], A.isEmpty)).toEqual(false)
39 | })
40 | })
41 |
--------------------------------------------------------------------------------
/__tests__/String/get.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { S, A, O, pipe } from '../..'
4 |
5 | describe('get', () => {
6 | it('provides correct types', () => {
7 | expectType>(S.get('hello', 0))
8 | expectType>>(
9 | A.map(['hello', 'world'], S.get(1)),
10 | )
11 | })
12 |
13 | it('returns true if the given string starts with substr', () => {
14 | expect(S.get('hello', 1)).toEqual(O.Some('e'))
15 | })
16 |
17 | it('*', () => {
18 | const { Some } = O
19 | expect(S.get('hello', 1)).toEqual(Some('e'))
20 | })
21 | })
22 |
23 | describe('get (pipe)', () => {
24 | it('provides correct types', () => {
25 | expectType>(pipe('hello', S.get(1)))
26 | expectType>>(
27 | pipe(['hello', 'world'], A.map(S.get(1))),
28 | )
29 | })
30 |
31 | it('returns true if the given string ends with substr', () => {
32 | expect(pipe('ts-belt', S.get(1))).toEqual(O.Some('s'))
33 | })
34 |
35 | it('*', () => {
36 | const { None } = O
37 | expect(pipe('ts-belt', S.get(9))).toEqual(None)
38 | })
39 | })
40 |
--------------------------------------------------------------------------------
/tools/comment-ppx/esy.lock/opam/dot-merlin-reader.4.1/opam:
--------------------------------------------------------------------------------
1 | opam-version: "2.0"
2 | maintainer: "defree@gmail.com"
3 | authors: "The Merlin team"
4 | synopsis: "Reads config files for merlin"
5 | homepage: "https://github.com/ocaml/merlin"
6 | bug-reports: "https://github.com/ocaml/merlin/issues"
7 | dev-repo: "git+https://github.com/ocaml/merlin.git"
8 | build: [
9 | ["dune" "subst"] {dev}
10 | ["dune" "build" "-p" name "-j" jobs]
11 | ]
12 | depends: [
13 | "ocaml" {>= "4.06.1" }
14 | "dune" {>= "2.7.0"}
15 | "yojson" {>= "1.6.0"}
16 | "ocamlfind" {>= "1.6.0"}
17 | "csexp" {>= "1.2.3"}
18 | "result" {>= "1.5"}
19 | ]
20 | description:
21 | "Helper process: reads .merlin files and gives the normalized content to merlin"
22 | x-commit-hash: "ab02f60994c81166820791b5f465f467d752b8dc"
23 | url {
24 | src:
25 | "https://github.com/ocaml/merlin/releases/download/v4.1/dot-merlin-reader-v4.1.tbz"
26 | checksum: [
27 | "sha256=14a36d6fb8646a5df4530420a7861722f1a4ee04753717947305e3676031e7cd"
28 | "sha512=65fd4ab08904c05651a7ef8971802ffaa428daa920765dbcf162e3c56e8047e4c9e4356daa45efccce7c73a586635c8f6cf8118fd3059789de9aff68579bd436"
29 | ]
30 | }
31 |
--------------------------------------------------------------------------------
/__tests__/Dict/merge.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { D, pipe } from '../..'
4 |
5 | const fst = {
6 | x: 1,
7 | y: 2,
8 | }
9 |
10 | const snd = {
11 | y: 3,
12 | z: 4,
13 | }
14 |
15 | describe('merge', () => {
16 | it('provides correct types', () => {
17 | expectType<{ x: number; y: number; z: number }>(D.merge(fst, snd))
18 | })
19 |
20 | it('merges two provided objects', () => {
21 | expect(D.merge(fst, snd)).toEqual({ x: 1, y: 3, z: 4 })
22 | })
23 |
24 | it('*', () => {
25 | expect(D.merge({ x: 1, y: 2 }, { y: 3, z: 4 })).toEqual(
26 | // prettier-ignore
27 | { x: 1, y: 3, z: 4 },
28 | )
29 | })
30 | })
31 |
32 | describe('merge (pipe)', () => {
33 | it('provides correct types', () => {
34 | expectType<{ x: number; y: number; z: number }>(pipe(fst, D.merge(snd)))
35 | })
36 |
37 | it('merges two provided objects', () => {
38 | expect(pipe(fst, D.merge(snd))).toEqual({ x: 1, y: 3, z: 4 })
39 | })
40 |
41 | it('*', () => {
42 | expect(pipe({ x: 1, y: 2 }, D.merge({ y: 3, z: 4 }))).toEqual(
43 | // prettier-ignore
44 | { x: 1, y: 3, z: 4 },
45 | )
46 | })
47 | })
48 |
--------------------------------------------------------------------------------
/__tests__/Guards/isDate.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { G, F, pipe } from '../..'
4 |
5 | describe('isDate', () => {
6 | it('provides correct types', () => {
7 | const x = new Date()
8 |
9 | if (G.isDate(x)) {
10 | expectType(x)
11 | }
12 |
13 | const y: unknown = new Date()
14 |
15 | if (G.isDate(y)) {
16 | expectType(y)
17 | }
18 | })
19 |
20 | it('determines whether the provided value is Date', () => {
21 | expect(G.isDate([1, 2, 3])).toEqual(false)
22 | expect(G.isDate('hello')).toEqual(false)
23 | expect(G.isDate({})).toEqual(false)
24 | expect(G.isDate(0)).toEqual(false)
25 | expect(G.isDate(false)).toEqual(false)
26 | expect(G.isDate(F.ignore)).toEqual(false)
27 | expect(G.isDate(Promise.resolve(1))).toEqual(false)
28 | expect(G.isDate(new Date())).toEqual(true)
29 | expect(G.isArray(new Error('oops'))).toEqual(false)
30 | })
31 |
32 | it('*', () => {
33 | expect(G.isDate(new Date())).toEqual(true)
34 | })
35 | })
36 |
37 | describe('isDate (pipe)', () => {
38 | it('*', () => {
39 | expect(pipe(new Date(), G.isDate)).toEqual(true)
40 | })
41 | })
42 |
--------------------------------------------------------------------------------
/__tests__/Guards/isNumber.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { G, F, pipe } from '../..'
4 |
5 | describe('isNumber', () => {
6 | it('provides correct types', () => {
7 | const x = 0
8 |
9 | if (G.isNumber(x)) {
10 | expectType(x)
11 | }
12 |
13 | const y: unknown = 0
14 |
15 | if (G.isNumber(y)) {
16 | expectType(y)
17 | }
18 | })
19 |
20 | it('determines whether the provided value is number', () => {
21 | expect(G.isNumber([1, 2, 3])).toEqual(false)
22 | expect(G.isNumber('hello')).toEqual(false)
23 | expect(G.isNumber({})).toEqual(false)
24 | expect(G.isNumber(0)).toEqual(true)
25 | expect(G.isNumber(false)).toEqual(false)
26 | expect(G.isNumber(F.ignore)).toEqual(false)
27 | expect(G.isNumber(Promise.resolve(1))).toEqual(false)
28 | expect(G.isNumber(new Date())).toEqual(false)
29 | expect(G.isNumber(new Error('oops'))).toEqual(false)
30 | })
31 |
32 | it('*', () => {
33 | expect(G.isNumber(3)).toEqual(true)
34 | })
35 | })
36 |
37 | describe('isNumber (pipe)', () => {
38 | it('*', () => {
39 | expect(pipe(3, G.isNumber)).toEqual(true)
40 | })
41 | })
42 |
--------------------------------------------------------------------------------
/__tests__/Guards/isString.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { G, F, pipe } from '../..'
4 |
5 | describe('isString', () => {
6 | it('provides correct types', () => {
7 | const x = ''
8 |
9 | if (G.isString(x)) {
10 | expectType(x)
11 | }
12 |
13 | const y: unknown = ''
14 |
15 | if (G.isString(y)) {
16 | expectType(y)
17 | }
18 | })
19 |
20 | it('determines whether the provided value is string', () => {
21 | expect(G.isString([1, 2, 3])).toEqual(false)
22 | expect(G.isString('hello')).toEqual(true)
23 | expect(G.isString({})).toEqual(false)
24 | expect(G.isString(0)).toEqual(false)
25 | expect(G.isString(false)).toEqual(false)
26 | expect(G.isString(F.ignore)).toEqual(false)
27 | expect(G.isString(Promise.resolve(1))).toEqual(false)
28 | expect(G.isString(new Date())).toEqual(false)
29 | expect(G.isString(new Error('oops'))).toEqual(false)
30 | })
31 |
32 | it('*', () => {
33 | expect(G.isString('ts')).toEqual(true)
34 | })
35 | })
36 |
37 | describe('isString (pipe)', () => {
38 | it('*', () => {
39 | expect(pipe('belt', G.isString)).toEqual(true)
40 | })
41 | })
42 |
--------------------------------------------------------------------------------
/__tests__/String/isNotEmpty.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { S, pipe } from '../..'
4 |
5 | describe('isNotEmpty', () => {
6 | it('provides correct types', () => {
7 | expectType(S.isNotEmpty('hello'))
8 | })
9 |
10 | it('returns `true` if the given string is not empty', () => {
11 | expect(S.isNotEmpty('hello')).toEqual(true)
12 | })
13 |
14 | it('returns `false` if the given string is empty', () => {
15 | expect(S.isNotEmpty('')).toEqual(false)
16 | })
17 |
18 | it('*', () => {
19 | expect(S.isNotEmpty('hello world')).toEqual(true)
20 | expect(S.isNotEmpty('')).toEqual(false)
21 | })
22 | })
23 |
24 | describe('isNotEmpty (pipe)', () => {
25 | it('provides correct types', () => {
26 | expectType(pipe('hello', S.isNotEmpty))
27 | })
28 |
29 | it('returns `true` if the given string is not empty', () => {
30 | expect(pipe('ts-belt', S.isNotEmpty)).toEqual(true)
31 | })
32 |
33 | it('returns `false` if the given string is empty', () => {
34 | expect(pipe('', S.isNotEmpty)).toEqual(false)
35 | })
36 |
37 | it('*', () => {
38 | expect(pipe('ts-belt', S.isNotEmpty)).toEqual(true)
39 | })
40 | })
41 |
--------------------------------------------------------------------------------
/__tests__/Array/filterMap.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { A, O, pipe } from '../..'
4 |
5 | describe('filterMap', () => {
6 | it('provides correct types', () => {
7 | expectType>(
8 | A.filterMap(['', 'hello', 'world'], value => {
9 | return value.length ? O.Some(value) : O.None
10 | }),
11 | )
12 | })
13 |
14 | it('*', () => {
15 | expect(
16 | A.filterMap(['', 'hello', 'world', ''], value => {
17 | return value.length > 0 ? O.Some(value.length) : O.None
18 | }),
19 | ).toEqual([5, 5])
20 | })
21 | })
22 |
23 | describe('filterMap (pipe)', () => {
24 | it('provides correct types', () => {
25 | expectType>(
26 | pipe(
27 | [1, 2, 3, 4, 5],
28 | A.filterMap(value => {
29 | return value % 2 === 0 ? O.Some(value * 2) : O.None
30 | }),
31 | ),
32 | )
33 | })
34 |
35 | it('*', () => {
36 | expect(
37 | pipe(
38 | [1, 2, 3, 4, 5],
39 | A.filterMap(value => {
40 | return value % 2 === 0 ? O.Some(value * 2) : O.None
41 | }),
42 | ),
43 | ).toEqual([4, 8])
44 | })
45 | })
46 |
--------------------------------------------------------------------------------
/__tests__/Array/isNotEmpty.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { A, pipe } from '../..'
4 |
5 | describe('isNotEmpty', () => {
6 | it('provides correct types', () => {
7 | expectType(A.isNotEmpty([1, 2, 3]))
8 | })
9 |
10 | it('returns `true` if the given array is not empty', () => {
11 | expect(A.isNotEmpty([1, 2, 3])).toEqual(true)
12 | })
13 |
14 | it('returns `false` if the given array is empty', () => {
15 | expect(A.isNotEmpty([])).toEqual(false)
16 | })
17 |
18 | it('*', () => {
19 | expect(A.isNotEmpty(['hello', 'world'])).toEqual(true)
20 | expect(A.isNotEmpty([])).toEqual(false)
21 | })
22 | })
23 |
24 | describe('isNotEmpty (pipe)', () => {
25 | it('provides correct types', () => {
26 | expectType(pipe([1, 2, 3], A.isNotEmpty))
27 | })
28 |
29 | it('returns `true` if the given array is not empty', () => {
30 | expect(pipe([1, 2, 3], A.isNotEmpty)).toEqual(true)
31 | })
32 |
33 | it('returns `false` if the given array is empty', () => {
34 | expect(pipe([], A.isNotEmpty)).toEqual(false)
35 | })
36 |
37 | it('*', () => {
38 | expect(pipe([1, 2, 3], A.isNotEmpty)).toEqual(true)
39 | })
40 | })
41 |
--------------------------------------------------------------------------------
/__tests__/Option/getExn.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 | import { pipe, O } from '../..'
3 |
4 | describe('getExn', () => {
5 | it('provides correct types', () => {
6 | const value = '' as unknown as string | null
7 | const option = O.fromNullable(value)
8 |
9 | expectType(O.getExn(option))
10 | })
11 |
12 | it('should throw an error', () => {
13 | expect(() => {
14 | pipe(O.fromNullable(null), O.getExn)
15 | }).toThrow(Object)
16 | expect(() => {
17 | pipe(
18 | O.fromNullable('value'),
19 | O.mapNullable(_ => null),
20 | O.getExn,
21 | )
22 | }).toThrow(Object)
23 | })
24 |
25 | it('returns a value', () => {
26 | expect(pipe(O.fromNullable('value'), O.getExn)).toEqual('value')
27 | expect(
28 | pipe(
29 | O.fromNullable('value'),
30 | O.map(_ => 'this is fine'),
31 | O.getExn,
32 | ),
33 | ).toEqual('this is fine')
34 | })
35 |
36 | it('*', () => {
37 | expect(
38 | pipe(
39 | O.fromNullable('hello'),
40 | O.map(value => `${value} world!`),
41 | O.getExn,
42 | ),
43 | ).toEqual('hello world!')
44 | })
45 | })
46 |
--------------------------------------------------------------------------------
/tools/typescript-codemods/make-readonly-array.ts:
--------------------------------------------------------------------------------
1 | import { API } from 'jscodeshift'
2 |
3 | const transform = (source: string, j: API['jscodeshift']): string => {
4 | const root = j(source)
5 |
6 | root
7 | .find(j.TSFunctionType, {
8 | typeAnnotation: {
9 | typeAnnotation: {
10 | type: 'TSArrayType',
11 | },
12 | },
13 | })
14 | .replaceWith(p => {
15 | if (p.value.typeAnnotation?.typeAnnotation?.type === 'TSArrayType') {
16 | const fn = j.tsFunctionType(p.value.parameters)
17 | fn.typeParameters = p.value.typeParameters
18 | fn.typeAnnotation = j.tsTypeAnnotation(
19 | p.value.typeAnnotation.typeAnnotation,
20 | )
21 | return fn
22 | }
23 |
24 | return p.value
25 | })
26 |
27 | // T[] to Array
28 | root.find(j.TSArrayType).replaceWith(p => {
29 | const elementType = p.value.elementType
30 |
31 | if (elementType) {
32 | return j.tsTypeReference(
33 | j.identifier('Array'),
34 | j.tsTypeParameterInstantiation([elementType]),
35 | )
36 | }
37 |
38 | return p.value
39 | })
40 |
41 | return root.toSource()
42 | }
43 |
44 | export default transform
45 |
--------------------------------------------------------------------------------
/__tests__/Guards/isBoolean.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { G, F, pipe } from '../..'
4 |
5 | describe('isBoolean', () => {
6 | it('provides correct types', () => {
7 | const x = true
8 |
9 | if (G.isBoolean(x)) {
10 | expectType(x)
11 | }
12 |
13 | const y: unknown = true
14 |
15 | if (G.isBoolean(y)) {
16 | expectType(y)
17 | }
18 | })
19 |
20 | it('determines whether the provided value is boolean', () => {
21 | expect(G.isBoolean([1, 2, 3])).toEqual(false)
22 | expect(G.isBoolean('hello')).toEqual(false)
23 | expect(G.isBoolean({})).toEqual(false)
24 | expect(G.isBoolean(0)).toEqual(false)
25 | expect(G.isBoolean(false)).toEqual(true)
26 | expect(G.isBoolean(F.ignore)).toEqual(false)
27 | expect(G.isBoolean(Promise.resolve(1))).toEqual(false)
28 | expect(G.isBoolean(new Date())).toEqual(false)
29 | expect(G.isBoolean(new Error('oops'))).toEqual(false)
30 | })
31 |
32 | it('*', () => {
33 | expect(G.isBoolean(false)).toEqual(true)
34 | })
35 | })
36 |
37 | describe('isBoolean (pipe)', () => {
38 | it('*', () => {
39 | expect(pipe(true, G.isBoolean)).toEqual(true)
40 | })
41 | })
42 |
--------------------------------------------------------------------------------
/__tests__/Option/contains.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 | import { pipe, O, A } from '../..'
3 |
4 | describe('contains', () => {
5 | it('provides correct types', () => {
6 | const value = null as unknown as string | null
7 | const option = O.fromNullable(value)
8 | expectType(O.contains(option, 3))
9 | })
10 |
11 | it('returns true', () => {
12 | expect(pipe(O.fromNullable([1]), O.contains([1]))).toEqual(true)
13 | expect(pipe(O.fromNullable(false), O.contains(false))).toEqual(true)
14 | expect(
15 | pipe(O.fromNullable({ key: 'value' }), O.contains({ key: 'value' })),
16 | ).toEqual(true)
17 | expect(pipe(O.fromNullable(0), O.contains(0))).toEqual(true)
18 | })
19 |
20 | it('returns false', () => {
21 | expect(pipe(O.fromNullable(null), O.contains(0))).toEqual(false)
22 | expect(pipe(O.fromNullable(undefined), O.contains('hello'))).toEqual(false)
23 | })
24 |
25 | it('*', () => {
26 | expect(
27 | pipe(O.fromNullable([3, 6, 9]), O.flatMap(A.head), O.contains(3)),
28 | ).toEqual(true)
29 |
30 | expect(
31 | pipe(O.fromNullable([3, 6, 9]), O.flatMap(A.get(1)), O.contains(3)),
32 | ).toEqual(false)
33 | })
34 | })
35 |
--------------------------------------------------------------------------------
/tools/javascript-codemods/post/index.ts:
--------------------------------------------------------------------------------
1 | import { API, FileInfo } from 'jscodeshift'
2 |
3 | const transform = (file: FileInfo, api: API) => {
4 | const j = api.jscodeshift
5 | const root = j(file.source)
6 |
7 | // b.hasOwnProperty(key) to Object.prototype.hasOwnProperty.call(b, key)
8 | root
9 | .find(j.CallExpression, {
10 | callee: {
11 | property: {
12 | type: 'Identifier',
13 | name: 'hasOwnProperty',
14 | },
15 | },
16 | })
17 | .replaceWith(p => {
18 | if (p.value.callee.type === 'MemberExpression') {
19 | const [arg] = p.value.arguments
20 | const obj = p.value.callee.object
21 |
22 | return j.callExpression(
23 | j.memberExpression(
24 | j.memberExpression(
25 | j.memberExpression(
26 | j.identifier('Object'),
27 | j.identifier('prototype'),
28 | ),
29 | j.identifier('hasOwnProperty'),
30 | ),
31 | j.identifier('call'),
32 | ),
33 | [obj, arg],
34 | )
35 | }
36 |
37 | return p.value
38 | })
39 |
40 | return root.toSource()
41 | }
42 |
43 | export default transform
44 |
--------------------------------------------------------------------------------
/__tests__/Array/zipWithIndex.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { A, pipe } from '../..'
4 |
5 | const xs = [5, 4, 3, 2, 1]
6 |
7 | describe('zipWithIndex', () => {
8 | it('provides correct types', () => {
9 | expectType>(A.zipWithIndex(xs))
10 | })
11 |
12 | it('creates a new array of each value paired with its index in a tuple', () => {
13 | expect(A.zipWithIndex(xs)).toEqual([
14 | [5, 0],
15 | [4, 1],
16 | [3, 2],
17 | [2, 3],
18 | [1, 4],
19 | ])
20 | })
21 |
22 | it('*', () => {
23 | expect(A.zipWithIndex(['hello', 'world'])).toEqual(
24 | // prettier-ignore
25 | [['hello', 0], ['world', 1]],
26 | )
27 | })
28 | })
29 |
30 | describe('zipWithIndex (pipe)', () => {
31 | it('provides correct types', () => {
32 | expectType>(
33 | pipe(xs, A.zipWithIndex),
34 | )
35 | })
36 |
37 | it('creates a new array of each value paired with its index in a tuple', () => {
38 | expect(pipe(xs, A.zipWithIndex)).toEqual([
39 | [5, 0],
40 | [4, 1],
41 | [3, 2],
42 | [2, 3],
43 | [1, 4],
44 | ])
45 | })
46 | })
47 |
--------------------------------------------------------------------------------
/__tests__/Array/dropWhile.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { A, S, pipe } from '../..'
4 |
5 | const xs = [1, 2, 3, 4, 5, 6, 7]
6 |
7 | // TODO: expectType
8 | describe('dropWhile', () => {
9 | it('provides correct types', () => {
10 | expectType>(
11 | A.dropWhile(['hello', 'world'], S.endsWith('o')),
12 | )
13 | })
14 |
15 | it('drops elements from the beginning of the array until an element is reached which does not satisfy the given predicate', () => {
16 | expect(A.dropWhile(xs, x => x < 4)).toEqual([4, 5, 6, 7])
17 | expect(A.dropWhile([1, 3, 5, 7, 9], x => x < 5)).toEqual([5, 7, 9])
18 | })
19 |
20 | it('returns correct array elements if either true or false', () => {
21 | expect(A.dropWhile(xs, _x => true)).toEqual([])
22 | expect(A.dropWhile(xs, _x => false)).toEqual([1, 2, 3, 4, 5, 6, 7])
23 | })
24 | })
25 |
26 | describe('dropWhile (pipe)', () => {
27 | it('drops elements from the beginning of the array until an element is reached which does not satisfy the given predicate', () => {
28 | const result = pipe(
29 | xs,
30 | A.dropWhile(x => x < 4),
31 | )
32 | expect(result).toEqual([4, 5, 6, 7])
33 | })
34 | })
35 |
--------------------------------------------------------------------------------
/__tests__/Guards/isError.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { G, F, pipe } from '../..'
4 |
5 | describe('isError', () => {
6 | it('provides correct types', () => {
7 | const x = new Error('oops!')
8 |
9 | if (G.isError(x)) {
10 | expectType(x)
11 | }
12 |
13 | const y: unknown = new Error('oops!')
14 |
15 | if (G.isError(y)) {
16 | expectType(y)
17 | }
18 | })
19 |
20 | it('determines whether the provided value is Error', () => {
21 | expect(G.isError(new Error('oops'))).toEqual(true)
22 | expect(G.isError([1, 2, 3])).toEqual(false)
23 | expect(G.isError('hello')).toEqual(false)
24 | expect(G.isError({})).toEqual(false)
25 | expect(G.isError(0)).toEqual(false)
26 | expect(G.isError(true)).toEqual(false)
27 | expect(G.isError(F.ignore)).toEqual(false)
28 | expect(G.isError(Promise.resolve(1))).toEqual(false)
29 | expect(G.isError(new Date())).toEqual(false)
30 | })
31 |
32 | it('*', () => {
33 | expect(G.isError(new Error('oops!'))).toEqual(true)
34 | })
35 | })
36 |
37 | describe('isError (pipe)', () => {
38 | it('*', () => {
39 | expect(pipe(new Error('oops!'), G.isError)).toEqual(true)
40 | })
41 | })
42 |
--------------------------------------------------------------------------------
/__tests__/Guards/isObject.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 | import { G, F, pipe } from '../..'
3 |
4 | describe('isObject', () => {
5 | it('provides correct types', () => {
6 | const x = {} as Record
7 |
8 | if (G.isObject(x)) {
9 | expectType>(x)
10 | }
11 |
12 | const y: unknown = {}
13 |
14 | if (G.isObject(y)) {
15 | expectType>(y)
16 | }
17 | })
18 |
19 | it('determines whether the provided value is object', () => {
20 | expect(G.isObject({})).toEqual(true)
21 | expect(G.isObject([1, 2, 3])).toEqual(false)
22 | expect(G.isObject('hello')).toEqual(false)
23 | expect(G.isObject(0)).toEqual(false)
24 | expect(G.isObject(false)).toEqual(false)
25 | expect(G.isObject(F.ignore)).toEqual(false)
26 | expect(G.isObject(Promise.resolve(1))).toEqual(true)
27 | expect(G.isObject(new Date())).toEqual(true)
28 | expect(G.isObject(new Error('oops'))).toEqual(true)
29 | })
30 |
31 | it('*', () => {
32 | expect(G.isObject({})).toEqual(true)
33 | })
34 | })
35 |
36 | describe('isObject (pipe)', () => {
37 | it('*', () => {
38 | expect(pipe({}, G.isObject)).toEqual(true)
39 | })
40 | })
41 |
--------------------------------------------------------------------------------
/__tests__/Guards/isArray.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { G, F, pipe } from '../..'
4 |
5 | describe('isArray', () => {
6 | it('provides correct types', () => {
7 | const xs = [1, 2, 3]
8 |
9 | if (G.isArray(xs)) {
10 | expectType>(xs)
11 | }
12 |
13 | const ys: unknown = [1, 2, 3]
14 |
15 | if (G.isArray(ys)) {
16 | expectType>(ys)
17 | }
18 | })
19 |
20 | it('determines whether the provided value is array', () => {
21 | expect(G.isArray([1, 2, 3])).toEqual(true)
22 | expect(G.isArray('hello')).toEqual(false)
23 | expect(G.isArray({})).toEqual(false)
24 | expect(G.isArray(0)).toEqual(false)
25 | expect(G.isArray(false)).toEqual(false)
26 | expect(G.isArray(F.ignore)).toEqual(false)
27 | expect(G.isArray(Promise.resolve(1))).toEqual(false)
28 | expect(G.isArray(new Date())).toEqual(false)
29 | expect(G.isArray(new Error('oops'))).toEqual(false)
30 | })
31 |
32 | it('*', () => {
33 | expect(G.isArray([1, 2, 3])).toEqual(true)
34 | })
35 | })
36 |
37 | describe('isArray (pipe)', () => {
38 | it('*', () => {
39 | expect(pipe(['hello', 'world'], G.isArray)).toEqual(true)
40 | })
41 | })
42 |
--------------------------------------------------------------------------------
/__tests__/Guards/isFunction.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { G, F, pipe } from '../..'
4 |
5 | describe('isError', () => {
6 | it('provides correct types', () => {
7 | const x = F.ignore
8 |
9 | if (G.isFunction(x)) {
10 | expectType(x)
11 | }
12 |
13 | const y: unknown = F.ignore
14 |
15 | if (G.isFunction(y)) {
16 | expectType(y)
17 | }
18 | })
19 |
20 | it('determines whether the provided value is function', () => {
21 | expect(G.isFunction([1, 2, 3])).toEqual(false)
22 | expect(G.isFunction('hello')).toEqual(false)
23 | expect(G.isFunction({})).toEqual(false)
24 | expect(G.isFunction(0)).toEqual(false)
25 | expect(G.isFunction(false)).toEqual(false)
26 | expect(G.isFunction(F.ignore)).toEqual(true)
27 | expect(G.isFunction(Promise.resolve(1))).toEqual(false)
28 | expect(G.isFunction(new Date())).toEqual(false)
29 | expect(G.isArray(new Error('oops'))).toEqual(false)
30 | })
31 |
32 | it('*', () => {
33 | expect(G.isFunction(F.ignore)).toEqual(true)
34 | })
35 | })
36 |
37 | describe('isFunction (pipe)', () => {
38 | it('*', () => {
39 | expect(pipe(F.ignore, G.isFunction)).toEqual(true)
40 | })
41 | })
42 |
--------------------------------------------------------------------------------
/__tests__/Result/fromFalsy.test.ts:
--------------------------------------------------------------------------------
1 | import { R } from '../..'
2 |
3 | describe('fromFalsy', () => {
4 | it('returns Error', () => {
5 | expect(R.fromFalsy(null, 'this is bad')).toEqual(R.Error('this is bad'))
6 | expect(R.fromFalsy(undefined, 'this is bad')).toEqual(
7 | R.Error('this is bad'),
8 | )
9 | expect(R.fromFalsy(0, 'this is bad')).toEqual(R.Error('this is bad'))
10 | expect(R.fromFalsy('', 'this is bad')).toEqual(R.Error('this is bad'))
11 | expect(R.fromFalsy(false, 'this is bad')).toEqual(R.Error('this is bad'))
12 | })
13 |
14 | it('returns Ok', () => {
15 | expect(R.fromFalsy('value', 'this is bad')).toEqual(R.Ok('value'))
16 | expect(R.fromFalsy([], 'this is bad')).toEqual(R.Ok([]))
17 | expect(R.fromFalsy({}, 'this is bad')).toEqual(R.Ok({}))
18 | })
19 |
20 | it('*', () => {
21 | const { Ok, Error } = R
22 | expect(R.fromFalsy(4, 'falsy')).toEqual(Ok(4))
23 | expect(R.fromFalsy([], 'falsy')).toEqual(Ok([]))
24 | expect(R.fromFalsy({}, 'falsy')).toEqual(Ok({}))
25 | expect(R.fromFalsy(0, 'falsy')).toEqual(Error('falsy'))
26 | expect(R.fromFalsy('', 'falsy')).toEqual(Error('falsy'))
27 | expect(R.fromFalsy(false, 'falsy')).toEqual(Error('falsy'))
28 | })
29 | })
30 |
--------------------------------------------------------------------------------
/tools/typescript-codemods/make-readonly-tuples.ts:
--------------------------------------------------------------------------------
1 | import { API } from 'jscodeshift'
2 |
3 | const transform = (source: string, j: API['jscodeshift']): string => {
4 | const root = j(source)
5 |
6 | // [A, B] to readonly [A, B]
7 | root
8 | .find(j.TSFunctionType, {
9 | typeAnnotation: {
10 | typeAnnotation: {
11 | type: 'TSTupleType',
12 | },
13 | },
14 | })
15 | .replaceWith(p => {
16 | if (p.value.typeAnnotation?.typeAnnotation?.type === 'TSTupleType') {
17 | const fn = j.tsFunctionType(p.value.parameters)
18 | fn.typeParameters = p.value.typeParameters
19 | fn.typeAnnotation = j.tsTypeAnnotation(
20 | p.value.typeAnnotation.typeAnnotation,
21 | )
22 | return fn
23 | }
24 |
25 | return p.value
26 | })
27 |
28 | root.find(j.TSTupleType).replaceWith(p => {
29 | if (p.parent && p.parent.value.operator !== 'readonly') {
30 | const operator = {
31 | typeAnnotation: p.value,
32 | type: 'TSTypeOperator',
33 | operator: 'readonly',
34 | }
35 |
36 | return operator
37 | }
38 |
39 | return p.value
40 | })
41 |
42 | return root.toSource()
43 | }
44 |
45 | export default transform
46 |
--------------------------------------------------------------------------------
/__tests__/Function/once.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { F, N } from '../..'
4 |
5 | const fn = (n: number) => {
6 | return `called ${n} times`
7 | }
8 |
9 | const fn2 = (n: number, x: string) => {
10 | return `called ${n} times with ${x}`
11 | }
12 |
13 | describe('once', () => {
14 | it('provides correct types', () => {
15 | expectType<(n: number) => string>(F.once(fn))
16 | expectType<(n: number, x: string) => string>(F.once(fn2))
17 | expectType<(n: number) => number>(F.once(N.add(2)))
18 | })
19 |
20 | it('handles multiple parameters', function () {
21 | let calls = 0
22 | const addTwoNumbers = (x: number, y: number) => {
23 | calls = calls + 1
24 | return x + y
25 | }
26 | const add = F.once(addTwoNumbers)
27 |
28 | expect(add(2, 2)).toEqual(4)
29 | expect(add(4, 4)).toEqual(4)
30 | expect(add(8, 8)).toEqual(4)
31 | expect(calls).toEqual(1)
32 | })
33 |
34 | it('*', () => {
35 | const addTwoOnce = F.once(N.add(2))
36 |
37 | expect(
38 | /*
39 | const addTwoOnce = F.once(N.add(2))
40 | */
41 | addTwoOnce(4),
42 | ).toEqual(6)
43 | expect(addTwoOnce(8)).toEqual(6)
44 | expect(addTwoOnce(16)).toEqual(6)
45 | })
46 | })
47 |
--------------------------------------------------------------------------------
/__tests__/Option/fromFalsy.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 | import { O } from '../..'
3 |
4 | describe('fromFalsy', () => {
5 | it('provides correct types', () => {
6 | const value = null as unknown as string | null
7 |
8 | expectType>(O.fromFalsy(value))
9 | expectType>(O.fromFalsy(null))
10 | })
11 |
12 | it('returns None', () => {
13 | expect(O.fromFalsy(null)).toEqual(O.None)
14 | expect(O.fromFalsy(undefined)).toEqual(O.None)
15 | expect(O.fromFalsy(0)).toEqual(O.None)
16 | expect(O.fromFalsy('')).toEqual(O.None)
17 | expect(O.fromFalsy(false)).toEqual(O.None)
18 | })
19 |
20 | it('returns Some', () => {
21 | expect(O.fromFalsy('value')).toEqual(O.Some('value'))
22 | expect(O.fromFalsy(1)).toEqual(O.Some(1))
23 | expect(O.fromFalsy([])).toEqual(O.Some([]))
24 | expect(O.fromFalsy({})).toEqual(O.Some({}))
25 | })
26 |
27 | it('*', () => {
28 | const { Some, None } = O
29 |
30 | expect(O.fromFalsy(1)).toEqual(Some(1))
31 | expect(O.fromFalsy('hello world')).toEqual(Some('hello world'))
32 | expect(O.fromFalsy([])).toEqual(Some([]))
33 | expect(O.fromFalsy(0)).toEqual(None)
34 | expect(O.fromFalsy('')).toEqual(None)
35 | })
36 | })
37 |
--------------------------------------------------------------------------------
/__tests__/Option/toNullable.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 | import { pipe, O, A } from '../..'
3 |
4 | describe('toNullable', () => {
5 | it('provides correct types', () => {
6 | expectType(O.toNullable(O.None))
7 | expectType(O.toNullable(O.Some('hello')))
8 | })
9 |
10 | it('returns null', () => {
11 | expect(pipe(O.None, O.toNullable)).toBe(null)
12 | expect(
13 | pipe(
14 | O.fromNullable({ prop: null }),
15 | O.mapNullable(obj => obj.prop),
16 | O.toNullable,
17 | ),
18 | ).toEqual(null)
19 | })
20 |
21 | it('returns a value', () => {
22 | expect(pipe(O.Some('value'), O.toNullable)).toEqual('value')
23 | expect(
24 | pipe(
25 | O.fromNullable({ prop: 'value' }),
26 | O.mapNullable(obj => obj.prop),
27 | O.toNullable,
28 | ),
29 | ).toEqual('value')
30 | })
31 |
32 | it('*', () => {
33 | expect(
34 | pipe(
35 | O.fromNullable(['hello', 'world']),
36 | O.flatMap(A.takeExactly(2)),
37 | O.toNullable,
38 | ),
39 | ).toEqual(['hello', 'world'])
40 | expect(
41 | pipe(O.fromNullable([]), O.flatMap(A.takeExactly(2)), O.toNullable),
42 | ).toEqual(null)
43 | })
44 | })
45 |
--------------------------------------------------------------------------------
/tools/comment-ppx/esy.lock/overrides/opam__s__ocamlfind_opam__c__1.9.1_opam_override/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "build": [
3 | [
4 | "bash",
5 | "-c",
6 | "#{os == 'windows' ? 'patch -p1 < findlib-1.9.1.patch' : 'true'}"
7 | ],
8 | [
9 | "./configure",
10 | "-bindir",
11 | "#{self.bin}",
12 | "-sitelib",
13 | "#{self.lib}",
14 | "-mandir",
15 | "#{self.man}",
16 | "-config",
17 | "#{self.lib}/findlib.conf",
18 | "-no-custom",
19 | "-no-topfind"
20 | ],
21 | [
22 | "make",
23 | "all"
24 | ],
25 | [
26 | "make",
27 | "opt"
28 | ]
29 | ],
30 | "install": [
31 | [
32 | "make",
33 | "install"
34 | ],
35 | [
36 | "install",
37 | "-m",
38 | "0755",
39 | "ocaml-stub",
40 | "#{self.bin}/ocaml"
41 | ],
42 | [
43 | "mkdir",
44 | "-p",
45 | "#{self.toplevel}"
46 | ],
47 | [
48 | "install",
49 | "-m",
50 | "0644",
51 | "src/findlib/topfind",
52 | "#{self.toplevel}/topfind"
53 | ]
54 | ],
55 | "exportedEnv": {
56 | "OCAML_TOPLEVEL_PATH": {
57 | "val": "#{self.toplevel}",
58 | "scope": "global"
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/__tests__/Number/lt.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { N, pipe } from '../..'
4 |
5 | describe('lt', () => {
6 | it('provides correct types', () => {
7 | expectType(N.lt(2, 2))
8 | })
9 |
10 | it('reports if first argument is lower than second', () => {
11 | expect(N.lt(2, 4)).toEqual(true)
12 | expect(N.lt(4, 2)).toEqual(false)
13 | expect(N.lt(2, 2)).toEqual(false)
14 |
15 | expect(N.lt(2.0, 2.0)).toEqual(false)
16 | expect(N.lt(1.9, 2.0)).toEqual(true)
17 | expect(N.lt(2.1, 2.0)).toEqual(false)
18 | })
19 |
20 | it('*', () => {
21 | expect(N.lt(2, 4)).toEqual(true)
22 | })
23 | })
24 |
25 | describe('lt (pipe)', () => {
26 | it('provides correct types', () => {
27 | expectType(pipe(3, N.lt(6)))
28 | })
29 |
30 | it('reports if first argument is lower than second', () => {
31 | expect(pipe(2, N.lt(4))).toEqual(true)
32 | expect(pipe(4, N.lt(2))).toEqual(false)
33 | expect(pipe(2, N.lt(2))).toEqual(false)
34 |
35 | expect(pipe(2.0, N.lt(2.0))).toEqual(false)
36 | expect(pipe(1.9, N.lt(2.0))).toEqual(true)
37 | expect(pipe(2.1, N.lt(2.0))).toEqual(false)
38 | })
39 |
40 | it('*', () => {
41 | expect(pipe(4, N.lt(2))).toEqual(false)
42 | })
43 | })
44 |
--------------------------------------------------------------------------------
/__tests__/Function/before.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { F, N } from '../..'
4 |
5 | const fn = (n: number) => {
6 | return `called ${n} times`
7 | }
8 |
9 | const fn2 = (n: number, x: string) => {
10 | return `called ${n} times with ${x}`
11 | }
12 |
13 | describe('before', () => {
14 | it('provides correct types', () => {
15 | expectType<(n: number) => string>(F.before(2, fn))
16 | expectType<(n: number, x: string) => string>(F.before(2, fn2))
17 | expectType<(n: number) => number>(F.before(2, N.add(2)))
18 | })
19 |
20 | it('handles multiple parameters', function () {
21 | let calls = 0
22 |
23 | const addTwoNumbers = (x: number, y: number) => {
24 | calls = calls + 1
25 | return x + y
26 | }
27 | const add = F.before(2, addTwoNumbers)
28 |
29 | expect(add(2, 2)).toEqual(4)
30 | expect(add(4, 4)).toEqual(8)
31 | expect(add(8, 8)).toEqual(8)
32 | expect(calls).toEqual(2)
33 | })
34 |
35 | it('*', () => {
36 | const addOne = F.before(2, N.add(1))
37 |
38 | expect(
39 | /*
40 | const addOne = F.before(2, N.add(1))
41 | */
42 | addOne(3),
43 | ).toEqual(4)
44 | expect(addOne(6)).toEqual(7)
45 | expect(addOne(12)).toEqual(7)
46 | })
47 | })
48 |
--------------------------------------------------------------------------------
/__tests__/Number/gt.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { N, pipe } from '../..'
4 |
5 | describe('gt', () => {
6 | it('provides correct types', () => {
7 | expectType(N.gt(2, 2))
8 | })
9 |
10 | it('reports if first argument is greater than second', () => {
11 | expect(N.gt(2, 4)).toEqual(false)
12 | expect(N.gt(4, 2)).toEqual(true)
13 | expect(N.gt(2, 2)).toEqual(false)
14 |
15 | expect(N.gt(2.0, 2.0)).toEqual(false)
16 | expect(N.gt(1.9, 2.0)).toEqual(false)
17 | expect(N.gt(2.1, 2.0)).toEqual(true)
18 | })
19 |
20 | it('*', () => {
21 | expect(N.gt(2, 4)).toEqual(false)
22 | })
23 | })
24 |
25 | describe('gt (pipe)', () => {
26 | it('provides correct types', () => {
27 | expectType(pipe(3, N.gt(6)))
28 | })
29 |
30 | it('reports if first argument is greater than second', () => {
31 | expect(pipe(2, N.gt(4))).toEqual(false)
32 | expect(pipe(4, N.gt(2))).toEqual(true)
33 | expect(pipe(2, N.gt(2))).toEqual(false)
34 |
35 | expect(pipe(2.0, N.gt(2.0))).toEqual(false)
36 | expect(pipe(1.9, N.gt(2.0))).toEqual(false)
37 | expect(pipe(2.1, N.gt(2.0))).toEqual(true)
38 | })
39 |
40 | it('*', () => {
41 | expect(pipe(4, N.gt(2))).toEqual(true)
42 | })
43 | })
44 |
--------------------------------------------------------------------------------
/__tests__/String/indexOf.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { S, A, O, pipe } from '../..'
4 |
5 | describe('indexOf', () => {
6 | it('provides correct types', () => {
7 | expectType>(S.indexOf('hello', 'l'))
8 | expectType>(
9 | A.keepMap(['hello', 'world'], S.indexOf('o')),
10 | )
11 | })
12 |
13 | it('returns an index correctly', () => {
14 | expect(S.indexOf('hello', 'e')).toEqual(O.Some(1))
15 | expect(S.indexOf('world', 'x')).toEqual(O.None)
16 | })
17 |
18 | it('*', () => {
19 | const { Some } = O
20 | expect(S.indexOf('hello', 'e')).toEqual(Some(1))
21 | })
22 | })
23 |
24 | describe('indexOf (pipe)', () => {
25 | it('provides correct types', () => {
26 | expectType>(pipe('hello', S.indexOf('l')))
27 | expectType>>(
28 | pipe(['hello', 'world'], A.map(S.indexOf('l'))),
29 | )
30 | })
31 |
32 | it('returns an index correctly', () => {
33 | expect(pipe('ts-belt', S.indexOf('-'))).toEqual(O.Some(2))
34 | expect(pipe('ts-belt', S.indexOf('x'))).toEqual(O.None)
35 | })
36 |
37 | it('*', () => {
38 | expect(pipe(['hello', 'world'], A.keepMap(S.indexOf('o')))).toEqual([4, 1])
39 | })
40 | })
41 |
--------------------------------------------------------------------------------
/tools/comment-ppx/esy.lock/opam/junit.2.0.2/opam:
--------------------------------------------------------------------------------
1 | opam-version: "2.0"
2 | maintainer: "Louis Roché "
3 | authors: "Louis Roché "
4 | homepage: "https://github.com/Khady/ocaml-junit"
5 | bug-reports: "https://github.com/Khady/ocaml-junit/issues"
6 | license: "LGPL-3.0-or-later WITH OCaml-LGPL-linking-exception"
7 | dev-repo: "git+https://github.com/Khady/ocaml-junit.git"
8 | doc: "https://khady.github.io/ocaml-junit/"
9 | tags: ["junit" "jenkins"]
10 | depends: [
11 | "dune" {>= "1.0"}
12 | "ptime"
13 | "tyxml" {>= "4.0.0"}
14 | "odoc" {with-doc & >= "1.1.1"}
15 | ]
16 | build: [
17 | ["dune" "subst"] {dev}
18 | ["dune" "build" "-p" name "-j" jobs]
19 | ["dune" "runtest" "-p" name "-j" jobs] {with-test}
20 | ["dune" "build" "-p" name "-j" jobs] {with-doc}
21 | ]
22 | synopsis: "JUnit XML reports generation library"
23 | description: "JUnit XML reports generation library"
24 | url {
25 | src:
26 | "https://github.com/Khady/ocaml-junit/releases/download/2.0.2/junit-2.0.2.tbz"
27 | checksum: [
28 | "sha256=fda941b653613a4a5731f9b3557364b12baa341daa13c01676c9eb8d64e96b01"
29 | "sha512=5a9fa803c4861748bb8482fc51197420bf3cc3b9540989a489c4ffb65fdd02386aaa60437eae29182209dae0903b0e537c095249e19d395a451b8e8214f15f03"
30 | ]
31 | }
32 |
--------------------------------------------------------------------------------
/__tests__/Guards/isPromise.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { G, F, pipe } from '../..'
4 |
5 | describe('isPromise', () => {
6 | it('provides correct types', () => {
7 | const x = Promise.resolve(1)
8 |
9 | if (G.isPromise(x)) {
10 | expectType>(x)
11 | }
12 |
13 | const y: unknown = Promise.resolve(1)
14 |
15 | if (G.isPromise(y)) {
16 | expectType>(y)
17 | }
18 | })
19 |
20 | it('determines whether the provided value is Promise', () => {
21 | expect(G.isPromise([1, 2, 3])).toEqual(false)
22 | expect(G.isPromise('hello')).toEqual(false)
23 | expect(G.isPromise({})).toEqual(false)
24 | expect(G.isPromise(0)).toEqual(false)
25 | expect(G.isPromise(false)).toEqual(false)
26 | expect(G.isPromise(F.ignore)).toEqual(false)
27 | expect(G.isPromise(Promise.resolve(1))).toEqual(true)
28 | expect(G.isPromise(new Date())).toEqual(false)
29 | expect(G.isPromise(new Error('oops'))).toEqual(false)
30 | })
31 |
32 | it('*', () => {
33 | expect(G.isPromise(Promise.resolve(1))).toEqual(true)
34 | })
35 | })
36 |
37 | describe('isPromise (pipe)', () => {
38 | it('*', () => {
39 | expect(pipe(Promise.resolve(1), G.isPromise)).toEqual(true)
40 | })
41 | })
42 |
--------------------------------------------------------------------------------
/__tests__/Number/clamp.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { N, pipe } from '../..'
4 |
5 | describe('clamp', () => {
6 | it('provides correct types', () => {
7 | expectType(N.clamp(2, 2, 5))
8 | })
9 |
10 | it('clamps value', () => {
11 | expect(N.clamp(2, 4, 5)).toEqual(4)
12 | expect(N.clamp(8, 2, 5)).toEqual(5)
13 | expect(N.clamp(6, 2, 10)).toEqual(6)
14 |
15 | expect(N.clamp(2.0, 2.1, 5)).toEqual(2.1)
16 | expect(N.clamp(8.1, 2, 8.05)).toEqual(8.05)
17 | expect(N.clamp(6.01, 0.2, 10.8)).toEqual(6.01)
18 | })
19 |
20 | it('*', () => {
21 | expect(N.clamp(2, 4, 6)).toEqual(4)
22 | })
23 | })
24 |
25 | describe('clamp (pipe)', () => {
26 | it('provides correct types', () => {
27 | expectType(pipe(3, N.clamp(6, 10)))
28 | })
29 |
30 | it('clamps value', () => {
31 | expect(pipe(2, N.clamp(3, 6))).toEqual(3)
32 | expect(pipe(8, N.clamp(2, 4))).toEqual(4)
33 | expect(pipe(6, N.clamp(1, 10))).toEqual(6)
34 |
35 | expect(pipe(2.0, N.clamp(2.1, 5))).toEqual(2.1)
36 | expect(pipe(6.1, N.clamp(1.1, 5.5))).toEqual(5.5)
37 | expect(pipe(0.11, N.clamp(0.1, 5))).toEqual(0.11)
38 | })
39 |
40 | it('*', () => {
41 | expect(pipe(10, N.clamp(2, 5))).toEqual(5)
42 | })
43 | })
44 |
--------------------------------------------------------------------------------
/__tests__/Function/defaultTo.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { F, pipe } from '../..'
4 |
5 | const nullable = F.coerce(null)
6 |
7 | describe('defaultTo', () => {
8 | it('provides correct types', () => {
9 | expectType(F.defaultTo(1, 2))
10 | expectType(F.defaultTo(nullable, 'default'))
11 | })
12 |
13 | it('returns a default value', function () {
14 | expect(F.defaultTo(nullable, 'default')).toEqual('default')
15 | })
16 |
17 | it('returns a non-nullable value', function () {
18 | expect(F.defaultTo(1, 2)).toEqual(1)
19 | expect(F.defaultTo('hello', 'default')).toEqual('hello')
20 | })
21 |
22 | it('*', () => {
23 | // ⬇️ const nullable = F.coerce(null)
24 | expect(F.defaultTo(nullable, 'default')).toEqual('default')
25 | })
26 | })
27 |
28 | describe('defaultTo (pipe)', () => {
29 | it('provides correct types', () => {
30 | expectType(pipe(1, F.defaultTo(2)))
31 | expectType(pipe(nullable, F.defaultTo('default')))
32 | })
33 |
34 | it('returns a default value', () => {
35 | expect(pipe(nullable, F.defaultTo('default'))).toEqual('default')
36 | })
37 |
38 | it('*', () => {
39 | expect(pipe(2, F.defaultTo(1))).toEqual(2)
40 | })
41 | })
42 |
--------------------------------------------------------------------------------
/tools/comment-ppx/esy.lock/opam/ocamlbuild.0.14.0/opam:
--------------------------------------------------------------------------------
1 | opam-version: "2.0"
2 | maintainer: "Gabriel Scherer "
3 | authors: ["Nicolas Pouillard" "Berke Durak"]
4 | homepage: "https://github.com/ocaml/ocamlbuild/"
5 | bug-reports: "https://github.com/ocaml/ocamlbuild/issues"
6 | license: "LGPL-2.1-only WITH OCaml-LGPL-linking-exception"
7 | doc: "https://github.com/ocaml/ocamlbuild/blob/master/manual/manual.adoc"
8 | dev-repo: "git+https://github.com/ocaml/ocamlbuild.git"
9 | build: [
10 | [
11 | make
12 | "-f"
13 | "configure.make"
14 | "all"
15 | "OCAMLBUILD_PREFIX=%{prefix}%"
16 | "OCAMLBUILD_BINDIR=%{bin}%"
17 | "OCAMLBUILD_LIBDIR=%{lib}%"
18 | "OCAMLBUILD_MANDIR=%{man}%"
19 | "OCAML_NATIVE=%{ocaml:native}%"
20 | "OCAML_NATIVE_TOOLS=%{ocaml:native}%"
21 | ]
22 | [make "check-if-preinstalled" "all" "opam-install"]
23 | ]
24 | conflicts: [
25 | "base-ocamlbuild"
26 | "ocamlfind" {< "1.6.2"}
27 | ]
28 | synopsis:
29 | "OCamlbuild is a build system with builtin rules to easily build most OCaml projects."
30 | depends: [
31 | "ocaml" {>= "4.03"}
32 | ]
33 | url {
34 | src: "https://github.com/ocaml/ocamlbuild/archive/0.14.0.tar.gz"
35 | checksum: "sha256=87b29ce96958096c0a1a8eeafeb6268077b2d11e1bf2b3de0f5ebc9cf8d42e78"
36 | }
37 |
--------------------------------------------------------------------------------
/__tests__/Dict/values.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { D, pipe } from '../..'
4 |
5 | type T = {
6 | readonly name: string
7 | readonly age: number
8 | }
9 |
10 | const user: T = {
11 | name: 'Joe',
12 | age: 20,
13 | }
14 |
15 | describe('values', () => {
16 | it('provides correct types', () => {
17 | expectType>(D.values(user))
18 | })
19 |
20 | it('returns a new array that contains all values of the provided object', () => {
21 | expect(D.values(user)).toEqual(['Joe', 20])
22 | })
23 |
24 | it('*', () => {
25 | expect(
26 | D.values({
27 | name: 'Joe',
28 | age: 20,
29 | }),
30 | ).toEqual(['Joe', 20])
31 | })
32 | })
33 |
34 | describe('values (pipe)', () => {
35 | it('provides correct types', () => {
36 | expectType>(pipe(user, D.values))
37 | })
38 |
39 | it('returns a new array that contains all values of the provided object', () => {
40 | expect(pipe(user, D.values)).toEqual(['Joe', 20])
41 | })
42 |
43 | it('*', () => {
44 | expect(
45 | pipe(
46 | {
47 | name: 'Joe',
48 | age: 20,
49 | },
50 | D.values,
51 | ),
52 | ).toEqual(['Joe', 20])
53 | })
54 | })
55 |
--------------------------------------------------------------------------------
/__tests__/Result/flip.test.ts:
--------------------------------------------------------------------------------
1 | import { pipe, R } from '../..'
2 | import { expectType } from 'ts-expect'
3 |
4 | describe('flip', () => {
5 | it('provides correct types', () => {
6 | expectType>(
7 | pipe(R.fromNullable(0, 'this is bad'), R.flip),
8 | )
9 | })
10 |
11 | it('returns Ok', () => {
12 | expect(pipe(R.fromNullable(null, 'this is bad'), R.flip)).toEqual(
13 | R.Ok('this is bad'),
14 | )
15 | })
16 |
17 | it('returns Error', () => {
18 | expect(pipe(R.fromNullable([1, 2, 3], 'this is bad'), R.flip)).toEqual(
19 | R.Error([1, 2, 3]),
20 | )
21 | })
22 |
23 | it('*', () => {
24 | const { Ok, Error } = R
25 |
26 | let value: string | null = 'Joe'
27 |
28 | expect(
29 | // type Value = string | null
30 | pipe(
31 | // ⬇️ const value: Value = 'Joe'
32 | R.fromNullable(value, 'value cannot be nullable'),
33 | R.flip,
34 | ),
35 | ).toEqual(Error('Joe'))
36 |
37 | value = null
38 |
39 | expect(
40 | // type Value = string | null
41 | pipe(
42 | // ⬇️ const value: Value = null
43 | R.fromNullable(value, 'value cannot be nullable'),
44 | R.flip,
45 | ),
46 | ).toEqual(Ok('value cannot be nullable'))
47 | })
48 | })
49 |
--------------------------------------------------------------------------------
/__tests__/Number/lte.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { N, pipe } from '../..'
4 |
5 | describe('lte', () => {
6 | it('provides correct types', () => {
7 | expectType(N.lte(2, 2))
8 | })
9 |
10 | it('reports if first argument is lower or equal than second', () => {
11 | expect(N.lte(2, 4)).toEqual(true)
12 | expect(N.lte(4, 2)).toEqual(false)
13 | expect(N.lte(2, 2)).toEqual(true)
14 |
15 | expect(N.lte(2.0, 2.0)).toEqual(true)
16 | expect(N.lte(1.9, 2.0)).toEqual(true)
17 | expect(N.lte(2.1, 2.0)).toEqual(false)
18 | })
19 |
20 | it('*', () => {
21 | expect(N.lte(2, 4)).toEqual(true)
22 | })
23 | })
24 |
25 | describe('lte (pipe)', () => {
26 | it('provides correct types', () => {
27 | expectType(pipe(3, N.lte(6)))
28 | })
29 |
30 | it('reports if first argument is lower or equal than second', () => {
31 | expect(pipe(2, N.lte(4))).toEqual(true)
32 | expect(pipe(4, N.lte(2))).toEqual(false)
33 | expect(pipe(2, N.lte(2))).toEqual(true)
34 |
35 | expect(pipe(2.0, N.lte(2.0))).toEqual(true)
36 | expect(pipe(1.9, N.lte(2.0))).toEqual(true)
37 | expect(pipe(2.1, N.lte(2.0))).toEqual(false)
38 | })
39 |
40 | it('*', () => {
41 | expect(pipe(4, N.lte(2))).toEqual(false)
42 | })
43 | })
44 |
--------------------------------------------------------------------------------
/tools/comment-ppx/esy.lock/opam/merlin-extend.0.6/opam:
--------------------------------------------------------------------------------
1 | opam-version: "2.0"
2 | maintainer: "Frederic Bour "
3 | authors: "Frederic Bour "
4 | homepage: "https://github.com/let-def/merlin-extend"
5 | bug-reports: "https://github.com/let-def/merlin-extend"
6 | license: "MIT"
7 | dev-repo: "git+https://github.com/let-def/merlin-extend.git"
8 | build: [
9 | ["dune" "subst"] {dev}
10 | ["dune" "build" "-p" name "-j" jobs]
11 | ]
12 | depends: [
13 | "dune" {>= "1.0"}
14 | "cppo" {build & >= "1.1.0"}
15 | "ocaml" {>= "4.02.3"}
16 | ]
17 | synopsis: "A protocol to provide custom frontend to Merlin"
18 | description: """
19 | This protocol allows to replace the OCaml frontend of Merlin.
20 | It extends what used to be done with the `-pp' flag to handle a few more cases."""
21 | doc: "https://let-def.github.io/merlin-extend"
22 | x-commit-hash: "640620568a5f5c7798239ecf7c707c813e3df3cf"
23 | url {
24 | src:
25 | "https://github.com/let-def/merlin-extend/releases/download/v0.6/merlin-extend-v0.6.tbz"
26 | checksum: [
27 | "sha256=c2f236ae97feb6ba0bc90f33beb7b7343e42f9871b66de9ba07974917e256c43"
28 | "sha512=4c64a490e2ece04fc89aef679c1d9202175df4fe045b5fdc7a37cd7cebe861226fddd9648c1bf4f06175ecfcd2ed7686c96bd6a8cae003a5096f6134c240f857"
29 | ]
30 | }
31 |
--------------------------------------------------------------------------------
/__tests__/Number/gte.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { N, pipe } from '../..'
4 |
5 | describe('gte', () => {
6 | it('provides correct types', () => {
7 | expectType(N.gte(2, 2))
8 | })
9 |
10 | it('reports if first argument is greater or equal than second', () => {
11 | expect(N.gte(2, 4)).toEqual(false)
12 | expect(N.gte(4, 2)).toEqual(true)
13 | expect(N.gte(2, 2)).toEqual(true)
14 |
15 | expect(N.gte(2.0, 2.0)).toEqual(true)
16 | expect(N.gte(1.9, 2.0)).toEqual(false)
17 | expect(N.gte(2.1, 2.0)).toEqual(true)
18 | })
19 |
20 | it('*', () => {
21 | expect(N.gte(2, 4)).toEqual(false)
22 | })
23 | })
24 |
25 | describe('gte (pipe)', () => {
26 | it('provides correct types', () => {
27 | expectType(pipe(3, N.gte(6)))
28 | })
29 |
30 | it('reports if first argument is greater or equal than second', () => {
31 | expect(pipe(2, N.gte(4))).toEqual(false)
32 | expect(pipe(4, N.gte(2))).toEqual(true)
33 | expect(pipe(2, N.gte(2))).toEqual(true)
34 |
35 | expect(pipe(2.0, N.gte(2.0))).toEqual(true)
36 | expect(pipe(1.9, N.gte(2.0))).toEqual(false)
37 | expect(pipe(2.1, N.gte(2.0))).toEqual(true)
38 | })
39 |
40 | it('*', () => {
41 | expect(pipe(4, N.gte(2))).toEqual(true)
42 | })
43 | })
44 |
--------------------------------------------------------------------------------
/__tests__/Option/map.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 | import { pipe, O, A } from '../..'
3 |
4 | describe('map', () => {
5 | it('provides correct types', () => {
6 | const value = null as unknown as string | null
7 | const option = O.fromNullable(value)
8 |
9 | expectType>(
10 | O.map(option, value => {
11 | return `${value}!`
12 | }),
13 | )
14 | })
15 |
16 | it('returns None', () => {
17 | expect(
18 | pipe(
19 | O.fromNullable(null),
20 | O.map(_ => 'this is fine'),
21 | ),
22 | ).toEqual(O.None)
23 | })
24 |
25 | it('returns Some', () => {
26 | expect(
27 | pipe(
28 | O.fromNullable([1, 2, 3]),
29 | O.map(_ => 'this is fine'),
30 | ),
31 | ).toEqual(O.Some('this is fine'))
32 | })
33 |
34 | it('*', () => {
35 | const { Some, None } = O
36 |
37 | expect(
38 | pipe(
39 | O.fromNullable([1, 2, 3]),
40 | O.flatMap(A.get(0)),
41 | O.map(n => `${n}. hello world!`),
42 | ),
43 | ).toEqual(Some('1. hello world!'))
44 |
45 | expect(
46 | pipe(
47 | O.fromNullable([]),
48 | O.flatMap(A.get(0)),
49 | O.map(n => `${n}. hello world!`),
50 | ),
51 | ).toEqual(None)
52 | })
53 | })
54 |
--------------------------------------------------------------------------------
/__tests__/Option/toUndefined.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 | import { pipe, O, A } from '../..'
3 |
4 | describe('toUndefined', () => {
5 | it('provides correct types', () => {
6 | expectType(O.toUndefined(O.None))
7 | expectType(O.toUndefined(O.Some('hello')))
8 | })
9 |
10 | it('returns undefined', () => {
11 | expect(pipe(O.None, O.toUndefined)).toEqual(undefined)
12 | expect(
13 | pipe(
14 | O.fromNullable({ prop: null }),
15 | O.mapNullable(obj => obj.prop),
16 | O.toUndefined,
17 | ),
18 | ).toEqual(undefined)
19 | })
20 |
21 | it('returns a value', () => {
22 | expect(pipe(O.Some('value'), O.toUndefined)).toEqual('value')
23 | expect(
24 | pipe(
25 | O.fromNullable({ prop: 'value' }),
26 | O.mapNullable(obj => obj.prop),
27 | O.toUndefined,
28 | ),
29 | ).toEqual('value')
30 | })
31 |
32 | it('*', () => {
33 | expect(
34 | pipe(
35 | O.fromNullable(['hello', 'world']),
36 | O.flatMap(A.takeExactly(2)),
37 | O.toUndefined,
38 | ),
39 | ).toEqual(['hello', 'world'])
40 | expect(
41 | pipe(O.fromNullable([]), O.flatMap(A.takeExactly(2)), O.toUndefined),
42 | ).toEqual(undefined)
43 | })
44 | })
45 |
--------------------------------------------------------------------------------
/tools/comment-ppx/esy.lock/opam/uchar.0.0.2/opam:
--------------------------------------------------------------------------------
1 | opam-version: "2.0"
2 | maintainer: "Daniel Bünzli "
3 | authors: ["Daniel Bünzli "]
4 | homepage: "http://ocaml.org"
5 | doc: "https://ocaml.github.io/uchar/"
6 | dev-repo: "git+https://github.com/ocaml/uchar.git"
7 | bug-reports: "https://github.com/ocaml/uchar/issues"
8 | tags: [ "text" "character" "unicode" "compatibility" "org:ocaml.org" ]
9 | license: "typeof OCaml system"
10 | depends: [
11 | "ocaml" {>= "3.12.0"}
12 | "ocamlbuild" {build}
13 | ]
14 | build: [
15 | ["ocaml" "pkg/git.ml"]
16 | [
17 | "ocaml"
18 | "pkg/build.ml"
19 | "native=%{ocaml:native}%"
20 | "native-dynlink=%{ocaml:native-dynlink}%"
21 | ]
22 | ]
23 | synopsis: "Compatibility library for OCaml's Uchar module"
24 | description: """
25 | The `uchar` package provides a compatibility library for the
26 | [`Uchar`][1] module introduced in OCaml 4.03.
27 |
28 | The `uchar` package is distributed under the license of the OCaml
29 | compiler. See [LICENSE](LICENSE) for details.
30 |
31 | [1]: http://caml.inria.fr/pub/docs/manual-ocaml/libref/Uchar.html"""
32 | url {
33 | src:
34 | "https://github.com/ocaml/uchar/releases/download/v0.0.2/uchar-0.0.2.tbz"
35 | checksum: "md5=c9ba2c738d264c420c642f7bb1cf4a36"
36 | }
37 |
--------------------------------------------------------------------------------
/tools/comment-ppx/esy.lock/opam/cppo.1.6.8/opam:
--------------------------------------------------------------------------------
1 | opam-version: "2.0"
2 | maintainer: "martin@mjambon.com"
3 | authors: "Martin Jambon"
4 | license: "BSD-3-Clause"
5 | homepage: "https://github.com/ocaml-community/cppo"
6 | doc: "https://ocaml-community.github.io/cppo/"
7 | bug-reports: "https://github.com/ocaml-community/cppo/issues"
8 | depends: [
9 | "ocaml" {>= "4.02.3"}
10 | "dune" {>= "1.0"}
11 | "base-unix"
12 | ]
13 | build: [
14 | ["dune" "subst"] {dev}
15 | ["dune" "build" "-p" name "-j" jobs]
16 | ["dune" "runtest" "-p" name "-j" jobs] {with-test}
17 | ]
18 | dev-repo: "git+https://github.com/ocaml-community/cppo.git"
19 | synopsis: "Code preprocessor like cpp for OCaml"
20 | description: """
21 | Cppo is an equivalent of the C preprocessor for OCaml programs.
22 | It allows the definition of simple macros and file inclusion.
23 |
24 | Cppo is:
25 |
26 | * more OCaml-friendly than cpp
27 | * easy to learn without consulting a manual
28 | * reasonably fast
29 | * simple to install and to maintain
30 | """
31 | url {
32 | src: "https://github.com/ocaml-community/cppo/archive/v1.6.8.tar.gz"
33 | checksum: [
34 | "md5=fed401197d86f9089e89f6cbdf1d660d"
35 | "sha512=069bbe0ef09c03b0dc4b5795f909c3ef872fe99c6f1e6704a0fa97594b1570b3579226ec67fe11d696ccc349a4585055bbaf07c65eff423aa45af28abf38c858"
36 | ]
37 | }
38 |
--------------------------------------------------------------------------------
/__tests__/Array/removeFirstBy.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { A, N, pipe } from '../..'
4 |
5 | const xs = [1, 2, 1, 3]
6 |
7 | describe('removeFirstBy', () => {
8 | it('provides correct types', () => {
9 | expectType>(A.removeFirstBy(xs, 1, (x, y) => x === y))
10 | })
11 |
12 | it('removes the first occurence of the given value', () => {
13 | expect(A.removeFirstBy(xs, 1, (x, y) => x === y)).toEqual([2, 1, 3])
14 | })
15 |
16 | it('*', () => {
17 | expect(A.removeFirstBy([1, 2, 1, 3, 4], 2, N.gt)).toEqual([1, 2, 1, 4])
18 | })
19 | })
20 |
21 | describe('removeFirstBy (pipe)', () => {
22 | it('provides correct types', () => {
23 | expectType>(
24 | pipe(
25 | xs,
26 | A.removeFirstBy(1, (x, y) => x === y),
27 | ),
28 | )
29 | })
30 |
31 | it('removes the first occurence of the given value', () => {
32 | expect(
33 | pipe(
34 | xs,
35 | A.removeFirstBy(1, (x, y) => x === y),
36 | ),
37 | ).toEqual([2, 1, 3])
38 | })
39 |
40 | it('*', () => {
41 | expect(
42 | pipe(
43 | ['hello', 'wrld', 'world'],
44 | A.removeFirstBy(4, (str, length) => str.length === length),
45 | ),
46 | ).toEqual(['hello', 'world'])
47 | })
48 | })
49 |
--------------------------------------------------------------------------------
/__tests__/Array/flip.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { A, D, pipe } from '../..'
4 |
5 | describe('flip', () => {
6 | it('provides correct types', () => {
7 | expectType(A.flip([1, 2]))
8 | })
9 |
10 | it('returns a new tuple with the reverse order of the elements', () => {
11 | expect(A.flip([1, 2])).toEqual([2, 1])
12 | })
13 |
14 | it('*', () => {
15 | expect(A.flip([1, 2])).toEqual([2, 1])
16 | })
17 | })
18 |
19 | describe('flip (pipe)', () => {
20 | it('provides correct types', () => {
21 | expectType(pipe(A.toTuple([1, 2]), A.flip))
22 |
23 | expectType>(
24 | pipe(
25 | { name: 'Joe', location: 'Warsaw' },
26 | D.toPairs,
27 | A.map(A.flip),
28 | D.fromPairs,
29 | ),
30 | )
31 | })
32 |
33 | it('returns a new tuple with the reverse order of the elements', () => {
34 | const result = pipe(A.toTuple([1, 2]), A.flip)
35 | expect(result).toEqual([2, 1])
36 | })
37 |
38 | it('*', () => {
39 | expect(
40 | pipe(
41 | { name: 'Joe', location: 'Warsaw' },
42 | D.toPairs,
43 | A.map(A.flip),
44 | D.fromPairs,
45 | ),
46 | ).toEqual({ Joe: 'name', Warsaw: 'location' })
47 | })
48 | })
49 |
--------------------------------------------------------------------------------
/__tests__/Option/fromExecution.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 | import { O } from '../..'
3 |
4 | const okJSON = `{"name": "John"}`
5 | const badJSON = `{name": John}`
6 |
7 | type User = {
8 | readonly name: string
9 | }
10 |
11 | const parseJSON =
12 | (value: string) =>
13 | () => {
14 | return JSON.parse(value) as T
15 | }
16 |
17 | describe('fromExecution', () => {
18 | it('provides correct types', () => {
19 | expectType>(O.fromExecution(parseJSON(okJSON)))
20 | })
21 |
22 | it('returns None', () => {
23 | expect(O.fromExecution(parseJSON(badJSON))).toEqual(O.None)
24 | })
25 |
26 | it('returns Some', () => {
27 | expect(O.fromExecution(parseJSON(okJSON))).toEqual(
28 | O.Some({
29 | name: 'John',
30 | }),
31 | )
32 | })
33 |
34 | it('*', () => {
35 | const { Some, None } = O
36 |
37 | expect(
38 | /*
39 | type User = { readonly name: string }
40 | const parseJSON = (value: string) => () => JSON.parse(value) as T
41 | const okJSON = `{"name": "John"}`
42 | const badJSON = `{name": John}`
43 | */
44 | O.fromExecution(parseJSON(okJSON)),
45 | ).toEqual(Some({ name: 'John' }))
46 |
47 | expect(O.fromExecution(parseJSON(badJSON))).toEqual(None)
48 | })
49 | })
50 |
--------------------------------------------------------------------------------
/scripts/generate.ts:
--------------------------------------------------------------------------------
1 | import { task, desc, option, setGlobalOptions } from 'foy'
2 |
3 | import * as globby from 'globby'
4 | import * as path from 'path'
5 |
6 | setGlobalOptions({
7 | strict: true,
8 | logCommand: false,
9 | loading: false,
10 | })
11 |
12 | type Options = {
13 | readonly rebuild: boolean
14 | }
15 | type TSCOptions = {
16 | readonly esm: boolean
17 | readonly cjs: boolean
18 | }
19 |
20 | const defaultEncoding = { encoding: 'utf8' } as const
21 |
22 | desc('Generate docs')
23 | option('-r, --rebuild', 'rebuild rescript files')
24 | task('docs', async ctx => {
25 | const files = await globby('src/**/index.ts')
26 | const ts = files.join(' ')
27 |
28 | ctx.fs.mkdirp('docs/api/generated')
29 |
30 | if (ctx.options.rebuild) {
31 | await ctx.exec('yarn transform typescript -r')
32 | }
33 |
34 | await ctx.exec(
35 | `node node_modules/.bin/jscodeshift --run-in-band --extensions=ts --parser=ts -t tools/generate-docs/index.ts ${ts}`,
36 | )
37 | })
38 |
39 | desc('Generate contributors in README.md')
40 | task('contributors', async ctx => {
41 | await ctx.exec('yarn all-contributors generate')
42 | })
43 |
44 | desc('Generate tsc')
45 | task('tsc', async ctx => {
46 | await ctx.exec(
47 | 'yarn tsc --outDir ./dist/types --project ./tsconfig.build.json',
48 | )
49 | })
50 |
--------------------------------------------------------------------------------
/tools/comment-ppx/esy.lock/opam/stdlib-shims.0.3.0/opam:
--------------------------------------------------------------------------------
1 | opam-version: "2.0"
2 | maintainer: "The stdlib-shims programmers"
3 | authors: "The stdlib-shims programmers"
4 | homepage: "https://github.com/ocaml/stdlib-shims"
5 | doc: "https://ocaml.github.io/stdlib-shims/"
6 | dev-repo: "git+https://github.com/ocaml/stdlib-shims.git"
7 | bug-reports: "https://github.com/ocaml/stdlib-shims/issues"
8 | tags: ["stdlib" "compatibility" "org:ocaml"]
9 | license: ["typeof OCaml system"]
10 | depends: [
11 | "dune"
12 | "ocaml" {>= "4.02.3"}
13 | ]
14 | build: [ "dune" "build" "-p" name "-j" jobs ]
15 | synopsis: "Backport some of the new stdlib features to older compiler"
16 | description: """
17 | Backport some of the new stdlib features to older compiler,
18 | such as the Stdlib module.
19 |
20 | This allows projects that require compatibility with older compiler to
21 | use these new features in their code.
22 | """
23 | x-commit-hash: "fb6815e5d745f07fd567c11671149de6ef2e74c8"
24 | url {
25 | src:
26 | "https://github.com/ocaml/stdlib-shims/releases/download/0.3.0/stdlib-shims-0.3.0.tbz"
27 | checksum: [
28 | "sha256=babf72d3917b86f707885f0c5528e36c63fccb698f4b46cf2bab5c7ccdd6d84a"
29 | "sha512=1151d7edc8923516e9a36995a3f8938d323aaade759ad349ed15d6d8501db61ffbe63277e97c4d86149cf371306ac23df0f581ec7e02611f58335126e1870980"
30 | ]
31 | }
32 |
--------------------------------------------------------------------------------
/docs/benchmarks/introduction.md:
--------------------------------------------------------------------------------
1 | ---
2 | id: introduction
3 | title: Introduction
4 | ---
5 |
6 | ### Competitors
7 |
8 | | Library | Version |
9 | |--|---------|
10 | | [ramda](https://github.com/ramda/ramda) | `v0.27.1` |
11 | | [rambda](https://github.com/selfrefactor/rambda) | `v6.9.0` |
12 | | [remeda](https://github.com/remeda/remeda) | `v0.0.32` |
13 | | [lodash/fp](https://github.com/lodash/lodash/wiki/FP-Guide) | `v4.17.21` |
14 | | [@mobily/ts-belt](https://github.com/mobily/ts-belt) | `v3.0.0` |
15 |
16 | ### How to run benchmarks?
17 |
18 | Clone the repo:
19 |
20 | ```bash
21 | git clone https://github.com/mobily/ts-belt.git
22 | ```
23 |
24 | Install all dependencies and build `ts-belt`:
25 |
26 | ```bash
27 | yarn
28 | yarn build dist -t
29 | ```
30 |
31 | Go to the `benchmarks` directory and install all dependencies as well:
32 |
33 | ```bash
34 | cd ./benchmarks
35 | yarn
36 | ```
37 |
38 | Then, run the following command in order to run benchmark suites:
39 |
40 | ```bash
41 | yarn start
42 | # or
43 | yarn generate # if you want to generate a markdown file
44 | ```
45 |
46 | :::info
47 |
48 | Both commands generate a new results file, which is saved in the `benchmarks/.results` directory. Don't hesitate to send the results file to me! 😊 (DM me on [Twitter](https://twitter.com/__marcin_) to get more details)
49 |
50 | :::
51 |
--------------------------------------------------------------------------------
/src/Bool/Bool.res:
--------------------------------------------------------------------------------
1 | open Externals
2 |
3 | let placeholder = () => Js.Undefined.empty
4 |
5 | %comment(
6 | "Folds a boolean value into a value of a different type, using a function for the `true` and `false` cases."
7 | )
8 | @gentype
9 | let ifElse = (value, truthyFn, falsyFn) => value ? truthyFn() : falsyFn()
10 |
11 | %comment("Negates the given boolean.")
12 | @gentype
13 | let inverse = value => !value
14 |
15 | %comment("Alias for `inverse`.")
16 | @gentype
17 | let not_ = value => !value
18 |
19 | %comment("Combines two booleans using `AND` → `a && b`.")
20 | @gentype
21 | let and_ = (a, b) => a && b
22 |
23 | %comment("Combines two booleans using `OR` → `a || b`.")
24 | @gentype
25 | let or_ = (a, b) => a || b
26 |
27 | %comment("Combines two booleans using `NAND` → `!(a && b)`.")
28 | @gentype
29 | let nand = (a, b) => !(a && b)
30 |
31 | %comment("Combines two booleans using `NOR` → `!(a || b)`.")
32 | @gentype
33 | let nor = (a, b) => !(a || b)
34 |
35 | %comment("Combines two booleans using `XOR` → `(!a && b) || (a && !b)`.")
36 | @gentype
37 | let xor = (a, b) => (!a && b) || (a && !b)
38 |
39 | %comment("Combines two booleans using `XNOR` → `!xor(a, b)`.")
40 | @gentype
41 | let xnor = (a, b) => !xor(a, b)
42 |
43 | %comment("Combines two booleans using an implication (`!a || b`).")
44 | @gentype
45 | let implies = (a, b) => !a || b
46 |
--------------------------------------------------------------------------------
/__tests__/Result/mapWithDefault.test.ts:
--------------------------------------------------------------------------------
1 | import { pipe, R } from '../..'
2 |
3 | describe('mapWithDefault', () => {
4 | it('returns a default value', () => {
5 | expect(
6 | pipe(
7 | R.fromNullable(null, 'this is bad'),
8 | R.mapWithDefault('default value', _ => 'value'),
9 | ),
10 | ).toEqual('default value')
11 | })
12 |
13 | it('should skip a default value', () => {
14 | expect(
15 | pipe(
16 | R.fromNullable('hello', 'this is bad'),
17 | R.mapWithDefault('default', str => {
18 | return `${str} world`
19 | }),
20 | ),
21 | ).toEqual('hello world')
22 | })
23 |
24 | it('*', () => {
25 | let name: string | null = 'Joe'
26 |
27 | expect(
28 | // type Name = string | null
29 | pipe(
30 | // ⬇️ const name: Name = 'Joe'
31 | R.fromNullable(name, 'cannot be nullable'),
32 | R.mapWithDefault('Hello, stranger!', name => `Hello, ${name}!`),
33 | ),
34 | ).toEqual('Hello, Joe!')
35 |
36 | name = null as unknown as string | null
37 |
38 | expect(
39 | pipe(
40 | // ⬇️ const name: Name = null
41 | R.fromNullable(name, 'cannot be nullable'),
42 | R.mapWithDefault('Hello, stranger!', name => `Hello, ${name}!`),
43 | ),
44 | ).toEqual('Hello, stranger!')
45 | })
46 | })
47 |
--------------------------------------------------------------------------------
/__tests__/Array/make.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { A, pipe } from '../..'
4 |
5 | describe('make', () => {
6 | it('provides correct types', () => {
7 | expectType>(A.make(3, 3))
8 | expectType>(A.make(3, 'hello'))
9 | })
10 |
11 | it('creates an empty array', () => {
12 | const result = A.make(-1, 'hello')
13 | expect(result).toEqual([])
14 | })
15 |
16 | it('creates a new array of size `n`', () => {
17 | const result = A.make(3, 1)
18 | expect(result).toEqual([1, 1, 1])
19 | })
20 |
21 | it('*', () => {
22 | expect(A.make(-1, 'hello')).toEqual([])
23 | expect(A.make(3, 1)).toEqual([1, 1, 1])
24 | })
25 | })
26 |
27 | describe('make (pipe)', () => {
28 | it('provides correct types', () => {
29 | expectType>(pipe(2, A.make('hello')))
30 | expectType>(pipe(2, A.make(5)))
31 | })
32 |
33 | it('creates an empty array', () => {
34 | const result = pipe(-1, A.make('hello'))
35 | expect(result).toEqual([])
36 | })
37 |
38 | it('creates a new array of size `n`', () => {
39 | const result = pipe(3, A.make(1))
40 | expect(result).toEqual([1, 1, 1])
41 | })
42 |
43 | it('*', () => {
44 | expect(pipe(2, A.make('hello'))).toEqual(['hello', 'hello'])
45 | })
46 | })
47 |
--------------------------------------------------------------------------------
/__tests__/Guards/isNot.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { G, F, pipe } from '../..'
4 |
5 | const isNotString = G.isNot(G.isString)
6 |
7 | describe('isNot', () => {
8 | it('provides correct types', () => {
9 | const x = Promise.resolve(0)
10 |
11 | if (isNotString(x)) {
12 | expectType>(x)
13 | }
14 |
15 | const y = '' as unknown as string | number
16 |
17 | if (isNotString(y)) {
18 | expectType(y)
19 | }
20 | })
21 |
22 | it('determines whether the provided value is not string', () => {
23 | expect(isNotString([1, 2, 3])).toEqual(true)
24 | expect(isNotString('hello')).toEqual(false)
25 | expect(isNotString({})).toEqual(true)
26 | expect(isNotString(0)).toEqual(true)
27 | expect(isNotString(false)).toEqual(true)
28 | expect(isNotString(F.ignore)).toEqual(true)
29 | expect(isNotString(Promise.resolve(1))).toEqual(true)
30 | expect(isNotString(new Date())).toEqual(true)
31 | expect(isNotString(new Error('oops'))).toEqual(true)
32 | })
33 |
34 | it('*', () => {
35 | expect(
36 | // ⬇️ const isNotString = G.isNot(G.isString)
37 | isNotString(0),
38 | ).toEqual(true)
39 | })
40 | })
41 |
42 | describe('isNot (pipe)', () => {
43 | it('*', () => {
44 | expect(pipe('ts-belt', G.isNot(G.isString))).toEqual(false)
45 | })
46 | })
47 |
--------------------------------------------------------------------------------
/tools/comment-ppx/esy.lock/opam/ocaml-compiler-libs.v0.12.4/opam:
--------------------------------------------------------------------------------
1 | opam-version: "2.0"
2 | synopsis: "OCaml compiler libraries repackaged"
3 | description: """
4 | This packages exposes the OCaml compiler libraries repackages under
5 | the toplevel names Ocaml_common, Ocaml_bytecomp, Ocaml_optcomp, ..."""
6 | maintainer: ["Jane Street developers"]
7 | authors: ["Jane Street Group, LLC"]
8 | license: "MIT"
9 | homepage: "https://github.com/janestreet/ocaml-compiler-libs"
10 | bug-reports: "https://github.com/janestreet/ocaml-compiler-libs/issues"
11 | depends: [
12 | "dune" {>= "2.8"}
13 | "ocaml" {>= "4.04.1"}
14 | "odoc" {with-doc}
15 | ]
16 | build: [
17 | ["dune" "subst"] {dev}
18 | [
19 | "dune"
20 | "build"
21 | "-p"
22 | name
23 | "-j"
24 | jobs
25 | "@install"
26 | "@runtest" {with-test}
27 | "@doc" {with-doc}
28 | ]
29 | ]
30 | dev-repo: "git+https://github.com/janestreet/ocaml-compiler-libs.git"
31 | url {
32 | src:
33 | "https://github.com/janestreet/ocaml-compiler-libs/releases/download/v0.12.4/ocaml-compiler-libs-v0.12.4.tbz"
34 | checksum: [
35 | "sha256=4ec9c9ec35cc45c18c7a143761154ef1d7663036a29297f80381f47981a07760"
36 | "sha512=978dba8dfa61f98fa24fda7a9c26c2e837081f37d1685fe636dc19cfc3278a940cf01a10293504b185c406706bc1008bc54313d50f023bcdea6d5ac6c0788b35"
37 | ]
38 | }
39 | x-commit-hash: "8cd12f18bb7171c2b67d661868c4271fae528d93"
40 |
--------------------------------------------------------------------------------
/__tests__/Option/fromNullable.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 | import { O } from '../..'
3 |
4 | describe('fromNullable', () => {
5 | it('provides correct types', () => {
6 | const value = null as unknown as string | null
7 |
8 | expectType>(O.fromNullable(value))
9 | expectType>(O.fromNullable(null))
10 | })
11 |
12 | it('returns None', () => {
13 | expect(O.fromNullable(null)).toEqual(O.None)
14 | expect(O.fromNullable(undefined)).toEqual(O.None)
15 | })
16 |
17 | it('returns Some', () => {
18 | expect(O.fromNullable('value')).toEqual(O.Some('value'))
19 | expect(O.fromNullable([])).toEqual(O.Some([]))
20 | expect(O.fromNullable({})).toEqual(O.Some({}))
21 | expect(O.fromNullable(0)).toEqual(O.Some(0))
22 | expect(O.fromNullable(1)).toEqual(O.Some(1))
23 | expect(O.fromNullable(false)).toEqual(O.Some(false))
24 | expect(O.fromNullable(true)).toEqual(O.Some(true))
25 | })
26 |
27 | it('*', () => {
28 | const { Some, None } = O
29 |
30 | expect(O.fromNullable(1)).toEqual(Some(1))
31 | expect(O.fromNullable('hello world')).toEqual(Some('hello world'))
32 | expect(O.fromNullable([])).toEqual(Some([]))
33 | expect(O.fromNullable(false)).toEqual(Some(false))
34 | expect(O.fromNullable(null)).toEqual(None)
35 | expect(O.fromNullable(undefined)).toEqual(None)
36 | })
37 | })
38 |
--------------------------------------------------------------------------------
/__tests__/String/lastIndexOf.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { S, A, O, pipe } from '../..'
4 |
5 | describe('lastIndexOf', () => {
6 | it('provides correct types', () => {
7 | expectType>(S.lastIndexOf('hello', 'l'))
8 | expectType>(
9 | A.keepMap(['hello', 'world'], S.lastIndexOf('o')),
10 | )
11 | })
12 |
13 | it('returns an index correctly', () => {
14 | expect(S.lastIndexOf('hello', 'l')).toEqual(O.Some(3))
15 | expect(S.lastIndexOf('world', 'x')).toEqual(O.None)
16 | })
17 |
18 | it('*', () => {
19 | const { Some, None } = O
20 | expect(S.lastIndexOf('ts,rescript', 's')).toEqual(Some(5))
21 | expect(S.lastIndexOf('ts,rescript', 'x')).toEqual(None)
22 | })
23 | })
24 |
25 | describe('lastIndexOf (pipe)', () => {
26 | it('provides correct types', () => {
27 | expectType>(pipe('hello', S.lastIndexOf('l')))
28 | expectType>>(
29 | pipe(['hello', 'world'], A.map(S.lastIndexOf('l'))),
30 | )
31 | })
32 |
33 | it('returns an index correctly', () => {
34 | expect(pipe('hello', S.lastIndexOf('-'))).toEqual(O.None)
35 | expect(pipe('wooorld', S.lastIndexOf('o'))).toEqual(O.Some(3))
36 | })
37 |
38 | it('*', () => {
39 | expect(pipe(['hello', 'ts'], A.keepMap(S.lastIndexOf('l')))).toEqual([3])
40 | })
41 | })
42 |
--------------------------------------------------------------------------------
/__tests__/Dict/keys.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { D, pipe } from '../..'
4 |
5 | type T = {
6 | readonly name: string
7 | readonly age: number
8 | }
9 |
10 | const user: T = {
11 | name: 'Joe',
12 | age: 20,
13 | }
14 |
15 | describe('keys', () => {
16 | it('provides correct types', () => {
17 | expectType>(D.keys(user))
18 | expectType>(D.keys(user))
19 | })
20 |
21 | it('returns a new array that contains all keys of the provided object', () => {
22 | expect(D.keys(user)).toEqual(['name', 'age'])
23 | })
24 |
25 | it('*', () => {
26 | expect(
27 | D.keys({
28 | name: 'Joe',
29 | age: 20,
30 | }),
31 | ).toEqual(['name', 'age'])
32 | })
33 | })
34 |
35 | describe('keys (pipe)', () => {
36 | it('provides correct types', () => {
37 | expectType>(pipe(user, D.keys))
38 | expectType>(pipe(user, D.keys))
39 | })
40 |
41 | it('returns a new array that contains all keys of the provided object', () => {
42 | expect(pipe(user, D.keys)).toEqual(['name', 'age'])
43 | })
44 |
45 | it('*', () => {
46 | expect(
47 | pipe(
48 | {
49 | name: 'Joe',
50 | age: 20,
51 | },
52 | D.keys,
53 | ),
54 | ).toEqual(['name', 'age'])
55 | })
56 | })
57 |
--------------------------------------------------------------------------------
/__tests__/Function/after.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { F, N, O } from '../..'
4 |
5 | const fn = (n: number) => {
6 | return `called ${n} times`
7 | }
8 |
9 | const fn2 = (n: number, x: string) => {
10 | return `called ${n} times with ${x}`
11 | }
12 |
13 | describe('after', () => {
14 | it('provides correct types', () => {
15 | expectType<(n: number) => O.Option>(F.after(2, fn))
16 | expectType<(n: number, x: string) => string>(F.after(2, fn2))
17 | expectType<(n: number) => O.Option>(F.after(2, N.add(2)))
18 | })
19 |
20 | it('handles multiple parameters', function () {
21 | let calls = 0
22 |
23 | const addTwoNumbers = (x: number, y: number) => {
24 | calls = calls + 1
25 | return x + y
26 | }
27 | const add = F.after(2, addTwoNumbers)
28 |
29 | expect(add(2, 2)).toEqual(O.None)
30 | expect(add(4, 4)).toEqual(O.None)
31 | expect(add(8, 8)).toEqual(O.Some(16))
32 | expect(add(8, 16)).toEqual(O.Some(24))
33 | expect(calls).toEqual(2)
34 | })
35 |
36 | it('*', () => {
37 | const { Some, None } = O
38 | const addTwo = F.after(2, N.add(2))
39 |
40 | expect(
41 | /*
42 | const addTwo = F.after(2, N.add(2))
43 | */
44 | addTwo(4),
45 | ).toEqual(None)
46 | expect(addTwo(8)).toEqual(None)
47 | expect(addTwo(16)).toEqual(Some(18))
48 | })
49 | })
50 |
--------------------------------------------------------------------------------
/__tests__/Dict/isEmpty.test.ts:
--------------------------------------------------------------------------------
1 | import { expectType } from 'ts-expect'
2 |
3 | import { D, pipe } from '../..'
4 |
5 | type T = {
6 | readonly name: string
7 | readonly age: number
8 | }
9 |
10 | const user: T = {
11 | name: 'Joe',
12 | age: 20,
13 | }
14 |
15 | describe('isEmpty', () => {
16 | it('provides correct types', () => {
17 | expectType(D.isEmpty(user))
18 | expectType(D.isEmpty({}))
19 | })
20 |
21 | it('determines whether the given object is empty', () => {
22 | expect(D.isEmpty(user)).toEqual(false)
23 | expect(D.isEmpty({})).toEqual(true)
24 | })
25 |
26 | it('*', () => {
27 | expect(D.isEmpty({ name: 'Joe', age: 20 })).toEqual(false)
28 | expect(D.isEmpty({})).toEqual(true)
29 | })
30 | })
31 |
32 | describe('isEmpty (pipe)', () => {
33 | it('provides correct types', () => {
34 | expectType(pipe(user, D.isEmpty))
35 | expectType