# anymock-openapi

Latest version **1.2.0** (published 2022-07-18) · MIT license · 0 weekly downloads

## Install

```sh
npm install anymock-openapi
pnpm add anymock-openapi
yarn add anymock-openapi
bun add anymock-openapi
```

## Health

**Score 20/100 (F)** — status: abandoned.

Positive: has types; no vulnerabilities.

Warnings: low downloads; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 1.2.0 |
| Published | 2022-07-18 |
| First published | 2019-08-16 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 4 |
| Unpacked size | 57.5 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Maintainers | beyondghx, qiu8310, legend80s, candy.zheng, codingserf |

## Links

- npm: https://www.npmjs.com/package/anymock-openapi
- npm.io page: https://npm.io/package/anymock-openapi

## Dependencies (4)

- [tslib](https://npm.io/package/tslib.md) ^1.10.0
- [@types/node](https://npm.io/package/@types/node.md) ^13.7.4
- [anymock-include](https://npm.io/package/anymock-include.md) ^0.2.1
- [anymock-client-token](https://npm.io/package/anymock-client-token.md) ^1.2.0

## Recent versions

- 1.2.0 (latest) — 2022-07-18
- 1.2.1-alpha.2 (alpha) — 2023-01-12
- 1.2.0-beta.0 (beta) — 2022-07-12
- 1.2.1-alpha.1 — 2022-11-08
- 1.1.2 — 2022-04-06
- 1.1.2-alpha.2 — 2022-03-08
- 1.1.1-alpha.2 — 2022-03-08
- 1.1.1-alpha.0 — 2022-02-07
- 1.1.0-alpha.0 — 2021-12-29
- 1.0.3 — 2020-11-10
- 1.0.2 — 2020-05-21
- 1.0.1 — 2020-04-26
- 1.0.0 — 2020-04-26
- 0.3.0 — 2020-03-31
- 0.2.4 — 2020-03-09
- … 13 more at https://npm.io/package/anymock-openapi/versions

## README

# anymock-openapi

<p align="center">
  <a href="https://anymock.alipay.com/">
    <img width="25%" src="https://gw.alipayobjects.com/mdn/rms_2a4b50/afts/img/A*HUcOR5hvy-cAAAAAAAAAAABkARQnAQ" alt="Anymock">
  </a>
</p>

> 可跨端的 Anymock OpenAPI SDK。可用于获取 Mock 数据以及其他众多OpenAPI。
>
> —— 一款好用的 [Anymock 平台](https://anymock.alipay.com/) 辅助工具

## Install

```sh
npm install anymock-openapi --save
```

## Concept

通过调用者使用不同环境下的的请求发生器，该 openapi sdk 可以灵活适配浏览器或 Node.js 场景。

请求发生器在本 SDK 中被抽象成“管道”，英文名 pipe。

## Use

### Browser

```js
import AnymockOpenapi from 'anymock-openapi';
import { EClients, ETypes } from 'anymock-include';

const fetch = window.fetch;
const config = {
  fromClient: EClients.chromeExtensionAnymock,

  // 请前往 https://anymock.alipay.com/ 在对应中获取项目 token
  projectToken: 'YOUR_ANYMOCK_PROJECT_TOKEN',
  bizId: '', // 接入业务代号，请找anymock产品开发人员确认。新接入必须申请后接入
};

/**
 * Pipe for browser.
 * @params {IRequestOptions} options
 * @return Promise<any>
 */
const pipe = (options) => {
  // interface IRequestOptions {
  //   url: string;
  //   headers: { [key: string]: any };
  //   method: string;
  //   data: { [key: string]: any }
  // }

  const url = options.url;
  const body = JSON.stringify(options.data);

  delete options.url;
  delete options.data;

  return fetch(url, { ...options, body })
    .then(res => res.json());
};

const openapi = new AnymockOpenapi(config, pipe);

main();

async function main() {
  // 1. fetch mock data
  const resp = await openapi.mock.query({
    type: ETypes.HTTP,
    subType: 'POST',
    matching: '/post',
    // parameters: {},
  });

  console.log('mock resp from https://anymock.alipay.com:\n', resp);
  console.log();
  console.log('mock data:')
  console.log(resp.data.mock.data);
  console.log();
  console.log('typeof mock data:', typeof resp.data.mock.data);

  // 2. fetch project details
  const { data: projectDetails } = await openapi.project.get();

  // projectDetails interface
  // {
  //   id: string;
  //   name: string;
  //   cname: string;
  //   // ...
  // }
}
```

### Node.js

Playground: <https://runkit.com/embed/qaym3apxzvma>

```js
const fetch = require('node-fetch');
const AnymockOpenapi = require('anymock-openapi').default;
const { EClients, ETypes } =  require('anymock-include');

const config = {
  fromClient: EClients.nodejsAnymock,

  // 请前往 https://anymock.alipay.com/ 获取项目 token
  projectToken: 'YOUR_ANYMOCK_PROJECT_TOKEN',
};

/**
 * Pipe for Node.js.
 * @params {IRequestOptions} options
 * @return Promise<T>
 */
const pipe = (options) => {
  // interface IRequestOptions {
  //   url: string;
  //   headers: { [key: string]: any };
  //   method: string;
  //   data: { [key: string]: any }
  // }

  const url = options.url;
  const body = JSON.stringify(options.data);

  delete options.url;
  delete options.data;

  return fetch(url, { ...options,body })
    .then(res => res.json());
};

const openapi = new AnymockOpenapi(config, pipe);

main();

async function main() {
  const resp = await openapi.mock.query({
    type: ETypes.HTTP,
    subType: 'POST',
    matching: '/post',
  });

  console.log('mock resp from https://anymock.alipay.com:\n', resp);
  console.log();
  console.log('mock data:')
  console.log(resp.data.mock.data);
  console.log();
  console.log('typeof mock data:', typeof resp.data.mock.data);
}
```

### openapi

所有 openapi 方法返回值类型均遵循：

```typescript
interface IAnymockResponse<T = null> {
  success: boolean;
  data: T;

  errorMessage: string;
  errorCode: string;
  errorExtra: any;
}
```

公共类型：

```typescript
// import { IAnymockConfigUpdate } from 'anymock-include';

export interface IAnymockConfigUpdate {
  /**
   * 用户是否自定义请求 mock 数据的 host
   * 默认 https://anymock.alipay.com。注意无结尾斜杠“/”
   */
  host?: string;
  /**
   * 用户 token
   */
  userToken?: string;

  /**
   * 项目 token
   * 必选
   * 请前往 https://anymock.alipay.com/ 获取
   */
  projectToken?: string;

  /**
   * 请求来源
   */
  fromClient?: EClients | string;
}
```

#### Mock 数据

##### 获取 Mock 数据

方法：`openapi.mock.query({ payload: IMockQueryPayload, options?: IAnymockConfigUpdate })`

入参：

```typescript
// import { IMockQueryPayload } from 'anymock-include';

export interface IMockQueryPayload {
  type: ETypes;

  /** 如果是 type 是 HTTP，则 subType 可以是 GET POST 等 */
  subType?: string;
  matching: string;

  /** 场景 ID。指定返回某个场景下的数据 */
  sceneId?: string;
  parameters?: any;
}

export enum ETypes {
  HTTP = 'HTTP',
  MTOP = 'MTOP',
  JSAPI = 'JSAPI',
}
```

返回值：`Promise<IAnymockResponse<IMockResp>>`

```typescript
export interface IMockResp {
  mock: {
    data: string;
  };
}
```

示例：

```typescript
const resp = await openapi.mock.query({
  type: ETypes.HTTP,
  subType: 'GET',
  matching: '/api/projects',
  // parameters: {},
});
```

##### 更新 Mock 数据

方法：`openapi.mock.update(requestId: ID, mockId: ID, payload: Partial<IMock>, config?: IAnymockConfigUpdate)`

入参：

```typescript
export type ID = string | number;

export interface IMock {
  data: string;
  dataType: number;
  gmtCreate: string;
  gmtModified: string;
  id: number;
  mockType: MockTypeEnum;
  requestId: number;
}
```

返回值：`Promise<IAnymockResponse<any>>`

示例：

```typescript
const resp = await openapi.mock.update({
  requestId: 1001,
  mockId: 2001,
  payload: {
    data: '{ success: false, name: "anymock" }'
  },
});
```

#### 项目

##### 获取项目详情

方法：`openapi.project.get(options?: IAnymockConfigUpdate, payload: IGetProjectPayload = {})`

入参：可选

返回值：`Promise<IAnymockResponse<IProject>>`

```typescript
export interface IProject {
  id: number;
  gmtCreate: string;
  gmtModified: string;
  name: string;
  cname: string;
  avatar?: any;
  description: string;
  spaceId: number;
  status: number;
  token: string;
  members: IMember[];
}

export interface IMember {
  id: number;
  anymockId: string;
  userId: string;
  userName: string;
  nickName: string;
  avatar: string;
}
```

示例：

```typescript
openapi.project.get()
```

#### 接口

##### 获取接口列表

方法：`openapi.interface.list(options?: IAnymockConfigUpdate, payload?: IQuery = {})`

入参：可选

```typescript
export interface IQuery {
  [key: string]: any;
}
```

返回值：`Promise<IAnymockResponse<IInterface[]>>`

```typescript
export interface IInterface {
  cname?: any;
  description?: any;
  gmtCreate: string;
  gmtModified: string;
  id: number;
  matching: string;
  matchingType: string;
  name: string;
  projectId: number;
  request: IRequest[];
  subType: string;
  type: string;
}
export interface IRequest {
  cname: string;
  gmtCreate: string;
  gmtModified: string;
  id: number;
  interfaceId: number;
  isActive: boolean;
  mock: IMock[];
  status: number;
}

export interface IMock {
  data: string;
  dataType: number;
  gmtCreate: string;
  gmtModified: string;
  id: number;
  mockType: MockTypeEnum;
  requestId: number;
}

export enum MockTypeEnum {
  ResponseBody = 1,
  ResponseHeader = 2,
  RequestBody = 3,
  RequestHeader = 4,
}
```

##### 新增接口

方法：`openapi.interface.create(payload: IInterfaceModifiableParams, options?: IAnymockConfigUpdate)`

入参：必须

```typescript
export interface IInterfaceModifiableParams {
  type: string;

  /** 若 HTTP 接口则该字段必须 */
  subType?: string;

  matching: string;
  name?: string;
  description?: string;
}
```

返回值：`Promise<IAnymockResponse<number>>` 返回新增接口的 id

示例：

```typescript
openapi.interface.create({
  type: ETypes.HTTP,
  subType: 'GET',
  matching: '/api/projects/:pid',
})
```

##### 获取接口详情

方法：`openapi.interface.get(interfaceId?: string | number, config?: IAnymockConfigUpdate)`

入参：接口 id

返回值：`Promise<IAnymockResponse<IInterface>>`

```typescript
// 已有，省略
```

示例：

```typescript
openapi.interface.get(10001)
```

##### 更新接口

方法：`openapi.interface.update(interfaceId: ID, payload: IInterfaceModifiableParams, config?: IAnymockConfigUpdate)`

入参：必须

```typescript
export interface IQuery {
  [key: string]: any;
}
```

返回值：`Promise<IAnymockResponse<null>>`

示例：

```typescript
openapi.interface.update(1001, { matching: '/api/projects/:pid/interfaces' })
```

##### 删除接口

方法：`openapi.interface.delete(interfaceId: ID, config?: IAnymockConfigUpdate)`

入参：必须

返回值：`Promise<IAnymockResponse<null>>`

示例：

```typescript
openapi.interface.update(1001)
```

#### 请求

##### 创建请求（有明确的 interfaceId）

方法：`openapi.request.create(interfaceId: ID, payload: Partial<IRequest>, config?: IAnymockConfigUpdate)`

入参：必须

返回值：`Promise<IAnymockResponse<object>>`

示例：

```typescript
openapi.request.create(1001, {
  cname: '成功'
})
```

##### 获取请求详情

方法：`openapi.request.get(requestId: ID, config?: IAnymockConfigUpdate)`

入参：必须

返回值：`Promise<IAnymockResponse<IRequest>>`

示例：

```typescript
openapi.request.get(2001)
```

##### 更新请求

方法：`openapi.request.update(interfaceId: ID, requestId: ID, payload: Partial<IRequest>, config?: IAnymockConfigUpdate)`

入参：必须

返回值：`Promise<IAnymockResponse<object>>`

示例：

```typescript
openapi.request.update(1001, 2001, {
  cname: '失败'
})
```

##### 删除请求

方法：`openapi.request.delete(requestId: ID, config?: IAnymockConfigUpdate)`

入参：必须

返回值：`Promise<IAnymockResponse<null>>`

示例：

```typescript
openapi.request.delete(2001)
```

##### 新增请求（可能存在 interfaceId）

> 复合接口，有可能会先创建一个接口。
>
> 当接口存在则在接口下创建一个 request，否则先创建接口然后在其下新增一个 request
>
> 定位接口是否存在的规则：优先通过 interfaceId 或通过三要素（type / subType / matching）

方法：`openapi.request.addRequest(payload: IAddRequestParam, config?: IAnymockConfigUpdate)`

入参：必须

```typescript
export interface IAddRequestParam {
  /**
   * 若有则通过 interfaceId 唯一定位一个 interface
   * 否则通过三要素唯一定位（性能相对较差，但是为了客户端方便）
   */
  interfaceId?: ID;


  // 这些属性来自 interface
  // 三要素
  type: string;
  subType: string;
  matching: string;

  description?: string;
  name?: string;


  // 这才是 request 的真正属性
  request: {
    cname: string;
    mock: { data: string };
  };
}
```

返回值：`Promise<IAnymockResponse<{ interface: { id: ID }; request: any }>>`

示例：

```typescript
// 如果 type subType matching 相同的接口存在，则在该接口下新增一个 request
// 否则先创建接口，然后在其下新增一个 request
openapi.request.addRequest({
  type: 'HTTP',
  subType: 'POST',
  matching: '/api/projects/:pid',

  request: {
    cname: '成功',
    mock: {
      data: "{ success: true, name: 'anymock' }"
    }
  }
});
```

#### 场景
场景相关接口的描述如下：
```typescript
export interface IScene extends Omit<ISceneDBProps, 'id' | 'projectId' | 'status'> {
  /** 场景 id */
  id: string,
  /** 所属项目 id */
  projectId: string,
  name: string,
  description: string;
  active: boolean;
  records: ISceneRecord[];
  sceneUser: ISceneUser,
}

interface ISceneRecord extends IBaseDBProps {
  id: string;
  sceneId: string;
  interface: IInterface;
}

type ISceneUser = ISceneUserDB;

interface ISceneUserDB extends IBaseDBProps {
  id: number;
  sceneId: number;
  userId: number;
  interfaceId: number;
  status: number;
}

interface IBaseDBProps {
  gmtCreate: string;
  gmtModified: string;
}
```
##### 获取场景列表

方法：`openapi.scene.list(options?: IAnymockConfigUpdate, payload?: IQuery = {})`

入参：可选

返回值：`Promise<IAnymockResponse<IScene[]>>`

示例：

```typescript
const resp = await openapi.scene.list();
```

##### 获取场景详情

方法：`openapi.scene.get(sceneId: string, options?: IAnymockConfigUpdate, payload?: IQuery = {})`

入参：`sceneId: string`

返回值：`Promise<IAnymockResponse<IScene>>`

示例：

```typescript
const resp = await openapi.scene.get(sceneId);
```

#### 验收

相关接口描述如下：

```typescript
export interface IPage {
  id: string;
  gmtCreate?: string;
  gmtModified?: string;
  designUrl?: string;
  userId: string; // 所属用户 ID
  projectId: string; // 所属项目 ID
  url?: string; // 页面 URL
  extInfo?: string; // 扩展参数
  name?:	string; // 页面名称
  ua?: string; // 比如 Alipay App 对应的 UA
  script?: string; // 可以插入任意 script 脚本
  type: PageTypeEnum; // 1 在线页面；2 离线包；3 小程序
  appid?: string; // 小程序appid
  version?: string; // 小程序版本号
  platform?: number; // 应用所属平台：支付宝：1；高德：2；菜鸟：3；微信：4；飞猪：5
  superId?: string; // 标识流程验收的父级验收
  acceptanceType?: string; // unsigned 验收类型：流程验收：1；页面验收：2
  params?: string; // 自定义启动参数
  sceneId?: string; // 关联的场景id
  description?: string; // 验收描述信息
}

interface IPreviewPage extends IPage {
  previewUrl?: string; // 预览URL（会根据入参判断调用环境等生成可预览的地址）
  urlStatus?: string; // 预览url结果，默认为空，如果有异常会抛出对应错误
}
```
##### 获取验收列表

方法：`openapi.page.list(payload?: IQuery = {}, options?: IAnymockConfigUpdate)`

入参：可选

返回值：`Promise<IAnymockResponse<IPage[]>>`

示例：

```typescript
const resp = await openapi.scene.list();
```

##### 获取验收详情

方法：`openapi.page.get(pageId: string, payload?: IQuery = {}, options?: IAnymockConfigUpdate)`

入参：`pageId: string`

返回值：`Promise<IAnymockResponse<IPage>>`

示例：

```typescript
const resp = await openapi.page.get(pageId);
```

##### 获取验收链接&详情
该API会将前端传入的验收详情及选择的场景等信息，自动根据一定规则拼接出完整可验收的url。url可在真机中直接使用（真机验收需要先接入SDK）

方法：`openapi.page.preview(payload?: IQuery = {}, options?: IAnymockConfigUpdate)`

入参：`payload: IPage`

返回值：`Promise<IAnymockResponse<IPreviewPage>>`

示例：

```typescript
const resp = await openapi.page.preview(pageInfo: IPage);
```

## Develop

### 单元测试

```sh
ANYMOCK_HOST=http://127.0.0.1:7002 yarn test packages/openapi/__tests__/scene.spec.ts

yarn test packages/openapi/__tests__/basic.spec.ts
```

---
_Source: https://npm.io/package/anymock-openapi · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
