open-index/open-npm huggingface dataset:
npm package: @keq-request/cli
Description: Transform Swagger/OpenAPI to the function that send request by keq
Author: Val.istar.Guo
Latest version: 5.0.0-alpha.31

<!-- title -->
<p align="center" style="padding-top: 41px">
  <img src="https://raw.githubusercontent.com/keq-request/keq/refs/heads/master/images/logo.svg" width="121" alt="logo" />
</p>

<h2 align="center" style="text-align: center">KEQ-CLI</h2>
<!-- title -->

[npm]: https://www.npmjs.com/package/keq-cli
[Document EN]: https://keq-request.github.io/guide/cli
[Document CN]: https://keq-request.github.io/zh/guide/cli

[![version](https://img.shields.io/npm/v/keq-cli.svg?logo=npm&style=for-the-badge)][npm]
[![downloads](https://img.shields.io/npm/dm/keq-cli.svg?logo=npm&style=for-the-badge)][npm]
[![dependencies](https://img.shields.io/librariesio/release/npm/keq-cli?logo=npm&style=for-the-badge)][npm]
[![license](https://img.shields.io/npm/l/keq-cli.svg?logo=github&style=for-the-badge)][npm]
[![Codecov](https://img.shields.io/codecov/c/gh/keq-request/keq-cli?logo=codecov&token=PLF0DT6869&style=for-the-badge)](https://codecov.io/gh/keq-request/keq-cli)

<!-- description -->

[**Document**][Document EN] | [**中文文档**][Document CN]

Transform Swagger 3.0/2.0 to the function that send request by [keq](https://github.com/keq-request/keq).
npm package: @keq-request/exception
Description: Request exception for keq
Author: Val.istar.Guo
Latest version: 5.0.0-alpha.31

<!-- title -->
<p align="center" style="padding-top: 41px">
  <img src="https://raw.githubusercontent.com/keq-request/keq/refs/heads/master/images/logo.svg" width="121" alt="logo" />
</p>

<h2 align="center" style="text-align: center">KEQ-EXCEPTION</h2>
<!-- title -->

[![version](https://img.shields.io/npm/v/keq-exception.svg?style=for-the-badge)](https://www.npmjs.com/package/keq-exception)
[![downloads](https://img.shields.io/npm/dm/keq-exception.svg?style=for-the-badge)](https://www.npmjs.com/package/keq-exception)
[![license](https://img.shields.io/npm/l/keq-exception.svg?style=for-the-badge)](https://www.npmjs.com/package/keq-exception)
[![dependencies](https://img.shields.io/librariesio/release/npm/keq-exception?style=for-the-badge)](https://www.npmjs.com/package/keq-exception)
[![codecov](https://img.shields.io/codecov/c/gh/keq-request/keq-exception?logo=codecov&token=HWP4GTMWV8&style=for-the-badge)](https://codecov.io/gh/keq-request/keq-exception)

[Document EN]: https://keq-request.github.io/guide/libraries/keq-exception
[Document CN]: https://keq-request.github.io/zh/guide/libraries/keq-exception

[**Document**][Document EN] | [**中文文档**][Document CN]

`Middleware` for throwing/catching exceptions. And it can control whether the exception trigger `retry`.

## Usage

<!-- prettier-ignore -->
```typescript
import { request } from "keq"
import {
  throwException,
  catchException,
  RequestException,
} from "keq-exception"

request
  .use(
    catchException((err) => {
      if (err instanceof RequestException && err.code === 401) {
        context.redirect("/login")
        return
      }

      throw err
    })
  )

  // Callback will run after `await next()`.
  // This way you can throw errors based on the response body.
  .use(
    throwException(async (ctx) => {
      if (ctx.response && ctx.response.status >= 400) {
        const body = await ctx.response.json()
        throw new RequestException(ctx.response.status, body.message)
      }
    })
  )
```

### RequestException(statusCode[, errorMessage[, retry]])

| **Parameter** | **Default** | **Description**                              |
| :------------ | :---------- | -------------------------------------------- |
| statusCode    | -           | Error code                                   |
| message       | `''`        | Error message                                |
| retry         | `true`      | Whether the thrown error can trigger a retry |
npm package: @keq-request/headers
Description: Set/Append headers to request.
Author: Val.istar.Guo
Latest version: 5.0.0-alpha.31

<!-- title -->
<p align="center" style="padding-top: 41px">
  <img src="https://raw.githubusercontent.com/keq-request/keq/refs/heads/master/images/logo.svg" width="121" alt="logo" />
</p>

<h2 align="center" style="text-align: center">KEQ-HEADERS</h2>
<!-- title -->

[![version](https://img.shields.io/npm/v/keq-headers.svg?style=for-the-badge)](https://www.npmjs.com/package/keq-headers)
[![downloads](https://img.shields.io/npm/dm/keq-headers.svg?style=for-the-badge)](https://www.npmjs.com/package/keq-headers)
[![license](https://img.shields.io/npm/l/keq-headers.svg?style=for-the-badge)](https://www.npmjs.com/package/keq-headers)
[![dependencies](https://img.shields.io/librariesio/release/npm/keq-headers?style=for-the-badge)](https://www.npmjs.com/package/keq-headers)
[![Codecov](https://img.shields.io/codecov/c/gh/keq-request/keq-headers?logo=codecov&token=PLF0DT6869&style=for-the-badge)](https://codecov.io/gh/keq-request/keq-headers)

[Document EN]: https://keq-request.github.io/guide/libraries/keq-headers
[Document CN]: https://keq-request.github.io/zh/guide/libraries/keq-headers

[**Document**][Document EN] | [**中文文档**][Document CN]

Set/Append headers to request.

## Usage

```typescript
import { request } from "keq";
import {
  setHeader,
  setHeaders,
  appendHeader,
  appendHeaders,
  insertHeader,
  insertHeaders,
} from "keq-headers";

request
  .use(setHeader("x-user-name", "Kerry"))
  .use(appendHeader("x-user-name", "Marry"))
  .use(insertHeader("x-user-name", "J"))
  .use(
    setHeaders({
      "x-user-name": "Kerry",
      "x-user-id": "1",
    })
  )
  .use(
    appendHeaders({
      "x-user-name": "Marray",
      "x-user-id": "1",
    })
  )
  .use(
    insertHeaders({
      "x-user-name": "J",
      "x-user-id": 1,
    })
  );
```

| **Middleware** | **Description**                                                            |
| :------------- | :------------------------------------------------------------------------- |
| setHeader      | Set a header.If it already exists, the original value will be overwritten. |
| setHeaders     | Set headers.If it already exists, the original value will be overwritten.  |
| appendHeader   | Append a header.                                                           |
| appendHeaders  | Append headers.                                                            |
| insertHeader   | Set a header, if it isn't existed.                                         |
| insertHeaders  | Set headers, if it isn't existed.                                          |

## Contributing & Development

If there is any doubt, it is very welcome to discuss the issue together.
npm package: @keq-request/url
Description: Set request url
Author: Val.istar.Guo
Latest version: 5.0.0-alpha.31

<!-- title -->
<p align="center" style="padding-top: 41px">
  <img src="https://raw.githubusercontent.com/keq-request/keq/refs/heads/master/images/logo.svg" width="121" alt="logo" />
</p>

<h2 align="center" style="text-align: center">KEQ-URL</h2>
<!-- title -->

[![version](https://img.shields.io/npm/v/keq-url.svg?style=for-the-badge)](https://www.npmjs.com/package/keq-url)
[![downloads](https://img.shields.io/npm/dm/keq-url.svg?style=for-the-badge)](https://www.npmjs.com/package/keq-url)
[![license](https://img.shields.io/npm/l/keq-url.svg?style=for-the-badge)](https://www.npmjs.com/package/keq-url)
[![dependencies](https://img.shields.io/librariesio/release/npm/keq-url?style=for-the-badge)](https://www.npmjs.com/package/keq-url)
[![Codecov](https://img.shields.io/codecov/c/gh/keq-request/keq-url?logo=codecov&token=PLF0DT6869&style=for-the-badge)](https://codecov.io/gh/keq-request/keq-url)

[Document EN]: https://keq-request.github.io/guide/libraries/keq-url
[Document CN]: https://keq-request.github.io/zh/guide/libraries/keq-url

[**Document**][Document EN] | [**中文文档**][Document CN]

[Keq](https://github.com/keq-request/keq) middleware for setting the request url.

## Usage

### `setBaseUrl(baseUrl)`

```typescript
import { request } from "keq";
import { setBaseUrl, setHost } from "keq-url";

request.use(setBaseUrl("http://example.com/api"));

await request.get("/test");
// it will send request to 'http://example.com/api/test'
```

### `setOrigin(origin)`

```typescript
import { request } from "keq";
import { setOrigin } from "keq-url";


await request.get("http://test.com/test");
  .use(setOrigin("http://example.com:8080"));
// it will send request to 'http://example.com:8080/test'

// and prefix pathname is also possible
await request.get("http://test.com/test");
  .use(setOrigin("/api"));
// it will send request to 'http://test.com:8080/api/test'
```

### `setHost(host)`

```typescript
import { request } from "keq";
import { setHost } from "keq-url";

request.use(setHost("example.com"));

await request.get("http://test.com/test");
// it will send request to 'http://example.com/test'
```

## Contributing & Development

If there is any doubt, it is very welcome to discuss the issue together.
npm package: @keqi.gress/plugin-bridge
Description: Gress 插件桥接核心包 - 提供插件与宿主应用通信的标准 API
Author: Gress Team
Latest version: 1.0.0

# @gress/plugin-bridge

Gress 插件桥接核心包 - 提供插件与宿主应用通信的标准 API

## 📦 安装

```bash
npm install @gress/plugin-bridge
# or
yarn add @gress/plugin-bridge
# or
pnpm add @gress/plugin-bridge
```

## 🚀 快速开始

### 在主应用中创建插件桥

```typescript
import { createPluginBridge, exposePluginBridge } from '@gress/plugin-bridge'

const bridge = createPluginBridge({
  app,
  router,
  pinia,
  http: requestClient,
  permissions: [
    PluginPermission.NETWORK_ACCESS,
    PluginPermission.ROUTER_NAVIGATE,
    // ... 其他权限
  ]
})

// 暴露给插件使用
exposePluginBridge(bridge)
```

### 在插件中使用桥接功能

```typescript
import { useHostBridge, useIcon } from '@gress/plugin-bridge'

// 获取宿主能力
const { router, message, http, events } = useHostBridge()

// 路由导航
router.push('/some-path')

// 显示消息
message.success('操作成功')

// HTTP 请求
const data = await http.get('/api/data')

// 使用图标
const HomeIcon = useIcon('HomeOutline')
```

## 📚 API 文档

### Composables

#### `useHostBridge()`

获取宿主桥接对象，提供对主应用能力的访问。

**返回值：**
- `bridge` - 完整的桥接对象
- `router` - 路由 API
- `route` - 当前路由
- `message` - 消息提示 API
- `dialog` - 对话框 API
- `notification` - 通知 API
- `loadingBar` - 加载条 API
- `http` - HTTP 客户端
- `events` - 事件总线
- `utils` - 工具函数

#### `useIcon(iconName: string)`

获取图标组件。

```typescript
const HomeIcon = useIcon('HomeOutline')
```

#### `useIcons(iconNames: string[])`

批量获取图标组件。

```typescript
const icons = useIcons(['HomeOutline', 'AddOutline', 'SearchOutline'])
```

### 核心功能

#### `createPluginBridge(options)`

创建插件桥实例（主应用使用）。

#### `createPluginContext(pluginId, manifest, bridge)`

创建插件上下文（插件系统内部使用）。

#### `createEventEmitter()`

创建事件发射器。

## 🔒 权限系统

插件需要声明所需权限：

```typescript
export const manifest: PluginManifest = {
  id: 'my-plugin',
  name: 'My Plugin',
  version: '1.0.0',
  permissions: [
    PluginPermission.NETWORK_ACCESS,
    PluginPermission.ROUTER_NAVIGATE,
    PluginPermission.DATA_READ
  ]
}
```

可用权限：
- `NETWORK_ACCESS` - 网络访问
- `ROUTER_NAVIGATE` - 路由导航
- `ROUTER_REGISTER` - 注册路由
- `COMPONENT_REGISTER` - 注册组件
- `DATA_READ` - 读取数据
- `DATA_WRITE` - 写入数据
- `SYSTEM_NOTIFICATION` - 系统通知

## 📄 License

MIT
npm package: @keqin/adonis-sentry
Description: ## Installation
Latest version: 1.1.1

# Adonis-Sentry

## Installation

```bash
npm i @keqin/adonis-sentry
node ace configure @keqin/adonis-sentry
```

1. Set Env `SENTRY_DSN=`
2. call `Sentry.captureException` in `app/Exceptions/Handler.ts`
3. Add types for ENV in `env.ts`

```typescript
SENTRY_DSN: Env.schema.string.optional({ format: 'url' }),
SENTRY_TRACES_SAMPLE_RATE: Env.schema.string.optional(),
SENTRY_DEBUG: Env.schema.boolean.optional(),
```

## Test Sentry DSN 

`node ace sentry:ping`

## Performance monitoring
- set a env variable `SENTRY_TRACES_SAMPLE_RATE` between `0` to `1` as `tracesSampleRate`. we suggest set it to `1` in dev/testing environment.
- regisitry middleware in `kernel.ts`
    ```typescript
    Server.middleware.register([
        () => import('@keqin/adonis-sentry/build/TracingHandler')
    ])
    ```
    it would startTransaction in a http request, and inject `sentry`/`sentryTrx` to ctx

- Optional: create span in a request
- 
```typescript
import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'

export default class Controller {
    public async index({ sentry, sentryTrx }: HttpContextContract) {
        const span = sentryTrx.startChild({
            op: 'query',
            description: "more specific details"
        })
        // to do something
        span.finish()
    }
}
```

## Example

```ts
import Sentry from '@ioc:Adonis/Addons/Sentry'

Sentry.captureMessage('Hello World')
```

## Debug mode
set `SENTRY_DEBUG` as `true` to turn debug mode on 

## License
The MIT License
npm package: @keqin/squirrel-auth
Description: ### Installation ```bash npm i @keqin/squirrel-auth node ace configure @keqin/squirrel-auth ```
Latest version: 1.0.16

# Squirrel-Auth

### Installation
```bash
npm i @keqin/squirrel-auth
node ace configure @keqin/squirrel-auth
```

### Set env
```bash
DB_CONNECTION=
SESSION_DRIVER=
REDIS_CONNECTION=
SESSION_VALID_TIME=
```

### Init tables
```bash
node ace auth:initTable
```

### Register middleware inside your `start/kernel.ts` file.
```ts
Server.middleware.registerNamed({
  squirrelAuth : () => import('@ioc:Keqin/SquirrelAuthMiddleware')
})
```
npm package: @keqingrong/dom-utils
Description: Utilities for DOM, CSSOM
Author: Qingrong Ke
Latest version: 0.1.0

# @keqingrong/dom-utils

[![npm version](https://img.shields.io/npm/v/@keqingrong/dom-utils.svg)](https://www.npmjs.com/package/@keqingrong/dom-utils)

> Utilities for DOM, CSSOM

English | [简体中文](./README-zh-hans.md)

## Installation

```sh
npm install @keqingrong/dom-utils
```

## API

- `getPageScrollOffset()`
- `getPageSize()`
- `getViewportSize()`
- `getElementBoundingRect(element)`
- `isInViewport(element)`
- `isOutOfViewport(element)`
- `isIntersectWithViewport(element)`

## License

MIT © Qingrong Ke
npm package: @keqingrong/fingerprint
Description: ## Installation
Author: Qingrong Ke
Latest version: 0.1.0

# @keqingrong/fingerprint (WIP)

## Installation

```bash
# npm
npm install @keqingrong/fingerprint

# yarn
yarn add @keqingrong/fingerprint
```

## Usage

```ts
import { getCustomHash } from '@keqingrong/fingerprint';

getCustomHash(hash).then(() => {
  console.log(hash);
});
```

## APIs

- APIs from `@fingerprintjs/fingerprintjs`: `load()`, `hashComponents()`, etc.
- `getGpuInfo()`
- `getGpuFingerprint()`
- `getPublicIP(serviceURL)`
- `getRobustPublicIP()`
- `getIPFingerprint()`
- `getOSVersion()`
- `getOSVersionFingerprint()`
- `getCanvasHash()`
- `getCanvasStableHash()`
- `getAudioHash()`
- `getCustomHash()`
- `getHash()`
- `getHashes()`

## License

MIT © Qingrong Ke
npm package: @keqingrong/globals
Description: Global identifiers for rollup's `output.globals` and webpack's `externals`
Author: keqingrong
Latest version: 0.2.1

# @keqingrong/globals

[![npm version](https://img.shields.io/npm/v/@keqingrong/globals.svg)](https://www.npmjs.com/package/@keqingrong/globals)

Global identifiers for rollup's [`output.globals`](https://rollupjs.org/guide/en/#outputglobals) and webpack's [`externals`](https://webpack.js.org/configuration/externals/)

## Installation

```sh
# npm
npm install -D @keqingrong/globals

# yarn
yarn add -D @keqingrong/globals
```

## Usage

### rollup

```js
// rollup.config.js
import globals from '@keqingrong/globals';
import pkg from './package.json';

export default {
  // ...
  external: Object.keys(pkg.dependencies),
  output: {
    globals,
  },
};
```

### webpack

```js
// webpack.config.js
const globals = require('@keqingrong/globals');
const pkg = require('./package.json');

module.exports = {
  // ...
  externals: globals,
};
```

or

```js
// webpack.config.js
const globals = require('@keqingrong/globals');
const pkg = require('./package.json');

const externals = {};
Object.keys(pkg.dependencies).forEach(name => {
  if (globals[name]) {
    externals[name] = {
      commonjs: name,
      amd: name,
      root: globals[name],
    };
  }
});

module.exports = {
  // ...
  externals,
};
```

## License

MIT © Qingrong Ke
npm package: @keqingrong/hooks
Description: Collection of React Hooks
Author: Qingrong Ke
Latest version: 0.2.0

# @keqingrong/hooks (WIP)

Collection of React Hooks

## Installation

```sh
# npm
npm install @keqingrong/hooks

# yarn
yarn add @keqingrong/hooks
```

## Usage

### Use query string parameters

```tsx
import { useQueryParams } from '@keqingrong/hooks';

function App() {
  const query = useQueryParams();
  return <div>App</div>;
}
```

### Check whether element has scrollbars

```tsx
import { useHasScrollbar } from '@keqingrong/hooks';

function App() {
  const ref = useRef<HTMLDivElement>(null);
  const hasScrollbar = useHasScrollbar(ref);
  return (
    <div>
      <ul>
        <li>{hasScrollbar.vertical ? '✅' : '❌'} vertical scrollbar</li>
        <li>{hasScrollbar.horizontal ? '✅' : '❌'} horizontal scrollbar</li>
      </ul>
      <div ref={ref}>...</div>
    </div>
  );
}
```

## APIs

- `useFixInputFocusScroll()`
- `useHasScrollbar()`
- `useMutationObserver()`
- `useQueryParams(opts)`
  - `opts.mode`: `'auto'|'std'|'hash'|'mixed'`

## License

MIT © Qingrong Ke
npm package: @keqingrong/http-client
Description: A JavaScript HTTP client based on axios and fetch-jsonp
Author: Qingrong Ke
Latest version: 0.1.0

# @keqingrong/http-client

[![npm version](https://img.shields.io/npm/v/@keqingrong/http-client.svg)](https://www.npmjs.com/package/@keqingrong/http-client)

A JavaScript HTTP client based on axios and fetch-jsonp

## Installation

```bash
# npm
npm install @keqingrong/http-client

# yarn
yarn add @keqingrong/http-client
```

## Usage

```ts
import { http, HttpClient } from '@keqingrong/http-client';

interface ResponseData { }

(async () => {
  try {
    const response = await http.get<ResponseData>(url);
    // ...
  } catch(err) {
    // ...
  }
})();
```

## API

```js
// GET method
http.get(url);
http.get(url, { foo: 'bar' });
http.get(url, new URLSearchParams());

// POST method
http.post(url, { foo: 'bar' });

// Shortcuts POST method
http.postFormUrlencoded(url, { foo: 'bar' });
http.postFormUrlencoded(url, new URLSearchParams());
http.postFormData(url, new FormData());
http.postJSON(url, { foo: 'bar' });

// JSONP
http.jsonp(url);
http.jsonp(url, { foo: 'bar' });
http.jsonp(url, new URLSearchParams());

// Custom
http.request({
  url,
  method: 'POST',
  headers: {
    'Content-Type': 'application/json;charset=utf-8'
  }
  data: { foo: 'bar' }
});
```

## License

MIT © Qingrong Ke
npm package: @keqingrong/js-codemod
Description: JS codemod scripts
Author: Qingrong Ke
Latest version: 0.1.0

# @keqingrong/js-codemod (WIP)

## Installation

```sh
# npm
npm install -D @keqingrong/js-codemod

# yarn
yarn add -D @keqingrong/js-codemod
```

## Transforms

- `strip-header-comment`

## License

MIT © Qingrong Ke
npm package: @keqingrong/math
Description: Utilities for some frequently used calculation
Author: keqingrong
Latest version: 0.1.0

# @keqingrong/math (WIP)

> Utilities for some frequently used calculation

[![npm version](https://img.shields.io/npm/v/@keqingrong/math.svg)](https://www.npmjs.com/package/@keqingrong/math)

## Installation

```sh
npm install @keqingrong/math
```

## Usage

```js
import {
  toFixedAdvanced,
  yuan2cent,
  calculateDiscountedPrice,
  calculateDiscount,
} from '@keqingrong/math';

(0.015).toFixed(2); // '0.01'
toFixedAdvanced(0.015, 2); // '0.02'

33.8 * 100; // 3379.9999999999995
yuan2cent(33.8); // 3380;

calculateDiscountedPrice(1000, 8); // '800.00'
calculateDiscountedPrice(998, 8.8); // '888.22'

calculateDiscount(1000, 800); // '8'
calculateDiscount(1000, 888); // '8.9'
```

## API

- `mb2gb()`
- `cent2yuan()`
- `yuan2cent()`
- `addYuan()`
- `subYuan()`
- `calculateDiscountedPrice()`
- `calculateDiscount()`
- `toFixed()`
- `toFixedAdvanced()`
- `stripTrailingZeros()`
- `getDecimalDigits()`
- `subDecimal()`

## License

MIT © Qingrong Ke
npm package: @keqingrong/npm-apis
Description: Programmatic APIs for npm
Author: Qingrong Ke
Latest version: 0.7.0

# @keqingrong/npm-apis (WIP)

[![npm version](https://img.shields.io/npm/v/@keqingrong/npm-apis.svg)](https://www.npmjs.com/package/@keqingrong/npm-apis)

Programmatic APIs for npm

## Installation

```bash
# npm
npm install @keqingrong/npm-apis

# yarn
yarn add @keqingrong/npm-apis
```

## Usage

```ts
import { outdated } from '@keqingrong/npm-apis';

(async () => {
  const result = await outdated(
    {
      json: true,
      long: true
    },
    { cwd: __dirname }
  );
  const outdatedJson = JSON.parse(result);
  console.log(outdatedJson);
})();
```

## APIs

- `install(pkg)` Install a package
- `outdated()` Check for outdated packages
- `version(release)` Bump a package version
- `spawnAsync()` Promisified `child_process.spawn()`

## License

MIT © Qingrong Ke

## See Also

Official packages from the npm team:

- [libnpm](https://www.npmjs.com/package/libnpm)
- [libnpmhook](https://www.npmjs.com/package/libnpmhook)
- [libnpmexec](https://www.npmjs.com/package/libnpmexec)
- [libnpmversion](https://www.npmjs.com/package/libnpmversion)
- [libnpmaccess](https://www.npmjs.com/package/libnpmaccess)
- ...
npm package: @keqingrong/react-native-cli-apis
Description: Programmatic APIs for React Native CLI
Author: Qingrong Ke
Latest version: 0.5.0

# @keqingrong/react-native-cli-apis (WIP)

[![npm version](https://img.shields.io/npm/v/@keqingrong/react-native-cli-apis.svg)](https://www.npmjs.com/package/@keqingrong/react-native-cli-apis)

Programmatic APIs for React Native CLI

## Installation

```bash
# npm
npm install @keqingrong/react-native-cli-apis

# yarn
yarn add @keqingrong/react-native-cli-apis
```

## Usage

```ts
import { bundle, setPATH } from '@keqingrong/react-native-cli-apis';

(async () => {
  const config = {
    entryFile: 'index.js',
    platform: 'android',
    dev: false,
    resetCache: false,
    bundleOutput: './build/index.android.jsbundle',
    sourcemapOutput: './build/index.android.map',
    assetsDest: './build/assets',
  };
  const basePath = __dirname;
  const spawnOptions = {
    cwd: basePath,
    env: setPATH(basePath, process.env),
  };

  info('Building bundle for Android\n');
  await bundle(config, spawnOptions);
  info('Done building bundle for Android');
})();
```

## APIs

- `bundle(config)` Builds the JavaScript bundle for offline use
- `version()` Print React Native CLI version

## License

MIT © Qingrong Ke
npm package: @keqingrong/rsdoctor-webpack-plugin
Description: A wrapper for @rsdoctor/webpack-plugin
Author: keqingrong
Latest version: 0.1.1

# A wrapper for @rsdoctor/webpack-plugin

## Install

```sh
npm i -D @rsdoctor/webpack-plugin @keqingrong/rsdoctor-webpack-plugin
```

## Usage

webpack:

```js
// webpack.config.js
const RsdoctorWebpackPlugin = require('@keqingrong/rsdoctor-webpack-plugin');

module.exports = {
  // ...
  plugins: [
    process.env.RSDOCTOR &&
      new RsdoctorWebpackPlugin({
        // options
      }),
  ].filter(Boolean),
};
```

ice.js v2:

```js
// build.config.js
module.exports = {
  webpackPlugins: {
    '@keqingrong/rsdoctor-webpack-plugin': {},
  },
};
```

Or

```jsonc
// build.json
{
  "webpackPlugins": {
    "@keqingrong/rsdoctor-webpack-plugin": {}
  }
}
```

## See Also

- [rsdoctor](https://rsdoctor.dev/)
- [ice.js v2](https://v2.ice.work/docs/config/about#webpackplugins-)
npm package: @keqingrong/system-fonts
Description: Which fonts can I use?
Author: Qingrong Ke
Latest version: 0.4.0

# system-fonts (WIP)

[![npm version](https://img.shields.io/npm/v/@keqingrong/system-fonts.svg)](https://www.npmjs.com/package/@keqingrong/system-fonts)

> Which fonts can I use?

## Installation

```sh
$ npm install @keqingrong/system-fonts
```

## Usage

```js
import macOS_BigSur from '@keqingrong/system-fonts/data/macos/11.0.json';
import windows_10 from '@keqingrong/system-fonts/data/windows/10.json';
import iOS_13 from '@keqingrong/system-fonts/data/ios/13.json';
```

## TODO

- [ ] Fonts included with Microsoft Windows
  - [ ] Windows 11
  - [x] Windows 10
  - [x] Windows 8.1
  - [x] Windows 8
  - [x] Windows 7
  - [x] Windows Vista
  - [ ] Windows XP
  - [ ] Windows 2000
  - [ ] Windows 98
  - [ ] Windows 95
- [ ] Fonts included with macOS
  - [ ] macOS 12.0 Monterey
  - [x] macOS 11.0 Big Sur
  - [x] macOS 10.15 Catalina
  - [x] macOS 10.14 Mojave
  - [x] macOS 10.13 High Sierra
  - [x] macOS 10.12 Sierra
  - [ ] OS X 10.11 El Capitan
  - [ ] OS X 10.10 Yosemite
  - [x] OS X 10.9 Mavericks
  - [x] OS X 10.8 Mountain Lion
  - [ ] OS X 10.7 Lion
  - [ ] OS X 10.6 Snow Leopard
  - [x] OS X 10.5 Leopard
  - [x] OS X 10.4 Tiger
  - [x] OS X 10.3 Panther
- [ ] Fonts included with Android
  - [ ] Android 5~12
  - [ ] Android 4.4
  - [ ] MIUI 12
- [ ] Fonts included with iOS
  - [ ] iOS 15
  - [ ] iOS 14
  - [x] iOS 13
- [ ] A website like caniuse.com and iosfonts.com

## License

MIT © Qingrong Ke
npm package: @keqingrong/validator
Description: Utilities for validation and sanitization
Author: Qingrong Ke
Latest version: 0.1.1

# @keqingrong/validator

[![npm version](https://img.shields.io/npm/v/@keqingrong/validator.svg)](https://www.npmjs.com/package/@keqingrong/validator)

Utilities for validation and sanitization

## Installation

```sh
# npm
npm install @keqingrong/validator

# yarn
yarn add @keqingrong/validator
```

## Usage

```ts
import { validateIdCardNumber } from '@keqingrong/validator';

validateIdCardNumber('321280202101011234');
```

## API

- `validateIdCardNumberLegacy()`
- `validateIdCardNumber()` / `sanitizeIdCardNumber()`
- `validateSocialNumber()` / `sanitizeSocialNumber()`
- `validateBankCardNumber()`
- `validatePhoneNumber()` / `sanitizePhoneNumber()`
- `sanitizeChineseCharacter()`
- `sanitizeEmoji()`
- `Emoji_RegExp`

## License

MIT © Qingrong Ke
npm package: @keqingrong/vm
Description: A JavaScript utility like Node's vm module for browsers
Author: Qingrong Ke
Latest version: 0.2.0

# @keqingrong/vm

[![npm version](https://img.shields.io/npm/v/@keqingrong/vm.svg)](https://www.npmjs.com/package/@keqingrong/vm)

> A JavaScript utility like Node's vm module for browsers

Live demo available at [here](https://keqingrong.github.io/vm/example/).

## Installation

```sh
$ npm install @keqingrong/vm
```

The CDN build is also available on unpkg:

- [unpkg.com/@keqingrong/vm/dist/vm.umd.js](https://unpkg.com/@keqingrong/vm/dist/vm.umd.js)
- [unpkg.com/@keqingrong/vm/dist/vm.umd.min.js](https://unpkg.com/@keqingrong/vm/dist/vm.umd.min.js)

## Usage

```js
import { runInNewContext } from '@keqingrong/vm';

const sandbox = {
  x: 2
};
const code = 'function add(a) { return a+x; }; add(42);';
runInNewContext(code, sandbox).then((result) => {
  console.log(result); // 44
}, (error) => {
  console.error(error);
});
```

## API

- `runInNewContext(code, sandbox, options)`
- `runInNewIframe(code, sandbox)`
- `runInNewWorker(code, sandbox)`

## License

MIT
npm package: @keqingrong/web-apis
Description: Web APIs
Author: Qingrong Ke
Latest version: 0.5.0

# @keqingrong/web-apis (WIP)

[![npm version](https://img.shields.io/npm/v/@keqingrong/web-apis.svg)](https://www.npmjs.com/package/@keqingrong/web-apis)

Web APIs

## Installation

```bash
# npm
npm install @keqingrong/web-apis

# yarn
yarn add @keqingrong/web-apis
```

## Usage

```ts
import { chooseImage, getImageInfo } from '@keqingrong/web-apis';

(async () => {
  const [imageUrl] = await chooseImage({
    url: 'http://api.example.com/upload/image'
  });

  const { width, height, type } = await getImageInfo(imageUrl);
})();
```

## APIs

- Base
  - `base64ToArrayBuffer()`
  - `arrayBufferToBase64()`
- Device
  - Phone
    - `makePhoneCall()`
- Media
  - Image
    - `getImageInfo()` (WIP)
    - `getBaseImageInfo()`
    - `chooseImage()`
    - `chooseImageFile()`
    - `chooseImageDataURL()`
- Network
  - Download
    - `downloadFile()`
- Route
  - `navigateTo()`
- File
  - `saveFile()`
  - `saveImage()`
  - `saveJSON()`
  - `saveText()`
- Internal Utils
  - Base64
    - `arrayBufferToBase64()`
    - `base64ToTypedArray()`
    - `base64ToArrayBuffer()`
    - `base64ToBlob()`
    - `toBase64()`
    - `fromBase64()`
  - Blob
    - `blobToArrayBuffer()`/`readAsArrayBuffer()`
    - `blobToDataURL()`/`readAsDataURL()`
    - `blobToText()`/`readAsText()`
    - `latin1ToTypedArray()`
    - `utf16ToTypedArray()`
    - `stringToTypedArray()`
    - `arrayBufferToString()`
  - Data URL
    - `pareseDataURL()`
    - `dataURLToArrayBuffer()`
    - `dataURLToBlob()`
    - `dataURLToImageData()`
  - Download
    - `saveBlobOrURL()`
    - `downloadFile()`
  - Image
    - `imageToBlob()`
    - `imageToDataURL()`
  - URL
    - `isHttpURL()`
    - `isHttpsURL()`
    - `isDataURL()`
    - `isBlobURL()`
    - `httpsToHttp()`
    - `parseURL()`
    - `parseScheme()`
    - `getSubdomain()`
    - `isSameOrigin()`
    - `isCorssOrigin()`
    - `isSameSite()`
    - `isCrossSite()`
    - `isSchemefulSameSite()`
    - `isSchemefulCrossSite()`

## License

MIT © Qingrong Ke