@shwfed/nuxt 0.7.8 → 0.7.9
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/dist/module.json +1 -1
- package/dist/runtime/components/app.d.vue.ts +0 -2
- package/dist/runtime/components/app.vue +1 -7
- package/dist/runtime/components/app.vue.d.ts +0 -2
- package/dist/runtime/components/fields.d.vue.ts +155 -0
- package/dist/runtime/components/fields.vue +312 -0
- package/dist/runtime/components/fields.vue.d.ts +155 -0
- package/dist/runtime/components/ui/button-group/ButtonGroupSeparator.vue +1 -1
- package/dist/runtime/components/ui/button-group/ButtonGroupText.vue +1 -1
- package/dist/runtime/components/ui/calendar/Calendar.d.vue.ts +5 -12
- package/dist/runtime/components/ui/calendar/Calendar.vue +77 -92
- package/dist/runtime/components/ui/calendar/Calendar.vue.d.ts +5 -12
- package/dist/runtime/components/ui/calendar/CalendarCellTrigger.vue +1 -1
- package/dist/runtime/components/ui/calendar/index.d.ts +1 -1
- package/dist/runtime/components/ui/command/CommandGroup.vue +4 -0
- package/dist/runtime/components/ui/dialog/DialogOverlay.vue +1 -1
- package/dist/runtime/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue +1 -1
- package/dist/runtime/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue +1 -1
- package/dist/runtime/components/ui/field/FieldDescription.vue +1 -1
- package/dist/runtime/components/ui/field/FieldError.vue +1 -1
- package/dist/runtime/components/ui/field/FieldLabel.vue +1 -1
- package/dist/runtime/components/ui/field/FieldSeparator.vue +1 -1
- package/dist/runtime/components/ui/field/index.js +7 -5
- package/dist/runtime/components/ui/input/Input.vue +1 -1
- package/dist/runtime/components/ui/input-group/InputGroup.vue +3 -0
- package/dist/runtime/components/ui/input-group/InputGroupCombobox.d.vue.ts +4 -1
- package/dist/runtime/components/ui/input-group/InputGroupCombobox.vue +10 -4
- package/dist/runtime/components/ui/input-group/InputGroupCombobox.vue.d.ts +4 -1
- package/dist/runtime/components/ui/input-group/InputGroupComboboxInput.vue +3 -1
- package/dist/runtime/components/ui/input-group/InputGroupInput.vue +1 -1
- package/dist/runtime/components/ui/input-group/InputGroupNumberField.vue +1 -1
- package/dist/runtime/components/ui/input-group/InputGroupText.vue +1 -1
- package/dist/runtime/components/ui/input-group/InputGroupTextarea.vue +1 -1
- package/dist/runtime/components/ui/input-group/index.js +1 -1
- package/dist/runtime/components/ui/label/Label.vue +1 -1
- package/dist/runtime/components/ui/native-select/NativeSelect.vue +3 -3
- package/dist/runtime/components/ui/navigation-menu/NavigationMenuLink.vue +1 -1
- package/dist/runtime/components/ui/navigation-menu/NavigationMenuViewport.vue +1 -1
- package/dist/runtime/components/ui/range-calendar/RangeCalendarCell.vue +1 -1
- package/dist/runtime/components/ui/range-calendar/RangeCalendarCellTrigger.vue +1 -1
- package/dist/runtime/components/ui/sheet/SheetOverlay.vue +1 -1
- package/dist/runtime/components/ui/switch/Switch.d.vue.ts +24 -0
- package/dist/runtime/components/ui/switch/Switch.vue +46 -0
- package/dist/runtime/components/ui/switch/Switch.vue.d.ts +24 -0
- package/dist/runtime/components/ui/switch/index.d.ts +1 -0
- package/dist/runtime/components/ui/switch/index.js +1 -0
- package/dist/runtime/components/ui/textarea/Textarea.vue +1 -1
- package/dist/runtime/plugins/cel/env.d.ts +2 -2
- package/dist/runtime/plugins/cel/env.js +5 -4
- package/dist/runtime/plugins/cel/index.d.ts +3 -3
- package/dist/runtime/plugins/cel/index.js +7 -3
- package/dist/runtime/plugins/markdown/index.d.ts +1 -1
- package/dist/runtime/utils/coders.d.ts +7 -0
- package/dist/runtime/utils/coders.js +39 -0
- package/dist/runtime/vendor/cel/index.d.ts +17 -0
- package/dist/runtime/vendor/cel/index.js +10 -0
- package/dist/runtime/vendor/cel-js/LICENSE +21 -0
- package/dist/runtime/vendor/cel-js/UPSTREAM.md +17 -0
- package/dist/runtime/vendor/cel-js/lib/errors.d.ts +21 -0
- package/dist/runtime/vendor/cel-js/lib/errors.js +97 -0
- package/dist/runtime/vendor/cel-js/lib/evaluator.d.ts +4 -0
- package/dist/runtime/vendor/cel-js/lib/evaluator.js +192 -0
- package/dist/runtime/vendor/cel-js/lib/functions.d.ts +53 -0
- package/dist/runtime/vendor/cel-js/lib/functions.js +513 -0
- package/dist/runtime/vendor/cel-js/lib/globals.d.ts +27 -0
- package/dist/runtime/vendor/cel-js/lib/globals.js +33 -0
- package/dist/runtime/vendor/cel-js/lib/index.d.ts +469 -0
- package/dist/runtime/vendor/cel-js/lib/index.js +18 -0
- package/dist/runtime/vendor/cel-js/lib/macros.d.ts +1 -0
- package/dist/runtime/vendor/cel-js/lib/macros.js +230 -0
- package/dist/runtime/vendor/cel-js/lib/operators.d.ts +117 -0
- package/dist/runtime/vendor/cel-js/lib/operators.js +739 -0
- package/dist/runtime/vendor/cel-js/lib/optional.d.ts +14 -0
- package/dist/runtime/vendor/cel-js/lib/optional.js +161 -0
- package/dist/runtime/vendor/cel-js/lib/options.d.ts +23 -0
- package/dist/runtime/vendor/cel-js/lib/options.js +47 -0
- package/dist/runtime/vendor/cel-js/lib/overloads.d.ts +1 -0
- package/dist/runtime/vendor/cel-js/lib/overloads.js +214 -0
- package/dist/runtime/vendor/cel-js/lib/parser.d.ts +56 -0
- package/dist/runtime/vendor/cel-js/lib/parser.js +827 -0
- package/dist/runtime/vendor/cel-js/lib/registry.d.ts +279 -0
- package/dist/runtime/vendor/cel-js/lib/registry.js +1596 -0
- package/dist/runtime/vendor/cel-js/lib/serialize.d.ts +1 -0
- package/dist/runtime/vendor/cel-js/lib/serialize.js +259 -0
- package/dist/runtime/vendor/cel-js/lib/type-checker.d.ts +26 -0
- package/dist/runtime/vendor/cel-js/lib/type-checker.js +81 -0
- package/package.json +7 -4
- package/dist/runtime/components/locale.d.vue.ts +0 -14
- package/dist/runtime/components/locale.vue +0 -89
- package/dist/runtime/components/locale.vue.d.ts +0 -14
- package/dist/runtime/components/query.d.vue.ts +0 -30
- package/dist/runtime/components/query.vue +0 -266
- package/dist/runtime/components/query.vue.d.ts +0 -30
- package/dist/runtime/utilities/query-config/global.d.ts +0 -4
- package/dist/runtime/utilities/query-config/global.js +0 -18
- package/dist/runtime/utilities/query-config/index.d.ts +0 -3
- package/dist/runtime/utilities/query-config/index.js +0 -14
- package/dist/runtime/utilities/query-config/schema.d.ts +0 -96
- package/dist/runtime/utilities/query-config/schema.js +0 -51
|
@@ -0,0 +1,513 @@
|
|
|
1
|
+
import {EvaluationError} from './errors.js'
|
|
2
|
+
import {TYPES, Type} from './registry.js'
|
|
3
|
+
import {register as registerOptional} from './optional.js'
|
|
4
|
+
import {objKeys, arrayFrom} from './globals.js'
|
|
5
|
+
|
|
6
|
+
const MIN_UINT = 0n
|
|
7
|
+
const MAX_UINT = 18446744073709551615n
|
|
8
|
+
|
|
9
|
+
export class UnsignedInt {
|
|
10
|
+
#value
|
|
11
|
+
constructor(value) {
|
|
12
|
+
this.verify(typeof value === 'bigint' ? value : BigInt(value))
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
get value() {
|
|
16
|
+
return this.#value
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
valueOf() {
|
|
20
|
+
return this.#value
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
toString() {
|
|
24
|
+
return `${this.#value}`
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
verify(v) {
|
|
28
|
+
if (v < MIN_UINT || v > MAX_UINT) throw new EvaluationError('Unsigned integer overflow')
|
|
29
|
+
this.#value = v
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
get [Symbol.toStringTag]() {
|
|
33
|
+
return `value = ${this.#value}`
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
[Symbol.for('nodejs.util.inspect.custom')]() {
|
|
37
|
+
return `UnsignedInteger { value: ${this.#value} }`
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const UNIT_NANOSECONDS = {
|
|
42
|
+
h: 3600000000000n,
|
|
43
|
+
m: 60000000000n,
|
|
44
|
+
s: 1000000000n,
|
|
45
|
+
ms: 1000000n,
|
|
46
|
+
us: 1000n,
|
|
47
|
+
µs: 1000n,
|
|
48
|
+
ns: 1n
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export class Duration {
|
|
52
|
+
#seconds
|
|
53
|
+
#nanos
|
|
54
|
+
|
|
55
|
+
constructor(seconds, nanos = 0) {
|
|
56
|
+
this.#seconds = BigInt(seconds)
|
|
57
|
+
this.#nanos = nanos
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
get seconds() {
|
|
61
|
+
return this.#seconds
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
get nanos() {
|
|
65
|
+
return this.#nanos
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
valueOf() {
|
|
69
|
+
return Number(this.#seconds) * 1000 + this.#nanos / 1000000
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
static fromMilliseconds(ms) {
|
|
73
|
+
const totalNanos = BigInt(Math.trunc(ms * 1_000_000))
|
|
74
|
+
const seconds = totalNanos / 1_000_000_000n
|
|
75
|
+
const nanos = Number(totalNanos % 1_000_000_000n)
|
|
76
|
+
return new Duration(seconds, nanos)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
addDuration(other) {
|
|
80
|
+
const nanos = this.#nanos + other.nanos
|
|
81
|
+
return new Duration(
|
|
82
|
+
this.#seconds + other.seconds + BigInt(Math.floor(nanos / 1_000_000_000)),
|
|
83
|
+
nanos % 1_000_000_000
|
|
84
|
+
)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
subtractDuration(other) {
|
|
88
|
+
const nanos = this.#nanos - other.nanos
|
|
89
|
+
return new Duration(
|
|
90
|
+
this.#seconds - other.seconds + BigInt(Math.floor(nanos / 1_000_000_000)),
|
|
91
|
+
(nanos + 1_000_000_000) % 1_000_000_000
|
|
92
|
+
)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
extendTimestamp(ts) {
|
|
96
|
+
return new Date(
|
|
97
|
+
ts.getTime() + Number(this.#seconds) * 1000 + Math.floor(this.#nanos / 1_000_000)
|
|
98
|
+
)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
subtractTimestamp(ts) {
|
|
102
|
+
return new Date(
|
|
103
|
+
ts.getTime() - Number(this.#seconds) * 1000 - Math.floor(this.#nanos / 1_000_000)
|
|
104
|
+
)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
toString() {
|
|
108
|
+
const nanos = this.#nanos
|
|
109
|
+
? (this.#nanos / 1000000000)
|
|
110
|
+
.toLocaleString('en-US', {useGrouping: false, maximumFractionDigits: 9})
|
|
111
|
+
.slice(1)
|
|
112
|
+
: ''
|
|
113
|
+
return `${this.#seconds}${nanos}s`
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
getHours() {
|
|
117
|
+
return this.#seconds / 3600n
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
getMinutes() {
|
|
121
|
+
return this.#seconds / 60n
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
getSeconds() {
|
|
125
|
+
return this.#seconds
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
getMilliseconds() {
|
|
129
|
+
return this.#seconds * 1000n + BigInt(Math.floor(this.#nanos / 1000000))
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
get [Symbol.toStringTag]() {
|
|
133
|
+
return 'google.protobuf.Duration'
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
[Symbol.for('nodejs.util.inspect.custom')]() {
|
|
137
|
+
return `google.protobuf.Duration { seconds: ${this.#seconds}, nanos: ${this.#nanos} }`
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export function registerFunctions(registry) {
|
|
142
|
+
const sync = {async: false}
|
|
143
|
+
const functionOverload = (sig, handler) => registry.registerFunctionOverload(sig, handler, sync)
|
|
144
|
+
const identity = (v) => v
|
|
145
|
+
|
|
146
|
+
functionOverload('dyn(dyn): dyn', identity)
|
|
147
|
+
|
|
148
|
+
for (const _t in TYPES) {
|
|
149
|
+
const type = TYPES[_t]
|
|
150
|
+
if (!(type instanceof Type)) continue
|
|
151
|
+
functionOverload(`type(${type.name}): type`, () => type)
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
functionOverload('bool(bool): bool', identity)
|
|
155
|
+
functionOverload('bool(string): bool', (v) => {
|
|
156
|
+
switch (v) {
|
|
157
|
+
case '1':
|
|
158
|
+
case 't':
|
|
159
|
+
case 'true':
|
|
160
|
+
case 'TRUE':
|
|
161
|
+
case 'True':
|
|
162
|
+
return true
|
|
163
|
+
case '0':
|
|
164
|
+
case 'f':
|
|
165
|
+
case 'false':
|
|
166
|
+
case 'FALSE':
|
|
167
|
+
case 'False':
|
|
168
|
+
return false
|
|
169
|
+
default:
|
|
170
|
+
throw new EvaluationError(`bool() conversion error: invalid string value "${v}"`)
|
|
171
|
+
}
|
|
172
|
+
})
|
|
173
|
+
|
|
174
|
+
functionOverload('size(string): int', (v) => BigInt(stringSize(v)))
|
|
175
|
+
functionOverload('size(bytes): int', (v) => BigInt(v.length))
|
|
176
|
+
functionOverload('size(list): int', (v) => BigInt(v.length ?? v.size))
|
|
177
|
+
functionOverload('size(map): int', (v) => BigInt(v instanceof Map ? v.size : objKeys(v).length))
|
|
178
|
+
functionOverload('string.size(): int', (v) => BigInt(stringSize(v)))
|
|
179
|
+
functionOverload('bytes.size(): int', (v) => BigInt(v.length))
|
|
180
|
+
functionOverload('list.size(): int', (v) => BigInt(v.length ?? v.size))
|
|
181
|
+
functionOverload('map.size(): int', (v) => BigInt(v instanceof Map ? v.size : objKeys(v).length))
|
|
182
|
+
|
|
183
|
+
functionOverload('bytes(string): bytes', (v) => ByteOpts.fromString(v))
|
|
184
|
+
functionOverload('bytes(bytes): bytes', identity)
|
|
185
|
+
|
|
186
|
+
functionOverload('double(double): double', identity)
|
|
187
|
+
functionOverload('double(int): double', (v) => Number(v))
|
|
188
|
+
functionOverload('double(uint): double', (v) => Number(v))
|
|
189
|
+
functionOverload('double(string): double', (v) => {
|
|
190
|
+
if (!v || v !== v.trim())
|
|
191
|
+
throw new EvaluationError('double() type error: cannot convert to double')
|
|
192
|
+
|
|
193
|
+
const s = v.toLowerCase()
|
|
194
|
+
switch (s) {
|
|
195
|
+
case 'inf':
|
|
196
|
+
case '+inf':
|
|
197
|
+
case 'infinity':
|
|
198
|
+
case '+infinity':
|
|
199
|
+
return Number.POSITIVE_INFINITY
|
|
200
|
+
case '-inf':
|
|
201
|
+
case '-infinity':
|
|
202
|
+
return Number.NEGATIVE_INFINITY
|
|
203
|
+
case 'nan':
|
|
204
|
+
return Number.NaN
|
|
205
|
+
default: {
|
|
206
|
+
const parsed = Number(v)
|
|
207
|
+
if (!Number.isNaN(parsed)) return parsed
|
|
208
|
+
throw new EvaluationError('double() type error: cannot convert to double')
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
})
|
|
212
|
+
|
|
213
|
+
functionOverload('int(int): int', identity)
|
|
214
|
+
functionOverload('int(double): int', (v) => {
|
|
215
|
+
if (Number.isFinite(v)) return BigInt(Math.trunc(v))
|
|
216
|
+
throw new EvaluationError('int() type error: integer overflow')
|
|
217
|
+
})
|
|
218
|
+
|
|
219
|
+
functionOverload('int(string): int', (v) => {
|
|
220
|
+
if (v !== v.trim() || v.length > 20 || v.includes('0x')) {
|
|
221
|
+
throw new EvaluationError('int() type error: cannot convert to int')
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
try {
|
|
225
|
+
const num = BigInt(v)
|
|
226
|
+
if (num <= 9223372036854775807n && num >= -9223372036854775808n) return num
|
|
227
|
+
} catch (_e) {}
|
|
228
|
+
|
|
229
|
+
throw new EvaluationError('int() type error: cannot convert to int')
|
|
230
|
+
})
|
|
231
|
+
|
|
232
|
+
functionOverload('uint(uint): uint', identity)
|
|
233
|
+
functionOverload('uint(int): uint', (v) => {
|
|
234
|
+
try {
|
|
235
|
+
return new UnsignedInt(v)
|
|
236
|
+
} catch (e) {
|
|
237
|
+
throw new EvaluationError('uint() type error: cannot convert to uint')
|
|
238
|
+
}
|
|
239
|
+
})
|
|
240
|
+
functionOverload('uint(double): uint', (v) => {
|
|
241
|
+
try {
|
|
242
|
+
return new UnsignedInt(Math.trunc(v))
|
|
243
|
+
} catch (e) {
|
|
244
|
+
throw new EvaluationError('uint() type error: unsigned integer overflow')
|
|
245
|
+
}
|
|
246
|
+
})
|
|
247
|
+
|
|
248
|
+
functionOverload('uint(string): uint', (v) => {
|
|
249
|
+
if (v !== v.trim() || v.length > 20 || v.includes('0x')) {
|
|
250
|
+
throw new EvaluationError('uint() type error: cannot convert to uint')
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
try {
|
|
254
|
+
return new UnsignedInt(v)
|
|
255
|
+
} catch (e) {
|
|
256
|
+
throw new EvaluationError('uint() type error: cannot convert to uint')
|
|
257
|
+
}
|
|
258
|
+
})
|
|
259
|
+
|
|
260
|
+
functionOverload('string(string): string', identity)
|
|
261
|
+
functionOverload('string(bool): string', (v) => `${v}`)
|
|
262
|
+
functionOverload('string(int): string', (v) => `${v}`)
|
|
263
|
+
functionOverload('string(uint): string', (v) => `${v}`)
|
|
264
|
+
functionOverload('string(bytes): string', (v) => ByteOpts.toUtf8(v))
|
|
265
|
+
functionOverload('string(double): string', (v) => {
|
|
266
|
+
if (v === Infinity) return '+Inf'
|
|
267
|
+
if (v === -Infinity) return '-Inf'
|
|
268
|
+
return `${v}`
|
|
269
|
+
})
|
|
270
|
+
|
|
271
|
+
functionOverload('string.startsWith(string): bool', (a, b) => a.startsWith(b))
|
|
272
|
+
functionOverload('string.endsWith(string): bool', (a, b) => a.endsWith(b))
|
|
273
|
+
functionOverload('string.contains(string): bool', (a, b) => a.includes(b))
|
|
274
|
+
functionOverload('string.lowerAscii(): string', (a) => a.toLowerCase())
|
|
275
|
+
functionOverload('string.upperAscii(): string', (a) => a.toUpperCase())
|
|
276
|
+
functionOverload('string.trim(): string', (a) => a.trim())
|
|
277
|
+
|
|
278
|
+
functionOverload('string.indexOf(string): int', (string, search) =>
|
|
279
|
+
BigInt(string.indexOf(search))
|
|
280
|
+
)
|
|
281
|
+
functionOverload('string.indexOf(string, int): int', (string, search, fromIndex) => {
|
|
282
|
+
if (search === '') return fromIndex
|
|
283
|
+
|
|
284
|
+
fromIndex = Number(fromIndex)
|
|
285
|
+
if (fromIndex < 0 || fromIndex >= string.length) {
|
|
286
|
+
throw new EvaluationError('string.indexOf(search, fromIndex): fromIndex out of range')
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
return BigInt(string.indexOf(search, fromIndex))
|
|
290
|
+
})
|
|
291
|
+
|
|
292
|
+
functionOverload('string.lastIndexOf(string): int', (string, search) =>
|
|
293
|
+
BigInt(string.lastIndexOf(search))
|
|
294
|
+
)
|
|
295
|
+
|
|
296
|
+
functionOverload('string.lastIndexOf(string, int): int', (string, search, fromIndex) => {
|
|
297
|
+
if (search === '') return fromIndex
|
|
298
|
+
|
|
299
|
+
fromIndex = Number(fromIndex)
|
|
300
|
+
if (fromIndex < 0 || fromIndex >= string.length) {
|
|
301
|
+
throw new EvaluationError('string.lastIndexOf(search, fromIndex): fromIndex out of range')
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
return BigInt(string.lastIndexOf(search, fromIndex))
|
|
305
|
+
})
|
|
306
|
+
|
|
307
|
+
functionOverload('string.substring(int): string', (string, start) => {
|
|
308
|
+
start = Number(start)
|
|
309
|
+
if (start < 0 || start > string.length) {
|
|
310
|
+
throw new EvaluationError('string.substring(start, end): start index out of range')
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
return string.substring(start)
|
|
314
|
+
})
|
|
315
|
+
|
|
316
|
+
functionOverload('string.substring(int, int): string', (string, start, end) => {
|
|
317
|
+
start = Number(start)
|
|
318
|
+
if (start < 0 || start > string.length) {
|
|
319
|
+
throw new EvaluationError('string.substring(start, end): start index out of range')
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
end = Number(end)
|
|
323
|
+
if (end < start || end > string.length) {
|
|
324
|
+
throw new EvaluationError('string.substring(start, end): end index out of range')
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
return string.substring(start, end)
|
|
328
|
+
})
|
|
329
|
+
|
|
330
|
+
functionOverload('string.matches(string): bool', (a, b) => {
|
|
331
|
+
try {
|
|
332
|
+
return new RegExp(b).test(a)
|
|
333
|
+
} catch (_err) {
|
|
334
|
+
throw new EvaluationError(`Invalid regular expression: ${b}`)
|
|
335
|
+
}
|
|
336
|
+
})
|
|
337
|
+
|
|
338
|
+
functionOverload('string.split(string): list<string>', (s, sep) => s.split(sep))
|
|
339
|
+
functionOverload('string.split(string, int): list<string>', (s, sep, l) => {
|
|
340
|
+
l = Number(l)
|
|
341
|
+
if (l === 0) return []
|
|
342
|
+
const parts = s.split(sep)
|
|
343
|
+
if (l < 0 || parts.length <= l) return parts
|
|
344
|
+
const limited = parts.slice(0, l - 1)
|
|
345
|
+
limited.push(parts.slice(l - 1).join(sep))
|
|
346
|
+
return limited
|
|
347
|
+
})
|
|
348
|
+
|
|
349
|
+
functionOverload('list<string>.join(): string', (v) => {
|
|
350
|
+
for (let i = 0; i < v.length; i++) {
|
|
351
|
+
if (typeof v[i] !== 'string') {
|
|
352
|
+
throw new EvaluationError('string.join(): list must contain only strings')
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
return v.join('')
|
|
356
|
+
})
|
|
357
|
+
|
|
358
|
+
functionOverload('list<string>.join(string): string', (v, sep) => {
|
|
359
|
+
for (let i = 0; i < v.length; i++) {
|
|
360
|
+
if (typeof v[i] !== 'string') {
|
|
361
|
+
throw new EvaluationError('string.join(separator): list must contain only strings')
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
return v.join(sep)
|
|
365
|
+
})
|
|
366
|
+
|
|
367
|
+
const textEncoder = new TextEncoder('utf8')
|
|
368
|
+
const textDecoder = new TextDecoder('utf8')
|
|
369
|
+
const ByteOpts =
|
|
370
|
+
typeof Buffer !== 'undefined'
|
|
371
|
+
? {
|
|
372
|
+
byteLength: (v) => Buffer.byteLength(v),
|
|
373
|
+
fromString: (str) => Buffer.from(str, 'utf8'),
|
|
374
|
+
toHex: (b) => Buffer.prototype.hexSlice.call(b, 0, b.length),
|
|
375
|
+
toBase64: (b) => Buffer.prototype.base64Slice.call(b, 0, b.length),
|
|
376
|
+
toUtf8: (b) => Buffer.prototype.utf8Slice.call(b, 0, b.length),
|
|
377
|
+
jsonParse: (b) => JSON.parse(b)
|
|
378
|
+
}
|
|
379
|
+
: {
|
|
380
|
+
textEncoder: new TextEncoder('utf8'),
|
|
381
|
+
byteLength: (v) => textEncoder.encode(v).length,
|
|
382
|
+
fromString: (str) => textEncoder.encode(str),
|
|
383
|
+
toHex: Uint8Array.prototype.toHex
|
|
384
|
+
? (b) => b.toHex()
|
|
385
|
+
: (b) => arrayFrom(b, (i) => i.toString(16).padStart(2, '0')).join(''),
|
|
386
|
+
toBase64: Uint8Array.prototype.toBase64
|
|
387
|
+
? (b) => b.toBase64()
|
|
388
|
+
: (b) => btoa(arrayFrom(b, (i) => String.fromCodePoint(i)).join('')),
|
|
389
|
+
toUtf8: (b) => textDecoder.decode(b),
|
|
390
|
+
jsonParse: (b) => JSON.parse(textEncoder.decode(b))
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
functionOverload('bytes.json(): map', ByteOpts.jsonParse)
|
|
394
|
+
functionOverload('bytes.hex(): string', ByteOpts.toHex)
|
|
395
|
+
functionOverload('bytes.string(): string', ByteOpts.toUtf8)
|
|
396
|
+
functionOverload('bytes.base64(): string', ByteOpts.toBase64)
|
|
397
|
+
functionOverload('bytes.at(int): int', (b, index) => {
|
|
398
|
+
if (index < 0 || index >= b.length) throw new EvaluationError('Bytes index out of range')
|
|
399
|
+
return BigInt(b[index])
|
|
400
|
+
})
|
|
401
|
+
|
|
402
|
+
const TS = 'google.protobuf.Timestamp'
|
|
403
|
+
const GPD = 'google.protobuf.Duration'
|
|
404
|
+
const TimestampType = registry.registerType(TS, Date).typeType
|
|
405
|
+
const DurationType = registry.registerType(GPD, Duration).typeType
|
|
406
|
+
registry.registerConstant('google', 'map<string, map<string, type>>', {
|
|
407
|
+
protobuf: {Duration: DurationType, Timestamp: TimestampType}
|
|
408
|
+
})
|
|
409
|
+
|
|
410
|
+
function tzDate(d, timeZone) {
|
|
411
|
+
return new Date(d.toLocaleString('en-US', {timeZone}))
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
function getDayOfYear(d, tz) {
|
|
415
|
+
const workingDate = tz
|
|
416
|
+
? tzDate(d, tz)
|
|
417
|
+
: new Date(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate())
|
|
418
|
+
|
|
419
|
+
const start = new Date(workingDate.getFullYear(), 0, 0)
|
|
420
|
+
return BigInt(Math.floor((workingDate - start) / 86_400_000) - 1)
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
functionOverload(`timestamp(string): ${TS}`, (v) => {
|
|
424
|
+
if (v.length < 20 || v.length > 30) {
|
|
425
|
+
throw new EvaluationError('timestamp() requires a string in ISO 8601 format')
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
const d = new Date(v)
|
|
429
|
+
if (d <= 253402300799999 && d >= -62135596800000) return d
|
|
430
|
+
throw new EvaluationError('timestamp() requires a string in ISO 8601 format')
|
|
431
|
+
})
|
|
432
|
+
|
|
433
|
+
functionOverload(`timestamp(int): ${TS}`, (i) => {
|
|
434
|
+
i = Number(i) * 1000
|
|
435
|
+
if (i <= 253402300799999 && i >= -62135596800000) return new Date(i)
|
|
436
|
+
throw new EvaluationError('timestamp() requires a valid integer unix timestamp')
|
|
437
|
+
})
|
|
438
|
+
|
|
439
|
+
functionOverload(`${TS}.getDate(): int`, (d) => BigInt(d.getUTCDate()))
|
|
440
|
+
functionOverload(`${TS}.getDate(string): int`, (d, tz) => BigInt(tzDate(d, tz).getDate()))
|
|
441
|
+
functionOverload(`${TS}.getDayOfMonth(): int`, (d) => BigInt(d.getUTCDate() - 1))
|
|
442
|
+
functionOverload(`${TS}.getDayOfMonth(string): int`, (d, tz) =>
|
|
443
|
+
BigInt(tzDate(d, tz).getDate() - 1)
|
|
444
|
+
)
|
|
445
|
+
functionOverload(`${TS}.getDayOfWeek(): int`, (d) => BigInt(d.getUTCDay()))
|
|
446
|
+
functionOverload(`${TS}.getDayOfWeek(string): int`, (d, tz) => BigInt(tzDate(d, tz).getDay()))
|
|
447
|
+
functionOverload(`${TS}.getDayOfYear(): int`, getDayOfYear)
|
|
448
|
+
functionOverload(`${TS}.getDayOfYear(string): int`, getDayOfYear)
|
|
449
|
+
functionOverload(`${TS}.getFullYear(): int`, (d) => BigInt(d.getUTCFullYear()))
|
|
450
|
+
functionOverload(`${TS}.getFullYear(string): int`, (d, tz) => BigInt(tzDate(d, tz).getFullYear()))
|
|
451
|
+
functionOverload(`${TS}.getHours(): int`, (d) => BigInt(d.getUTCHours()))
|
|
452
|
+
functionOverload(`${TS}.getHours(string): int`, (d, tz) => BigInt(tzDate(d, tz).getHours()))
|
|
453
|
+
functionOverload(`${TS}.getMilliseconds(): int`, (d) => BigInt(d.getUTCMilliseconds()))
|
|
454
|
+
functionOverload(`${TS}.getMilliseconds(string): int`, (d) => BigInt(d.getUTCMilliseconds()))
|
|
455
|
+
functionOverload(`${TS}.getMinutes(): int`, (d) => BigInt(d.getUTCMinutes()))
|
|
456
|
+
functionOverload(`${TS}.getMinutes(string): int`, (d, tz) => BigInt(tzDate(d, tz).getMinutes()))
|
|
457
|
+
functionOverload(`${TS}.getMonth(): int`, (d) => BigInt(d.getUTCMonth()))
|
|
458
|
+
functionOverload(`${TS}.getMonth(string): int`, (d, tz) => BigInt(tzDate(d, tz).getMonth()))
|
|
459
|
+
functionOverload(`${TS}.getSeconds(): int`, (d) => BigInt(d.getUTCSeconds()))
|
|
460
|
+
functionOverload(`${TS}.getSeconds(string): int`, (d, tz) => BigInt(tzDate(d, tz).getSeconds()))
|
|
461
|
+
|
|
462
|
+
const parseDurationPattern = /(\d*\.?\d*)(ns|us|µs|ms|s|m|h)/
|
|
463
|
+
|
|
464
|
+
// parseDuration parses a golang-style duration string.
|
|
465
|
+
// A duration string is a possibly signed sequence of decimal numbers,
|
|
466
|
+
// each with optional fraction and a unit suffix,
|
|
467
|
+
// such as "300ms", "-1.5h" or "2h45m". Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
|
|
468
|
+
// https://pkg.go.dev/time#ParseDuration
|
|
469
|
+
function parseDuration(/** @type {string} */ string) {
|
|
470
|
+
if (!string) throw new EvaluationError(`Invalid duration string: ''`)
|
|
471
|
+
|
|
472
|
+
const isNegative = string[0] === '-'
|
|
473
|
+
if (string[0] === '-' || string[0] === '+') string = string.slice(1)
|
|
474
|
+
|
|
475
|
+
let nanoseconds = BigInt(0)
|
|
476
|
+
while (true) {
|
|
477
|
+
const match = parseDurationPattern.exec(string)
|
|
478
|
+
if (!match) throw new EvaluationError(`Invalid duration string: ${string}`)
|
|
479
|
+
|
|
480
|
+
if (match.index !== 0) throw new EvaluationError(`Invalid duration string: ${string}`)
|
|
481
|
+
string = string.slice(match[0].length)
|
|
482
|
+
|
|
483
|
+
const unitNanos = UNIT_NANOSECONDS[match[2]]
|
|
484
|
+
const [intPart = '0', fracPart = ''] = match[1].split('.')
|
|
485
|
+
const intVal = BigInt(intPart) * unitNanos
|
|
486
|
+
const fracNanos = fracPart
|
|
487
|
+
? (BigInt(fracPart.slice(0, 13).padEnd(13, '0')) * unitNanos) / 10000000000000n
|
|
488
|
+
: 0n
|
|
489
|
+
|
|
490
|
+
nanoseconds += intVal + fracNanos
|
|
491
|
+
if (string === '') break
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
const seconds = nanoseconds >= 1000000000n ? nanoseconds / 1000000000n : 0n
|
|
495
|
+
const nanos = Number(nanoseconds % 1000000000n)
|
|
496
|
+
|
|
497
|
+
if (isNegative) return new Duration(-seconds, -nanos)
|
|
498
|
+
return new Duration(seconds, nanos)
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
functionOverload(`duration(string): google.protobuf.Duration`, (s) => parseDuration(s))
|
|
502
|
+
functionOverload(`google.protobuf.Duration.getHours(): int`, (d) => d.getHours())
|
|
503
|
+
functionOverload(`google.protobuf.Duration.getMinutes(): int`, (d) => d.getMinutes())
|
|
504
|
+
functionOverload(`google.protobuf.Duration.getSeconds(): int`, (d) => d.getSeconds())
|
|
505
|
+
functionOverload(`google.protobuf.Duration.getMilliseconds(): int`, (d) => d.getMilliseconds())
|
|
506
|
+
registerOptional(registry)
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
function stringSize(str) {
|
|
510
|
+
let count = 0
|
|
511
|
+
for (const c of str) count++ // eslint-disable-line no-unused-vars
|
|
512
|
+
return count
|
|
513
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export function isAsync(fn: any, fallback: any): boolean;
|
|
2
|
+
export const hasOwn: (o: object, v: PropertyKey) => boolean;
|
|
3
|
+
export const objKeys: {
|
|
4
|
+
(o: object): string[];
|
|
5
|
+
(o: {}): string[];
|
|
6
|
+
};
|
|
7
|
+
export const objFreeze: {
|
|
8
|
+
<T extends Function>(f: T): T;
|
|
9
|
+
<T extends {
|
|
10
|
+
[idx: string]: U | null | undefined | object;
|
|
11
|
+
}, U extends string | bigint | number | boolean | symbol>(o: T): Readonly<T>;
|
|
12
|
+
<T>(o: T): Readonly<T>;
|
|
13
|
+
};
|
|
14
|
+
export const objEntries: {
|
|
15
|
+
<T>(o: {
|
|
16
|
+
[s: string]: T;
|
|
17
|
+
} | ArrayLike<T>): [string, T][];
|
|
18
|
+
(o: {}): [string, any][];
|
|
19
|
+
};
|
|
20
|
+
export const isArray: (arg: any) => arg is any[];
|
|
21
|
+
export const arrayFrom: {
|
|
22
|
+
<T>(arrayLike: ArrayLike<T>): T[];
|
|
23
|
+
<T, U>(arrayLike: ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[];
|
|
24
|
+
<T>(iterable: Iterable<T> | ArrayLike<T>): T[];
|
|
25
|
+
<T, U>(iterable: Iterable<T> | ArrayLike<T>, mapfn: (v: T, k: number) => U, thisArg?: any): U[];
|
|
26
|
+
};
|
|
27
|
+
export const RESERVED: Set<string>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export const hasOwn = Object.hasOwn
|
|
2
|
+
export const objKeys = Object.keys
|
|
3
|
+
export const objFreeze = Object.freeze
|
|
4
|
+
export const objEntries = Object.entries
|
|
5
|
+
export const isArray = Array.isArray
|
|
6
|
+
export const arrayFrom = Array.from
|
|
7
|
+
|
|
8
|
+
export function isAsync(fn, fallback) {
|
|
9
|
+
if (fn?.[Symbol.toStringTag] === 'AsyncFunction') return true
|
|
10
|
+
return typeof fallback === 'boolean' ? fallback : true
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const RESERVED = new Set([
|
|
14
|
+
'as',
|
|
15
|
+
'break',
|
|
16
|
+
'const',
|
|
17
|
+
'continue',
|
|
18
|
+
'else',
|
|
19
|
+
'for',
|
|
20
|
+
'function',
|
|
21
|
+
'if',
|
|
22
|
+
'import',
|
|
23
|
+
'let',
|
|
24
|
+
'loop',
|
|
25
|
+
'package',
|
|
26
|
+
'namespace',
|
|
27
|
+
'return',
|
|
28
|
+
'var',
|
|
29
|
+
'void',
|
|
30
|
+
'while',
|
|
31
|
+
'__proto__',
|
|
32
|
+
'prototype'
|
|
33
|
+
])
|