@quanxiaoxiao/datav 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.babelrc ADDED
@@ -0,0 +1,7 @@
1
+ {
2
+ "plugins": [
3
+ "@babel/plugin-proposal-optional-chaining",
4
+ "@babel/plugin-proposal-nullish-coalescing-operator",
5
+ "@babel/plugin-syntax-import-attributes"
6
+ ]
7
+ }
package/.editorconfig ADDED
@@ -0,0 +1,13 @@
1
+ root = true
2
+
3
+ [*]
4
+ end_of_line = lf
5
+ charset = utf-8
6
+ trim_trailing_whitespace = true
7
+ insert_final_newline = true
8
+ indent_style = space
9
+ indent_size = 2
10
+ max_line_length = 100
11
+
12
+ [*.md]
13
+ trim_trailing_whitespace = false
package/.eslintrc ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "parser": "@babel/eslint-parser",
3
+ "extends": "eslint-config-airbnb",
4
+ "env": {
5
+ "node": true
6
+ },
7
+ "rules": {
8
+ "no-console": 0,
9
+ "max-len": 0,
10
+ "no-continue": 0,
11
+ "no-bitwise": 0,
12
+ "import/no-extraneous-dependencies": [
13
+ "error",
14
+ {
15
+ "devDependencies": true,
16
+ "optionalDependencies": false,
17
+ "peerDependencies": false
18
+ }
19
+ ],
20
+ "no-param-reassign": 0,
21
+ "no-mixed-operators": 0,
22
+ "no-underscore-dangle": 0,
23
+ "import/prefer-default-export": 0,
24
+ "class-methods-use-this": 0,
25
+ "no-plusplus": 0,
26
+ "global-require": 0
27
+ },
28
+ "globals": {}
29
+ }
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@quanxiaoxiao/datav",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "scripts": {
6
+ "test": "node --test"
7
+ },
8
+ "main": "./src/index.mjs",
9
+ "exports": {
10
+ ".": "./src/index.mjs",
11
+ "./package.json": "./package.json"
12
+ },
13
+ "devDependencies": {
14
+ "@babel/eslint-parser": "^7.23.10",
15
+ "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6",
16
+ "@babel/plugin-proposal-optional-chaining": "^7.21.0",
17
+ "@babel/plugin-syntax-import-attributes": "^7.23.3",
18
+ "eslint": "^8.56.0",
19
+ "eslint-config-airbnb": "^19.0.4",
20
+ "eslint-plugin-import": "^2.29.1",
21
+ "eslint-plugin-jsx-a11y": "^6.8.0",
22
+ "eslint-plugin-react": "^7.33.2",
23
+ "eslint-plugin-react-hooks": "^4.6.0"
24
+ },
25
+ "publishConfig": {
26
+ "registry": "https://registry.npmjs.org"
27
+ },
28
+ "engines": {
29
+ "node": ">= 20.0.0"
30
+ },
31
+ "dependencies": {
32
+ "ajv": "^8.12.0",
33
+ "lodash": "^4.17.21"
34
+ }
35
+ }
@@ -0,0 +1,134 @@
1
+ import _ from 'lodash';
2
+
3
+ const DATA_TYPE_NUMBER = 'number';
4
+ const DATA_TYPE_STRING = 'string';
5
+ const DATA_TYPE_BOOLEAN = 'boolean';
6
+ const DATA_TYPE_JSON = 'json';
7
+ const DATA_TYPE_ARRAY = 'array';
8
+ const DATA_TYPE_OBJECT = 'object';
9
+ const DATA_TYPE_INTEGER = 'integer';
10
+
11
+ const map = {
12
+ [DATA_TYPE_STRING]: (v) => {
13
+ if (typeof v !== 'string') {
14
+ return v.toString ? `${v.toString()}` : JSON.stringify(v);
15
+ }
16
+ return v;
17
+ },
18
+ [DATA_TYPE_INTEGER]: (v) => {
19
+ if (Number.isNaN(v)) {
20
+ return v;
21
+ }
22
+ if (v === '') {
23
+ return null;
24
+ }
25
+ const type = typeof v;
26
+ if (type !== 'number' && type !== 'string') {
27
+ return null;
28
+ }
29
+ const number = Number(v);
30
+ if (Number.isNaN(number)) {
31
+ return null;
32
+ }
33
+ if (`${number}` !== `${v}`) {
34
+ return null;
35
+ }
36
+ return parseInt(number, 10);
37
+ },
38
+ [DATA_TYPE_NUMBER]: (v) => {
39
+ if (v === '') {
40
+ return null;
41
+ }
42
+ const number = Number(v);
43
+ if (Number.isNaN(number)) {
44
+ return null;
45
+ }
46
+ if (`${number}` !== `${v}`) {
47
+ return null;
48
+ }
49
+ return number;
50
+ },
51
+ [DATA_TYPE_BOOLEAN]: (v) => {
52
+ if (v !== 'false' && v !== 'true') {
53
+ return null;
54
+ }
55
+ return v === 'true';
56
+ },
57
+ [DATA_TYPE_JSON]: (v) => {
58
+ try {
59
+ return JSON.parse(v);
60
+ } catch (error) {
61
+ return null;
62
+ }
63
+ },
64
+ [DATA_TYPE_OBJECT]: (v) => {
65
+ try {
66
+ const d = JSON.parse(v);
67
+ if (Array.isArray(d)) {
68
+ return null;
69
+ }
70
+ if (typeof d !== 'object') {
71
+ return null;
72
+ }
73
+ return d;
74
+ } catch (error) {
75
+ return null;
76
+ }
77
+ },
78
+ [DATA_TYPE_ARRAY]: (v) => {
79
+ try {
80
+ const d = JSON.parse(v);
81
+ if (Array.isArray(d)) {
82
+ return d;
83
+ }
84
+ return [];
85
+ } catch (error) {
86
+ return [];
87
+ }
88
+ },
89
+ };
90
+
91
+ const typeNameMap = {
92
+ [DATA_TYPE_NUMBER]: 'number',
93
+ [DATA_TYPE_STRING]: 'string',
94
+ [DATA_TYPE_INTEGER]: 'integer',
95
+ [DATA_TYPE_BOOLEAN]: 'boolean',
96
+ [DATA_TYPE_JSON]: 'object',
97
+ [DATA_TYPE_ARRAY]: 'object',
98
+ [DATA_TYPE_OBJECT]: 'object',
99
+ };
100
+
101
+ export default (value, type) => {
102
+ if (type == null) {
103
+ throw new Error('data type is empty');
104
+ }
105
+ if (!Object.hasOwnProperty.call(map, type)) {
106
+ throw new Error(`\`${type}\` invalid data type`);
107
+ }
108
+ if (value == null) {
109
+ if (type === 'array') {
110
+ return [];
111
+ }
112
+ return null;
113
+ }
114
+ const valueType = typeof value;
115
+ if (valueType !== 'string') {
116
+ if (type === DATA_TYPE_INTEGER) {
117
+ return map[DATA_TYPE_INTEGER](value);
118
+ }
119
+ if (type === DATA_TYPE_STRING) {
120
+ return map[DATA_TYPE_STRING](value);
121
+ }
122
+ if (valueType === typeNameMap[type]) {
123
+ if (type === DATA_TYPE_ARRAY) {
124
+ return Array.isArray(value) ? value : [];
125
+ }
126
+ if (type === DATA_TYPE_OBJECT) {
127
+ return _.isPlainObject(value) ? value : null;
128
+ }
129
+ return value;
130
+ }
131
+ return type === DATA_TYPE_ARRAY ? [] : null;
132
+ }
133
+ return map[type](value);
134
+ };
@@ -0,0 +1,140 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert';
3
+ import checkout from './checkout.mjs';
4
+
5
+ test('checkout invalid data type', () => {
6
+ assert.throws(() => {
7
+ checkout('aaa', 'bbb');
8
+ });
9
+ assert.throws(() => {
10
+ checkout('aaa');
11
+ });
12
+ });
13
+
14
+ test('checkout with data value null', () => {
15
+ assert.deepEqual(checkout(null, 'array'), []);
16
+ assert.equal(checkout(null, 'object'), null);
17
+ assert.equal(checkout(null, 'string'), null);
18
+ assert.equal(checkout(null, 'number'), null);
19
+ assert.equal(checkout(null, 'integer'), null);
20
+ assert.equal(checkout(null, 'boolean'), null);
21
+ assert.equal(checkout(null, 'json'), null);
22
+ });
23
+
24
+ test('checkout with string', () => {
25
+ assert.equal(checkout(1, 'string'), '1');
26
+ assert.equal(checkout(null, 'string'), null);
27
+ assert.equal(checkout(true, 'string'), 'true');
28
+ assert.equal(checkout(false, 'string'), 'false');
29
+ assert.equal(checkout(' 1', 'string'), ' 1');
30
+ assert.equal(checkout([1, 2, 3], 'string'), '1,2,3');
31
+ assert.equal(checkout({ name: 'cqq' }, 'string'), '[object Object]');
32
+ assert.equal(checkout({
33
+ name: 'quan',
34
+ toString: () => 'cqq',
35
+ }, 'string'), 'cqq');
36
+ });
37
+
38
+ test('checkout with integer', () => {
39
+ assert.equal(checkout(null, 'integer'), null);
40
+ assert.equal(checkout('', 'integer'), null);
41
+ assert.equal(checkout(true, 'integer'), null);
42
+ assert.equal(checkout(false, 'integer'), null);
43
+ assert.equal(checkout([], 'integer'), null);
44
+ assert.equal(checkout({}, 'integer'), null);
45
+ assert.equal(checkout('aaa', 'integer'), null);
46
+ assert.equal(checkout('1', 'integer'), 1);
47
+ assert.equal(checkout('01', 'integer'), null);
48
+ assert.equal(checkout(' 1', 'integer'), null);
49
+ assert.equal(checkout('1.1', 'integer'), 1);
50
+ assert.equal(checkout('-3.1', 'integer'), -3);
51
+ assert.equal(checkout(3.1, 'integer'), 3);
52
+ assert.equal(checkout(1, 'integer'), 1);
53
+ assert(Number.isNaN(checkout(NaN, 'integer')));
54
+ });
55
+
56
+ test('checkout with number', () => {
57
+ assert.equal(checkout('1', 'number'), 1);
58
+ assert.equal(checkout('01', 'number'), null);
59
+ assert.equal(checkout(true, 'number'), null);
60
+ assert.equal(checkout(false, 'number'), null);
61
+ assert.equal(checkout([], 'number'), null);
62
+ assert.equal(checkout({}, 'number'), null);
63
+ assert.equal(checkout('', 'number'), null);
64
+ assert.equal(checkout('a', 'number'), null);
65
+ assert.equal(checkout('1a', 'number'), null);
66
+ assert.equal(checkout('0', 'number'), 0);
67
+ assert.equal(checkout('-0', 'number'), null);
68
+ assert.equal(checkout('-1', 'number'), -1);
69
+ assert.equal(checkout('-1.5', 'number'), -1.5);
70
+ assert.equal(checkout('-2.5', 'number'), -2.5);
71
+ assert.equal(checkout('2.5', 'number'), 2.5);
72
+ assert.equal(checkout(1, 'number'), 1);
73
+ assert(Number.isNaN(checkout(NaN, 'number')));
74
+ });
75
+
76
+ test('checkout with boolean', () => {
77
+ assert.equal(checkout('', 'boolean'), null);
78
+ assert.equal(checkout('false', 'boolean'), false);
79
+ assert.equal(checkout(' false', 'boolean'), null);
80
+ assert.equal(checkout('false ', 'boolean'), null);
81
+ assert.equal(checkout('true', 'boolean'), true);
82
+ assert.equal(checkout(' true', 'boolean'), null);
83
+ assert.equal(checkout('true ', 'boolean'), null);
84
+ assert.equal(checkout(true, 'boolean'), true);
85
+ assert.equal(checkout(false, 'boolean'), false);
86
+ assert.equal(checkout(1, 'boolean'), null);
87
+ assert.equal(checkout({}, 'boolean'), null);
88
+ assert.equal(checkout([], 'boolean'), null);
89
+ assert.equal(checkout('aaa', 'boolean'), null);
90
+ });
91
+
92
+ test('checkout with json', () => {
93
+ assert.equal(checkout('1', 'json'), 1);
94
+ assert.equal(checkout(' 1', 'json'), 1);
95
+ assert.equal(checkout('"1"', 'json'), '1');
96
+ assert.equal(checkout('\'1\'', 'json'), null);
97
+ assert.equal(checkout('null', 'json'), null);
98
+ assert.equal(checkout('aa', 'json'), null);
99
+ assert.deepEqual(checkout('{}', 'json'), {});
100
+ assert.deepEqual(checkout('{fail}', 'json'), null);
101
+ assert.deepEqual(checkout('{"name":"cqq"}', 'json'), { name: 'cqq' });
102
+ assert.deepEqual(checkout('[]', 'json'), []);
103
+ assert.deepEqual(checkout([], 'json'), []);
104
+ assert.deepEqual(checkout({}, 'json'), {});
105
+ assert.deepEqual(checkout(2, 'json'), null);
106
+ });
107
+
108
+ test('checkout with array', () => {
109
+ assert.deepEqual(checkout(null, 'array'), []);
110
+ assert.deepEqual(checkout('[]', 'array'), []);
111
+ assert.deepEqual(checkout('[xxx]', 'array'), []);
112
+ assert.deepEqual(checkout([], 'array'), []);
113
+ assert.deepEqual(checkout([1, 2, 3], 'array'), [1, 2, 3]);
114
+ assert.deepEqual(checkout(1, 'array'), []);
115
+ assert.deepEqual(checkout({}, 'array'), []);
116
+ assert.deepEqual(checkout('1', 'array'), []);
117
+ assert.deepEqual(checkout('{}', 'array'), []);
118
+ assert.deepEqual(checkout(['12345'], 'array'), ['12345']);
119
+ assert.deepEqual(checkout(true, 'array'), []);
120
+ assert.deepEqual(checkout(false, 'array'), []);
121
+ assert.deepEqual(checkout([{ name: 'cqq' }], 'array'), [{ name: 'cqq' }]);
122
+ assert.deepEqual(checkout(JSON.stringify([{ name: 'cqq' }]), 'array'), [{ name: 'cqq' }]);
123
+ });
124
+
125
+ test('checkout with object', () => {
126
+ assert.equal(checkout(null, 'object'), null);
127
+ assert.equal(checkout(1, 'object'), null);
128
+ assert.equal(checkout('aa', 'object'), null);
129
+ assert.equal(checkout('1', 'object'), null);
130
+ assert.equal(checkout(JSON.stringify('aa'), 'object'), null);
131
+ assert.equal(checkout(true, 'object'), null);
132
+ assert.equal(checkout('true', 'object'), null);
133
+ assert.equal(checkout('false', 'object'), null);
134
+ assert.equal(checkout(false, 'object'), null);
135
+ assert.equal(checkout([], 'object'), null);
136
+ assert.equal(checkout(JSON.stringify([]), 'object'), null);
137
+ assert.deepEqual(checkout({ name: 'cqq' }, 'object'), { name: 'cqq' });
138
+ assert.deepEqual(checkout(JSON.stringify({ name: 'cqq' }), 'object'), { name: 'cqq' });
139
+ assert.deepEqual(checkout('{fail}', 'object'), null);
140
+ });
@@ -0,0 +1,44 @@
1
+ import _ from 'lodash';
2
+
3
+ const walk = (obj, nameList) => {
4
+ const [dataKey, ...other] = nameList;
5
+ if (Array.isArray(obj)) {
6
+ const n = parseInt(dataKey, 10);
7
+ if (Number.isNaN(n) || `${n}` !== dataKey) {
8
+ return null;
9
+ }
10
+ const len = obj.length;
11
+ if (n > len) {
12
+ return null;
13
+ }
14
+ if (other.length === 0) {
15
+ return obj[n];
16
+ }
17
+ return walk(obj[n], other);
18
+ }
19
+ if (!Object.hasOwnProperty.call(obj, dataKey)) {
20
+ return null;
21
+ }
22
+ const value = obj[dataKey];
23
+ if (other.length === 0) {
24
+ return value;
25
+ }
26
+ return walk(value, other);
27
+ };
28
+
29
+ export default (obj, pathname) => {
30
+ if (typeof pathname !== 'string' || (/\.$/.test(pathname) && pathname !== '.')) {
31
+ throw new Error('pathname invalid');
32
+ }
33
+ if (!Array.isArray(obj) && !_.isPlainObject(obj)) {
34
+ return null;
35
+ }
36
+ let str = pathname;
37
+ if (pathname.startsWith('.')) {
38
+ str = pathname.slice(1);
39
+ }
40
+ if (str === '') {
41
+ return obj;
42
+ }
43
+ return walk(obj, str.split(/(?<!\\)\./).map((d) => d.replace(/\\\./g, '.')));
44
+ };
@@ -0,0 +1,29 @@
1
+ import assert from 'node:assert';
2
+ import test from 'node:test';
3
+ import getValueOfPathname from './getValueOfPathname.mjs';
4
+
5
+ test('getValueOfPathname', () => {
6
+ assert.throws(() => {
7
+ getValueOfPathname({}, 11);
8
+ });
9
+ assert.throws(() => {
10
+ getValueOfPathname({}, 'name.');
11
+ });
12
+ assert.deepEqual(getValueOfPathname({}, '.'), {});
13
+ assert.equal(getValueOfPathname([], 'name'), null);
14
+ assert.equal(getValueOfPathname(null, 'xxx'), null);
15
+ assert.equal(getValueOfPathname({ name: 'quan' }, 'quan'), null);
16
+ assert.equal(getValueOfPathname({ name: 'quan' }, 'name'), 'quan');
17
+ assert.equal(getValueOfPathname({ name: 'quan' }, '.name'), 'quan');
18
+ assert.equal(getValueOfPathname({ '.name': 'quan', name: 'cqq' }, '\\.name'), 'quan');
19
+ assert.deepEqual(getValueOfPathname({ name: 'quan' }, ''), { name: 'quan' });
20
+ assert.deepEqual(getValueOfPathname({ name: 'quan', obj: { foo: 'bar' } }, 'obj'), { foo: 'bar' });
21
+ assert.equal(getValueOfPathname({ name: 'quan', obj: { name: 'bar' } }, 'obj.name'), 'bar');
22
+ assert.equal(getValueOfPathname({ 'obj.name': 'xxx', name: 'quan', obj: { name: 'bar' } }, 'obj\\.name'), 'xxx');
23
+ });
24
+
25
+ test('getValueOfPathname of array', () => {
26
+ assert.equal(getValueOfPathname([{ name: 'aa' }, { name: 'bb' }], '0.name'), 'aa');
27
+ assert.equal(getValueOfPathname([{ name: 'aa' }, { name: 'bb' }], '5.name'), null);
28
+ assert.equal(getValueOfPathname([{ name: 'aa' }, { name: 'bb' }], '5'), null);
29
+ });
package/src/index.mjs ADDED
@@ -0,0 +1,9 @@
1
+ import checkout from './checkout.mjs';
2
+ import getValueOfPathname from './getValueOfPathname.mjs';
3
+ import select from './select/index.mjs';
4
+
5
+ export {
6
+ select,
7
+ checkout,
8
+ getValueOfPathname,
9
+ };
@@ -0,0 +1,63 @@
1
+ import Ajv from 'ajv';
2
+
3
+ const ajv = new Ajv();
4
+
5
+ const validate = ajv.compile({
6
+ type: 'object',
7
+ anyOf: [
8
+ {
9
+ properties: {
10
+ type: {
11
+ enum: ['object'],
12
+ },
13
+ properties: {
14
+ type: 'object',
15
+ },
16
+ },
17
+ required: ['type', 'properties'],
18
+ },
19
+ {
20
+ properties: {
21
+ type: {
22
+ enum: ['array'],
23
+ },
24
+ properties: {
25
+ anyOf: [
26
+ {
27
+ type: 'object',
28
+ },
29
+ {
30
+ type: 'array',
31
+ items: [
32
+ {
33
+ type: 'string',
34
+ },
35
+ {
36
+ type: 'object',
37
+ },
38
+ ],
39
+ additionalItems: false,
40
+ minItems: 2,
41
+ maxItems: 2,
42
+ },
43
+ ],
44
+ },
45
+ },
46
+ required: ['type', 'properties'],
47
+ },
48
+ {
49
+ properties: {
50
+ type: {
51
+ enum: ['string', 'number', 'boolean', 'integer'],
52
+ },
53
+ },
54
+ required: ['type'],
55
+ },
56
+ ],
57
+ });
58
+
59
+ export default (express) => {
60
+ if (!validate(express)) {
61
+ throw new Error(`\`${JSON.stringify(express)}\` ${JSON.stringify(validate.errors)}`);
62
+ }
63
+ };
@@ -0,0 +1,75 @@
1
+ import assert from 'node:assert';
2
+ import test from 'node:test';
3
+ import check from './check.mjs';
4
+
5
+ test('select > check', () => {
6
+ assert.throws(() => {
7
+ check([]);
8
+ });
9
+ assert.throws(() => {
10
+ check('number');
11
+ });
12
+ assert.throws(() => {
13
+ check('integer');
14
+ });
15
+ assert.throws(() => {
16
+ check({});
17
+ });
18
+ assert.throws(() => {
19
+ check({
20
+ type: 'object',
21
+ properties: [],
22
+ });
23
+ });
24
+ assert.throws(() => {
25
+ check({
26
+ type: 'xxx',
27
+ });
28
+ });
29
+ assert.throws(() => {
30
+ check({
31
+ type: 'json',
32
+ });
33
+ });
34
+ assert.throws(() => {
35
+ check({
36
+ type: 'array',
37
+ properties: [],
38
+ });
39
+ });
40
+ assert.throws(() => {
41
+ check({
42
+ type: 'array',
43
+ properties: ['dataKey', []],
44
+ });
45
+ });
46
+ check({
47
+ type: 'string',
48
+ });
49
+ check({
50
+ type: 'string',
51
+ properties: ['dataKey'],
52
+ });
53
+ check({
54
+ type: 'string',
55
+ properties: ['dataKey', []],
56
+ });
57
+ check({
58
+ type: 'string',
59
+ properties: ['dataKey', {}],
60
+ });
61
+ check({
62
+ type: 'object',
63
+ properties: {
64
+ },
65
+ });
66
+ check({
67
+ type: 'array',
68
+ properties: {
69
+ },
70
+ });
71
+ check({
72
+ type: 'array',
73
+ properties: ['dataKey', {}],
74
+ });
75
+ });
@@ -0,0 +1,108 @@
1
+ /* eslint no-use-before-define: 0 */
2
+ import _ from 'lodash';
3
+ import check from './check.mjs';
4
+ import checkout from '../checkout.mjs';
5
+ import getValueOfPathname from '../getValueOfPathname.mjs';
6
+
7
+ function walkWithObject(properties) {
8
+ const keys = Object.keys(properties);
9
+ const list = [];
10
+ for (let i = 0; i < keys.length; i++) {
11
+ const dataKey = keys[i];
12
+ const express = properties[dataKey];
13
+ const handler = {
14
+ dataKey,
15
+ express,
16
+ fn: select(express),
17
+ };
18
+ list.push(handler);
19
+ }
20
+ return (d, _root) => {
21
+ const root = _root == null ? d : _root;
22
+ return list.reduce((acc, cur) => {
23
+ if (Array.isArray(cur.express)) {
24
+ return {
25
+ ...acc,
26
+ [cur.dataKey]: cur.fn(d, root),
27
+ };
28
+ }
29
+ return {
30
+ ...acc,
31
+ [cur.dataKey]: cur.fn(d == null ? d : d[cur.dataKey], root),
32
+ };
33
+ }, {});
34
+ };
35
+ }
36
+
37
+ function select(express) {
38
+ if (Array.isArray(express)) {
39
+ const [pathname] = express;
40
+ if (typeof pathname !== 'string'
41
+ || !_.isPlainObject(express[1])
42
+ ) {
43
+ throw new Error(`\`${JSON.stringify(express)}\` express invalid`);
44
+ }
45
+ const walk = select(express[1]);
46
+ return (obj, _root) => {
47
+ const root = _root == null ? obj : _root;
48
+ if (pathname.startsWith('$')) {
49
+ return walk(getValueOfPathname(root, pathname.slice(1)), root);
50
+ }
51
+ return walk(getValueOfPathname(obj, pathname), root);
52
+ };
53
+ }
54
+ check(express);
55
+ if (['string', 'number', 'boolean', 'integer'].includes(express.type)) {
56
+ return (v, _root) => {
57
+ const root = _root == null ? v : _root;
58
+ let value = v;
59
+ if (express.resolve) {
60
+ value = express.resolve(value, root);
61
+ }
62
+ return checkout(value, express.type);
63
+ };
64
+ }
65
+ if (express.resolve) {
66
+ console.warn('data type `array` or `object` unspport resolve');
67
+ }
68
+ if (express.type === 'object') {
69
+ return walkWithObject(express.properties);
70
+ }
71
+ if (Array.isArray(express.properties)) {
72
+ const walk = select(express.properties[1]);
73
+ return (arr, _root) => {
74
+ const root = _root == null ? arr : _root;
75
+ const [pathname] = express.properties;
76
+ if (!Array.isArray(arr)) {
77
+ if (pathname.startsWith('$')) {
78
+ const ret = walk(getValueOfPathname(root, pathname.slice(1)), root);
79
+ if (ret == null) {
80
+ return [];
81
+ }
82
+ return [ret];
83
+ }
84
+ return [];
85
+ }
86
+ return arr.map((d) => {
87
+ if (pathname === '' || pathname === '.') {
88
+ return walk(d, root);
89
+ }
90
+ return walk(getValueOfPathname(d, pathname), root);
91
+ });
92
+ };
93
+ }
94
+ const walk = walkWithObject(express.properties);
95
+ return (arr, _root) => {
96
+ const root = _root == null ? arr : _root;
97
+ if (!Array.isArray(arr)) {
98
+ if (_.isEmpty(express.properties)) {
99
+ return [];
100
+ }
101
+ const ret = walk(arr, root);
102
+ return [ret];
103
+ }
104
+ return arr.map((d) => walk(d, root));
105
+ };
106
+ }
107
+
108
+ export default select;