From 048b64cfb3dec0be74161940f2049d566927e374 Mon Sep 17 00:00:00 2001 From: Shigma Date: Thu, 4 Apr 2024 03:42:22 +0800 Subject: [PATCH] fix(core): fix recursive checking --- packages/core/src/eval.ts | 3 ++- packages/core/src/utils.ts | 32 ++++++++++++++++++++++++-------- packages/tests/package.json | 11 +++++------ packages/tests/src/model.ts | 12 ++++++------ packages/tests/src/selection.ts | 2 +- packages/tests/src/shims.d.ts | 1 - 6 files changed, 38 insertions(+), 23 deletions(-) diff --git a/packages/core/src/eval.ts b/packages/core/src/eval.ts index 037e1e6f..95184824 100644 --- a/packages/core/src/eval.ts +++ b/packages/core/src/eval.ts @@ -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 @@ -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))) diff --git a/packages/core/src/utils.ts b/packages/core/src/utils.ts index 8de53ff7..a36d27d5 100644 --- a/packages/core/src/utils.ts +++ b/packages/core/src/utils.ts @@ -7,24 +7,40 @@ export type Keys = 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 = { [K in P]?: S } - // rule out atomic / recursive types - | (S extends Atomic | T ? never +type FlatWrap = { [K in P]?: S } + // rule out atomic types + | (S extends Values ? never // rule out array types : S extends any[] ? never + // check recursion depth // rule out dict / infinite types : string extends keyof S ? never - : FlatMap) + : A extends [0, ...infer R extends 0[]] ? FlatMap + : never) -type FlatMap = Values<{ - [K in keyof S & string as `${P}${K}`]: FlatWrap +type FlatMap = Values<{ + [K in keyof S & string as `${P}${K}`]: FlatWrap }> -export type Flatten = Intersect> +type Sequence = A['length'] extends N ? A : Sequence + +export type Flatten = Intersect>> export type Row = { [K in keyof S]-?: Row.Cell> diff --git a/packages/tests/package.json b/packages/tests/package.json index 7fdd53e1..41e9f640 100644 --- a/packages/tests/package.json +++ b/packages/tests/package.json @@ -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", @@ -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" } diff --git a/packages/tests/src/model.ts b/packages/tests/src/model.ts index 6d5949e0..4532faca 100644 --- a/packages/tests/src/model.ts +++ b/packages/tests/src/model.ts @@ -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 @@ -464,7 +464,7 @@ 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'), @@ -472,13 +472,13 @@ namespace ModelOperations { '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]]) }) diff --git a/packages/tests/src/selection.ts b/packages/tests/src/selection.ts index 80815c5e..79ad64da 100644 --- a/packages/tests/src/selection.ts +++ b/packages/tests/src/selection.ts @@ -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) }) diff --git a/packages/tests/src/shims.d.ts b/packages/tests/src/shims.d.ts index 53ea4190..7df2b820 100644 --- a/packages/tests/src/shims.d.ts +++ b/packages/tests/src/shims.d.ts @@ -1,5 +1,4 @@ /// -/// interface DeepEqualOptions { comparator?: (leftHandOperand: T1, rightHandOperand: T2) => boolean | null;