@startlibs/utils 1.0.3 → 1.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.
Files changed (63) hide show
  1. package/lib/ActionUtils.mjs +117 -0
  2. package/lib/ActionUtils.mjs.map +1 -0
  3. package/lib/FetchUtils.mjs +100 -0
  4. package/lib/FetchUtils.mjs.map +1 -0
  5. package/lib/createPressEvent.mjs +74 -0
  6. package/lib/createPressEvent.mjs.map +1 -0
  7. package/lib/fixMediaQuery.mjs +64 -0
  8. package/lib/fixMediaQuery.mjs.map +1 -0
  9. package/lib/formatDate.mjs +110 -0
  10. package/lib/formatDate.mjs.map +1 -0
  11. package/lib/formatUtils.mjs +64 -0
  12. package/lib/formatUtils.mjs.map +1 -0
  13. package/lib/getClosestOffsetScroll.mjs +15 -0
  14. package/lib/getClosestOffsetScroll.mjs.map +1 -0
  15. package/lib/hooks/useEventListener.mjs +27 -0
  16. package/lib/hooks/useEventListener.mjs.map +1 -0
  17. package/lib/index.cjs +1811 -0
  18. package/lib/index.cjs.map +1 -0
  19. package/lib/index.mjs +19 -0
  20. package/lib/index.mjs.map +1 -0
  21. package/lib/lodashUtils.mjs +131 -0
  22. package/lib/lodashUtils.mjs.map +1 -0
  23. package/lib/promiseUtils.mjs +92 -0
  24. package/lib/promiseUtils.mjs.map +1 -0
  25. package/lib/reactUtils.mjs +12 -0
  26. package/lib/reactUtils.mjs.map +1 -0
  27. package/lib/reduceUtils.mjs +14 -0
  28. package/lib/reduceUtils.mjs.map +1 -0
  29. package/lib/smoothScroll.mjs +59 -0
  30. package/lib/smoothScroll.mjs.map +1 -0
  31. package/lib/styled.mjs +234 -0
  32. package/lib/styled.mjs.map +1 -0
  33. package/lib/timeUtils.mjs +81 -0
  34. package/lib/timeUtils.mjs.map +1 -0
  35. package/lib/timerUtils.mjs +11 -0
  36. package/lib/timerUtils.mjs.map +1 -0
  37. package/lib/utils.mjs +386 -0
  38. package/lib/utils.mjs.map +1 -0
  39. package/lib/wrapLazy.mjs +132 -0
  40. package/lib/wrapLazy.mjs.map +1 -0
  41. package/package.json +44 -30
  42. package/src/ActionUtils.js +90 -0
  43. package/src/FetchUtils.js +87 -0
  44. package/src/createPressEvent.jsx +79 -0
  45. package/src/fixMediaQuery.js +71 -0
  46. package/src/formatDate.js +121 -0
  47. package/src/formatUtils.jsx +63 -0
  48. package/src/getClosestOffsetScroll.js +12 -0
  49. package/src/hooks/useEventListener.js +26 -0
  50. package/src/index.js +19 -0
  51. package/src/lodashUtils.jsx +110 -0
  52. package/src/promiseUtils.jsx +75 -0
  53. package/src/reactUtils.jsx +7 -0
  54. package/src/reduceUtils.jsx +6 -0
  55. package/src/smoothScroll.js +58 -0
  56. package/src/styled.js +177 -0
  57. package/src/timeUtils.jsx +57 -0
  58. package/src/timerUtils.jsx +10 -0
  59. package/src/utils.jsx +342 -0
  60. package/src/wrapLazy.jsx +122 -0
  61. package/.babelrc +0 -26
  62. package/lib/index.js +0 -2382
  63. package/rollup.config.js +0 -44
package/src/utils.jsx ADDED
@@ -0,0 +1,342 @@
1
+ import {scrollWidth} from './fixMediaQuery'
2
+ import _ from 'lodash/fp'
3
+
4
+ export const formatPath = (...paths) => paths.map(path=>Array.isArray(path) ? path.join('.') : ( path ? path.toString().replace(/\[/g,'.').replace(/^\./,'').replace(/]/g,'') : '')).filter(_=>_).join('.')
5
+
6
+ export const identityFn = (n=0) => (...e) => e[n]
7
+
8
+ export const will = (fn,...props) => (...more) => fn(...props,...more)
9
+
10
+ export const lazyValue = (v) => () => v
11
+ export const callIfFunction = (prop,...args) => typeof prop === "function" ? prop(...args) : prop
12
+ export const callIfFunctions = (prop,...args) => typeof prop === "function" ? prop(...args.map((e)=>callIfFunction(e))) : prop
13
+ export const callMany = (...many) => (...args) => many.map(_=> callIfFunction(_,...args))
14
+ export const ifUndefined = (v,...or) => v !== undefined ? v : (or.length === 1 ? or[0] : ifUndefined(or[0],...or.slice(1)))
15
+ export const using = (...v) => (fn) => fn(...v.map((v) => callIfFunction(v)))
16
+
17
+ export const stopPropagation = (cb) => (e) => { (e && e.stopPropagation && e.stopPropagation()); callIfFunction(cb,e) }
18
+ export const preventDefault = (cb) => (e) => { (e && e.preventDefault && e.preventDefault()); callIfFunction(cb,e) }
19
+ export const constrainEvent = (cb) => (e) => { e?.preventDefault(); e.stopPropagation(); callIfFunction(cb,e) }
20
+
21
+ export const mapGetOrSet = (map,key,value) => (map.has(key) ? map : map.set(key, value)).get(key);
22
+
23
+ export const intToHour = (hour, autoFill = true) => {
24
+ if (hour === undefined || hour === null) return ''
25
+ if (hour === 0) { return "00:00"}
26
+
27
+ //const [h,m] = ('000' + hour.toString().replace(":","")).slice(-4).replace(/(\d\d)(\d\d)/, '$1:$2').split(":")
28
+
29
+ const h = hour.toString().replace(":","").slice(-4, -2)
30
+ const m = hour.toString().replace(":","").slice(-2)
31
+ if (callIfFunction(autoFill,hour)) {
32
+ return ('000' + (h ? parseInt(h,10) % 24 : '') + m).slice(-4).replace(/(\d\d)(\d\d)/, '$1:$2')
33
+ }
34
+ if (h) return (parseInt(h, 10) > 23 ? h.slice(1) : h) + ':' + m
35
+ return m
36
+ }
37
+ export const formatHour = (hour = "") => {
38
+ if (!hour) { return ""}
39
+ const h = hour.toString().replace(":","").slice(-4, -2)
40
+ const m = hour.toString().replace(":","").slice(-2)
41
+ if (!h && parseInt(m) < 24 && !_.isFinite(hour)) {
42
+ return m+":00"
43
+ } else if (h) {
44
+ return (parseInt(h, 10) > 23 ? h.slice(1) : h) + ':' + m
45
+ }
46
+ return ('000' + hour.toString().replace(":","")).slice(-4).replace(/(\d\d)(\d\d)/, '$1:$2')
47
+ }
48
+
49
+
50
+ export const willRafThrottle = () => {
51
+ let ticking = false;
52
+ return (fn) => {
53
+ if (!ticking) {
54
+ window.requestAnimationFrame(() => {
55
+ fn()
56
+ ticking = false;
57
+ });
58
+ ticking = true;
59
+ }
60
+ }
61
+ }
62
+
63
+ export const rafThrottle = (fn) => {
64
+ const throttle = willRafThrottle()
65
+ return () => {
66
+ throttle(fn)
67
+ }
68
+ }
69
+
70
+ export const intsToHour = ({open, close}) => intToHour(open) + ' - ' + intToHour(close)
71
+
72
+ export function isSmallDevice(width=600) {
73
+ const smallDeviceQuery = window.matchMedia ? window.matchMedia( `(max-width: ${width+scrollWidth}px)` ) : {matches:false}
74
+ return smallDeviceQuery.matches;
75
+ }
76
+
77
+ export function isHighDensity() {
78
+ return ((window.matchMedia && (window.matchMedia('only screen and (min-resolution: 124dpi), only screen and (min-resolution: 1.3dppx), only screen and (min-resolution: 48.8dpcm)').matches || window.matchMedia('only screen and (-webkit-min-device-pixel-ratio: 1.3), only screen and (-o-min-device-pixel-ratio: 2.6/2), only screen and (min--moz-device-pixel-ratio: 1.3), only screen and (min-device-pixel-ratio: 1.3)').matches)) || (window.devicePixelRatio && window.devicePixelRatio > 1.3))
79
+ }
80
+
81
+ export function isRetina() {
82
+ return ((window.matchMedia && (window.matchMedia('only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx), only screen and (min-resolution: 75.6dpcm)').matches || window.matchMedia('only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (min--moz-device-pixel-ratio: 2), only screen and (min-device-pixel-ratio: 2)').matches)) || (window.devicePixelRatio && window.devicePixelRatio >= 2)) && /(iPad|iPhone|iPod)/g.test(navigator.userAgent)
83
+ }
84
+
85
+ export function isMobile() {
86
+ if (typeof navigator === 'undefined') return false
87
+
88
+ const ua = navigator.userAgent
89
+
90
+ const isAndroid = /android/i.test(ua)
91
+ const isiOS = /iphone|ipod|ipad/i.test(ua)
92
+
93
+ // iPadOS 13+ reports "Macintosh" but has touch
94
+ const isIPadOS =
95
+ navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1
96
+
97
+ return isAndroid || isiOS || isIPadOS
98
+ }
99
+ export function isAndroid() {
100
+ if (navigator.userAgentData) {
101
+ return navigator.userAgentData.platform === "Android"
102
+ }
103
+ return /Android/i.test(navigator.userAgent)
104
+ }
105
+ export const isPWA = () => {
106
+ return (window.matchMedia && window.matchMedia("(display-mode: standalone)").matches)
107
+ || !!window.hasWebviewBridge
108
+ }
109
+
110
+ export function isTouchDevice() {
111
+ return window.document && 'ontouchstart' in window.document.documentElement;
112
+ }
113
+
114
+ export const isIOS = () => {
115
+ return /iPad|iPhone|iPod/.test(navigator.platform) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)
116
+ }
117
+ export const isIPad = () => {
118
+ return navigator.userAgent.match(/iPad/i) != null;
119
+ }
120
+
121
+ export const getNumberInputType2 = () => {
122
+ const isIOS = (/iPad|iPhone|iPod/.test(navigator.platform) || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1))
123
+ return isMobile() ? (isIOS ? "tel" : "number") : "text"
124
+ }
125
+ export const getNumberInputType = () => {
126
+ return "tel"
127
+ }
128
+
129
+ export function addHttp(s,secure) {
130
+ s = (s || '').trim()
131
+ if (s.indexOf('http://') === 0 || s.indexOf('https://') === 0) {
132
+ return s
133
+ } else {
134
+ return `http${secure ? 's': ''}://` + s
135
+ }
136
+ }
137
+
138
+ const protocols = '(^|\\s|\u00a0)(https?://)?(www\\.)?'
139
+ const subdomains = '([a-zA-Z0-9][a-zA-Z0-9-_]*[a-zA-Z0-9]?\\.)*'
140
+ const domain = '(([a-zA-Z]{1})|([a-zA-Z]{1}[a-zA-Z]{1})|([a-zA-Z]{1}[0-9]{1})|([0-9]{1}[a-zA-Z]{1})|([a-zA-Z0-9][a-zA-Z0-9-_]{1,61}[a-zA-Z0-9]))\\.([a-zA-Z]{2,6}|[a-zA-Z0-9-]{2,30}\\.[a-zA-Z]{2,3})'
141
+ const resource = '[\u00A1-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEFa-zA-Z0-9-._~:/?#%[\\]@!$&\'()*+,;=]*'
142
+ export const linkRegex = new RegExp(protocols + subdomains + domain + resource)
143
+
144
+ export function isUrl(url) {
145
+ return linkRegex.test(addHttp(url))
146
+ }
147
+
148
+ export function ellipsis(str = "", length) {
149
+ if (str.length > length) {
150
+ let words = str.slice(0, length).split(' ')
151
+ if (str.split(' ').indexOf(words[words.length - 1]) < 0)
152
+ words = words.slice(0, words.length - 1)
153
+ return words.join(' ') + '...'
154
+ } else
155
+ return str
156
+ }
157
+
158
+ export function safeNewLineToBr(str,keepMany) {
159
+ const result = (str||"").replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;')
160
+ if (keepMany===true) {
161
+ return result.replace(/\n/g,'<br/>')
162
+ }
163
+ return result.replace(/\n+/g,'<br/>')
164
+ }
165
+
166
+ function padGroups(pattern,value) {
167
+ return pattern.split('').reduce(([acc,value],char,i) => {
168
+ if (char === '0') {
169
+ const shouldHave = pattern.slice(i).search(/[^0#?*]/)
170
+ const has = value.slice(i).search(/\D/)
171
+ if (has > 0 && shouldHave > has) {
172
+ return [acc.concat('0'),acc.join('')+'0'+value.slice(i)]
173
+ } else {
174
+ return [acc.concat(value[i]),value]
175
+ }
176
+ } else {
177
+ return [acc.concat(value[i]),value]
178
+ }
179
+ },[[],value])[0].join('')
180
+ }
181
+
182
+ export const digitsToPattern = (patternWithLimit,optValue) => {
183
+ const value = optValue || ""
184
+ if (patternWithLimit[0] === '>' && Number(patternWithLimit.replace(/^>(\d*).*/g,"$1"))>value.length) return value
185
+ const pattern = patternWithLimit.replace(/^>\d+/,'')
186
+ const digits = padGroups(pattern,value).replace(/\D/g,'')
187
+ const totalRequired = pattern.split(/[0#]/).length-1
188
+ const totalOptional = pattern.split(/[?*]/).length-1
189
+ const available = digits.length-totalRequired
190
+
191
+ if (available>0 && totalOptional>0) {
192
+ let i = 0;
193
+ return digitsToPattern(
194
+ pattern
195
+ .replace(/\?/g,()=>i++<available?'#':'')
196
+ .replace('*',new Array(Math.max(0,available-i+1)).join("#")),
197
+ value
198
+ )
199
+ }
200
+ let i = 0
201
+ return pattern.replace(/^>\d*/,'').split('').reduce((acc,char)=> {
202
+ if (!digits[Math.max(i-1,0)] || char === '?' || char === '*') return acc
203
+ if (char==='#' || char=== '0') {
204
+ return acc+(digits[i++]||'')
205
+ } else {
206
+ return acc+char
207
+ }
208
+ },'')
209
+ }
210
+
211
+ export const normalizeTouch = (fn, endFn) => (e) => {
212
+ const touch = e.touches[0]
213
+ if (e.touches.length > 1 && e.type !== 'touchend') {
214
+ callIfFunction(endFn,e,touch)
215
+ } else {
216
+ callIfFunction(fn,e, touch)
217
+ }
218
+ }
219
+ export const normalizeMouse = (fn,endFn) => (e) => {
220
+ if (e.buttons>1 && e.type !== 'mouseup') {
221
+ callIfFunction(endFn,e,e)
222
+ } else {
223
+ callIfFunction(fn,e, e)
224
+ }
225
+ }
226
+
227
+ export const normalizePress = (fn,endFn) => (e) => {
228
+ if (e.touches) {
229
+ normalizeTouch(fn,endFn)(e)
230
+ } else {
231
+ normalizeMouse(fn,endFn)(e)
232
+ }
233
+ }
234
+
235
+
236
+ export const touchClick = (cb,sensibility = 5) => (e) => {
237
+ if (e.touches?.length !== 1) { return }
238
+ const target = e.target
239
+ const originalX = e.touches[0].screenX
240
+ const originalY = e.touches[0].screenY
241
+ const isInsideBounds = (touch) => Math.sqrt( Math.pow((originalX-touch.screenX), 2) + Math.pow((originalY-touch.screenY), 2) ) < sensibility
242
+
243
+ const checkBounds = (e) => {
244
+ if (e.touches.length !== 1) { return }
245
+ if (!isInsideBounds(e.changedTouches[0])) {
246
+ maybeClick()
247
+ }
248
+ }
249
+ const maybeClick = (e) => {
250
+ target.removeEventListener('touchend',maybeClick)
251
+ target.removeEventListener('touchmove',checkBounds)
252
+ if (e?.changedTouches?.length !== 1) { return }
253
+ if (isInsideBounds(e.changedTouches[0])) {
254
+ e.preventDefault()
255
+ cb(e)
256
+ }
257
+ }
258
+ target.addEventListener('touchend',maybeClick)
259
+ target.addEventListener('touchmove',checkBounds)
260
+ }
261
+
262
+
263
+ export const isEmptyHtml = (__html = "") => {
264
+ const a = document.createElement('span')
265
+ a.innerHTML = __html
266
+ return a.textContent.replace(/\s/g,'').length === 0
267
+ }
268
+
269
+
270
+ export const getScrollParent = (node) => {
271
+ if (!node) {
272
+ return window
273
+ }
274
+ const overflowY = window.getComputedStyle(node).overflowY
275
+ const isScrollable = overflowY !== 'visible' && overflowY !== 'hidden'
276
+ if (isScrollable && (node.scrollHeight > node.clientHeight || overflowY === 'scroll')) {
277
+ return node
278
+ } else {
279
+ return getScrollParent((node.offsetParent))
280
+ }
281
+ }
282
+
283
+ export const scrollIntoViewWithOffset = (el,offset) => {
284
+ const scrollOffset = getScrollParent(el)
285
+ const scrollY = scrollOffset === window ? window.pageYOffset : scrollOffset.scrollTop
286
+
287
+ const elTop = el.getBoundingClientRect().top
288
+ const computedOffset = callIfFunction(offset,elTop > 0)
289
+
290
+ const y = el.getBoundingClientRect().top + scrollY + computedOffset;
291
+
292
+ scrollOffset.scrollTo({top: y, behavior: 'smooth'});
293
+ }
294
+ export const isElementInView = async (element) => {
295
+ if (!element) return false;
296
+ if (1 !== element.nodeType) return false;
297
+
298
+ var html = document.documentElement;
299
+ var rect = element.getBoundingClientRect();
300
+ if (IntersectionObserver) {
301
+ return new Promise(resolve => {
302
+ const o = new IntersectionObserver(([entry]) => {
303
+ resolve(entry.intersectionRatio === 1);
304
+ o.disconnect();
305
+ });
306
+ o.observe(element);
307
+ });
308
+ }
309
+ return !!rect &&
310
+ rect.bottom >= 0 &&
311
+ rect.right >= 0 &&
312
+ rect.left <= html.clientWidth &&
313
+ rect.top <= html.clientHeight;
314
+ }
315
+
316
+
317
+ let i = 0
318
+ export const getUID = () => Date.now().toString(36)+Math.random().toString(36).slice(2)+(i++).toString(36)
319
+
320
+ export const getUrlParams = () => _.fromPairs(Array.from(new URLSearchParams(location.search).entries()))
321
+
322
+ export const isShallowEqualSameKeys = (a, b) => {
323
+ for(var key in a) {
324
+ if(a[key] !== b[key]) {
325
+ return false;
326
+ }
327
+ }
328
+ return true;
329
+ }
330
+ export const isShallowEqual = (a, b) => {
331
+ for(var key in a) {
332
+ if(!(key in b) || a[key] !== b[key]) {
333
+ return false;
334
+ }
335
+ }
336
+ for(var key in b) {
337
+ if(!(key in a) || a[key] !== b[key]) {
338
+ return false;
339
+ }
340
+ }
341
+ return true;
342
+ }
@@ -0,0 +1,122 @@
1
+ import React from 'react'
2
+ import _ from 'lodash/fp'
3
+ import {callIfFunction} from './utils'
4
+
5
+ // Suspense integrations like Relay implement
6
+ // a contract like this to integrate with React.
7
+ // Real implementations can be significantly more complex.
8
+ // Don't copy-paste this into your project!
9
+ const EMPTY_ARGS = []
10
+ const UNDEFINED_CURRENT_VALUE = {}
11
+ const innerWrapLazy = (refreshCallback) => (maybePromise, ...rootArgs) => {
12
+ let status;
13
+ let awaitReadResolver;
14
+ let checker = _.isEqual;
15
+ let lazyArgs = EMPTY_ARGS;
16
+ let uid = Math.random().toString()+Date.now();
17
+ let result;
18
+ let currentValue = UNDEFINED_CURRENT_VALUE
19
+
20
+ const promisify = (maybePromise,resolveNow) => {
21
+ return ((_.isFunction(maybePromise) && !resolveNow) ? new Promise(res => awaitReadResolver = res) : Promise.resolve())
22
+ .then((...args) => callIfFunction(maybePromise, ...rootArgs, ...lazyArgs, ...args))
23
+ }
24
+ const onPromiseSuccess = (returnedPromise) => r => {
25
+ if (returnedPromise !== suspender) {
26
+ return suspender
27
+ }
28
+ status = "success";
29
+ currentValue = r
30
+ result = r;
31
+ return r
32
+ }
33
+ const onPromiseError = (returnedPromise) => (e) => {
34
+ if (returnedPromise !== suspender) {
35
+ return suspender
36
+ }
37
+ status = "error";
38
+ result = e;
39
+ return Promise.reject(e)
40
+ }
41
+
42
+ const suspend = (maybePromise) => {
43
+ status = "pending"
44
+ awaitReadResolver = _.identity
45
+ const returnedPromise = promisify(maybePromise)
46
+ returnedPromise.then(onPromiseSuccess(returnedPromise), onPromiseError(returnedPromise));
47
+ return returnedPromise;
48
+ }
49
+
50
+ let suspender = suspend(maybePromise)
51
+
52
+ return {
53
+ read() {
54
+ awaitReadResolver()
55
+ if (status === "pending") {
56
+ throw suspender;
57
+ } else if (status === "error") {
58
+ throw result;
59
+ } else if (status === "success") {
60
+ return currentValue;
61
+ }
62
+ },
63
+ promise() {
64
+ awaitReadResolver()
65
+ return suspender
66
+ },
67
+ refresh(force) {
68
+ if (status !== "pending" || force) {
69
+ suspender = suspend(maybePromise)
70
+ uid = Math.random().toString()+Date.now();
71
+ callIfFunction(refreshCallback,this)
72
+ }
73
+ return this
74
+ },
75
+ next(...args) {
76
+ return wrapLazy(maybePromise, ...rootArgs, ...args).checkWith(checker)
77
+ },
78
+ use(...args) {
79
+ if (!checker(args, lazyArgs)) {
80
+ if (lazyArgs !== EMPTY_ARGS) {
81
+ uid = Math.random().toString()+Date.now();
82
+ }
83
+ lazyArgs = args
84
+ suspender = suspend(maybePromise)
85
+ }
86
+ return this
87
+ },
88
+ _getCurrentValue() {
89
+ return currentValue
90
+ },
91
+ silentRefresh() {
92
+ const currentSuspender = suspender
93
+ const suspended = promisify(maybePromise,true).then((v) => {
94
+ if (currentSuspender === suspender) {
95
+ suspender = suspended
96
+ }
97
+ return v
98
+ })
99
+ suspended.then(onPromiseSuccess(suspended),onPromiseError(suspended))
100
+ uid = Math.random().toString()+Date.now();
101
+ callIfFunction(refreshCallback,this)
102
+ return suspended
103
+ },
104
+ and(lazy) {
105
+
106
+ },
107
+ checkWith(isEqual) {
108
+ checker = isEqual
109
+ return this
110
+ },
111
+ localUpdate(updater) {
112
+ currentValue = callIfFunction(updater,currentValue)
113
+ return this
114
+ },
115
+ uid() {
116
+ return uid
117
+ }
118
+ }
119
+ }
120
+ const UNMOUNTED = {}
121
+
122
+ export const wrapLazy = innerWrapLazy()
package/.babelrc DELETED
@@ -1,26 +0,0 @@
1
- // .babelrc
2
- {
3
- "presets": [
4
- "@babel/preset-react",
5
- "@babel/preset-flow",
6
- ["@babel/preset-env", {
7
- "exclude": ["@babel/plugin-proposal-unicode-property-regex", "@babel/plugin-transform-unicode-regex"],
8
- "modules": false
9
- }
10
- ]
11
- ],
12
- "plugins": [
13
- "lodash",
14
- "macros",
15
- "fbjs-scripts/babel-6/dev-expression",
16
- "@babel/plugin-proposal-export-namespace-from",
17
- "@babel/plugin-proposal-throw-expressions",
18
- "@babel/plugin-syntax-import-meta",
19
- "@babel/plugin-proposal-json-strings",
20
- "@babel/plugin-syntax-dynamic-import",
21
- "@babel/plugin-transform-arrow-functions",
22
- "@babel/plugin-transform-spread",
23
- "@babel/plugin-proposal-object-rest-spread",
24
- ["@babel/plugin-proposal-class-properties", {"loose": true}]
25
- ]
26
- }