Skip to content

Commit

Permalink
fix(core): fix recursive checking
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Apr 3, 2024
1 parent 2e85244 commit 048b64c
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 23 deletions.
3 changes: 2 additions & 1 deletion packages/core/src/eval.ts
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ defineProperty(Eval, 'length', unary('length', (expr, table) => Array.isArray(ta
: Array.from(executeEval(table, expr)).length, Type.Number))

operators.$object = (field, table) => valueMap(field, value => executeAggr(value, table))
Eval.object = (fields) => {
Eval.object = (fields: any) => {
if (fields.$model) {
const modelFields: [string, Field][] = Object.entries(fields.$model.fields)
const prefix: string = fields.$prefix
Expand All @@ -258,6 +258,7 @@ Eval.object = (fields) => {
}
return Eval('object', fields, Type.Object(valueMap(fields, (value) => Type.fromTerm(value)))) as any
}

Eval.array = unary('array', (expr, table) => Array.isArray(table)
? table.map(data => executeAggr(expr, data))
: Array.from(executeEval(table, expr)), (expr) => Type.Array(Type.fromTerm(expr)))
Expand Down
32 changes: 24 additions & 8 deletions packages/core/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,40 @@ export type Keys<O, T = any> = Values<{
[K in keyof O]: O[K] extends T | undefined ? K : never
}> & string

export type Atomic = number | string | boolean | bigint | symbol | Date
export interface AtomicTypes {
Number: number
String: string
Boolean: boolean
BigInt: bigint
Symbol: symbol
Date: Date
RegExp: RegExp
Function: Function
ArrayBuffer: ArrayBuffer
SharedArrayBuffer: SharedArrayBuffer
}

export type Indexable = string | number
export type Comparable = string | number | boolean | Date

type FlatWrap<S, T, P extends string> = { [K in P]?: S }
// rule out atomic / recursive types
| (S extends Atomic | T ? never
type FlatWrap<S, A extends 0[], P extends string> = { [K in P]?: S }
// rule out atomic types
| (S extends Values<AtomicTypes> ? never
// rule out array types
: S extends any[] ? never
// check recursion depth
// rule out dict / infinite types
: string extends keyof S ? never
: FlatMap<S, T, `${P}.`>)
: A extends [0, ...infer R extends 0[]] ? FlatMap<S, R, `${P}.`>
: never)

type FlatMap<S, T = never, P extends string = ''> = Values<{
[K in keyof S & string as `${P}${K}`]: FlatWrap<S[K], S | T, `${P}${K}`>
type FlatMap<S, T extends 0[], P extends string = ''> = Values<{
[K in keyof S & string as `${P}${K}`]: FlatWrap<S[K], T, `${P}${K}`>
}>

export type Flatten<S> = Intersect<FlatMap<S>>
type Sequence<N extends number, A extends 0[] = []> = A['length'] extends N ? A : Sequence<N, [0, ...A]>

export type Flatten<S, D extends number = 5> = Intersect<FlatMap<S, Sequence<D>>>

export type Row<S> = {
[K in keyof S]-?: Row.Cell<NonNullable<S[K]>>
Expand Down
11 changes: 5 additions & 6 deletions packages/tests/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@minatojs/tests",
"version": "2.0.1",
"version": "2.0.2",
"description": "Test Cases for Minato",
"type": "module",
"main": "lib/index.js",
Expand All @@ -27,15 +27,14 @@
"unit"
],
"devDependencies": {
"@types/chai": "^4.3.11",
"@types/chai-as-promised": "^7.1.8",
"@types/deep-eql": "^4.0.2"
"@types/chai": "^4.3.14",
"@types/chai-as-promised": "^7.1.8"
},
"peerDependencies": {
"minato": "^3.0.1"
"minato": "^3.0.2"
},
"dependencies": {
"chai": "^4.3.10",
"chai": "^4.4.1",
"chai-as-promised": "^7.1.1",
"cosmokit": "^1.5.2"
}
Expand Down
12 changes: 6 additions & 6 deletions packages/tests/src/model.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { isNullable, valueMap } from 'cosmokit'
import { valueMap } from 'cosmokit'
import { $, Database, Field, Type } from 'minato'
import chai, { expect } from 'chai'
import { expect } from 'chai'

interface DType {
id: number
Expand Down Expand Up @@ -464,21 +464,21 @@ namespace ModelOperations {
binary: Buffer.from('boom'),
}

await database.set('dobjects', table[0].id, row => ({
await database.set('dobjects', table[0].id, {
'foo.nested.timestamp': new Date('2009/10/01 15:40:00'),
'foo.nested.date': new Date('1999/10/01'),
'foo.nested.binary': Buffer.from('boom'),
'bar.nested.id': 9,
'bar.nested.timestamp': new Date('2009/10/01 15:40:00'),
'bar.nested.date': new Date('1999/10/01'),
'bar.nested.binary': Buffer.from('boom'),
} as any))
})
await expect(database.get('dobjects', table[0].id)).to.eventually.deep.eq([table[0]])

table[0].baz = [{}, {}]
await database.set('dobjects', table[0].id, row => ({
await database.set('dobjects', table[0].id, {
baz: [{}, {}]
}))
})
await expect(database.get('dobjects', table[0].id)).to.eventually.deep.eq([table[0]])
})

Expand Down
2 changes: 1 addition & 1 deletion packages/tests/src/selection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ namespace SelectionTests {
it('access from join', async () => {
const w = x => database.select('bar').evaluate(row => $.add($.count(row.id), -6, x))
await expect(database
.join(['foo', 'bar'] as const, (foo, bar) => $.gt(foo.id, w(bar.pid)))
.join(['foo', 'bar'], (foo, bar) => $.gt(foo.id, w(bar.pid)))
.execute()
).to.eventually.have.length(9)
})
Expand Down
1 change: 0 additions & 1 deletion packages/tests/src/shims.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/// <reference types="chai" />
/// <reference types="deep-eql" />

interface DeepEqualOptions<T1 = unknown, T2 = unknown> {
comparator?: (leftHandOperand: T1, rightHandOperand: T2) => boolean | null;
Expand Down

0 comments on commit 048b64c

Please sign in to comment.