simplex-lang 0.2.2 → 1.0.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 (51) hide show
  1. package/README.md +530 -13
  2. package/build/parser/index.js +1161 -479
  3. package/build/parser/index.js.map +1 -1
  4. package/build/src/compiler.d.ts +26 -18
  5. package/build/src/compiler.js +211 -457
  6. package/build/src/compiler.js.map +1 -1
  7. package/build/src/constants.d.ts +25 -0
  8. package/build/src/constants.js +29 -0
  9. package/build/src/constants.js.map +1 -0
  10. package/build/src/error-mapping.d.ts +31 -0
  11. package/build/src/error-mapping.js +72 -0
  12. package/build/src/error-mapping.js.map +1 -0
  13. package/build/src/errors.d.ts +8 -5
  14. package/build/src/errors.js +8 -10
  15. package/build/src/errors.js.map +1 -1
  16. package/build/src/index.d.ts +1 -0
  17. package/build/src/index.js +1 -0
  18. package/build/src/index.js.map +1 -1
  19. package/build/src/simplex-tree.d.ts +25 -3
  20. package/build/src/simplex.peggy +120 -3
  21. package/build/src/tools/index.d.ts +25 -6
  22. package/build/src/tools/index.js +91 -19
  23. package/build/src/tools/index.js.map +1 -1
  24. package/build/src/version.js +1 -1
  25. package/build/src/visitors.d.ts +15 -0
  26. package/build/src/visitors.js +330 -0
  27. package/build/src/visitors.js.map +1 -0
  28. package/package.json +10 -8
  29. package/parser/index.js +1161 -479
  30. package/parser/index.js.map +1 -1
  31. package/src/compiler.ts +332 -609
  32. package/src/constants.ts +30 -0
  33. package/src/error-mapping.ts +112 -0
  34. package/src/errors.ts +8 -12
  35. package/src/index.ts +1 -0
  36. package/src/simplex-tree.ts +30 -2
  37. package/src/simplex.peggy +120 -3
  38. package/src/tools/index.ts +117 -24
  39. package/src/visitors.ts +491 -0
  40. package/build/src/tools/cast.d.ts +0 -2
  41. package/build/src/tools/cast.js +0 -20
  42. package/build/src/tools/cast.js.map +0 -1
  43. package/build/src/tools/ensure.d.ts +0 -3
  44. package/build/src/tools/ensure.js +0 -30
  45. package/build/src/tools/ensure.js.map +0 -1
  46. package/build/src/tools/guards.d.ts +0 -2
  47. package/build/src/tools/guards.js +0 -20
  48. package/build/src/tools/guards.js.map +0 -1
  49. package/src/tools/cast.ts +0 -26
  50. package/src/tools/ensure.ts +0 -41
  51. package/src/tools/guards.ts +0 -29
@@ -0,0 +1,491 @@
1
+ import { CompileError } from './errors.js'
2
+ import { TOPIC_TOKEN, GEN } from './constants.js'
3
+ import {
4
+ Expression,
5
+ ExpressionByType,
6
+ ExpressionStatement,
7
+ Location
8
+ } from './simplex-tree.js'
9
+
10
+ // --- Visitor Helpers ---
11
+
12
+ export interface SourceLocation {
13
+ len: number
14
+ location: Location
15
+ }
16
+
17
+ export interface VisitResult {
18
+ code: string
19
+ offsets: SourceLocation[]
20
+ }
21
+
22
+ export interface TraverseContext {
23
+ expression: string
24
+ insidePipe: boolean
25
+ }
26
+
27
+ type Visit = (node: Expression) => VisitResult[]
28
+
29
+ const codePart = (
30
+ codePart: string,
31
+ ownerNode: { location: Location }
32
+ ): VisitResult => ({
33
+ code: codePart,
34
+ offsets: [{ len: codePart.length, location: ownerNode.location }]
35
+ })
36
+
37
+ const combineVisitResults = (parts: VisitResult[]) => {
38
+ return parts.reduce((res, it) => {
39
+ return {
40
+ code: res.code + it.code,
41
+ offsets: res.offsets.concat(it.offsets)
42
+ } as VisitResult
43
+ })
44
+ }
45
+
46
+ /** Build a comma-separated list of VisitResult[] segments. */
47
+ const commaSeparated = (
48
+ items: VisitResult[][],
49
+ commaNode: { location: Location }
50
+ ): VisitResult[] => {
51
+ if (items.length === 0) return []
52
+ return items.flatMap((item, i) =>
53
+ i < items.length - 1 ? [...item, codePart(',', commaNode)] : item
54
+ )
55
+ }
56
+
57
+ /** Wrap visited args as `fnName(arg1, arg2, ...)`. */
58
+ const wrapCall = (
59
+ fnName: string,
60
+ node: { location: Location },
61
+ ...args: VisitResult[][]
62
+ ): VisitResult[] => [
63
+ codePart(`${fnName}(`, node),
64
+ ...commaSeparated(args, node),
65
+ codePart(')', node)
66
+ ]
67
+
68
+ /** Wrap visited args as `registry["op"](arg1, arg2, ...)`. */
69
+ const wrapOp = (
70
+ registry: string,
71
+ operator: string,
72
+ node: { location: Location },
73
+ ...args: VisitResult[][]
74
+ ): VisitResult[] => [
75
+ codePart(`${registry}["${operator}"](`, node),
76
+ ...commaSeparated(args, node),
77
+ codePart(')', node)
78
+ ]
79
+
80
+ /** Wrap visit results as a thunk: `()=>(...)`. */
81
+ const thunk = (
82
+ node: { location: Location },
83
+ parts: VisitResult[]
84
+ ): VisitResult[] => [codePart('()=>(', node), ...parts, codePart(')', node)]
85
+
86
+ // --- AST Visitors ---
87
+
88
+ const visitors: {
89
+ [P in keyof ExpressionByType]: (
90
+ node: ExpressionByType[P],
91
+ visit: Visit,
92
+ context: TraverseContext
93
+ ) => VisitResult[]
94
+ } = {
95
+ Literal: node => {
96
+ const parts: VisitResult[] = [codePart(JSON.stringify(node.value), node)]
97
+
98
+ return parts
99
+ },
100
+
101
+ Identifier: node => {
102
+ const parts: VisitResult[] = [
103
+ codePart(`${GEN.get}(${GEN.scope},${JSON.stringify(node.name)})`, node)
104
+ ]
105
+
106
+ return parts
107
+ },
108
+
109
+ UnaryExpression: (node, visit) =>
110
+ wrapOp(GEN.uop, node.operator, node, visit(node.argument)),
111
+
112
+ BinaryExpression: (node, visit) =>
113
+ wrapOp(GEN.bop, node.operator, node, visit(node.left), visit(node.right)),
114
+
115
+ LogicalExpression: (node, visit) =>
116
+ wrapOp(
117
+ GEN.lop,
118
+ node.operator,
119
+ node,
120
+ thunk(node, visit(node.left)),
121
+ thunk(node, visit(node.right))
122
+ ),
123
+
124
+ ConditionalExpression: (node, visit) => {
125
+ const parts: VisitResult[] = [
126
+ codePart(`(${GEN.bool}(`, node),
127
+ ...visit(node.test),
128
+ codePart(')?', node),
129
+ ...visit(node.consequent),
130
+ codePart(':', node),
131
+ ...(node.alternate !== null
132
+ ? visit(node.alternate)
133
+ : [codePart('undefined', node)]),
134
+ codePart(')', node)
135
+ ]
136
+
137
+ return parts
138
+ },
139
+
140
+ ObjectExpression: (node, visit, context) => {
141
+ const items = node.properties.map(p => {
142
+ if (p.type === 'SpreadElement') {
143
+ return [
144
+ codePart(`...${GEN.ensObj}(`, p),
145
+ ...visit(p.argument),
146
+ codePart(')', p)
147
+ ]
148
+ }
149
+ let keyParts: VisitResult[]
150
+ if (p.computed) {
151
+ keyParts = [codePart('[', p), ...visit(p.key), codePart(']', p)]
152
+ } else if (p.key.type === 'Identifier') {
153
+ keyParts = [codePart(p.key.name, p)]
154
+ } else if (p.key.type === 'Literal') {
155
+ // JSON.stringify(Infinity) returns "null", producing wrong key
156
+ if (typeof p.key.value === 'number' && !Number.isFinite(p.key.value)) {
157
+ throw new CompileError(
158
+ `Invalid object key: ${p.key.value}`,
159
+ context.expression,
160
+ p.key.location
161
+ )
162
+ }
163
+ keyParts = [codePart(JSON.stringify(p.key.value), p)]
164
+ } else {
165
+ // Unreachable: grammar restricts keys to Identifier and Literal
166
+ throw new CompileError(
167
+ `Unsupported object key type: ${p.key.type}`,
168
+ context.expression,
169
+ p.key.location
170
+ )
171
+ }
172
+ return [...keyParts, codePart(':', node), ...visit(p.value)]
173
+ })
174
+
175
+ return [
176
+ codePart('{', node),
177
+ ...commaSeparated(items, node),
178
+ codePart('}', node)
179
+ ]
180
+ },
181
+
182
+ ArrayExpression: (node, visit) => {
183
+ const items = node.elements.map(el => {
184
+ if (el === null) return []
185
+ if (el.type === 'SpreadElement') {
186
+ return [
187
+ codePart(`...${GEN.ensArr}(`, el),
188
+ ...visit(el.argument),
189
+ codePart(')', el)
190
+ ]
191
+ }
192
+ return visit(el)
193
+ })
194
+
195
+ return [
196
+ codePart('[', node),
197
+ ...commaSeparated(items, node),
198
+ codePart(']', node)
199
+ ]
200
+ },
201
+
202
+ NonNullAssertExpression: (node, visit) =>
203
+ wrapCall(GEN.nna, node, visit(node.expression)),
204
+
205
+ MemberExpression: (node, visit) => {
206
+ const { computed, object, property } = node
207
+
208
+ // TODO Pass computed to prop?
209
+
210
+ const propertyPart = computed
211
+ ? visit(property)
212
+ : [codePart(JSON.stringify(property.name), property)]
213
+
214
+ const extension = !computed && node.extension === true
215
+ return wrapCall(GEN.prop, node, visit(object), propertyPart, [
216
+ codePart(String(extension), node)
217
+ ])
218
+ },
219
+
220
+ CallExpression: (node, visit) => {
221
+ if (node.arguments.length > 0) {
222
+ const items = node.arguments.map((arg, index) =>
223
+ arg.type === 'CurryPlaceholder'
224
+ ? [codePart(`a${index}`, arg)]
225
+ : visit(arg)
226
+ )
227
+
228
+ const curriedArgs = node.arguments.flatMap((arg, index) =>
229
+ arg.type === 'CurryPlaceholder' ? [`a${index}`] : []
230
+ )
231
+
232
+ // call({{callee}},[{{arguments}}])
233
+ let parts: VisitResult[] = [
234
+ codePart(`${GEN.call}(`, node),
235
+ ...visit(node.callee),
236
+ codePart(',[', node),
237
+ ...commaSeparated(items, node),
238
+ codePart('])', node)
239
+ ]
240
+
241
+ if (curriedArgs.length > 0) {
242
+ parts = [
243
+ codePart(`(${GEN.scope}=>(${curriedArgs.join()})=>`, node),
244
+ ...parts,
245
+ codePart(`)(${GEN.scope})`, node)
246
+ ]
247
+ }
248
+
249
+ return parts
250
+ } else {
251
+ const parts: VisitResult[] = [
252
+ codePart(`${GEN.call}(`, node),
253
+ ...visit(node.callee),
254
+ codePart(',null)', node)
255
+ ]
256
+
257
+ return parts
258
+ }
259
+ },
260
+
261
+ NullishCoalescingExpression: (node, visit) => {
262
+ const parts: VisitResult[] = [
263
+ codePart('(', node),
264
+ ...visit(node.left),
265
+ codePart('??', node),
266
+ ...visit(node.right),
267
+ codePart(')', node)
268
+ ]
269
+
270
+ return parts
271
+ },
272
+
273
+ PipeSequence: (node, visit, context) => {
274
+ const headCode = visit(node.head)
275
+
276
+ const prevInsidePipe = context.insidePipe
277
+ context.insidePipe = true
278
+
279
+ const items = node.tail.map(t => {
280
+ const opt = t.operator === '|?'
281
+ const fwd = t.operator === '|>'
282
+ return [
283
+ codePart(
284
+ `{opt:${opt},fwd:${fwd},next:(${GEN.scope}=>topic=>{${GEN.scope}=[["${TOPIC_TOKEN}"],[topic],${GEN.scope}];return `,
285
+ t.expression
286
+ ),
287
+ ...visit(t.expression),
288
+ codePart(`})(${GEN.scope})}`, t.expression)
289
+ ]
290
+ })
291
+
292
+ context.insidePipe = prevInsidePipe
293
+
294
+ return [
295
+ codePart(`${GEN.pipe}(`, node),
296
+ ...headCode,
297
+ codePart(',[', node),
298
+ ...commaSeparated(items, node),
299
+ codePart('])', node)
300
+ ]
301
+ },
302
+
303
+ TopicReference: (node, _visit, context) => {
304
+ if (!context.insidePipe) {
305
+ throw new CompileError(
306
+ `Topic reference "${TOPIC_TOKEN}" is unbound; it must be inside a pipe body`,
307
+ context.expression,
308
+ node.location
309
+ )
310
+ }
311
+ const parts: VisitResult[] = [
312
+ codePart(`${GEN.get}(${GEN.scope},"${TOPIC_TOKEN}")`, node)
313
+ ]
314
+ return parts
315
+ },
316
+
317
+ LambdaExpression: (node, visit) => {
318
+ // Lambda with parameters
319
+ if (node.params.length > 0) {
320
+ const paramsNames = node.params.map(p => p.name)
321
+
322
+ const fnParams = Array.from(
323
+ { length: paramsNames.length },
324
+ (_, index) => `p${index}`
325
+ )
326
+
327
+ const fnParamsList = fnParams.join()
328
+ const fnParamsNamesList = paramsNames.map(p => JSON.stringify(p)).join()
329
+
330
+ const parts: VisitResult[] = [
331
+ codePart(
332
+ `((${GEN.scope},params)=>function(${fnParamsList}){${GEN.scope}=[params,[${fnParamsList}],${GEN.scope}];return `,
333
+ node
334
+ ),
335
+ ...visit(node.expression),
336
+ codePart(`})(${GEN.scope},[${fnParamsNamesList}])`, node)
337
+ ]
338
+
339
+ return parts
340
+ }
341
+
342
+ // Lambda without parameters
343
+ else {
344
+ // (() => {{code}})
345
+ const parts: VisitResult[] = [
346
+ codePart(`(()=>`, node),
347
+ ...visit(node.expression),
348
+ codePart(`)`, node)
349
+ ]
350
+
351
+ return parts
352
+ }
353
+ },
354
+
355
+ TemplateLiteral: (node, visit) => {
356
+ const { quasis, expressions, tag } = node
357
+
358
+ // --- Tagged template literal ---
359
+ if (tag !== null) {
360
+ const quasisItems = quasis.map(q => [codePart(JSON.stringify(q.value), q)])
361
+ const quasisArray: VisitResult[] = [
362
+ codePart('[', node),
363
+ ...commaSeparated(quasisItems, node),
364
+ codePart(']', node)
365
+ ]
366
+ const allArgs = [quasisArray, ...expressions.map(e => visit(e))]
367
+ return [
368
+ codePart(`${GEN.call}(`, node),
369
+ ...visit(tag),
370
+ codePart(',[', node),
371
+ ...commaSeparated(allArgs, node),
372
+ codePart('])', node)
373
+ ]
374
+ }
375
+
376
+ // No interpolations → emit as plain string literal
377
+ if (expressions.length === 0) {
378
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
379
+ return [codePart(JSON.stringify(quasis[0]!.value), node)]
380
+ }
381
+
382
+ const parts: VisitResult[] = [codePart('(', node)]
383
+
384
+ for (let i = 0; i < quasis.length; i++) {
385
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
386
+ const quasi = quasis[i]!
387
+ const expr = expressions[i]
388
+
389
+ // Add "+" between parts (skip before the first part)
390
+ if (i > 0) {
391
+ parts.push(codePart('+', node))
392
+ }
393
+
394
+ // Emit the static string part
395
+ if (quasi.value !== '' || expr == null) {
396
+ parts.push(codePart(JSON.stringify(quasi.value), quasi))
397
+ if (expr != null) {
398
+ parts.push(codePart('+', node))
399
+ }
400
+ }
401
+
402
+ // Emit the interpolated expression wrapped in castToString
403
+ if (expr != null) {
404
+ parts.push(codePart(`${GEN.str}(`, node))
405
+ parts.push(...visit(expr))
406
+ parts.push(codePart(')', node))
407
+ }
408
+ }
409
+
410
+ parts.push(codePart(')', node))
411
+ return parts
412
+ },
413
+
414
+ LetExpression: (node, visit, context) => {
415
+ const declarationsNamesSet = new Set()
416
+
417
+ for (const d of node.declarations) {
418
+ if (declarationsNamesSet.has(d.id.name)) {
419
+ throw new CompileError(
420
+ `"${d.id.name}" name defined inside let expression was repeated`,
421
+ context.expression,
422
+ d.id.location
423
+ )
424
+ }
425
+ declarationsNamesSet.add(d.id.name)
426
+ }
427
+
428
+ // (scope=> {
429
+ // var _varNames = [];
430
+ // var _varValues = [];
431
+ // scope = [_varNames, _varValues, scope];
432
+
433
+ // // a = {{init}}
434
+ // _varNames.push("a");
435
+ // _varValues.push({{init}});
436
+
437
+ // // {{expression}}
438
+ // return {{expression}}
439
+ // })(scope)
440
+
441
+ const parts: VisitResult[] = [
442
+ codePart(
443
+ `(${GEN.scope}=>{var ${GEN._varNames}=[];var ${GEN._varValues}=[];${GEN.scope}=[${GEN._varNames},${GEN._varValues},${GEN.scope}];`,
444
+ node
445
+ ),
446
+ ...node.declarations.flatMap(d => [
447
+ codePart(`${GEN._varValues}.push(`, d),
448
+ ...visit(d.init),
449
+ codePart(`);`, d),
450
+ codePart(`${GEN._varNames}.push(`, d),
451
+ codePart(JSON.stringify(d.id.name), d.id),
452
+ codePart(`);`, d)
453
+ ]),
454
+ codePart(`return `, node),
455
+ ...visit(node.expression),
456
+ codePart(`})(${GEN.scope})`, node)
457
+ ]
458
+
459
+ return parts
460
+ }
461
+ }
462
+
463
+ // --- Traverse ---
464
+
465
+ const visit = (
466
+ node: Expression,
467
+ _parentNode: Expression | null,
468
+ context: TraverseContext
469
+ ): VisitResult[] => {
470
+ const nodeTypeVisitor = visitors[node.type]
471
+
472
+ if (nodeTypeVisitor === undefined) {
473
+ throw new Error(`No handler for node type - ${node.type}`)
474
+ }
475
+
476
+ const innerVisit: Visit = (childNode: Expression) => {
477
+ return visit(childNode, node, context)
478
+ }
479
+
480
+ // @ts-expect-error skip node is never
481
+ return nodeTypeVisitor(node, innerVisit, context)
482
+ }
483
+
484
+ /** Walk the AST and produce generated JS code with source location offsets. */
485
+ export function traverse(
486
+ tree: ExpressionStatement,
487
+ expression: string
488
+ ): VisitResult {
489
+ const context: TraverseContext = { expression, insidePipe: false }
490
+ return combineVisitResults(visit(tree.expression, null, context))
491
+ }
@@ -1,2 +0,0 @@
1
- export declare function castToBoolean(val: unknown): boolean;
2
- export declare function castToString(val: unknown): string;
@@ -1,20 +0,0 @@
1
- import { unbox } from './index.js';
2
- // eslint-disable-next-line @typescript-eslint/unbound-method
3
- const toString = Object.prototype.toString;
4
- export function castToBoolean(val) {
5
- return Boolean(unbox(val));
6
- }
7
- export function castToString(val) {
8
- val = unbox(val);
9
- const type = typeof val;
10
- if (type === 'string')
11
- return val;
12
- if (val == null ||
13
- type === 'number' ||
14
- type === 'boolean' ||
15
- type === 'bigint') {
16
- return String(val);
17
- }
18
- return toString.call(val);
19
- }
20
- //# sourceMappingURL=cast.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cast.js","sourceRoot":"","sources":["../../../src/tools/cast.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAElC,6DAA6D;AAC7D,MAAM,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAA;AAE1C,MAAM,UAAU,aAAa,CAAC,GAAY;IACxC,OAAO,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAA;AAC5B,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,GAAY;IACvC,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,CAAA;IAEhB,MAAM,IAAI,GAAG,OAAO,GAAG,CAAA;IAEvB,IAAI,IAAI,KAAK,QAAQ;QAAE,OAAO,GAAa,CAAA;IAC3C,IACE,GAAG,IAAI,IAAI;QACX,IAAI,KAAK,QAAQ;QACjB,IAAI,KAAK,SAAS;QAClB,IAAI,KAAK,QAAQ,EACjB,CAAC;QACD,OAAO,MAAM,CAAC,GAAG,CAAC,CAAA;IACpB,CAAC;IAED,OAAO,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAC3B,CAAC"}
@@ -1,3 +0,0 @@
1
- export declare function ensureNumber(val: unknown): number | bigint;
2
- export declare function ensureFunction(val: unknown): Function;
3
- export declare function ensureRelationalComparable(val: unknown): number | string | bigint;
@@ -1,30 +0,0 @@
1
- import { UnexpectedTypeError } from '../errors.js';
2
- import { unbox } from './index.js';
3
- export function ensureNumber(val) {
4
- if (typeof val === 'number' && Number.isFinite(val)) {
5
- return val;
6
- }
7
- if (typeof val === 'bigint') {
8
- return val;
9
- }
10
- if (typeof val === 'object' && val instanceof Number) {
11
- return ensureNumber(val.valueOf());
12
- }
13
- throw new UnexpectedTypeError(['number', 'bigint'], val);
14
- }
15
- export function ensureFunction(val) {
16
- if (typeof val === 'function')
17
- return val;
18
- throw new UnexpectedTypeError(['function'], val);
19
- }
20
- export function ensureRelationalComparable(val) {
21
- val = unbox(val);
22
- const type = typeof val;
23
- if ((type === 'number' && Number.isNaN(val) === false) ||
24
- type === 'string' ||
25
- type === 'bigint') {
26
- return val;
27
- }
28
- throw new UnexpectedTypeError(['number', 'bigint', 'string'], val);
29
- }
30
- //# sourceMappingURL=ensure.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ensure.js","sourceRoot":"","sources":["../../../src/tools/ensure.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAClD,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAElC,MAAM,UAAU,YAAY,CAAC,GAAY;IACvC,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACpD,OAAO,GAAG,CAAA;IACZ,CAAC;IAED,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5B,OAAO,GAAG,CAAA;IACZ,CAAC;IAED,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,YAAY,MAAM,EAAE,CAAC;QACrD,OAAO,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;IACpC,CAAC;IAED,MAAM,IAAI,mBAAmB,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,GAAG,CAAC,CAAA;AAC1D,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,GAAY;IACzC,IAAI,OAAO,GAAG,KAAK,UAAU;QAAE,OAAO,GAAG,CAAA;IACzC,MAAM,IAAI,mBAAmB,CAAC,CAAC,UAAU,CAAC,EAAE,GAAG,CAAC,CAAA;AAClD,CAAC;AAED,MAAM,UAAU,0BAA0B,CACxC,GAAY;IAEZ,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,CAAA;IAEhB,MAAM,IAAI,GAAG,OAAO,GAAG,CAAA;IAEvB,IACE,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC;QAClD,IAAI,KAAK,QAAQ;QACjB,IAAI,KAAK,QAAQ,EACjB,CAAC;QACD,OAAO,GAA+B,CAAA;IACxC,CAAC;IAED,MAAM,IAAI,mBAAmB,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,GAAG,CAAC,CAAA;AACpE,CAAC"}
@@ -1,2 +0,0 @@
1
- export declare function isObject(val: unknown): val is object;
2
- export declare function isSimpleValue(val: unknown): val is number | string | boolean | bigint | null | undefined;
@@ -1,20 +0,0 @@
1
- import { unbox } from './index.js';
2
- // eslint-disable-next-line @typescript-eslint/unbound-method
3
- var objToStrProto = Object.prototype.toString;
4
- export function isObject(val) {
5
- return objToStrProto.call(val) === '[object Object]';
6
- }
7
- export function isSimpleValue(val) {
8
- val = unbox(val);
9
- const type = typeof val;
10
- if (type === 'string' ||
11
- type === 'number' ||
12
- type === 'boolean' ||
13
- type === 'bigint') {
14
- return true;
15
- }
16
- if (val == null)
17
- return true;
18
- return false;
19
- }
20
- //# sourceMappingURL=guards.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"guards.js","sourceRoot":"","sources":["../../../src/tools/guards.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAElC,6DAA6D;AAC7D,IAAI,aAAa,GAAG,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAA;AAE7C,MAAM,UAAU,QAAQ,CAAC,GAAY;IACnC,OAAO,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,iBAAiB,CAAA;AACtD,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,GAAY;IAEZ,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,CAAA;IAEhB,MAAM,IAAI,GAAG,OAAO,GAAG,CAAA;IAEvB,IACE,IAAI,KAAK,QAAQ;QACjB,IAAI,KAAK,QAAQ;QACjB,IAAI,KAAK,SAAS;QAClB,IAAI,KAAK,QAAQ,EACjB,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,IAAI,GAAG,IAAI,IAAI;QAAE,OAAO,IAAI,CAAA;IAE5B,OAAO,KAAK,CAAA;AACd,CAAC"}
package/src/tools/cast.ts DELETED
@@ -1,26 +0,0 @@
1
- import { unbox } from './index.js'
2
-
3
- // eslint-disable-next-line @typescript-eslint/unbound-method
4
- const toString = Object.prototype.toString
5
-
6
- export function castToBoolean(val: unknown): boolean {
7
- return Boolean(unbox(val))
8
- }
9
-
10
- export function castToString(val: unknown): string {
11
- val = unbox(val)
12
-
13
- const type = typeof val
14
-
15
- if (type === 'string') return val as string
16
- if (
17
- val == null ||
18
- type === 'number' ||
19
- type === 'boolean' ||
20
- type === 'bigint'
21
- ) {
22
- return String(val)
23
- }
24
-
25
- return toString.call(val)
26
- }
@@ -1,41 +0,0 @@
1
- import { UnexpectedTypeError } from '../errors.js'
2
- import { unbox } from './index.js'
3
-
4
- export function ensureNumber(val: unknown): number | bigint {
5
- if (typeof val === 'number' && Number.isFinite(val)) {
6
- return val
7
- }
8
-
9
- if (typeof val === 'bigint') {
10
- return val
11
- }
12
-
13
- if (typeof val === 'object' && val instanceof Number) {
14
- return ensureNumber(val.valueOf())
15
- }
16
-
17
- throw new UnexpectedTypeError(['number', 'bigint'], val)
18
- }
19
-
20
- export function ensureFunction(val: unknown): Function {
21
- if (typeof val === 'function') return val
22
- throw new UnexpectedTypeError(['function'], val)
23
- }
24
-
25
- export function ensureRelationalComparable(
26
- val: unknown
27
- ): number | string | bigint {
28
- val = unbox(val)
29
-
30
- const type = typeof val
31
-
32
- if (
33
- (type === 'number' && Number.isNaN(val) === false) ||
34
- type === 'string' ||
35
- type === 'bigint'
36
- ) {
37
- return val as number | string | bigint
38
- }
39
-
40
- throw new UnexpectedTypeError(['number', 'bigint', 'string'], val)
41
- }
@@ -1,29 +0,0 @@
1
- import { unbox } from './index.js'
2
-
3
- // eslint-disable-next-line @typescript-eslint/unbound-method
4
- var objToStrProto = Object.prototype.toString
5
-
6
- export function isObject(val: unknown): val is object {
7
- return objToStrProto.call(val) === '[object Object]'
8
- }
9
-
10
- export function isSimpleValue(
11
- val: unknown
12
- ): val is number | string | boolean | bigint | null | undefined {
13
- val = unbox(val)
14
-
15
- const type = typeof val
16
-
17
- if (
18
- type === 'string' ||
19
- type === 'number' ||
20
- type === 'boolean' ||
21
- type === 'bigint'
22
- ) {
23
- return true
24
- }
25
-
26
- if (val == null) return true
27
-
28
- return false
29
- }