amis 1.3.4 → 1.4.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.
Files changed (270) hide show
  1. package/README.md +2 -1
  2. package/lib/RootRenderer.js +4 -1
  3. package/lib/RootRenderer.js.map +2 -2
  4. package/lib/components/Badge.d.ts +13 -1
  5. package/lib/components/Badge.js +16 -2
  6. package/lib/components/Badge.js.map +2 -2
  7. package/lib/components/Checkbox.d.ts +1 -1
  8. package/lib/components/Checkbox.js +1 -1
  9. package/lib/components/Checkbox.js.map +2 -2
  10. package/lib/components/Drawer.js +1 -1
  11. package/lib/components/Drawer.js.map +2 -2
  12. package/lib/components/Modal.js +1 -1
  13. package/lib/components/Modal.js.map +2 -2
  14. package/lib/components/RichText.d.ts +0 -3
  15. package/lib/components/RichText.js +1 -22
  16. package/lib/components/RichText.js.map +2 -2
  17. package/lib/components/Select.d.ts +7 -0
  18. package/lib/components/Select.js.map +2 -2
  19. package/lib/components/Steps.d.ts +3 -3
  20. package/lib/components/Steps.js.map +1 -1
  21. package/lib/components/WithRemoteConfig.d.ts +8 -0
  22. package/lib/components/WithRemoteConfig.js +28 -2
  23. package/lib/components/WithRemoteConfig.js.map +2 -2
  24. package/lib/components/condition-builder/Field.js +0 -1
  25. package/lib/components/condition-builder/Field.js.map +2 -2
  26. package/lib/components/condition-builder/Value.js +2 -1
  27. package/lib/components/condition-builder/Value.js.map +2 -2
  28. package/lib/components/condition-builder/types.d.ts +5 -0
  29. package/lib/components/condition-builder/types.js.map +1 -1
  30. package/lib/env.d.ts +1 -1
  31. package/lib/env.js.map +1 -1
  32. package/lib/factory.d.ts +6 -2
  33. package/lib/factory.js +9 -4
  34. package/lib/factory.js.map +2 -2
  35. package/lib/index.d.ts +1 -0
  36. package/lib/index.js +2 -1
  37. package/lib/index.js.map +2 -2
  38. package/lib/locale/de-DE.js +1 -0
  39. package/lib/locale/de-DE.js.map +2 -2
  40. package/lib/locale/en-US.js +2 -1
  41. package/lib/locale/en-US.js.map +2 -2
  42. package/lib/locale/zh-CN.js +2 -1
  43. package/lib/locale/zh-CN.js.map +2 -2
  44. package/lib/renderers/Action.d.ts +6 -0
  45. package/lib/renderers/Action.js +9 -1
  46. package/lib/renderers/Action.js.map +2 -2
  47. package/lib/renderers/CRUD.d.ts +2 -2
  48. package/lib/renderers/CRUD.js +13 -21
  49. package/lib/renderers/CRUD.js.map +2 -2
  50. package/lib/renderers/Card.js +11 -11
  51. package/lib/renderers/Card.js.map +2 -2
  52. package/lib/renderers/Collapse.d.ts +1 -1
  53. package/lib/renderers/Collapse.js +5 -1
  54. package/lib/renderers/Collapse.js.map +2 -2
  55. package/lib/renderers/Copyable.js +30 -28
  56. package/lib/renderers/Copyable.js.map +2 -2
  57. package/lib/renderers/Dialog.d.ts +0 -252
  58. package/lib/renderers/Dialog.js +3 -2
  59. package/lib/renderers/Dialog.js.map +2 -2
  60. package/lib/renderers/Drawer.js +2 -1
  61. package/lib/renderers/Drawer.js.map +2 -2
  62. package/lib/renderers/DropDownButton.d.ts +4 -0
  63. package/lib/renderers/DropDownButton.js +2 -2
  64. package/lib/renderers/DropDownButton.js.map +2 -2
  65. package/lib/renderers/Form/ButtonGroupSelect.js +3 -0
  66. package/lib/renderers/Form/ButtonGroupSelect.js.map +2 -2
  67. package/lib/renderers/Form/Combo.d.ts +2 -0
  68. package/lib/renderers/Form/Combo.js +16 -1
  69. package/lib/renderers/Form/Combo.js.map +2 -2
  70. package/lib/renderers/Form/DiffEditor.d.ts +0 -2
  71. package/lib/renderers/Form/Editor.d.ts +0 -2
  72. package/lib/renderers/Form/Editor.js +1 -1
  73. package/lib/renderers/Form/Editor.js.map +2 -2
  74. package/lib/renderers/Form/InputExcel.d.ts +5 -0
  75. package/lib/renderers/Form/InputExcel.js +24 -3
  76. package/lib/renderers/Form/InputExcel.js.map +2 -2
  77. package/lib/renderers/Form/InputImage.d.ts +8 -0
  78. package/lib/renderers/Form/InputImage.js +2 -1
  79. package/lib/renderers/Form/InputImage.js.map +2 -2
  80. package/lib/renderers/Form/InputNumber.d.ts +19 -5
  81. package/lib/renderers/Form/InputNumber.js +69 -7
  82. package/lib/renderers/Form/InputNumber.js.map +2 -2
  83. package/lib/renderers/Form/InputRange.js +7 -2
  84. package/lib/renderers/Form/InputRange.js.map +2 -2
  85. package/lib/renderers/Form/InputTable.d.ts +23 -5
  86. package/lib/renderers/Form/InputTable.js +32 -3
  87. package/lib/renderers/Form/InputTable.js.map +2 -2
  88. package/lib/renderers/Form/NestedSelect.js +2 -3
  89. package/lib/renderers/Form/NestedSelect.js.map +2 -2
  90. package/lib/renderers/Form/Options.js +3 -1
  91. package/lib/renderers/Form/Options.js.map +2 -2
  92. package/lib/renderers/Form/index.js +0 -10
  93. package/lib/renderers/Form/index.js.map +2 -2
  94. package/lib/renderers/Form/wrapControl.js +3 -3
  95. package/lib/renderers/Form/wrapControl.js.map +2 -2
  96. package/lib/renderers/Json.js +5 -1
  97. package/lib/renderers/Json.js.map +2 -2
  98. package/lib/renderers/List.d.ts +5 -0
  99. package/lib/renderers/List.js +20 -14
  100. package/lib/renderers/List.js.map +2 -2
  101. package/lib/renderers/Page.d.ts +6 -0
  102. package/lib/renderers/Page.js +10 -2
  103. package/lib/renderers/Page.js.map +2 -2
  104. package/lib/renderers/Service.d.ts +10 -1
  105. package/lib/renderers/Service.js +85 -3
  106. package/lib/renderers/Service.js.map +2 -2
  107. package/lib/renderers/Steps.d.ts +4 -4
  108. package/lib/renderers/Steps.js +5 -2
  109. package/lib/renderers/Steps.js.map +2 -2
  110. package/lib/renderers/Table/TableBody.d.ts +5 -3
  111. package/lib/renderers/Table/TableBody.js +17 -11
  112. package/lib/renderers/Table/TableBody.js.map +2 -2
  113. package/lib/renderers/Table/TableCell.js +6 -2
  114. package/lib/renderers/Table/TableCell.js.map +2 -2
  115. package/lib/renderers/Table/TableContent.d.ts +3 -1
  116. package/lib/renderers/Table/TableContent.js +6 -2
  117. package/lib/renderers/Table/TableContent.js.map +2 -2
  118. package/lib/renderers/Table/TableRow.d.ts +1 -1
  119. package/lib/renderers/Table/TableRow.js +14 -13
  120. package/lib/renderers/Table/TableRow.js.map +2 -2
  121. package/lib/renderers/Table/index.d.ts +28 -3
  122. package/lib/renderers/Table/index.js +97 -54
  123. package/lib/renderers/Table/index.js.map +2 -2
  124. package/lib/schemaExtend.d.ts +1 -0
  125. package/lib/schemaExtend.js +59 -0
  126. package/lib/schemaExtend.js.map +13 -0
  127. package/lib/store/app.d.ts +0 -1
  128. package/lib/store/combo.d.ts +0 -2
  129. package/lib/store/crud.d.ts +3 -3
  130. package/lib/store/crud.js +41 -36
  131. package/lib/store/crud.js.map +2 -2
  132. package/lib/store/form.d.ts +0 -1
  133. package/lib/store/formItem.js +10 -6
  134. package/lib/store/formItem.js.map +2 -2
  135. package/lib/store/modal.d.ts +1 -1
  136. package/lib/store/modal.js +4 -0
  137. package/lib/store/modal.js.map +2 -2
  138. package/lib/store/root.d.ts +0 -1
  139. package/lib/store/service.d.ts +0 -1
  140. package/lib/store/service.js +0 -13
  141. package/lib/store/service.js.map +2 -2
  142. package/lib/store/table.d.ts +1 -2
  143. package/lib/store/table.js +44 -3
  144. package/lib/store/table.js.map +2 -2
  145. package/lib/themes/ang-ie11.css +278 -17
  146. package/lib/themes/ang.css +278 -17
  147. package/lib/themes/ang.css.map +1 -1
  148. package/lib/themes/antd-ie11.css +278 -17
  149. package/lib/themes/antd.css +278 -17
  150. package/lib/themes/antd.css.map +1 -1
  151. package/lib/themes/cxd-ie11.css +278 -17
  152. package/lib/themes/cxd.css +278 -17
  153. package/lib/themes/cxd.css.map +1 -1
  154. package/lib/themes/dark-ie11.css +278 -17
  155. package/lib/themes/dark.css +278 -17
  156. package/lib/themes/dark.css.map +1 -1
  157. package/lib/themes/default.css +278 -17
  158. package/lib/themes/default.css.map +1 -1
  159. package/lib/utils/api.js +12 -0
  160. package/lib/utils/api.js.map +2 -2
  161. package/lib/utils/attachmentAdpator.d.ts +7 -0
  162. package/lib/utils/attachmentAdpator.js +82 -0
  163. package/lib/utils/attachmentAdpator.js.map +13 -0
  164. package/lib/utils/helper.d.ts +2 -0
  165. package/lib/utils/helper.js +14 -1
  166. package/lib/utils/helper.js.map +2 -2
  167. package/lib/utils/resize-sensor.js +6 -0
  168. package/lib/utils/resize-sensor.js.map +2 -2
  169. package/lib/utils/tpl-builtin.d.ts +1 -0
  170. package/lib/utils/tpl-builtin.js +24 -8
  171. package/lib/utils/tpl-builtin.js.map +2 -2
  172. package/lib/utils/validations.js +62 -5
  173. package/lib/utils/validations.js.map +2 -2
  174. package/package.json +1 -1
  175. package/schema.json +369 -164
  176. package/scss/_properties.scss +6 -0
  177. package/scss/components/_badge.scss +15 -1
  178. package/scss/components/_list.scss +8 -0
  179. package/scss/components/_markdown.scss +266 -0
  180. package/scss/components/_spinner.scss +6 -2
  181. package/scss/components/_table.scss +4 -0
  182. package/scss/components/form/_form.scss +3 -17
  183. package/scss/components/form/_group.scss +4 -0
  184. package/scss/components/form/_nested-select.scss +4 -0
  185. package/scss/components/form/_number.scss +12 -1
  186. package/scss/themes/_common.scss +1 -0
  187. package/sdk/ang-ie11.css +324 -20
  188. package/sdk/ang.css +330 -20
  189. package/sdk/antd-ie11.css +324 -20
  190. package/sdk/antd.css +330 -20
  191. package/sdk/charts.js +15 -15
  192. package/sdk/color-picker.js +65 -69
  193. package/sdk/cropperjs.js +2 -2
  194. package/sdk/cxd-ie11.css +324 -20
  195. package/sdk/cxd.css +330 -20
  196. package/sdk/dark-ie11.css +324 -20
  197. package/sdk/dark.css +330 -20
  198. package/sdk/exceljs.js +1 -1
  199. package/sdk/locale/de-DE.js +1 -0
  200. package/sdk/markdown.js +69 -69
  201. package/sdk/papaparse.js +1 -1
  202. package/sdk/renderers/Form/CityDB.js +1 -1
  203. package/sdk/rest.js +27 -23
  204. package/sdk/rich-text.js +63 -63
  205. package/sdk/sdk-ie11.css +324 -20
  206. package/sdk/sdk.css +330 -20
  207. package/sdk/sdk.js +1146 -1138
  208. package/sdk/thirds/hls.js/hls.js +1 -1
  209. package/sdk/thirds/mpegts.js/mpegts.js +1 -1
  210. package/sdk/tinymce.js +57 -57
  211. package/src/RootRenderer.tsx +8 -3
  212. package/src/components/Badge.tsx +41 -6
  213. package/src/components/Checkbox.tsx +5 -2
  214. package/src/components/Drawer.tsx +3 -2
  215. package/src/components/Modal.tsx +3 -2
  216. package/src/components/RichText.tsx +2 -27
  217. package/src/components/Select.tsx +1 -0
  218. package/src/components/Steps.tsx +3 -3
  219. package/src/components/WithRemoteConfig.tsx +37 -2
  220. package/src/components/condition-builder/Field.tsx +1 -2
  221. package/src/components/condition-builder/Value.tsx +3 -0
  222. package/src/components/condition-builder/types.ts +6 -0
  223. package/src/env.tsx +1 -1
  224. package/src/factory.tsx +14 -4
  225. package/src/index.tsx +2 -0
  226. package/src/locale/de-DE.ts +1 -0
  227. package/src/locale/en-US.ts +2 -1
  228. package/src/locale/zh-CN.ts +2 -1
  229. package/src/renderers/Action.tsx +19 -1
  230. package/src/renderers/CRUD.tsx +15 -34
  231. package/src/renderers/Card.tsx +21 -15
  232. package/src/renderers/Collapse.tsx +5 -1
  233. package/src/renderers/Copyable.tsx +46 -44
  234. package/src/renderers/Dialog.tsx +3 -2
  235. package/src/renderers/Drawer.tsx +2 -1
  236. package/src/renderers/DropDownButton.tsx +8 -0
  237. package/src/renderers/Form/ButtonGroupSelect.tsx +3 -0
  238. package/src/renderers/Form/Combo.tsx +7 -0
  239. package/src/renderers/Form/Editor.tsx +19 -20
  240. package/src/renderers/Form/InputExcel.tsx +28 -3
  241. package/src/renderers/Form/InputImage.tsx +23 -8
  242. package/src/renderers/Form/InputNumber.tsx +113 -18
  243. package/src/renderers/Form/InputRange.tsx +5 -2
  244. package/src/renderers/Form/InputTable.tsx +88 -9
  245. package/src/renderers/Form/NestedSelect.tsx +1 -1
  246. package/src/renderers/Form/Options.tsx +3 -1
  247. package/src/renderers/Form/index.tsx +0 -15
  248. package/src/renderers/Form/wrapControl.tsx +2 -2
  249. package/src/renderers/Json.tsx +10 -1
  250. package/src/renderers/List.tsx +32 -19
  251. package/src/renderers/Page.tsx +19 -0
  252. package/src/renderers/Service.tsx +101 -3
  253. package/src/renderers/Steps.tsx +12 -9
  254. package/src/renderers/Table/TableBody.tsx +29 -10
  255. package/src/renderers/Table/TableCell.tsx +15 -1
  256. package/src/renderers/Table/TableContent.tsx +7 -1
  257. package/src/renderers/Table/TableRow.tsx +18 -17
  258. package/src/renderers/Table/index.tsx +117 -28
  259. package/src/schemaExtend.ts +66 -0
  260. package/src/store/crud.ts +34 -38
  261. package/src/store/formItem.ts +10 -6
  262. package/src/store/modal.ts +4 -0
  263. package/src/store/service.ts +0 -19
  264. package/src/store/table.ts +48 -0
  265. package/src/utils/api.ts +11 -0
  266. package/src/utils/attachmentAdpator.ts +90 -0
  267. package/src/utils/helper.ts +15 -0
  268. package/src/utils/resize-sensor.ts +7 -0
  269. package/src/utils/tpl-builtin.ts +36 -17
  270. package/src/utils/validations.ts +80 -12
@@ -0,0 +1,90 @@
1
+ /**
2
+ * 处理接口返回附件的情况,好几个地方用
3
+ * @param response
4
+ * @param __
5
+ * @returns
6
+ */
7
+
8
+ export default function attachmentAdpator(response: any, __: Function) {
9
+ if (response && response.headers && response.headers['content-disposition']) {
10
+ const disposition = response.headers['content-disposition'];
11
+ let filename = '';
12
+
13
+ if (disposition && disposition.indexOf('attachment') !== -1) {
14
+ // disposition 有可能是 attachment; filename="??.xlsx"; filename*=UTF-8''%E4%B8%AD%E6%96%87.xlsx
15
+ // 这种情况下最后一个才是正确的文件名
16
+ let filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)$/;
17
+
18
+ let matches = disposition.match(filenameRegex);
19
+ if (matches && matches.length) {
20
+ filename = matches[1].replace(`UTF-8''`, '').replace(/['"]/g, '');
21
+ }
22
+
23
+ // 很可能是中文被 url-encode 了
24
+ if (filename && filename.replace(/[^%]/g, '').length > 2) {
25
+ filename = decodeURIComponent(filename);
26
+ }
27
+
28
+ let type = response.headers['content-type'];
29
+ let blob =
30
+ response.data.toString() === '[object Blob]'
31
+ ? response.data
32
+ : new Blob([response.data], {type: type});
33
+ if (typeof (window.navigator as any).msSaveBlob !== 'undefined') {
34
+ // IE workaround for "HTML7007: One or more blob URLs were revoked by closing the blob for which they were created. These URLs will no longer resolve as the data backing the URL has been freed."
35
+ (window.navigator as any).msSaveBlob(blob, filename);
36
+ } else {
37
+ let URL = window.URL || (window as any).webkitURL;
38
+ let downloadUrl = URL.createObjectURL(blob);
39
+ if (filename) {
40
+ // use HTML5 a[download] attribute to specify filename
41
+ let a = document.createElement('a');
42
+ // safari doesn't support this yet
43
+ if (typeof a.download === 'undefined') {
44
+ (window as any).location = downloadUrl;
45
+ } else {
46
+ a.href = downloadUrl;
47
+ a.download = filename;
48
+ document.body.appendChild(a);
49
+ a.click();
50
+ }
51
+ } else {
52
+ (window as any).location = downloadUrl;
53
+ }
54
+ setTimeout(function () {
55
+ URL.revokeObjectURL(downloadUrl);
56
+ }, 100); // cleanup
57
+ }
58
+
59
+ return {
60
+ ...response,
61
+ data: {
62
+ status: 0,
63
+ msg: __('Embed.downloading')
64
+ }
65
+ };
66
+ }
67
+ } else if (response.data.toString() === '[object Blob]') {
68
+ return new Promise((resolve, reject) => {
69
+ let reader = new FileReader();
70
+ reader.addEventListener('loadend', e => {
71
+ const text = reader.result as string;
72
+
73
+ try {
74
+ resolve({
75
+ ...response,
76
+ data: {
77
+ ...JSON.parse(text)
78
+ }
79
+ });
80
+ } catch (e) {
81
+ reject(e);
82
+ }
83
+ });
84
+
85
+ reader.readAsText(response.data);
86
+ });
87
+ }
88
+
89
+ return response;
90
+ }
@@ -1682,3 +1682,18 @@ export function normalizeNodePath(
1682
1682
 
1683
1683
  return {nodeValueArray, nodePathArray};
1684
1684
  }
1685
+
1686
+ // 主要用于排除点击输入框和链接等情况
1687
+ export function isClickOnInput(e: React.MouseEvent<HTMLElement>) {
1688
+ const target: HTMLElement = e.target as HTMLElement;
1689
+ let formItem;
1690
+ if (
1691
+ !e.currentTarget.contains(target) ||
1692
+ ~['INPUT', 'TEXTAREA'].indexOf(target.tagName) ||
1693
+ ((formItem = target.closest(`button, a, [data-role="form-item"]`)) &&
1694
+ e.currentTarget.contains(formItem))
1695
+ ) {
1696
+ return true;
1697
+ }
1698
+ return false;
1699
+ }
@@ -29,6 +29,9 @@ export function getComputedStyle(element: HTMLElement, prop: string) {
29
29
  }
30
30
 
31
31
  function attachResizeEvent(element: HTMLElement, resized: () => void) {
32
+ if (!element) {
33
+ return;
34
+ }
32
35
  if (!(element as any).resizedAttached) {
33
36
  (element as any).resizedAttached = new EventQueue();
34
37
  (element as any).resizedAttached.add(resized);
@@ -165,6 +168,10 @@ export function resizeSensor(
165
168
  callback: () => void,
166
169
  once: boolean = false
167
170
  ) {
171
+ if (!element) {
172
+ return () => {};
173
+ }
174
+
168
175
  let disposeEvent: (() => void) | undefined = undefined;
169
176
 
170
177
  if (once) {
@@ -115,7 +115,8 @@ const timeUnitMap: {
115
115
  millisecond: 'ms'
116
116
  };
117
117
 
118
- export const relativeValueRe = /^(.+)?(\+|-)(\d+)(minute|min|hour|day|week|month|year|weekday|second|millisecond)s?$/i;
118
+ export const relativeValueRe =
119
+ /^(.+)?(\+|-)(\d+)(minute|min|hour|day|week|month|year|weekday|second|millisecond)s?$/i;
119
120
  export const filterDate = (
120
121
  value: string,
121
122
  data: object = {},
@@ -164,9 +165,10 @@ export const filterDate = (
164
165
  };
165
166
 
166
167
  export function parseDuration(str: string): moment.Duration | undefined {
167
- const matches = /^((?:\-|\+)?(?:\d*\.)?\d+)(minute|min|hour|day|week|month|quarter|year|weekday|second|millisecond)s?$/.exec(
168
- str
169
- );
168
+ const matches =
169
+ /^((?:\-|\+)?(?:\d*\.)?\d+)(minute|min|hour|day|week|month|quarter|year|weekday|second|millisecond)s?$/.exec(
170
+ str
171
+ );
170
172
 
171
173
  if (matches) {
172
174
  const duration = moment.duration(parseFloat(matches[1]), matches[2] as any);
@@ -179,6 +181,15 @@ export function parseDuration(str: string): moment.Duration | undefined {
179
181
  return;
180
182
  }
181
183
 
184
+ // 主要用于解决 0.1+0.2 结果的精度问题导致太长
185
+ export function stripNumber(number: number) {
186
+ if (typeof number === 'number') {
187
+ return parseFloat(number.toPrecision(12));
188
+ } else {
189
+ return number;
190
+ }
191
+ }
192
+
182
193
  export const filters: {
183
194
  [propName: string]: (input: any, ...args: any[]) => any;
184
195
  } = {
@@ -209,6 +220,8 @@ export const filters: {
209
220
  data.add();
210
221
  return data.isValid() ? data.toDate() : undefined;
211
222
  },
223
+ fromNow: (input: any, inputFormat = '') =>
224
+ moment(input, inputFormat).fromNow(),
212
225
  dateModify: (
213
226
  input: any,
214
227
  modifier: 'add' | 'subtract' | 'endOf' | 'startOf' = 'add',
@@ -370,18 +383,23 @@ export const filters: {
370
383
  first: input => input && input[0],
371
384
  nth: (input, nth = 0) => input && input[nth],
372
385
  last: input => input && (input.length ? input[input.length - 1] : null),
373
- minus: (input, step = 1) => (parseInt(input, 10) || 0) - parseInt(step, 10),
374
- plus: (input, step = 1) => (parseInt(input, 10) || 0) + parseInt(step, 10),
386
+ minus: (input, step = 1) =>
387
+ stripNumber((parseInt(input, 10) || 0) - parseInt(step, 10)),
388
+ plus: (input, step = 1) =>
389
+ stripNumber((parseInt(input, 10) || 0) + parseInt(step, 10)),
375
390
  count: (input: any) =>
376
391
  Array.isArray(input) || typeof input === 'string' ? input.length : 0,
377
- sum: (input, field) =>
378
- Array.isArray(input)
379
- ? input.reduce(
380
- (sum, item) =>
381
- sum + (parseFloat(field ? pickValues(field, item) : item) || 0),
382
- 0
383
- )
384
- : input,
392
+ sum: (input, field) => {
393
+ if (!Array.isArray(input)) {
394
+ return input;
395
+ }
396
+ const restult = input.reduce(
397
+ (sum, item) =>
398
+ sum + (parseFloat(field ? pickValues(field, item) : item) || 0),
399
+ 0
400
+ );
401
+ return stripNumber(restult);
402
+ },
385
403
  abs: (input: any) => (typeof input === 'number' ? Math.abs(input) : input),
386
404
  pick: (input, path = '&') =>
387
405
  Array.isArray(input) && !/^\d+$/.test(path)
@@ -721,9 +739,10 @@ export const resolveVariableAndFilter = (
721
739
  return undefined;
722
740
  }
723
741
 
724
- const m = /^(\\)?\$(?:((?:\w+\:)?[a-z0-9_.][a-z0-9_.\[\]]*)|{([\s\S]+)})$/i.exec(
725
- path
726
- );
742
+ const m =
743
+ /^(\\)?\$(?:((?:\w+\:)?[a-z0-9_.][a-z0-9_.\[\]]*)|{([\s\S]+)})$/i.exec(
744
+ path
745
+ );
727
746
 
728
747
  if (!m) {
729
748
  return undefined;
@@ -14,6 +14,79 @@ const makeRegexp = (reg: string | RegExp) => {
14
14
 
15
15
  return /^$/;
16
16
  };
17
+ import memoize from 'lodash/memoize';
18
+ import isPlainObject from 'lodash/isPlainObject';
19
+
20
+ const makeUrlRegexp = memoize(function (options: any) {
21
+ options = {
22
+ schemes: ['http', 'https', 'ftp', 'sftp'],
23
+ allowLocal: true,
24
+ allowDataUrl: false,
25
+ ...(isPlainObject(options) ? options : {})
26
+ };
27
+
28
+ // https://github.com/ansman/validate.js/blob/master/validate.js#L1098-L1164
29
+ let {schemes, allowLocal, allowDataUrl} = options;
30
+
31
+ if (!Array.isArray(schemes)) {
32
+ schemes = ['http', 'https', 'ftp', 'sftp'];
33
+ }
34
+
35
+ let regex =
36
+ '^' +
37
+ // protocol identifier
38
+ '(?:(?:' +
39
+ schemes.join('|') +
40
+ ')://)' +
41
+ // user:pass authentication
42
+ '(?:\\S+(?::\\S*)?@)?' +
43
+ '(?:';
44
+
45
+ var tld = '(?:\\.(?:[a-z\\u00a1-\\uffff]{2,}))';
46
+
47
+ if (allowLocal) {
48
+ tld += '?';
49
+ } else {
50
+ regex +=
51
+ // IP address exclusion
52
+ // private & local networks
53
+ '(?!(?:10|127)(?:\\.\\d{1,3}){3})' +
54
+ '(?!(?:169\\.254|192\\.168)(?:\\.\\d{1,3}){2})' +
55
+ '(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})';
56
+ }
57
+
58
+ regex +=
59
+ // IP address dotted notation octets
60
+ // excludes loopback network 0.0.0.0
61
+ // excludes reserved space >= 224.0.0.0
62
+ // excludes network & broacast addresses
63
+ // (first & last IP address of each class)
64
+ '(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])' +
65
+ '(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}' +
66
+ '(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))' +
67
+ '|' +
68
+ // host name
69
+ '(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)' +
70
+ // domain name
71
+ '(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*' +
72
+ tld +
73
+ ')' +
74
+ // port number
75
+ '(?::\\d{2,5})?' +
76
+ // resource path
77
+ '(?:[/?#]\\S*)?' +
78
+ '$';
79
+
80
+ if (allowDataUrl) {
81
+ // RFC 2397
82
+ var mediaType = '\\w+\\/[-+.\\w]+(?:;[\\w=]+)*';
83
+ var urlchar = "[A-Za-z0-9-_.!~\\*'();\\/?:@&=+$,%]*";
84
+ var dataurl = 'data:(?:' + mediaType + ')?(?:;base64)?,' + urlchar;
85
+ regex = '(?:' + regex + ')|(?:^' + dataurl + '$)';
86
+ }
87
+
88
+ return new RegExp(regex, 'i');
89
+ });
17
90
 
18
91
  export interface ValidateFn {
19
92
  (
@@ -55,12 +128,8 @@ export const validations: {
55
128
  /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i
56
129
  );
57
130
  },
58
- isUrl: function (values, value) {
59
- return validations.matchRegexp(
60
- values,
61
- value,
62
- /^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i
63
- );
131
+ isUrl: function (values, value, options) {
132
+ return validations.matchRegexp(values, value, makeUrlRegexp(options));
64
133
  },
65
134
  isTrue: function (values, value) {
66
135
  return value === true;
@@ -282,9 +351,8 @@ export function validate(
282
351
  }
283
352
 
284
353
  const fn = validations[ruleName];
285
- const args = (Array.isArray(rules[ruleName])
286
- ? rules[ruleName]
287
- : [rules[ruleName]]
354
+ const args = (
355
+ Array.isArray(rules[ruleName]) ? rules[ruleName] : [rules[ruleName]]
288
356
  ).map((item: any) => {
289
357
  if (typeof item === 'string' && isPureVariable(item)) {
290
358
  return resolveVariableAndFilter(item, values, '|raw');
@@ -356,9 +424,9 @@ const splitValidations = function (str: string): Array<string> {
356
424
  .map(str => (/^__\d+$/.test(str) ? placeholder[str] : str.trim()));
357
425
  };
358
426
 
359
- export function str2rules(
360
- validations: string | {[propName: string]: any}
361
- ): {[propName: string]: any} {
427
+ export function str2rules(validations: string | {[propName: string]: any}): {
428
+ [propName: string]: any;
429
+ } {
362
430
  if (typeof validations === 'string') {
363
431
  return validations
364
432
  ? splitValidations(validations).reduce(function (