From d115ce0bdc36e6a74ddfac518c3845684a7482b4 Mon Sep 17 00:00:00 2001 From: "guokai.jgk" Date: Sat, 10 Oct 2020 09:06:00 +0800 Subject: [PATCH 01/18] feat: add datasource engine & handlers --- packages/datasource-engine/.eslintignore | 1 + packages/datasource-engine/.eslintrc.js | 7 + packages/datasource-engine/.gitignore | 6 + packages/datasource-engine/.prettierrc.js | 4 + packages/datasource-engine/CHANGELOG.md | 30 ++++ packages/datasource-engine/ava.config.js | 8 + packages/datasource-engine/interpret.d.ts | 1 + packages/datasource-engine/interpret.js | 1 + packages/datasource-engine/package.json | 39 +++++ packages/datasource-engine/readme.md | 45 ++++++ packages/datasource-engine/runtime.d.ts | 1 + packages/datasource-engine/runtime.js | 1 + .../src/core/RuntimeDataSourceItem.ts | 144 ++++++++++++++++++ .../datasource-engine/src/core/adapter.ts | 66 ++++++++ packages/datasource-engine/src/core/index.ts | 2 + .../src/core/reloadDataSourceFactory.ts | 64 ++++++++ .../datasource-engine/src/helpers/index.ts | 14 ++ packages/datasource-engine/src/index.ts | 4 + .../src/interpret/DataSourceEngineFactory.ts | 56 +++++++ .../datasource-engine/src/interpret/index.ts | 3 + .../runtime/RuntimeDataSourceEngineFactory.ts | 69 +++++++++ .../datasource-engine/src/runtime/index.ts | 3 + packages/datasource-engine/src/typings.d.ts | 3 + packages/datasource-engine/src/utils.ts | 139 +++++++++++++++++ .../test/_helpers/bind-runtime-context.ts | 25 +++ .../datasource-engine/test/_helpers/delay.ts | 3 + .../datasource-engine/test/_helpers/index.ts | 3 + .../test/_helpers/mock-context.ts | 50 ++++++ .../scenes/p0-0-simplest-defaults/README.md | 3 + .../_datasource-runtime.ts | 15 ++ .../_datasource-schema.ts | 15 ++ .../p0-0-simplest-defaults/_macro-abnormal.ts | 72 +++++++++ .../p0-0-simplest-defaults/_macro-normal.ts | 81 ++++++++++ .../abnormal-interpret.test.ts | 22 +++ .../abnormal-runtime.test.ts | 20 +++ .../normal-interpret.test.ts | 20 +++ .../normal-runtime.test.ts | 20 +++ .../README.md | 3 + .../_datasource-runtime.ts | 33 ++++ .../_datasource-schema.ts | 30 ++++ .../_macro-abnormal.ts | 96 ++++++++++++ .../_macro-normal.ts | 92 +++++++++++ .../abnormal-interpret.test.ts | 22 +++ .../abnormal-runtime.test.ts | 20 +++ .../normal-interpret.test.ts | 20 +++ .../normal-runtime.test.ts | 20 +++ .../test/scenes/p0-0-url-params/README.md | 3 + .../p0-0-url-params/_datasource-runtime.ts | 13 ++ .../p0-0-url-params/_datasource-schema.ts | 13 ++ .../scenes/p0-0-url-params/_macro-normal.ts | 72 +++++++++ .../p0-0-url-params/normal-interpret.test.ts | 20 +++ .../p0-0-url-params/normal-runtime.test.ts | 20 +++ .../p0-1-custom-response-status/README.md | 26 ++++ .../_datasource-runtime.ts | 30 ++++ .../_datasource-schema.ts | 35 +++++ .../_macro-abnormal.ts | 95 ++++++++++++ .../_macro-normal.ts | 96 ++++++++++++ .../abnormal-interpret.test.ts | 21 +++ .../abnormal-runtime.test.ts | 20 +++ .../normal-interpret.test.ts | 20 +++ .../normal-runtime.test.ts | 20 +++ .../snapshots/abnormal-interpret.test.ts.md | 20 +++ .../snapshots/abnormal-interpret.test.ts.snap | Bin 0 -> 274 bytes .../snapshots/abnormal-runtime.test.ts.md | 20 +++ .../snapshots/abnormal-runtime.test.ts.snap | Bin 0 -> 274 bytes .../README.md | 3 + .../_datasource-runtime.ts | 21 +++ .../_datasource-schema.ts | 24 +++ .../_macro-abnormal.ts | 78 ++++++++++ .../_macro-normal.ts | 81 ++++++++++ .../abnormal-interpret.test.ts | 22 +++ .../abnormal-runtime.test.ts | 20 +++ .../normal-interpret.test.ts | 20 +++ .../normal-runtime.test.ts | 20 +++ .../README.md | 3 + .../_datasource-runtime.ts | 30 ++++ .../_datasource-schema.ts | 35 +++++ .../_macro-abnormal.ts | 95 ++++++++++++ .../_macro-normal.ts | 96 ++++++++++++ .../abnormal-interpret.test.ts | 21 +++ .../abnormal-runtime.test.ts | 20 +++ .../normal-interpret.test.ts | 20 +++ .../normal-runtime.test.ts | 20 +++ .../snapshots/abnormal-interpret.test.ts.md | 20 +++ .../snapshots/abnormal-interpret.test.ts.snap | Bin 0 -> 274 bytes .../snapshots/abnormal-runtime.test.ts.md | 20 +++ .../snapshots/abnormal-runtime.test.ts.snap | Bin 0 -> 274 bytes .../README.md | 3 + .../_datasource-runtime.ts | 32 ++++ .../_datasource-schema.ts | 38 +++++ .../_macro-normal.ts | 108 +++++++++++++ .../normal-interpret.test.ts | 20 +++ .../normal-runtime.test.ts | 20 +++ packages/datasource-engine/tsconfig.json | 68 +++++++++ packages/datasource-handlers/.eslintignore | 1 + packages/datasource-handlers/.eslintrc.js | 7 + packages/datasource-handlers/.prettierrc.js | 4 + packages/datasource-handlers/lerna.json | 5 + packages/datasource-handlers/package.json | 9 ++ .../packages/fetch/es/index.d.ts | 2 + .../packages/fetch/es/index.js | 25 +++ .../packages/fetch/package.json | 29 ++++ .../packages/fetch/src/index.ts | 20 +++ .../packages/fetch/tsconfig.json | 10 ++ .../packages/mopen/es/index.d.ts | 5 + .../packages/mopen/es/index.js | 26 ++++ .../packages/mopen/package.json | 29 ++++ .../packages/mopen/src/index.ts | 33 ++++ .../packages/mopen/tsconfig.json | 10 ++ .../packages/mtop/es/index.d.ts | 6 + .../packages/mtop/es/index.js | 35 +++++ .../packages/mtop/package.json | 29 ++++ .../packages/mtop/src/index.ts | 26 ++++ .../packages/mtop/src/typings.d.ts | 11 ++ .../packages/mtop/tsconfig.json | 10 ++ .../packages/universalMtop/es/index.d.ts | 5 + .../packages/universalMtop/es/index.js | 23 +++ .../packages/universalMtop/package.json | 29 ++++ .../packages/universalMtop/src/index.ts | 29 ++++ .../packages/universalMtop/tsconfig.json | 10 ++ .../packages/urlParams/es/index.d.ts | 2 + .../packages/urlParams/es/index.js | 21 +++ .../packages/urlParams/package.json | 29 ++++ .../packages/urlParams/src/index.ts | 15 ++ .../packages/urlParams/tsconfig.json | 10 ++ packages/datasource-handlers/tsconfig.json | 67 ++++++++ 126 files changed, 3470 insertions(+) create mode 100644 packages/datasource-engine/.eslintignore create mode 100644 packages/datasource-engine/.eslintrc.js create mode 100644 packages/datasource-engine/.gitignore create mode 100644 packages/datasource-engine/.prettierrc.js create mode 100644 packages/datasource-engine/CHANGELOG.md create mode 100644 packages/datasource-engine/ava.config.js create mode 100644 packages/datasource-engine/interpret.d.ts create mode 100644 packages/datasource-engine/interpret.js create mode 100644 packages/datasource-engine/package.json create mode 100644 packages/datasource-engine/readme.md create mode 100644 packages/datasource-engine/runtime.d.ts create mode 100644 packages/datasource-engine/runtime.js create mode 100644 packages/datasource-engine/src/core/RuntimeDataSourceItem.ts create mode 100644 packages/datasource-engine/src/core/adapter.ts create mode 100644 packages/datasource-engine/src/core/index.ts create mode 100644 packages/datasource-engine/src/core/reloadDataSourceFactory.ts create mode 100644 packages/datasource-engine/src/helpers/index.ts create mode 100644 packages/datasource-engine/src/index.ts create mode 100644 packages/datasource-engine/src/interpret/DataSourceEngineFactory.ts create mode 100644 packages/datasource-engine/src/interpret/index.ts create mode 100644 packages/datasource-engine/src/runtime/RuntimeDataSourceEngineFactory.ts create mode 100644 packages/datasource-engine/src/runtime/index.ts create mode 100644 packages/datasource-engine/src/typings.d.ts create mode 100644 packages/datasource-engine/src/utils.ts create mode 100644 packages/datasource-engine/test/_helpers/bind-runtime-context.ts create mode 100644 packages/datasource-engine/test/_helpers/delay.ts create mode 100644 packages/datasource-engine/test/_helpers/index.ts create mode 100644 packages/datasource-engine/test/_helpers/mock-context.ts create mode 100644 packages/datasource-engine/test/scenes/p0-0-simplest-defaults/README.md create mode 100644 packages/datasource-engine/test/scenes/p0-0-simplest-defaults/_datasource-runtime.ts create mode 100644 packages/datasource-engine/test/scenes/p0-0-simplest-defaults/_datasource-schema.ts create mode 100644 packages/datasource-engine/test/scenes/p0-0-simplest-defaults/_macro-abnormal.ts create mode 100644 packages/datasource-engine/test/scenes/p0-0-simplest-defaults/_macro-normal.ts create mode 100644 packages/datasource-engine/test/scenes/p0-0-simplest-defaults/abnormal-interpret.test.ts create mode 100644 packages/datasource-engine/test/scenes/p0-0-simplest-defaults/abnormal-runtime.test.ts create mode 100644 packages/datasource-engine/test/scenes/p0-0-simplest-defaults/normal-interpret.test.ts create mode 100644 packages/datasource-engine/test/scenes/p0-0-simplest-defaults/normal-runtime.test.ts create mode 100644 packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/README.md create mode 100644 packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/_datasource-runtime.ts create mode 100644 packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/_datasource-schema.ts create mode 100644 packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/_macro-abnormal.ts create mode 100644 packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/_macro-normal.ts create mode 100644 packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/abnormal-interpret.test.ts create mode 100644 packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/abnormal-runtime.test.ts create mode 100644 packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/normal-interpret.test.ts create mode 100644 packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/normal-runtime.test.ts create mode 100644 packages/datasource-engine/test/scenes/p0-0-url-params/README.md create mode 100644 packages/datasource-engine/test/scenes/p0-0-url-params/_datasource-runtime.ts create mode 100644 packages/datasource-engine/test/scenes/p0-0-url-params/_datasource-schema.ts create mode 100644 packages/datasource-engine/test/scenes/p0-0-url-params/_macro-normal.ts create mode 100644 packages/datasource-engine/test/scenes/p0-0-url-params/normal-interpret.test.ts create mode 100644 packages/datasource-engine/test/scenes/p0-0-url-params/normal-runtime.test.ts create mode 100644 packages/datasource-engine/test/scenes/p0-1-custom-response-status/README.md create mode 100644 packages/datasource-engine/test/scenes/p0-1-custom-response-status/_datasource-runtime.ts create mode 100644 packages/datasource-engine/test/scenes/p0-1-custom-response-status/_datasource-schema.ts create mode 100644 packages/datasource-engine/test/scenes/p0-1-custom-response-status/_macro-abnormal.ts create mode 100644 packages/datasource-engine/test/scenes/p0-1-custom-response-status/_macro-normal.ts create mode 100644 packages/datasource-engine/test/scenes/p0-1-custom-response-status/abnormal-interpret.test.ts create mode 100644 packages/datasource-engine/test/scenes/p0-1-custom-response-status/abnormal-runtime.test.ts create mode 100644 packages/datasource-engine/test/scenes/p0-1-custom-response-status/normal-interpret.test.ts create mode 100644 packages/datasource-engine/test/scenes/p0-1-custom-response-status/normal-runtime.test.ts create mode 100644 packages/datasource-engine/test/scenes/p0-1-custom-response-status/snapshots/abnormal-interpret.test.ts.md create mode 100644 packages/datasource-engine/test/scenes/p0-1-custom-response-status/snapshots/abnormal-interpret.test.ts.snap create mode 100644 packages/datasource-engine/test/scenes/p0-1-custom-response-status/snapshots/abnormal-runtime.test.ts.md create mode 100644 packages/datasource-engine/test/scenes/p0-1-custom-response-status/snapshots/abnormal-runtime.test.ts.snap create mode 100644 packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/README.md create mode 100644 packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/_datasource-runtime.ts create mode 100644 packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/_datasource-schema.ts create mode 100644 packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/_macro-abnormal.ts create mode 100644 packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/_macro-normal.ts create mode 100644 packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/abnormal-interpret.test.ts create mode 100644 packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/abnormal-runtime.test.ts create mode 100644 packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/normal-interpret.test.ts create mode 100644 packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/normal-runtime.test.ts create mode 100644 packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/README.md create mode 100644 packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/_datasource-runtime.ts create mode 100644 packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/_datasource-schema.ts create mode 100644 packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/_macro-abnormal.ts create mode 100644 packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/_macro-normal.ts create mode 100644 packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/abnormal-interpret.test.ts create mode 100644 packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/abnormal-runtime.test.ts create mode 100644 packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/normal-interpret.test.ts create mode 100644 packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/normal-runtime.test.ts create mode 100644 packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/snapshots/abnormal-interpret.test.ts.md create mode 100644 packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/snapshots/abnormal-interpret.test.ts.snap create mode 100644 packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/snapshots/abnormal-runtime.test.ts.md create mode 100644 packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/snapshots/abnormal-runtime.test.ts.snap create mode 100644 packages/datasource-engine/test/scenes/p1-1-shouldfetch-control-request/README.md create mode 100644 packages/datasource-engine/test/scenes/p1-1-shouldfetch-control-request/_datasource-runtime.ts create mode 100644 packages/datasource-engine/test/scenes/p1-1-shouldfetch-control-request/_datasource-schema.ts create mode 100644 packages/datasource-engine/test/scenes/p1-1-shouldfetch-control-request/_macro-normal.ts create mode 100644 packages/datasource-engine/test/scenes/p1-1-shouldfetch-control-request/normal-interpret.test.ts create mode 100644 packages/datasource-engine/test/scenes/p1-1-shouldfetch-control-request/normal-runtime.test.ts create mode 100644 packages/datasource-engine/tsconfig.json create mode 100644 packages/datasource-handlers/.eslintignore create mode 100644 packages/datasource-handlers/.eslintrc.js create mode 100644 packages/datasource-handlers/.prettierrc.js create mode 100644 packages/datasource-handlers/lerna.json create mode 100644 packages/datasource-handlers/package.json create mode 100644 packages/datasource-handlers/packages/fetch/es/index.d.ts create mode 100644 packages/datasource-handlers/packages/fetch/es/index.js create mode 100644 packages/datasource-handlers/packages/fetch/package.json create mode 100644 packages/datasource-handlers/packages/fetch/src/index.ts create mode 100644 packages/datasource-handlers/packages/fetch/tsconfig.json create mode 100644 packages/datasource-handlers/packages/mopen/es/index.d.ts create mode 100644 packages/datasource-handlers/packages/mopen/es/index.js create mode 100644 packages/datasource-handlers/packages/mopen/package.json create mode 100644 packages/datasource-handlers/packages/mopen/src/index.ts create mode 100644 packages/datasource-handlers/packages/mopen/tsconfig.json create mode 100644 packages/datasource-handlers/packages/mtop/es/index.d.ts create mode 100644 packages/datasource-handlers/packages/mtop/es/index.js create mode 100644 packages/datasource-handlers/packages/mtop/package.json create mode 100644 packages/datasource-handlers/packages/mtop/src/index.ts create mode 100644 packages/datasource-handlers/packages/mtop/src/typings.d.ts create mode 100644 packages/datasource-handlers/packages/mtop/tsconfig.json create mode 100644 packages/datasource-handlers/packages/universalMtop/es/index.d.ts create mode 100644 packages/datasource-handlers/packages/universalMtop/es/index.js create mode 100644 packages/datasource-handlers/packages/universalMtop/package.json create mode 100644 packages/datasource-handlers/packages/universalMtop/src/index.ts create mode 100644 packages/datasource-handlers/packages/universalMtop/tsconfig.json create mode 100644 packages/datasource-handlers/packages/urlParams/es/index.d.ts create mode 100644 packages/datasource-handlers/packages/urlParams/es/index.js create mode 100644 packages/datasource-handlers/packages/urlParams/package.json create mode 100644 packages/datasource-handlers/packages/urlParams/src/index.ts create mode 100644 packages/datasource-handlers/packages/urlParams/tsconfig.json create mode 100644 packages/datasource-handlers/tsconfig.json diff --git a/packages/datasource-engine/.eslintignore b/packages/datasource-engine/.eslintignore new file mode 100644 index 000000000..30bc16279 --- /dev/null +++ b/packages/datasource-engine/.eslintignore @@ -0,0 +1 @@ +/node_modules \ No newline at end of file diff --git a/packages/datasource-engine/.eslintrc.js b/packages/datasource-engine/.eslintrc.js new file mode 100644 index 000000000..b33327802 --- /dev/null +++ b/packages/datasource-engine/.eslintrc.js @@ -0,0 +1,7 @@ +module.exports = { + extends: '../../.eslintrc.js', + rules: { + '@typescript-eslint/no-parameter-properties': 1, + 'no-param-reassign': 0 + }, +}; diff --git a/packages/datasource-engine/.gitignore b/packages/datasource-engine/.gitignore new file mode 100644 index 000000000..207b42eba --- /dev/null +++ b/packages/datasource-engine/.gitignore @@ -0,0 +1,6 @@ +/node_modules/ +*.log +.DS_Store +/es/ +/lib/ +/dist \ No newline at end of file diff --git a/packages/datasource-engine/.prettierrc.js b/packages/datasource-engine/.prettierrc.js new file mode 100644 index 000000000..d2db80ead --- /dev/null +++ b/packages/datasource-engine/.prettierrc.js @@ -0,0 +1,4 @@ +module.exports = { + singleQuote: true, + trailingComma: 'always', +}; diff --git a/packages/datasource-engine/CHANGELOG.md b/packages/datasource-engine/CHANGELOG.md new file mode 100644 index 000000000..c43546b6a --- /dev/null +++ b/packages/datasource-engine/CHANGELOG.md @@ -0,0 +1,30 @@ +# Change Log + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + + +## [0.1.14](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-datasource-engine@0.1.13...@ali/lowcode-datasource-engine@0.1.14) (2020-09-29) + + + + +**Note:** Version bump only for package @ali/lowcode-datasource-engine + + +## [0.1.13](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/compare/@ali/lowcode-datasource-engine@0.1.12...@ali/lowcode-datasource-engine@0.1.13) (2020-09-28) + + + + +**Note:** Version bump only for package @ali/lowcode-datasource-engine + + +## 0.1.12 (2020-09-28) + + +### Features + +* 🎸 按 826 对齐结论调整出码和数据源引擎 ([b9a562e](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/b9a562e)) +* 🎸 添加数据源引擎 ([624e2f8](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/624e2f8)) +* 🎸 与国凯的数据源保持一致,将 urlParams 所需的 search 参数直接传入 ([19fabc1](https://gitlab.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/commit/19fabc1)) diff --git a/packages/datasource-engine/ava.config.js b/packages/datasource-engine/ava.config.js new file mode 100644 index 000000000..987ecb184 --- /dev/null +++ b/packages/datasource-engine/ava.config.js @@ -0,0 +1,8 @@ +export default { + babel: { + compileEnhancements: false, + }, + files: ['./test/core/*.ts', './test/scenes/**/*.test.ts'], + require: ['ts-node/register/transpile-only'], + extensions: ['ts'], +}; diff --git a/packages/datasource-engine/interpret.d.ts b/packages/datasource-engine/interpret.d.ts new file mode 100644 index 000000000..b37fce092 --- /dev/null +++ b/packages/datasource-engine/interpret.d.ts @@ -0,0 +1 @@ +export { create } from './dist/interpret'; diff --git a/packages/datasource-engine/interpret.js b/packages/datasource-engine/interpret.js new file mode 100644 index 000000000..42c42028e --- /dev/null +++ b/packages/datasource-engine/interpret.js @@ -0,0 +1 @@ +module.exports = require('./dist/interpret'); diff --git a/packages/datasource-engine/package.json b/packages/datasource-engine/package.json new file mode 100644 index 000000000..99c775919 --- /dev/null +++ b/packages/datasource-engine/package.json @@ -0,0 +1,39 @@ +{ + "name": "@ali/lowcode-datasource-engine", + "version": "1.0.1", + "main": "dist/index.js", + "files": [ + "dist", + "src", + "interpret*", + "runtime*" + ], + "scripts": { + "build": "rm -rf dist && tsc --outDir ./dist --module esnext", + "test": "ava", + "prepublishOnly": "npm run build" + }, + "typings": "dist/index.d.ts", + "dependencies": { + "@ali/build-success-types": "^0.1.2-alpha.35", + "typescript": "^3.9.7" + }, + "devDependencies": { + "@ali/datasource-engine-universal-mtop-handler": "1.0.0-alpha.2", + "@ali/datasource-engine-url-params-handler": "^1.0.0-alpha.3", + "@ali/lowcode-datasource-http-handler": "^1.0.0-alpha.1", + "@ali/lowcode-datasource-url-params-handler": "^1.0.0-alpha.3", + "@ali/ng-lc-types": "^1.0.0-r2009222d5o6k8r8", + "@ava/babel": "^1.0.1", + "@types/sinon": "^9.0.5", + "ava": "3.11.1", + "get-port": "^5.1.1", + "json5": "^2.1.3", + "sinon": "^9.0.3", + "ts-node": "^8.10.2", + "tslib": "^2.0.1" + }, + "publishConfig": { + "registry": "https://registry.npm.alibaba-inc.com" + } +} diff --git a/packages/datasource-engine/readme.md b/packages/datasource-engine/readme.md new file mode 100644 index 000000000..d5bcb84d6 --- /dev/null +++ b/packages/datasource-engine/readme.md @@ -0,0 +1,45 @@ +## 关于 @ali/lc-datasource-engine + +低代码引擎数据源核心代码 + +## doc + +[原理介绍](https://yuque.antfin-inc.com/docs/share/6ba9dab7-0712-4302-a5bb-b17d4a5f8505?# 《DataSource Engine》) + + +[fetch流程图](https://yuque.antfin-inc.com/docs/share/e9baef9a-3586-40fc-8708-eaeee0d7937e?# 《fetch 流程》) + + +## 使用 + +```ts +// 面向运行时渲染,直接给 schema +import { create } from '@ali/lowcode-datasource-engine/interpret'; + +// 面向出码,需要给处理过后的内容 +import { create } from '@ali/lowcode-datasource-engine/runtime'; + +// dataSource 可以是 schema 协议内容 或者是运行时的转化后的配置内容 (出码专用) + +// context 上下文(setState 为必选) +const dsf = create(dataSource, context, { + requestHandlersMap: { // 可选参数,以下内容为当前默认的内容 + urlParams: handlersMap.urlParams('?bar=1&test=2'), + mtop: mtophandlers, + }, +}); + + +console.log(dsf.dataSourceMap) // 符合集团协议的 datasourceMap https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#QUSn5 + +dsf.dataSourceMap['id'].load() // 加载 + +dsf.dataSourceMap['id'].status // 获取状态 + +dsf.dataSourceMap['id'].data // 获取数据 + +dsf.dataSourceMap['id'].error // 获取错误信息 + +dsf.reloadDataSource(); // 刷新所有数据源 + +``` diff --git a/packages/datasource-engine/runtime.d.ts b/packages/datasource-engine/runtime.d.ts new file mode 100644 index 000000000..61344f9b4 --- /dev/null +++ b/packages/datasource-engine/runtime.d.ts @@ -0,0 +1 @@ +export { create } from './dist/runtime'; diff --git a/packages/datasource-engine/runtime.js b/packages/datasource-engine/runtime.js new file mode 100644 index 000000000..28f19824a --- /dev/null +++ b/packages/datasource-engine/runtime.js @@ -0,0 +1 @@ +module.exports = require('./dist/runtime/index'); diff --git a/packages/datasource-engine/src/core/RuntimeDataSourceItem.ts b/packages/datasource-engine/src/core/RuntimeDataSourceItem.ts new file mode 100644 index 000000000..b2dff9bb1 --- /dev/null +++ b/packages/datasource-engine/src/core/RuntimeDataSourceItem.ts @@ -0,0 +1,144 @@ +import { + IRuntimeDataSource, + RuntimeDataSourceConfig, + RuntimeDataSourceStatus, + IRuntimeContext, + RequestHandler, + RuntimeOptionsConfig, + UrlParamsHandler, +} from '@ali/build-success-types'; + +class RuntimeDataSourceItem< + TParams extends Record = Record, + TResultData = unknown +> implements IRuntimeDataSource { + private _data?: TResultData; + + private _error?: Error; + + private _status = RuntimeDataSourceStatus.Initial; + + private _dataSourceConfig: RuntimeDataSourceConfig; + + private _request: + | RequestHandler<{ data: TResultData }> + | UrlParamsHandler; + + private _context: IRuntimeContext; + + private _options?: RuntimeOptionsConfig; + + constructor( + dataSourceConfig: RuntimeDataSourceConfig, + request: + | RequestHandler<{ data: TResultData }> + | UrlParamsHandler, + context: IRuntimeContext, + ) { + this._dataSourceConfig = dataSourceConfig; + this._request = request; + this._context = context; + } + + get data() { + return this._data; + } + + get error() { + return this._error; + } + + get status() { + return this._status; + } + + public async load(params?: TParams) { + if (!this._dataSourceConfig) return; + // 考虑没有绑定对应的 handler 的情况 + if (!this._request) { + throw new Error(`no ${this._dataSourceConfig.type} handler provide`); + } + + // TODO: urlParams 有没有更好的处理方式 + if (this._dataSourceConfig.type === 'urlParams') { + const response = await (this._request as UrlParamsHandler)( + this._context, + ); + this._context.setState({ + [this._dataSourceConfig.id]: response, + }); + + this._data = response; + this._status = RuntimeDataSourceStatus.Loaded; + return response; + } + + if (!this._dataSourceConfig.options) { + throw new Error(`${this._dataSourceConfig.id} has no options`); + } + + if (typeof this._dataSourceConfig.options === 'function') { + this._options = this._dataSourceConfig.options(); + } + + // 考虑转换之后是 null 的场景 + if (!this._options) { + throw new Error(`${this._dataSourceConfig.id} options transform error`); + } + + // 临时变量存,每次可能结果不一致,不做缓存 + let shouldFetch = true; + + if (this._dataSourceConfig.shouldFetch) { + if (typeof this._dataSourceConfig.shouldFetch === 'function') { + shouldFetch = this._dataSourceConfig.shouldFetch(); + } else if (typeof this._dataSourceConfig.shouldFetch === 'boolean') { + shouldFetch = this._dataSourceConfig.shouldFetch; + } + } + + if (!shouldFetch) { + this._status = RuntimeDataSourceStatus.Error; + this._error = new Error( + `the ${this._dataSourceConfig.id} request should not fetch, please check the condition`, + ); + return; + } + + // willFetch + this._dataSourceConfig.willFetch!(); + + // 约定如果 params 有内容,直接做替换,如果没有就用默认的 options 的 + if (params && this._options) { + this._options.params = params; + } + + const dataHandler = this._dataSourceConfig.dataHandler!; + const { errorHandler } = this._dataSourceConfig; + + // 调用实际的请求,获取到对应的数据和状态后赋值给当前的 dataSource + try { + this._status = RuntimeDataSourceStatus.Loading; + + // _context 会给传,但是用不用由 handler 说了算 + const result = await (this._request as RequestHandler<{ + data: TResultData; + }>)(this._options, this._context).then(dataHandler, errorHandler); + + // setState + this._context.setState({ + [this._dataSourceConfig.id]: result, + }); + // 结果赋值 + this._data = result; + this._status = RuntimeDataSourceStatus.Loaded; + return this._data; + } catch (error) { + this._error = error; + this._status = RuntimeDataSourceStatus.Error; + throw error; + } + } +} + +export { RuntimeDataSourceItem }; diff --git a/packages/datasource-engine/src/core/adapter.ts b/packages/datasource-engine/src/core/adapter.ts new file mode 100644 index 000000000..b1274b6ae --- /dev/null +++ b/packages/datasource-engine/src/core/adapter.ts @@ -0,0 +1,66 @@ +import { + transformFunction, + getRuntimeValueFromConfig, + getRuntimeJsValue, + buildOptions, + buildShouldFetch, +} from './../utils'; +// 将不同渠道给的 schema 转为 runtime 需要的类型 + +import { + DataSource, + IPageContext, + DataSourceConfig, + RuntimeDataSourceConfig, + DataSourceMap, +} from '@ali/build-success-types'; +import { defaultDataHandler, defaultWillFetch } from '../helpers'; + +const adapt2Runtime = (dataSource: DataSource, context: IPageContext) => { + const { + list: interpretConfigList, + dataHandler: interpretDataHandler, + } = dataSource; + const dataHandler: (dataMap?: DataSourceMap) => void = + interpretDataHandler && + interpretDataHandler.compiled && + transformFunction(interpretDataHandler.compiled, context); + + // 为空判断 + if (!interpretConfigList || !interpretConfigList.length) { + return { + list: [], + dataHandler, + }; + } + const list: RuntimeDataSourceConfig[] = interpretConfigList.map( + (el: DataSourceConfig) => { + return { + id: el.id, + isInit: + getRuntimeValueFromConfig('boolean', el.isInit, context) || true, // 默认 true + isSync: + getRuntimeValueFromConfig('boolean', el.isSync, context) || false, // 默认 false + type: el.type || 'fetch', + willFetch: el.willFetch + ? getRuntimeJsValue(el.willFetch, context) + : defaultWillFetch, + shouldFetch: buildShouldFetch(el, context), + dataHandler: el.dataHandler + ? getRuntimeJsValue(el.dataHandler, context) + : defaultDataHandler, + errorHandler: el.errorHandler + ? getRuntimeJsValue(el.errorHandler, context) + : undefined, + options: buildOptions(el, context), + }; + }, + ); + + return { + list, + dataHandler, + }; +}; + +export { adapt2Runtime }; diff --git a/packages/datasource-engine/src/core/index.ts b/packages/datasource-engine/src/core/index.ts new file mode 100644 index 000000000..846867d09 --- /dev/null +++ b/packages/datasource-engine/src/core/index.ts @@ -0,0 +1,2 @@ +export { RuntimeDataSourceItem } from './RuntimeDataSourceItem'; +export { adapt2Runtime } from './adapter'; diff --git a/packages/datasource-engine/src/core/reloadDataSourceFactory.ts b/packages/datasource-engine/src/core/reloadDataSourceFactory.ts new file mode 100644 index 000000000..ac8776341 --- /dev/null +++ b/packages/datasource-engine/src/core/reloadDataSourceFactory.ts @@ -0,0 +1,64 @@ +import { + RuntimeDataSource, + DataSourceMap, + RuntimeDataSourceConfig, +} from '@ali/build-success-types'; + +export const reloadDataSourceFactory = ( + dataSource: RuntimeDataSource, + dataSourceMap: DataSourceMap, +) => async () => { + const allAsyncLoadings: Array> = []; + + // TODO: 那么,如果有新的类型过来,这个地方怎么处理??? + // 单独处理 urlParams 类型的 + dataSource.list + .filter( + (el: RuntimeDataSourceConfig) => el.type === 'urlParams' && + (typeof el.isInit === 'boolean' ? el.isInit : true), + ) + .forEach((el: RuntimeDataSourceConfig) => { + dataSourceMap[el.id].load(); + }); + + const remainRuntimeDataSourceList = dataSource.list.filter( + (el: RuntimeDataSourceConfig) => el.type !== 'urlParams', + ); + + // 处理并行 + for (const ds of remainRuntimeDataSourceList) { + if (!ds.options) { + continue; + } + if ( + // 需要考虑出码直接不传值的情况 + ds.isInit && + !ds.isSync + ) { + allAsyncLoadings.push(dataSourceMap[ds.id].load()); + } + } + + // 处理串行 + for (const ds of remainRuntimeDataSourceList) { + if (!ds.options) { + continue; + } + + if ( + // 需要考虑出码直接不传值的情况 + ds.isInit && + ds.isSync + ) { + // TODO: 我理解这个异常也应该吃掉的,待确认 + try { + // eslint-disable-next-line no-await-in-loop + await dataSourceMap[ds.id].load(); + } catch (e) { + console.error(e); + } + } + } + + await Promise.allSettled(allAsyncLoadings); +}; diff --git a/packages/datasource-engine/src/helpers/index.ts b/packages/datasource-engine/src/helpers/index.ts new file mode 100644 index 000000000..d13e747f6 --- /dev/null +++ b/packages/datasource-engine/src/helpers/index.ts @@ -0,0 +1,14 @@ +import { DataHandler } from '@ali/build-success-types'; + +function noop() {} + +// 默认的 dataSourceItem 的 dataHandler +export const defaultDataHandler: DataHandler = async (response: { + data: T; +}) => response.data; + +// 默认的 dataSourceItem 的 willFetch +export const defaultWillFetch = noop; + +// 默认的 dataSourceItem 的 shouldFetch +export const defaultShouldFetch = () => true; diff --git a/packages/datasource-engine/src/index.ts b/packages/datasource-engine/src/index.ts new file mode 100644 index 000000000..560958856 --- /dev/null +++ b/packages/datasource-engine/src/index.ts @@ -0,0 +1,4 @@ +import createInterpret from './interpret/DataSourceEngineFactory'; +import createRuntime from './runtime/RuntimeDataSourceEngineFactory'; + +export { createInterpret, createRuntime }; diff --git a/packages/datasource-engine/src/interpret/DataSourceEngineFactory.ts b/packages/datasource-engine/src/interpret/DataSourceEngineFactory.ts new file mode 100644 index 000000000..a31a5a095 --- /dev/null +++ b/packages/datasource-engine/src/interpret/DataSourceEngineFactory.ts @@ -0,0 +1,56 @@ +import { + IRuntimeContext, + IRuntimeDataSource, + DataSource, + RuntimeDataSourceConfig, + RuntimeDataSource, + RequestHandlersMap, +} from '@ali/build-success-types'; + +import { adapt2Runtime } from '../core/adapter'; +import { RuntimeDataSourceItem } from '../core/RuntimeDataSourceItem'; +import { reloadDataSourceFactory } from '../core/reloadDataSourceFactory'; + +// TODO: requestConfig mtop 默认的请求 config 怎么处理? +/** + * @param dataSource + * @param context + */ + +export default ( + dataSource: DataSource, + context: IRuntimeContext, + extraConfig: { + requestHandlersMap: RequestHandlersMap<{ data: unknown }>; + } = { + requestHandlersMap: {}, + }, +) => { + const { requestHandlersMap } = extraConfig; + + const runtimeDataSource: RuntimeDataSource = adapt2Runtime( + dataSource, + context, + ); + + const dataSourceMap = runtimeDataSource.list.reduce( + ( + prev: Record, + current: RuntimeDataSourceConfig, + ) => { + prev[current.id] = new RuntimeDataSourceItem( + current, + // type 协议默认值 fetch + requestHandlersMap[current.type || 'fetch'], + context, + ); + return prev; + }, + {}, + ); + + return { + dataSourceMap, + reloadDataSource: reloadDataSourceFactory(runtimeDataSource, dataSourceMap), + }; +}; diff --git a/packages/datasource-engine/src/interpret/index.ts b/packages/datasource-engine/src/interpret/index.ts new file mode 100644 index 000000000..e139eac42 --- /dev/null +++ b/packages/datasource-engine/src/interpret/index.ts @@ -0,0 +1,3 @@ +import createInterpret from './DataSourceEngineFactory'; + +export const create = createInterpret; diff --git a/packages/datasource-engine/src/runtime/RuntimeDataSourceEngineFactory.ts b/packages/datasource-engine/src/runtime/RuntimeDataSourceEngineFactory.ts new file mode 100644 index 000000000..2a98f1a14 --- /dev/null +++ b/packages/datasource-engine/src/runtime/RuntimeDataSourceEngineFactory.ts @@ -0,0 +1,69 @@ +/* eslint-disable no-nested-ternary */ +import { + IRuntimeContext, + IRuntimeDataSource, + RuntimeDataSourceConfig, + RuntimeDataSource, + RequestHandlersMap, +} from '@ali/build-success-types'; + +import { RuntimeDataSourceItem } from '../core'; +import { reloadDataSourceFactory } from '../core/reloadDataSourceFactory'; +import { + defaultDataHandler, + defaultShouldFetch, + defaultWillFetch, +} from '../helpers'; + +// TODO: requestConfig mtop 默认的请求 config 怎么处理? +/** + * @param dataSource + * @param context + */ +export default ( + dataSource: RuntimeDataSource, + context: IRuntimeContext, + extraConfig: { + requestHandlersMap: RequestHandlersMap<{ data: unknown }>; + } = { + requestHandlersMap: {}, + }, +) => { + const { requestHandlersMap } = extraConfig; + + // TODO: 对于出码类型,需要做一层数据兼容,给一些必要的值设置默认值,先兜底几个必要的 + dataSource.list.forEach((ds) => { + ds.isInit = ds.isInit || true; + ds.isSync = ds.isSync || false; + ds.shouldFetch = !ds.shouldFetch + ? defaultShouldFetch + : typeof ds.shouldFetch === 'function' + ? ds.shouldFetch.bind(context) + : ds.shouldFetch; + ds.willFetch = ds.willFetch ? ds.willFetch.bind(context) : defaultWillFetch; + ds.dataHandler = ds.dataHandler + ? ds.dataHandler.bind(context) + : defaultDataHandler; + }); + + const dataSourceMap = dataSource.list.reduce( + ( + prev: Record, + current: RuntimeDataSourceConfig, + ) => { + prev[current.id] = new RuntimeDataSourceItem( + current, + // type 协议默认值 fetch + requestHandlersMap[current.type || 'fetch'], + context, + ); + return prev; + }, + {}, + ); + + return { + dataSourceMap, + reloadDataSource: reloadDataSourceFactory(dataSource, dataSourceMap), + }; +}; diff --git a/packages/datasource-engine/src/runtime/index.ts b/packages/datasource-engine/src/runtime/index.ts new file mode 100644 index 000000000..8123c7207 --- /dev/null +++ b/packages/datasource-engine/src/runtime/index.ts @@ -0,0 +1,3 @@ +import createRuntime from './RuntimeDataSourceEngineFactory'; + +export const create = createRuntime; diff --git a/packages/datasource-engine/src/typings.d.ts b/packages/datasource-engine/src/typings.d.ts new file mode 100644 index 000000000..d82d18b87 --- /dev/null +++ b/packages/datasource-engine/src/typings.d.ts @@ -0,0 +1,3 @@ +declare module '@ali/mirror-io-client-mopen'; +declare module '@ali/mirror-io-client-mtop'; +declare module '@ali/mirror-io-client-universal-mtop'; diff --git a/packages/datasource-engine/src/utils.ts b/packages/datasource-engine/src/utils.ts new file mode 100644 index 000000000..f39171e96 --- /dev/null +++ b/packages/datasource-engine/src/utils.ts @@ -0,0 +1,139 @@ +/* eslint-disable no-new-func */ +import { + JSExpression, + IRuntimeContext, + CompositeValue, + JSFunction, + JSONObject, + isJSExpression, + DataSourceConfig, + isJSFunction, +} from '@ali/build-success-types'; + +export const transformExpression = (code: string, context: IRuntimeContext) => { + try { + return new Function(`return (${code})`).call(context); + } catch (error) { + console.error( + `transformExpression error, code is ${code}, context is ${context}, error is ${error}`, + ); + } +}; + +export const transformFunction = (code: string, context: IRuntimeContext) => { + try { + return new Function(`return (${code})`).call(context).bind(context); + } catch (error) { + console.error( + `transformFunction error, code is ${code}, context is ${context}, error is ${error}`, + ); + } +}; + +export const transformBoolStr = (str: string) => { + return str !== 'false'; +}; + +export const getRuntimeJsValue = ( + value: JSExpression | JSFunction, + context: IRuntimeContext, +) => { + if (!['JSExpression', 'JSFunction'].includes(value.type)) { + console.error(`translate error, value is ${JSON.stringify(value)}`); + return ''; + } + const code = value.compiled || value.value; + return value.type === 'JSFunction' + ? transformFunction(code, context) + : transformExpression(code, context); +}; + +export const getRuntimeBaseValue = (type: string, value: any) => { + switch (type) { + case 'string': + return `${value}`; + case 'boolean': + return typeof value === 'string' + ? transformBoolStr(value as string) + : value; + case 'number': + return Number(value); + default: + return value; + } +}; + +export const getRuntimeValueFromConfig = ( + type: string, + value: CompositeValue, + context: IRuntimeContext, +) => { + if (!value) return undefined; + if (isJSExpression(value) || isJSFunction(value)) { + return getRuntimeBaseValue(type, getRuntimeJsValue(value, context)); + } + return getRuntimeBaseValue(type, value); +}; + +export const buildJsonObj = ( + params: JSONObject | JSExpression, + context: IRuntimeContext, +) => { + const result: Record = {}; + if (isJSExpression(params)) { + return transformExpression(params.value, context); + } + Object.keys(params).forEach((key: string) => { + const currentParam: any = params[key]; + if (isJSExpression(currentParam)) { + result[key] = transformExpression(currentParam.value, context); + } else { + result[key] = getRuntimeBaseValue(currentParam.type, currentParam.value); + } + }); + + return result; +}; + +export const buildShouldFetch = ( + ds: DataSourceConfig, + context: IRuntimeContext, +) => { + if (!ds.options || !ds.shouldFetch) { + return true; // 默认为 true + } + if (isJSExpression(ds.shouldFetch) || isJSFunction(ds.shouldFetch)) { + return getRuntimeJsValue(ds.shouldFetch, context); + } + + return getRuntimeBaseValue('boolean', ds.shouldFetch); +}; + +export const buildOptions = ( + ds: DataSourceConfig, + context: IRuntimeContext, +) => { + const { options } = ds; + if (!options) return undefined; + return function () { + return { + uri: getRuntimeValueFromConfig('string', options.uri, context), + params: options.params ? buildJsonObj(options.params, context) : {}, + method: options.method + ? getRuntimeValueFromConfig('string', options.method, context) + : 'GET', + isCors: options.isCors + ? getRuntimeValueFromConfig('boolean', options.isCors, context) + : true, + timeout: options.timeout + ? getRuntimeValueFromConfig('number', options.timeout, context) + : 5000, + headers: options.headers + ? buildJsonObj(options.headers, context) + : undefined, + v: options.v + ? getRuntimeValueFromConfig('string', options.v, context) + : '1.0', + }; + }; +}; diff --git a/packages/datasource-engine/test/_helpers/bind-runtime-context.ts b/packages/datasource-engine/test/_helpers/bind-runtime-context.ts new file mode 100644 index 000000000..d8c4d471e --- /dev/null +++ b/packages/datasource-engine/test/_helpers/bind-runtime-context.ts @@ -0,0 +1,25 @@ +export function bindRuntimeContext(x: T, ctx: U): T { + if (typeof x === 'function') { + return x.bind(ctx); + } + + if (typeof x !== 'object') { + return x; + } + + if (x === null) { + return null; + } + + if (Array.isArray(x)) { + return (x.map((item) => bindRuntimeContext(item, ctx)) as unknown) as T; + } + + const res = {} as Record; + + Object.entries(x).forEach(([k, v]) => { + res[k] = bindRuntimeContext(v, ctx); + }); + + return (res as unknown) as T; +} diff --git a/packages/datasource-engine/test/_helpers/delay.ts b/packages/datasource-engine/test/_helpers/delay.ts new file mode 100644 index 000000000..81b6039c3 --- /dev/null +++ b/packages/datasource-engine/test/_helpers/delay.ts @@ -0,0 +1,3 @@ +export async function delay(ms: number = 0) { + return new Promise((resolve) => setTimeout(resolve, ms)); +} diff --git a/packages/datasource-engine/test/_helpers/index.ts b/packages/datasource-engine/test/_helpers/index.ts new file mode 100644 index 000000000..3ef1ff216 --- /dev/null +++ b/packages/datasource-engine/test/_helpers/index.ts @@ -0,0 +1,3 @@ +export * from './mock-context'; +export * from './delay'; +export * from './bind-runtime-context'; diff --git a/packages/datasource-engine/test/_helpers/mock-context.ts b/packages/datasource-engine/test/_helpers/mock-context.ts new file mode 100644 index 000000000..f602489de --- /dev/null +++ b/packages/datasource-engine/test/_helpers/mock-context.ts @@ -0,0 +1,50 @@ +import { IDataSourceEngine, IRuntimeContext } from '@ali/build-success-types'; + +export class MockContext> + implements IRuntimeContext { + private _dataSourceEngine: IDataSourceEngine; + + public constructor( + private _state: TState, + private _createDataSourceEngine: ( + context: IRuntimeContext + ) => IDataSourceEngine, + private _customMethods: Record any> = {} + ) { + this._dataSourceEngine = _createDataSourceEngine(this); + + // 自定义方法 + Object.assign(this, _customMethods); + } + + public get state() { + return this._state; + } + + public setState(state: Partial) { + this._state = { + ...this._state, + ...state, + }; + } + + public get dataSourceMap() { + return this._dataSourceEngine.dataSourceMap; + } + + public async reloadDataSource(): Promise { + this._dataSourceEngine.reloadDataSource(); + } + + public get page(): any { + throw new Error('this.page should not be accessed by datasource-engine'); + } + + public get component(): any { + throw new Error( + 'this.component should not be accessed by datasource-engine' + ); + } + + [customMethod: string]: any; +} diff --git a/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/README.md b/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/README.md new file mode 100644 index 000000000..e7ab03e28 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/README.md @@ -0,0 +1,3 @@ +# 关于此场景 + +这个是一个及其简单的场景 -- 就是直接调用 fetch,没有啥 dataHandler 之类的 diff --git a/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/_datasource-runtime.ts b/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/_datasource-runtime.ts new file mode 100644 index 000000000..ccb41e1f0 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/_datasource-runtime.ts @@ -0,0 +1,15 @@ +import { RuntimeDataSource } from '@ali/build-success-types'; + +// 这里仅仅是数据源部分的: +// @see: https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 +export const dataSource: RuntimeDataSource = { + list: [ + { + id: 'user', + type: 'fetch', + options: () => ({ + uri: 'https://mocks.alibaba-inc.com/user.json', + }), + }, + ], +}; diff --git a/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/_datasource-schema.ts b/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/_datasource-schema.ts new file mode 100644 index 000000000..7218c7864 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/_datasource-schema.ts @@ -0,0 +1,15 @@ +import { DataSource } from '@ali/build-success-types'; + +// 这里仅仅是数据源部分的 schema: +// @see: https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 +export const DATA_SOURCE_SCHEMA: DataSource = { + list: [ + { + id: 'user', + type: 'fetch', + options: { + uri: 'https://mocks.alibaba-inc.com/user.json', + }, + }, + ], +}; diff --git a/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/_macro-abnormal.ts b/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/_macro-abnormal.ts new file mode 100644 index 000000000..4a2297aa0 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/_macro-abnormal.ts @@ -0,0 +1,72 @@ +import { + DataSource, + IDataSourceEngine, + IRuntimeContext, + RuntimeDataSource, + RuntimeDataSourceStatus, +} from '@ali/build-success-types'; +import sinon from 'sinon'; + +import { delay, MockContext } from '../../_helpers'; +// import { DATA_SOURCE_SCHEMA } from './_datasource-schema'; + +import type { ExecutionContext, Macro } from 'ava'; +import type { SinonFakeTimers } from 'sinon'; + +export const abnormalScene: Macro<[ + { + create: ( + dataSource: any, + ctx: IRuntimeContext, + options: any + ) => IDataSourceEngine; + dataSource: RuntimeDataSource | DataSource; + } +]> = async ( + t: ExecutionContext<{ clock: SinonFakeTimers }>, + { create, dataSource }, +) => { + const { clock } = t.context; + const ERROR_MSG = 'test error'; + const fetchHandler = sinon.fake(async () => { + await delay(100); + throw new Error(ERROR_MSG); + }); + + const context = new MockContext>({}, (ctx) => create(dataSource, ctx, { + requestHandlersMap: { + fetch: fetchHandler, + }, + })); + + const setState = sinon.spy(context, 'setState'); + + // 一开始应该是初始状态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Initial); + + const loading = context.reloadDataSource(); + + await clock.tickAsync(50); + + // 中间应该有 loading 态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loading); + + await Promise.all([clock.runAllAsync(), loading]); + + // 最后应该失败了,error 状态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Error); + + // 检查数据源的数据 + t.deepEqual(context.dataSourceMap.user.data, undefined); + t.not(context.dataSourceMap.user.error, undefined); + t.regex(context.dataSourceMap.user.error!.message, new RegExp(ERROR_MSG)); + + // 检查状态数据 + t.assert(setState.notCalled); + t.deepEqual(context.state.user, undefined); + + // fetchHandler 不应该被调 + t.assert(fetchHandler.calledOnce); +}; + +abnormalScene.title = (providedTitle) => providedTitle || 'abnormal scene'; diff --git a/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/_macro-normal.ts b/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/_macro-normal.ts new file mode 100644 index 000000000..7115ab1eb --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/_macro-normal.ts @@ -0,0 +1,81 @@ +import { + DataSource, + IDataSourceEngine, + IRuntimeContext, + RuntimeDataSource, + RuntimeDataSourceStatus, +} from '@ali/build-success-types'; +import sinon from 'sinon'; + +import { delay, MockContext } from '../../_helpers'; +import { DATA_SOURCE_SCHEMA } from './_datasource-schema'; + +import type { ExecutionContext, Macro } from 'ava'; +import type { SinonFakeTimers } from 'sinon'; + +export const normalScene: Macro<[ + { + create: ( + dataSource: any, + ctx: IRuntimeContext, + options: any + ) => IDataSourceEngine; + dataSource: RuntimeDataSource | DataSource; + } +]> = async ( + t: ExecutionContext<{ clock: SinonFakeTimers }>, + { create, dataSource }, +) => { + const { clock } = t.context; + + const USER_DATA = { + name: 'Alice', + age: 18, + }; + + const fetchHandler = sinon.fake(async () => { + await delay(100); + return { data: USER_DATA }; + }); + + const context = new MockContext>({}, (ctx) => create(dataSource, ctx, { + requestHandlersMap: { + fetch: fetchHandler, + }, + })); + + const setState = sinon.spy(context, 'setState'); + + // 一开始应该是初始状态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Initial); + + const loading = context.reloadDataSource(); + + await clock.tickAsync(50); + + // 中间应该有 loading 态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loading); + + await Promise.all([clock.runAllAsync(), loading]); + + // 最后应该成功了,loaded 状态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loaded); + + // 检查数据源的数据 + t.deepEqual(context.dataSourceMap.user.data, USER_DATA); + t.deepEqual(context.dataSourceMap.user.error, undefined); + + // 检查状态数据 + t.assert(setState.calledOnce); + t.deepEqual(context.state.user, USER_DATA); + + // fetchHandler 应该被调用了一次 + t.assert(fetchHandler.calledOnce); + + const firstListItemOptions = DATA_SOURCE_SCHEMA.list[0].options; + const fetchHandlerCallArgs = fetchHandler.firstCall.args[0]; + // 检查调用参数 + t.is(firstListItemOptions.uri, fetchHandlerCallArgs.uri); +}; + +normalScene.title = (providedTitle) => providedTitle || 'normal scene'; diff --git a/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/abnormal-interpret.test.ts b/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/abnormal-interpret.test.ts new file mode 100644 index 000000000..816523b10 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/abnormal-interpret.test.ts @@ -0,0 +1,22 @@ +import test, { ExecutionContext } from 'ava'; +import sinon from 'sinon'; + +import { create } from '../../../src/interpret'; + +import { DATA_SOURCE_SCHEMA } from './_datasource-schema'; +import { abnormalScene } from './_macro-abnormal'; + +import type { SinonFakeTimers } from 'sinon'; + +test.before((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock = sinon.useFakeTimers(); +}); + +test.after((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock.restore(); +}); + +test(abnormalScene, { + create, + dataSource: DATA_SOURCE_SCHEMA, +}); diff --git a/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/abnormal-runtime.test.ts b/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/abnormal-runtime.test.ts new file mode 100644 index 000000000..c338af3b1 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/abnormal-runtime.test.ts @@ -0,0 +1,20 @@ +import test, { ExecutionContext } from 'ava'; +import sinon, { SinonFakeTimers } from 'sinon'; + +import { create } from '../../../src/runtime'; + +import { dataSource } from './_datasource-runtime'; +import { abnormalScene } from './_macro-abnormal'; + +test.before((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock = sinon.useFakeTimers(); +}); + +test.after((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock.restore(); +}); + +test(abnormalScene, { + create, + dataSource, +}); diff --git a/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/normal-interpret.test.ts b/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/normal-interpret.test.ts new file mode 100644 index 000000000..9dac84e8d --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/normal-interpret.test.ts @@ -0,0 +1,20 @@ +import test, { ExecutionContext } from 'ava'; +import sinon, { SinonFakeTimers } from 'sinon'; + +import { create } from '../../../src/interpret'; + +import { DATA_SOURCE_SCHEMA } from './_datasource-schema'; +import { normalScene } from './_macro-normal'; + +test.before((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock = sinon.useFakeTimers(); +}); + +test.after((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock.restore(); +}); + +test(normalScene, { + create, + dataSource: DATA_SOURCE_SCHEMA, +}); diff --git a/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/normal-runtime.test.ts b/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/normal-runtime.test.ts new file mode 100644 index 000000000..761979c30 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/normal-runtime.test.ts @@ -0,0 +1,20 @@ +import test, { ExecutionContext } from 'ava'; +import sinon, { SinonFakeTimers } from 'sinon'; + +import { create } from '../../../src/runtime'; + +import { dataSource } from './_datasource-runtime'; +import { normalScene } from './_macro-normal'; + +test.before((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock = sinon.useFakeTimers(); +}); + +test.after((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock.restore(); +}); + +test(normalScene, { + create, + dataSource, +}); diff --git a/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/README.md b/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/README.md new file mode 100644 index 000000000..3aa7d33e4 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/README.md @@ -0,0 +1,3 @@ +# 关于此场景 + +有些场景下,多个数据源之间有依赖关系,这时候可以将其都设置为 `isSync: true`, 这样这些数据源就会按配置面板的顺序进行串行调用。 diff --git a/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/_datasource-runtime.ts b/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/_datasource-runtime.ts new file mode 100644 index 000000000..09e244a38 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/_datasource-runtime.ts @@ -0,0 +1,33 @@ +import { RuntimeDataSource } from '@ali/build-success-types'; + +// 这里仅仅是数据源部分的: +// @see: https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 +export const dataSource: RuntimeDataSource = { + list: [ + { + id: 'user', + isInit: true, + type: 'fetch', + isSync: true, + options() { + return { + uri: 'https://mocks.alibaba-inc.com/user.json', + }; + }, + }, + { + id: 'orders', + isInit: true, + type: 'fetch', + isSync: true, + options() { + return { + uri: 'https://mocks.alibaba-inc.com/orders.json', + params: { + userId: this.state.user.id, + }, + }; + }, + }, + ], +}; diff --git a/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/_datasource-schema.ts b/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/_datasource-schema.ts new file mode 100644 index 000000000..e4e549ece --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/_datasource-schema.ts @@ -0,0 +1,30 @@ +import { DataSource } from '@ali/build-success-types'; + +// 这里仅仅是数据源部分的 schema: +// @see: https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 +export const DATA_SOURCE_SCHEMA: DataSource = { + list: [ + { + id: 'user', + isInit: true, + type: 'fetch', + isSync: true, + options: { + uri: 'https://mocks.alibaba-inc.com/user.json', + }, + }, + { + id: 'orders', + isInit: true, + type: 'fetch', + isSync: true, + options: { + uri: 'https://mocks.alibaba-inc.com/orders.json', + params: { + type: 'JSExpression', + value: '{ userId: this.state.user.id }', + }, + }, + }, + ], +}; diff --git a/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/_macro-abnormal.ts b/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/_macro-abnormal.ts new file mode 100644 index 000000000..fc0aaa0b3 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/_macro-abnormal.ts @@ -0,0 +1,96 @@ +import { + DataSource, + IDataSourceEngine, + IRuntimeContext, + RuntimeDataSource, + RuntimeDataSourceStatus, +} from '@ali/build-success-types'; +import sinon from 'sinon'; + +import { bindRuntimeContext, delay, MockContext } from '../../_helpers'; +import { DATA_SOURCE_SCHEMA } from './_datasource-schema'; + +import type { ExecutionContext, Macro } from 'ava'; +import type { SinonFakeTimers } from 'sinon'; + +export const abnormalScene: Macro<[ + { + create: ( + dataSource: any, + ctx: IRuntimeContext, + options: any + ) => IDataSourceEngine; + dataSource: RuntimeDataSource | DataSource; + } +]> = async ( + t: ExecutionContext<{ clock: SinonFakeTimers }>, + { create, dataSource }, +) => { + const { clock } = t.context; + + const USER_DATA = { + id: 9527, + name: 'Alice', + }; + const ERROR_MSG = 'test error'; + const fetchHandler = sinon.fake(async ({ uri }) => { + await delay(100); + if (/user/.test(uri)) { + return { data: USER_DATA }; + } else { + throw new Error(ERROR_MSG); + } + }); + + const context = new MockContext>({}, (ctx) => create(bindRuntimeContext(dataSource, ctx), ctx, { + requestHandlersMap: { + fetch: fetchHandler, + }, + })); + + const setState = sinon.spy(context, 'setState'); + + // 一开始应该是初始状态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Initial); + t.is(context.dataSourceMap.orders.status, RuntimeDataSourceStatus.Initial); + + const loading = context.reloadDataSource(); + + await clock.tickAsync(50); + + // 中间应该有 loading 态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loading); + + await clock.tickAsync(50); + + t.is(context.dataSourceMap.orders.status, RuntimeDataSourceStatus.Loading); + + await Promise.all([clock.runAllAsync(), loading]); + + // 最后 user 应该成功了,loaded + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loaded); + // 最后 orders 应该失败了,error 状态 + t.is(context.dataSourceMap.orders.status, RuntimeDataSourceStatus.Error); + + // 检查数据源的数据 + t.deepEqual(context.dataSourceMap.user.data, USER_DATA); + t.is(context.dataSourceMap.user.error, undefined); + t.deepEqual(context.dataSourceMap.orders.data, undefined); + t.not(context.dataSourceMap.orders.error, undefined); + t.regex(context.dataSourceMap.orders.error!.message, new RegExp(ERROR_MSG)); + + // 检查状态数据 + t.assert(setState.calledOnce); + t.deepEqual(context.state.user, USER_DATA); + t.is(context.state.orders, undefined); + + // fetchHandler 应该被调用了2次 + t.assert(fetchHandler.calledTwice); + + const firstListItemOptions = DATA_SOURCE_SCHEMA.list[0].options; + const fetchHandlerCallArgs = fetchHandler.firstCall.args[0]; + // 检查调用参数 + t.is(firstListItemOptions.uri, fetchHandlerCallArgs.uri); +}; + +abnormalScene.title = (providedTitle) => providedTitle || 'abnormal scene'; diff --git a/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/_macro-normal.ts b/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/_macro-normal.ts new file mode 100644 index 000000000..2587c08b3 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/_macro-normal.ts @@ -0,0 +1,92 @@ +import { + DataSource, + IDataSourceEngine, + IRuntimeContext, + RuntimeDataSource, + RuntimeDataSourceStatus, +} from '@ali/build-success-types'; +import sinon from 'sinon'; + +import { bindRuntimeContext, delay, MockContext } from '../../_helpers'; +import { DATA_SOURCE_SCHEMA } from './_datasource-schema'; + +import type { ExecutionContext, Macro } from 'ava'; +import type { SinonFakeTimers } from 'sinon'; + +export const normalScene: Macro<[ + { + create: ( + dataSource: any, + ctx: IRuntimeContext, + options: any + ) => IDataSourceEngine; + dataSource: RuntimeDataSource | DataSource; + } +]> = async ( + t: ExecutionContext<{ clock: SinonFakeTimers }>, + { create, dataSource }, +) => { + const { clock } = t.context; + + const USER_DATA = { + id: 9527, + name: 'Alice', + }; + + const ORDERS_DATA = [{ id: 123 }, { id: 456 }]; + + const fetchHandler = sinon.fake(async ({ uri }) => { + await delay(100); + return { data: /user/.test(uri) ? USER_DATA : ORDERS_DATA }; + }); + + const context = new MockContext>({}, (ctx) => create(bindRuntimeContext(dataSource, ctx), ctx, { + requestHandlersMap: { + fetch: fetchHandler, + }, + })); + + const setState = sinon.spy(context, 'setState'); + + // 一开始应该是初始状态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Initial); + t.is(context.dataSourceMap.orders.status, RuntimeDataSourceStatus.Initial); + + const loading = context.reloadDataSource(); + + await clock.tickAsync(50); + + // 中间应该有 loading 态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loading); + + await clock.tickAsync(50); + + t.is(context.dataSourceMap.orders.status, RuntimeDataSourceStatus.Loading); + + await Promise.all([clock.runAllAsync(), loading]); + + // 最后应该成功了,loaded 状态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loaded); + t.is(context.dataSourceMap.orders.status, RuntimeDataSourceStatus.Loaded); + + // 检查数据源的数据 + t.deepEqual(context.dataSourceMap.user.data, USER_DATA); + t.deepEqual(context.dataSourceMap.user.error, undefined); + t.deepEqual(context.dataSourceMap.orders.data, ORDERS_DATA); + t.deepEqual(context.dataSourceMap.orders.error, undefined); + + // 检查状态数据 + t.assert(setState.calledTwice); + t.deepEqual(context.state.user, USER_DATA); + t.deepEqual(context.state.orders, ORDERS_DATA); + + // fetchHandler 应该被调用了2次 + t.assert(fetchHandler.calledTwice); + + // 检查调用参数 + const firstListItemOptions = DATA_SOURCE_SCHEMA.list[0].options; + const fetchHandlerCallArgs = fetchHandler.firstCall.args[0]; + t.is(firstListItemOptions.uri, fetchHandlerCallArgs.uri); +}; + +normalScene.title = (providedTitle) => providedTitle || 'normal scene'; diff --git a/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/abnormal-interpret.test.ts b/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/abnormal-interpret.test.ts new file mode 100644 index 000000000..816523b10 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/abnormal-interpret.test.ts @@ -0,0 +1,22 @@ +import test, { ExecutionContext } from 'ava'; +import sinon from 'sinon'; + +import { create } from '../../../src/interpret'; + +import { DATA_SOURCE_SCHEMA } from './_datasource-schema'; +import { abnormalScene } from './_macro-abnormal'; + +import type { SinonFakeTimers } from 'sinon'; + +test.before((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock = sinon.useFakeTimers(); +}); + +test.after((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock.restore(); +}); + +test(abnormalScene, { + create, + dataSource: DATA_SOURCE_SCHEMA, +}); diff --git a/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/abnormal-runtime.test.ts b/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/abnormal-runtime.test.ts new file mode 100644 index 000000000..c338af3b1 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/abnormal-runtime.test.ts @@ -0,0 +1,20 @@ +import test, { ExecutionContext } from 'ava'; +import sinon, { SinonFakeTimers } from 'sinon'; + +import { create } from '../../../src/runtime'; + +import { dataSource } from './_datasource-runtime'; +import { abnormalScene } from './_macro-abnormal'; + +test.before((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock = sinon.useFakeTimers(); +}); + +test.after((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock.restore(); +}); + +test(abnormalScene, { + create, + dataSource, +}); diff --git a/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/normal-interpret.test.ts b/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/normal-interpret.test.ts new file mode 100644 index 000000000..9dac84e8d --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/normal-interpret.test.ts @@ -0,0 +1,20 @@ +import test, { ExecutionContext } from 'ava'; +import sinon, { SinonFakeTimers } from 'sinon'; + +import { create } from '../../../src/interpret'; + +import { DATA_SOURCE_SCHEMA } from './_datasource-schema'; +import { normalScene } from './_macro-normal'; + +test.before((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock = sinon.useFakeTimers(); +}); + +test.after((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock.restore(); +}); + +test(normalScene, { + create, + dataSource: DATA_SOURCE_SCHEMA, +}); diff --git a/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/normal-runtime.test.ts b/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/normal-runtime.test.ts new file mode 100644 index 000000000..761979c30 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/normal-runtime.test.ts @@ -0,0 +1,20 @@ +import test, { ExecutionContext } from 'ava'; +import sinon, { SinonFakeTimers } from 'sinon'; + +import { create } from '../../../src/runtime'; + +import { dataSource } from './_datasource-runtime'; +import { normalScene } from './_macro-normal'; + +test.before((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock = sinon.useFakeTimers(); +}); + +test.after((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock.restore(); +}); + +test(normalScene, { + create, + dataSource, +}); diff --git a/packages/datasource-engine/test/scenes/p0-0-url-params/README.md b/packages/datasource-engine/test/scenes/p0-0-url-params/README.md new file mode 100644 index 000000000..e7ab03e28 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-0-url-params/README.md @@ -0,0 +1,3 @@ +# 关于此场景 + +这个是一个及其简单的场景 -- 就是直接调用 fetch,没有啥 dataHandler 之类的 diff --git a/packages/datasource-engine/test/scenes/p0-0-url-params/_datasource-runtime.ts b/packages/datasource-engine/test/scenes/p0-0-url-params/_datasource-runtime.ts new file mode 100644 index 000000000..2f58b64e0 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-0-url-params/_datasource-runtime.ts @@ -0,0 +1,13 @@ +import { RuntimeDataSource } from '@ali/build-success-types'; + +// 这里仅仅是数据源部分的: +// @see: https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 +export const dataSource: RuntimeDataSource = { + list: [ + { + id: 'urlParams', + isInit: true, + type: 'urlParams', + }, + ], +}; diff --git a/packages/datasource-engine/test/scenes/p0-0-url-params/_datasource-schema.ts b/packages/datasource-engine/test/scenes/p0-0-url-params/_datasource-schema.ts new file mode 100644 index 000000000..9b00b9300 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-0-url-params/_datasource-schema.ts @@ -0,0 +1,13 @@ +import { DataSource } from '@ali/build-success-types'; + +// 这里仅仅是数据源部分的 schema: +// @see: https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 +export const DATA_SOURCE_SCHEMA: DataSource = { + list: [ + { + id: 'urlParams', + isInit: true, + type: 'urlParams', + }, + ], +}; diff --git a/packages/datasource-engine/test/scenes/p0-0-url-params/_macro-normal.ts b/packages/datasource-engine/test/scenes/p0-0-url-params/_macro-normal.ts new file mode 100644 index 000000000..4b0b9bc06 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-0-url-params/_macro-normal.ts @@ -0,0 +1,72 @@ +import { + DataSource, + IDataSourceEngine, + IRuntimeContext, + RuntimeDataSource, + RuntimeDataSourceStatus, +} from '@ali/build-success-types'; +import sinon from 'sinon'; + +import { MockContext } from '../../_helpers'; + +import type { ExecutionContext, Macro } from 'ava'; +import type { SinonFakeTimers } from 'sinon'; + +export const normalScene: Macro<[ + { + create: ( + dataSource: any, + ctx: IRuntimeContext, + options: any + ) => IDataSourceEngine; + dataSource: RuntimeDataSource | DataSource; + } +]> = async ( + t: ExecutionContext<{ clock: SinonFakeTimers }>, + { create, dataSource }, +) => { + const { clock } = t.context; + + const URL_PARAMS = { + name: 'Alice', + age: '18', + }; + + const urlParamsHandler = sinon.fake(async () => { + return URL_PARAMS; // TODO: 别的都是返回的套了一层 data 的,但是 urlParams 的为啥不一样? + }); + + const context = new MockContext>({}, (ctx) => create(dataSource, ctx, { + requestHandlersMap: { + urlParams: urlParamsHandler, + }, + })); + + const setState = sinon.spy(context, 'setState'); + + // 一开始应该是初始状态 + t.is(context.dataSourceMap.urlParams.status, RuntimeDataSourceStatus.Initial); + + const loading = context.reloadDataSource(); + + await Promise.all([clock.runAllAsync(), loading]); + + // 最后应该成功了,loaded 状态 + t.is(context.dataSourceMap.urlParams.status, RuntimeDataSourceStatus.Loaded); + + // 检查数据源的数据 + t.deepEqual(context.dataSourceMap.urlParams.data, URL_PARAMS); + t.deepEqual(context.dataSourceMap.urlParams.error, undefined); + + // 检查状态数据 + t.assert(setState.calledOnce); + t.deepEqual(context.state.urlParams, URL_PARAMS); + + // fetchHandler 应该被调用了一次 + t.assert(urlParamsHandler.calledOnce); + + // 检查调用参数 url 没有 options + t.deepEqual(urlParamsHandler.firstCall.args, [context]); +}; + +normalScene.title = (providedTitle) => providedTitle || 'normal scene'; diff --git a/packages/datasource-engine/test/scenes/p0-0-url-params/normal-interpret.test.ts b/packages/datasource-engine/test/scenes/p0-0-url-params/normal-interpret.test.ts new file mode 100644 index 000000000..9dac84e8d --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-0-url-params/normal-interpret.test.ts @@ -0,0 +1,20 @@ +import test, { ExecutionContext } from 'ava'; +import sinon, { SinonFakeTimers } from 'sinon'; + +import { create } from '../../../src/interpret'; + +import { DATA_SOURCE_SCHEMA } from './_datasource-schema'; +import { normalScene } from './_macro-normal'; + +test.before((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock = sinon.useFakeTimers(); +}); + +test.after((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock.restore(); +}); + +test(normalScene, { + create, + dataSource: DATA_SOURCE_SCHEMA, +}); diff --git a/packages/datasource-engine/test/scenes/p0-0-url-params/normal-runtime.test.ts b/packages/datasource-engine/test/scenes/p0-0-url-params/normal-runtime.test.ts new file mode 100644 index 000000000..761979c30 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-0-url-params/normal-runtime.test.ts @@ -0,0 +1,20 @@ +import test, { ExecutionContext } from 'ava'; +import sinon, { SinonFakeTimers } from 'sinon'; + +import { create } from '../../../src/runtime'; + +import { dataSource } from './_datasource-runtime'; +import { normalScene } from './_macro-normal'; + +test.before((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock = sinon.useFakeTimers(); +}); + +test.after((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock.restore(); +}); + +test(normalScene, { + create, + dataSource, +}); diff --git a/packages/datasource-engine/test/scenes/p0-1-custom-response-status/README.md b/packages/datasource-engine/test/scenes/p0-1-custom-response-status/README.md new file mode 100644 index 000000000..cccb18844 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-1-custom-response-status/README.md @@ -0,0 +1,26 @@ +# 关于此场景 + +这个是一个很常见的场景 -- 查出来的数据里面套的还有一层数据,可能有异常状态得需要处理下。 + +比如,期望的正常的数据应该是: + +```json +{ + "success": true, + "data": { + // ... + } +} +``` + +而异常场景下,服务端会返回: + +```json +{ + "success": false, + "message": "这是错误原因", + "code": "错误码" +} +``` + +-- 这时候期望有异常监控埋点。 diff --git a/packages/datasource-engine/test/scenes/p0-1-custom-response-status/_datasource-runtime.ts b/packages/datasource-engine/test/scenes/p0-1-custom-response-status/_datasource-runtime.ts new file mode 100644 index 000000000..756adeb83 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-1-custom-response-status/_datasource-runtime.ts @@ -0,0 +1,30 @@ +import { RuntimeDataSource } from '@ali/build-success-types'; + +// 这里仅仅是数据源部分的: +// @see: https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 +export const dataSource: RuntimeDataSource = { + list: [ + { + id: 'user', + isInit: true, + type: 'fetch', + options: () => ({ + uri: 'https://mocks.alibaba-inc.com/user.json', + }), + dataHandler: function dataHandler(response: any) { + const { data } = response; + if (!data) { + throw new Error('empty data!'); + } + + if (data.success) { + return data.data; + } + + this.recordError({ type: 'FETCH_ERROR', detail: data }); + + throw new Error(data.message); + }, + }, + ], +}; diff --git a/packages/datasource-engine/test/scenes/p0-1-custom-response-status/_datasource-schema.ts b/packages/datasource-engine/test/scenes/p0-1-custom-response-status/_datasource-schema.ts new file mode 100644 index 000000000..111cf641f --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-1-custom-response-status/_datasource-schema.ts @@ -0,0 +1,35 @@ +import { DataSource } from '@ali/build-success-types'; + +// 这里仅仅是数据源部分的 schema: +// @see: https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 +export const DATA_SOURCE_SCHEMA: DataSource = { + list: [ + { + id: 'user', + isInit: true, + type: 'fetch', + options: { + uri: 'https://mocks.alibaba-inc.com/user.json', + }, + dataHandler: { + type: 'JSFunction', + value: ` +function dataHandler(response){ + const { data } = response; + if (!data) { + throw new Error('empty data!'); + } + + if (data.success){ + return data.data; + } + + this.recordError({ type: 'FETCH_ERROR', detail: data }); + + throw new Error(data.message); +} +`, + }, + }, + ], +}; diff --git a/packages/datasource-engine/test/scenes/p0-1-custom-response-status/_macro-abnormal.ts b/packages/datasource-engine/test/scenes/p0-1-custom-response-status/_macro-abnormal.ts new file mode 100644 index 000000000..757aaba6e --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-1-custom-response-status/_macro-abnormal.ts @@ -0,0 +1,95 @@ +import { + DataSource, + IDataSourceEngine, + IRuntimeContext, + RuntimeDataSource, + RuntimeDataSourceStatus, +} from '@ali/build-success-types'; +import sinon from 'sinon'; + +import { bindRuntimeContext, delay, MockContext } from '../../_helpers'; +import { DATA_SOURCE_SCHEMA } from './_datasource-schema'; + +import type { ExecutionContext, Macro } from 'ava'; +import type { SinonFakeTimers } from 'sinon'; + +export const abnormalScene: Macro<[ + { + create: ( + dataSource: any, + ctx: IRuntimeContext, + options: any + ) => IDataSourceEngine; + dataSource: RuntimeDataSource | DataSource; + } +]> = async ( + t: ExecutionContext<{ clock: SinonFakeTimers }>, + { create, dataSource }, +) => { + const { clock } = t.context; + const ERROR_MSG = 'test error'; + const fetchHandler = sinon.fake(async () => { + await delay(100); + return { + data: { + success: false, + message: ERROR_MSG, + code: 'E_FOO', + }, + }; + }); + + const context = new MockContext>( + {}, + (ctx) => create(bindRuntimeContext(dataSource, ctx), ctx, { + requestHandlersMap: { + fetch: fetchHandler, + }, + }), + { + recordError() {}, + }, + ); + + const setState = sinon.spy(context, 'setState'); + const recordError = sinon.spy(context, 'recordError'); + + // 一开始应该是初始状态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Initial); + + const loading = context.reloadDataSource(); + + await clock.tickAsync(50); + + // 中间应该有 loading 态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loading); + + await Promise.all([clock.runAllAsync(), loading]); + + // 最后应该失败了,error 状态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Error); + + // 检查数据源的数据 + t.deepEqual(context.dataSourceMap.user.data, undefined); + t.not(context.dataSourceMap.user.error, undefined); + + t.regex(context.dataSourceMap.user.error!.message, new RegExp(ERROR_MSG)); + + // 检查状态数据 + t.assert(setState.notCalled); + t.deepEqual(context.state.user, undefined); + + // fetchHandler 应该被调用了一次 + t.assert(fetchHandler.calledOnce); + + // 检查调用参数 + const firstListItemOptions = DATA_SOURCE_SCHEMA.list[0].options; + const fetchHandlerCallArgs = fetchHandler.firstCall.args[0]; + t.is(firstListItemOptions.uri, fetchHandlerCallArgs.uri); + + // 埋点应该也会被调用 + t.assert(recordError.calledOnce); + t.snapshot(recordError.firstCall.args); +}; + +abnormalScene.title = (providedTitle) => providedTitle || 'abnormal scene'; diff --git a/packages/datasource-engine/test/scenes/p0-1-custom-response-status/_macro-normal.ts b/packages/datasource-engine/test/scenes/p0-1-custom-response-status/_macro-normal.ts new file mode 100644 index 000000000..d00fa39d9 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-1-custom-response-status/_macro-normal.ts @@ -0,0 +1,96 @@ +import { + DataSource, + IDataSourceEngine, + IRuntimeContext, + RuntimeDataSource, + RuntimeDataSourceStatus, +} from '@ali/build-success-types'; +import sinon from 'sinon'; + +import { bindRuntimeContext, delay, MockContext } from '../../_helpers'; +import { DATA_SOURCE_SCHEMA } from './_datasource-schema'; + +import type { ExecutionContext, Macro } from 'ava'; +import type { SinonFakeTimers } from 'sinon'; + +export const normalScene: Macro<[ + { + create: ( + dataSource: any, + ctx: IRuntimeContext, + options: any + ) => IDataSourceEngine; + dataSource: RuntimeDataSource | DataSource; + } +]> = async ( + t: ExecutionContext<{ clock: SinonFakeTimers }>, + { create, dataSource }, +) => { + const { clock } = t.context; + + const USER_DATA = { + name: 'Alice', + age: 18, + }; + + const fetchHandler = sinon.fake(async () => { + await delay(100); + return { + data: { + success: true, + data: USER_DATA, + }, + }; + }); + + const context = new MockContext>( + {}, + (ctx) => create(bindRuntimeContext(dataSource, ctx), ctx, { + requestHandlersMap: { + fetch: fetchHandler, + }, + }), + { + recordError() {}, + }, + ); + + const setState = sinon.spy(context, 'setState'); + const recordError = sinon.spy(context, 'recordError'); + + // 一开始应该是初始状态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Initial); + + const loading = context.reloadDataSource(); + + await clock.tickAsync(50); + + // 中间应该有 loading 态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loading); + + await Promise.all([clock.runAllAsync(), loading]); + + // 最后应该成功了,loaded 状态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loaded); + + // 检查数据源的数据 + t.deepEqual(context.dataSourceMap.user.data, USER_DATA); + t.deepEqual(context.dataSourceMap.user.error, undefined); + + // 检查状态数据 + t.assert(setState.calledOnce); + t.deepEqual(context.state.user, USER_DATA); + + // fetchHandler 应该被调用了一次 + t.assert(fetchHandler.calledOnce); + + // 检查调用参数 + const firstListItemOptions = DATA_SOURCE_SCHEMA.list[0].options; + const fetchHandlerCallArgs = fetchHandler.firstCall.args[0]; + t.is(firstListItemOptions.uri, fetchHandlerCallArgs.uri); + + // 埋点不应该被调用 + t.assert(recordError.notCalled); +}; + +normalScene.title = (providedTitle) => providedTitle || 'normal scene'; diff --git a/packages/datasource-engine/test/scenes/p0-1-custom-response-status/abnormal-interpret.test.ts b/packages/datasource-engine/test/scenes/p0-1-custom-response-status/abnormal-interpret.test.ts new file mode 100644 index 000000000..7f3169a50 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-1-custom-response-status/abnormal-interpret.test.ts @@ -0,0 +1,21 @@ +import test, { ExecutionContext } from 'ava'; +import sinon from 'sinon'; + +import { create } from '../../../src/interpret'; +import { DATA_SOURCE_SCHEMA } from './_datasource-schema'; +import { abnormalScene } from './_macro-abnormal'; + +import type { SinonFakeTimers } from 'sinon'; + +test.before((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock = sinon.useFakeTimers(); +}); + +test.after((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock.restore(); +}); + +test(abnormalScene, { + create, + dataSource: DATA_SOURCE_SCHEMA, +}); diff --git a/packages/datasource-engine/test/scenes/p0-1-custom-response-status/abnormal-runtime.test.ts b/packages/datasource-engine/test/scenes/p0-1-custom-response-status/abnormal-runtime.test.ts new file mode 100644 index 000000000..c338af3b1 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-1-custom-response-status/abnormal-runtime.test.ts @@ -0,0 +1,20 @@ +import test, { ExecutionContext } from 'ava'; +import sinon, { SinonFakeTimers } from 'sinon'; + +import { create } from '../../../src/runtime'; + +import { dataSource } from './_datasource-runtime'; +import { abnormalScene } from './_macro-abnormal'; + +test.before((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock = sinon.useFakeTimers(); +}); + +test.after((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock.restore(); +}); + +test(abnormalScene, { + create, + dataSource, +}); diff --git a/packages/datasource-engine/test/scenes/p0-1-custom-response-status/normal-interpret.test.ts b/packages/datasource-engine/test/scenes/p0-1-custom-response-status/normal-interpret.test.ts new file mode 100644 index 000000000..9dac84e8d --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-1-custom-response-status/normal-interpret.test.ts @@ -0,0 +1,20 @@ +import test, { ExecutionContext } from 'ava'; +import sinon, { SinonFakeTimers } from 'sinon'; + +import { create } from '../../../src/interpret'; + +import { DATA_SOURCE_SCHEMA } from './_datasource-schema'; +import { normalScene } from './_macro-normal'; + +test.before((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock = sinon.useFakeTimers(); +}); + +test.after((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock.restore(); +}); + +test(normalScene, { + create, + dataSource: DATA_SOURCE_SCHEMA, +}); diff --git a/packages/datasource-engine/test/scenes/p0-1-custom-response-status/normal-runtime.test.ts b/packages/datasource-engine/test/scenes/p0-1-custom-response-status/normal-runtime.test.ts new file mode 100644 index 000000000..761979c30 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-1-custom-response-status/normal-runtime.test.ts @@ -0,0 +1,20 @@ +import test, { ExecutionContext } from 'ava'; +import sinon, { SinonFakeTimers } from 'sinon'; + +import { create } from '../../../src/runtime'; + +import { dataSource } from './_datasource-runtime'; +import { normalScene } from './_macro-normal'; + +test.before((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock = sinon.useFakeTimers(); +}); + +test.after((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock.restore(); +}); + +test(normalScene, { + create, + dataSource, +}); diff --git a/packages/datasource-engine/test/scenes/p0-1-custom-response-status/snapshots/abnormal-interpret.test.ts.md b/packages/datasource-engine/test/scenes/p0-1-custom-response-status/snapshots/abnormal-interpret.test.ts.md new file mode 100644 index 000000000..5baeac319 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-1-custom-response-status/snapshots/abnormal-interpret.test.ts.md @@ -0,0 +1,20 @@ +# Snapshot report for `test/scenes/custom-response-status/abnormal-interpret.test.ts` + +The actual snapshot is saved in `abnormal-interpret.test.ts.snap`. + +Generated by [AVA](https://avajs.dev). + +## abnormal scene + +> Snapshot 1 + + [ + { + detail: { + code: 'E_FOO', + message: 'test error', + success: false, + }, + type: 'FETCH_ERROR', + }, + ] diff --git a/packages/datasource-engine/test/scenes/p0-1-custom-response-status/snapshots/abnormal-interpret.test.ts.snap b/packages/datasource-engine/test/scenes/p0-1-custom-response-status/snapshots/abnormal-interpret.test.ts.snap new file mode 100644 index 0000000000000000000000000000000000000000..6a9794bde2dd0e5ca70c5439fb81d97ebf958f80 GIT binary patch literal 274 zcmV+t0qy=lRzVZO*LU;00AE$#mvACW;1dyGU)(mBOn%LWD{g$bu21M ztYl<_vH1D<85p@37#SHDxfvO4V49fIfpjhqx56~C`6p$iCYLZW!I=UA0t}4242(<+ zjC_oYYk>+y7?~LuS%C^tQcDsua~K%;fqI!>qAVqq1*tF&x0`E-vq!vZP>_ER$U>Go zK>d$^m<8y1Jw`N3nK3M7MmIb;KLu_$t82WQzdxD^_T1Fs;>2{gBCe9u;u3|_qN4mF Ybd|-W$;m*)U_O%o0LO-s0c-&P0I>aR-2eap literal 0 HcmV?d00001 diff --git a/packages/datasource-engine/test/scenes/p0-1-custom-response-status/snapshots/abnormal-runtime.test.ts.md b/packages/datasource-engine/test/scenes/p0-1-custom-response-status/snapshots/abnormal-runtime.test.ts.md new file mode 100644 index 000000000..7c65d528f --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-1-custom-response-status/snapshots/abnormal-runtime.test.ts.md @@ -0,0 +1,20 @@ +# Snapshot report for `test/scenes/p0-1-custom-response-status/abnormal-runtime.test.ts` + +The actual snapshot is saved in `abnormal-runtime.test.ts.snap`. + +Generated by [AVA](https://avajs.dev). + +## abnormal scene + +> Snapshot 1 + + [ + { + detail: { + code: 'E_FOO', + message: 'test error', + success: false, + }, + type: 'FETCH_ERROR', + }, + ] diff --git a/packages/datasource-engine/test/scenes/p0-1-custom-response-status/snapshots/abnormal-runtime.test.ts.snap b/packages/datasource-engine/test/scenes/p0-1-custom-response-status/snapshots/abnormal-runtime.test.ts.snap new file mode 100644 index 0000000000000000000000000000000000000000..6a9794bde2dd0e5ca70c5439fb81d97ebf958f80 GIT binary patch literal 274 zcmV+t0qy=lRzVZO*LU;00AE$#mvACW;1dyGU)(mBOn%LWD{g$bu21M ztYl<_vH1D<85p@37#SHDxfvO4V49fIfpjhqx56~C`6p$iCYLZW!I=UA0t}4242(<+ zjC_oYYk>+y7?~LuS%C^tQcDsua~K%;fqI!>qAVqq1*tF&x0`E-vq!vZP>_ER$U>Go zK>d$^m<8y1Jw`N3nK3M7MmIb;KLu_$t82WQzdxD^_T1Fs;>2{gBCe9u;u3|_qN4mF Ybd|-W$;m*)U_O%o0LO-s0c-&P0I>aR-2eap literal 0 HcmV?d00001 diff --git a/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/README.md b/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/README.md new file mode 100644 index 000000000..d2eb4a470 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/README.md @@ -0,0 +1,3 @@ +# 关于此场景 + +有些数据源的错误可以忽略(吃掉)-- 通过 dataHandler 捕获 error,只要其不重新抛出 error 而且不返回 rejected 状态的 Promise. diff --git a/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/_datasource-runtime.ts b/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/_datasource-runtime.ts new file mode 100644 index 000000000..2608841e1 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/_datasource-runtime.ts @@ -0,0 +1,21 @@ +import { RuntimeDataSource } from '@ali/build-success-types'; + +export const DEFAULT_USER_DATA = { id: 0, name: 'guest' }; // 返回一个兜底的数据 + +// 这里仅仅是数据源部分的: +// @see: https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 +export const dataSource: RuntimeDataSource = { + list: [ + { + id: 'user', + isInit: true, + type: 'fetch', + options: () => ({ + uri: 'https://mocks.alibaba-inc.com/user.json', + }), + dataHandler: function dataHandler(response: any) { + return response.data; + }, + }, + ], +}; diff --git a/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/_datasource-schema.ts b/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/_datasource-schema.ts new file mode 100644 index 000000000..b9b44cc6a --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/_datasource-schema.ts @@ -0,0 +1,24 @@ +import { DataSource } from '@ali/build-success-types'; + +// 这里仅仅是数据源部分的 schema: +// @see: https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 +export const DATA_SOURCE_SCHEMA: DataSource = { + list: [ + { + id: 'user', + isInit: true, + type: 'fetch', + options: { + uri: 'https://mocks.alibaba-inc.com/user.json', + }, + dataHandler: { + type: 'JSFunction', + value: ` +function dataHandler(response) { + return response.data; +} +`, + }, + }, + ], +}; diff --git a/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/_macro-abnormal.ts b/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/_macro-abnormal.ts new file mode 100644 index 000000000..1c1e5d800 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/_macro-abnormal.ts @@ -0,0 +1,78 @@ +import { + DataSource, + IDataSourceEngine, + IRuntimeContext, + RuntimeDataSource, + RuntimeDataSourceStatus, +} from '@ali/build-success-types'; +import sinon from 'sinon'; + +import { delay, MockContext } from '../../_helpers'; +import { DATA_SOURCE_SCHEMA } from './_datasource-schema'; + +import type { ExecutionContext, Macro } from 'ava'; +import type { SinonFakeTimers } from 'sinon'; + +export const abnormalScene: Macro<[ + { + create: ( + dataSource: any, + ctx: IRuntimeContext, + options: any + ) => IDataSourceEngine; + dataSource: RuntimeDataSource | DataSource; + } +]> = async ( + t: ExecutionContext<{ clock: SinonFakeTimers }>, + { create, dataSource }, +) => { + const { clock } = t.context; + const ERROR_MSG = 'test error'; + const fetchHandler = sinon.fake(async () => { + await delay(100); + throw new Error(ERROR_MSG); + }); + + const context = new MockContext>({}, (ctx) => create(dataSource, ctx, { + requestHandlersMap: { + fetch: fetchHandler, + }, + })); + + const setState = sinon.spy(context, 'setState'); + + // 一开始应该是初始状态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Initial); + + const loading = context.reloadDataSource(); + + await clock.tickAsync(50); + + // 中间应该有 loading 态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loading); + + await Promise.all([clock.runAllAsync(), loading]); + + // 注意 error 是会被吃掉了,还是 loaded 状态 + // FIXME: 根据协议内容,dataHandler 返回的结果是需要抛出错误的,那么 fetchHandler 的错误难道不需要处理? + // TODO: 提案:request 如果挂了,不应该需要走 dataHandler 了,没有意义 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Error); + + // 检查数据源的数据 + t.deepEqual(context.dataSourceMap.user.data, undefined); + t.not(context.dataSourceMap.user.error, undefined); + t.regex(context.dataSourceMap.user.error!.message, new RegExp(ERROR_MSG)); + + // 检查状态数据 + t.assert(setState.notCalled); + + // fetchHandler 应该没调 + t.assert.skip(fetchHandler.notCalled); + + // 检查调用参数 + const firstListItemOptions = DATA_SOURCE_SCHEMA.list[0].options; + const fetchHandlerCallArgs = fetchHandler.firstCall.args[0]; + t.is(firstListItemOptions.uri, fetchHandlerCallArgs.uri); +}; + +abnormalScene.title = (providedTitle) => providedTitle || 'abnormal scene'; diff --git a/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/_macro-normal.ts b/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/_macro-normal.ts new file mode 100644 index 000000000..78aa87c61 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/_macro-normal.ts @@ -0,0 +1,81 @@ +import { + DataSource, + IDataSourceEngine, + IRuntimeContext, + RuntimeDataSource, + RuntimeDataSourceStatus, +} from '@ali/build-success-types'; +import sinon from 'sinon'; + +import { delay, MockContext } from '../../_helpers'; +import { DATA_SOURCE_SCHEMA } from './_datasource-schema'; + +import type { ExecutionContext, Macro } from 'ava'; +import type { SinonFakeTimers } from 'sinon'; + +export const normalScene: Macro<[ + { + create: ( + dataSource: any, + ctx: IRuntimeContext, + options: any + ) => IDataSourceEngine; + dataSource: RuntimeDataSource | DataSource; + } +]> = async ( + t: ExecutionContext<{ clock: SinonFakeTimers }>, + { create, dataSource }, +) => { + const { clock } = t.context; + + const USER_DATA = { + name: 'Alice', + age: 18, + }; + + const fetchHandler = sinon.fake(async () => { + await delay(100); + return { data: USER_DATA }; + }); + + const context = new MockContext>({}, (ctx) => create(dataSource, ctx, { + requestHandlersMap: { + fetch: fetchHandler, + }, + })); + + const setState = sinon.spy(context, 'setState'); + + // 一开始应该是初始状态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Initial); + + const loading = context.reloadDataSource(); + + await clock.tickAsync(50); + + // 中间应该有 loading 态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loading); + + await Promise.all([clock.runAllAsync(), loading]); + + // 最后应该成功了,loaded 状态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loaded); + + // 检查数据源的数据 + t.deepEqual(context.dataSourceMap.user.data, USER_DATA); + t.deepEqual(context.dataSourceMap.user.error, undefined); + + // 检查状态数据 + t.assert(setState.calledOnce); + t.deepEqual(context.state.user, USER_DATA); + + // fetchHandler 应该被调用了一次 + t.assert(fetchHandler.calledOnce); + + // 检查调用参数 + const firstListItemOptions = DATA_SOURCE_SCHEMA.list[0].options; + const fetchHandlerCallArgs = fetchHandler.firstCall.args[0]; + t.is(firstListItemOptions.uri, fetchHandlerCallArgs.uri); +}; + +normalScene.title = (providedTitle) => providedTitle || 'normal scene'; diff --git a/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/abnormal-interpret.test.ts b/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/abnormal-interpret.test.ts new file mode 100644 index 000000000..816523b10 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/abnormal-interpret.test.ts @@ -0,0 +1,22 @@ +import test, { ExecutionContext } from 'ava'; +import sinon from 'sinon'; + +import { create } from '../../../src/interpret'; + +import { DATA_SOURCE_SCHEMA } from './_datasource-schema'; +import { abnormalScene } from './_macro-abnormal'; + +import type { SinonFakeTimers } from 'sinon'; + +test.before((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock = sinon.useFakeTimers(); +}); + +test.after((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock.restore(); +}); + +test(abnormalScene, { + create, + dataSource: DATA_SOURCE_SCHEMA, +}); diff --git a/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/abnormal-runtime.test.ts b/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/abnormal-runtime.test.ts new file mode 100644 index 000000000..c338af3b1 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/abnormal-runtime.test.ts @@ -0,0 +1,20 @@ +import test, { ExecutionContext } from 'ava'; +import sinon, { SinonFakeTimers } from 'sinon'; + +import { create } from '../../../src/runtime'; + +import { dataSource } from './_datasource-runtime'; +import { abnormalScene } from './_macro-abnormal'; + +test.before((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock = sinon.useFakeTimers(); +}); + +test.after((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock.restore(); +}); + +test(abnormalScene, { + create, + dataSource, +}); diff --git a/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/normal-interpret.test.ts b/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/normal-interpret.test.ts new file mode 100644 index 000000000..9dac84e8d --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/normal-interpret.test.ts @@ -0,0 +1,20 @@ +import test, { ExecutionContext } from 'ava'; +import sinon, { SinonFakeTimers } from 'sinon'; + +import { create } from '../../../src/interpret'; + +import { DATA_SOURCE_SCHEMA } from './_datasource-schema'; +import { normalScene } from './_macro-normal'; + +test.before((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock = sinon.useFakeTimers(); +}); + +test.after((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock.restore(); +}); + +test(normalScene, { + create, + dataSource: DATA_SOURCE_SCHEMA, +}); diff --git a/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/normal-runtime.test.ts b/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/normal-runtime.test.ts new file mode 100644 index 000000000..761979c30 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/normal-runtime.test.ts @@ -0,0 +1,20 @@ +import test, { ExecutionContext } from 'ava'; +import sinon, { SinonFakeTimers } from 'sinon'; + +import { create } from '../../../src/runtime'; + +import { dataSource } from './_datasource-runtime'; +import { normalScene } from './_macro-normal'; + +test.before((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock = sinon.useFakeTimers(); +}); + +test.after((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock.restore(); +}); + +test(normalScene, { + create, + dataSource, +}); diff --git a/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/README.md b/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/README.md new file mode 100644 index 000000000..4f8590da4 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/README.md @@ -0,0 +1,3 @@ +# 关于此场景 + +某些场景下 dataHandler 不能同步返回,比如可能需要读取某个特殊的异步的数据源并合并响应数据。 diff --git a/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/_datasource-runtime.ts b/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/_datasource-runtime.ts new file mode 100644 index 000000000..5dc07956a --- /dev/null +++ b/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/_datasource-runtime.ts @@ -0,0 +1,30 @@ +import { RuntimeDataSource } from '@ali/build-success-types'; + +// 这里仅仅是数据源部分的: +// @see: https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 +export const dataSource: RuntimeDataSource = { + list: [ + { + id: 'user', + isInit: true, + type: 'fetch', + options: () => ({ + uri: 'https://mocks.alibaba-inc.com/user.json', + }), + dataHandler: async function dataHandler(response: any) { + const { data } = response; + if (!data) { + throw new Error('empty data!'); + } + + if (data.success) { + return data.data; + } + + this.recordError({ type: 'FETCH_ERROR', detail: data }); + + throw new Error(data.message); + }, + }, + ], +}; diff --git a/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/_datasource-schema.ts b/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/_datasource-schema.ts new file mode 100644 index 000000000..f35743828 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/_datasource-schema.ts @@ -0,0 +1,35 @@ +import { DataSource } from '@ali/build-success-types'; + +// 这里仅仅是数据源部分的 schema: +// @see: https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 +export const DATA_SOURCE_SCHEMA: DataSource = { + list: [ + { + id: 'user', + isInit: true, + type: 'fetch', + options: { + uri: 'https://mocks.alibaba-inc.com/user.json', + }, + dataHandler: { + type: 'JSFunction', + value: ` +async function dataHandler(response){ + const { data } = response; + if (!data) { + throw new Error('empty data!'); + } + + if (data.success){ + return data.data; + } + + this.recordError({ type: 'FETCH_ERROR', detail: data }); + + throw new Error(data.message); +} +`, + }, + }, + ], +}; diff --git a/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/_macro-abnormal.ts b/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/_macro-abnormal.ts new file mode 100644 index 000000000..757aaba6e --- /dev/null +++ b/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/_macro-abnormal.ts @@ -0,0 +1,95 @@ +import { + DataSource, + IDataSourceEngine, + IRuntimeContext, + RuntimeDataSource, + RuntimeDataSourceStatus, +} from '@ali/build-success-types'; +import sinon from 'sinon'; + +import { bindRuntimeContext, delay, MockContext } from '../../_helpers'; +import { DATA_SOURCE_SCHEMA } from './_datasource-schema'; + +import type { ExecutionContext, Macro } from 'ava'; +import type { SinonFakeTimers } from 'sinon'; + +export const abnormalScene: Macro<[ + { + create: ( + dataSource: any, + ctx: IRuntimeContext, + options: any + ) => IDataSourceEngine; + dataSource: RuntimeDataSource | DataSource; + } +]> = async ( + t: ExecutionContext<{ clock: SinonFakeTimers }>, + { create, dataSource }, +) => { + const { clock } = t.context; + const ERROR_MSG = 'test error'; + const fetchHandler = sinon.fake(async () => { + await delay(100); + return { + data: { + success: false, + message: ERROR_MSG, + code: 'E_FOO', + }, + }; + }); + + const context = new MockContext>( + {}, + (ctx) => create(bindRuntimeContext(dataSource, ctx), ctx, { + requestHandlersMap: { + fetch: fetchHandler, + }, + }), + { + recordError() {}, + }, + ); + + const setState = sinon.spy(context, 'setState'); + const recordError = sinon.spy(context, 'recordError'); + + // 一开始应该是初始状态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Initial); + + const loading = context.reloadDataSource(); + + await clock.tickAsync(50); + + // 中间应该有 loading 态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loading); + + await Promise.all([clock.runAllAsync(), loading]); + + // 最后应该失败了,error 状态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Error); + + // 检查数据源的数据 + t.deepEqual(context.dataSourceMap.user.data, undefined); + t.not(context.dataSourceMap.user.error, undefined); + + t.regex(context.dataSourceMap.user.error!.message, new RegExp(ERROR_MSG)); + + // 检查状态数据 + t.assert(setState.notCalled); + t.deepEqual(context.state.user, undefined); + + // fetchHandler 应该被调用了一次 + t.assert(fetchHandler.calledOnce); + + // 检查调用参数 + const firstListItemOptions = DATA_SOURCE_SCHEMA.list[0].options; + const fetchHandlerCallArgs = fetchHandler.firstCall.args[0]; + t.is(firstListItemOptions.uri, fetchHandlerCallArgs.uri); + + // 埋点应该也会被调用 + t.assert(recordError.calledOnce); + t.snapshot(recordError.firstCall.args); +}; + +abnormalScene.title = (providedTitle) => providedTitle || 'abnormal scene'; diff --git a/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/_macro-normal.ts b/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/_macro-normal.ts new file mode 100644 index 000000000..d00fa39d9 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/_macro-normal.ts @@ -0,0 +1,96 @@ +import { + DataSource, + IDataSourceEngine, + IRuntimeContext, + RuntimeDataSource, + RuntimeDataSourceStatus, +} from '@ali/build-success-types'; +import sinon from 'sinon'; + +import { bindRuntimeContext, delay, MockContext } from '../../_helpers'; +import { DATA_SOURCE_SCHEMA } from './_datasource-schema'; + +import type { ExecutionContext, Macro } from 'ava'; +import type { SinonFakeTimers } from 'sinon'; + +export const normalScene: Macro<[ + { + create: ( + dataSource: any, + ctx: IRuntimeContext, + options: any + ) => IDataSourceEngine; + dataSource: RuntimeDataSource | DataSource; + } +]> = async ( + t: ExecutionContext<{ clock: SinonFakeTimers }>, + { create, dataSource }, +) => { + const { clock } = t.context; + + const USER_DATA = { + name: 'Alice', + age: 18, + }; + + const fetchHandler = sinon.fake(async () => { + await delay(100); + return { + data: { + success: true, + data: USER_DATA, + }, + }; + }); + + const context = new MockContext>( + {}, + (ctx) => create(bindRuntimeContext(dataSource, ctx), ctx, { + requestHandlersMap: { + fetch: fetchHandler, + }, + }), + { + recordError() {}, + }, + ); + + const setState = sinon.spy(context, 'setState'); + const recordError = sinon.spy(context, 'recordError'); + + // 一开始应该是初始状态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Initial); + + const loading = context.reloadDataSource(); + + await clock.tickAsync(50); + + // 中间应该有 loading 态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loading); + + await Promise.all([clock.runAllAsync(), loading]); + + // 最后应该成功了,loaded 状态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loaded); + + // 检查数据源的数据 + t.deepEqual(context.dataSourceMap.user.data, USER_DATA); + t.deepEqual(context.dataSourceMap.user.error, undefined); + + // 检查状态数据 + t.assert(setState.calledOnce); + t.deepEqual(context.state.user, USER_DATA); + + // fetchHandler 应该被调用了一次 + t.assert(fetchHandler.calledOnce); + + // 检查调用参数 + const firstListItemOptions = DATA_SOURCE_SCHEMA.list[0].options; + const fetchHandlerCallArgs = fetchHandler.firstCall.args[0]; + t.is(firstListItemOptions.uri, fetchHandlerCallArgs.uri); + + // 埋点不应该被调用 + t.assert(recordError.notCalled); +}; + +normalScene.title = (providedTitle) => providedTitle || 'normal scene'; diff --git a/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/abnormal-interpret.test.ts b/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/abnormal-interpret.test.ts new file mode 100644 index 000000000..7f3169a50 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/abnormal-interpret.test.ts @@ -0,0 +1,21 @@ +import test, { ExecutionContext } from 'ava'; +import sinon from 'sinon'; + +import { create } from '../../../src/interpret'; +import { DATA_SOURCE_SCHEMA } from './_datasource-schema'; +import { abnormalScene } from './_macro-abnormal'; + +import type { SinonFakeTimers } from 'sinon'; + +test.before((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock = sinon.useFakeTimers(); +}); + +test.after((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock.restore(); +}); + +test(abnormalScene, { + create, + dataSource: DATA_SOURCE_SCHEMA, +}); diff --git a/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/abnormal-runtime.test.ts b/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/abnormal-runtime.test.ts new file mode 100644 index 000000000..c338af3b1 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/abnormal-runtime.test.ts @@ -0,0 +1,20 @@ +import test, { ExecutionContext } from 'ava'; +import sinon, { SinonFakeTimers } from 'sinon'; + +import { create } from '../../../src/runtime'; + +import { dataSource } from './_datasource-runtime'; +import { abnormalScene } from './_macro-abnormal'; + +test.before((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock = sinon.useFakeTimers(); +}); + +test.after((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock.restore(); +}); + +test(abnormalScene, { + create, + dataSource, +}); diff --git a/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/normal-interpret.test.ts b/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/normal-interpret.test.ts new file mode 100644 index 000000000..9dac84e8d --- /dev/null +++ b/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/normal-interpret.test.ts @@ -0,0 +1,20 @@ +import test, { ExecutionContext } from 'ava'; +import sinon, { SinonFakeTimers } from 'sinon'; + +import { create } from '../../../src/interpret'; + +import { DATA_SOURCE_SCHEMA } from './_datasource-schema'; +import { normalScene } from './_macro-normal'; + +test.before((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock = sinon.useFakeTimers(); +}); + +test.after((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock.restore(); +}); + +test(normalScene, { + create, + dataSource: DATA_SOURCE_SCHEMA, +}); diff --git a/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/normal-runtime.test.ts b/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/normal-runtime.test.ts new file mode 100644 index 000000000..761979c30 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/normal-runtime.test.ts @@ -0,0 +1,20 @@ +import test, { ExecutionContext } from 'ava'; +import sinon, { SinonFakeTimers } from 'sinon'; + +import { create } from '../../../src/runtime'; + +import { dataSource } from './_datasource-runtime'; +import { normalScene } from './_macro-normal'; + +test.before((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock = sinon.useFakeTimers(); +}); + +test.after((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock.restore(); +}); + +test(normalScene, { + create, + dataSource, +}); diff --git a/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/snapshots/abnormal-interpret.test.ts.md b/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/snapshots/abnormal-interpret.test.ts.md new file mode 100644 index 000000000..558b612d6 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/snapshots/abnormal-interpret.test.ts.md @@ -0,0 +1,20 @@ +# Snapshot report for `test/scenes/data-handler-returns-promise/abnormal-interpret.test.ts` + +The actual snapshot is saved in `abnormal-interpret.test.ts.snap`. + +Generated by [AVA](https://avajs.dev). + +## abnormal scene + +> Snapshot 1 + + [ + { + detail: { + code: 'E_FOO', + message: 'test error', + success: false, + }, + type: 'FETCH_ERROR', + }, + ] diff --git a/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/snapshots/abnormal-interpret.test.ts.snap b/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/snapshots/abnormal-interpret.test.ts.snap new file mode 100644 index 0000000000000000000000000000000000000000..6a9794bde2dd0e5ca70c5439fb81d97ebf958f80 GIT binary patch literal 274 zcmV+t0qy=lRzVZO*LU;00AE$#mvACW;1dyGU)(mBOn%LWD{g$bu21M ztYl<_vH1D<85p@37#SHDxfvO4V49fIfpjhqx56~C`6p$iCYLZW!I=UA0t}4242(<+ zjC_oYYk>+y7?~LuS%C^tQcDsua~K%;fqI!>qAVqq1*tF&x0`E-vq!vZP>_ER$U>Go zK>d$^m<8y1Jw`N3nK3M7MmIb;KLu_$t82WQzdxD^_T1Fs;>2{gBCe9u;u3|_qN4mF Ybd|-W$;m*)U_O%o0LO-s0c-&P0I>aR-2eap literal 0 HcmV?d00001 diff --git a/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/snapshots/abnormal-runtime.test.ts.md b/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/snapshots/abnormal-runtime.test.ts.md new file mode 100644 index 000000000..98deb8904 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/snapshots/abnormal-runtime.test.ts.md @@ -0,0 +1,20 @@ +# Snapshot report for `test/scenes/p1-0-data-handler-returns-promise/abnormal-runtime.test.ts` + +The actual snapshot is saved in `abnormal-runtime.test.ts.snap`. + +Generated by [AVA](https://avajs.dev). + +## abnormal scene + +> Snapshot 1 + + [ + { + detail: { + code: 'E_FOO', + message: 'test error', + success: false, + }, + type: 'FETCH_ERROR', + }, + ] diff --git a/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/snapshots/abnormal-runtime.test.ts.snap b/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/snapshots/abnormal-runtime.test.ts.snap new file mode 100644 index 0000000000000000000000000000000000000000..6a9794bde2dd0e5ca70c5439fb81d97ebf958f80 GIT binary patch literal 274 zcmV+t0qy=lRzVZO*LU;00AE$#mvACW;1dyGU)(mBOn%LWD{g$bu21M ztYl<_vH1D<85p@37#SHDxfvO4V49fIfpjhqx56~C`6p$iCYLZW!I=UA0t}4242(<+ zjC_oYYk>+y7?~LuS%C^tQcDsua~K%;fqI!>qAVqq1*tF&x0`E-vq!vZP>_ER$U>Go zK>d$^m<8y1Jw`N3nK3M7MmIb;KLu_$t82WQzdxD^_T1Fs;>2{gBCe9u;u3|_qN4mF Ybd|-W$;m*)U_O%o0LO-s0c-&P0I>aR-2eap literal 0 HcmV?d00001 diff --git a/packages/datasource-engine/test/scenes/p1-1-shouldfetch-control-request/README.md b/packages/datasource-engine/test/scenes/p1-1-shouldfetch-control-request/README.md new file mode 100644 index 000000000..efde6173c --- /dev/null +++ b/packages/datasource-engine/test/scenes/p1-1-shouldfetch-control-request/README.md @@ -0,0 +1,3 @@ +# 关于此场景 + +某些场景下 shouldFetch 的结果可以影响请求是否被发出去。 diff --git a/packages/datasource-engine/test/scenes/p1-1-shouldfetch-control-request/_datasource-runtime.ts b/packages/datasource-engine/test/scenes/p1-1-shouldfetch-control-request/_datasource-runtime.ts new file mode 100644 index 000000000..2085535c6 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p1-1-shouldfetch-control-request/_datasource-runtime.ts @@ -0,0 +1,32 @@ +import { RuntimeDataSource } from '@ali/build-success-types'; + +// 这里仅仅是数据源部分的: +// @see: https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 +export const dataSource: RuntimeDataSource = { + list: [ + { + id: 'user', + isInit: true, + type: 'fetch', + isSync: true, + options: () => ({ + uri: 'https://mocks.alibaba-inc.com/user.json', + }), + }, + { + id: 'orders', + isInit: true, + type: 'fetch', + isSync: true, + shouldFetch: () => false, + options() { + return { + uri: 'https://mocks.alibaba-inc.com/orders.json', + params: { + userId: this.state.user.id, + }, + }; + }, + }, + ], +}; diff --git a/packages/datasource-engine/test/scenes/p1-1-shouldfetch-control-request/_datasource-schema.ts b/packages/datasource-engine/test/scenes/p1-1-shouldfetch-control-request/_datasource-schema.ts new file mode 100644 index 000000000..e333f485a --- /dev/null +++ b/packages/datasource-engine/test/scenes/p1-1-shouldfetch-control-request/_datasource-schema.ts @@ -0,0 +1,38 @@ +import { DataSource } from '@ali/build-success-types'; + +// 这里仅仅是数据源部分的 schema: +// @see: https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 +export const DATA_SOURCE_SCHEMA: DataSource = { + list: [ + { + id: 'user', + isInit: true, + type: 'fetch', + isSync: true, + options: { + uri: 'https://mocks.alibaba-inc.com/user.json', + }, + }, + { + id: 'orders', + isInit: true, + type: 'fetch', + isSync: true, + shouldFetch: { + type: 'JSFunction', + value: ` + function (){ + return false; + } + `, + }, + options: { + uri: 'https://mocks.alibaba-inc.com/orders.json', + params: { + type: 'JSExpression', + value: '{ userId: this.state.user.id }', + }, + }, + }, + ], +}; diff --git a/packages/datasource-engine/test/scenes/p1-1-shouldfetch-control-request/_macro-normal.ts b/packages/datasource-engine/test/scenes/p1-1-shouldfetch-control-request/_macro-normal.ts new file mode 100644 index 000000000..4289a6d89 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p1-1-shouldfetch-control-request/_macro-normal.ts @@ -0,0 +1,108 @@ +import { + DataSource, + IDataSourceEngine, + IRuntimeContext, + RuntimeDataSource, + RuntimeDataSourceStatus, +} from '@ali/build-success-types'; +import sinon from 'sinon'; + +import { bindRuntimeContext, delay, MockContext } from '../../_helpers'; + +import type { ExecutionContext, Macro } from 'ava'; +import type { SinonFakeTimers } from 'sinon'; +import { DATA_SOURCE_SCHEMA } from './_datasource-schema'; + +export const normalScene: Macro<[ + { + create: ( + dataSource: any, + ctx: IRuntimeContext, + options: any + ) => IDataSourceEngine; + dataSource: RuntimeDataSource | DataSource; + } +]> = async ( + t: ExecutionContext<{ clock: SinonFakeTimers }>, + { create, dataSource }, +) => { + const { clock } = t.context; + const ORDERS_ERROR_MSG = + 'the orders request should not fetch, please check the condition'; + + const USER_DATA = { + name: 'Alice', + age: 18, + }; + + const fetchHandler = sinon.fake(async () => { + await delay(100); + return { + data: USER_DATA, + }; + }); + + const context = new MockContext>( + {}, + (ctx) => create(bindRuntimeContext(dataSource, ctx), ctx, { + requestHandlersMap: { + fetch: fetchHandler, + }, + }), + { + recordError() {}, + }, + ); + + const setState = sinon.spy(context, 'setState'); + // const recordError = sinon.spy(context, 'recordError'); + + // 一开始应该是初始状态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Initial); + t.is(context.dataSourceMap.orders.status, RuntimeDataSourceStatus.Initial); + + const loading = context.reloadDataSource(); + + await clock.tickAsync(50); + + // 中间应该有 loading 态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loading); + + await clock.tickAsync(50); + + // 中间应该有 loading 态 + t.is(context.dataSourceMap.orders.status, RuntimeDataSourceStatus.Error); + + await Promise.all([clock.runAllAsync(), loading]); + + // 最后 user 成功, orders 失败 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loaded); + t.is(context.dataSourceMap.orders.status, RuntimeDataSourceStatus.Error); + + // 检查数据源的数据 + t.deepEqual(context.dataSourceMap.user.data, USER_DATA); + t.is(context.dataSourceMap.user.error, undefined); + t.regex( + context.dataSourceMap.orders.error!.message, + new RegExp(ORDERS_ERROR_MSG), + ); + + // 检查状态数据 + t.assert(setState.calledOnce); + t.deepEqual(context.state.user, USER_DATA); + + // fetchHandler 应该被调用了 1 次 + t.assert(fetchHandler.calledOnce); + + // 检查调用参数 + + const firstListItemOptions = DATA_SOURCE_SCHEMA.list[0].options; + const fetchHandlerCallArgs = fetchHandler.firstCall.args[0]; + t.is(firstListItemOptions.uri, fetchHandlerCallArgs.uri); + + // // 埋点应该也会被调用 + // t.assert(recordError.calledOnce); + // t.snapshot(recordError.firstCall.args); +}; + +normalScene.title = (providedTitle) => providedTitle || 'normal scene'; diff --git a/packages/datasource-engine/test/scenes/p1-1-shouldfetch-control-request/normal-interpret.test.ts b/packages/datasource-engine/test/scenes/p1-1-shouldfetch-control-request/normal-interpret.test.ts new file mode 100644 index 000000000..9dac84e8d --- /dev/null +++ b/packages/datasource-engine/test/scenes/p1-1-shouldfetch-control-request/normal-interpret.test.ts @@ -0,0 +1,20 @@ +import test, { ExecutionContext } from 'ava'; +import sinon, { SinonFakeTimers } from 'sinon'; + +import { create } from '../../../src/interpret'; + +import { DATA_SOURCE_SCHEMA } from './_datasource-schema'; +import { normalScene } from './_macro-normal'; + +test.before((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock = sinon.useFakeTimers(); +}); + +test.after((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock.restore(); +}); + +test(normalScene, { + create, + dataSource: DATA_SOURCE_SCHEMA, +}); diff --git a/packages/datasource-engine/test/scenes/p1-1-shouldfetch-control-request/normal-runtime.test.ts b/packages/datasource-engine/test/scenes/p1-1-shouldfetch-control-request/normal-runtime.test.ts new file mode 100644 index 000000000..761979c30 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p1-1-shouldfetch-control-request/normal-runtime.test.ts @@ -0,0 +1,20 @@ +import test, { ExecutionContext } from 'ava'; +import sinon, { SinonFakeTimers } from 'sinon'; + +import { create } from '../../../src/runtime'; + +import { dataSource } from './_datasource-runtime'; +import { normalScene } from './_macro-normal'; + +test.before((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock = sinon.useFakeTimers(); +}); + +test.after((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock.restore(); +}); + +test(normalScene, { + create, + dataSource, +}); diff --git a/packages/datasource-engine/tsconfig.json b/packages/datasource-engine/tsconfig.json new file mode 100644 index 000000000..4c30ce1c8 --- /dev/null +++ b/packages/datasource-engine/tsconfig.json @@ -0,0 +1,68 @@ +{ + "compilerOptions": { + /* Basic Options */ + // "incremental": true, /* Enable incremental compilation */ + "target": "esnext" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */, + "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */, + // "lib": [], /* Specify library files to be included in the compilation. */ + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "checkJs": true, /* Report errors in .js files. */ + "jsx": "preserve" /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */, + "declaration": true /* Generates corresponding '.d.ts' file. */, + // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + "outDir": "dist" /* Redirect output structure to the directory. */, + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "composite": true, /* Enable project compilation */ + // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ + // "removeComments": true, /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + "importHelpers": true /* Import emit helpers from 'tslib'. */, + // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + + /* Strict Type-Checking Options */ + "strict": true /* Enable all strict type-checking options. */, + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "strictFunctionTypes": true, /* Enable strict checking of function types. */ + // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ + // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + + /* Additional Checks */ + // "noUnusedLocals": true, /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + + /* Module Resolution Options */ + "moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */, + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + "allowSyntheticDefaultImports": true /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */, + "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, + // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + + /* Source Map Options */ + // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + + /* Advanced Options */ + "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */, + "skipLibCheck": true + }, + "include": ["src"] +} diff --git a/packages/datasource-handlers/.eslintignore b/packages/datasource-handlers/.eslintignore new file mode 100644 index 000000000..096746c14 --- /dev/null +++ b/packages/datasource-handlers/.eslintignore @@ -0,0 +1 @@ +/node_modules/ \ No newline at end of file diff --git a/packages/datasource-handlers/.eslintrc.js b/packages/datasource-handlers/.eslintrc.js new file mode 100644 index 000000000..e19c549ba --- /dev/null +++ b/packages/datasource-handlers/.eslintrc.js @@ -0,0 +1,7 @@ +module.exports = { + extends: '../../.eslintrc.js', + rules: { + '@typescript-eslint/no-parameter-properties': 1, + 'no-param-reassign': 0, + }, +}; diff --git a/packages/datasource-handlers/.prettierrc.js b/packages/datasource-handlers/.prettierrc.js new file mode 100644 index 000000000..d2db80ead --- /dev/null +++ b/packages/datasource-handlers/.prettierrc.js @@ -0,0 +1,4 @@ +module.exports = { + singleQuote: true, + trailingComma: 'always', +}; diff --git a/packages/datasource-handlers/lerna.json b/packages/datasource-handlers/lerna.json new file mode 100644 index 000000000..b9933894c --- /dev/null +++ b/packages/datasource-handlers/lerna.json @@ -0,0 +1,5 @@ +{ + "packages": ["packages/*"], + "version": "independent", + "npmClient": "yarn" +} diff --git a/packages/datasource-handlers/package.json b/packages/datasource-handlers/package.json new file mode 100644 index 000000000..43cea9f9d --- /dev/null +++ b/packages/datasource-handlers/package.json @@ -0,0 +1,9 @@ +{ + "name": "@ali/lowcode-datasource-handlers", + "version": "1.0.0", + "main": "index.js", + "license": "MIT", + "devDependencies": { + "lerna": "^3.22.0" + } +} diff --git a/packages/datasource-handlers/packages/fetch/es/index.d.ts b/packages/datasource-handlers/packages/fetch/es/index.d.ts new file mode 100644 index 000000000..443ad0dd1 --- /dev/null +++ b/packages/datasource-handlers/packages/fetch/es/index.d.ts @@ -0,0 +1,2 @@ +import { RuntimeOptionsConfig } from '@ali/build-success-types'; +export declare function createFetchHandler(config?: unknown): (options: RuntimeOptionsConfig) => Promise; diff --git a/packages/datasource-handlers/packages/fetch/es/index.js b/packages/datasource-handlers/packages/fetch/es/index.js new file mode 100644 index 000000000..0b4d6e5ba --- /dev/null +++ b/packages/datasource-handlers/packages/fetch/es/index.js @@ -0,0 +1,25 @@ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +import request from 'universal-request'; +// config 留着扩展 +export function createFetchHandler(config) { + return function (options) { + return __awaiter(this, void 0, void 0, function* () { + const requestConfig = Object.assign(Object.assign({}, options), { url: options.uri, method: options.method, data: options.params, headers: options.headers }); + try { + const response = yield request(requestConfig); + return response; + } + catch (error) { + throw error; + } + }); + }; +} diff --git a/packages/datasource-handlers/packages/fetch/package.json b/packages/datasource-handlers/packages/fetch/package.json new file mode 100644 index 000000000..ad28decb4 --- /dev/null +++ b/packages/datasource-handlers/packages/fetch/package.json @@ -0,0 +1,29 @@ +{ + "name": "@ali/lowcode-datasource-fetch-handler", + "version": "1.0.2", + "main": "lib/index.js", + "module": "es/index.js", + "typings": "es/index.d.ts", + "files": [ + "src", + "lib", + "es" + ], + "scripts": { + "dev": "tsc --watch", + "clean": "rm -rf es lib", + "build": "npm run clean && tsc && tsc --outDir ./lib --module commonjs ", + "prepublishOnly": "npm run build" + }, + "dependencies": { + "typescript": "^3.9.7", + "universal-request": "^2.2.0" + }, + "devDependencies": { + "@ali/build-success-types": "^0.1.2-alpha.35" + }, + "publishConfig": { + "registry": "https://registry.npm.alibaba-inc.com" + }, + "gitHead": "829e504c52a294fc28966ab0e491f4d2de1d4c90" +} diff --git a/packages/datasource-handlers/packages/fetch/src/index.ts b/packages/datasource-handlers/packages/fetch/src/index.ts new file mode 100644 index 000000000..d59fc0a8d --- /dev/null +++ b/packages/datasource-handlers/packages/fetch/src/index.ts @@ -0,0 +1,20 @@ +import { RuntimeOptionsConfig } from '@ali/build-success-types'; + +import request from 'universal-request'; +import { RequestOptions, AsObject } from 'universal-request/lib/types'; + +// config 留着扩展 +export function createFetchHandler(config?: Record) { + return async function (options: RuntimeOptionsConfig) { + const requestConfig: RequestOptions = { + ...options, + url: options.uri, + method: options.method as RequestOptions['method'], + data: options.params as AsObject, + headers: options.headers as AsObject, + ...config, + }; + const response = await request(requestConfig); + return response; + }; +} diff --git a/packages/datasource-handlers/packages/fetch/tsconfig.json b/packages/datasource-handlers/packages/fetch/tsconfig.json new file mode 100644 index 000000000..268731175 --- /dev/null +++ b/packages/datasource-handlers/packages/fetch/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "es", + "target": "es6", + "module": "esnext" + }, + + "include": ["src/**/*"] +} diff --git a/packages/datasource-handlers/packages/mopen/es/index.d.ts b/packages/datasource-handlers/packages/mopen/es/index.d.ts new file mode 100644 index 000000000..17039d9f2 --- /dev/null +++ b/packages/datasource-handlers/packages/mopen/es/index.d.ts @@ -0,0 +1,5 @@ +import { MopenClientConfig } from '@ali/mirror-io-client-mopen'; +import { RuntimeOptionsConfig } from '@ali/build-success-types'; +export declare function createMopenHandler(config?: MopenClientConfig): (options: RuntimeOptionsConfig) => Promise<{ + data: T; +}>; diff --git a/packages/datasource-handlers/packages/mopen/es/index.js b/packages/datasource-handlers/packages/mopen/es/index.js new file mode 100644 index 000000000..967facd1d --- /dev/null +++ b/packages/datasource-handlers/packages/mopen/es/index.js @@ -0,0 +1,26 @@ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +import { MopenClient, MOPEN_APPKEY_XSPACE_PRE_ONLINE, MOPEN_DOMAIN_TAOBAO_PRE_ONLINE, } from '@ali/mirror-io-client-mopen'; +export function createMopenHandler(config = { + mtopDomain: MOPEN_DOMAIN_TAOBAO_PRE_ONLINE, + appKey: MOPEN_APPKEY_XSPACE_PRE_ONLINE, +}) { + return function (options) { + return __awaiter(this, void 0, void 0, function* () { + try { + const { data, response } = yield MopenClient.request(Object.assign(Object.assign({ config }, options), { api: options.uri, v: options.v, data: options.params, type: options.method || 'get', dataType: options.dataType || 'json', timeout: options.timeout, headers: options.headers })); + return Object.assign(Object.assign({}, response), { data }); + } + catch (error) { + throw error; + } + }); + }; +} diff --git a/packages/datasource-handlers/packages/mopen/package.json b/packages/datasource-handlers/packages/mopen/package.json new file mode 100644 index 000000000..87ff98947 --- /dev/null +++ b/packages/datasource-handlers/packages/mopen/package.json @@ -0,0 +1,29 @@ +{ + "name": "@ali/lowcode-datasource-mopen-handler", + "version": "1.0.2", + "main": "lib/index.js", + "module": "es/index.js", + "typings": "es/index.d.ts", + "files": [ + "src", + "lib", + "es" + ], + "scripts": { + "dev": "tsc --watch", + "clean": "rm -rf es lib", + "build": "npm run clean && tsc && tsc --outDir ./lib --module commonjs ", + "prepublishOnly": "npm run build" + }, + "devDependencies": { + "@ali/build-success-types": "^0.1.2-alpha.35" + }, + "dependencies": { + "@ali/mirror-io-client-mopen": "1.0.0-beta.16", + "typescript": "^3.9.7" + }, + "publishConfig": { + "registry": "https://registry.npm.alibaba-inc.com" + }, + "gitHead": "829e504c52a294fc28966ab0e491f4d2de1d4c90" +} diff --git a/packages/datasource-handlers/packages/mopen/src/index.ts b/packages/datasource-handlers/packages/mopen/src/index.ts new file mode 100644 index 000000000..9367fbb4f --- /dev/null +++ b/packages/datasource-handlers/packages/mopen/src/index.ts @@ -0,0 +1,33 @@ +import { + MopenClient, + MopenClientConfig, + MOPEN_APPKEY_XSPACE_PRE_ONLINE, + MOPEN_DOMAIN_TAOBAO_PRE_ONLINE, +} from '@ali/mirror-io-client-mopen'; +import { RuntimeOptionsConfig } from '@ali/build-success-types'; + +type Method = 'get' | 'post' | 'GET' | 'POST'; + +type DataType = 'jsonp' | 'json' | 'originaljsonp'; + +export function createMopenHandler( + config: MopenClientConfig = { + mtopDomain: MOPEN_DOMAIN_TAOBAO_PRE_ONLINE, + appKey: MOPEN_APPKEY_XSPACE_PRE_ONLINE, + }, +) { + return async function (options: RuntimeOptionsConfig): Promise<{ data: T }> { + const { data, response } = await MopenClient.request({ + config, + ...options, + api: options.uri, + v: options.v as string, + data: options.params, + type: (options.method as Method) || 'get', + dataType: (options.dataType as DataType) || 'json', + timeout: options.timeout, + headers: options.headers, + }); + return { ...response, data }; + }; +} diff --git a/packages/datasource-handlers/packages/mopen/tsconfig.json b/packages/datasource-handlers/packages/mopen/tsconfig.json new file mode 100644 index 000000000..268731175 --- /dev/null +++ b/packages/datasource-handlers/packages/mopen/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "es", + "target": "es6", + "module": "esnext" + }, + + "include": ["src/**/*"] +} diff --git a/packages/datasource-handlers/packages/mtop/es/index.d.ts b/packages/datasource-handlers/packages/mtop/es/index.d.ts new file mode 100644 index 000000000..c30b6a50a --- /dev/null +++ b/packages/datasource-handlers/packages/mtop/es/index.d.ts @@ -0,0 +1,6 @@ +import { RuntimeOptionsConfig } from '@ali/build-success-types'; +export declare type Method = 'get' | 'post' | 'GET' | 'POST'; +export declare type DataType = 'jsonp' | 'json' | 'originaljsonp'; +export declare function createMtopHandler(config?: MTopConfig): (options: RuntimeOptionsConfig) => Promise<{ + data: T; +}>; diff --git a/packages/datasource-handlers/packages/mtop/es/index.js b/packages/datasource-handlers/packages/mtop/es/index.js new file mode 100644 index 000000000..fed789e22 --- /dev/null +++ b/packages/datasource-handlers/packages/mtop/es/index.js @@ -0,0 +1,35 @@ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +import mtopRequest from '@ali/universal-mtop'; +// 考虑一下 mtop 类型的问题,官方没有提供 ts 文件 +export function createMtopHandler(config) { + if (config && Object.keys(config).length > 0) { + Object.keys(config).forEach((key) => mtopRequest.config(key, config[key])); + } + return function (options) { + return __awaiter(this, void 0, void 0, function* () { + try { + const response = yield mtopRequest.request({ + api: options.uri, + v: options.v || '1.0', + data: options.params, + type: options.method || 'get', + dataType: options.dataType || 'json', + timeout: options.timeout, + headers: options.headers, + }); + return response; + } + catch (error) { + throw error; + } + }); + }; +} diff --git a/packages/datasource-handlers/packages/mtop/package.json b/packages/datasource-handlers/packages/mtop/package.json new file mode 100644 index 000000000..d0f0288c7 --- /dev/null +++ b/packages/datasource-handlers/packages/mtop/package.json @@ -0,0 +1,29 @@ +{ + "name": "@ali/lowcode-datasource-mtop-handler", + "version": "1.0.1", + "main": "lib/index.js", + "module": "es/index.js", + "typings": "es/index.d.ts", + "files": [ + "src", + "lib", + "es" + ], + "scripts": { + "dev": "tsc --watch", + "clean": "rm -rf es lib", + "build": "npm run clean && tsc && tsc --outDir ./lib --module commonjs ", + "prepublishOnly": "npm run build" + }, + "devDependencies": { + "@ali/build-success-types": "^0.1.2-alpha.35" + }, + "dependencies": { + "@ali/universal-mtop": "^5.1.9", + "typescript": "^3.9.7" + }, + "publishConfig": { + "registry": "https://registry.npm.alibaba-inc.com" + }, + "gitHead": "829e504c52a294fc28966ab0e491f4d2de1d4c90" +} diff --git a/packages/datasource-handlers/packages/mtop/src/index.ts b/packages/datasource-handlers/packages/mtop/src/index.ts new file mode 100644 index 000000000..0c01cdd64 --- /dev/null +++ b/packages/datasource-handlers/packages/mtop/src/index.ts @@ -0,0 +1,26 @@ +import mtopRequest from '@ali/universal-mtop'; + +import { RuntimeOptionsConfig } from '@ali/build-success-types'; + +export type Method = 'get' | 'post' | 'GET' | 'POST'; + +export type DataType = 'jsonp' | 'json' | 'originaljsonp'; + +// 考虑一下 mtop 类型的问题,官方没有提供 ts 文件 +export function createMtopHandler(config?: MTopConfig) { + if (config && Object.keys(config).length > 0) { + Object.keys(config).forEach((key: string) => mtopRequest.config(key, config[key])); + } + return async function (options: RuntimeOptionsConfig): Promise<{ data: T }> { + const response = await mtopRequest.request({ + api: options.uri, + v: (options.v as string) || '1.0', + data: options.params, + type: (options.method as Method) || 'get', + dataType: (options.dataType as DataType) || 'json', + timeout: options.timeout, + headers: options.headers, + }); + return response; + }; +} diff --git a/packages/datasource-handlers/packages/mtop/src/typings.d.ts b/packages/datasource-handlers/packages/mtop/src/typings.d.ts new file mode 100644 index 000000000..6a5989f78 --- /dev/null +++ b/packages/datasource-handlers/packages/mtop/src/typings.d.ts @@ -0,0 +1,11 @@ +declare interface MTopConfig { + prefix?: string; + subDomain?: string; + mainDomain?: string; + [index: string]: unknown; +} + +declare module '@ali/universal-mtop' { + const request: (config: any) => Promise<{ data: T }>; + const config: (key: string, value: unknown) => void; +} diff --git a/packages/datasource-handlers/packages/mtop/tsconfig.json b/packages/datasource-handlers/packages/mtop/tsconfig.json new file mode 100644 index 000000000..268731175 --- /dev/null +++ b/packages/datasource-handlers/packages/mtop/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "es", + "target": "es6", + "module": "esnext" + }, + + "include": ["src/**/*"] +} diff --git a/packages/datasource-handlers/packages/universalMtop/es/index.d.ts b/packages/datasource-handlers/packages/universalMtop/es/index.d.ts new file mode 100644 index 000000000..2a16eb3e9 --- /dev/null +++ b/packages/datasource-handlers/packages/universalMtop/es/index.d.ts @@ -0,0 +1,5 @@ +import { UniversalMtopClientConfig } from '@ali/mirror-io-client-universal-mtop'; +import { RuntimeOptionsConfig } from '@ali/build-success-types'; +export declare function createMopenHandler(config?: UniversalMtopClientConfig): (options: RuntimeOptionsConfig) => Promise<{ + data: T; +}>; diff --git a/packages/datasource-handlers/packages/universalMtop/es/index.js b/packages/datasource-handlers/packages/universalMtop/es/index.js new file mode 100644 index 000000000..718adf31b --- /dev/null +++ b/packages/datasource-handlers/packages/universalMtop/es/index.js @@ -0,0 +1,23 @@ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +import { UniversalMtopClient, } from '@ali/mirror-io-client-universal-mtop'; +export function createMopenHandler(config) { + return function (options) { + return __awaiter(this, void 0, void 0, function* () { + try { + const { data, response } = yield UniversalMtopClient.request(Object.assign(Object.assign({ config }, options), { api: options.uri, v: options.v, data: options.params, type: options.method || 'get', dataType: options.dataType || 'json', timeout: options.timeout, headers: options.headers })); + return Object.assign(Object.assign({}, response), { data }); + } + catch (error) { + throw error; + } + }); + }; +} diff --git a/packages/datasource-handlers/packages/universalMtop/package.json b/packages/datasource-handlers/packages/universalMtop/package.json new file mode 100644 index 000000000..75c9f216f --- /dev/null +++ b/packages/datasource-handlers/packages/universalMtop/package.json @@ -0,0 +1,29 @@ +{ + "name": "@ali/lowcode-datasource-universal-mtop-handler", + "version": "1.0.1", + "main": "lib/index.js", + "module": "es/index.js", + "typings": "es/index.d.ts", + "files": [ + "src", + "lib", + "es" + ], + "scripts": { + "dev": "tsc --watch", + "clean": "rm -rf es lib", + "build": "npm run clean && tsc && tsc --outDir ./lib --module commonjs ", + "prepublishOnly": "npm run build" + }, + "devDependencies": { + "@ali/build-success-types": "^0.1.2-alpha.27" + }, + "dependencies": { + "@ali/mirror-io-client-universal-mtop": "1.0.0-beta.16", + "typescript": "^3.9.7" + }, + "publishConfig": { + "registry": "https://registry.npm.alibaba-inc.com" + }, + "gitHead": "829e504c52a294fc28966ab0e491f4d2de1d4c90" +} diff --git a/packages/datasource-handlers/packages/universalMtop/src/index.ts b/packages/datasource-handlers/packages/universalMtop/src/index.ts new file mode 100644 index 000000000..f44d9eebd --- /dev/null +++ b/packages/datasource-handlers/packages/universalMtop/src/index.ts @@ -0,0 +1,29 @@ +import { + UniversalMtopClient, + UniversalMtopClientConfig, +} from '@ali/mirror-io-client-universal-mtop'; + +import { RuntimeOptionsConfig } from '@ali/build-success-types'; + +type Method = 'get' | 'post' | 'GET' | 'POST'; + +type DataType = 'jsonp' | 'json' | 'originaljsonp'; + +export function createMopenHandler( + config?: UniversalMtopClientConfig, +) { + return async function (options: RuntimeOptionsConfig): Promise<{ data: T }> { + const { data, response } = await UniversalMtopClient.request({ + config, + ...options, + api: options.uri, + v: options.v as string, + data: options.params, + type: (options.method as Method) || 'get', + dataType: (options.dataType as DataType) || 'json', + timeout: options.timeout, + headers: options.headers, + }); + return { ...response, data }; + }; +} diff --git a/packages/datasource-handlers/packages/universalMtop/tsconfig.json b/packages/datasource-handlers/packages/universalMtop/tsconfig.json new file mode 100644 index 000000000..268731175 --- /dev/null +++ b/packages/datasource-handlers/packages/universalMtop/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "es", + "target": "es6", + "module": "esnext" + }, + + "include": ["src/**/*"] +} diff --git a/packages/datasource-handlers/packages/urlParams/es/index.d.ts b/packages/datasource-handlers/packages/urlParams/es/index.d.ts new file mode 100644 index 000000000..f16cb44c3 --- /dev/null +++ b/packages/datasource-handlers/packages/urlParams/es/index.d.ts @@ -0,0 +1,2 @@ +import { UrlParamsHandler } from '@ali/build-success-types'; +export declare function createUrlParamsHandler(searchString?: string | T): UrlParamsHandler; diff --git a/packages/datasource-handlers/packages/urlParams/es/index.js b/packages/datasource-handlers/packages/urlParams/es/index.js new file mode 100644 index 000000000..84a9451ef --- /dev/null +++ b/packages/datasource-handlers/packages/urlParams/es/index.js @@ -0,0 +1,21 @@ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +import qs from 'query-string'; +export function createUrlParamsHandler(searchString = '') { + return function () { + return __awaiter(this, void 0, void 0, function* () { + if (typeof searchString === 'string') { + const params = qs.parse(searchString); + return params; + } + return searchString; + }); + }; +} diff --git a/packages/datasource-handlers/packages/urlParams/package.json b/packages/datasource-handlers/packages/urlParams/package.json new file mode 100644 index 000000000..41ee2e618 --- /dev/null +++ b/packages/datasource-handlers/packages/urlParams/package.json @@ -0,0 +1,29 @@ +{ + "name": "@ali/lowcode-datasource-url-params-handler", + "version": "1.0.1", + "main": "lib/index.js", + "module": "es/index.js", + "typings": "es/index.d.ts", + "files": [ + "src", + "lib", + "es" + ], + "scripts": { + "dev": "tsc --watch", + "clean": "rm -rf es lib", + "build": "npm run clean && tsc && tsc --outDir ./lib --module commonjs ", + "prepublishOnly": "npm run build" + }, + "devDependencies": { + "@ali/build-success-types": "^0.1.2-alpha.31" + }, + "dependencies": { + "query-string": "^6.13.1", + "typescript": "^3.9.7" + }, + "publishConfig": { + "registry": "https://registry.npm.alibaba-inc.com" + }, + "gitHead": "829e504c52a294fc28966ab0e491f4d2de1d4c90" +} diff --git a/packages/datasource-handlers/packages/urlParams/src/index.ts b/packages/datasource-handlers/packages/urlParams/src/index.ts new file mode 100644 index 000000000..c0c4a8836 --- /dev/null +++ b/packages/datasource-handlers/packages/urlParams/src/index.ts @@ -0,0 +1,15 @@ +import qs from 'query-string'; +import { UrlParamsHandler } from '@ali/build-success-types'; + +export function createUrlParamsHandler( + searchString: string | T = '', +): UrlParamsHandler { + return async function (): Promise { + if (typeof searchString === 'string') { + const params = (qs.parse(searchString) as unknown) as T; + return params; + } + + return searchString; + }; +} diff --git a/packages/datasource-handlers/packages/urlParams/tsconfig.json b/packages/datasource-handlers/packages/urlParams/tsconfig.json new file mode 100644 index 000000000..268731175 --- /dev/null +++ b/packages/datasource-handlers/packages/urlParams/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "es", + "target": "es6", + "module": "esnext" + }, + + "include": ["src/**/*"] +} diff --git a/packages/datasource-handlers/tsconfig.json b/packages/datasource-handlers/tsconfig.json new file mode 100644 index 000000000..68d4e6bb3 --- /dev/null +++ b/packages/datasource-handlers/tsconfig.json @@ -0,0 +1,67 @@ +{ + "compilerOptions": { + /* Basic Options */ + // "incremental": true, /* Enable incremental compilation */ + // "target": "es6" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */, + // "module": "esnext" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */, + "lib": ["ESNext", "DOM"] /* Specify library files to be included in the compilation. */, + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "checkJs": true, /* Report errors in .js files. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + "declaration": true /* Generates corresponding '.d.ts' file. */, + // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + // "outDir": "es" /* Redirect output structure to the directory. */, + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "composite": true, /* Enable project compilation */ + // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ + // "removeComments": true, /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + + /* Strict Type-Checking Options */ + "strict": true /* Enable all strict type-checking options. */, + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "strictFunctionTypes": true, /* Enable strict checking of function types. */ + // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ + // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + + /* Additional Checks */ + // "noUnusedLocals": true, /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + + /* Module Resolution Options */ + "moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */, + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, + // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + + /* Source Map Options */ + // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + + /* Advanced Options */ + "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */, + "skipLibCheck": true + } +} From 2b9bcb5174466371663fa5496ccd93dc2e4dc7c4 Mon Sep 17 00:00:00 2001 From: "guokai.jgk" Date: Tue, 13 Oct 2020 17:06:51 +0800 Subject: [PATCH 02/18] =?UTF-8?q?feat:=20=E8=B0=83=E6=95=B4=20datasource-h?= =?UTF-8?q?andlers?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/datasource-engine/.eslintignore | 4 +- packages/datasource-engine/.eslintrc.js | 4 +- packages/datasource-engine/.prettierrc.js | 2 +- packages/datasource-engine/package.json | 7 +- .../src/core/RuntimeDataSourceItem.ts | 21 +-- .../datasource-engine/src/core/adapter.ts | 21 ++- .../src/core/reloadDataSourceFactory.ts | 16 +- .../datasource-engine/src/helpers/index.ts | 3 +- .../src/interpret/DataSourceEngineFactory.ts | 25 ++- .../runtime/RuntimeDataSourceEngineFactory.ts | 19 +- packages/datasource-engine/src/utils.ts | 40 +++-- .../test/_helpers/mock-context.ts | 11 +- .../_datasource-runtime.ts | 2 +- .../_datasource-schema.ts | 4 +- .../p0-0-simplest-defaults/_macro-abnormal.ts | 74 ++++---- .../p0-0-simplest-defaults/_macro-normal.ts | 110 ++++++------ .../_datasource-runtime.ts | 2 +- .../_datasource-schema.ts | 4 +- .../_macro-abnormal.ts | 140 +++++++-------- .../_macro-normal.ts | 132 +++++++------- .../p0-0-url-params/_datasource-runtime.ts | 2 +- .../p0-0-url-params/_datasource-schema.ts | 4 +- .../scenes/p0-0-url-params/_macro-normal.ts | 94 +++++----- .../_datasource-runtime.ts | 2 +- .../_datasource-schema.ts | 4 +- .../_macro-abnormal.ts | 114 ++++++------ .../_macro-normal.ts | 140 +++++++-------- .../_datasource-runtime.ts | 2 +- .../_datasource-schema.ts | 4 +- .../_macro-abnormal.ts | 84 ++++----- .../_macro-normal.ts | 110 ++++++------ .../_datasource-runtime.ts | 2 +- .../_datasource-schema.ts | 4 +- .../_macro-abnormal.ts | 114 ++++++------ .../_macro-normal.ts | 140 +++++++-------- .../_datasource-runtime.ts | 2 +- .../_datasource-schema.ts | 4 +- .../_macro-normal.ts | 164 +++++++++--------- .../datasource-fetch-handler/.eslintignore | 3 + .../.eslintrc.js | 2 +- .../.prettierrc.js | 2 +- .../package.json | 4 +- .../src/index.ts | 2 +- .../tsconfig.json | 21 ++- packages/datasource-handlers/.eslintignore | 1 - packages/datasource-handlers/lerna.json | 5 - packages/datasource-handlers/package.json | 9 - .../packages/fetch/es/index.d.ts | 2 - .../packages/fetch/es/index.js | 25 --- .../packages/fetch/tsconfig.json | 10 -- .../packages/mopen/es/index.d.ts | 5 - .../packages/mopen/es/index.js | 26 --- .../packages/mopen/tsconfig.json | 10 -- .../packages/mtop/es/index.d.ts | 6 - .../packages/mtop/es/index.js | 35 ---- .../packages/mtop/tsconfig.json | 10 -- .../packages/universalMtop/es/index.d.ts | 5 - .../packages/universalMtop/es/index.js | 23 --- .../packages/universalMtop/tsconfig.json | 10 -- .../packages/urlParams/es/index.d.ts | 2 - .../packages/urlParams/es/index.js | 21 --- .../packages/urlParams/tsconfig.json | 10 -- .../datasource-mopen-handler/.eslintignore | 3 + .../datasource-mopen-handler/.eslintrc.js | 7 + .../datasource-mopen-handler/.prettierrc.js | 4 + .../package.json | 4 +- .../src/index.ts | 2 +- .../datasource-mopen-handler/tsconfig.json | 70 ++++++++ .../datasource-mtop-handler/.eslintignore | 3 + packages/datasource-mtop-handler/.eslintrc.js | 7 + .../datasource-mtop-handler/.prettierrc.js | 4 + .../package.json | 4 +- .../src/index.ts | 2 +- .../src/typings.d.ts | 0 .../datasource-mtop-handler/tsconfig.json | 70 ++++++++ .../.eslintignore | 3 + .../.eslintrc.js | 7 + .../.prettierrc.js | 4 + .../package.json | 4 +- .../src/index.ts | 2 +- .../tsconfig.json | 70 ++++++++ .../.eslintignore | 3 + .../.eslintrc.js | 7 + .../.prettierrc.js | 0 .../package.json | 4 +- .../src/index.ts | 2 +- .../tsconfig.json | 70 ++++++++ packages/types/.eslintignore | 3 + packages/types/.eslintrc.js | 9 + packages/types/.prettierrc.js | 6 + packages/types/src/data-source-handlers.ts | 15 ++ packages/types/src/data-source-interpret.ts | 41 +++++ packages/types/src/data-source-runtime.ts | 53 ++++++ packages/types/src/data-source.ts | 73 ++++++-- packages/types/src/index.ts | 3 + packages/types/src/value-type.ts | 63 ++++++- 96 files changed, 1426 insertions(+), 1076 deletions(-) create mode 100644 packages/datasource-fetch-handler/.eslintignore rename packages/{datasource-handlers => datasource-fetch-handler}/.eslintrc.js (78%) rename packages/{datasource-handlers => datasource-fetch-handler}/.prettierrc.js (61%) rename packages/{datasource-handlers/packages/fetch => datasource-fetch-handler}/package.json (88%) rename packages/{datasource-handlers/packages/fetch => datasource-fetch-handler}/src/index.ts (90%) rename packages/{datasource-handlers => datasource-fetch-handler}/tsconfig.json (95%) delete mode 100644 packages/datasource-handlers/.eslintignore delete mode 100644 packages/datasource-handlers/lerna.json delete mode 100644 packages/datasource-handlers/package.json delete mode 100644 packages/datasource-handlers/packages/fetch/es/index.d.ts delete mode 100644 packages/datasource-handlers/packages/fetch/es/index.js delete mode 100644 packages/datasource-handlers/packages/fetch/tsconfig.json delete mode 100644 packages/datasource-handlers/packages/mopen/es/index.d.ts delete mode 100644 packages/datasource-handlers/packages/mopen/es/index.js delete mode 100644 packages/datasource-handlers/packages/mopen/tsconfig.json delete mode 100644 packages/datasource-handlers/packages/mtop/es/index.d.ts delete mode 100644 packages/datasource-handlers/packages/mtop/es/index.js delete mode 100644 packages/datasource-handlers/packages/mtop/tsconfig.json delete mode 100644 packages/datasource-handlers/packages/universalMtop/es/index.d.ts delete mode 100644 packages/datasource-handlers/packages/universalMtop/es/index.js delete mode 100644 packages/datasource-handlers/packages/universalMtop/tsconfig.json delete mode 100644 packages/datasource-handlers/packages/urlParams/es/index.d.ts delete mode 100644 packages/datasource-handlers/packages/urlParams/es/index.js delete mode 100644 packages/datasource-handlers/packages/urlParams/tsconfig.json create mode 100644 packages/datasource-mopen-handler/.eslintignore create mode 100644 packages/datasource-mopen-handler/.eslintrc.js create mode 100644 packages/datasource-mopen-handler/.prettierrc.js rename packages/{datasource-handlers/packages/mopen => datasource-mopen-handler}/package.json (89%) rename packages/{datasource-handlers/packages/mopen => datasource-mopen-handler}/src/index.ts (93%) create mode 100644 packages/datasource-mopen-handler/tsconfig.json create mode 100644 packages/datasource-mtop-handler/.eslintignore create mode 100644 packages/datasource-mtop-handler/.eslintrc.js create mode 100644 packages/datasource-mtop-handler/.prettierrc.js rename packages/{datasource-handlers/packages/mtop => datasource-mtop-handler}/package.json (88%) rename packages/{datasource-handlers/packages/mtop => datasource-mtop-handler}/src/index.ts (93%) rename packages/{datasource-handlers/packages/mtop => datasource-mtop-handler}/src/typings.d.ts (100%) create mode 100644 packages/datasource-mtop-handler/tsconfig.json create mode 100644 packages/datasource-universal-mtop-handler/.eslintignore create mode 100644 packages/datasource-universal-mtop-handler/.eslintrc.js create mode 100644 packages/datasource-universal-mtop-handler/.prettierrc.js rename packages/{datasource-handlers/packages/universalMtop => datasource-universal-mtop-handler}/package.json (89%) rename packages/{datasource-handlers/packages/universalMtop => datasource-universal-mtop-handler}/src/index.ts (92%) create mode 100644 packages/datasource-universal-mtop-handler/tsconfig.json create mode 100644 packages/datasource-url-params-handler/.eslintignore create mode 100644 packages/datasource-url-params-handler/.eslintrc.js create mode 100644 packages/datasource-url-params-handler/.prettierrc.js rename packages/{datasource-handlers/packages/urlParams => datasource-url-params-handler}/package.json (88%) rename packages/{datasource-handlers/packages/urlParams => datasource-url-params-handler}/src/index.ts (85%) create mode 100644 packages/datasource-url-params-handler/tsconfig.json create mode 100644 packages/types/.eslintignore create mode 100644 packages/types/.eslintrc.js create mode 100644 packages/types/.prettierrc.js create mode 100644 packages/types/src/data-source-handlers.ts create mode 100644 packages/types/src/data-source-interpret.ts create mode 100644 packages/types/src/data-source-runtime.ts diff --git a/packages/datasource-engine/.eslintignore b/packages/datasource-engine/.eslintignore index 30bc16279..fecb7c26d 100644 --- a/packages/datasource-engine/.eslintignore +++ b/packages/datasource-engine/.eslintignore @@ -1 +1,3 @@ -/node_modules \ No newline at end of file +/node_modules +/es +/lib \ No newline at end of file diff --git a/packages/datasource-engine/.eslintrc.js b/packages/datasource-engine/.eslintrc.js index b33327802..8c13fcaf4 100644 --- a/packages/datasource-engine/.eslintrc.js +++ b/packages/datasource-engine/.eslintrc.js @@ -1,7 +1,7 @@ module.exports = { - extends: '../../.eslintrc.js', + extends: '../../.eslintrc', rules: { '@typescript-eslint/no-parameter-properties': 1, - 'no-param-reassign': 0 + 'no-param-reassign': 0, }, }; diff --git a/packages/datasource-engine/.prettierrc.js b/packages/datasource-engine/.prettierrc.js index d2db80ead..de2f53cdf 100644 --- a/packages/datasource-engine/.prettierrc.js +++ b/packages/datasource-engine/.prettierrc.js @@ -1,4 +1,4 @@ module.exports = { singleQuote: true, - trailingComma: 'always', + trailingComma: 'all', }; diff --git a/packages/datasource-engine/package.json b/packages/datasource-engine/package.json index 99c775919..6479c7c0b 100644 --- a/packages/datasource-engine/package.json +++ b/packages/datasource-engine/package.json @@ -15,15 +15,10 @@ }, "typings": "dist/index.d.ts", "dependencies": { - "@ali/build-success-types": "^0.1.2-alpha.35", + "@ali/lowcode-types": "^0.8.13", "typescript": "^3.9.7" }, "devDependencies": { - "@ali/datasource-engine-universal-mtop-handler": "1.0.0-alpha.2", - "@ali/datasource-engine-url-params-handler": "^1.0.0-alpha.3", - "@ali/lowcode-datasource-http-handler": "^1.0.0-alpha.1", - "@ali/lowcode-datasource-url-params-handler": "^1.0.0-alpha.3", - "@ali/ng-lc-types": "^1.0.0-r2009222d5o6k8r8", "@ava/babel": "^1.0.1", "@types/sinon": "^9.0.5", "ava": "3.11.1", diff --git a/packages/datasource-engine/src/core/RuntimeDataSourceItem.ts b/packages/datasource-engine/src/core/RuntimeDataSourceItem.ts index b2dff9bb1..d4184707a 100644 --- a/packages/datasource-engine/src/core/RuntimeDataSourceItem.ts +++ b/packages/datasource-engine/src/core/RuntimeDataSourceItem.ts @@ -1,12 +1,13 @@ +/* eslint-disable @typescript-eslint/indent */ import { + IDataSourceRuntimeContext, IRuntimeDataSource, + RequestHandler, RuntimeDataSourceConfig, RuntimeDataSourceStatus, - IRuntimeContext, - RequestHandler, RuntimeOptionsConfig, UrlParamsHandler, -} from '@ali/build-success-types'; +} from '@ali/lowcode-types'; class RuntimeDataSourceItem< TParams extends Record = Record, @@ -21,19 +22,19 @@ class RuntimeDataSourceItem< private _dataSourceConfig: RuntimeDataSourceConfig; private _request: - | RequestHandler<{ data: TResultData }> - | UrlParamsHandler; + | RequestHandler<{ data: TResultData }> + | UrlParamsHandler; - private _context: IRuntimeContext; + private _context: IDataSourceRuntimeContext; private _options?: RuntimeOptionsConfig; constructor( dataSourceConfig: RuntimeDataSourceConfig, request: - | RequestHandler<{ data: TResultData }> - | UrlParamsHandler, - context: IRuntimeContext, + | RequestHandler<{ data: TResultData }> + | UrlParamsHandler, + context: IDataSourceRuntimeContext, ) { this._dataSourceConfig = dataSourceConfig; this._request = request; @@ -52,7 +53,7 @@ class RuntimeDataSourceItem< return this._status; } - public async load(params?: TParams) { + async load(params?: TParams) { if (!this._dataSourceConfig) return; // 考虑没有绑定对应的 handler 的情况 if (!this._request) { diff --git a/packages/datasource-engine/src/core/adapter.ts b/packages/datasource-engine/src/core/adapter.ts index b1274b6ae..41a476bc7 100644 --- a/packages/datasource-engine/src/core/adapter.ts +++ b/packages/datasource-engine/src/core/adapter.ts @@ -7,16 +7,19 @@ import { } from './../utils'; // 将不同渠道给的 schema 转为 runtime 需要的类型 -import { - DataSource, - IPageContext, - DataSourceConfig, - RuntimeDataSourceConfig, - DataSourceMap, -} from '@ali/build-success-types'; import { defaultDataHandler, defaultWillFetch } from '../helpers'; +import { + DataSourceMap, + IDataSourceRuntimeContext, + InterpretDataSource, + InterpretDataSourceConfig, + RuntimeDataSourceConfig, +} from '@ali/lowcode-types'; -const adapt2Runtime = (dataSource: DataSource, context: IPageContext) => { +const adapt2Runtime = ( + dataSource: InterpretDataSource, + context: IDataSourceRuntimeContext, +) => { const { list: interpretConfigList, dataHandler: interpretDataHandler, @@ -34,7 +37,7 @@ const adapt2Runtime = (dataSource: DataSource, context: IPageContext) => { }; } const list: RuntimeDataSourceConfig[] = interpretConfigList.map( - (el: DataSourceConfig) => { + (el: InterpretDataSourceConfig) => { return { id: el.id, isInit: diff --git a/packages/datasource-engine/src/core/reloadDataSourceFactory.ts b/packages/datasource-engine/src/core/reloadDataSourceFactory.ts index ac8776341..8433d0d0a 100644 --- a/packages/datasource-engine/src/core/reloadDataSourceFactory.ts +++ b/packages/datasource-engine/src/core/reloadDataSourceFactory.ts @@ -1,8 +1,8 @@ import { - RuntimeDataSource, DataSourceMap, + RuntimeDataSource, RuntimeDataSourceConfig, -} from '@ali/build-success-types'; +} from '@ali/lowcode-types'; export const reloadDataSourceFactory = ( dataSource: RuntimeDataSource, @@ -14,7 +14,8 @@ export const reloadDataSourceFactory = ( // 单独处理 urlParams 类型的 dataSource.list .filter( - (el: RuntimeDataSourceConfig) => el.type === 'urlParams' && + (el: RuntimeDataSourceConfig) => + el.type === 'urlParams' && (typeof el.isInit === 'boolean' ? el.isInit : true), ) .forEach((el: RuntimeDataSourceConfig) => { @@ -50,13 +51,8 @@ export const reloadDataSourceFactory = ( ds.isInit && ds.isSync ) { - // TODO: 我理解这个异常也应该吃掉的,待确认 - try { - // eslint-disable-next-line no-await-in-loop - await dataSourceMap[ds.id].load(); - } catch (e) { - console.error(e); - } + // eslint-disable-next-line no-await-in-loop + await dataSourceMap[ds.id].load(); } } diff --git a/packages/datasource-engine/src/helpers/index.ts b/packages/datasource-engine/src/helpers/index.ts index d13e747f6..71565b434 100644 --- a/packages/datasource-engine/src/helpers/index.ts +++ b/packages/datasource-engine/src/helpers/index.ts @@ -1,5 +1,6 @@ -import { DataHandler } from '@ali/build-success-types'; +import { DataHandler } from '@ali/lowcode-types'; +// eslint-disable-next-line @typescript-eslint/no-empty-function function noop() {} // 默认的 dataSourceItem 的 dataHandler diff --git a/packages/datasource-engine/src/interpret/DataSourceEngineFactory.ts b/packages/datasource-engine/src/interpret/DataSourceEngineFactory.ts index a31a5a095..4adcf1f82 100644 --- a/packages/datasource-engine/src/interpret/DataSourceEngineFactory.ts +++ b/packages/datasource-engine/src/interpret/DataSourceEngineFactory.ts @@ -1,15 +1,14 @@ -import { - IRuntimeContext, - IRuntimeDataSource, - DataSource, - RuntimeDataSourceConfig, - RuntimeDataSource, - RequestHandlersMap, -} from '@ali/build-success-types'; - import { adapt2Runtime } from '../core/adapter'; import { RuntimeDataSourceItem } from '../core/RuntimeDataSourceItem'; import { reloadDataSourceFactory } from '../core/reloadDataSourceFactory'; +import { + IDataSourceRuntimeContext, + InterpretDataSource, + IRuntimeDataSource, + RequestHandlersMap, + RuntimeDataSource, + RuntimeDataSourceConfig, +} from '@ali/lowcode-types'; // TODO: requestConfig mtop 默认的请求 config 怎么处理? /** @@ -18,13 +17,11 @@ import { reloadDataSourceFactory } from '../core/reloadDataSourceFactory'; */ export default ( - dataSource: DataSource, - context: IRuntimeContext, + dataSource: InterpretDataSource, + context: IDataSourceRuntimeContext, extraConfig: { requestHandlersMap: RequestHandlersMap<{ data: unknown }>; - } = { - requestHandlersMap: {}, - }, + } = { requestHandlersMap: {} }, ) => { const { requestHandlersMap } = extraConfig; diff --git a/packages/datasource-engine/src/runtime/RuntimeDataSourceEngineFactory.ts b/packages/datasource-engine/src/runtime/RuntimeDataSourceEngineFactory.ts index 2a98f1a14..d504054c3 100644 --- a/packages/datasource-engine/src/runtime/RuntimeDataSourceEngineFactory.ts +++ b/packages/datasource-engine/src/runtime/RuntimeDataSourceEngineFactory.ts @@ -1,11 +1,12 @@ +/* eslint-disable @typescript-eslint/indent */ /* eslint-disable no-nested-ternary */ import { - IRuntimeContext, IRuntimeDataSource, + IDataSourceRuntimeContext, + RequestHandlersMap, RuntimeDataSourceConfig, RuntimeDataSource, - RequestHandlersMap, -} from '@ali/build-success-types'; +} from '@ali/lowcode-types'; import { RuntimeDataSourceItem } from '../core'; import { reloadDataSourceFactory } from '../core/reloadDataSourceFactory'; @@ -22,24 +23,22 @@ import { */ export default ( dataSource: RuntimeDataSource, - context: IRuntimeContext, + context: IDataSourceRuntimeContext, extraConfig: { requestHandlersMap: RequestHandlersMap<{ data: unknown }>; - } = { - requestHandlersMap: {}, - }, + } = { requestHandlersMap: {} }, ) => { const { requestHandlersMap } = extraConfig; // TODO: 对于出码类型,需要做一层数据兼容,给一些必要的值设置默认值,先兜底几个必要的 - dataSource.list.forEach((ds) => { + dataSource.list.forEach(ds => { ds.isInit = ds.isInit || true; ds.isSync = ds.isSync || false; ds.shouldFetch = !ds.shouldFetch ? defaultShouldFetch : typeof ds.shouldFetch === 'function' - ? ds.shouldFetch.bind(context) - : ds.shouldFetch; + ? ds.shouldFetch.bind(context) + : ds.shouldFetch; ds.willFetch = ds.willFetch ? ds.willFetch.bind(context) : defaultWillFetch; ds.dataHandler = ds.dataHandler ? ds.dataHandler.bind(context) diff --git a/packages/datasource-engine/src/utils.ts b/packages/datasource-engine/src/utils.ts index f39171e96..b31076f28 100644 --- a/packages/datasource-engine/src/utils.ts +++ b/packages/datasource-engine/src/utils.ts @@ -1,16 +1,20 @@ /* eslint-disable no-new-func */ + import { - JSExpression, - IRuntimeContext, CompositeValue, + IDataSourceRuntimeContext, + InterpretDataSourceConfig, + isJSExpression, + isJSFunction, + JSExpression, JSFunction, JSONObject, - isJSExpression, - DataSourceConfig, - isJSFunction, -} from '@ali/build-success-types'; +} from '@ali/lowcode-types'; -export const transformExpression = (code: string, context: IRuntimeContext) => { +export const transformExpression = ( + code: string, + context: IDataSourceRuntimeContext, +) => { try { return new Function(`return (${code})`).call(context); } catch (error) { @@ -20,7 +24,10 @@ export const transformExpression = (code: string, context: IRuntimeContext) => { } }; -export const transformFunction = (code: string, context: IRuntimeContext) => { +export const transformFunction = ( + code: string, + context: IDataSourceRuntimeContext, +) => { try { return new Function(`return (${code})`).call(context).bind(context); } catch (error) { @@ -36,12 +43,13 @@ export const transformBoolStr = (str: string) => { export const getRuntimeJsValue = ( value: JSExpression | JSFunction, - context: IRuntimeContext, + context: IDataSourceRuntimeContext, ) => { if (!['JSExpression', 'JSFunction'].includes(value.type)) { console.error(`translate error, value is ${JSON.stringify(value)}`); return ''; } + // TODO: 类型修复 const code = value.compiled || value.value; return value.type === 'JSFunction' ? transformFunction(code, context) @@ -66,7 +74,7 @@ export const getRuntimeBaseValue = (type: string, value: any) => { export const getRuntimeValueFromConfig = ( type: string, value: CompositeValue, - context: IRuntimeContext, + context: IDataSourceRuntimeContext, ) => { if (!value) return undefined; if (isJSExpression(value) || isJSFunction(value)) { @@ -77,7 +85,7 @@ export const getRuntimeValueFromConfig = ( export const buildJsonObj = ( params: JSONObject | JSExpression, - context: IRuntimeContext, + context: IDataSourceRuntimeContext, ) => { const result: Record = {}; if (isJSExpression(params)) { @@ -96,8 +104,8 @@ export const buildJsonObj = ( }; export const buildShouldFetch = ( - ds: DataSourceConfig, - context: IRuntimeContext, + ds: InterpretDataSourceConfig, + context: IDataSourceRuntimeContext, ) => { if (!ds.options || !ds.shouldFetch) { return true; // 默认为 true @@ -110,12 +118,12 @@ export const buildShouldFetch = ( }; export const buildOptions = ( - ds: DataSourceConfig, - context: IRuntimeContext, + ds: InterpretDataSourceConfig, + context: IDataSourceRuntimeContext, ) => { const { options } = ds; if (!options) return undefined; - return function () { + return function() { return { uri: getRuntimeValueFromConfig('string', options.uri, context), params: options.params ? buildJsonObj(options.params, context) : {}, diff --git a/packages/datasource-engine/test/_helpers/mock-context.ts b/packages/datasource-engine/test/_helpers/mock-context.ts index f602489de..7b62f29b7 100644 --- a/packages/datasource-engine/test/_helpers/mock-context.ts +++ b/packages/datasource-engine/test/_helpers/mock-context.ts @@ -1,13 +1,16 @@ -import { IDataSourceEngine, IRuntimeContext } from '@ali/build-success-types'; +import { + IDataSourceRuntimeContext, + IDataSourceEngine +} from '@ali/lowcode-types'; -export class MockContext> - implements IRuntimeContext { +export class MockContext = Record> + implements IDataSourceRuntimeContext { private _dataSourceEngine: IDataSourceEngine; public constructor( private _state: TState, private _createDataSourceEngine: ( - context: IRuntimeContext + context: IDataSourceRuntimeContext ) => IDataSourceEngine, private _customMethods: Record any> = {} ) { diff --git a/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/_datasource-runtime.ts b/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/_datasource-runtime.ts index ccb41e1f0..58002ead2 100644 --- a/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/_datasource-runtime.ts +++ b/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/_datasource-runtime.ts @@ -1,4 +1,4 @@ -import { RuntimeDataSource } from '@ali/build-success-types'; +import { RuntimeDataSource } from '@ali/lowcode-types'; // 这里仅仅是数据源部分的: // @see: https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 diff --git a/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/_datasource-schema.ts b/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/_datasource-schema.ts index 7218c7864..848a85687 100644 --- a/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/_datasource-schema.ts +++ b/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/_datasource-schema.ts @@ -1,8 +1,8 @@ -import { DataSource } from '@ali/build-success-types'; +import { InterpretDataSource } from '@ali/lowcode-types'; // 这里仅仅是数据源部分的 schema: // @see: https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 -export const DATA_SOURCE_SCHEMA: DataSource = { +export const DATA_SOURCE_SCHEMA: InterpretDataSource = { list: [ { id: 'user', diff --git a/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/_macro-abnormal.ts b/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/_macro-abnormal.ts index 4a2297aa0..78c0f5cb2 100644 --- a/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/_macro-abnormal.ts +++ b/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/_macro-abnormal.ts @@ -1,10 +1,10 @@ import { - DataSource, + InterpretDataSource, IDataSourceEngine, - IRuntimeContext, + IDataSourceRuntimeContext, RuntimeDataSource, RuntimeDataSourceStatus, -} from '@ali/build-success-types'; +} from '@ali/lowcode-types'; import sinon from 'sinon'; import { delay, MockContext } from '../../_helpers'; @@ -17,56 +17,56 @@ export const abnormalScene: Macro<[ { create: ( dataSource: any, - ctx: IRuntimeContext, + ctx: IDataSourceRuntimeContext, options: any ) => IDataSourceEngine; - dataSource: RuntimeDataSource | DataSource; + dataSource: RuntimeDataSource | InterpretDataSource; } ]> = async ( t: ExecutionContext<{ clock: SinonFakeTimers }>, { create, dataSource }, -) => { - const { clock } = t.context; - const ERROR_MSG = 'test error'; - const fetchHandler = sinon.fake(async () => { - await delay(100); - throw new Error(ERROR_MSG); - }); + ) => { + const { clock } = t.context; + const ERROR_MSG = 'test error'; + const fetchHandler = sinon.fake(async () => { + await delay(100); + throw new Error(ERROR_MSG); + }); - const context = new MockContext>({}, (ctx) => create(dataSource, ctx, { - requestHandlersMap: { - fetch: fetchHandler, - }, - })); + const context = new MockContext>({}, (ctx) => create(dataSource, ctx, { + requestHandlersMap: { + fetch: fetchHandler, + }, + })); - const setState = sinon.spy(context, 'setState'); + const setState = sinon.spy(context, 'setState'); - // 一开始应该是初始状态 - t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Initial); + // 一开始应该是初始状态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Initial); - const loading = context.reloadDataSource(); + const loading = context.reloadDataSource(); - await clock.tickAsync(50); + await clock.tickAsync(50); - // 中间应该有 loading 态 - t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loading); + // 中间应该有 loading 态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loading); - await Promise.all([clock.runAllAsync(), loading]); + await Promise.all([clock.runAllAsync(), loading]); - // 最后应该失败了,error 状态 - t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Error); + // 最后应该失败了,error 状态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Error); - // 检查数据源的数据 - t.deepEqual(context.dataSourceMap.user.data, undefined); - t.not(context.dataSourceMap.user.error, undefined); - t.regex(context.dataSourceMap.user.error!.message, new RegExp(ERROR_MSG)); + // 检查数据源的数据 + t.deepEqual(context.dataSourceMap.user.data, undefined); + t.not(context.dataSourceMap.user.error, undefined); + t.regex(context.dataSourceMap.user.error!.message, new RegExp(ERROR_MSG)); - // 检查状态数据 - t.assert(setState.notCalled); - t.deepEqual(context.state.user, undefined); + // 检查状态数据 + t.assert(setState.notCalled); + t.deepEqual(context.state.user, undefined); - // fetchHandler 不应该被调 - t.assert(fetchHandler.calledOnce); -}; + // fetchHandler 不应该被调 + t.assert(fetchHandler.calledOnce); + }; abnormalScene.title = (providedTitle) => providedTitle || 'abnormal scene'; diff --git a/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/_macro-normal.ts b/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/_macro-normal.ts index 7115ab1eb..9d2a7e353 100644 --- a/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/_macro-normal.ts +++ b/packages/datasource-engine/test/scenes/p0-0-simplest-defaults/_macro-normal.ts @@ -1,10 +1,10 @@ import { - DataSource, + InterpretDataSource, IDataSourceEngine, - IRuntimeContext, + IDataSourceRuntimeContext, RuntimeDataSource, RuntimeDataSourceStatus, -} from '@ali/build-success-types'; +} from '@ali/lowcode-types'; import sinon from 'sinon'; import { delay, MockContext } from '../../_helpers'; @@ -17,65 +17,65 @@ export const normalScene: Macro<[ { create: ( dataSource: any, - ctx: IRuntimeContext, + ctx: IDataSourceRuntimeContext, options: any ) => IDataSourceEngine; - dataSource: RuntimeDataSource | DataSource; + dataSource: RuntimeDataSource | InterpretDataSource; } ]> = async ( t: ExecutionContext<{ clock: SinonFakeTimers }>, { create, dataSource }, -) => { - const { clock } = t.context; + ) => { + const { clock } = t.context; - const USER_DATA = { - name: 'Alice', - age: 18, + const USER_DATA = { + name: 'Alice', + age: 18, + }; + + const fetchHandler = sinon.fake(async () => { + await delay(100); + return { data: USER_DATA }; + }); + + const context = new MockContext>({}, (ctx) => create(dataSource, ctx, { + requestHandlersMap: { + fetch: fetchHandler, + }, + })); + + const setState = sinon.spy(context, 'setState'); + + // 一开始应该是初始状态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Initial); + + const loading = context.reloadDataSource(); + + await clock.tickAsync(50); + + // 中间应该有 loading 态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loading); + + await Promise.all([clock.runAllAsync(), loading]); + + // 最后应该成功了,loaded 状态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loaded); + + // 检查数据源的数据 + t.deepEqual(context.dataSourceMap.user.data, USER_DATA); + t.deepEqual(context.dataSourceMap.user.error, undefined); + + // 检查状态数据 + t.assert(setState.calledOnce); + t.deepEqual(context.state.user, USER_DATA); + + // fetchHandler 应该被调用了一次 + t.assert(fetchHandler.calledOnce); + + const firstListItemOptions = DATA_SOURCE_SCHEMA.list[0].options; + const fetchHandlerCallArgs = fetchHandler.firstCall.args[0]; + // 检查调用参数 + t.is(firstListItemOptions.uri, fetchHandlerCallArgs.uri); }; - const fetchHandler = sinon.fake(async () => { - await delay(100); - return { data: USER_DATA }; - }); - - const context = new MockContext>({}, (ctx) => create(dataSource, ctx, { - requestHandlersMap: { - fetch: fetchHandler, - }, - })); - - const setState = sinon.spy(context, 'setState'); - - // 一开始应该是初始状态 - t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Initial); - - const loading = context.reloadDataSource(); - - await clock.tickAsync(50); - - // 中间应该有 loading 态 - t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loading); - - await Promise.all([clock.runAllAsync(), loading]); - - // 最后应该成功了,loaded 状态 - t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loaded); - - // 检查数据源的数据 - t.deepEqual(context.dataSourceMap.user.data, USER_DATA); - t.deepEqual(context.dataSourceMap.user.error, undefined); - - // 检查状态数据 - t.assert(setState.calledOnce); - t.deepEqual(context.state.user, USER_DATA); - - // fetchHandler 应该被调用了一次 - t.assert(fetchHandler.calledOnce); - - const firstListItemOptions = DATA_SOURCE_SCHEMA.list[0].options; - const fetchHandlerCallArgs = fetchHandler.firstCall.args[0]; - // 检查调用参数 - t.is(firstListItemOptions.uri, fetchHandlerCallArgs.uri); -}; - normalScene.title = (providedTitle) => providedTitle || 'normal scene'; diff --git a/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/_datasource-runtime.ts b/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/_datasource-runtime.ts index 09e244a38..c5fe1194c 100644 --- a/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/_datasource-runtime.ts +++ b/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/_datasource-runtime.ts @@ -1,4 +1,4 @@ -import { RuntimeDataSource } from '@ali/build-success-types'; +import { RuntimeDataSource } from '@ali/lowcode-types'; // 这里仅仅是数据源部分的: // @see: https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 diff --git a/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/_datasource-schema.ts b/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/_datasource-schema.ts index e4e549ece..2c75c180a 100644 --- a/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/_datasource-schema.ts +++ b/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/_datasource-schema.ts @@ -1,8 +1,8 @@ -import { DataSource } from '@ali/build-success-types'; +import { InterpretDataSource } from '@ali/lowcode-types'; // 这里仅仅是数据源部分的 schema: // @see: https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 -export const DATA_SOURCE_SCHEMA: DataSource = { +export const DATA_SOURCE_SCHEMA: InterpretDataSource = { list: [ { id: 'user', diff --git a/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/_macro-abnormal.ts b/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/_macro-abnormal.ts index fc0aaa0b3..f81db6b49 100644 --- a/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/_macro-abnormal.ts +++ b/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/_macro-abnormal.ts @@ -1,10 +1,10 @@ import { - DataSource, + InterpretDataSource, IDataSourceEngine, - IRuntimeContext, + IDataSourceRuntimeContext, RuntimeDataSource, RuntimeDataSourceStatus, -} from '@ali/build-success-types'; +} from '@ali/lowcode-types'; import sinon from 'sinon'; import { bindRuntimeContext, delay, MockContext } from '../../_helpers'; @@ -17,80 +17,80 @@ export const abnormalScene: Macro<[ { create: ( dataSource: any, - ctx: IRuntimeContext, + ctx: IDataSourceRuntimeContext, options: any ) => IDataSourceEngine; - dataSource: RuntimeDataSource | DataSource; + dataSource: RuntimeDataSource | InterpretDataSource; } ]> = async ( t: ExecutionContext<{ clock: SinonFakeTimers }>, { create, dataSource }, -) => { - const { clock } = t.context; + ) => { + const { clock } = t.context; - const USER_DATA = { - id: 9527, - name: 'Alice', + const USER_DATA = { + id: 9527, + name: 'Alice', + }; + const ERROR_MSG = 'test error'; + const fetchHandler = sinon.fake(async ({ uri }) => { + await delay(100); + if (/user/.test(uri)) { + return { data: USER_DATA }; + } else { + throw new Error(ERROR_MSG); + } + }); + + const context = new MockContext>({}, (ctx) => create(bindRuntimeContext(dataSource, ctx), ctx, { + requestHandlersMap: { + fetch: fetchHandler, + }, + })); + + const setState = sinon.spy(context, 'setState'); + + // 一开始应该是初始状态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Initial); + t.is(context.dataSourceMap.orders.status, RuntimeDataSourceStatus.Initial); + + const loading = context.reloadDataSource(); + + await clock.tickAsync(50); + + // 中间应该有 loading 态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loading); + + await clock.tickAsync(50); + + t.is(context.dataSourceMap.orders.status, RuntimeDataSourceStatus.Loading); + + await Promise.all([clock.runAllAsync(), loading]); + + // 最后 user 应该成功了,loaded + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loaded); + // 最后 orders 应该失败了,error 状态 + t.is(context.dataSourceMap.orders.status, RuntimeDataSourceStatus.Error); + + // 检查数据源的数据 + t.deepEqual(context.dataSourceMap.user.data, USER_DATA); + t.is(context.dataSourceMap.user.error, undefined); + t.deepEqual(context.dataSourceMap.orders.data, undefined); + t.not(context.dataSourceMap.orders.error, undefined); + t.regex(context.dataSourceMap.orders.error!.message, new RegExp(ERROR_MSG)); + + // 检查状态数据 + t.assert(setState.calledOnce); + t.deepEqual(context.state.user, USER_DATA); + t.is(context.state.orders, undefined); + + // fetchHandler 应该被调用了2次 + t.assert(fetchHandler.calledTwice); + + const firstListItemOptions = DATA_SOURCE_SCHEMA.list[0].options; + const fetchHandlerCallArgs = fetchHandler.firstCall.args[0]; + // 检查调用参数 + t.is(firstListItemOptions.uri, fetchHandlerCallArgs.uri); }; - const ERROR_MSG = 'test error'; - const fetchHandler = sinon.fake(async ({ uri }) => { - await delay(100); - if (/user/.test(uri)) { - return { data: USER_DATA }; - } else { - throw new Error(ERROR_MSG); - } - }); - - const context = new MockContext>({}, (ctx) => create(bindRuntimeContext(dataSource, ctx), ctx, { - requestHandlersMap: { - fetch: fetchHandler, - }, - })); - - const setState = sinon.spy(context, 'setState'); - - // 一开始应该是初始状态 - t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Initial); - t.is(context.dataSourceMap.orders.status, RuntimeDataSourceStatus.Initial); - - const loading = context.reloadDataSource(); - - await clock.tickAsync(50); - - // 中间应该有 loading 态 - t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loading); - - await clock.tickAsync(50); - - t.is(context.dataSourceMap.orders.status, RuntimeDataSourceStatus.Loading); - - await Promise.all([clock.runAllAsync(), loading]); - - // 最后 user 应该成功了,loaded - t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loaded); - // 最后 orders 应该失败了,error 状态 - t.is(context.dataSourceMap.orders.status, RuntimeDataSourceStatus.Error); - - // 检查数据源的数据 - t.deepEqual(context.dataSourceMap.user.data, USER_DATA); - t.is(context.dataSourceMap.user.error, undefined); - t.deepEqual(context.dataSourceMap.orders.data, undefined); - t.not(context.dataSourceMap.orders.error, undefined); - t.regex(context.dataSourceMap.orders.error!.message, new RegExp(ERROR_MSG)); - - // 检查状态数据 - t.assert(setState.calledOnce); - t.deepEqual(context.state.user, USER_DATA); - t.is(context.state.orders, undefined); - - // fetchHandler 应该被调用了2次 - t.assert(fetchHandler.calledTwice); - - const firstListItemOptions = DATA_SOURCE_SCHEMA.list[0].options; - const fetchHandlerCallArgs = fetchHandler.firstCall.args[0]; - // 检查调用参数 - t.is(firstListItemOptions.uri, fetchHandlerCallArgs.uri); -}; abnormalScene.title = (providedTitle) => providedTitle || 'abnormal scene'; diff --git a/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/_macro-normal.ts b/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/_macro-normal.ts index 2587c08b3..c6a95c672 100644 --- a/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/_macro-normal.ts +++ b/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/_macro-normal.ts @@ -1,10 +1,10 @@ import { - DataSource, + InterpretDataSource, IDataSourceEngine, - IRuntimeContext, + IDataSourceRuntimeContext, RuntimeDataSource, RuntimeDataSourceStatus, -} from '@ali/build-success-types'; +} from '@ali/lowcode-types'; import sinon from 'sinon'; import { bindRuntimeContext, delay, MockContext } from '../../_helpers'; @@ -17,76 +17,76 @@ export const normalScene: Macro<[ { create: ( dataSource: any, - ctx: IRuntimeContext, + ctx: IDataSourceRuntimeContext, options: any ) => IDataSourceEngine; - dataSource: RuntimeDataSource | DataSource; + dataSource: RuntimeDataSource | InterpretDataSource; } ]> = async ( t: ExecutionContext<{ clock: SinonFakeTimers }>, { create, dataSource }, -) => { - const { clock } = t.context; + ) => { + const { clock } = t.context; - const USER_DATA = { - id: 9527, - name: 'Alice', + const USER_DATA = { + id: 9527, + name: 'Alice', + }; + + const ORDERS_DATA = [{ id: 123 }, { id: 456 }]; + + const fetchHandler = sinon.fake(async ({ uri }) => { + await delay(100); + return { data: /user/.test(uri) ? USER_DATA : ORDERS_DATA }; + }); + + const context = new MockContext>({}, (ctx) => create(bindRuntimeContext(dataSource, ctx), ctx, { + requestHandlersMap: { + fetch: fetchHandler, + }, + })); + + const setState = sinon.spy(context, 'setState'); + + // 一开始应该是初始状态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Initial); + t.is(context.dataSourceMap.orders.status, RuntimeDataSourceStatus.Initial); + + const loading = context.reloadDataSource(); + + await clock.tickAsync(50); + + // 中间应该有 loading 态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loading); + + await clock.tickAsync(50); + + t.is(context.dataSourceMap.orders.status, RuntimeDataSourceStatus.Loading); + + await Promise.all([clock.runAllAsync(), loading]); + + // 最后应该成功了,loaded 状态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loaded); + t.is(context.dataSourceMap.orders.status, RuntimeDataSourceStatus.Loaded); + + // 检查数据源的数据 + t.deepEqual(context.dataSourceMap.user.data, USER_DATA); + t.deepEqual(context.dataSourceMap.user.error, undefined); + t.deepEqual(context.dataSourceMap.orders.data, ORDERS_DATA); + t.deepEqual(context.dataSourceMap.orders.error, undefined); + + // 检查状态数据 + t.assert(setState.calledTwice); + t.deepEqual(context.state.user, USER_DATA); + t.deepEqual(context.state.orders, ORDERS_DATA); + + // fetchHandler 应该被调用了2次 + t.assert(fetchHandler.calledTwice); + + // 检查调用参数 + const firstListItemOptions = DATA_SOURCE_SCHEMA.list[0].options; + const fetchHandlerCallArgs = fetchHandler.firstCall.args[0]; + t.is(firstListItemOptions.uri, fetchHandlerCallArgs.uri); }; - const ORDERS_DATA = [{ id: 123 }, { id: 456 }]; - - const fetchHandler = sinon.fake(async ({ uri }) => { - await delay(100); - return { data: /user/.test(uri) ? USER_DATA : ORDERS_DATA }; - }); - - const context = new MockContext>({}, (ctx) => create(bindRuntimeContext(dataSource, ctx), ctx, { - requestHandlersMap: { - fetch: fetchHandler, - }, - })); - - const setState = sinon.spy(context, 'setState'); - - // 一开始应该是初始状态 - t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Initial); - t.is(context.dataSourceMap.orders.status, RuntimeDataSourceStatus.Initial); - - const loading = context.reloadDataSource(); - - await clock.tickAsync(50); - - // 中间应该有 loading 态 - t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loading); - - await clock.tickAsync(50); - - t.is(context.dataSourceMap.orders.status, RuntimeDataSourceStatus.Loading); - - await Promise.all([clock.runAllAsync(), loading]); - - // 最后应该成功了,loaded 状态 - t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loaded); - t.is(context.dataSourceMap.orders.status, RuntimeDataSourceStatus.Loaded); - - // 检查数据源的数据 - t.deepEqual(context.dataSourceMap.user.data, USER_DATA); - t.deepEqual(context.dataSourceMap.user.error, undefined); - t.deepEqual(context.dataSourceMap.orders.data, ORDERS_DATA); - t.deepEqual(context.dataSourceMap.orders.error, undefined); - - // 检查状态数据 - t.assert(setState.calledTwice); - t.deepEqual(context.state.user, USER_DATA); - t.deepEqual(context.state.orders, ORDERS_DATA); - - // fetchHandler 应该被调用了2次 - t.assert(fetchHandler.calledTwice); - - // 检查调用参数 - const firstListItemOptions = DATA_SOURCE_SCHEMA.list[0].options; - const fetchHandlerCallArgs = fetchHandler.firstCall.args[0]; - t.is(firstListItemOptions.uri, fetchHandlerCallArgs.uri); -}; - normalScene.title = (providedTitle) => providedTitle || 'normal scene'; diff --git a/packages/datasource-engine/test/scenes/p0-0-url-params/_datasource-runtime.ts b/packages/datasource-engine/test/scenes/p0-0-url-params/_datasource-runtime.ts index 2f58b64e0..09b060b49 100644 --- a/packages/datasource-engine/test/scenes/p0-0-url-params/_datasource-runtime.ts +++ b/packages/datasource-engine/test/scenes/p0-0-url-params/_datasource-runtime.ts @@ -1,4 +1,4 @@ -import { RuntimeDataSource } from '@ali/build-success-types'; +import { RuntimeDataSource } from '@ali/lowcode-types'; // 这里仅仅是数据源部分的: // @see: https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 diff --git a/packages/datasource-engine/test/scenes/p0-0-url-params/_datasource-schema.ts b/packages/datasource-engine/test/scenes/p0-0-url-params/_datasource-schema.ts index 9b00b9300..20fcb2154 100644 --- a/packages/datasource-engine/test/scenes/p0-0-url-params/_datasource-schema.ts +++ b/packages/datasource-engine/test/scenes/p0-0-url-params/_datasource-schema.ts @@ -1,8 +1,8 @@ -import { DataSource } from '@ali/build-success-types'; +import { InterpretDataSource } from '@ali/lowcode-types'; // 这里仅仅是数据源部分的 schema: // @see: https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 -export const DATA_SOURCE_SCHEMA: DataSource = { +export const DATA_SOURCE_SCHEMA: InterpretDataSource = { list: [ { id: 'urlParams', diff --git a/packages/datasource-engine/test/scenes/p0-0-url-params/_macro-normal.ts b/packages/datasource-engine/test/scenes/p0-0-url-params/_macro-normal.ts index 4b0b9bc06..0156af315 100644 --- a/packages/datasource-engine/test/scenes/p0-0-url-params/_macro-normal.ts +++ b/packages/datasource-engine/test/scenes/p0-0-url-params/_macro-normal.ts @@ -1,10 +1,10 @@ import { - DataSource, + InterpretDataSource, IDataSourceEngine, - IRuntimeContext, + IDataSourceRuntimeContext, RuntimeDataSource, RuntimeDataSourceStatus, -} from '@ali/build-success-types'; +} from '@ali/lowcode-types'; import sinon from 'sinon'; import { MockContext } from '../../_helpers'; @@ -16,57 +16,57 @@ export const normalScene: Macro<[ { create: ( dataSource: any, - ctx: IRuntimeContext, + ctx: IDataSourceRuntimeContext, options: any ) => IDataSourceEngine; - dataSource: RuntimeDataSource | DataSource; + dataSource: RuntimeDataSource | InterpretDataSource; } ]> = async ( t: ExecutionContext<{ clock: SinonFakeTimers }>, { create, dataSource }, -) => { - const { clock } = t.context; + ) => { + const { clock } = t.context; - const URL_PARAMS = { - name: 'Alice', - age: '18', + const URL_PARAMS = { + name: 'Alice', + age: '18', + }; + + const urlParamsHandler = sinon.fake(async () => { + return URL_PARAMS; // TODO: 别的都是返回的套了一层 data 的,但是 urlParams 的为啥不一样? + }); + + const context = new MockContext>({}, (ctx) => create(dataSource, ctx, { + requestHandlersMap: { + urlParams: urlParamsHandler, + }, + })); + + const setState = sinon.spy(context, 'setState'); + + // 一开始应该是初始状态 + t.is(context.dataSourceMap.urlParams.status, RuntimeDataSourceStatus.Initial); + + const loading = context.reloadDataSource(); + + await Promise.all([clock.runAllAsync(), loading]); + + // 最后应该成功了,loaded 状态 + t.is(context.dataSourceMap.urlParams.status, RuntimeDataSourceStatus.Loaded); + + // 检查数据源的数据 + t.deepEqual(context.dataSourceMap.urlParams.data, URL_PARAMS); + t.deepEqual(context.dataSourceMap.urlParams.error, undefined); + + // 检查状态数据 + t.assert(setState.calledOnce); + t.deepEqual(context.state.urlParams, URL_PARAMS); + + // fetchHandler 应该被调用了一次 + t.assert(urlParamsHandler.calledOnce); + + // 检查调用参数 url 没有 options + t.deepEqual(urlParamsHandler.firstCall.args, [context]); }; - const urlParamsHandler = sinon.fake(async () => { - return URL_PARAMS; // TODO: 别的都是返回的套了一层 data 的,但是 urlParams 的为啥不一样? - }); - - const context = new MockContext>({}, (ctx) => create(dataSource, ctx, { - requestHandlersMap: { - urlParams: urlParamsHandler, - }, - })); - - const setState = sinon.spy(context, 'setState'); - - // 一开始应该是初始状态 - t.is(context.dataSourceMap.urlParams.status, RuntimeDataSourceStatus.Initial); - - const loading = context.reloadDataSource(); - - await Promise.all([clock.runAllAsync(), loading]); - - // 最后应该成功了,loaded 状态 - t.is(context.dataSourceMap.urlParams.status, RuntimeDataSourceStatus.Loaded); - - // 检查数据源的数据 - t.deepEqual(context.dataSourceMap.urlParams.data, URL_PARAMS); - t.deepEqual(context.dataSourceMap.urlParams.error, undefined); - - // 检查状态数据 - t.assert(setState.calledOnce); - t.deepEqual(context.state.urlParams, URL_PARAMS); - - // fetchHandler 应该被调用了一次 - t.assert(urlParamsHandler.calledOnce); - - // 检查调用参数 url 没有 options - t.deepEqual(urlParamsHandler.firstCall.args, [context]); -}; - normalScene.title = (providedTitle) => providedTitle || 'normal scene'; diff --git a/packages/datasource-engine/test/scenes/p0-1-custom-response-status/_datasource-runtime.ts b/packages/datasource-engine/test/scenes/p0-1-custom-response-status/_datasource-runtime.ts index 756adeb83..4b06ca7b8 100644 --- a/packages/datasource-engine/test/scenes/p0-1-custom-response-status/_datasource-runtime.ts +++ b/packages/datasource-engine/test/scenes/p0-1-custom-response-status/_datasource-runtime.ts @@ -1,4 +1,4 @@ -import { RuntimeDataSource } from '@ali/build-success-types'; +import { RuntimeDataSource } from '@ali/lowcode-types'; // 这里仅仅是数据源部分的: // @see: https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 diff --git a/packages/datasource-engine/test/scenes/p0-1-custom-response-status/_datasource-schema.ts b/packages/datasource-engine/test/scenes/p0-1-custom-response-status/_datasource-schema.ts index 111cf641f..2352df683 100644 --- a/packages/datasource-engine/test/scenes/p0-1-custom-response-status/_datasource-schema.ts +++ b/packages/datasource-engine/test/scenes/p0-1-custom-response-status/_datasource-schema.ts @@ -1,8 +1,8 @@ -import { DataSource } from '@ali/build-success-types'; +import { InterpretDataSource } from '@ali/lowcode-types'; // 这里仅仅是数据源部分的 schema: // @see: https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 -export const DATA_SOURCE_SCHEMA: DataSource = { +export const DATA_SOURCE_SCHEMA: InterpretDataSource = { list: [ { id: 'user', diff --git a/packages/datasource-engine/test/scenes/p0-1-custom-response-status/_macro-abnormal.ts b/packages/datasource-engine/test/scenes/p0-1-custom-response-status/_macro-abnormal.ts index 757aaba6e..a07619bd4 100644 --- a/packages/datasource-engine/test/scenes/p0-1-custom-response-status/_macro-abnormal.ts +++ b/packages/datasource-engine/test/scenes/p0-1-custom-response-status/_macro-abnormal.ts @@ -1,10 +1,10 @@ import { - DataSource, + InterpretDataSource, IDataSourceEngine, - IRuntimeContext, + IDataSourceRuntimeContext, RuntimeDataSource, RuntimeDataSourceStatus, -} from '@ali/build-success-types'; +} from '@ali/lowcode-types'; import sinon from 'sinon'; import { bindRuntimeContext, delay, MockContext } from '../../_helpers'; @@ -17,79 +17,79 @@ export const abnormalScene: Macro<[ { create: ( dataSource: any, - ctx: IRuntimeContext, + ctx: IDataSourceRuntimeContext, options: any ) => IDataSourceEngine; - dataSource: RuntimeDataSource | DataSource; + dataSource: RuntimeDataSource | InterpretDataSource; } ]> = async ( t: ExecutionContext<{ clock: SinonFakeTimers }>, { create, dataSource }, -) => { - const { clock } = t.context; - const ERROR_MSG = 'test error'; - const fetchHandler = sinon.fake(async () => { - await delay(100); - return { - data: { - success: false, - message: ERROR_MSG, - code: 'E_FOO', + ) => { + const { clock } = t.context; + const ERROR_MSG = 'test error'; + const fetchHandler = sinon.fake(async () => { + await delay(100); + return { + data: { + success: false, + message: ERROR_MSG, + code: 'E_FOO', + }, + }; + }); + + const context = new MockContext>( + {}, + (ctx) => create(bindRuntimeContext(dataSource, ctx), ctx, { + requestHandlersMap: { + fetch: fetchHandler, + }, + }), + { + recordError() { }, }, - }; - }); + ); - const context = new MockContext>( - {}, - (ctx) => create(bindRuntimeContext(dataSource, ctx), ctx, { - requestHandlersMap: { - fetch: fetchHandler, - }, - }), - { - recordError() {}, - }, - ); + const setState = sinon.spy(context, 'setState'); + const recordError = sinon.spy(context, 'recordError'); - const setState = sinon.spy(context, 'setState'); - const recordError = sinon.spy(context, 'recordError'); + // 一开始应该是初始状态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Initial); - // 一开始应该是初始状态 - t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Initial); + const loading = context.reloadDataSource(); - const loading = context.reloadDataSource(); + await clock.tickAsync(50); - await clock.tickAsync(50); + // 中间应该有 loading 态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loading); - // 中间应该有 loading 态 - t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loading); + await Promise.all([clock.runAllAsync(), loading]); - await Promise.all([clock.runAllAsync(), loading]); + // 最后应该失败了,error 状态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Error); - // 最后应该失败了,error 状态 - t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Error); + // 检查数据源的数据 + t.deepEqual(context.dataSourceMap.user.data, undefined); + t.not(context.dataSourceMap.user.error, undefined); - // 检查数据源的数据 - t.deepEqual(context.dataSourceMap.user.data, undefined); - t.not(context.dataSourceMap.user.error, undefined); + t.regex(context.dataSourceMap.user.error!.message, new RegExp(ERROR_MSG)); - t.regex(context.dataSourceMap.user.error!.message, new RegExp(ERROR_MSG)); + // 检查状态数据 + t.assert(setState.notCalled); + t.deepEqual(context.state.user, undefined); - // 检查状态数据 - t.assert(setState.notCalled); - t.deepEqual(context.state.user, undefined); + // fetchHandler 应该被调用了一次 + t.assert(fetchHandler.calledOnce); - // fetchHandler 应该被调用了一次 - t.assert(fetchHandler.calledOnce); + // 检查调用参数 + const firstListItemOptions = DATA_SOURCE_SCHEMA.list[0].options; + const fetchHandlerCallArgs = fetchHandler.firstCall.args[0]; + t.is(firstListItemOptions.uri, fetchHandlerCallArgs.uri); - // 检查调用参数 - const firstListItemOptions = DATA_SOURCE_SCHEMA.list[0].options; - const fetchHandlerCallArgs = fetchHandler.firstCall.args[0]; - t.is(firstListItemOptions.uri, fetchHandlerCallArgs.uri); - - // 埋点应该也会被调用 - t.assert(recordError.calledOnce); - t.snapshot(recordError.firstCall.args); -}; + // 埋点应该也会被调用 + t.assert(recordError.calledOnce); + t.snapshot(recordError.firstCall.args); + }; abnormalScene.title = (providedTitle) => providedTitle || 'abnormal scene'; diff --git a/packages/datasource-engine/test/scenes/p0-1-custom-response-status/_macro-normal.ts b/packages/datasource-engine/test/scenes/p0-1-custom-response-status/_macro-normal.ts index d00fa39d9..8774ef200 100644 --- a/packages/datasource-engine/test/scenes/p0-1-custom-response-status/_macro-normal.ts +++ b/packages/datasource-engine/test/scenes/p0-1-custom-response-status/_macro-normal.ts @@ -1,10 +1,10 @@ import { - DataSource, + InterpretDataSource, IDataSourceEngine, - IRuntimeContext, + IDataSourceRuntimeContext, RuntimeDataSource, RuntimeDataSourceStatus, -} from '@ali/build-success-types'; +} from '@ali/lowcode-types'; import sinon from 'sinon'; import { bindRuntimeContext, delay, MockContext } from '../../_helpers'; @@ -17,80 +17,80 @@ export const normalScene: Macro<[ { create: ( dataSource: any, - ctx: IRuntimeContext, + ctx: IDataSourceRuntimeContext, options: any ) => IDataSourceEngine; - dataSource: RuntimeDataSource | DataSource; + dataSource: RuntimeDataSource | InterpretDataSource; } ]> = async ( t: ExecutionContext<{ clock: SinonFakeTimers }>, { create, dataSource }, -) => { - const { clock } = t.context; + ) => { + const { clock } = t.context; - const USER_DATA = { - name: 'Alice', - age: 18, + const USER_DATA = { + name: 'Alice', + age: 18, + }; + + const fetchHandler = sinon.fake(async () => { + await delay(100); + return { + data: { + success: true, + data: USER_DATA, + }, + }; + }); + + const context = new MockContext>( + {}, + (ctx) => create(bindRuntimeContext(dataSource, ctx), ctx, { + requestHandlersMap: { + fetch: fetchHandler, + }, + }), + { + recordError() { }, + }, + ); + + const setState = sinon.spy(context, 'setState'); + const recordError = sinon.spy(context, 'recordError'); + + // 一开始应该是初始状态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Initial); + + const loading = context.reloadDataSource(); + + await clock.tickAsync(50); + + // 中间应该有 loading 态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loading); + + await Promise.all([clock.runAllAsync(), loading]); + + // 最后应该成功了,loaded 状态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loaded); + + // 检查数据源的数据 + t.deepEqual(context.dataSourceMap.user.data, USER_DATA); + t.deepEqual(context.dataSourceMap.user.error, undefined); + + // 检查状态数据 + t.assert(setState.calledOnce); + t.deepEqual(context.state.user, USER_DATA); + + // fetchHandler 应该被调用了一次 + t.assert(fetchHandler.calledOnce); + + // 检查调用参数 + const firstListItemOptions = DATA_SOURCE_SCHEMA.list[0].options; + const fetchHandlerCallArgs = fetchHandler.firstCall.args[0]; + t.is(firstListItemOptions.uri, fetchHandlerCallArgs.uri); + + // 埋点不应该被调用 + t.assert(recordError.notCalled); }; - const fetchHandler = sinon.fake(async () => { - await delay(100); - return { - data: { - success: true, - data: USER_DATA, - }, - }; - }); - - const context = new MockContext>( - {}, - (ctx) => create(bindRuntimeContext(dataSource, ctx), ctx, { - requestHandlersMap: { - fetch: fetchHandler, - }, - }), - { - recordError() {}, - }, - ); - - const setState = sinon.spy(context, 'setState'); - const recordError = sinon.spy(context, 'recordError'); - - // 一开始应该是初始状态 - t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Initial); - - const loading = context.reloadDataSource(); - - await clock.tickAsync(50); - - // 中间应该有 loading 态 - t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loading); - - await Promise.all([clock.runAllAsync(), loading]); - - // 最后应该成功了,loaded 状态 - t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loaded); - - // 检查数据源的数据 - t.deepEqual(context.dataSourceMap.user.data, USER_DATA); - t.deepEqual(context.dataSourceMap.user.error, undefined); - - // 检查状态数据 - t.assert(setState.calledOnce); - t.deepEqual(context.state.user, USER_DATA); - - // fetchHandler 应该被调用了一次 - t.assert(fetchHandler.calledOnce); - - // 检查调用参数 - const firstListItemOptions = DATA_SOURCE_SCHEMA.list[0].options; - const fetchHandlerCallArgs = fetchHandler.firstCall.args[0]; - t.is(firstListItemOptions.uri, fetchHandlerCallArgs.uri); - - // 埋点不应该被调用 - t.assert(recordError.notCalled); -}; - normalScene.title = (providedTitle) => providedTitle || 'normal scene'; diff --git a/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/_datasource-runtime.ts b/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/_datasource-runtime.ts index 2608841e1..d9ac8d6d0 100644 --- a/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/_datasource-runtime.ts +++ b/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/_datasource-runtime.ts @@ -1,4 +1,4 @@ -import { RuntimeDataSource } from '@ali/build-success-types'; +import { RuntimeDataSource } from '@ali/lowcode-types'; export const DEFAULT_USER_DATA = { id: 0, name: 'guest' }; // 返回一个兜底的数据 diff --git a/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/_datasource-schema.ts b/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/_datasource-schema.ts index b9b44cc6a..1b33622a9 100644 --- a/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/_datasource-schema.ts +++ b/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/_datasource-schema.ts @@ -1,8 +1,8 @@ -import { DataSource } from '@ali/build-success-types'; +import { InterpretDataSource } from '@ali/lowcode-types'; // 这里仅仅是数据源部分的 schema: // @see: https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 -export const DATA_SOURCE_SCHEMA: DataSource = { +export const DATA_SOURCE_SCHEMA: InterpretDataSource = { list: [ { id: 'user', diff --git a/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/_macro-abnormal.ts b/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/_macro-abnormal.ts index 1c1e5d800..4b5a2237e 100644 --- a/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/_macro-abnormal.ts +++ b/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/_macro-abnormal.ts @@ -1,10 +1,10 @@ import { - DataSource, + InterpretDataSource, IDataSourceEngine, - IRuntimeContext, + IDataSourceRuntimeContext, RuntimeDataSource, RuntimeDataSourceStatus, -} from '@ali/build-success-types'; +} from '@ali/lowcode-types'; import sinon from 'sinon'; import { delay, MockContext } from '../../_helpers'; @@ -17,62 +17,62 @@ export const abnormalScene: Macro<[ { create: ( dataSource: any, - ctx: IRuntimeContext, + ctx: IDataSourceRuntimeContext, options: any ) => IDataSourceEngine; - dataSource: RuntimeDataSource | DataSource; + dataSource: RuntimeDataSource | InterpretDataSource; } ]> = async ( t: ExecutionContext<{ clock: SinonFakeTimers }>, { create, dataSource }, -) => { - const { clock } = t.context; - const ERROR_MSG = 'test error'; - const fetchHandler = sinon.fake(async () => { - await delay(100); - throw new Error(ERROR_MSG); - }); + ) => { + const { clock } = t.context; + const ERROR_MSG = 'test error'; + const fetchHandler = sinon.fake(async () => { + await delay(100); + throw new Error(ERROR_MSG); + }); - const context = new MockContext>({}, (ctx) => create(dataSource, ctx, { - requestHandlersMap: { - fetch: fetchHandler, - }, - })); + const context = new MockContext>({}, (ctx) => create(dataSource, ctx, { + requestHandlersMap: { + fetch: fetchHandler, + }, + })); - const setState = sinon.spy(context, 'setState'); + const setState = sinon.spy(context, 'setState'); - // 一开始应该是初始状态 - t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Initial); + // 一开始应该是初始状态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Initial); - const loading = context.reloadDataSource(); + const loading = context.reloadDataSource(); - await clock.tickAsync(50); + await clock.tickAsync(50); - // 中间应该有 loading 态 - t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loading); + // 中间应该有 loading 态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loading); - await Promise.all([clock.runAllAsync(), loading]); + await Promise.all([clock.runAllAsync(), loading]); - // 注意 error 是会被吃掉了,还是 loaded 状态 - // FIXME: 根据协议内容,dataHandler 返回的结果是需要抛出错误的,那么 fetchHandler 的错误难道不需要处理? - // TODO: 提案:request 如果挂了,不应该需要走 dataHandler 了,没有意义 - t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Error); + // 注意 error 是会被吃掉了,还是 loaded 状态 + // FIXME: 根据协议内容,dataHandler 返回的结果是需要抛出错误的,那么 fetchHandler 的错误难道不需要处理? + // TODO: 提案:request 如果挂了,不应该需要走 dataHandler 了,没有意义 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Error); - // 检查数据源的数据 - t.deepEqual(context.dataSourceMap.user.data, undefined); - t.not(context.dataSourceMap.user.error, undefined); - t.regex(context.dataSourceMap.user.error!.message, new RegExp(ERROR_MSG)); + // 检查数据源的数据 + t.deepEqual(context.dataSourceMap.user.data, undefined); + t.not(context.dataSourceMap.user.error, undefined); + t.regex(context.dataSourceMap.user.error!.message, new RegExp(ERROR_MSG)); - // 检查状态数据 - t.assert(setState.notCalled); + // 检查状态数据 + t.assert(setState.notCalled); - // fetchHandler 应该没调 - t.assert.skip(fetchHandler.notCalled); + // fetchHandler 应该没调 + t.assert.skip(fetchHandler.notCalled); - // 检查调用参数 - const firstListItemOptions = DATA_SOURCE_SCHEMA.list[0].options; - const fetchHandlerCallArgs = fetchHandler.firstCall.args[0]; - t.is(firstListItemOptions.uri, fetchHandlerCallArgs.uri); -}; + // 检查调用参数 + const firstListItemOptions = DATA_SOURCE_SCHEMA.list[0].options; + const fetchHandlerCallArgs = fetchHandler.firstCall.args[0]; + t.is(firstListItemOptions.uri, fetchHandlerCallArgs.uri); + }; abnormalScene.title = (providedTitle) => providedTitle || 'abnormal scene'; diff --git a/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/_macro-normal.ts b/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/_macro-normal.ts index 78aa87c61..c8484c434 100644 --- a/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/_macro-normal.ts +++ b/packages/datasource-engine/test/scenes/p0-1-data-handler-can-eat-errors/_macro-normal.ts @@ -1,10 +1,10 @@ import { - DataSource, + InterpretDataSource, IDataSourceEngine, - IRuntimeContext, + IDataSourceRuntimeContext, RuntimeDataSource, RuntimeDataSourceStatus, -} from '@ali/build-success-types'; +} from '@ali/lowcode-types'; import sinon from 'sinon'; import { delay, MockContext } from '../../_helpers'; @@ -17,65 +17,65 @@ export const normalScene: Macro<[ { create: ( dataSource: any, - ctx: IRuntimeContext, + ctx: IDataSourceRuntimeContext, options: any ) => IDataSourceEngine; - dataSource: RuntimeDataSource | DataSource; + dataSource: RuntimeDataSource | InterpretDataSource; } ]> = async ( t: ExecutionContext<{ clock: SinonFakeTimers }>, { create, dataSource }, -) => { - const { clock } = t.context; + ) => { + const { clock } = t.context; - const USER_DATA = { - name: 'Alice', - age: 18, + const USER_DATA = { + name: 'Alice', + age: 18, + }; + + const fetchHandler = sinon.fake(async () => { + await delay(100); + return { data: USER_DATA }; + }); + + const context = new MockContext>({}, (ctx) => create(dataSource, ctx, { + requestHandlersMap: { + fetch: fetchHandler, + }, + })); + + const setState = sinon.spy(context, 'setState'); + + // 一开始应该是初始状态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Initial); + + const loading = context.reloadDataSource(); + + await clock.tickAsync(50); + + // 中间应该有 loading 态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loading); + + await Promise.all([clock.runAllAsync(), loading]); + + // 最后应该成功了,loaded 状态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loaded); + + // 检查数据源的数据 + t.deepEqual(context.dataSourceMap.user.data, USER_DATA); + t.deepEqual(context.dataSourceMap.user.error, undefined); + + // 检查状态数据 + t.assert(setState.calledOnce); + t.deepEqual(context.state.user, USER_DATA); + + // fetchHandler 应该被调用了一次 + t.assert(fetchHandler.calledOnce); + + // 检查调用参数 + const firstListItemOptions = DATA_SOURCE_SCHEMA.list[0].options; + const fetchHandlerCallArgs = fetchHandler.firstCall.args[0]; + t.is(firstListItemOptions.uri, fetchHandlerCallArgs.uri); }; - const fetchHandler = sinon.fake(async () => { - await delay(100); - return { data: USER_DATA }; - }); - - const context = new MockContext>({}, (ctx) => create(dataSource, ctx, { - requestHandlersMap: { - fetch: fetchHandler, - }, - })); - - const setState = sinon.spy(context, 'setState'); - - // 一开始应该是初始状态 - t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Initial); - - const loading = context.reloadDataSource(); - - await clock.tickAsync(50); - - // 中间应该有 loading 态 - t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loading); - - await Promise.all([clock.runAllAsync(), loading]); - - // 最后应该成功了,loaded 状态 - t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loaded); - - // 检查数据源的数据 - t.deepEqual(context.dataSourceMap.user.data, USER_DATA); - t.deepEqual(context.dataSourceMap.user.error, undefined); - - // 检查状态数据 - t.assert(setState.calledOnce); - t.deepEqual(context.state.user, USER_DATA); - - // fetchHandler 应该被调用了一次 - t.assert(fetchHandler.calledOnce); - - // 检查调用参数 - const firstListItemOptions = DATA_SOURCE_SCHEMA.list[0].options; - const fetchHandlerCallArgs = fetchHandler.firstCall.args[0]; - t.is(firstListItemOptions.uri, fetchHandlerCallArgs.uri); -}; - normalScene.title = (providedTitle) => providedTitle || 'normal scene'; diff --git a/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/_datasource-runtime.ts b/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/_datasource-runtime.ts index 5dc07956a..19d35f910 100644 --- a/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/_datasource-runtime.ts +++ b/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/_datasource-runtime.ts @@ -1,4 +1,4 @@ -import { RuntimeDataSource } from '@ali/build-success-types'; +import { RuntimeDataSource } from '@ali/lowcode-types'; // 这里仅仅是数据源部分的: // @see: https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 diff --git a/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/_datasource-schema.ts b/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/_datasource-schema.ts index f35743828..f163ea6c2 100644 --- a/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/_datasource-schema.ts +++ b/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/_datasource-schema.ts @@ -1,8 +1,8 @@ -import { DataSource } from '@ali/build-success-types'; +import { InterpretDataSource } from '@ali/lowcode-types'; // 这里仅仅是数据源部分的 schema: // @see: https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 -export const DATA_SOURCE_SCHEMA: DataSource = { +export const DATA_SOURCE_SCHEMA: InterpretDataSource = { list: [ { id: 'user', diff --git a/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/_macro-abnormal.ts b/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/_macro-abnormal.ts index 757aaba6e..a07619bd4 100644 --- a/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/_macro-abnormal.ts +++ b/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/_macro-abnormal.ts @@ -1,10 +1,10 @@ import { - DataSource, + InterpretDataSource, IDataSourceEngine, - IRuntimeContext, + IDataSourceRuntimeContext, RuntimeDataSource, RuntimeDataSourceStatus, -} from '@ali/build-success-types'; +} from '@ali/lowcode-types'; import sinon from 'sinon'; import { bindRuntimeContext, delay, MockContext } from '../../_helpers'; @@ -17,79 +17,79 @@ export const abnormalScene: Macro<[ { create: ( dataSource: any, - ctx: IRuntimeContext, + ctx: IDataSourceRuntimeContext, options: any ) => IDataSourceEngine; - dataSource: RuntimeDataSource | DataSource; + dataSource: RuntimeDataSource | InterpretDataSource; } ]> = async ( t: ExecutionContext<{ clock: SinonFakeTimers }>, { create, dataSource }, -) => { - const { clock } = t.context; - const ERROR_MSG = 'test error'; - const fetchHandler = sinon.fake(async () => { - await delay(100); - return { - data: { - success: false, - message: ERROR_MSG, - code: 'E_FOO', + ) => { + const { clock } = t.context; + const ERROR_MSG = 'test error'; + const fetchHandler = sinon.fake(async () => { + await delay(100); + return { + data: { + success: false, + message: ERROR_MSG, + code: 'E_FOO', + }, + }; + }); + + const context = new MockContext>( + {}, + (ctx) => create(bindRuntimeContext(dataSource, ctx), ctx, { + requestHandlersMap: { + fetch: fetchHandler, + }, + }), + { + recordError() { }, }, - }; - }); + ); - const context = new MockContext>( - {}, - (ctx) => create(bindRuntimeContext(dataSource, ctx), ctx, { - requestHandlersMap: { - fetch: fetchHandler, - }, - }), - { - recordError() {}, - }, - ); + const setState = sinon.spy(context, 'setState'); + const recordError = sinon.spy(context, 'recordError'); - const setState = sinon.spy(context, 'setState'); - const recordError = sinon.spy(context, 'recordError'); + // 一开始应该是初始状态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Initial); - // 一开始应该是初始状态 - t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Initial); + const loading = context.reloadDataSource(); - const loading = context.reloadDataSource(); + await clock.tickAsync(50); - await clock.tickAsync(50); + // 中间应该有 loading 态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loading); - // 中间应该有 loading 态 - t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loading); + await Promise.all([clock.runAllAsync(), loading]); - await Promise.all([clock.runAllAsync(), loading]); + // 最后应该失败了,error 状态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Error); - // 最后应该失败了,error 状态 - t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Error); + // 检查数据源的数据 + t.deepEqual(context.dataSourceMap.user.data, undefined); + t.not(context.dataSourceMap.user.error, undefined); - // 检查数据源的数据 - t.deepEqual(context.dataSourceMap.user.data, undefined); - t.not(context.dataSourceMap.user.error, undefined); + t.regex(context.dataSourceMap.user.error!.message, new RegExp(ERROR_MSG)); - t.regex(context.dataSourceMap.user.error!.message, new RegExp(ERROR_MSG)); + // 检查状态数据 + t.assert(setState.notCalled); + t.deepEqual(context.state.user, undefined); - // 检查状态数据 - t.assert(setState.notCalled); - t.deepEqual(context.state.user, undefined); + // fetchHandler 应该被调用了一次 + t.assert(fetchHandler.calledOnce); - // fetchHandler 应该被调用了一次 - t.assert(fetchHandler.calledOnce); + // 检查调用参数 + const firstListItemOptions = DATA_SOURCE_SCHEMA.list[0].options; + const fetchHandlerCallArgs = fetchHandler.firstCall.args[0]; + t.is(firstListItemOptions.uri, fetchHandlerCallArgs.uri); - // 检查调用参数 - const firstListItemOptions = DATA_SOURCE_SCHEMA.list[0].options; - const fetchHandlerCallArgs = fetchHandler.firstCall.args[0]; - t.is(firstListItemOptions.uri, fetchHandlerCallArgs.uri); - - // 埋点应该也会被调用 - t.assert(recordError.calledOnce); - t.snapshot(recordError.firstCall.args); -}; + // 埋点应该也会被调用 + t.assert(recordError.calledOnce); + t.snapshot(recordError.firstCall.args); + }; abnormalScene.title = (providedTitle) => providedTitle || 'abnormal scene'; diff --git a/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/_macro-normal.ts b/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/_macro-normal.ts index d00fa39d9..8774ef200 100644 --- a/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/_macro-normal.ts +++ b/packages/datasource-engine/test/scenes/p1-0-data-handler-returns-promise/_macro-normal.ts @@ -1,10 +1,10 @@ import { - DataSource, + InterpretDataSource, IDataSourceEngine, - IRuntimeContext, + IDataSourceRuntimeContext, RuntimeDataSource, RuntimeDataSourceStatus, -} from '@ali/build-success-types'; +} from '@ali/lowcode-types'; import sinon from 'sinon'; import { bindRuntimeContext, delay, MockContext } from '../../_helpers'; @@ -17,80 +17,80 @@ export const normalScene: Macro<[ { create: ( dataSource: any, - ctx: IRuntimeContext, + ctx: IDataSourceRuntimeContext, options: any ) => IDataSourceEngine; - dataSource: RuntimeDataSource | DataSource; + dataSource: RuntimeDataSource | InterpretDataSource; } ]> = async ( t: ExecutionContext<{ clock: SinonFakeTimers }>, { create, dataSource }, -) => { - const { clock } = t.context; + ) => { + const { clock } = t.context; - const USER_DATA = { - name: 'Alice', - age: 18, + const USER_DATA = { + name: 'Alice', + age: 18, + }; + + const fetchHandler = sinon.fake(async () => { + await delay(100); + return { + data: { + success: true, + data: USER_DATA, + }, + }; + }); + + const context = new MockContext>( + {}, + (ctx) => create(bindRuntimeContext(dataSource, ctx), ctx, { + requestHandlersMap: { + fetch: fetchHandler, + }, + }), + { + recordError() { }, + }, + ); + + const setState = sinon.spy(context, 'setState'); + const recordError = sinon.spy(context, 'recordError'); + + // 一开始应该是初始状态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Initial); + + const loading = context.reloadDataSource(); + + await clock.tickAsync(50); + + // 中间应该有 loading 态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loading); + + await Promise.all([clock.runAllAsync(), loading]); + + // 最后应该成功了,loaded 状态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loaded); + + // 检查数据源的数据 + t.deepEqual(context.dataSourceMap.user.data, USER_DATA); + t.deepEqual(context.dataSourceMap.user.error, undefined); + + // 检查状态数据 + t.assert(setState.calledOnce); + t.deepEqual(context.state.user, USER_DATA); + + // fetchHandler 应该被调用了一次 + t.assert(fetchHandler.calledOnce); + + // 检查调用参数 + const firstListItemOptions = DATA_SOURCE_SCHEMA.list[0].options; + const fetchHandlerCallArgs = fetchHandler.firstCall.args[0]; + t.is(firstListItemOptions.uri, fetchHandlerCallArgs.uri); + + // 埋点不应该被调用 + t.assert(recordError.notCalled); }; - const fetchHandler = sinon.fake(async () => { - await delay(100); - return { - data: { - success: true, - data: USER_DATA, - }, - }; - }); - - const context = new MockContext>( - {}, - (ctx) => create(bindRuntimeContext(dataSource, ctx), ctx, { - requestHandlersMap: { - fetch: fetchHandler, - }, - }), - { - recordError() {}, - }, - ); - - const setState = sinon.spy(context, 'setState'); - const recordError = sinon.spy(context, 'recordError'); - - // 一开始应该是初始状态 - t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Initial); - - const loading = context.reloadDataSource(); - - await clock.tickAsync(50); - - // 中间应该有 loading 态 - t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loading); - - await Promise.all([clock.runAllAsync(), loading]); - - // 最后应该成功了,loaded 状态 - t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loaded); - - // 检查数据源的数据 - t.deepEqual(context.dataSourceMap.user.data, USER_DATA); - t.deepEqual(context.dataSourceMap.user.error, undefined); - - // 检查状态数据 - t.assert(setState.calledOnce); - t.deepEqual(context.state.user, USER_DATA); - - // fetchHandler 应该被调用了一次 - t.assert(fetchHandler.calledOnce); - - // 检查调用参数 - const firstListItemOptions = DATA_SOURCE_SCHEMA.list[0].options; - const fetchHandlerCallArgs = fetchHandler.firstCall.args[0]; - t.is(firstListItemOptions.uri, fetchHandlerCallArgs.uri); - - // 埋点不应该被调用 - t.assert(recordError.notCalled); -}; - normalScene.title = (providedTitle) => providedTitle || 'normal scene'; diff --git a/packages/datasource-engine/test/scenes/p1-1-shouldfetch-control-request/_datasource-runtime.ts b/packages/datasource-engine/test/scenes/p1-1-shouldfetch-control-request/_datasource-runtime.ts index 2085535c6..49d30425e 100644 --- a/packages/datasource-engine/test/scenes/p1-1-shouldfetch-control-request/_datasource-runtime.ts +++ b/packages/datasource-engine/test/scenes/p1-1-shouldfetch-control-request/_datasource-runtime.ts @@ -1,4 +1,4 @@ -import { RuntimeDataSource } from '@ali/build-success-types'; +import { RuntimeDataSource } from '@ali/lowcode-types'; // 这里仅仅是数据源部分的: // @see: https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 diff --git a/packages/datasource-engine/test/scenes/p1-1-shouldfetch-control-request/_datasource-schema.ts b/packages/datasource-engine/test/scenes/p1-1-shouldfetch-control-request/_datasource-schema.ts index e333f485a..4032c9a35 100644 --- a/packages/datasource-engine/test/scenes/p1-1-shouldfetch-control-request/_datasource-schema.ts +++ b/packages/datasource-engine/test/scenes/p1-1-shouldfetch-control-request/_datasource-schema.ts @@ -1,8 +1,8 @@ -import { DataSource } from '@ali/build-success-types'; +import { InterpretDataSource } from '@ali/lowcode-types'; // 这里仅仅是数据源部分的 schema: // @see: https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 -export const DATA_SOURCE_SCHEMA: DataSource = { +export const DATA_SOURCE_SCHEMA: InterpretDataSource = { list: [ { id: 'user', diff --git a/packages/datasource-engine/test/scenes/p1-1-shouldfetch-control-request/_macro-normal.ts b/packages/datasource-engine/test/scenes/p1-1-shouldfetch-control-request/_macro-normal.ts index 4289a6d89..a12e0a48c 100644 --- a/packages/datasource-engine/test/scenes/p1-1-shouldfetch-control-request/_macro-normal.ts +++ b/packages/datasource-engine/test/scenes/p1-1-shouldfetch-control-request/_macro-normal.ts @@ -1,10 +1,10 @@ import { - DataSource, + InterpretDataSource, IDataSourceEngine, - IRuntimeContext, + IDataSourceRuntimeContext, RuntimeDataSource, RuntimeDataSourceStatus, -} from '@ali/build-success-types'; +} from '@ali/lowcode-types'; import sinon from 'sinon'; import { bindRuntimeContext, delay, MockContext } from '../../_helpers'; @@ -17,92 +17,92 @@ export const normalScene: Macro<[ { create: ( dataSource: any, - ctx: IRuntimeContext, + ctx: IDataSourceRuntimeContext, options: any ) => IDataSourceEngine; - dataSource: RuntimeDataSource | DataSource; + dataSource: RuntimeDataSource | InterpretDataSource; } ]> = async ( t: ExecutionContext<{ clock: SinonFakeTimers }>, { create, dataSource }, -) => { - const { clock } = t.context; - const ORDERS_ERROR_MSG = - 'the orders request should not fetch, please check the condition'; + ) => { + const { clock } = t.context; + const ORDERS_ERROR_MSG = + 'the orders request should not fetch, please check the condition'; - const USER_DATA = { - name: 'Alice', - age: 18, + const USER_DATA = { + name: 'Alice', + age: 18, + }; + + const fetchHandler = sinon.fake(async () => { + await delay(100); + return { + data: USER_DATA, + }; + }); + + const context = new MockContext>( + {}, + (ctx) => create(bindRuntimeContext(dataSource, ctx), ctx, { + requestHandlersMap: { + fetch: fetchHandler, + }, + }), + { + recordError() { }, + }, + ); + + const setState = sinon.spy(context, 'setState'); + // const recordError = sinon.spy(context, 'recordError'); + + // 一开始应该是初始状态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Initial); + t.is(context.dataSourceMap.orders.status, RuntimeDataSourceStatus.Initial); + + const loading = context.reloadDataSource(); + + await clock.tickAsync(50); + + // 中间应该有 loading 态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loading); + + await clock.tickAsync(50); + + // 中间应该有 loading 态 + t.is(context.dataSourceMap.orders.status, RuntimeDataSourceStatus.Error); + + await Promise.all([clock.runAllAsync(), loading]); + + // 最后 user 成功, orders 失败 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loaded); + t.is(context.dataSourceMap.orders.status, RuntimeDataSourceStatus.Error); + + // 检查数据源的数据 + t.deepEqual(context.dataSourceMap.user.data, USER_DATA); + t.is(context.dataSourceMap.user.error, undefined); + t.regex( + context.dataSourceMap.orders.error!.message, + new RegExp(ORDERS_ERROR_MSG), + ); + + // 检查状态数据 + t.assert(setState.calledOnce); + t.deepEqual(context.state.user, USER_DATA); + + // fetchHandler 应该被调用了 1 次 + t.assert(fetchHandler.calledOnce); + + // 检查调用参数 + + const firstListItemOptions = DATA_SOURCE_SCHEMA.list[0].options; + const fetchHandlerCallArgs = fetchHandler.firstCall.args[0]; + t.is(firstListItemOptions.uri, fetchHandlerCallArgs.uri); + + // // 埋点应该也会被调用 + // t.assert(recordError.calledOnce); + // t.snapshot(recordError.firstCall.args); }; - const fetchHandler = sinon.fake(async () => { - await delay(100); - return { - data: USER_DATA, - }; - }); - - const context = new MockContext>( - {}, - (ctx) => create(bindRuntimeContext(dataSource, ctx), ctx, { - requestHandlersMap: { - fetch: fetchHandler, - }, - }), - { - recordError() {}, - }, - ); - - const setState = sinon.spy(context, 'setState'); - // const recordError = sinon.spy(context, 'recordError'); - - // 一开始应该是初始状态 - t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Initial); - t.is(context.dataSourceMap.orders.status, RuntimeDataSourceStatus.Initial); - - const loading = context.reloadDataSource(); - - await clock.tickAsync(50); - - // 中间应该有 loading 态 - t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loading); - - await clock.tickAsync(50); - - // 中间应该有 loading 态 - t.is(context.dataSourceMap.orders.status, RuntimeDataSourceStatus.Error); - - await Promise.all([clock.runAllAsync(), loading]); - - // 最后 user 成功, orders 失败 - t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loaded); - t.is(context.dataSourceMap.orders.status, RuntimeDataSourceStatus.Error); - - // 检查数据源的数据 - t.deepEqual(context.dataSourceMap.user.data, USER_DATA); - t.is(context.dataSourceMap.user.error, undefined); - t.regex( - context.dataSourceMap.orders.error!.message, - new RegExp(ORDERS_ERROR_MSG), - ); - - // 检查状态数据 - t.assert(setState.calledOnce); - t.deepEqual(context.state.user, USER_DATA); - - // fetchHandler 应该被调用了 1 次 - t.assert(fetchHandler.calledOnce); - - // 检查调用参数 - - const firstListItemOptions = DATA_SOURCE_SCHEMA.list[0].options; - const fetchHandlerCallArgs = fetchHandler.firstCall.args[0]; - t.is(firstListItemOptions.uri, fetchHandlerCallArgs.uri); - - // // 埋点应该也会被调用 - // t.assert(recordError.calledOnce); - // t.snapshot(recordError.firstCall.args); -}; - normalScene.title = (providedTitle) => providedTitle || 'normal scene'; diff --git a/packages/datasource-fetch-handler/.eslintignore b/packages/datasource-fetch-handler/.eslintignore new file mode 100644 index 000000000..fecb7c26d --- /dev/null +++ b/packages/datasource-fetch-handler/.eslintignore @@ -0,0 +1,3 @@ +/node_modules +/es +/lib \ No newline at end of file diff --git a/packages/datasource-handlers/.eslintrc.js b/packages/datasource-fetch-handler/.eslintrc.js similarity index 78% rename from packages/datasource-handlers/.eslintrc.js rename to packages/datasource-fetch-handler/.eslintrc.js index e19c549ba..8c13fcaf4 100644 --- a/packages/datasource-handlers/.eslintrc.js +++ b/packages/datasource-fetch-handler/.eslintrc.js @@ -1,5 +1,5 @@ module.exports = { - extends: '../../.eslintrc.js', + extends: '../../.eslintrc', rules: { '@typescript-eslint/no-parameter-properties': 1, 'no-param-reassign': 0, diff --git a/packages/datasource-handlers/.prettierrc.js b/packages/datasource-fetch-handler/.prettierrc.js similarity index 61% rename from packages/datasource-handlers/.prettierrc.js rename to packages/datasource-fetch-handler/.prettierrc.js index d2db80ead..de2f53cdf 100644 --- a/packages/datasource-handlers/.prettierrc.js +++ b/packages/datasource-fetch-handler/.prettierrc.js @@ -1,4 +1,4 @@ module.exports = { singleQuote: true, - trailingComma: 'always', + trailingComma: 'all', }; diff --git a/packages/datasource-handlers/packages/fetch/package.json b/packages/datasource-fetch-handler/package.json similarity index 88% rename from packages/datasource-handlers/packages/fetch/package.json rename to packages/datasource-fetch-handler/package.json index ad28decb4..8dbc63a6f 100644 --- a/packages/datasource-handlers/packages/fetch/package.json +++ b/packages/datasource-fetch-handler/package.json @@ -16,12 +16,10 @@ "prepublishOnly": "npm run build" }, "dependencies": { + "@ali/lowcode-types": "^1.0.10", "typescript": "^3.9.7", "universal-request": "^2.2.0" }, - "devDependencies": { - "@ali/build-success-types": "^0.1.2-alpha.35" - }, "publishConfig": { "registry": "https://registry.npm.alibaba-inc.com" }, diff --git a/packages/datasource-handlers/packages/fetch/src/index.ts b/packages/datasource-fetch-handler/src/index.ts similarity index 90% rename from packages/datasource-handlers/packages/fetch/src/index.ts rename to packages/datasource-fetch-handler/src/index.ts index d59fc0a8d..2bb5df893 100644 --- a/packages/datasource-handlers/packages/fetch/src/index.ts +++ b/packages/datasource-fetch-handler/src/index.ts @@ -1,4 +1,4 @@ -import { RuntimeOptionsConfig } from '@ali/build-success-types'; +import { RuntimeOptionsConfig } from '@ali/lowcode-types'; import request from 'universal-request'; import { RequestOptions, AsObject } from 'universal-request/lib/types'; diff --git a/packages/datasource-handlers/tsconfig.json b/packages/datasource-fetch-handler/tsconfig.json similarity index 95% rename from packages/datasource-handlers/tsconfig.json rename to packages/datasource-fetch-handler/tsconfig.json index 68d4e6bb3..ecd74d9e2 100644 --- a/packages/datasource-handlers/tsconfig.json +++ b/packages/datasource-fetch-handler/tsconfig.json @@ -1,10 +1,16 @@ { "compilerOptions": { + "outDir": "es", + "target": "es6", + "module": "esnext", /* Basic Options */ // "incremental": true, /* Enable incremental compilation */ // "target": "es6" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */, // "module": "esnext" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */, - "lib": ["ESNext", "DOM"] /* Specify library files to be included in the compilation. */, + "lib": [ + "ESNext", + "DOM" + ] /* Specify library files to be included in the compilation. */, // "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ @@ -21,7 +27,6 @@ // "importHelpers": true, /* Import emit helpers from 'tslib'. */ // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ - /* Strict Type-Checking Options */ "strict": true /* Enable all strict type-checking options. */, // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ @@ -31,13 +36,11 @@ // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ - /* Additional Checks */ // "noUnusedLocals": true, /* Report errors on unused locals. */ // "noUnusedParameters": true, /* Report errors on unused parameters. */ // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ - /* Module Resolution Options */ "moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */, // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ @@ -49,19 +52,19 @@ "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - /* Source Map Options */ // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ - /* Experimental Options */ // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ - /* Advanced Options */ "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */, - "skipLibCheck": true + "skipLibCheck": true, + "include": [ + "src/**/*" + ] } -} +} \ No newline at end of file diff --git a/packages/datasource-handlers/.eslintignore b/packages/datasource-handlers/.eslintignore deleted file mode 100644 index 096746c14..000000000 --- a/packages/datasource-handlers/.eslintignore +++ /dev/null @@ -1 +0,0 @@ -/node_modules/ \ No newline at end of file diff --git a/packages/datasource-handlers/lerna.json b/packages/datasource-handlers/lerna.json deleted file mode 100644 index b9933894c..000000000 --- a/packages/datasource-handlers/lerna.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "packages": ["packages/*"], - "version": "independent", - "npmClient": "yarn" -} diff --git a/packages/datasource-handlers/package.json b/packages/datasource-handlers/package.json deleted file mode 100644 index 43cea9f9d..000000000 --- a/packages/datasource-handlers/package.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "@ali/lowcode-datasource-handlers", - "version": "1.0.0", - "main": "index.js", - "license": "MIT", - "devDependencies": { - "lerna": "^3.22.0" - } -} diff --git a/packages/datasource-handlers/packages/fetch/es/index.d.ts b/packages/datasource-handlers/packages/fetch/es/index.d.ts deleted file mode 100644 index 443ad0dd1..000000000 --- a/packages/datasource-handlers/packages/fetch/es/index.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import { RuntimeOptionsConfig } from '@ali/build-success-types'; -export declare function createFetchHandler(config?: unknown): (options: RuntimeOptionsConfig) => Promise; diff --git a/packages/datasource-handlers/packages/fetch/es/index.js b/packages/datasource-handlers/packages/fetch/es/index.js deleted file mode 100644 index 0b4d6e5ba..000000000 --- a/packages/datasource-handlers/packages/fetch/es/index.js +++ /dev/null @@ -1,25 +0,0 @@ -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -import request from 'universal-request'; -// config 留着扩展 -export function createFetchHandler(config) { - return function (options) { - return __awaiter(this, void 0, void 0, function* () { - const requestConfig = Object.assign(Object.assign({}, options), { url: options.uri, method: options.method, data: options.params, headers: options.headers }); - try { - const response = yield request(requestConfig); - return response; - } - catch (error) { - throw error; - } - }); - }; -} diff --git a/packages/datasource-handlers/packages/fetch/tsconfig.json b/packages/datasource-handlers/packages/fetch/tsconfig.json deleted file mode 100644 index 268731175..000000000 --- a/packages/datasource-handlers/packages/fetch/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "outDir": "es", - "target": "es6", - "module": "esnext" - }, - - "include": ["src/**/*"] -} diff --git a/packages/datasource-handlers/packages/mopen/es/index.d.ts b/packages/datasource-handlers/packages/mopen/es/index.d.ts deleted file mode 100644 index 17039d9f2..000000000 --- a/packages/datasource-handlers/packages/mopen/es/index.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { MopenClientConfig } from '@ali/mirror-io-client-mopen'; -import { RuntimeOptionsConfig } from '@ali/build-success-types'; -export declare function createMopenHandler(config?: MopenClientConfig): (options: RuntimeOptionsConfig) => Promise<{ - data: T; -}>; diff --git a/packages/datasource-handlers/packages/mopen/es/index.js b/packages/datasource-handlers/packages/mopen/es/index.js deleted file mode 100644 index 967facd1d..000000000 --- a/packages/datasource-handlers/packages/mopen/es/index.js +++ /dev/null @@ -1,26 +0,0 @@ -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -import { MopenClient, MOPEN_APPKEY_XSPACE_PRE_ONLINE, MOPEN_DOMAIN_TAOBAO_PRE_ONLINE, } from '@ali/mirror-io-client-mopen'; -export function createMopenHandler(config = { - mtopDomain: MOPEN_DOMAIN_TAOBAO_PRE_ONLINE, - appKey: MOPEN_APPKEY_XSPACE_PRE_ONLINE, -}) { - return function (options) { - return __awaiter(this, void 0, void 0, function* () { - try { - const { data, response } = yield MopenClient.request(Object.assign(Object.assign({ config }, options), { api: options.uri, v: options.v, data: options.params, type: options.method || 'get', dataType: options.dataType || 'json', timeout: options.timeout, headers: options.headers })); - return Object.assign(Object.assign({}, response), { data }); - } - catch (error) { - throw error; - } - }); - }; -} diff --git a/packages/datasource-handlers/packages/mopen/tsconfig.json b/packages/datasource-handlers/packages/mopen/tsconfig.json deleted file mode 100644 index 268731175..000000000 --- a/packages/datasource-handlers/packages/mopen/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "outDir": "es", - "target": "es6", - "module": "esnext" - }, - - "include": ["src/**/*"] -} diff --git a/packages/datasource-handlers/packages/mtop/es/index.d.ts b/packages/datasource-handlers/packages/mtop/es/index.d.ts deleted file mode 100644 index c30b6a50a..000000000 --- a/packages/datasource-handlers/packages/mtop/es/index.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { RuntimeOptionsConfig } from '@ali/build-success-types'; -export declare type Method = 'get' | 'post' | 'GET' | 'POST'; -export declare type DataType = 'jsonp' | 'json' | 'originaljsonp'; -export declare function createMtopHandler(config?: MTopConfig): (options: RuntimeOptionsConfig) => Promise<{ - data: T; -}>; diff --git a/packages/datasource-handlers/packages/mtop/es/index.js b/packages/datasource-handlers/packages/mtop/es/index.js deleted file mode 100644 index fed789e22..000000000 --- a/packages/datasource-handlers/packages/mtop/es/index.js +++ /dev/null @@ -1,35 +0,0 @@ -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -import mtopRequest from '@ali/universal-mtop'; -// 考虑一下 mtop 类型的问题,官方没有提供 ts 文件 -export function createMtopHandler(config) { - if (config && Object.keys(config).length > 0) { - Object.keys(config).forEach((key) => mtopRequest.config(key, config[key])); - } - return function (options) { - return __awaiter(this, void 0, void 0, function* () { - try { - const response = yield mtopRequest.request({ - api: options.uri, - v: options.v || '1.0', - data: options.params, - type: options.method || 'get', - dataType: options.dataType || 'json', - timeout: options.timeout, - headers: options.headers, - }); - return response; - } - catch (error) { - throw error; - } - }); - }; -} diff --git a/packages/datasource-handlers/packages/mtop/tsconfig.json b/packages/datasource-handlers/packages/mtop/tsconfig.json deleted file mode 100644 index 268731175..000000000 --- a/packages/datasource-handlers/packages/mtop/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "outDir": "es", - "target": "es6", - "module": "esnext" - }, - - "include": ["src/**/*"] -} diff --git a/packages/datasource-handlers/packages/universalMtop/es/index.d.ts b/packages/datasource-handlers/packages/universalMtop/es/index.d.ts deleted file mode 100644 index 2a16eb3e9..000000000 --- a/packages/datasource-handlers/packages/universalMtop/es/index.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { UniversalMtopClientConfig } from '@ali/mirror-io-client-universal-mtop'; -import { RuntimeOptionsConfig } from '@ali/build-success-types'; -export declare function createMopenHandler(config?: UniversalMtopClientConfig): (options: RuntimeOptionsConfig) => Promise<{ - data: T; -}>; diff --git a/packages/datasource-handlers/packages/universalMtop/es/index.js b/packages/datasource-handlers/packages/universalMtop/es/index.js deleted file mode 100644 index 718adf31b..000000000 --- a/packages/datasource-handlers/packages/universalMtop/es/index.js +++ /dev/null @@ -1,23 +0,0 @@ -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -import { UniversalMtopClient, } from '@ali/mirror-io-client-universal-mtop'; -export function createMopenHandler(config) { - return function (options) { - return __awaiter(this, void 0, void 0, function* () { - try { - const { data, response } = yield UniversalMtopClient.request(Object.assign(Object.assign({ config }, options), { api: options.uri, v: options.v, data: options.params, type: options.method || 'get', dataType: options.dataType || 'json', timeout: options.timeout, headers: options.headers })); - return Object.assign(Object.assign({}, response), { data }); - } - catch (error) { - throw error; - } - }); - }; -} diff --git a/packages/datasource-handlers/packages/universalMtop/tsconfig.json b/packages/datasource-handlers/packages/universalMtop/tsconfig.json deleted file mode 100644 index 268731175..000000000 --- a/packages/datasource-handlers/packages/universalMtop/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "outDir": "es", - "target": "es6", - "module": "esnext" - }, - - "include": ["src/**/*"] -} diff --git a/packages/datasource-handlers/packages/urlParams/es/index.d.ts b/packages/datasource-handlers/packages/urlParams/es/index.d.ts deleted file mode 100644 index f16cb44c3..000000000 --- a/packages/datasource-handlers/packages/urlParams/es/index.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import { UrlParamsHandler } from '@ali/build-success-types'; -export declare function createUrlParamsHandler(searchString?: string | T): UrlParamsHandler; diff --git a/packages/datasource-handlers/packages/urlParams/es/index.js b/packages/datasource-handlers/packages/urlParams/es/index.js deleted file mode 100644 index 84a9451ef..000000000 --- a/packages/datasource-handlers/packages/urlParams/es/index.js +++ /dev/null @@ -1,21 +0,0 @@ -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -import qs from 'query-string'; -export function createUrlParamsHandler(searchString = '') { - return function () { - return __awaiter(this, void 0, void 0, function* () { - if (typeof searchString === 'string') { - const params = qs.parse(searchString); - return params; - } - return searchString; - }); - }; -} diff --git a/packages/datasource-handlers/packages/urlParams/tsconfig.json b/packages/datasource-handlers/packages/urlParams/tsconfig.json deleted file mode 100644 index 268731175..000000000 --- a/packages/datasource-handlers/packages/urlParams/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "outDir": "es", - "target": "es6", - "module": "esnext" - }, - - "include": ["src/**/*"] -} diff --git a/packages/datasource-mopen-handler/.eslintignore b/packages/datasource-mopen-handler/.eslintignore new file mode 100644 index 000000000..fecb7c26d --- /dev/null +++ b/packages/datasource-mopen-handler/.eslintignore @@ -0,0 +1,3 @@ +/node_modules +/es +/lib \ No newline at end of file diff --git a/packages/datasource-mopen-handler/.eslintrc.js b/packages/datasource-mopen-handler/.eslintrc.js new file mode 100644 index 000000000..8c13fcaf4 --- /dev/null +++ b/packages/datasource-mopen-handler/.eslintrc.js @@ -0,0 +1,7 @@ +module.exports = { + extends: '../../.eslintrc', + rules: { + '@typescript-eslint/no-parameter-properties': 1, + 'no-param-reassign': 0, + }, +}; diff --git a/packages/datasource-mopen-handler/.prettierrc.js b/packages/datasource-mopen-handler/.prettierrc.js new file mode 100644 index 000000000..de2f53cdf --- /dev/null +++ b/packages/datasource-mopen-handler/.prettierrc.js @@ -0,0 +1,4 @@ +module.exports = { + singleQuote: true, + trailingComma: 'all', +}; diff --git a/packages/datasource-handlers/packages/mopen/package.json b/packages/datasource-mopen-handler/package.json similarity index 89% rename from packages/datasource-handlers/packages/mopen/package.json rename to packages/datasource-mopen-handler/package.json index 87ff98947..7c60a774a 100644 --- a/packages/datasource-handlers/packages/mopen/package.json +++ b/packages/datasource-mopen-handler/package.json @@ -15,10 +15,8 @@ "build": "npm run clean && tsc && tsc --outDir ./lib --module commonjs ", "prepublishOnly": "npm run build" }, - "devDependencies": { - "@ali/build-success-types": "^0.1.2-alpha.35" - }, "dependencies": { + "@ali/lowcode-types": "^1.0.10", "@ali/mirror-io-client-mopen": "1.0.0-beta.16", "typescript": "^3.9.7" }, diff --git a/packages/datasource-handlers/packages/mopen/src/index.ts b/packages/datasource-mopen-handler/src/index.ts similarity index 93% rename from packages/datasource-handlers/packages/mopen/src/index.ts rename to packages/datasource-mopen-handler/src/index.ts index 9367fbb4f..6fc4fb287 100644 --- a/packages/datasource-handlers/packages/mopen/src/index.ts +++ b/packages/datasource-mopen-handler/src/index.ts @@ -4,7 +4,7 @@ import { MOPEN_APPKEY_XSPACE_PRE_ONLINE, MOPEN_DOMAIN_TAOBAO_PRE_ONLINE, } from '@ali/mirror-io-client-mopen'; -import { RuntimeOptionsConfig } from '@ali/build-success-types'; +import { RuntimeOptionsConfig } from '@ali/lowcode-types'; type Method = 'get' | 'post' | 'GET' | 'POST'; diff --git a/packages/datasource-mopen-handler/tsconfig.json b/packages/datasource-mopen-handler/tsconfig.json new file mode 100644 index 000000000..ecd74d9e2 --- /dev/null +++ b/packages/datasource-mopen-handler/tsconfig.json @@ -0,0 +1,70 @@ +{ + "compilerOptions": { + "outDir": "es", + "target": "es6", + "module": "esnext", + /* Basic Options */ + // "incremental": true, /* Enable incremental compilation */ + // "target": "es6" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */, + // "module": "esnext" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */, + "lib": [ + "ESNext", + "DOM" + ] /* Specify library files to be included in the compilation. */, + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "checkJs": true, /* Report errors in .js files. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + "declaration": true /* Generates corresponding '.d.ts' file. */, + // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + // "outDir": "es" /* Redirect output structure to the directory. */, + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "composite": true, /* Enable project compilation */ + // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ + // "removeComments": true, /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + /* Strict Type-Checking Options */ + "strict": true /* Enable all strict type-checking options. */, + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "strictFunctionTypes": true, /* Enable strict checking of function types. */ + // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ + // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + /* Additional Checks */ + // "noUnusedLocals": true, /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + /* Module Resolution Options */ + "moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */, + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, + // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + /* Source Map Options */ + // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + /* Advanced Options */ + "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */, + "skipLibCheck": true, + "include": [ + "src/**/*" + ] + } +} \ No newline at end of file diff --git a/packages/datasource-mtop-handler/.eslintignore b/packages/datasource-mtop-handler/.eslintignore new file mode 100644 index 000000000..fecb7c26d --- /dev/null +++ b/packages/datasource-mtop-handler/.eslintignore @@ -0,0 +1,3 @@ +/node_modules +/es +/lib \ No newline at end of file diff --git a/packages/datasource-mtop-handler/.eslintrc.js b/packages/datasource-mtop-handler/.eslintrc.js new file mode 100644 index 000000000..8c13fcaf4 --- /dev/null +++ b/packages/datasource-mtop-handler/.eslintrc.js @@ -0,0 +1,7 @@ +module.exports = { + extends: '../../.eslintrc', + rules: { + '@typescript-eslint/no-parameter-properties': 1, + 'no-param-reassign': 0, + }, +}; diff --git a/packages/datasource-mtop-handler/.prettierrc.js b/packages/datasource-mtop-handler/.prettierrc.js new file mode 100644 index 000000000..de2f53cdf --- /dev/null +++ b/packages/datasource-mtop-handler/.prettierrc.js @@ -0,0 +1,4 @@ +module.exports = { + singleQuote: true, + trailingComma: 'all', +}; diff --git a/packages/datasource-handlers/packages/mtop/package.json b/packages/datasource-mtop-handler/package.json similarity index 88% rename from packages/datasource-handlers/packages/mtop/package.json rename to packages/datasource-mtop-handler/package.json index d0f0288c7..2143f71eb 100644 --- a/packages/datasource-handlers/packages/mtop/package.json +++ b/packages/datasource-mtop-handler/package.json @@ -15,10 +15,8 @@ "build": "npm run clean && tsc && tsc --outDir ./lib --module commonjs ", "prepublishOnly": "npm run build" }, - "devDependencies": { - "@ali/build-success-types": "^0.1.2-alpha.35" - }, "dependencies": { + "@ali/lowcode-types": "^1.0.10", "@ali/universal-mtop": "^5.1.9", "typescript": "^3.9.7" }, diff --git a/packages/datasource-handlers/packages/mtop/src/index.ts b/packages/datasource-mtop-handler/src/index.ts similarity index 93% rename from packages/datasource-handlers/packages/mtop/src/index.ts rename to packages/datasource-mtop-handler/src/index.ts index 0c01cdd64..2527dda5c 100644 --- a/packages/datasource-handlers/packages/mtop/src/index.ts +++ b/packages/datasource-mtop-handler/src/index.ts @@ -1,6 +1,6 @@ import mtopRequest from '@ali/universal-mtop'; -import { RuntimeOptionsConfig } from '@ali/build-success-types'; +import { RuntimeOptionsConfig } from '@ali/lowcode-types'; export type Method = 'get' | 'post' | 'GET' | 'POST'; diff --git a/packages/datasource-handlers/packages/mtop/src/typings.d.ts b/packages/datasource-mtop-handler/src/typings.d.ts similarity index 100% rename from packages/datasource-handlers/packages/mtop/src/typings.d.ts rename to packages/datasource-mtop-handler/src/typings.d.ts diff --git a/packages/datasource-mtop-handler/tsconfig.json b/packages/datasource-mtop-handler/tsconfig.json new file mode 100644 index 000000000..ecd74d9e2 --- /dev/null +++ b/packages/datasource-mtop-handler/tsconfig.json @@ -0,0 +1,70 @@ +{ + "compilerOptions": { + "outDir": "es", + "target": "es6", + "module": "esnext", + /* Basic Options */ + // "incremental": true, /* Enable incremental compilation */ + // "target": "es6" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */, + // "module": "esnext" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */, + "lib": [ + "ESNext", + "DOM" + ] /* Specify library files to be included in the compilation. */, + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "checkJs": true, /* Report errors in .js files. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + "declaration": true /* Generates corresponding '.d.ts' file. */, + // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + // "outDir": "es" /* Redirect output structure to the directory. */, + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "composite": true, /* Enable project compilation */ + // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ + // "removeComments": true, /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + /* Strict Type-Checking Options */ + "strict": true /* Enable all strict type-checking options. */, + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "strictFunctionTypes": true, /* Enable strict checking of function types. */ + // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ + // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + /* Additional Checks */ + // "noUnusedLocals": true, /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + /* Module Resolution Options */ + "moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */, + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, + // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + /* Source Map Options */ + // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + /* Advanced Options */ + "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */, + "skipLibCheck": true, + "include": [ + "src/**/*" + ] + } +} \ No newline at end of file diff --git a/packages/datasource-universal-mtop-handler/.eslintignore b/packages/datasource-universal-mtop-handler/.eslintignore new file mode 100644 index 000000000..fecb7c26d --- /dev/null +++ b/packages/datasource-universal-mtop-handler/.eslintignore @@ -0,0 +1,3 @@ +/node_modules +/es +/lib \ No newline at end of file diff --git a/packages/datasource-universal-mtop-handler/.eslintrc.js b/packages/datasource-universal-mtop-handler/.eslintrc.js new file mode 100644 index 000000000..8c13fcaf4 --- /dev/null +++ b/packages/datasource-universal-mtop-handler/.eslintrc.js @@ -0,0 +1,7 @@ +module.exports = { + extends: '../../.eslintrc', + rules: { + '@typescript-eslint/no-parameter-properties': 1, + 'no-param-reassign': 0, + }, +}; diff --git a/packages/datasource-universal-mtop-handler/.prettierrc.js b/packages/datasource-universal-mtop-handler/.prettierrc.js new file mode 100644 index 000000000..de2f53cdf --- /dev/null +++ b/packages/datasource-universal-mtop-handler/.prettierrc.js @@ -0,0 +1,4 @@ +module.exports = { + singleQuote: true, + trailingComma: 'all', +}; diff --git a/packages/datasource-handlers/packages/universalMtop/package.json b/packages/datasource-universal-mtop-handler/package.json similarity index 89% rename from packages/datasource-handlers/packages/universalMtop/package.json rename to packages/datasource-universal-mtop-handler/package.json index 75c9f216f..bcb45d028 100644 --- a/packages/datasource-handlers/packages/universalMtop/package.json +++ b/packages/datasource-universal-mtop-handler/package.json @@ -15,10 +15,8 @@ "build": "npm run clean && tsc && tsc --outDir ./lib --module commonjs ", "prepublishOnly": "npm run build" }, - "devDependencies": { - "@ali/build-success-types": "^0.1.2-alpha.27" - }, "dependencies": { + "@ali/lowcode-types": "^1.0.10", "@ali/mirror-io-client-universal-mtop": "1.0.0-beta.16", "typescript": "^3.9.7" }, diff --git a/packages/datasource-handlers/packages/universalMtop/src/index.ts b/packages/datasource-universal-mtop-handler/src/index.ts similarity index 92% rename from packages/datasource-handlers/packages/universalMtop/src/index.ts rename to packages/datasource-universal-mtop-handler/src/index.ts index f44d9eebd..81cad731d 100644 --- a/packages/datasource-handlers/packages/universalMtop/src/index.ts +++ b/packages/datasource-universal-mtop-handler/src/index.ts @@ -3,7 +3,7 @@ import { UniversalMtopClientConfig, } from '@ali/mirror-io-client-universal-mtop'; -import { RuntimeOptionsConfig } from '@ali/build-success-types'; +import { RuntimeOptionsConfig } from '@ali/lowcode-types'; type Method = 'get' | 'post' | 'GET' | 'POST'; diff --git a/packages/datasource-universal-mtop-handler/tsconfig.json b/packages/datasource-universal-mtop-handler/tsconfig.json new file mode 100644 index 000000000..ecd74d9e2 --- /dev/null +++ b/packages/datasource-universal-mtop-handler/tsconfig.json @@ -0,0 +1,70 @@ +{ + "compilerOptions": { + "outDir": "es", + "target": "es6", + "module": "esnext", + /* Basic Options */ + // "incremental": true, /* Enable incremental compilation */ + // "target": "es6" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */, + // "module": "esnext" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */, + "lib": [ + "ESNext", + "DOM" + ] /* Specify library files to be included in the compilation. */, + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "checkJs": true, /* Report errors in .js files. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + "declaration": true /* Generates corresponding '.d.ts' file. */, + // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + // "outDir": "es" /* Redirect output structure to the directory. */, + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "composite": true, /* Enable project compilation */ + // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ + // "removeComments": true, /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + /* Strict Type-Checking Options */ + "strict": true /* Enable all strict type-checking options. */, + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "strictFunctionTypes": true, /* Enable strict checking of function types. */ + // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ + // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + /* Additional Checks */ + // "noUnusedLocals": true, /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + /* Module Resolution Options */ + "moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */, + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, + // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + /* Source Map Options */ + // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + /* Advanced Options */ + "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */, + "skipLibCheck": true, + "include": [ + "src/**/*" + ] + } +} \ No newline at end of file diff --git a/packages/datasource-url-params-handler/.eslintignore b/packages/datasource-url-params-handler/.eslintignore new file mode 100644 index 000000000..fecb7c26d --- /dev/null +++ b/packages/datasource-url-params-handler/.eslintignore @@ -0,0 +1,3 @@ +/node_modules +/es +/lib \ No newline at end of file diff --git a/packages/datasource-url-params-handler/.eslintrc.js b/packages/datasource-url-params-handler/.eslintrc.js new file mode 100644 index 000000000..8c13fcaf4 --- /dev/null +++ b/packages/datasource-url-params-handler/.eslintrc.js @@ -0,0 +1,7 @@ +module.exports = { + extends: '../../.eslintrc', + rules: { + '@typescript-eslint/no-parameter-properties': 1, + 'no-param-reassign': 0, + }, +}; diff --git a/packages/datasource-url-params-handler/.prettierrc.js b/packages/datasource-url-params-handler/.prettierrc.js new file mode 100644 index 000000000..e69de29bb diff --git a/packages/datasource-handlers/packages/urlParams/package.json b/packages/datasource-url-params-handler/package.json similarity index 88% rename from packages/datasource-handlers/packages/urlParams/package.json rename to packages/datasource-url-params-handler/package.json index 41ee2e618..869648b15 100644 --- a/packages/datasource-handlers/packages/urlParams/package.json +++ b/packages/datasource-url-params-handler/package.json @@ -15,10 +15,8 @@ "build": "npm run clean && tsc && tsc --outDir ./lib --module commonjs ", "prepublishOnly": "npm run build" }, - "devDependencies": { - "@ali/build-success-types": "^0.1.2-alpha.31" - }, "dependencies": { + "@ali/lowcode-types": "^1.0.10", "query-string": "^6.13.1", "typescript": "^3.9.7" }, diff --git a/packages/datasource-handlers/packages/urlParams/src/index.ts b/packages/datasource-url-params-handler/src/index.ts similarity index 85% rename from packages/datasource-handlers/packages/urlParams/src/index.ts rename to packages/datasource-url-params-handler/src/index.ts index c0c4a8836..db4761fc0 100644 --- a/packages/datasource-handlers/packages/urlParams/src/index.ts +++ b/packages/datasource-url-params-handler/src/index.ts @@ -1,5 +1,5 @@ import qs from 'query-string'; -import { UrlParamsHandler } from '@ali/build-success-types'; +import { UrlParamsHandler } from '@ali/lowcode-types'; export function createUrlParamsHandler( searchString: string | T = '', diff --git a/packages/datasource-url-params-handler/tsconfig.json b/packages/datasource-url-params-handler/tsconfig.json new file mode 100644 index 000000000..ecd74d9e2 --- /dev/null +++ b/packages/datasource-url-params-handler/tsconfig.json @@ -0,0 +1,70 @@ +{ + "compilerOptions": { + "outDir": "es", + "target": "es6", + "module": "esnext", + /* Basic Options */ + // "incremental": true, /* Enable incremental compilation */ + // "target": "es6" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */, + // "module": "esnext" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */, + "lib": [ + "ESNext", + "DOM" + ] /* Specify library files to be included in the compilation. */, + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "checkJs": true, /* Report errors in .js files. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + "declaration": true /* Generates corresponding '.d.ts' file. */, + // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + // "outDir": "es" /* Redirect output structure to the directory. */, + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "composite": true, /* Enable project compilation */ + // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ + // "removeComments": true, /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + /* Strict Type-Checking Options */ + "strict": true /* Enable all strict type-checking options. */, + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "strictFunctionTypes": true, /* Enable strict checking of function types. */ + // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ + // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + /* Additional Checks */ + // "noUnusedLocals": true, /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + /* Module Resolution Options */ + "moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */, + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, + // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + /* Source Map Options */ + // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + /* Advanced Options */ + "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */, + "skipLibCheck": true, + "include": [ + "src/**/*" + ] + } +} \ No newline at end of file diff --git a/packages/types/.eslintignore b/packages/types/.eslintignore new file mode 100644 index 000000000..a218a6cce --- /dev/null +++ b/packages/types/.eslintignore @@ -0,0 +1,3 @@ +lib +es +node_modules \ No newline at end of file diff --git a/packages/types/.eslintrc.js b/packages/types/.eslintrc.js new file mode 100644 index 000000000..3c65aade8 --- /dev/null +++ b/packages/types/.eslintrc.js @@ -0,0 +1,9 @@ +module.exports = { + extends: '../../.eslintrc', + rules: { + '@typescript-eslint/no-parameter-properties': 1, + 'no-param-reassign': 0, + '@typescript-eslint/member-ordering': 0, + indent: 0, + }, +}; diff --git a/packages/types/.prettierrc.js b/packages/types/.prettierrc.js new file mode 100644 index 000000000..092b67059 --- /dev/null +++ b/packages/types/.prettierrc.js @@ -0,0 +1,6 @@ +module.exports = { + printWidth: 80, + singleQuote: true, + trailingComma: 'all', + tabSize: 2, +}; diff --git a/packages/types/src/data-source-handlers.ts b/packages/types/src/data-source-handlers.ts new file mode 100644 index 000000000..2e054b4e8 --- /dev/null +++ b/packages/types/src/data-source-handlers.ts @@ -0,0 +1,15 @@ +import { + IDataSourceRuntimeContext, + RuntimeOptionsConfig, +} from './data-source-runtime'; + +export type RequestHandler = ( + options: RuntimeOptionsConfig, + context: IDataSourceRuntimeContext +) => Promise; + +export type UrlParamsHandler = ( + context?: IDataSourceRuntimeContext +) => Promise; + +export type RequestHandlersMap = Record>; diff --git a/packages/types/src/data-source-interpret.ts b/packages/types/src/data-source-interpret.ts new file mode 100644 index 000000000..be28117f7 --- /dev/null +++ b/packages/types/src/data-source-interpret.ts @@ -0,0 +1,41 @@ +import { + CompositeValue, + JSExpression, + JSFunction, + JSONObject, +} from './value-type'; + +/** + * 数据源对象 + * @see https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 + */ +export interface InterpretDataSource { + list: InterpretDataSourceConfig[]; + dataHandler?: JSFunction; +} + +/** + * 数据源对象 + * @see https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 + */ +export interface InterpretDataSourceConfig { + id: string; + isInit?: boolean | JSExpression; + isSync?: boolean | JSExpression; + type?: string; + requestHandler?: JSFunction; + dataHandler?: JSFunction; + errorHandler?: JSFunction; + willFetch?: JSFunction; + shouldFetch?: JSFunction; + options?: { + uri: string | JSExpression; + params?: JSONObject | JSExpression; + method?: string | JSExpression; + isCors?: boolean | JSExpression; + timeout?: number | JSExpression; + headers?: JSONObject | JSExpression; + [option: string]: CompositeValue; + }; + [otherKey: string]: CompositeValue; +} diff --git a/packages/types/src/data-source-runtime.ts b/packages/types/src/data-source-runtime.ts new file mode 100644 index 000000000..eb27dab61 --- /dev/null +++ b/packages/types/src/data-source-runtime.ts @@ -0,0 +1,53 @@ +import { IRuntimeDataSource } from './data-source'; + +// 先定义运行模式的类型 +export interface RuntimeDataSource { + list: RuntimeDataSourceConfig[]; + // TODO: dataMap 格式不对要处理 + dataHandler?: (dataMap: DataSourceMap) => void; +} + +export type DataSourceMap = Record; + +export interface RuntimeDataSourceConfig { + id: string; + isInit?: boolean; + isSync?: boolean; + type?: string; + willFetch?: () => void; + shouldFetch?: () => boolean; + requestHandler?: () => void; // TODO: 待定 + dataHandler?: DataHandler; + errorHandler?: ErrorHandler; + options?: RuntimeOptions; + [otherKey: string]: unknown; +} + +export type DataHandler = (response: { + data: T; + [index: string]: unknown; +}) => Promise; + +export type ErrorHandler = (err: unknown) => Promise; + +export type RuntimeOptions = () => RuntimeOptionsConfig; + +export interface RuntimeOptionsConfig { + uri: string; + params?: Record; + method?: string; + isCors?: boolean; + timeout?: number; + headers?: Record; + [option: string]: unknown; +} + +// 可以采用 react 的 state,但是需要注意必须提供同步的 setState 功能 +export interface IDataSourceRuntimeContext< + TState extends Record = Record + > { + /** 当前数据源的内容 */ + state: TState; + /** 设置状态(浅合并) */ + setState(state: Partial): void; +} diff --git a/packages/types/src/data-source.ts b/packages/types/src/data-source.ts index 79bca2e91..77d8c6d56 100644 --- a/packages/types/src/data-source.ts +++ b/packages/types/src/data-source.ts @@ -1,16 +1,65 @@ -import { CompositeValue } from './value-type'; +import { RequestHandlersMap } from './data-source-handlers'; +import { + IDataSourceRuntimeContext, + RuntimeDataSource, +} from './data-source-runtime'; -export interface DataSourceConfig { - id: string; - isInit: boolean; - type: string; - options: { - uri: string; - [option: string]: CompositeValue; - }; - [otherKey: string]: CompositeValue; +/** 数据源的状态 */ +export enum RuntimeDataSourceStatus { + /** 初始状态,尚未加载 */ + Initial = 'init', + + /** 正在加载 */ + Loading = 'loading', + + /** 已加载(无错误) */ + Loaded = 'loaded', + + /** 加载出错了 */ + Error = 'error', } -export interface DataSource { - items: DataSourceConfig[]; +/** + * 运行时的数据源(对外暴露的接口) + * @see https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#Jwgj5 + */ +export interface IRuntimeDataSource { + /** 当前状态(initial/loading/loaded/error) */ + readonly status: RuntimeDataSourceStatus; + + /** 加载成功时的数据 */ + readonly data?: TResultData; + + /** 加载出错的时候的错误信息 */ + readonly error?: Error; + + /** + * 加载数据 (无论是否曾经加载过) + * 注意:若提供 params,则会和默认配置的参数做浅合并;否则会使用默认配置的参数。 + */ + load(params?: TParams): Promise; +} + +/** + * DataSourceEngineFactory + * 用来定义 engine 的工厂函数类型 + */ +export interface IRuntimeDataSourceEngineFactory { + create( + dataSource: RuntimeDataSource, + context: IDataSourceRuntimeContext, + extraConfig?: { + requestHandlersMap: RequestHandlersMap; + [key: string]: any; + } + ): IDataSourceEngine; +} + +// create 返回的 DataSourceEngine 定义 +export interface IDataSourceEngine { + /** 数据源, key 是数据源的 ID */ + dataSourceMap: Record; + + /** 重新加载所有的数据源 */ + reloadDataSource(): Promise; } diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index d8f66a46c..4889f5e8f 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -1,4 +1,7 @@ export * from './data-source'; +export * from './data-source-handlers'; +export * from './data-source-interpret'; +export * from './data-source-runtime'; export * from './editor'; export * from './field-config'; export * from './i18n'; diff --git a/packages/types/src/value-type.ts b/packages/types/src/value-type.ts index 6e5083c0a..353033605 100644 --- a/packages/types/src/value-type.ts +++ b/packages/types/src/value-type.ts @@ -11,6 +11,44 @@ export interface JSExpression { * 模拟值 */ mock?: any; +} + +// 函数 +export interface JSFunction { + type: 'JSFunction'; + /** + * 表达式字符串 + */ + value: string; +} + +/** + * 事件函数类型 + * @see https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#feHTW + */ +export interface JSFunction { + type: 'JSFunction'; + + /** + * 函数定义,或直接函数表达式 + */ + value: string; + + /** 源码 */ + compiled?: string; +} + +// 函数 +export interface JSFunction { + type: 'JSFunction'; + /** + * 函数字符串 + */ + value: string; + /** + * 模拟值 + */ + mock?: any; /** * 额外扩展属性,如 extType、events */ @@ -18,7 +56,6 @@ export interface JSExpression { } export interface JSSlot { - name?: string; type: 'JSSlot'; title?: string; // 函数的入参 @@ -32,28 +69,44 @@ export interface JSBlock { } // JSON 基本类型 -export type JSONValue = boolean | string | number | null | undefined | JSONArray | JSONObject; +export type JSONValue = + | boolean + | string + | number + | null + | undefined + | JSONArray + | JSONObject; export type JSONArray = JSONValue[]; export interface JSONObject { [key: string]: JSONValue; } // 复合类型 -export type CompositeValue = JSONValue | JSExpression | JSSlot | CompositeArray | CompositeObject; +export type CompositeValue = + | JSONValue + | JSExpression + | JSFunction + | JSSlot + | CompositeArray + | CompositeObject; export type CompositeArray = CompositeValue[]; export interface CompositeObject { [key: string]: CompositeValue; } - export function isJSExpression(data: any): data is JSExpression { return data && data.type === 'JSExpression'; } +export function isJSFunction(x: any): x is JSFunction { + return typeof x === 'object' && x && x.type === 'JSFunction'; +} + export function isJSSlot(data: any): data is JSSlot { return data && data.type === 'JSSlot'; } export function isJSBlock(data: any): data is JSBlock { - return data && data.type === 'JSBlock' + return data && data.type === 'JSBlock'; } From 64a477cf3573729a55c031103e621954f08e5b73 Mon Sep 17 00:00:00 2001 From: "guokai.jgk" Date: Tue, 13 Oct 2020 17:17:04 +0800 Subject: [PATCH 03/18] =?UTF-8?q?fix:=20tsconfig=20=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/datasource-fetch-handler/tsconfig.json | 10 ++++------ packages/datasource-mopen-handler/tsconfig.json | 10 ++++------ packages/datasource-mtop-handler/tsconfig.json | 10 ++++------ .../tsconfig.json | 10 ++++------ .../datasource-url-params-handler/tsconfig.json | 15 +++++---------- 5 files changed, 21 insertions(+), 34 deletions(-) diff --git a/packages/datasource-fetch-handler/tsconfig.json b/packages/datasource-fetch-handler/tsconfig.json index ecd74d9e2..4f788e5ed 100644 --- a/packages/datasource-fetch-handler/tsconfig.json +++ b/packages/datasource-fetch-handler/tsconfig.json @@ -62,9 +62,7 @@ // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ /* Advanced Options */ "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */, - "skipLibCheck": true, - "include": [ - "src/**/*" - ] - } -} \ No newline at end of file + "skipLibCheck": true + }, + "include": ["src/**/*"] +} diff --git a/packages/datasource-mopen-handler/tsconfig.json b/packages/datasource-mopen-handler/tsconfig.json index ecd74d9e2..4f788e5ed 100644 --- a/packages/datasource-mopen-handler/tsconfig.json +++ b/packages/datasource-mopen-handler/tsconfig.json @@ -62,9 +62,7 @@ // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ /* Advanced Options */ "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */, - "skipLibCheck": true, - "include": [ - "src/**/*" - ] - } -} \ No newline at end of file + "skipLibCheck": true + }, + "include": ["src/**/*"] +} diff --git a/packages/datasource-mtop-handler/tsconfig.json b/packages/datasource-mtop-handler/tsconfig.json index ecd74d9e2..4f788e5ed 100644 --- a/packages/datasource-mtop-handler/tsconfig.json +++ b/packages/datasource-mtop-handler/tsconfig.json @@ -62,9 +62,7 @@ // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ /* Advanced Options */ "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */, - "skipLibCheck": true, - "include": [ - "src/**/*" - ] - } -} \ No newline at end of file + "skipLibCheck": true + }, + "include": ["src/**/*"] +} diff --git a/packages/datasource-universal-mtop-handler/tsconfig.json b/packages/datasource-universal-mtop-handler/tsconfig.json index ecd74d9e2..4f788e5ed 100644 --- a/packages/datasource-universal-mtop-handler/tsconfig.json +++ b/packages/datasource-universal-mtop-handler/tsconfig.json @@ -62,9 +62,7 @@ // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ /* Advanced Options */ "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */, - "skipLibCheck": true, - "include": [ - "src/**/*" - ] - } -} \ No newline at end of file + "skipLibCheck": true + }, + "include": ["src/**/*"] +} diff --git a/packages/datasource-url-params-handler/tsconfig.json b/packages/datasource-url-params-handler/tsconfig.json index ecd74d9e2..eeea7a79b 100644 --- a/packages/datasource-url-params-handler/tsconfig.json +++ b/packages/datasource-url-params-handler/tsconfig.json @@ -7,10 +7,7 @@ // "incremental": true, /* Enable incremental compilation */ // "target": "es6" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */, // "module": "esnext" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */, - "lib": [ - "ESNext", - "DOM" - ] /* Specify library files to be included in the compilation. */, + "lib": ["ESNext", "DOM"] /* Specify library files to be included in the compilation. */, // "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ @@ -62,9 +59,7 @@ // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ /* Advanced Options */ "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */, - "skipLibCheck": true, - "include": [ - "src/**/*" - ] - } -} \ No newline at end of file + "skipLibCheck": true + }, + "include": ["src/**/*"] +} From af4bc83cc39f69448a1280e9e9ee8da59638d7c4 Mon Sep 17 00:00:00 2001 From: "guokai.jgk" Date: Tue, 13 Oct 2020 17:29:40 +0800 Subject: [PATCH 04/18] =?UTF-8?q?fix:=20=E4=BB=A3=E7=A0=81=E7=BB=93?= =?UTF-8?q?=E6=9E=84=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/datasource-mopen-handler/src/index.ts | 2 +- packages/datasource-mtop-handler/src/index.ts | 6 ++++-- packages/datasource-url-params-handler/package.json | 2 +- packages/datasource-url-params-handler/src/index.ts | 6 ++---- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/datasource-mopen-handler/src/index.ts b/packages/datasource-mopen-handler/src/index.ts index 6fc4fb287..20fa4d2cc 100644 --- a/packages/datasource-mopen-handler/src/index.ts +++ b/packages/datasource-mopen-handler/src/index.ts @@ -16,7 +16,7 @@ export function createMopenHandler( appKey: MOPEN_APPKEY_XSPACE_PRE_ONLINE, }, ) { - return async function (options: RuntimeOptionsConfig): Promise<{ data: T }> { + return async function(options: RuntimeOptionsConfig): Promise<{ data: T }> { const { data, response } = await MopenClient.request({ config, ...options, diff --git a/packages/datasource-mtop-handler/src/index.ts b/packages/datasource-mtop-handler/src/index.ts index 2527dda5c..1a6007be6 100644 --- a/packages/datasource-mtop-handler/src/index.ts +++ b/packages/datasource-mtop-handler/src/index.ts @@ -9,9 +9,11 @@ export type DataType = 'jsonp' | 'json' | 'originaljsonp'; // 考虑一下 mtop 类型的问题,官方没有提供 ts 文件 export function createMtopHandler(config?: MTopConfig) { if (config && Object.keys(config).length > 0) { - Object.keys(config).forEach((key: string) => mtopRequest.config(key, config[key])); + Object.keys(config).forEach((key: string) => + mtopRequest.config(key, config[key]), + ); } - return async function (options: RuntimeOptionsConfig): Promise<{ data: T }> { + return async function(options: RuntimeOptionsConfig): Promise<{ data: T }> { const response = await mtopRequest.request({ api: options.uri, v: (options.v as string) || '1.0', diff --git a/packages/datasource-url-params-handler/package.json b/packages/datasource-url-params-handler/package.json index 869648b15..39f45f729 100644 --- a/packages/datasource-url-params-handler/package.json +++ b/packages/datasource-url-params-handler/package.json @@ -16,7 +16,7 @@ "prepublishOnly": "npm run build" }, "dependencies": { - "@ali/lowcode-types": "^1.0.10", + "@ali/lowcode-types": "^0.8.13", "query-string": "^6.13.1", "typescript": "^3.9.7" }, diff --git a/packages/datasource-url-params-handler/src/index.ts b/packages/datasource-url-params-handler/src/index.ts index db4761fc0..350234854 100644 --- a/packages/datasource-url-params-handler/src/index.ts +++ b/packages/datasource-url-params-handler/src/index.ts @@ -1,10 +1,8 @@ import qs from 'query-string'; import { UrlParamsHandler } from '@ali/lowcode-types'; -export function createUrlParamsHandler( - searchString: string | T = '', -): UrlParamsHandler { - return async function (): Promise { +export function createUrlParamsHandler(searchString: string | T = ''): UrlParamsHandler { + return async function(): Promise { if (typeof searchString === 'string') { const params = (qs.parse(searchString) as unknown) as T; return params; From b9bf8002dce78212f542c854f7bb0075ce2596dc Mon Sep 17 00:00:00 2001 From: "guokai.jgk" Date: Fri, 23 Oct 2020 11:30:38 +0800 Subject: [PATCH 05/18] =?UTF-8?q?fix:=20will=20fetch=20=E6=8C=89=E7=85=A7?= =?UTF-8?q?=E5=8D=8F=E8=AE=AE=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/core/RuntimeDataSourceItem.ts | 14 ++++++++++---- packages/datasource-engine/src/helpers/index.ts | 12 +++++++----- packages/types/src/data-source-runtime.ts | 8 ++++++-- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/packages/datasource-engine/src/core/RuntimeDataSourceItem.ts b/packages/datasource-engine/src/core/RuntimeDataSourceItem.ts index d4184707a..0abfe5a18 100644 --- a/packages/datasource-engine/src/core/RuntimeDataSourceItem.ts +++ b/packages/datasource-engine/src/core/RuntimeDataSourceItem.ts @@ -106,12 +106,18 @@ class RuntimeDataSourceItem< return; } + let fetchOptions = this._options; + // willFetch - this._dataSourceConfig.willFetch!(); + try { + fetchOptions = await this._dataSourceConfig.willFetch!(this._options); + } catch (error) { + console.error(error); + } // 约定如果 params 有内容,直接做替换,如果没有就用默认的 options 的 - if (params && this._options) { - this._options.params = params; + if (params && fetchOptions) { + fetchOptions.params = params; } const dataHandler = this._dataSourceConfig.dataHandler!; @@ -124,7 +130,7 @@ class RuntimeDataSourceItem< // _context 会给传,但是用不用由 handler 说了算 const result = await (this._request as RequestHandler<{ data: TResultData; - }>)(this._options, this._context).then(dataHandler, errorHandler); + }>)(fetchOptions, this._context).then(dataHandler, errorHandler); // setState this._context.setState({ diff --git a/packages/datasource-engine/src/helpers/index.ts b/packages/datasource-engine/src/helpers/index.ts index 71565b434..1b2726566 100644 --- a/packages/datasource-engine/src/helpers/index.ts +++ b/packages/datasource-engine/src/helpers/index.ts @@ -1,7 +1,8 @@ -import { DataHandler } from '@ali/lowcode-types'; - -// eslint-disable-next-line @typescript-eslint/no-empty-function -function noop() {} +import { + DataHandler, + RuntimeOptionsConfig, + WillFetch, +} from '@ali/lowcode-types'; // 默认的 dataSourceItem 的 dataHandler export const defaultDataHandler: DataHandler = async (response: { @@ -9,7 +10,8 @@ export const defaultDataHandler: DataHandler = async (response: { }) => response.data; // 默认的 dataSourceItem 的 willFetch -export const defaultWillFetch = noop; +export const defaultWillFetch: WillFetch = (options: RuntimeOptionsConfig) => + options; // 默认的 dataSourceItem 的 shouldFetch export const defaultShouldFetch = () => true; diff --git a/packages/types/src/data-source-runtime.ts b/packages/types/src/data-source-runtime.ts index eb27dab61..9a89e39aa 100644 --- a/packages/types/src/data-source-runtime.ts +++ b/packages/types/src/data-source-runtime.ts @@ -14,7 +14,7 @@ export interface RuntimeDataSourceConfig { isInit?: boolean; isSync?: boolean; type?: string; - willFetch?: () => void; + willFetch?: WillFetch; shouldFetch?: () => boolean; requestHandler?: () => void; // TODO: 待定 dataHandler?: DataHandler; @@ -23,6 +23,10 @@ export interface RuntimeDataSourceConfig { [otherKey: string]: unknown; } +export type WillFetch = ( + options: RuntimeOptionsConfig, +) => Promise | RuntimeOptionsConfig; + export type DataHandler = (response: { data: T; [index: string]: unknown; @@ -45,7 +49,7 @@ export interface RuntimeOptionsConfig { // 可以采用 react 的 state,但是需要注意必须提供同步的 setState 功能 export interface IDataSourceRuntimeContext< TState extends Record = Record - > { +> { /** 当前数据源的内容 */ state: TState; /** 设置状态(浅合并) */ From a2a7ee7fcc80969ab81a8acea80ed058e5b1a378 Mon Sep 17 00:00:00 2001 From: "guokai.jgk" Date: Fri, 23 Oct 2020 12:32:06 +0800 Subject: [PATCH 06/18] v0.8.14-alpha.1 --- packages/types/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/types/package.json b/packages/types/package.json index 010ae5cd1..afe7de92c 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-types", - "version": "0.8.13", + "version": "0.8.14-alpha.1", "description": "Types for Ali lowCode engine", "files": [ "es", From 9f51e39264f55cae94ad4a594145aa297c679c8f Mon Sep 17 00:00:00 2001 From: "guokai.jgk" Date: Fri, 23 Oct 2020 14:05:54 +0800 Subject: [PATCH 07/18] =?UTF-8?q?fix:=20JSExpression=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=20compiled?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/types/src/value-type.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/types/src/value-type.ts b/packages/types/src/value-type.ts index 353033605..47904a6b7 100644 --- a/packages/types/src/value-type.ts +++ b/packages/types/src/value-type.ts @@ -11,6 +11,8 @@ export interface JSExpression { * 模拟值 */ mock?: any; + /** 源码 */ + compiled?: string; } // 函数 From 7785e69a54c9febfb4c29e74f6ac6e09a520a2c2 Mon Sep 17 00:00:00 2001 From: "guokai.jgk" Date: Fri, 23 Oct 2020 18:37:13 +0800 Subject: [PATCH 08/18] v1.0.13-alpha.1 --- packages/types/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/types/package.json b/packages/types/package.json index 9dba9b103..54e781abc 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-types", - "version": "1.0.12", + "version": "1.0.13-alpha.1", "description": "Types for Ali lowCode engine", "files": [ "es", From 732c35b1ef6afca269cdd65216736b8e626bfc0a Mon Sep 17 00:00:00 2001 From: "guokai.jgk" Date: Fri, 23 Oct 2020 18:49:24 +0800 Subject: [PATCH 09/18] v1.0.2-alpha.1 --- packages/datasource-engine/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/datasource-engine/package.json b/packages/datasource-engine/package.json index 6479c7c0b..c19924a9d 100644 --- a/packages/datasource-engine/package.json +++ b/packages/datasource-engine/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-datasource-engine", - "version": "1.0.1", + "version": "1.0.2-alpha.1", "main": "dist/index.js", "files": [ "dist", @@ -15,7 +15,7 @@ }, "typings": "dist/index.d.ts", "dependencies": { - "@ali/lowcode-types": "^0.8.13", + "@ali/lowcode-types": "1.0.13-alpha.1", "typescript": "^3.9.7" }, "devDependencies": { From 9d97e569b146a3023d509def4a9b234c02512763 Mon Sep 17 00:00:00 2001 From: "guokai.jgk" Date: Fri, 23 Oct 2020 18:51:30 +0800 Subject: [PATCH 10/18] v1.0.2-alpha.1 --- packages/datasource-mtop-handler/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/datasource-mtop-handler/package.json b/packages/datasource-mtop-handler/package.json index 2143f71eb..ed15f9813 100644 --- a/packages/datasource-mtop-handler/package.json +++ b/packages/datasource-mtop-handler/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-datasource-mtop-handler", - "version": "1.0.1", + "version": "1.0.2-alpha.1", "main": "lib/index.js", "module": "es/index.js", "typings": "es/index.d.ts", @@ -16,7 +16,7 @@ "prepublishOnly": "npm run build" }, "dependencies": { - "@ali/lowcode-types": "^1.0.10", + "@ali/lowcode-types": "1.0.13-alpha.1", "@ali/universal-mtop": "^5.1.9", "typescript": "^3.9.7" }, From c346137092e20689cc9f67dd27652e37113075f7 Mon Sep 17 00:00:00 2001 From: "guokai.jgk" Date: Mon, 26 Oct 2020 15:32:55 +0800 Subject: [PATCH 11/18] fix: eslint --- packages/datasource-engine/package.json | 2 +- .../src/core/reloadDataSourceFactory.ts | 10 +- packages/datasource-engine/src/utils.ts | 82 ++++++++--- .../_macro-abnormal.ts | 130 +++++++++--------- 4 files changed, 138 insertions(+), 86 deletions(-) diff --git a/packages/datasource-engine/package.json b/packages/datasource-engine/package.json index c19924a9d..efa301ff7 100644 --- a/packages/datasource-engine/package.json +++ b/packages/datasource-engine/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-datasource-engine", - "version": "1.0.2-alpha.1", + "version": "1.0.2-alpha.2", "main": "dist/index.js", "files": [ "dist", diff --git a/packages/datasource-engine/src/core/reloadDataSourceFactory.ts b/packages/datasource-engine/src/core/reloadDataSourceFactory.ts index 8433d0d0a..b871c2f37 100644 --- a/packages/datasource-engine/src/core/reloadDataSourceFactory.ts +++ b/packages/datasource-engine/src/core/reloadDataSourceFactory.ts @@ -15,6 +15,7 @@ export const reloadDataSourceFactory = ( dataSource.list .filter( (el: RuntimeDataSourceConfig) => + // eslint-disable-next-line implicit-arrow-linebreak el.type === 'urlParams' && (typeof el.isInit === 'boolean' ? el.isInit : true), ) @@ -51,8 +52,13 @@ export const reloadDataSourceFactory = ( ds.isInit && ds.isSync ) { - // eslint-disable-next-line no-await-in-loop - await dataSourceMap[ds.id].load(); + try { + // eslint-disable-next-line no-await-in-loop + await dataSourceMap[ds.id].load(); + } catch (e) { + // TODO: 这个错误直接吃掉? + console.error(e); + } } } diff --git a/packages/datasource-engine/src/utils.ts b/packages/datasource-engine/src/utils.ts index b31076f28..19b277615 100644 --- a/packages/datasource-engine/src/utils.ts +++ b/packages/datasource-engine/src/utils.ts @@ -9,6 +9,7 @@ import { JSExpression, JSFunction, JSONObject, + RuntimeOptionsConfig, } from '@ali/lowcode-types'; export const transformExpression = ( @@ -123,25 +124,70 @@ export const buildOptions = ( ) => { const { options } = ds; if (!options) return undefined; + // eslint-disable-next-line space-before-function-paren return function() { - return { - uri: getRuntimeValueFromConfig('string', options.uri, context), - params: options.params ? buildJsonObj(options.params, context) : {}, - method: options.method - ? getRuntimeValueFromConfig('string', options.method, context) - : 'GET', - isCors: options.isCors - ? getRuntimeValueFromConfig('boolean', options.isCors, context) - : true, - timeout: options.timeout - ? getRuntimeValueFromConfig('number', options.timeout, context) - : 5000, - headers: options.headers - ? buildJsonObj(options.headers, context) - : undefined, - v: options.v - ? getRuntimeValueFromConfig('string', options.v, context) - : '1.0', + // 默认值 + const fetchOptions: RuntimeOptionsConfig = { + uri: '', + params: {}, + method: 'GET', + isCors: true, + timeout: 5000, + headers: undefined, + v: '1.0', }; + Object.keys(options).forEach((key: string) => { + switch (key) { + case 'uri': + fetchOptions.uri = getRuntimeValueFromConfig( + 'string', + options.uri, + context, + ); + break; + case 'params': + fetchOptions.params = buildJsonObj(options.params!, context); + break; + case 'method': + fetchOptions.method = getRuntimeValueFromConfig( + 'string', + options.method, + context, + ); + break; + case 'isCors': + fetchOptions.isCors = getRuntimeValueFromConfig( + 'boolean', + options.isCors, + context, + ); + break; + case 'timeout': + fetchOptions.timeout = getRuntimeValueFromConfig( + 'number', + options.timeout, + context, + ); + break; + case 'headers': + fetchOptions.headers = buildJsonObj(options.headers!, context); + break; + case 'v': + fetchOptions.v = getRuntimeValueFromConfig( + 'string', + options.v, + context, + ); + break; + default: + // 其余的除了做表达式或者 function 的转换,直接透传 + fetchOptions[key] = getRuntimeValueFromConfig( + 'unknown', + options[key], + context, + ); + } + }); + return fetchOptions; }; }; diff --git a/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/_macro-abnormal.ts b/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/_macro-abnormal.ts index f81db6b49..f0fa43060 100644 --- a/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/_macro-abnormal.ts +++ b/packages/datasource-engine/test/scenes/p0-0-sync-datasources-dealt-in-serial/_macro-abnormal.ts @@ -25,72 +25,72 @@ export const abnormalScene: Macro<[ ]> = async ( t: ExecutionContext<{ clock: SinonFakeTimers }>, { create, dataSource }, - ) => { - const { clock } = t.context; +) => { + const { clock } = t.context; - const USER_DATA = { - id: 9527, - name: 'Alice', - }; - const ERROR_MSG = 'test error'; - const fetchHandler = sinon.fake(async ({ uri }) => { - await delay(100); - if (/user/.test(uri)) { - return { data: USER_DATA }; - } else { - throw new Error(ERROR_MSG); - } - }); - - const context = new MockContext>({}, (ctx) => create(bindRuntimeContext(dataSource, ctx), ctx, { - requestHandlersMap: { - fetch: fetchHandler, - }, - })); - - const setState = sinon.spy(context, 'setState'); - - // 一开始应该是初始状态 - t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Initial); - t.is(context.dataSourceMap.orders.status, RuntimeDataSourceStatus.Initial); - - const loading = context.reloadDataSource(); - - await clock.tickAsync(50); - - // 中间应该有 loading 态 - t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loading); - - await clock.tickAsync(50); - - t.is(context.dataSourceMap.orders.status, RuntimeDataSourceStatus.Loading); - - await Promise.all([clock.runAllAsync(), loading]); - - // 最后 user 应该成功了,loaded - t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loaded); - // 最后 orders 应该失败了,error 状态 - t.is(context.dataSourceMap.orders.status, RuntimeDataSourceStatus.Error); - - // 检查数据源的数据 - t.deepEqual(context.dataSourceMap.user.data, USER_DATA); - t.is(context.dataSourceMap.user.error, undefined); - t.deepEqual(context.dataSourceMap.orders.data, undefined); - t.not(context.dataSourceMap.orders.error, undefined); - t.regex(context.dataSourceMap.orders.error!.message, new RegExp(ERROR_MSG)); - - // 检查状态数据 - t.assert(setState.calledOnce); - t.deepEqual(context.state.user, USER_DATA); - t.is(context.state.orders, undefined); - - // fetchHandler 应该被调用了2次 - t.assert(fetchHandler.calledTwice); - - const firstListItemOptions = DATA_SOURCE_SCHEMA.list[0].options; - const fetchHandlerCallArgs = fetchHandler.firstCall.args[0]; - // 检查调用参数 - t.is(firstListItemOptions.uri, fetchHandlerCallArgs.uri); + const USER_DATA = { + id: 9527, + name: 'Alice', }; + const ERROR_MSG = 'test error'; + const fetchHandler = sinon.fake(async ({ uri }) => { + await delay(100); + if (/user/.test(uri)) { + return { data: USER_DATA }; + } else { + throw new Error(ERROR_MSG); + } + }); + + const context = new MockContext>({}, (ctx) => create(bindRuntimeContext(dataSource, ctx), ctx, { + requestHandlersMap: { + fetch: fetchHandler, + }, + })); + + const setState = sinon.spy(context, 'setState'); + + // 一开始应该是初始状态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Initial); + t.is(context.dataSourceMap.orders.status, RuntimeDataSourceStatus.Initial); + + const loading = context.reloadDataSource(); + + await clock.tickAsync(50); + + // 中间应该有 loading 态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loading); + + await clock.tickAsync(50); + + t.is(context.dataSourceMap.orders.status, RuntimeDataSourceStatus.Loading); + + await Promise.all([clock.runAllAsync(), loading]); + + // 最后 user 应该成功了,loaded + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loaded); + // 最后 orders 应该失败了,error 状态 + t.is(context.dataSourceMap.orders.status, RuntimeDataSourceStatus.Error); + + // 检查数据源的数据 + t.deepEqual(context.dataSourceMap.user.data, USER_DATA); + t.is(context.dataSourceMap.user.error, undefined); + t.deepEqual(context.dataSourceMap.orders.data, undefined); + t.not(context.dataSourceMap.orders.error, undefined); + t.regex(context.dataSourceMap.orders.error!.message, new RegExp(ERROR_MSG)); + + // 检查状态数据 + t.assert(setState.calledOnce); + t.deepEqual(context.state.user, USER_DATA); + t.is(context.state.orders, undefined); + + // fetchHandler 应该被调用了2次 + t.assert(fetchHandler.calledTwice); + + const firstListItemOptions = DATA_SOURCE_SCHEMA.list[0].options; + const fetchHandlerCallArgs = fetchHandler.firstCall.args[0]; + // 检查调用参数 + t.is(firstListItemOptions.uri, fetchHandlerCallArgs.uri); +}; abnormalScene.title = (providedTitle) => providedTitle || 'abnormal scene'; From 17289d466a2e01f14fe996e0e11446ee14c15504 Mon Sep 17 00:00:00 2001 From: "guokai.jgk" Date: Tue, 27 Oct 2020 12:21:41 +0800 Subject: [PATCH 12/18] v1.0.2-alpha.2 --- packages/datasource-mtop-handler/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/datasource-mtop-handler/package.json b/packages/datasource-mtop-handler/package.json index ed15f9813..1c841db3a 100644 --- a/packages/datasource-mtop-handler/package.json +++ b/packages/datasource-mtop-handler/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-datasource-mtop-handler", - "version": "1.0.2-alpha.1", + "version": "1.0.2-alpha.2", "main": "lib/index.js", "module": "es/index.js", "typings": "es/index.d.ts", From 98f3a17c3c3fd048dde588286fde940854dfcccc Mon Sep 17 00:00:00 2001 From: "guokai.jgk" Date: Tue, 27 Oct 2020 12:24:18 +0800 Subject: [PATCH 13/18] fix: eslint --- packages/datasource-engine/.eslintrc.js | 2 +- .../src/core/DataSourceEngine.ts | 124 ------------------ .../src/core/RuntimeDataSource.ts | 94 ------------- .../datasource-fetch-handler/package.json | 2 +- .../datasource-mtop-handler/.prettierrc.js | 2 +- packages/datasource-mtop-handler/src/index.ts | 18 ++- .../datasource-mtop-handler/src/typings.d.ts | 2 +- 7 files changed, 18 insertions(+), 226 deletions(-) delete mode 100644 packages/datasource-engine/src/core/DataSourceEngine.ts delete mode 100644 packages/datasource-engine/src/core/RuntimeDataSource.ts diff --git a/packages/datasource-engine/.eslintrc.js b/packages/datasource-engine/.eslintrc.js index 8c13fcaf4..258d60040 100644 --- a/packages/datasource-engine/.eslintrc.js +++ b/packages/datasource-engine/.eslintrc.js @@ -1,7 +1,7 @@ module.exports = { extends: '../../.eslintrc', rules: { - '@typescript-eslint/no-parameter-properties': 1, + '@typescript-eslint/no-parameter-properties': 0, 'no-param-reassign': 0, }, }; diff --git a/packages/datasource-engine/src/core/DataSourceEngine.ts b/packages/datasource-engine/src/core/DataSourceEngine.ts deleted file mode 100644 index d24ef2420..000000000 --- a/packages/datasource-engine/src/core/DataSourceEngine.ts +++ /dev/null @@ -1,124 +0,0 @@ -import { - DataSourceConfig, - DataSourceEngineOptions, - IDataSourceEngine, - IDataSourceEngineFactory, - IRuntimeContext, -} from '../types'; -import { RuntimeDataSource } from './RuntimeDataSource'; - -export class DataSourceEngine implements IDataSourceEngine { - private _dataSourceMap: Record = {}; - - constructor( - private _dataSourceConfig: DataSourceConfig, - private _runtimeContext: IRuntimeContext, - private _options?: DataSourceEngineOptions, - ) { - // eslint-disable-next-line no-unused-expressions - _dataSourceConfig.list?.forEach((ds) => { - // 确保数据源都有处理器 - const requestHandler = ds.requestHandler || _options?.requestHandlersMap?.[ds.type]; - if (!requestHandler) { - throw new Error(`No request handler for "${ds.type}" data source`); - } - - this._dataSourceMap[ds.id] = new RuntimeDataSource( - ds.id, - ds.type, - getValue(ds.options) || {}, - requestHandler.bind(_runtimeContext), - ds.dataHandler ? ds.dataHandler.bind(_runtimeContext) : undefined, - (data) => { - _runtimeContext.setState({ [ds.id]: data }); - }, - ); - }); - } - - public get dataSourceMap() { - return this._dataSourceMap; - } - - public async reloadDataSource() { - try { - const allDataSourceConfigList = this._dataSourceConfig.list || []; - - // urlParams 类型的优先加载 - for (const ds of allDataSourceConfigList) { - if (ds.type === 'urlParams' && (getValue(ds.isInit) ?? true)) { - await this._dataSourceMap[ds.id].load(); - } - } - - // 然后是所有其他的 - const remainDataSourceConfigList = allDataSourceConfigList.filter((x) => x.type !== 'urlParams'); - - // 先发起异步的 - const asyncLoadings: Array> = []; - for (const ds of remainDataSourceConfigList) { - if (getValue(ds.isInit) ?? true) { - const options = getValue(ds.options); - if (options && !options.isSync) { - this._dataSourceMap[ds.id].setOptions(options); - asyncLoadings.push(this._dataSourceMap[ds.id].load(options?.params).catch(() => {})); - } - } - } - - try { - // 再按先后顺序发起同步请求 - for (const ds of remainDataSourceConfigList) { - if (getValue(ds.isInit) ?? true) { - const options = getValue(ds.options); - if (options && options.isSync) { - this._dataSourceMap[ds.id].setOptions(options); - await this._dataSourceMap[ds.id].load(options?.params); - await sleep(0); // TODO: 如何优雅地解决 setState 的异步问题? - } - } - } - } catch (e) { - // ignore error - } - - await Promise.all(asyncLoadings); - } finally { - const allDataHandler = this._dataSourceConfig.dataHandler; - if (allDataHandler) { - await allDataHandler(this._getDataMapOfAll()); - } - } - } - - private _getDataMapOfAll(): Record { - const dataMap: Record = {}; - - Object.entries(this._dataSourceMap).forEach(([dsId, ds]) => { - dataMap[dsId] = ds.data; - }); - - return dataMap; - } -} - -export const create: IDataSourceEngineFactory['create'] = (dataSourceConfig, runtimeContext, options) => { - return new DataSourceEngine(dataSourceConfig, runtimeContext, options); -}; - -function getValue(valueOrValueGetter: T | (() => T)): T; -function getValue(valueOrValueGetter: T | (() => T)): T | undefined { - if (typeof valueOrValueGetter === 'function') { - try { - return valueOrValueGetter(); - } catch (e) { - return undefined; - } - } else { - return valueOrValueGetter; - } -} - -function sleep(ms = 0) { - return new Promise((resolve) => setTimeout(resolve, ms)); -} diff --git a/packages/datasource-engine/src/core/RuntimeDataSource.ts b/packages/datasource-engine/src/core/RuntimeDataSource.ts deleted file mode 100644 index 89ec2d930..000000000 --- a/packages/datasource-engine/src/core/RuntimeDataSource.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { DataSourceOptions, IRuntimeDataSource, RequestHandler, RuntimeDataSourceStatus } from '../types'; -import { DataSourceResponse } from '../types/DataSourceResponse'; - -export class RuntimeDataSource< - TParams extends Record = Record, - TRequestResult = unknown, - TResultData = unknown -> implements IRuntimeDataSource { - private _status: RuntimeDataSourceStatus = RuntimeDataSourceStatus.Initial; - - private _data?: TResultData; - - private _error?: Error; - - private _latestOptions: DataSourceOptions; - - constructor( - private _id: string, - private _type: string, - private _initialOptions: DataSourceOptions, - private _requestHandler: RequestHandler, DataSourceResponse>, - private _dataHandler: - | (( - data: DataSourceResponse | undefined, - error: unknown | undefined, - ) => TResultData | Promise) - | undefined, - private _onLoaded: (data: TResultData) => void, - ) { - this._latestOptions = _initialOptions; - } - - public get status() { - return this._status; - } - - public get data() { - return this._data; - } - - public get error() { - return this._error; - } - - public async load(params?: TParams): Promise { - try { - this._latestOptions = { - ...this._latestOptions, - params: { - ...this._latestOptions.params, - ...params, - } as TParams, - }; - - this._status = RuntimeDataSourceStatus.Loading; - - const data = await this._request(this._latestOptions); - - this._status = RuntimeDataSourceStatus.Loaded; - - this._onLoaded(data); - - this._data = data; - return data; - } catch (err) { - this._error = err; - this._status = RuntimeDataSourceStatus.Error; - throw err; - } - } - - public setOptions(options: DataSourceOptions) { - this._latestOptions = options; - } - - private async _request(options: DataSourceOptions) { - try { - const response = await this._requestHandler(options); - - const data = this._dataHandler - ? await this._dataHandler(response, undefined) - : ((response.data as unknown) as TResultData); - - return data; - } catch (err) { - if (this._dataHandler) { - const data = await this._dataHandler(undefined, err); - return data; - } - - throw err; - } - } -} diff --git a/packages/datasource-fetch-handler/package.json b/packages/datasource-fetch-handler/package.json index 8dbc63a6f..720a8f770 100644 --- a/packages/datasource-fetch-handler/package.json +++ b/packages/datasource-fetch-handler/package.json @@ -16,7 +16,7 @@ "prepublishOnly": "npm run build" }, "dependencies": { - "@ali/lowcode-types": "^1.0.10", + "@ali/lowcode-types": "1.0.13-alpha.1", "typescript": "^3.9.7", "universal-request": "^2.2.0" }, diff --git a/packages/datasource-mtop-handler/.prettierrc.js b/packages/datasource-mtop-handler/.prettierrc.js index de2f53cdf..a425d3f76 100644 --- a/packages/datasource-mtop-handler/.prettierrc.js +++ b/packages/datasource-mtop-handler/.prettierrc.js @@ -1,4 +1,4 @@ module.exports = { singleQuote: true, - trailingComma: 'all', + trailingComma: 'es5', }; diff --git a/packages/datasource-mtop-handler/src/index.ts b/packages/datasource-mtop-handler/src/index.ts index 1a6007be6..a582076da 100644 --- a/packages/datasource-mtop-handler/src/index.ts +++ b/packages/datasource-mtop-handler/src/index.ts @@ -9,10 +9,11 @@ export type DataType = 'jsonp' | 'json' | 'originaljsonp'; // 考虑一下 mtop 类型的问题,官方没有提供 ts 文件 export function createMtopHandler(config?: MTopConfig) { if (config && Object.keys(config).length > 0) { - Object.keys(config).forEach((key: string) => - mtopRequest.config(key, config[key]), - ); + Object.keys(config).forEach((key: string) => { + mtopRequest.config(key, config[key]); + }); } + // eslint-disable-next-line space-before-function-paren return async function(options: RuntimeOptionsConfig): Promise<{ data: T }> { const response = await mtopRequest.request({ api: options.uri, @@ -23,6 +24,15 @@ export function createMtopHandler(config?: MTopConfig) { timeout: options.timeout, headers: options.headers, }); - return response; + if (response.ret && response.ret[0].indexOf('SUCCESS::') > -1) { + // 校验成功 + return response; + } + // 默认异常 + let errorMsg = '未知异常'; + if (response.ret && response.ret[0]) { + errorMsg = response.ret[0]; + } + throw new Error(errorMsg); }; } diff --git a/packages/datasource-mtop-handler/src/typings.d.ts b/packages/datasource-mtop-handler/src/typings.d.ts index 6a5989f78..11f4d02cd 100644 --- a/packages/datasource-mtop-handler/src/typings.d.ts +++ b/packages/datasource-mtop-handler/src/typings.d.ts @@ -6,6 +6,6 @@ declare interface MTopConfig { } declare module '@ali/universal-mtop' { - const request: (config: any) => Promise<{ data: T }>; + const request: (config: any) => Promise<{ data: T; ret: string[] }>; const config: (key: string, value: unknown) => void; } From 9c8a011160803f20afab954d110860c2135bb589 Mon Sep 17 00:00:00 2001 From: "guokai.jgk" Date: Thu, 29 Oct 2020 17:44:54 +0800 Subject: [PATCH 14/18] v1.0.13-alpha.2 --- packages/types/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/types/package.json b/packages/types/package.json index 54e781abc..200cc6eb7 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-types", - "version": "1.0.13-alpha.1", + "version": "1.0.13-alpha.2", "description": "Types for Ali lowCode engine", "files": [ "es", From 4ef1097638c4ce959781770d5cff4e8111f93659 Mon Sep 17 00:00:00 2001 From: "guokai.jgk" Date: Thu, 29 Oct 2020 17:47:17 +0800 Subject: [PATCH 15/18] v1.0.2-alpha.3 --- packages/datasource-engine/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/datasource-engine/package.json b/packages/datasource-engine/package.json index efa301ff7..ba99aee17 100644 --- a/packages/datasource-engine/package.json +++ b/packages/datasource-engine/package.json @@ -1,6 +1,6 @@ { "name": "@ali/lowcode-datasource-engine", - "version": "1.0.2-alpha.2", + "version": "1.0.2-alpha.3", "main": "dist/index.js", "files": [ "dist", @@ -15,7 +15,7 @@ }, "typings": "dist/index.d.ts", "dependencies": { - "@ali/lowcode-types": "1.0.13-alpha.1", + "@ali/lowcode-types": "1.0.13-alpha.2", "typescript": "^3.9.7" }, "devDependencies": { From cf3c7dbd35f90b8aa5efba81ff26ca10daf8c9bc Mon Sep 17 00:00:00 2001 From: "guokai.jgk" Date: Thu, 29 Oct 2020 17:54:53 +0800 Subject: [PATCH 16/18] feat: update datasource engine --- packages/datasource-engine/.eslintrc.js | 1 + packages/datasource-engine/.prettierrc.js | 1 + .../src/core/RuntimeDataSourceItem.ts | 28 +++--- .../datasource-engine/src/core/adapter.ts | 62 +++++-------- .../src/core/reloadDataSourceFactory.ts | 20 ++--- .../datasource-engine/src/helpers/index.ts | 26 ++++-- .../src/interpret/DataSourceEngineFactory.ts | 22 ++--- .../runtime/RuntimeDataSourceEngineFactory.ts | 29 ++---- .../p0-0-custom-request-handlers/README.md | 3 + .../_datasource-runtime.ts | 67 ++++++++++++++ .../_datasource-schema.ts | 67 ++++++++++++++ .../_macro-normal.ts | 90 +++++++++++++++++++ .../normal-interpret.test.ts | 20 +++++ .../normal-runtime.test.ts | 20 +++++ packages/types/src/data-source-handlers.ts | 10 ++- packages/types/src/data-source-runtime.ts | 6 +- 16 files changed, 355 insertions(+), 117 deletions(-) create mode 100644 packages/datasource-engine/test/scenes/p0-0-custom-request-handlers/README.md create mode 100644 packages/datasource-engine/test/scenes/p0-0-custom-request-handlers/_datasource-runtime.ts create mode 100644 packages/datasource-engine/test/scenes/p0-0-custom-request-handlers/_datasource-schema.ts create mode 100644 packages/datasource-engine/test/scenes/p0-0-custom-request-handlers/_macro-normal.ts create mode 100644 packages/datasource-engine/test/scenes/p0-0-custom-request-handlers/normal-interpret.test.ts create mode 100644 packages/datasource-engine/test/scenes/p0-0-custom-request-handlers/normal-runtime.test.ts diff --git a/packages/datasource-engine/.eslintrc.js b/packages/datasource-engine/.eslintrc.js index 258d60040..6cbc6c8e9 100644 --- a/packages/datasource-engine/.eslintrc.js +++ b/packages/datasource-engine/.eslintrc.js @@ -3,5 +3,6 @@ module.exports = { rules: { '@typescript-eslint/no-parameter-properties': 0, 'no-param-reassign': 0, + 'max-len': 0, }, }; diff --git a/packages/datasource-engine/.prettierrc.js b/packages/datasource-engine/.prettierrc.js index de2f53cdf..21ec86215 100644 --- a/packages/datasource-engine/.prettierrc.js +++ b/packages/datasource-engine/.prettierrc.js @@ -1,4 +1,5 @@ module.exports = { singleQuote: true, trailingComma: 'all', + printWidth: 120, }; diff --git a/packages/datasource-engine/src/core/RuntimeDataSourceItem.ts b/packages/datasource-engine/src/core/RuntimeDataSourceItem.ts index 0abfe5a18..5d71e2e1b 100644 --- a/packages/datasource-engine/src/core/RuntimeDataSourceItem.ts +++ b/packages/datasource-engine/src/core/RuntimeDataSourceItem.ts @@ -9,10 +9,8 @@ import { UrlParamsHandler, } from '@ali/lowcode-types'; -class RuntimeDataSourceItem< - TParams extends Record = Record, - TResultData = unknown -> implements IRuntimeDataSource { +class RuntimeDataSourceItem = Record, TResultData = unknown> + implements IRuntimeDataSource { private _data?: TResultData; private _error?: Error; @@ -21,9 +19,7 @@ class RuntimeDataSourceItem< private _dataSourceConfig: RuntimeDataSourceConfig; - private _request: - | RequestHandler<{ data: TResultData }> - | UrlParamsHandler; + private _request: RequestHandler<{ data: TResultData }> | UrlParamsHandler; private _context: IDataSourceRuntimeContext; @@ -31,9 +27,7 @@ class RuntimeDataSourceItem< constructor( dataSourceConfig: RuntimeDataSourceConfig, - request: - | RequestHandler<{ data: TResultData }> - | UrlParamsHandler, + request: RequestHandler<{ data: TResultData }> | UrlParamsHandler, context: IDataSourceRuntimeContext, ) { this._dataSourceConfig = dataSourceConfig; @@ -57,14 +51,14 @@ class RuntimeDataSourceItem< if (!this._dataSourceConfig) return; // 考虑没有绑定对应的 handler 的情况 if (!this._request) { - throw new Error(`no ${this._dataSourceConfig.type} handler provide`); + this._error = new Error(`no ${this._dataSourceConfig.type} handler provide`); + this._status = RuntimeDataSourceStatus.Error; + throw this._error; } // TODO: urlParams 有没有更好的处理方式 if (this._dataSourceConfig.type === 'urlParams') { - const response = await (this._request as UrlParamsHandler)( - this._context, - ); + const response = await (this._request as UrlParamsHandler)(this._context); this._context.setState({ [this._dataSourceConfig.id]: response, }); @@ -100,10 +94,8 @@ class RuntimeDataSourceItem< if (!shouldFetch) { this._status = RuntimeDataSourceStatus.Error; - this._error = new Error( - `the ${this._dataSourceConfig.id} request should not fetch, please check the condition`, - ); - return; + this._error = new Error(`the ${this._dataSourceConfig.id} request should not fetch, please check the condition`); + throw this._error; } let fetchOptions = this._options; diff --git a/packages/datasource-engine/src/core/adapter.ts b/packages/datasource-engine/src/core/adapter.ts index 41a476bc7..71f930bea 100644 --- a/packages/datasource-engine/src/core/adapter.ts +++ b/packages/datasource-engine/src/core/adapter.ts @@ -1,10 +1,4 @@ -import { - transformFunction, - getRuntimeValueFromConfig, - getRuntimeJsValue, - buildOptions, - buildShouldFetch, -} from './../utils'; +import { getRuntimeValueFromConfig, getRuntimeJsValue, buildOptions, buildShouldFetch } from './../utils'; // 将不同渠道给的 schema 转为 runtime 需要的类型 import { defaultDataHandler, defaultWillFetch } from '../helpers'; @@ -16,18 +10,11 @@ import { RuntimeDataSourceConfig, } from '@ali/lowcode-types'; -const adapt2Runtime = ( - dataSource: InterpretDataSource, - context: IDataSourceRuntimeContext, -) => { - const { - list: interpretConfigList, - dataHandler: interpretDataHandler, - } = dataSource; - const dataHandler: (dataMap?: DataSourceMap) => void = - interpretDataHandler && - interpretDataHandler.compiled && - transformFunction(interpretDataHandler.compiled, context); +const adapt2Runtime = (dataSource: InterpretDataSource, context: IDataSourceRuntimeContext) => { + const { list: interpretConfigList, dataHandler: interpretDataHandler } = dataSource; + const dataHandler: (dataMap?: DataSourceMap) => void = interpretDataHandler + ? getRuntimeJsValue(interpretDataHandler, context) + : undefined; // 为空判断 if (!interpretConfigList || !interpretConfigList.length) { @@ -36,29 +23,20 @@ const adapt2Runtime = ( dataHandler, }; } - const list: RuntimeDataSourceConfig[] = interpretConfigList.map( - (el: InterpretDataSourceConfig) => { - return { - id: el.id, - isInit: - getRuntimeValueFromConfig('boolean', el.isInit, context) || true, // 默认 true - isSync: - getRuntimeValueFromConfig('boolean', el.isSync, context) || false, // 默认 false - type: el.type || 'fetch', - willFetch: el.willFetch - ? getRuntimeJsValue(el.willFetch, context) - : defaultWillFetch, - shouldFetch: buildShouldFetch(el, context), - dataHandler: el.dataHandler - ? getRuntimeJsValue(el.dataHandler, context) - : defaultDataHandler, - errorHandler: el.errorHandler - ? getRuntimeJsValue(el.errorHandler, context) - : undefined, - options: buildOptions(el, context), - }; - }, - ); + const list: RuntimeDataSourceConfig[] = interpretConfigList.map((el: InterpretDataSourceConfig) => { + return { + id: el.id, + isInit: getRuntimeValueFromConfig('boolean', el.isInit, context) || true, // 默认 true + isSync: getRuntimeValueFromConfig('boolean', el.isSync, context) || false, // 默认 false + type: el.type || 'fetch', + willFetch: el.willFetch ? getRuntimeJsValue(el.willFetch, context) : defaultWillFetch, + shouldFetch: buildShouldFetch(el, context), + dataHandler: el.dataHandler ? getRuntimeJsValue(el.dataHandler, context) : defaultDataHandler, + errorHandler: el.errorHandler ? getRuntimeJsValue(el.errorHandler, context) : undefined, + requestHandler: el.requestHandler ? getRuntimeJsValue(el.requestHandler, context) : undefined, + options: buildOptions(el, context), + }; + }); return { list, diff --git a/packages/datasource-engine/src/core/reloadDataSourceFactory.ts b/packages/datasource-engine/src/core/reloadDataSourceFactory.ts index b871c2f37..87a111ca0 100644 --- a/packages/datasource-engine/src/core/reloadDataSourceFactory.ts +++ b/packages/datasource-engine/src/core/reloadDataSourceFactory.ts @@ -1,12 +1,9 @@ -import { - DataSourceMap, - RuntimeDataSource, - RuntimeDataSourceConfig, -} from '@ali/lowcode-types'; +import { DataSourceMap, RuntimeDataSource, RuntimeDataSourceConfig } from '@ali/lowcode-types'; export const reloadDataSourceFactory = ( dataSource: RuntimeDataSource, dataSourceMap: DataSourceMap, + dataHandler?: (dataSourceMap: DataSourceMap) => void, ) => async () => { const allAsyncLoadings: Array> = []; @@ -16,16 +13,13 @@ export const reloadDataSourceFactory = ( .filter( (el: RuntimeDataSourceConfig) => // eslint-disable-next-line implicit-arrow-linebreak - el.type === 'urlParams' && - (typeof el.isInit === 'boolean' ? el.isInit : true), + el.type === 'urlParams' && (typeof el.isInit === 'boolean' ? el.isInit : true), ) .forEach((el: RuntimeDataSourceConfig) => { dataSourceMap[el.id].load(); }); - const remainRuntimeDataSourceList = dataSource.list.filter( - (el: RuntimeDataSourceConfig) => el.type !== 'urlParams', - ); + const remainRuntimeDataSourceList = dataSource.list.filter((el: RuntimeDataSourceConfig) => el.type !== 'urlParams'); // 处理并行 for (const ds of remainRuntimeDataSourceList) { @@ -63,4 +57,10 @@ export const reloadDataSourceFactory = ( } await Promise.allSettled(allAsyncLoadings); + + // 所有的初始化请求都结束之后,调用钩子函数 + + if (dataHandler) { + dataHandler(dataSourceMap); + } }; diff --git a/packages/datasource-engine/src/helpers/index.ts b/packages/datasource-engine/src/helpers/index.ts index 1b2726566..6202e61b2 100644 --- a/packages/datasource-engine/src/helpers/index.ts +++ b/packages/datasource-engine/src/helpers/index.ts @@ -1,17 +1,33 @@ import { DataHandler, + RequestHandler, + RequestHandlersMap, + RuntimeDataSourceConfig, RuntimeOptionsConfig, + UrlParamsHandler, WillFetch, } from '@ali/lowcode-types'; // 默认的 dataSourceItem 的 dataHandler -export const defaultDataHandler: DataHandler = async (response: { - data: T; -}) => response.data; +export const defaultDataHandler: DataHandler = async (response: { data: T }) => response.data; // 默认的 dataSourceItem 的 willFetch -export const defaultWillFetch: WillFetch = (options: RuntimeOptionsConfig) => - options; +export const defaultWillFetch: WillFetch = (options: RuntimeOptionsConfig) => options; // 默认的 dataSourceItem 的 shouldFetch export const defaultShouldFetch = () => true; + +type GetRequestHandler = ( + ds: RuntimeDataSourceConfig, + requestHandlersMap: RequestHandlersMap<{ data: T }>, +) => RequestHandler<{ data: T }> | UrlParamsHandler; + +// 从当前 dataSourceItem 中获取 requestHandler +export const getRequestHandler: GetRequestHandler = (ds, requestHandlersMap) => { + if (ds.type === 'custom') { + // 自定义类型处理 + return (ds.requestHandler as unknown) as RequestHandler<{ data: unknown }>; // 理论上这里应该是能强转的,就算为空,应该在 request 请求的时候触发失败 + } + // type 协议默认值 fetch + return requestHandlersMap[ds.type || 'fetch']; +}; diff --git a/packages/datasource-engine/src/interpret/DataSourceEngineFactory.ts b/packages/datasource-engine/src/interpret/DataSourceEngineFactory.ts index 4adcf1f82..15d4dc5d8 100644 --- a/packages/datasource-engine/src/interpret/DataSourceEngineFactory.ts +++ b/packages/datasource-engine/src/interpret/DataSourceEngineFactory.ts @@ -9,11 +9,12 @@ import { RuntimeDataSource, RuntimeDataSourceConfig, } from '@ali/lowcode-types'; +import { getRequestHandler } from '../helpers'; -// TODO: requestConfig mtop 默认的请求 config 怎么处理? /** * @param dataSource * @param context + * @param extraConfig: { requestHandlersMap } */ export default ( @@ -25,22 +26,11 @@ export default ( ) => { const { requestHandlersMap } = extraConfig; - const runtimeDataSource: RuntimeDataSource = adapt2Runtime( - dataSource, - context, - ); + const runtimeDataSource: RuntimeDataSource = adapt2Runtime(dataSource, context); const dataSourceMap = runtimeDataSource.list.reduce( - ( - prev: Record, - current: RuntimeDataSourceConfig, - ) => { - prev[current.id] = new RuntimeDataSourceItem( - current, - // type 协议默认值 fetch - requestHandlersMap[current.type || 'fetch'], - context, - ); + (prev: Record, current: RuntimeDataSourceConfig) => { + prev[current.id] = new RuntimeDataSourceItem(current, getRequestHandler(current, requestHandlersMap), context); return prev; }, {}, @@ -48,6 +38,6 @@ export default ( return { dataSourceMap, - reloadDataSource: reloadDataSourceFactory(runtimeDataSource, dataSourceMap), + reloadDataSource: reloadDataSourceFactory(runtimeDataSource, dataSourceMap, runtimeDataSource.dataHandler), }; }; diff --git a/packages/datasource-engine/src/runtime/RuntimeDataSourceEngineFactory.ts b/packages/datasource-engine/src/runtime/RuntimeDataSourceEngineFactory.ts index d504054c3..e1cdead62 100644 --- a/packages/datasource-engine/src/runtime/RuntimeDataSourceEngineFactory.ts +++ b/packages/datasource-engine/src/runtime/RuntimeDataSourceEngineFactory.ts @@ -1,5 +1,4 @@ /* eslint-disable @typescript-eslint/indent */ -/* eslint-disable no-nested-ternary */ import { IRuntimeDataSource, IDataSourceRuntimeContext, @@ -10,17 +9,14 @@ import { import { RuntimeDataSourceItem } from '../core'; import { reloadDataSourceFactory } from '../core/reloadDataSourceFactory'; -import { - defaultDataHandler, - defaultShouldFetch, - defaultWillFetch, -} from '../helpers'; +import { defaultDataHandler, defaultShouldFetch, defaultWillFetch, getRequestHandler } from '../helpers'; -// TODO: requestConfig mtop 默认的请求 config 怎么处理? /** * @param dataSource * @param context + * @param extraConfig: { requestHandlersMap } */ + export default ( dataSource: RuntimeDataSource, context: IDataSourceRuntimeContext, @@ -34,28 +30,19 @@ export default ( dataSource.list.forEach(ds => { ds.isInit = ds.isInit || true; ds.isSync = ds.isSync || false; + // eslint-disable-next-line no-nested-ternary ds.shouldFetch = !ds.shouldFetch ? defaultShouldFetch : typeof ds.shouldFetch === 'function' ? ds.shouldFetch.bind(context) : ds.shouldFetch; ds.willFetch = ds.willFetch ? ds.willFetch.bind(context) : defaultWillFetch; - ds.dataHandler = ds.dataHandler - ? ds.dataHandler.bind(context) - : defaultDataHandler; + ds.dataHandler = ds.dataHandler ? ds.dataHandler.bind(context) : defaultDataHandler; }); const dataSourceMap = dataSource.list.reduce( - ( - prev: Record, - current: RuntimeDataSourceConfig, - ) => { - prev[current.id] = new RuntimeDataSourceItem( - current, - // type 协议默认值 fetch - requestHandlersMap[current.type || 'fetch'], - context, - ); + (prev: Record, current: RuntimeDataSourceConfig) => { + prev[current.id] = new RuntimeDataSourceItem(current, getRequestHandler(current, requestHandlersMap), context); return prev; }, {}, @@ -63,6 +50,6 @@ export default ( return { dataSourceMap, - reloadDataSource: reloadDataSourceFactory(dataSource, dataSourceMap), + reloadDataSource: reloadDataSourceFactory(dataSource, dataSourceMap, dataSource.dataHandler), }; }; diff --git a/packages/datasource-engine/test/scenes/p0-0-custom-request-handlers/README.md b/packages/datasource-engine/test/scenes/p0-0-custom-request-handlers/README.md new file mode 100644 index 000000000..355853ddd --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-0-custom-request-handlers/README.md @@ -0,0 +1,3 @@ +# 关于此场景 + +数据源的 type 可以是 `custom` 类型的, 此时需要提供 `requestHandler` 给数据源 diff --git a/packages/datasource-engine/test/scenes/p0-0-custom-request-handlers/_datasource-runtime.ts b/packages/datasource-engine/test/scenes/p0-0-custom-request-handlers/_datasource-runtime.ts new file mode 100644 index 000000000..fc46c3459 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-0-custom-request-handlers/_datasource-runtime.ts @@ -0,0 +1,67 @@ +import { RuntimeDataSource } from '@ali/lowcode-types'; + +// 这里仅仅是数据源部分的: +// @see: https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 +export const dataSource: RuntimeDataSource = { + list: [ + { + id: 'user', + isInit: true, + type: 'custom', + isSync: true, + requestHandler: options => { + return new Promise(res => { + setTimeout(() => { + // test return data + res({ + data: { + id: 9527, + name: 'Alice', + uri: options.uri, + }, + }); + }, 1000); + }); + }, + options() { + return { + uri: 'https://mocks.alibaba-inc.com/user.json', + }; + }, + }, + { + id: 'orders', + isInit: true, + type: 'custom', + isSync: true, + requestHandler: () => { + return new Promise((res, rej) => { + setTimeout(() => { + // test return data + rej(new Error('test error')); + }, 1000); + }); + }, + options() { + return { + uri: 'https://mocks.alibaba-inc.com/orders.json', + params: { + userId: this.state.user.id, + }, + }; + }, + }, + { + // 这个 api 是假的,调不通的,当前场景是故意需要报错的 + id: 'members', + isInit: true, + type: 'custom', + isSync: true, + options() { + return { + uri: 'https://mocks.alibaba-inc.com/members.json', + }; + }, + }, + ], +}; diff --git a/packages/datasource-engine/test/scenes/p0-0-custom-request-handlers/_datasource-schema.ts b/packages/datasource-engine/test/scenes/p0-0-custom-request-handlers/_datasource-schema.ts new file mode 100644 index 000000000..0a71914ca --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-0-custom-request-handlers/_datasource-schema.ts @@ -0,0 +1,67 @@ +import { InterpretDataSource } from '@ali/lowcode-types'; + +// 这里仅仅是数据源部分的 schema: +// @see: https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 +export const DATA_SOURCE_SCHEMA: InterpretDataSource = { + list: [ + { + id: 'user', + isInit: true, + type: 'custom', + isSync: true, + requestHandler: { + type: 'JSFunction', + value: `function(options){ + return new Promise(res => { + setTimeout(() => { + // test return data + res({ + data: { + id: 9527, + name: 'Alice', + uri: options.uri, + } + }); + }, 1000); + }); + }`, + }, + options: { + uri: 'https://mocks.alibaba-inc.com/user.json', + }, + }, + { + id: 'orders', + isInit: true, + type: 'custom', + isSync: true, + requestHandler: { + type: 'JSFunction', + value: `function(options){ + return new Promise((res, rej) => { + setTimeout(() => { + // test return data + return rej(new Error('test error')); + }, 1000); + }); + }`, + }, + options: { + uri: 'https://mocks.alibaba-inc.com/orders.json', + params: { + type: 'JSExpression', + value: '{ userId: this.state.user.id }', + }, + }, + }, + { + id: 'members', + isInit: true, + type: 'custom', + isSync: true, + options: { + uri: 'https://mocks.alibaba-inc.com/members.json', + }, + }, + ], +}; diff --git a/packages/datasource-engine/test/scenes/p0-0-custom-request-handlers/_macro-normal.ts b/packages/datasource-engine/test/scenes/p0-0-custom-request-handlers/_macro-normal.ts new file mode 100644 index 000000000..1fe39c61e --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-0-custom-request-handlers/_macro-normal.ts @@ -0,0 +1,90 @@ +import { + InterpretDataSource, + IDataSourceEngine, + IDataSourceRuntimeContext, + RuntimeDataSource, + RuntimeDataSourceStatus, +} from '@ali/lowcode-types'; +import sinon from 'sinon'; + +import { bindRuntimeContext, MockContext } from '../../_helpers'; + +import type { ExecutionContext, Macro } from 'ava'; +import type { SinonFakeTimers } from 'sinon'; + +export const normalScene: Macro<[ + { + create: ( + dataSource: any, + ctx: IDataSourceRuntimeContext, + options?: any + ) => IDataSourceEngine; + dataSource: RuntimeDataSource | InterpretDataSource; + } +]> = async ( + t: ExecutionContext<{ clock: SinonFakeTimers }>, + { create, dataSource }, +) => { + const { clock } = t.context; + + const USER_DATA = { + id: 9527, + name: 'Alice', + uri: 'https://mocks.alibaba-inc.com/user.json' + }; + const ERROR_MSG = 'test error'; + + + const context = new MockContext>({}, (ctx) => create(bindRuntimeContext(dataSource, ctx), ctx)); + + const setState = sinon.spy(context, 'setState'); + + // 一开始应该是初始状态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Initial); + t.is(context.dataSourceMap.orders.status, RuntimeDataSourceStatus.Initial); + t.is(context.dataSourceMap.members.status, RuntimeDataSourceStatus.Initial); + + const loading = context.reloadDataSource(); + + await clock.tickAsync(50); + + // 中间应该有 loading 态 + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loading); + + await clock.tickAsync(1050); + + // 中间应该有 loading 态 + t.is(context.dataSourceMap.orders.status, RuntimeDataSourceStatus.Loading); + + await clock.tickAsync(1050); + + // members 因为没有 requestHandler 直接就挂了 + t.is(context.dataSourceMap.members.status, RuntimeDataSourceStatus.Error) + + await Promise.all([clock.runAllAsync(), loading]); + + // 最后 user 应该成功了,loaded + t.is(context.dataSourceMap.user.status, RuntimeDataSourceStatus.Loaded); + // 最后 orders 应该失败了,error 状态 + t.is(context.dataSourceMap.orders.status, RuntimeDataSourceStatus.Error); + + // 检查数据源的数据 + t.deepEqual(context.dataSourceMap.user.data, USER_DATA); + t.is(context.dataSourceMap.user.error, undefined); + t.deepEqual(context.dataSourceMap.orders.data, undefined); + t.not(context.dataSourceMap.orders.error, undefined); + t.deepEqual(context.dataSourceMap.members.data, undefined); + t.not(context.dataSourceMap.members.error, undefined); + t.regex(context.dataSourceMap.orders.error!.message, new RegExp(ERROR_MSG)); + t.regex(context.dataSourceMap.members.error!.message, new RegExp('no custom handler provide')); + + + + // 检查状态数据 + t.assert(setState.calledOnce); + t.deepEqual(context.state.user, USER_DATA); + t.is(context.state.orders, undefined); + t.is(context.state.members, undefined); +}; + +normalScene.title = (providedTitle) => providedTitle || 'normal scene'; diff --git a/packages/datasource-engine/test/scenes/p0-0-custom-request-handlers/normal-interpret.test.ts b/packages/datasource-engine/test/scenes/p0-0-custom-request-handlers/normal-interpret.test.ts new file mode 100644 index 000000000..9dac84e8d --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-0-custom-request-handlers/normal-interpret.test.ts @@ -0,0 +1,20 @@ +import test, { ExecutionContext } from 'ava'; +import sinon, { SinonFakeTimers } from 'sinon'; + +import { create } from '../../../src/interpret'; + +import { DATA_SOURCE_SCHEMA } from './_datasource-schema'; +import { normalScene } from './_macro-normal'; + +test.before((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock = sinon.useFakeTimers(); +}); + +test.after((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock.restore(); +}); + +test(normalScene, { + create, + dataSource: DATA_SOURCE_SCHEMA, +}); diff --git a/packages/datasource-engine/test/scenes/p0-0-custom-request-handlers/normal-runtime.test.ts b/packages/datasource-engine/test/scenes/p0-0-custom-request-handlers/normal-runtime.test.ts new file mode 100644 index 000000000..761979c30 --- /dev/null +++ b/packages/datasource-engine/test/scenes/p0-0-custom-request-handlers/normal-runtime.test.ts @@ -0,0 +1,20 @@ +import test, { ExecutionContext } from 'ava'; +import sinon, { SinonFakeTimers } from 'sinon'; + +import { create } from '../../../src/runtime'; + +import { dataSource } from './_datasource-runtime'; +import { normalScene } from './_macro-normal'; + +test.before((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock = sinon.useFakeTimers(); +}); + +test.after((t: ExecutionContext<{ clock: SinonFakeTimers }>) => { + t.context.clock.restore(); +}); + +test(normalScene, { + create, + dataSource, +}); diff --git a/packages/types/src/data-source-handlers.ts b/packages/types/src/data-source-handlers.ts index 2e054b4e8..4ee7f6a0b 100644 --- a/packages/types/src/data-source-handlers.ts +++ b/packages/types/src/data-source-handlers.ts @@ -5,11 +5,17 @@ import { export type RequestHandler = ( options: RuntimeOptionsConfig, - context: IDataSourceRuntimeContext + context?: IDataSourceRuntimeContext, ) => Promise; export type UrlParamsHandler = ( - context?: IDataSourceRuntimeContext + context?: IDataSourceRuntimeContext, ) => Promise; export type RequestHandlersMap = Record>; + +// 仅在 type=custom 的时候生效的 handler +export type CustomRequestHandler = ( + options: RuntimeOptionsConfig, + context?: IDataSourceRuntimeContext, +) => Promise; diff --git a/packages/types/src/data-source-runtime.ts b/packages/types/src/data-source-runtime.ts index 9a89e39aa..878039340 100644 --- a/packages/types/src/data-source-runtime.ts +++ b/packages/types/src/data-source-runtime.ts @@ -1,10 +1,10 @@ import { IRuntimeDataSource } from './data-source'; +import { CustomRequestHandler } from './data-source-handlers'; // 先定义运行模式的类型 export interface RuntimeDataSource { list: RuntimeDataSourceConfig[]; - // TODO: dataMap 格式不对要处理 - dataHandler?: (dataMap: DataSourceMap) => void; + dataHandler?: (dataSourceMap: DataSourceMap) => void; } export type DataSourceMap = Record; @@ -16,7 +16,7 @@ export interface RuntimeDataSourceConfig { type?: string; willFetch?: WillFetch; shouldFetch?: () => boolean; - requestHandler?: () => void; // TODO: 待定 + requestHandler?: CustomRequestHandler; dataHandler?: DataHandler; errorHandler?: ErrorHandler; options?: RuntimeOptions; From dcdcf287af97db63c217c6c430a771eae6ccf43d Mon Sep 17 00:00:00 2001 From: "guokai.jgk" Date: Sat, 31 Oct 2020 21:04:06 +0800 Subject: [PATCH 17/18] feat: add jsonp datahandler --- .../datasource-engine/src/handlers/fetch.ts | 24 ------- .../datasource-engine/src/handlers/mtop.ts | 18 ----- .../src/handlers/url-params.ts | 12 ---- .../datasource-jsonp-handler/.eslintignore | 3 + .../datasource-jsonp-handler/.eslintrc.js | 7 ++ .../datasource-jsonp-handler/.prettierrc.js | 4 ++ .../datasource-jsonp-handler/package.json | 29 +++++++++ .../datasource-jsonp-handler/src/index.ts | 31 +++++++++ .../datasource-jsonp-handler/tsconfig.json | 65 +++++++++++++++++++ 9 files changed, 139 insertions(+), 54 deletions(-) delete mode 100644 packages/datasource-engine/src/handlers/fetch.ts delete mode 100644 packages/datasource-engine/src/handlers/mtop.ts delete mode 100644 packages/datasource-engine/src/handlers/url-params.ts create mode 100644 packages/datasource-jsonp-handler/.eslintignore create mode 100644 packages/datasource-jsonp-handler/.eslintrc.js create mode 100644 packages/datasource-jsonp-handler/.prettierrc.js create mode 100644 packages/datasource-jsonp-handler/package.json create mode 100644 packages/datasource-jsonp-handler/src/index.ts create mode 100644 packages/datasource-jsonp-handler/tsconfig.json diff --git a/packages/datasource-engine/src/handlers/fetch.ts b/packages/datasource-engine/src/handlers/fetch.ts deleted file mode 100644 index d0f6d344b..000000000 --- a/packages/datasource-engine/src/handlers/fetch.ts +++ /dev/null @@ -1,24 +0,0 @@ -import request from 'universal-request'; -import type { AsObject, RequestOptions } from 'universal-request/lib/types'; - -import { DataSourceOptions, RequestHandler } from '../types'; - -const fetchHandler: RequestHandler = async ({ - url, - uri, - data, - params, - ...otherOptions -}: DataSourceOptions) => { - const reqOptions = { - url: ((url || uri) as unknown) as string, - data: ((data || params) as unknown) as AsObject, - ...otherOptions, - }; - - const res = await request(reqOptions as RequestOptions); - - return res; -}; - -export default fetchHandler; diff --git a/packages/datasource-engine/src/handlers/mtop.ts b/packages/datasource-engine/src/handlers/mtop.ts deleted file mode 100644 index 4894b9ad9..000000000 --- a/packages/datasource-engine/src/handlers/mtop.ts +++ /dev/null @@ -1,18 +0,0 @@ -import mtop from '@ali/universal-mtop'; -import { RequestHandler } from '../types'; - -const mtopHandler: RequestHandler = async (options) => { - const { api, uri, data, params, type, method, ...otherOptions } = options; - const reqOptions = { - ...otherOptions, - api: api || uri, - data: data || params, - type: type || method, - }; - - const res = await mtop(reqOptions); - - return res; -}; - -export default mtopHandler; diff --git a/packages/datasource-engine/src/handlers/url-params.ts b/packages/datasource-engine/src/handlers/url-params.ts deleted file mode 100644 index 67540c9f2..000000000 --- a/packages/datasource-engine/src/handlers/url-params.ts +++ /dev/null @@ -1,12 +0,0 @@ -import qs from 'query-string'; -import { RequestHandler } from '../types'; - -export default function urlParamsHandler(search: string | Record): RequestHandler { - const urlParams = typeof search === 'string' ? qs.parse(search) : search; - - return async () => { - return { - data: urlParams, - }; - }; -} diff --git a/packages/datasource-jsonp-handler/.eslintignore b/packages/datasource-jsonp-handler/.eslintignore new file mode 100644 index 000000000..fecb7c26d --- /dev/null +++ b/packages/datasource-jsonp-handler/.eslintignore @@ -0,0 +1,3 @@ +/node_modules +/es +/lib \ No newline at end of file diff --git a/packages/datasource-jsonp-handler/.eslintrc.js b/packages/datasource-jsonp-handler/.eslintrc.js new file mode 100644 index 000000000..8c13fcaf4 --- /dev/null +++ b/packages/datasource-jsonp-handler/.eslintrc.js @@ -0,0 +1,7 @@ +module.exports = { + extends: '../../.eslintrc', + rules: { + '@typescript-eslint/no-parameter-properties': 1, + 'no-param-reassign': 0, + }, +}; diff --git a/packages/datasource-jsonp-handler/.prettierrc.js b/packages/datasource-jsonp-handler/.prettierrc.js new file mode 100644 index 000000000..de2f53cdf --- /dev/null +++ b/packages/datasource-jsonp-handler/.prettierrc.js @@ -0,0 +1,4 @@ +module.exports = { + singleQuote: true, + trailingComma: 'all', +}; diff --git a/packages/datasource-jsonp-handler/package.json b/packages/datasource-jsonp-handler/package.json new file mode 100644 index 000000000..e2f1d5c1f --- /dev/null +++ b/packages/datasource-jsonp-handler/package.json @@ -0,0 +1,29 @@ +{ + "name": "@ali/datasource-jsonp-handler", + "version": "1.0.0-alpha.1", + "main": "lib/index.js", + "module": "es/index.js", + "typings": "es/index.d.ts", + "files": [ + "src", + "lib", + "es" + ], + "scripts": { + "dev": "tsc --watch", + "clean": "rm -rf es lib", + "build": "npm run clean && tsc && tsc --outDir ./lib --module commonjs ", + "prepublishOnly": "npm run build" + }, + "dependencies": { + "@ali/lowcode-types": "1.0.13-alpha.1", + "jsonp": "^0.2.1", + "typescript": "^3.9.7" + }, + "publishConfig": { + "registry": "https://registry.npm.alibaba-inc.com" + }, + "devDependencies": { + "@types/jsonp": "^0.2.0" + } +} diff --git a/packages/datasource-jsonp-handler/src/index.ts b/packages/datasource-jsonp-handler/src/index.ts new file mode 100644 index 000000000..ca2d58bf8 --- /dev/null +++ b/packages/datasource-jsonp-handler/src/index.ts @@ -0,0 +1,31 @@ +import { RuntimeOptionsConfig } from '@ali/lowcode-types'; +import jsonp from 'jsonp'; + +const handleJsonpFetch = (url: string, param: string, name: string) => { + return new Promise((res, rej) => { + jsonp(url, { param, name }, (error: Error | null, data: any) => { + if (error) { + return rej(error); + } + res({ data }); + }); + }); +}; + +// config 留着扩展 +// eslint-disable-next-line @typescript-eslint/no-unused-vars +export function createJsonpHandler(config?: Record) { + // eslint-disable-next-line space-before-function-paren + return async function(options: RuntimeOptionsConfig) { + const params = + typeof options.params === 'object' + ? JSON.stringify(options.params) + : options.params; + const response = await handleJsonpFetch( + options.uri, + params || '', + options.name as string | '', + ); + return response; + }; +} diff --git a/packages/datasource-jsonp-handler/tsconfig.json b/packages/datasource-jsonp-handler/tsconfig.json new file mode 100644 index 000000000..eeea7a79b --- /dev/null +++ b/packages/datasource-jsonp-handler/tsconfig.json @@ -0,0 +1,65 @@ +{ + "compilerOptions": { + "outDir": "es", + "target": "es6", + "module": "esnext", + /* Basic Options */ + // "incremental": true, /* Enable incremental compilation */ + // "target": "es6" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */, + // "module": "esnext" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */, + "lib": ["ESNext", "DOM"] /* Specify library files to be included in the compilation. */, + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "checkJs": true, /* Report errors in .js files. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + "declaration": true /* Generates corresponding '.d.ts' file. */, + // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + // "outDir": "es" /* Redirect output structure to the directory. */, + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "composite": true, /* Enable project compilation */ + // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ + // "removeComments": true, /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + /* Strict Type-Checking Options */ + "strict": true /* Enable all strict type-checking options. */, + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "strictFunctionTypes": true, /* Enable strict checking of function types. */ + // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ + // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + /* Additional Checks */ + // "noUnusedLocals": true, /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + /* Module Resolution Options */ + "moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */, + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */, + // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + /* Source Map Options */ + // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + /* Advanced Options */ + "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */, + "skipLibCheck": true + }, + "include": ["src/**/*"] +} From cf3a61a8e8d662718b4c82914c056eed0bbb9f6a Mon Sep 17 00:00:00 2001 From: "guokai.jgk" Date: Tue, 3 Nov 2020 23:05:55 +0800 Subject: [PATCH 18/18] fix: jsonp handler rename --- packages/datasource-engine/handlers/fetch/index.d.ts | 1 - packages/datasource-engine/handlers/fetch/index.js | 1 - packages/datasource-engine/handlers/mtop/index.d.ts | 1 - packages/datasource-engine/handlers/mtop/index.js | 1 - .../datasource-engine/handlers/url-params/index.d.ts | 1 - .../datasource-engine/handlers/url-params/index.js | 1 - packages/datasource-engine/readme.md | 10 ++++++++-- packages/datasource-jsonp-handler/package.json | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) delete mode 100644 packages/datasource-engine/handlers/fetch/index.d.ts delete mode 100644 packages/datasource-engine/handlers/fetch/index.js delete mode 100644 packages/datasource-engine/handlers/mtop/index.d.ts delete mode 100644 packages/datasource-engine/handlers/mtop/index.js delete mode 100644 packages/datasource-engine/handlers/url-params/index.d.ts delete mode 100644 packages/datasource-engine/handlers/url-params/index.js diff --git a/packages/datasource-engine/handlers/fetch/index.d.ts b/packages/datasource-engine/handlers/fetch/index.d.ts deleted file mode 100644 index 86829236a..000000000 --- a/packages/datasource-engine/handlers/fetch/index.d.ts +++ /dev/null @@ -1 +0,0 @@ -export type * from '../../es/handlers/fetch'; diff --git a/packages/datasource-engine/handlers/fetch/index.js b/packages/datasource-engine/handlers/fetch/index.js deleted file mode 100644 index 5abed6279..000000000 --- a/packages/datasource-engine/handlers/fetch/index.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('../../lib/handlers/fetch').default; diff --git a/packages/datasource-engine/handlers/mtop/index.d.ts b/packages/datasource-engine/handlers/mtop/index.d.ts deleted file mode 100644 index 1d11c303b..000000000 --- a/packages/datasource-engine/handlers/mtop/index.d.ts +++ /dev/null @@ -1 +0,0 @@ -export type * from '../../es/handlers/mtop'; diff --git a/packages/datasource-engine/handlers/mtop/index.js b/packages/datasource-engine/handlers/mtop/index.js deleted file mode 100644 index 89f131c78..000000000 --- a/packages/datasource-engine/handlers/mtop/index.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('../../lib/handlers/mtop').default; diff --git a/packages/datasource-engine/handlers/url-params/index.d.ts b/packages/datasource-engine/handlers/url-params/index.d.ts deleted file mode 100644 index 58e059ec8..000000000 --- a/packages/datasource-engine/handlers/url-params/index.d.ts +++ /dev/null @@ -1 +0,0 @@ -export type * from '../../es/handlers/url-params'; diff --git a/packages/datasource-engine/handlers/url-params/index.js b/packages/datasource-engine/handlers/url-params/index.js deleted file mode 100644 index f9b01c61e..000000000 --- a/packages/datasource-engine/handlers/url-params/index.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('../../lib/handlers/url-params').default; diff --git a/packages/datasource-engine/readme.md b/packages/datasource-engine/readme.md index d5bcb84d6..d5be75f84 100644 --- a/packages/datasource-engine/readme.md +++ b/packages/datasource-engine/readme.md @@ -19,13 +19,19 @@ import { create } from '@ali/lowcode-datasource-engine/interpret'; // 面向出码,需要给处理过后的内容 import { create } from '@ali/lowcode-datasource-engine/runtime'; +import { createFetchHandler } from '@ali/lowcode-datasource-fetch-handler'; + +import { createMtopHandler } from '@ali/lowcode-datasource-mtop-handler'; + // dataSource 可以是 schema 协议内容 或者是运行时的转化后的配置内容 (出码专用) + // context 上下文(setState 为必选) -const dsf = create(dataSource, context, { +const dataSourceEngine = create(dataSource, context, { requestHandlersMap: { // 可选参数,以下内容为当前默认的内容 urlParams: handlersMap.urlParams('?bar=1&test=2'), - mtop: mtophandlers, + fetch: createFetchHandler, + mtop: createMtopHandler }, }); diff --git a/packages/datasource-jsonp-handler/package.json b/packages/datasource-jsonp-handler/package.json index e2f1d5c1f..58698ebae 100644 --- a/packages/datasource-jsonp-handler/package.json +++ b/packages/datasource-jsonp-handler/package.json @@ -1,5 +1,5 @@ { - "name": "@ali/datasource-jsonp-handler", + "name": "@ali/lowcode-datasource-jsonp-handler", "version": "1.0.0-alpha.1", "main": "lib/index.js", "module": "es/index.js",