open-index/open-npm huggingface dataset:
npm package: @just-web/preferences
Description: just-web user preferences plugin module
Author: Homa Wong
Latest version: 7.3.3

# @just-web/preferences

[![NPM version][npm-image]][npm-url]
[![NPM downloads][downloads-image]][downloads-url]

[@just-web/preferences] plugin defines the interface of get and set user preferences.

Where the preferences are saved depends on how it is implemented in the details.

This package provides a `memoryPreferencesGizmo` that stores preferences in memory.
But in practice, most likely you should use a different implementation such as:

- [@just-web/browser-preferences]: Save preference in browser local storage.
- 🚧 `@just-web/service-preferences`: Save preference in a remote service.

## Install

```sh
# npm
npm install @just-web/preferences

# yarn
yarn add @just-web/preferences

# pnpm
pnpm install @just-web/preferences

#rush
rush add -p @just-web/preferences
```

## Usage

Here is how to use `memoryPreferencesGizmo`:

```ts
import { justApp } from '@just-web/app'
import { commandsGizmoFn } from '@just-web/commands'
import { keyboardGizmoFn } from '@just-web/keyboard' // optional
import { memoryPreferencesGizmo } from '@just-web/preferences'

const app = await justApp({ name: 'your-app' })
  .with(commandsGizmoFn())
  .with(keyboardGizmoFn())
  .with(memoryPreferencesGizmo)
  .create()
```

[@just-web/preferences]: https://github.com/justland/just-web/tree/main/plugins/preferences
[@just-web/browser-preferences]: https://github.com/justland/just-web/tree/main/plugins/browser-preferences
[downloads-image]: https://img.shields.io/npm/dm/@just-web/preferences.svg?style=flat
[downloads-url]: https://npmjs.org/package/@just-web/preferences
[npm-image]: https://img.shields.io/npm/v/@just-web/preferences.svg?style=flat
[npm-url]: https://npmjs.org/package/@just-web/preferences
npm package: @just-web/presets-browser
Description: just-web presets for browser related features
Author: Homa Wong
Latest version: 8.0.2

# @just-web/presets-browser

[![NPM version][npm-image]][npm-url]
[![NPM downloads][downloads-image]][downloads-url]

[`@just-web/presets-browser`] provides common browser features using specific set of libraries.

This presets includes:

- [@just-web/browser](https://www.npmjs.com/package/@just-web/browser)
- [@just-web/browser-preferences](https://www.npmjs.com/package/@just-web/browser-preferences)
- [@just-web/history](https://www.npmjs.com/package/@just-web/history)

As a presets, you do not need to install any of the included packages yourself.

This presets depends on:

- [@just-web/commands](https://www.npmjs.com/package/@just-web/commands)
- [@just-web/keyboard](https://www.npmjs.com/package/@just-web/keyboard) (Optional)

## Install

```sh
# npm
npm install @just-web/presets-browser

# yarn
yarn add @just-web/presets-browser

# pnpm
pnpm install @just-web/presets-browser

#rush
rush add -p @just-web/presets-browser
```

## Usage

```ts
import { justApp } from '@just-web/app'
import { commandsGizmoFn } from '@just-web/commands'
import { keyboardGizmoFn } from '@just-web/keyboard' // optional
import { presetsBrowserGizmoFn } from '@just-web/presets-browser'

const app = await justApp({ name: 'your-awesome-app' })
  .with(commandsGizmoFn())
  .with(keyboardGizmoFn())
  .with(presetsBrowserGizmoFn())
  .create()
```

[`@just-web/presets-browser`]: https://github.com/justland/just-web/tree/main/plugins/presets-browser
[downloads-image]: https://img.shields.io/npm/dm/@just-web/presets-browser.svg?style=flat
[downloads-url]: https://npmjs.org/package/@just-web/presets-browser
[npm-image]: https://img.shields.io/npm/v/@just-web/presets-browser.svg?style=flat
[npm-url]: https://npmjs.org/package/@just-web/presets-browser
npm package: @just-web/react-commands
Description: @just-web/commands UI components in react
Author: Homa Wong
Latest version: 9.0.4

# @just-web/command-react <!-- omit in toc -->

[![NPM version][npm-image]][npm-url]
[![NPM downloads][downloads-image]][downloads-url]

[@just-web/react-commands] provides the components for [@just-web/commands] written in [React].

## Install <!-- omit in toc -->

```sh
# npm
npm install @just-web/react-commands

# yarn
yarn add @just-web/react-commands

# pnpm
pnpm install @just-web/react-commands

#rush
rush add -p @just-web/react-commands
```

## Usage <!-- omit in toc -->

You can load the plugin synchronously or asynchronously.
Here is an example to load it synchronously:

Note that currently there are no init work done in this plugin.
Meaning it can be converted to a library instead of a plugin.
The `extend()` call below is not needed.

```ts
import { createApp } from '@just-web/app'
import * as reactCommandModule from '@just-web/react-commands'

void (async () => {
  const app = await createApp({ name: 'my-app' })
    .extend(reactCommandModule)
  await app.start()
})()
```

## Features <!-- omit in toc -->

- [CommandPalette](#commandpalette)

## CommandPalette

```tsx
import { CommandPalette } from '@just-web/react-commands'

const Comp = () => <>
  <CommandPalette>
</>
```

[@just-web/commands]: https://github.com/justland/just-web/tree/main/plugins/commands
[@just-web/react-commands]: https://github.com/justland/just-web/tree/main/components/react-commands
[React]: https://reactjs.org/
[downloads-image]: https://img.shields.io/npm/dm/@just-web/react-commands.svg?style=flat
[downloads-url]: https://npmjs.org/package/@just-web/react-commands
[npm-image]: https://img.shields.io/npm/v/@just-web/react-commands.svg?style=flat
[npm-url]: https://npmjs.org/package/@just-web/react-commands
npm package: @just-web/react-intl
Description: react-intl gizmo for just-web applications
Author: Homa Wong
Latest version: 1.1.1

# @just-web/react-intl

[![NPM version][npm-image]][npm-url]
[![NPM downloads][downloads-image]][downloads-url]

[@just-web/react-intl] provides [react-intl] support for [@just-web] applications.

It re-exports [react-intl] so that you can access all functionality of [react-intl] directly.

## Install

[@just-web/react-intl] needs [@just-web/react](../react/README.md)

```sh
# npm
npm install @just-web/react-intl @just-web/react

# yarn
yarn add @just-web/react-intl @just-web/react

# pnpm
pnpm install @just-web/react-intl @just-web/react

#rush
rush add -p @just-web/react-intl @just-web/react
```

## Usage

```tsx
import { justApp } from '@just-web/app'
import { reactGizmo } from '@just-web/react'
import { reactIntlGizmoFn } from '@just-web/react-intl'

const app = await justApp({ name: 'your-awesome-app' })
  .with(reactGizmo)
  .with(reactIntlGizmoFn({ config: { locale: 'en', messages: {} } }))
  .create()

app.react_intl.intl.formatMessage({ defaultMessage: 'hello world' })

function App() {
  <JustAppProvider app={app}><Component/></JustAppProvider>
}

function Component() {
  const intl = useIntl()
  // or
  // const app = useJustAppContext()
  // const intl = app.react_intl.intl

  return <div>{intl.formatMessage({ defaultMessage: 'hello world' })}</div>
}
```

[@just-web]: https://github.com/justland/just-web
[@just-web/react-intl]: https://github.com/justland/just-web/tree/main/plugins/react-intl
[downloads-image]: https://img.shields.io/npm/dm/@just-web/react-intl.svg?style=flat
[downloads-url]: https://npmjs.org/package/@just-web/react-intl
[npm-image]: https://img.shields.io/npm/v/@just-web/react-intl.svg?style=flat
[npm-url]: https://npmjs.org/package/@just-web/react-intl
[react-intl]: https://formatjs.io/
npm package: @just-web/repo-scripts
Description: just-web shared repository config and scripts
Author: Homa Wong
Latest version: 0.3.1

# @just-web/repo-scripts

[![NPM version][npm-image]][npm-url]
[![NPM downloads][downloads-image]][downloads-url]

Shared config and scripts for [@just-web] application.

## Install

```sh
# npm
npm install -D @just-web/repo-scripts

# yarn
yarn add -D @just-web/repo-scripts

# pnpm
pnpm install -D @just-web/repo-scripts

#rush
rush add -p --dev @just-web/repo-scripts
```

[@just-web]: https://github.com/justland/just-web
[downloads-image]: https://img.shields.io/npm/dm/@just-web/repo-scripts.svg?style=flat
[downloads-url]: https://npmjs.org/package/@just-web/repo-scripts
[npm-image]: https://img.shields.io/npm/v/@just-web/repo-scripts.svg?style=flat
[npm-url]: https://npmjs.org/package/@just-web/repo-scripts
npm package: @just-web/routes
Description: just-web routes library
Author: Homa Wong
Latest version: 7.2.3

# @just-web/routes

[![NPM version][npm-image]][npm-url]
[![NPM downloads][downloads-image]][downloads-url]

[@just-web/routes] is a plugin that provides client side routing capability.

NOTE: This plugin is still in development and is not ready for production use.

## Features

- routing
- history

## Install

```sh
# npm
npm install @just-web/routes

# yarn
yarn add @just-web/routes

# pnpm
pnpm install @just-web/routes

#rush
rush add -p @just-web/routes
```

## Basic usage

Since routing is a basic functionality of an application,
you typically will load it statically:

```ts
import { createApp } from '@just-web/app'
import routesPlugin from '@just-web/routes'

void (async () => {
  const app = await createApp({ name: 'my-awesome-app' })
    .extend(routesPlugin())

  app.routes.register('/', () => { ... })
  app.routes.register('/error', () => { ... })
  await app.start()
})()

```

[@just-web/routes]: https://github.com/justland/just-web/tree/main/plugins/routes
[downloads-image]: https://img.shields.io/npm/dm/@just-web/routes.svg?style=flat
[downloads-url]: https://npmjs.org/package/@just-web/routes
[npm-image]: https://img.shields.io/npm/v/@just-web/routes.svg?style=flat
[npm-url]: https://npmjs.org/package/@just-web/routes
npm package: @just-web/toolkits
Description: Toolkits for web applications
Author: Unional
Latest version: 3.3.0

# @just-web/toolkits

[@just-web/toolkits][@just-web/toolkits] is a toolkit for working with web technologies.

## Install

```sh
npm install @just-web/toolkits

yarn add @just-web/toolkits

pnpm add @just-web/toolkits
```

[@just-web/toolkits]: https://github.com/justland/just-web-foundation/tree/main/libs/toolkits
npm package: @just-web/types
Description: Common types for web applications
Author: Unional
Latest version: 0.2.2

# @just-web/types

[@just-web/types][@just-web/types] provides common types for web applications.

## Install

```sh
npm install @just-web/types

yarn add @just-web/types

pnpm add @just-web/types
```

[@just-web/types]: https://github.com/justland/just-web-foundation/tree/main/libs/types
npm package: @just1arale/icons
Description: SVG-Icons as components for my projects
Author: Susanne Küchler aka just1arale
Latest version: 1.0.5

# Icon-Library

React SVG icons (for my projects). Supports custom color and size.

## Install package

```bash
$ npm i @just1arale/icons
```

## Import components

```js
// example
import { ArrowRight } from "@just1arale/icons";

<ArrowRight width="24" height="24" color="#B6D2CE">
```

## Icons Overview

Please check the [closed issue - all SVGs](https://github.com/justArale/icon-library/commit/9a68816)
for an overview of all icons
npm package: @just4/ajax
Description: Just for making XMLHTTPRequest easier to use in browser.
Author: Mr.Luo
Latest version: 1.1.0
Deprecated: Package no longer supported. Please use @just4/request instead.

# @just4/ajax

提供基于 XMLHTTPRequest 的 AJAX 请求接口。

注意，本程序包只能在浏览器环境下运行，如果要兼容微信小程序，请移步 [@just4/request](https://www.npmjs.com/package/@just4/request)。

## 特性

- 封装了 XMLHTTPRequest 对象创建、请求发起、请求响应的全流程，并支持取消请求。
- 支持常用的请求方式：get、post、put、delete 和 patch。
- 支持发送常用的数据类型：文本、对象、FormData、Blob 和 ArrayBuffer。
- 支持把数据序列化为 `application/json` 或 `application/x-www-form-urlencoded` 的请求体。
- 根据选项设置把响应内容解析为 JSON、XML、文本、Blob 或 ArrayBuffer。
- 支持文件上传和下载场景下的进度响应（`onDownloadProgress`、`onUploadProgress`）。
- 具备 Promise 化的接口。
- 带有 TypeScript 类型声明。
- 支持 PC 和移动端所有主流浏览器（其中 IE 浏览器的最低兼容版本是 9）。
  - 在 IE 9 中，符合特定条件的情况下，通过 XDomainRequest 发起跨域请求。

## 安装

```bash
npm i @just4/ajax
```

## 调用

安装完毕之后，就可以引入并调用相关的方法：

```typescript
import { send, cancel } from '@just4/ajax/ajax';

const res = await send(url, {
  // 选项说明见下文和 API 文档
});

res.data; // data 是响应的数据
res.xhr; // xhr 是发送请求的 XMLHttpRequest 对象
res.options; // options 是发送请求的选项
```

### GET 请求

```typescript
// 以下两种调用方法，发送的请求是一样的
await send('/detail?id=12345');
await send('/detail', {
  params: { id: '12345' }
});
```

### POST 请求

把 `method` 选项的值设为 `post`，就可以发送 POST 请求。

```typescript
await send('/login', {
  method: 'post',
  data: {
    username: 'user',
    password: 'qwer123'
  }
});
```

如果 POST 请求的部分数据是以 URL 参数的形式传输，仍然可以放到 `params` 选项中：

```typescript
await send('/login', {
  method: 'post',
  params: {
    from: 'promotion'
  },
  data: {
    username: 'user',
    password: 'qwer123'
  }
});
```

默认情况下，POST 请求的数据是以 `application/x-www-form-urlencoded` 编码发送的。如果需要发送 `application/json` 编码的数据，可以把 `requestType` 设置为 `json`。

```typescript
await send('/login', {
  method: 'post',
  requestType: 'json',
  params: {
    from: 'promotion'
  },
  data: {
    username: 'user',
    password: 'qwer123'
  }
});
```

### 防止缓存

设置 `preventCaching` 选项为 `true` 后，`send` 方法会在请求的 URL 后拼接时间戳参数（任何请求方式都有效）。

```typescript
// 实际请求的地址类似于 /detail?id=12345&_=1672712809951
await send('/detail', {
  params: { id: '12345' },
  preventCaching: true
});
```

### 请求超时

可以通过 `timeout` 指定请求的超时时间（毫秒）。如果请求超时，将会返回拒绝状态的 promise 实例。

```typescript
try {
  await send('/login', {
    method: 'post',
    data: {
      username: 'user',
      password: 'qwer123'
    },
    timeout: 8000
  });
} catch (e) {
  if (e.isTimeout) {
    // 请求超时
  }
}
```

### 取消请求

先通过 `receiveCancelId` 把请求的 id 记录下来，通过 `cancel` 方法取消请求。如果请求在完成前被取消，将会返回拒绝状态的 promise 实例。

```typescript
let requestId = 0;

setTimeout(() => {
  cancel(id);
}, 5000);

try {
  await send('/login', {
    method: 'post',
    data: {
      username: 'user',
      password: 'qwer123'
    },
    receiveCancelId(id) {
      requestId = id;
    }
  });
} catch (e) {
  if (e.isCancel) {
    // 请求被取消
  }
}
```

## API 文档

- [API 文档](https://heeroluo.github.io/just4/ajax/index.html)

## Changelog

### v1.1.0

- 升级依赖包版本并对应调整相关 API 的调用。
npm package: @just4/cookie
Description: Just for cookie manipulation in browser.
Author: Mr.Luo
Latest version: 2.1.0

# @just4/cookie

提供浏览器端的 cookie 操作接口。

## 特性

- 提供了浏览器端 cookie 读取、写入以及删除的接口。
- 写入 cookie 时，支持设置有效时间、主机名、路径、Secure、SameSite 等属性。

## 安装

```bash
npm i @just4/cookie
```

## 调用

安装完毕之后，就可以引入并调用相关的方法：

```javascript
import {
  getCookie,
  setCookie,
  removeCookie
} from '@just4/cookie';
```

### 读取 cookie

```javascript
getCookie('nickname');
```

默认情况下，读取 cookie 时分别是用 `encodeURIComponent` 和 `decodeURIComponent` 进行编码和解码的。如果要用其他编解码函数，可以通过 `encode` 和 `decode` 选项指定。

```javascript
getCookie('nickname', {
  encode(content) {
    //...
  },
  decode(content) {
    //...
  }
});
```

### 写入 cookie

最简单的 cookie 写入只需指定 key 和 value 的值。

```javascript
setCookie('nickname', 'Tom');
```

但 Cookie 还有多个属性（见 MDN 的《[Set-Cookie](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Set-Cookie)》文档），除了 HttpOnly 以外，其他均可在浏览器端进行设置。可通过 `setCookie` 函数的选项参数对 cookie 的属性进行设置。

#### 有效时间

有效时间有**绝对时间**和**相对时间**两种形式：

- 使用绝对时间时，要传入对应时间点的日期对象。
- 使用相对时间时，传入“数量 单位”格式的字符串，其中单位可以为单数也可以为复数。

```javascript
// 相对时间
setCookie('nickname', 'Tom', {
  expires: '1 month'  // 有效时间为一个月
});
```

```javascript
// 相对时间
setCookie('nickname', 'Tom', {
  expires: '2 years'  // 有效时间为两年
});
```

```javascript
// 绝对时间
setCookie('nickname', 'Tom', {
  expires: new Date(2023, 0, 1)  // 2023 年 1 月 1 日 0 点过期
});
```

#### 主机名和路径

```javascript
setCookie('nickname', 'Tom', {
  domain: '.abc.com',
  path: '/'
});
```

#### 仅在 https 请求中可用

```javascript
setCookie('nickname', 'Tom', {
  secure: true
});
```

#### SameSite

关于 SameSite 的说明可以参阅 MDN 的《[SameSite cookies](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Set-Cookie/SameSite)》。

```javascript
setCookie('nickname', 'Tom', {
  sameSite: 'strict'
});
```

```javascript
// SameSite 设为 none 时需要同时设置 Secure
setCookie('nickname', 'Tom', {
  sameSite: 'none',
  secure: true
});
```

#### 指定内容编码

默认情况下，写入 cookie 时是用 `encodeURIComponent` 进行编码的。如果要用其他编码函数，可以通过 `encode` 选项指定。

```javascript
setCookie('nickname', '汤姆', {
  encode(content) {
    //...
  }
});
```

### 删除 cookie

```javascript
removeCookie('nickname');
```

删除 cookie 实质上是把 cookie 设为过期，因此 `removeCookie` 支持 `setCookie` 的所有选项。

## 相关文档

- [API 文档](https://heeroluo.github.io/just4/cookie/modules/index.html)

## Changelog

### v2.1.0

- 获取 cookie 时，区分无 cookie 和 cookie 值为空字符串这两种情况。

### v2.0.0

- 设置 cookie 有效时间时，对相对时间的处理修改为通过 [@just4/util](https://www.npmjs.com/package/@just4/util) 中的 `addRelativeTime` 实现，因此：
  - 不再支持小数的数量（例如 `0.5 month`）。因为单位不一定是常量（例如一个月的总天数可能是 28、29、30、31），数量为小数时，表达的意思不明确。
  - 计算方式的变化。
    - 在 1.x 版本中，1 个月按 30 天算。如果有效时间为 1 个月，就是在当前时间的 30 天后过期；自本版本开始，变更为在下个月同一天同样的时间点过期。
    - 在 1.x 版本中，1 年按 365 天算。如果有效时间为 1 年，就是在当前时间的 365 天后过期；自本版本开始，变更为在下一年同一天同样的时间点过期。
npm package: @just4/dom
Description: Just for making dom manipulation much more easier in browser.
Author: Mr.Luo
Latest version: 1.0.0

# @just4/dom

提供 DOM 操作接口。

## 特性

- 包含常用的 DOM 操作接口，整体用法与 jQuery 相似，是 jQuery 功能的子集。
- 元素匹配通过浏览器原生的 querySelectorAll、matchesSelector 接口实现，避免引入庞大的 Sizzle 引擎。
- 支持 PC 和移动端所有主流浏览器（其中 IE 浏览器的最低兼容版本是 9）。

## 相关文档

- [API 文档](https://heeroluo.github.io/just4/dom/index.html)

## Changelog

### v1.0.0

- 发布正式版本。
npm package: @just4/load-script
Description: Just for script loading in browser.
Author: Mr.Luo
Latest version: 1.2.0

# @just4/load-script

提供动态加载脚本的相关接口。

## 安装

```bash
npm i @just4/load-script
```

## 调用

安装完毕之后，就可以引入并调用相关的方法：

```javascript
import {
  loadScript,
  jsonp
} from '@just4/load-script';
```

### 动态加载脚本文件

加载外部脚本文件，并获取其写入的全局对象：

```javascript
import { loadScript } from '@just4/load-script';
await loadScript('https://code.jquery.com/jquery-1.12.4.min.js');
const $ = window.jQuery;
```

### JSONP 请求

JSONP 本质上是通过动态加载脚本文件的方式来加载数据，调用示例如下：

```javascript
import { jsonp } from '@just4/load-script';
const res = await jsonp('a jsonp url', {
  data: { id: 1 },
  timeout: 5 * 1000,
  preventCaching: true
});
```

### 备用请求

无论是加载脚本还是 jsonp，都支持通过 `backupURL` 指定请求的备用地址。指定了备用地址时，如果原 URL 加载失败，就会加载备用 URL。

```javascript
import { loadScript } from '@just4/load-script';
await loadScript('https://code.jquery.com/jquery-1.12.4.min.js', {
  backupURL: 'https://ajax.aspnetcdn.com/ajax/jquery/jquery-1.12.4.min.js'
});
const $ = window.jQuery;
```

### 注意事项

- 慎用 `preventCaching` 选项。设为 `true` 时，会给请求的 url 加上时间戳参数，这可能会导致后端服务缓存穿透。
- 调用 `jsonp` 方法时，该方法会按照特定规则生成回调函数名，并确保该名字对应的全局变量没有被占用。如果你希望指定回调函数名，可以使用 `callbackName` 选项进行控制，但是这种情况下请自行确保 `callbackName` 对应的全局变量没有被占用。

## 相关文档

- [API 文档](https://heeroluo.github.io/just4/load-script/modules/index.html)

## Changelog

### v1.2.0

- 支持备用 URL 的加载。

### v1.1.0

- 升级依赖包版本并对应调整相关 API 的调用。
npm package: @just4/polling
Description: Just for making polling task easier to create.
Author: Mr.Luo
Latest version: 1.0.0

# @just4/polling

执行**轮询**（**定时**）任务。与纯粹的 setTimeout 或 setInterval 实现的定时任务相比，本模块还支持在异步操作（比如对后端接口的请求）完成之后，再进行下一轮计时。

## 安装

```bash
npm i @just4/polling
```

## 调用

### 基本调用

```javascript
import { Polling } from '@just4/polling';

const polling = new Polling(() => {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log('executed');
      resolve();
    }, 500);
  });
}, {
  // 1 秒执行一次
  interval: 1000
});
// 开始轮询
polling.start();
// 停止轮询
polling.stop();
```

调用 `start` 后会马上执行一次操作函数，如果不希望马上执行，可以传入参数 `false`：

```javascript
polling.start(false);
```

### 动态轮询间隔

```javascript
const polling = new Polling(() => {
  // ...
}, {
  // 越来越短的轮询间隔
  interval: function(lastInterval) {
    return lastInterval == null
      ? 10000
      : Math.max(1000, lastInterval - 200);
  }
});
polling.start();
```

### 通过钩子函数停止轮询

可以通过传入 `shouldContinue` 钩子函数控制是否继续轮询（返回值为 `false` 时停止轮询），可结合终止控制函数去使用：

```javascript
import { Polling, breakBy } from '@just4/polling';

const polling = new Polling(() => {
  // ...
}, {
  interval: 1000,
  // 轮询 3 次停止
  shouldContinue: breakBy.maxTimes(3)
});
polling.start();
```

### 出错后停止轮询

可以通过传入 `breakOnError: true` 在执行出错的时候停止轮询：

```javascript
const polling = new Polling(() => {
  return new Promise((resolve, reject) => {
    // 模拟出错的情况
    setTimeout(() => {
      if (Math.random < 0.5) {
        resolve();
      } else {
        reject();
      }
    }, 1000);
  });
}, {
  interval: 2000,
  breakOnError: true
});
polling.start();
```

### 更新轮询选项

可以调用实例方法 `updateOptions` 更新轮询选项：

```javascript
const polling = new Polling(() => {
  // ...
}, {
  interval: 2000,
  breakOnError: true
});
polling.start();

// 3 秒后轮询间隔改为 1 秒
setTimeout(() => {
  polling.updateOptions({
    interval: 1000
  });
}, 3000);
```

### 轮询过程中立刻执行一次操作函数

```javascript
const polling = new Polling(() => {
  // ...
}, {
  interval: 2000,
  breakOnError: true
});
polling.start();

setTimeout(() => {
  // 注意，如果操作函数是异步的而且当前还未执行完，
  // 那么 execImmediately 会等待它执行完之后才再次执行操作函数
  polling.execImmediately();
}, 3000);
```

### 监听事件

```javascript
import { Polling, breakBy } from '@just4/polling';
const polling = new Polling(() => {
  // ...
}, {
  interval: 1000,
  shouldContinue: breakBy.maxTimes(3)
});
polling.on('start', () => {
  console.log('start');
});
polling.on('stop', () => {
  console.log('stop');
});
polling.start();
```

## 相关文档

- [API 文档](https://heeroluo.github.io/just4/polling/modules/index.html)

## Changelog

### v1.0.0

- `interval` 选项支持传入函数，从而实现动态的轮询间隔。
- 增加终止控制函数（目前仅有 `maxTimes` 这个函数）。
- `start` 函数增加是否马上执行一次执行函数的参数，默认为马上执行。

### v0.3.0

- 事件发布/订阅机制更换为通过 `@just4/util/event` 中的 `PubSub` 实现。
- `PollingEvent` 不再是枚举类型，事件名通过字符串指定即可。

### v0.2.0

- 增加事件触发机制，支持轮询开始和轮询结束两个事件。
- 增加 `shouldContinue` 选项，用于传入一个决定是否停止轮询的函数。
npm package: @just4/querystring
Description: Just for querystring manipulation.
Author: Mr.Luo
Latest version: 2.0.0

# @just4/querystring

提供 URL 查询字符串（query string）的操作接口。

## 安装

```bash
npm i @just4/querystring
```

## 调用

### parse

`parse` 函数可以把一段查询字符串解析为对象：

```javascript
import { parse } from '@just4/querystring';
parse('id=0&str=hello'); // { id: '0', str: 'hello' }
```

一般情况下，解析结果的 `key` 和 `value` 都是字符串。然而，如果查询字符串中含有**重复的 key**，那么解析结果中该 `key` 对应的 `value` 就是字符串数组。

```javascript
parse('id=0&id=1'); // { id: ['0', '1'] }
```

### stringify

`stringify` 函数可以把对象序列化为查询字符串：

```javascript
import { stringify } from '@just4/querystring';
stringify({ id: '0', str: 'hello' }); // 'id=0&str=hello'
```

如果值是数组，则会遍历数组里面的每一项，均以对应的 `key` 进行序列化。

```javascript
stringify({ id: ['0', '1'] }); // 'id=0&id=1'
```

注意：如果值是数组以外的引用类型，其序列化结果将是空字符串。例如：

```javascript
stringify({ obj: { id: 0 } }); // 'obj='
```

### concat

`concat` 用于给指定 URL 或路径追加查询字符串。即使 URL 或路径中包含查询字符串或者锚点，也可以正常追加：

```javascript
import { concat } from '@just4/querystring';
concat('https://abc.com/?a=1#hash', {
  b: 2,
  c: 3
}); // 'https://abc.com/?a=1&b=2&c=3#hash'
```

### replace

`replace` 用于替换查询字符串中指定参数的值。它的行为与字符串的同名方法类似，只有匹配上才会替换：

 ```javascript
 import { replace } from '@just4/querystring';
 replace('abc?a=1&b=2', { a: 2 }); // 'abc?a=2&b=2'
 replace('abc?a=1&b=2', { c: 3 }); // 'abc?a=1&b=2'
 ```

## 相关文档

- [API 文档](https://heeroluo.github.io/just4/querystring/modules/index.html)

## Changelog

### v2.0.0

- 新增 `replace` 方法。
- 原 `appendToURL` 方法改名为 `concat`。
- 优化 `parse` 和 `stringify` 的内部实现。
- `stringify` 和 `concat` 的 `data` 参数调整为 any 类型。
- `stringify` 序列化数组以外的引用类型时，结果为空字符串。
- `parse` 的第一个参数不为字符串类型时，返回空对象而不是抛出异常。

### v1.0.1

- package.json 中增加 `main` 和 `miniprogram` 两个字段。
npm package: @just4/storage
Description: Just for making localStorage and sessionStorage easier to use.
Author: Mr.Luo
Latest version: 2.0.0

# @just4/storage

对 Web 存储对象（localStorage、sessionStorage）进行封装，使其接口更易用。封装后提供以下接口：

| 接口 | 说明 |
| --- | --- |
| get(key) | 即存储对象的 getItem 方法 |
| getAsJSON(key) | 对 get 的结果执行 JSON.parse 后返回 |
| set(key, value) | 调用存储对象的 setItem 方法时做了 try...catch 处理 |
| setAsJSON(key, value, options) | 对 value 执行 JSON.stringify 后再调用 set |
| remove(key) | 即存储对象的 removeItem 方法 |

## 安装

```bash
npm i @just4/storage
```

## 调用示例

```javascript
import { local, session } from '@just4/storage';
// local 即 localStorage 的封装
// session 即 sessionStorage 的封装
// 这两个对象没有任何插件（插件的说明见下文）

const user = { name: 'Tom', pet: 'cat' };

session.setAsJSON('user', user);
typeof session.get('user'); // 'string'
typeof session.getAsJSON('user'); // 'object'

local.setAsJSON('user', user);
local.getAsJSON('user');
typeof local.get('user'); // 'string'
typeof local.getAsJSON('user'); // 'object'
```

### 注意

当存储空间已满，或浏览器开启了隐私模式（无痕模式）时，`set` 操作可能无法往存储空间写入内容，但该方法不会抛出异常。开发者需要在业务代码中要做好数据无法被存储的预案。

## 插件机制

本程序包在 1.1.0 这个版本中引入了插件机制。该机制的实质就是在设置存储项的值时，以更多的关联存储项去配置存储属性。

举个例子：在设置 `token` 存储项的值为 `abcde` 时，以另外一个名叫 `__expires_of_token` 的关联存储项来存储过期时间。在获取 `token` 的值时，如果当前时间已经超过 `__expires_of_token` 所存储的过期时间，则返回 `null`，否则返回 `abcde`。

所有的插件都继承于 `StorageWrap`，并按需覆盖 `_doGetting`、`_doSetting` 以及 `_doRemoving` 三个方法。

注意，本程序包提供的 `local` 和 `session` 两个 `StorageWrap` 对象都不带有任何插件。

### 过期时间插件

本程序包提供了过期时间插件，调用示例如下：

```javascript
const storage = new StorageWrap('local', {
  plugins: [
    new ExpiresPlugin('local')
  ]
});
storage.set('test-01', '1', { expires: '1 month' });
```

## 相关文档

- [API 文档](https://heeroluo.github.io/just4/storage/modules/index.html)

## Changelog

### v2.0.0

- `StorageWrap` 的构造函数参数变更为 `storageType` 和 `options`，不兼容 v1.x 的调用方式。
- `StorageWrap` 新增 `available` 属性表示当前存储是否可用。
- `StorageWrap` 的 `set` 方法不再返回操作是否成功。
- 对 `StorageWrap` 进行了重构使其能支持插件机制。
- 新增过期时间插件 `ExpiresPlugin`，可以指定存储项的过期时间。
npm package: @just4/util
Description: Utility functions and classes.
Author: Mr.Luo
Latest version: 2.0.0

# @just4/util

本程序包主要为 Just4 的其他包提供基础的工具方法和工具类。包括：

- 数组操作。
- 对象操作。
- 日期操作。
- 类型判断。
- 事件操作。

## 安装

```bash
npm i @just4/util
```

## 调用

工具函数和工具类的功能及用法都较为简单，可参阅[API 文档](https://heeroluo.github.io/just4/util/modules/index.html)中的代码示例。

## Changelog

### v2.0.0

- 新增 event 模块，目前仅提供 `PubSub` 类。

### v1.1.0

- 新增 date 模块，目前仅有 `addRelativeTime` 一个方法。

### v1.0.1

- package.json 中增加 `main` 和 `miniprogram` 两个字段。
npm package: @just_testing13/coin-icons
Description: Internal coin icons used in Interlay UI components
Latest version: 0.1.3

# @interlay/coin-icons

Interlay UI internal coin icons.

## Contribution

Yes please! See the
[contributing guidelines](https://github.com/interlay/ui/blob/master/CONTRIBUTING.MD)
for details.

## License

[MIT](https://choosealicense.com/licenses/mit/)
npm package: @just_testing13/hooks
Description: Interlay UI hooks
Latest version: 0.2.1

# @interlay/hooks

Interlay UI hooks.

## Installation

```sh
yarn add @interlay/hooks
# or
npm i @interlay/hooks
```

## Contribution

Yes please! See the
[contributing guidelines](https://github.com/interlay/ui/blob/master/CONTRIBUTING.MD)
for details.

## License

[MIT](https://choosealicense.com/licenses/mit/)
npm package: @just_testing13/icons
Description: Interlay UI icons, commonly used in components
Latest version: 0.2.1

# @interlay/hooks

Interlay UI icons, also used in components.

## Installation

```sh
yarn add @interlay/icons
# or
npm i @interlay/icons
```

## Contribution

Yes please! See the
[contributing guidelines](https://github.com/interlay/ui/blob/master/CONTRIBUTING.MD)
for details.

## License

[MIT](https://choosealicense.com/licenses/mit/)
npm package: @just_testing13/system
Description: Interlay UI system primitives.
Latest version: 0.1.0

# @interlay/system

Interlay UI system primitives, `InterlayUIProvider` and some other utilities.

## Installation

```sh
yarn add @interlay/system
# or
npm i @interlay/system
```

## Contribution

Yes please! See the
[contributing guidelines](https://github.com/interlay/ui/blob/master/CONTRIBUTING.MD)
for details.

## License

[MIT](https://choosealicense.com/licenses/mit/)
npm package: @just_testing13/theme
Description: The default theme for Interlay UI components
Latest version: 0.2.1

# @interlay/theme

Interlay UI components theme.

## Installation

```sh
yarn add @interlay/theme
# or
npm i @interlay/theme
```

## Contribution

Yes please! See the
[contributing guidelines](https://github.com/interlay/ui/blob/master/CONTRIBUTING.MD)
for details.

## License

[MIT](https://choosealicense.com/licenses/mit/)
npm package: @just_testing13/ui
Description: Interlay UI library.
Latest version: 0.2.3

<p align="center">
      <h1 align="center">Interlay UI</h1>
</p>
</br>

Interlay IU is library of accessible, reusable, and composable React components built
around a crypto business model

## More infomation

See [README.md](https://github.com/interlay/ui/blob/master/README.md).
npm package: @justa/jst-pagination
Description: Angular component to handle with custom table pagination
Author: Valdery Paes
Latest version: 0.1.2

# Justa Pagination Library

Angular component to handle with custom table pagination

## Install

```bash
npm install --save @justa/jst-pagination
```

## Usage

Import the `JstPaginationModule` in your `app.module.ts` and add it to ngModule imports

just call `<jst-pagination></jst-pagination>` by passing the props of your need

## Props
 
| Props | type | default |
|-------|------|---------|
| numberOfPages | number | 1 |
| maxPagesShowed | number | 5 |
| innerElements | number | 3 |
| customClass | string | empty |
npm package: @justa/mask-directive
Description: ![](https://img.shields.io/bundlephobia/minzip/@justa/mask-directive.svg?style=flat-square) ![](https://img.shields.io/bundlephobia/min/@justa/mask-directive.svg?style=flat-square)
Author: Raí Siqueira
Latest version: 1.2.6

# JST Mask Directives

![](https://img.shields.io/bundlephobia/minzip/@justa/mask-directive.svg?style=flat-square) ![](https://img.shields.io/bundlephobia/min/@justa/mask-directive.svg?style=flat-square)

Justa Pagamentos Angular 2+ Directives! A set of NG2 Directives to improve your forms.

## Install

```bash
npm install --save @justa/mask-directive inputmask
```

## Usage

Add the `MaskDirectiveModule` in your `app.module.ts` file in the _imports_ array.

## Masks

### Money Mask (Deprecated)

> *Deprecated*: This directive is deprecated. For Brazilian Real, use the Currency Mask (`jstCurrencyMask`) instead.

Add the `jstMoneyMask` directive to your input.

### Props (inputs)

| Props | type | default |
|-------|------|---------|
| hasDecimal | bool | true |
| hasPrefix | bool | false |
| prefixSymbol | string | R$ |

**Example**

```html
<input jstMoneyMask [hasDecimal]="true" prefixSymbol="$" placeholder="$0.00">
```

### Legal document Mask (Brazil only)

Directive only used to format brazilian document (CNPJ/CPF) in a single input

Add the `jstLegalDocumentMask` Directive to your input.

**Example**

```html
<input jstLegalDocumentMask placeholder="000.000.000-00">
```

### Currency Mask (Brazil only)

Directive to format currency inputs. The form control value automatically is mutiplied/divided
by `currencyMultiplier` before rendering/after keyboard input.

#### Props (inputs)

| Prop | type | default |
|------|------|---------|
| currencyMultiplier | number | 100 |
| currencySuffix | string | 'R$ ' | 

**Example**

Add the `jstCurrencyMask` directive to your input:

```html
<input jstCurrencyMask formControlName="value">
```

### Percentage mask

Directive to format percentage inputs. The form control value is always between
0 and 1.

#### Props (inputs)

| Prop | type | default |
|------|------|---------|
| percentageSuffix | string | ' %' |

**Example**

Add the `jstPercentageMask` directive to your input:

```html
<input jstPercentageMask formControlName="value">
```

## License

MIT @ Justa Pagamentos
npm package: @justa/ng-schematics
Description: Angular feature generation tool for Justa productivity.
Author: Raí Siqueira
Latest version: 0.0.1-alpha.0

# Justa Angular Schematics

Angular feature generation tool for Justa productivity and project structure.

## Install

> WIP

## Running on dev mode

To test locally, install `@angular-devkit/schematics-cli` globally and use the `schematics` command line tool. That tool acts the same as the `generate` command of the Angular CLI, but also has a debug mode.

```bash
schematics .:<FEATURE-NAME> --debug=false
```

Check the documentation with
```bash
schematics --help
```

### Unit Testing

`npm run test` will run the unit tests, using Jasmine as a runner and test framework.

### License

MIT
npm package: @justa/ng-validators
Description: An collection of Angular reactive forms validators
Author: Rai Siqueira
Latest version: 1.3.0

<p align="center">
 <img width="80%" height="80%" src="./assets/project-logo.png">
</p>

Some _Angular Reactive Forms_ custom validators. ![npm bundle size](https://img.shields.io/bundlephobia/minzip/@justa/ng-validators.svg)

## Install

run `npm install --save @justa/ng-validators`

Install the peerDependecies:

`npm install --save moment @brazilian-utils/validators`

## Examples

Using the validators:

Import `ReactiveFormsModule` in _app.module.ts_

Example with **CNPJ Validator**

```typescript
import { Component, OnInit } from "@angular/core";
import { FormBuilder, FormGroup } from "@angular/forms";
import { jstValidators } from '@justa/ng-validators';

@Component({
  selector: 'app-form',
  templateUrl: './app-form.component.html',
  styleUrls: ['./app-form.component.scss'],
})
export class AppFormComponent implements OnInit {
  form: FormGroup;

  constructor(private fb: FormBuilder) {}

    ngOnInit() {
    this.form = this.fb.group({
      field: ['', jstValidators.validateCNPJ],
    });    
    }

}
```

**Example on Stackblitz:**

- [https://stackblitz.com/edit/ng-validators-jst](https://stackblitz.com/edit/ng-validators-jst)

## Available custom validators for controls

| Validator name | usage |
|----------------| ------ |
| validateDate | jstValidators.validateDate() |
| validateCNPJ | jstValidators.validateCNPJ |
| validateCPF | jstValidators.validateCPF |
| validatePhone | jstValidators.validatePhone |
| validateURL | jstValidators.validateURL |

## Available custom validators for FormGroup

| Validator name | usage |
| ---------------| ----- |
| mustMatchMinMaxValue | jstValidators.mustMatchMinMaxValue('minControl', 'maxControl') |

### Using Validators for FormGroup

Example:

```typescript
import { Component, OnInit } from "@angular/core";
import { FormBuilder, FormGroup } from "@angular/forms";
import { jstValidators } from '@justa/ng-validators';

@Component({
  selector: 'app-form',
  templateUrl: './app-form.component.html',
  styleUrls: ['./app-form.component.scss'],
})
export class AppFormComponent implements OnInit {
  form: FormGroup;

  constructor(private fb: FormBuilder) {}

    ngOnInit() {
    this.form = this.fb.group(
      {
        minValue: [''],
        maxValue: [''],
      },
      {
        validators: [
          jstValidators.mustMatchMinMaxValue('minValue', 'maxValue'),
        ],
      },
    );
    }
}
```

## Build (dev only)

Run `ng build @justa/ng-validators` on project root folder to build the project. The build artifacts will be stored in the `dist/` directory.

To build the package, run `ng build @justa/validators`. (See angular.json to more info about build proccess)

## License

MIT
npm package: @justa/prettier-rules
Description: Conjunto de regras usadas nas aplicações da Justa, com parsers para Angular e TypeScript.
Author: JUSTA SOLUCOES FINANCEIRAS S.A.
Latest version: 0.1.0

# `@justa/prettier-rules`

Conjunto de regras para o [prettier](https://prettier.io/).

## Instalação

```bash
npm install --dev @justa/prettier-rules
```

Ou

```bash
yarn add --dev @justa/prettier-rules
```

## Configuração

Referencie no `package.json` da seguinte forma:

```json
{
  "prettier": "@justa/prettier-rules"
}
```

## Licença

MIT @ JUSTA SOLUCOES FINANCEIRAS S.A.
npm package: @justa/utilities
Description: This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 8.1.2.
Author: Raí Siqueira
Latest version: 1.0.0

# Utilities

This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 8.1.2.

## Code scaffolding

Run `ng generate component component-name --project utilities` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project utilities`.
> Note: Don't forget to add `--project utilities` or else it will be added to the default project in your `angular.json` file. 

## Build

Run `ng build utilities` to build the project. The build artifacts will be stored in the `dist/` directory.

## Publishing

After building your library with `ng build utilities`, go to the dist folder `cd dist/utilities` and run `npm publish`.

## Running unit tests

Run `ng test utilities` to execute the unit tests via [Karma](https://karma-runner.github.io).

## Further help

To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
npm package: @justack/claude-hook
Description: Claude Code hook for human-in-the-loop approvals via Justack
Latest version: 0.1.0

# @justack/claude-hook

Human-in-the-loop tool approvals for Claude Code. Routes dangerous tool calls to a human reviewer via [Justack](https://justack.dev) for approval before execution.

## How it works

Registers as a Claude Code [PreToolUse hook](https://docs.anthropic.com/en/docs/claude-code/hooks). When Claude tries to use a tool (Bash, Write, Edit, MCP tools), the hook:

1. Evaluates the tool call against configurable rules
2. Auto-approves safe commands (e.g. `ls`, `git status`)
3. Sends dangerous/unknown commands to your Justack inbox for approval
4. Blocks until you approve or deny — with optional feedback and argument modification

## Installation

```bash
npm install -g @justack/claude-hook
```

Or run directly with npx (no install needed):

```bash
npx @justack/claude-hook init
```

## Quick start

### 1. Get a Justack API key

Sign up at [justack.dev](https://justack.dev) and create an API key from the dashboard.

### 2. Initialize the hook

```bash
cd your-project
npx @justack/claude-hook init
```

The wizard will:
- Prompt for your API key (`jstk_...`) or read `JUSTACK_API_KEY` from env
- Prompt for the reviewer's email address
- Validate credentials against the Justack API
- Create `.justack/config.json` with default rules
- Add `.justack/` to `.gitignore`
- Register the hook in `.claude/settings.json`

### 3. Use Claude Code as normal

The hook runs automatically. When Claude triggers a dangerous action, you'll get a notification in your Justack inbox with the full tool call details, diffs, and an approve/deny prompt.

## Default rules

| Tool | Mode | Behavior |
|------|------|----------|
| `Bash` | `pattern` | Auto-approves safe commands, flags dangerous ones, asks for unknown |
| `Write` | `all` | All file writes require approval |
| `Edit` | `all` | All file edits require approval |
| `mcp__*` | `all` | All MCP tool calls require approval |

**Safe patterns** (auto-approved): `ls`, `cat`, `git status`, `git diff`, `git log`, `pnpm install`, `tsc`, `eslint`, etc.

**Dangerous patterns** (require approval): `rm`, `git push`, `sudo`, `curl -X POST`, `npm publish`, `node`, `python`, etc.

## Configuration

The config lives at `.justack/config.json` in your project root:

```json
{
  "apiKey": "jstk_...",
  "recipientEmail": "reviewer@example.com",
  "rules": {
    "Bash": {
      "mode": "pattern",
      "dangerous": ["rm ", "git push", "..."],
      "safe": ["ls", "git status", "..."]
    },
    "Write": { "mode": "all" },
    "Edit": { "mode": "all" },
    "mcp__*": { "mode": "all" }
  }
}
```

### Rule modes

- **`all`** — Every call to this tool requires approval
- **`none`** — Auto-approve everything (skip this tool)
- **`pattern`** — Match against `dangerous` and `safe` substring lists. Unknown commands require approval.

Tool names support glob patterns (e.g. `mcp__*` matches all MCP tools).

## Environment variables

| Variable | Description |
|----------|-------------|
| `JUSTACK_API_KEY` | API key (used by `init` if set, avoids interactive prompt) |

## License

MIT
npm package: @justaddcl/init-js-lint
Description: A simple script to help initialize linting for js projects
Author: @justaddcl
Latest version: 1.2.0

# init-js-lint

I was tired of trying to remember all the packages and peer dependencies I needed to install just to get up and running with ESLint and Prerrier using [Airbnb's configs](https://www.npmjs.com/package/eslint-config-airbnb), so I created this handly little script to do all that for me.

Check out this project on [NPMjs.com](https://www.npmjs.com/package/@justaddcl/init-js-lint)

![npm (scoped)](https://img.shields.io/npm/v/@justaddcl/init-js-lint?style=flat-square&logo=npm) ![NPM](https://img.shields.io/npm/l/@justaddcl/init-js-lint?style=flat-square&logo=github) ![Travis (.org)](https://img.shields.io/travis/justaddcl/init-js-lint?style=flat-square&logo=travis) ![GitHub repo size](https://img.shields.io/github/repo-size/justaddcl/init-js-lint?style=flat-square&logo=github) ![npm](https://img.shields.io/npm/dt/@justaddcl/init-js-lint?style=flat-square&logo=npm)

## What it installs

- Airbnb's ESLint config (either base or with react depending on supplied argument)
- any peer dependencies for Airbnb's ESLint config
- any other packages specified in packages.js

Note: it will install the latest version of each package. Specifying versions is not (yet) supported. To install other versions, manually edit your package.json after you've run the script, then run `npm i`

# Usage

Base config (you're not using react)

```shell
  npx @justaddcl/init-js-lint
```

React config

```shell
  npx @justaddcl/init-js-lint react
```

# Thank you

A big shout out to the [npms.io](https://npms.io/about) API, which I use to get the latest list of peer dependencies for the Airbnb's config that need to be installed

If you find this useful in your projects or have ideas on how to make this more helpful, I'd love to hear about it! @justaddcl
npm package: @justaddjam/tsconfig
Description: A set of TypeScript compiler configurations.
Author: James Adarich
Latest version: 0.5.0

# @justaddjam/tsconfig

A set of TypeScript compiler configurations.

```json
{
    "extends": "@justaddjam/tsconfig/node",
    "compilerOptions": {
        "outDir": "./dist"
    },
    "exclude": [
        "./node_modules"
    ],
    "include": [
        "./**/*.ts"
    ]
}

```

## base

Sensible general defaults (mainly used as a base for the following configuration files).

## browser

Sensible defaults for browser based applications.

## node

Sensible defaults for nodejs based applications.
npm package: @justajwolf/body-parser-xml
Description: This is nodejs body parser xml middleware.
Author: justajwolf
Latest version: 1.0.0

# `express-body-parser-xml`

The pkg is a extension relative to the [body-parser](https://github.com/expressjs/body-parser) library. you can use it to parser xml data and convert into JavaScript Object, mounting on req.body.

The config options is highly opened：

- you can use your `read` to extract raw body from request stream if you think the default is not satisfied with your case.
- you can custom parser xml, just to set the parser into options, passing in middleware.

## Installation

```shell
$ npm install express-body-parser-xml
```

## Usage

for js

```js
const { XMLParseMiddleware } = require('express-body-parser-xml');
app.use(XMLParseMiddleware());
```

for ts

```ts
import { XMLParseMiddleware } from 'express-body-parser-xml';
app.use(XMLParseMiddleware());
```

### Options

- types
  - an array of types to match incoming request `content-type`.
- limit
  - only parser `content-length` less than limit body.
- charset
  - ascii
  - utf8
  - utf-8
  - utf16le
  - ucs2
  - ucs-2
  - base64
  - base64url
  - latin1
  - binary
  - hex
- parser
  - parser text to js object, the default is xml2js.
- defaultParserOpts
  - parserOpts for xml2js parser
- read
  - extract data from request stream.

### Default Options

```ts
{
  types: ['*/xml', '+xml'],
  limit: '1mb',
  charset: 'utf8',
  parser: defaultParser,
  defaultParserOpts: { async: true, explicitArray: false },
  read: defaultRead,
}
```

### Custom Parser type

```ts
type IParser = (xmlRaw: string) => Promise<Record<string, any>>;
```

### Custom Read

It will be considered to be right, when only the readRes.status === 200.

```ts
interface IReadRes {
  status: number;
  msg?: string;
  rawBody: string;
}
type IRead = (req: Request, opts: IXmlOptions) => Promise<IReadRes>;
```

## Example

for js

```js
const express = require('express');
const { XMLParseMiddleware } = require('express-body-parser-xml');
const app = express();
app.use(XMLParseMiddleware({ limit: '2mb' }));
app.post('/test', async (req, res) => {
  res.end(JSON.stringify(req.body));
});
```

for ts

```ts
import * as express from 'express';
import { XMLParseMiddleware } from 'express-body-parser-xml';
const app = express();
app.use(
  XMLParseMiddleware({
    types: ['text/xml'],
    limit: '2mb',
  }),
);
app.post('/test', async (req: express.Request, res: express.Response) => {
  res.end(JSON.stringify(req.body));
});
```

## Motivation

The chance to build this pkg is that i failed to find one pkg to use easily that parser xml as middleware, when i develop my wechat account service.

After refer to relevant packages, such as [body-parser-xml](https://www.npmjs.com/package/body-parser-xml), [body-parser](https://www.npmjs.com/package/body-parser), [xml2js](https://www.npmjs.com/package/xml2js), [type-is](https://www.npmjs.com/package/type-is) and so on. i write this pkg by ts.

In brief, thanks a lot, owing to the above pkgs, this pkg can born.

## License

MIT
npm package: @justajwolf/clickhouse
Description: This is nodejs clickhouse client.
Author: justajwolf
Latest version: 1.0.0

# `@justajwolf/clickhouse`

The pkg is clickhouse client for nodejs. in the next, the pkg will add more feature, for example support grpc ……

## Installation

```shell
$ npm install @justajwolf/clickhouse
```

## Usage

```ts
import {
  ClickHouse,
  ColumnDefInfo,
  ResponseData,
} from '@justajwolf/clickhouse';
// import * as assert from 'assert';
const driver = new ClickHouse({
  url: 'http://127.0.0.1:8123/?database=default&user=default&password=',
});

const create_table = `
  CREATE TABLE IF NOT EXISTS codec_example
  (
      id UInt32,
      dt Date CODEC(ZSTD),
      ts DateTime CODEC(LZ4HC),
      float_value Float32 CODEC(NONE),
      double_value Float64 CODEC(LZ4HC(9)),
      value Float32 CODEC(Delta, ZSTD)
  )
  ENGINE = MergeTree() PRIMARY KEY (id)
`;
const res1 = await driver.exec<string>(create_table);
// assert.equal(res1.status, 200);
// assert.equal(res1.data, '');

const res2 = await driver.exec<ResponseData<ColumnDefInfo>>(
  'describe table codec_example',
);
// assert.equal(res2.status, 200);
// assert.equal(res2.data.data.length, 6);

const res3 = await driver.insertOne<string>('codec_example', {});
// assert.equal(res3.status, 200);
// assert.equal(res3.data, '');

const res4 = await driver.insertMany<string>('codec_example', [{}]);
// assert.equal(res4.status, 200);
// assert.equal(res4.data, '');
```

## License

MIT