Skip to content

Commit 5d8ab20

Browse files
committed
Remove the legacy methods from the default methods javascript file
1 parent 4422db5 commit 5d8ab20

File tree

2 files changed

+161
-162
lines changed

2 files changed

+161
-162
lines changed

defaultMethods.js

Lines changed: 5 additions & 162 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import declareSync from './utilities/declareSync.js'
77
import { build, buildString } from './compiler.js'
88
import chainingSupported from './utilities/chainingSupported.js'
99
import InvalidControlInput from './errors/InvalidControlInput.js'
10-
import { splitPathMemoized } from './utilities/splitPath.js'
10+
import legacyMethods from './legacy.js'
1111

1212
function isDeterministic (method, engine, buildState) {
1313
if (Array.isArray(method)) {
@@ -278,26 +278,6 @@ const defaultMethods = {
278278
if (i && typeof i === 'object') return Object.keys(i).length
279279
return 0
280280
},
281-
get: {
282-
method: ([data, key, defaultValue], context, above, engine) => {
283-
const notFound = defaultValue === undefined ? null : defaultValue
284-
285-
const subProps = splitPathMemoized(String(key))
286-
for (let i = 0; i < subProps.length; i++) {
287-
if (data === null || data === undefined) {
288-
return notFound
289-
}
290-
// Descending into context
291-
data = data[subProps[i]]
292-
if (data === undefined) {
293-
return notFound
294-
}
295-
}
296-
if (engine.allowFunctions || typeof data[key] !== 'function') {
297-
return data
298-
}
299-
}
300-
},
301281
exists: {
302282
method: (key, context, above, engine) => {
303283
const result = defaultMethods.val.method(key, context, above, engine, Unfound)
@@ -384,64 +364,6 @@ const defaultMethods = {
384364
return false
385365
}
386366
},
387-
var: (key, context, above, engine) => {
388-
let b
389-
if (Array.isArray(key)) {
390-
b = key[1]
391-
key = key[0]
392-
}
393-
let iter = 0
394-
while (
395-
typeof key === 'string' &&
396-
key.startsWith('../') &&
397-
iter < above.length
398-
) {
399-
context = above[iter++]
400-
key = key.substring(3)
401-
// A performance optimization that allows you to pass the previous above array without spreading it as the last argument
402-
if (iter === above.length && Array.isArray(context)) {
403-
iter = 0
404-
above = context
405-
context = above[iter++]
406-
}
407-
}
408-
409-
const notFound = b === undefined ? null : b
410-
if (typeof key === 'undefined' || key === '' || key === null) {
411-
if (engine.allowFunctions || typeof context !== 'function') {
412-
return context
413-
}
414-
return null
415-
}
416-
const subProps = splitPathMemoized(String(key))
417-
for (let i = 0; i < subProps.length; i++) {
418-
if (context === null || context === undefined) {
419-
return notFound
420-
}
421-
// Descending into context
422-
context = context[subProps[i]]
423-
if (context === undefined) {
424-
return notFound
425-
}
426-
}
427-
if (engine.allowFunctions || typeof context !== 'function') {
428-
return context
429-
}
430-
return null
431-
},
432-
missing: (checked, context, above, engine) => {
433-
return (Array.isArray(checked) ? checked : [checked]).filter((key) => {
434-
return defaultMethods.var(key, context, above, engine) === null
435-
})
436-
},
437-
missing_some: ([needCount, options], context, above, engine) => {
438-
const missing = defaultMethods.missing(options, context, above, engine)
439-
if (options.length - missing.length >= needCount) {
440-
return []
441-
} else {
442-
return missing
443-
}
444-
},
445367
map: createArrayIterativeMethod('map'),
446368
some: createArrayIterativeMethod('some', true),
447369
all: createArrayIterativeMethod('every', true),
@@ -745,16 +667,7 @@ Object.keys(defaultMethods).forEach((item) => {
745667
? true
746668
: defaultMethods[item].deterministic
747669
})
748-
// @ts-ignore Allow custom attribute
749-
defaultMethods.var.deterministic = (data, buildState) => {
750-
return buildState.insideIterator && !String(data).includes('../../')
751-
}
752-
Object.assign(defaultMethods.missing, {
753-
deterministic: false
754-
})
755-
Object.assign(defaultMethods.missing_some, {
756-
deterministic: false
757-
})
670+
758671
// @ts-ignore Allow custom attribute
759672
defaultMethods['<'].compile = function (data, buildState) {
760673
if (!Array.isArray(data)) return false
@@ -926,81 +839,11 @@ defaultMethods['!!'].compile = function (data, buildState) {
926839
return `(!!engine.truthy(${data}))`
927840
}
928841
defaultMethods.none.deterministic = defaultMethods.some.deterministic
929-
defaultMethods.get.compile = function (data, buildState) {
930-
let defaultValue = null
931-
let key = data
932-
let obj = null
933-
if (Array.isArray(data) && data.length <= 3) {
934-
obj = data[0]
935-
key = data[1]
936-
defaultValue = typeof data[2] === 'undefined' ? null : data[2]
937-
938-
// Bail out if the key is dynamic; dynamic keys are not really optimized by this block.
939-
if (key && typeof key === 'object') return false
940-
941-
key = key.toString()
942-
const pieces = splitPathMemoized(key)
943-
if (!chainingSupported) {
944-
return `(((a,b) => (typeof a === 'undefined' || a === null) ? b : a)(${pieces.reduce(
945-
(text, i) => {
946-
return `(${text}||0)[${JSON.stringify(i)}]`
947-
},
948-
`(${buildString(obj, buildState)}||0)`
949-
)}, ${buildString(defaultValue, buildState)}))`
950-
}
951-
return `((${buildString(obj, buildState)})${pieces
952-
.map((i) => `?.[${buildString(i, buildState)}]`)
953-
.join('')} ?? ${buildString(defaultValue, buildState)})`
954-
}
955-
return false
956-
}
957-
// @ts-ignore Allow custom attribute
958-
defaultMethods.var.compile = function (data, buildState) {
959-
let key = data
960-
let defaultValue = null
961-
if (
962-
!key ||
963-
typeof data === 'string' ||
964-
typeof data === 'number' ||
965-
(Array.isArray(data) && data.length <= 2)
966-
) {
967-
if (Array.isArray(data)) {
968-
key = data[0]
969-
defaultValue = typeof data[1] === 'undefined' ? null : data[1]
970-
}
971-
972-
if (key === '../index' && buildState.iteratorCompile) return 'index'
973-
974-
// this counts the number of var accesses to determine if they're all just using this override.
975-
// this allows for a small optimization :)
976-
if (typeof key === 'undefined' || key === null || key === '') return 'context'
977-
if (typeof key !== 'string' && typeof key !== 'number') return false
978-
979-
key = key.toString()
980-
if (key.includes('../')) return false
981-
982-
const pieces = splitPathMemoized(key)
983-
984-
if (!buildState.engine.allowFunctions) buildState.methods.preventFunctions = a => typeof a === 'function' ? null : a
985-
else buildState.methods.preventFunctions = a => a
986-
987-
// support older versions of node
988-
if (!chainingSupported) {
989-
return `(methods.preventFunctions(((a,b) => (typeof a === 'undefined' || a === null) ? b : a)(${pieces.reduce(
990-
(text, i) => `(${text}||0)[${JSON.stringify(i)}]`,
991-
'(context||0)'
992-
)}, ${buildString(defaultValue, buildState)})))`
993-
}
994-
return `(methods.preventFunctions(context${pieces
995-
.map((i) => `?.[${JSON.stringify(i)}]`)
996-
.join('')} ?? ${buildString(defaultValue, buildState)}))`
997-
}
998-
return false
999-
}
1000842

1001843
// @ts-ignore Allowing a optimizeUnary attribute that can be used for performance optimizations
1002-
defaultMethods['+'].optimizeUnary = defaultMethods['-'].optimizeUnary = defaultMethods.var.optimizeUnary = defaultMethods['!'].optimizeUnary = defaultMethods['!!'].optimizeUnary = defaultMethods.cat.optimizeUnary = true
844+
defaultMethods['+'].optimizeUnary = defaultMethods['-'].optimizeUnary = defaultMethods['!'].optimizeUnary = defaultMethods['!!'].optimizeUnary = defaultMethods.cat.optimizeUnary = true
1003845

1004846
export default {
1005-
...defaultMethods
847+
...defaultMethods,
848+
...legacyMethods
1006849
}

legacy.js

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
import { buildString } from './compiler.js'
2+
import { splitPathMemoized } from './utilities/splitPath.js'
3+
import chainingSupported from './utilities/chainingSupported.js'
4+
import { Sync } from './constants.js'
5+
6+
const legacyMethods = {
7+
get: {
8+
[Sync]: true,
9+
method: ([data, key, defaultValue], context, above, engine) => {
10+
const notFound = defaultValue === undefined ? null : defaultValue
11+
12+
const subProps = splitPathMemoized(String(key))
13+
for (let i = 0; i < subProps.length; i++) {
14+
if (data === null || data === undefined) return notFound
15+
// Descending into context
16+
data = data[subProps[i]]
17+
if (data === undefined) return notFound
18+
}
19+
20+
if (engine.allowFunctions || typeof data[key] !== 'function') return data
21+
return null
22+
},
23+
deterministic: true,
24+
compile: (data, buildState) => {
25+
let defaultValue = null
26+
let key = data
27+
let obj = null
28+
if (Array.isArray(data) && data.length <= 3) {
29+
obj = data[0]
30+
key = data[1]
31+
defaultValue = typeof data[2] === 'undefined' ? null : data[2]
32+
33+
// Bail out if the key is dynamic; dynamic keys are not really optimized by this block.
34+
if (key && typeof key === 'object') return false
35+
36+
key = key.toString()
37+
const pieces = splitPathMemoized(key)
38+
if (!chainingSupported) {
39+
return `(((a,b) => (typeof a === 'undefined' || a === null) ? b : a)(${pieces.reduce(
40+
(text, i) => `(${text}||0)[${JSON.stringify(i)}]`,
41+
`(${buildString(obj, buildState)}||0)`
42+
)}, ${buildString(defaultValue, buildState)}))`
43+
}
44+
return `((${buildString(obj, buildState)})${pieces
45+
.map((i) => `?.[${buildString(i, buildState)}]`)
46+
.join('')} ?? ${buildString(defaultValue, buildState)})`
47+
}
48+
return false
49+
}
50+
},
51+
var: {
52+
[Sync]: true,
53+
method: (key, context, above, engine) => {
54+
let b
55+
if (Array.isArray(key)) {
56+
b = key[1]
57+
key = key[0]
58+
}
59+
let iter = 0
60+
while (typeof key === 'string' && key.startsWith('../') && iter < above.length) {
61+
context = above[iter++]
62+
key = key.substring(3)
63+
// A performance optimization that allows you to pass the previous above array without spreading it as the last argument
64+
if (iter === above.length && Array.isArray(context)) {
65+
iter = 0
66+
above = context
67+
context = above[iter++]
68+
}
69+
}
70+
71+
const notFound = b === undefined ? null : b
72+
if (typeof key === 'undefined' || key === '' || key === null) {
73+
if (engine.allowFunctions || typeof context !== 'function') return context
74+
return null
75+
}
76+
const subProps = splitPathMemoized(String(key))
77+
for (let i = 0; i < subProps.length; i++) {
78+
if (context === null || context === undefined) return notFound
79+
80+
// Descending into context
81+
context = context[subProps[i]]
82+
if (context === undefined) return notFound
83+
}
84+
85+
if (engine.allowFunctions || typeof context !== 'function') return context
86+
return null
87+
},
88+
deterministic: (data, buildState) => buildState.insideIterator && !String(data).includes('../../'),
89+
optimizeUnary: true,
90+
compile: (data, buildState) => {
91+
let key = data
92+
let defaultValue = null
93+
if (
94+
!key ||
95+
typeof data === 'string' ||
96+
typeof data === 'number' ||
97+
(Array.isArray(data) && data.length <= 2)
98+
) {
99+
if (Array.isArray(data)) {
100+
key = data[0]
101+
defaultValue = typeof data[1] === 'undefined' ? null : data[1]
102+
}
103+
104+
if (key === '../index' && buildState.iteratorCompile) return 'index'
105+
106+
// this counts the number of var accesses to determine if they're all just using this override.
107+
// this allows for a small optimization :)
108+
if (typeof key === 'undefined' || key === null || key === '') return 'context'
109+
if (typeof key !== 'string' && typeof key !== 'number') return false
110+
111+
key = key.toString()
112+
if (key.includes('../')) return false
113+
114+
const pieces = splitPathMemoized(key)
115+
116+
if (!buildState.engine.allowFunctions) buildState.methods.preventFunctions = a => typeof a === 'function' ? null : a
117+
else buildState.methods.preventFunctions = a => a
118+
119+
// support older versions of node
120+
if (!chainingSupported) {
121+
return `(methods.preventFunctions(((a,b) => (typeof a === 'undefined' || a === null) ? b : a)(${pieces.reduce(
122+
(text, i) => `(${text}||0)[${JSON.stringify(i)}]`,
123+
'(context||0)'
124+
)}, ${buildString(defaultValue, buildState)})))`
125+
}
126+
return `(methods.preventFunctions(context${pieces
127+
.map((i) => `?.[${JSON.stringify(i)}]`)
128+
.join('')} ?? ${buildString(defaultValue, buildState)}))`
129+
}
130+
return false
131+
}
132+
},
133+
missing: {
134+
[Sync]: true,
135+
method: (checked, context, above, engine) => {
136+
return (Array.isArray(checked) ? checked : [checked]).filter((key) => {
137+
return legacyMethods.var.method(key, context, above, engine) === null
138+
})
139+
},
140+
deterministic: false
141+
},
142+
missing_some: {
143+
[Sync]: true,
144+
method: ([needCount, options], context, above, engine) => {
145+
const missing = legacyMethods.missing.method(options, context, above, engine)
146+
if (options.length - missing.length >= needCount) {
147+
return []
148+
} else {
149+
return missing
150+
}
151+
},
152+
deterministic: false
153+
}
154+
}
155+
156+
export default legacyMethods

0 commit comments

Comments
 (0)