-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
122 lines (99 loc) · 2.99 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/* global define */
;(function (global) {
'use strict'
const placeholderRegex = /([{}])\1|[{](.*?)(?:!(.+?))?[}]/g
const isNumericRegex = /^\d+$/
const commaSpaceRegex = /,\s*/g
const ERR_ARGS_ARRAY = 'replacements argument must be an array, not a parameter list'
const ERR_NUMBERING_MIX = 'cannot mix implicit & explicit formatting'
const defaultTo = (x, y) => y == null ? x : y
const parseMethodArgs = keyArray =>
keyArray
.slice(1)
.join(' ')
.split(commaSpaceRegex)
.map(v => {
if (v === '_') return null
if (v === '__') return '_'
return v
})
const lookup = (obj, path) => {
if (!isNumericRegex.test(path[0])) {
path = ['0'].concat(path)
}
for (const key of path) {
const keyArray = key.split(' ')
const fn = keyArray[0]
obj = typeof obj[fn] === 'function'
? obj[fn].apply(obj, parseMethodArgs(keyArray))
: obj[key]
}
return obj
}
function create (transformers) {
transformers = Object.assign({}, transformers)
return function reformat (template, replacements) {
if (replacements == null) {
const partial = r => reformat(template, r)
return Object.defineProperty(partial, 'raw', {
configurable: false,
enumerable: true,
get: () => template
})
}
if (!Array.isArray(replacements)) {
if (arguments.length > 2) {
throw new TypeError(ERR_ARGS_ARRAY)
}
// single argument provided, cast as array
replacements = [replacements]
}
let idx = 0
let state = 'UNDEFINED'
return template.replace(placeholderRegex, (match, literal, key, xf) => {
if (literal != null) return literal
if (key.length > 0) {
if (state === 'IMPLICIT') {
throw new Error(ERR_NUMBERING_MIX)
}
state = 'EXPLICIT'
} else {
if (state === 'EXPLICIT') {
throw new Error(ERR_NUMBERING_MIX)
}
state = 'IMPLICIT'
key = String(idx)
idx += 1
}
const value = defaultTo('', lookup(replacements, key.split('.')))
if (xf == null) {
return value
} else if (transformers.hasOwnProperty(xf)) {
return transformers[xf](value, key, replacements)
} else {
throw new Error(`no transformer named '${xf}'`)
}
})
}
}
const strat = create({})
strat.create = create
strat.extend = (prototype, transformers) => {
const format = create(transformers)
prototype.format = function (replacements) {
return format.apply(global, [this, replacements])
}
}
strat.errors = {
ERR_ARGS_ARRAY,
ERR_NUMBERING_MIX
}
if (typeof module !== 'undefined') {
module.exports = strat
module.exports.default = module.exports
} else if (typeof define === 'function' && define.amd) {
define(() => strat)
} else {
global.strat = strat
}
}.call(this, this))