Merge branch 'release'

This commit is contained in:
Xu Chang 2023-01-31 20:57:59 +08:00
commit 9dad16432c
48 changed files with 922 additions and 477 deletions

View File

@ -1,16 +1,16 @@
import { ActionDef } from '../types/Action'; import { ActionDef } from '../types/Action';
export type ReadOnlyAction = 'select' | 'count' | 'stat' | 'download'; export declare type ReadOnlyAction = 'select' | 'count' | 'stat' | 'download' | 'aggregate';
export type AppendOnlyAction = ReadOnlyAction | 'create'; export declare type AppendOnlyAction = ReadOnlyAction | 'create';
export type ExcludeUpdateAction = AppendOnlyAction | 'remove'; export declare type ExcludeUpdateAction = AppendOnlyAction | 'remove';
export type ExcludeRemoveAction = AppendOnlyAction | 'update'; export declare type ExcludeRemoveAction = AppendOnlyAction | 'update';
export type GenericAction = 'update' | ExcludeUpdateAction; export declare type GenericAction = 'update' | ExcludeUpdateAction;
export type RelationAction = 'grant' | 'revoke'; export declare type RelationAction = 'grant' | 'revoke';
export declare const readOnlyActions: string[]; export declare const readOnlyActions: string[];
export declare const appendOnlyActions: string[]; export declare const appendOnlyActions: string[];
export declare const excludeUpdateActions: string[]; export declare const excludeUpdateActions: string[];
export declare const exludeRemoveActions: string[]; export declare const exludeRemoveActions: string[];
export declare const genericActions: string[]; export declare const genericActions: string[];
export declare const relationActions: string[]; export declare const relationActions: string[];
export type AbleAction = 'enable' | 'disable'; export declare type AbleAction = 'enable' | 'disable';
export type AbleState = 'enabled' | 'disabled'; export declare type AbleState = 'enabled' | 'disabled';
export declare const makeAbleActionDef: (initialState?: AbleState) => ActionDef<AbleAction, AbleState>; export declare const makeAbleActionDef: (initialState?: AbleState) => ActionDef<AbleAction, AbleState>;

View File

@ -1,7 +1,7 @@
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.makeAbleActionDef = exports.relationActions = exports.genericActions = exports.exludeRemoveActions = exports.excludeUpdateActions = exports.appendOnlyActions = exports.readOnlyActions = void 0; exports.makeAbleActionDef = exports.relationActions = exports.genericActions = exports.exludeRemoveActions = exports.excludeUpdateActions = exports.appendOnlyActions = exports.readOnlyActions = void 0;
exports.readOnlyActions = ['count', 'stat', 'download', 'select']; exports.readOnlyActions = ['count', 'stat', 'download', 'select', 'aggregate'];
exports.appendOnlyActions = exports.readOnlyActions.concat('create'); exports.appendOnlyActions = exports.readOnlyActions.concat('create');
exports.excludeUpdateActions = exports.appendOnlyActions.concat('remove'); exports.excludeUpdateActions = exports.appendOnlyActions.concat('remove');
exports.exludeRemoveActions = exports.appendOnlyActions.concat('update'); exports.exludeRemoveActions = exports.appendOnlyActions.concat('update');

View File

@ -1,5 +1,5 @@
import { CascadeRelationItem, RelationHierarchy } from "../types/Entity"; import { CascadeRelationItem, RelationHierarchy } from "../types/Entity";
export type GenericRelation = 'owner'; export declare type GenericRelation = 'owner';
export declare function convertHierarchyToAuth<R extends string>(hierarchy: RelationHierarchy<R>): { export declare function convertHierarchyToAuth<R extends string>(hierarchy: RelationHierarchy<R>): {
[K in R]?: CascadeRelationItem; [K in R]?: CascadeRelationItem;
}; };

View File

@ -3,7 +3,7 @@ import { EntityDef as ModiEntity } from "./ModiEntity/Schema";
import { EntityDef as Oper } from "./Oper/Schema"; import { EntityDef as Oper } from "./Oper/Schema";
import { EntityDef as OperEntity } from "./OperEntity/Schema"; import { EntityDef as OperEntity } from "./OperEntity/Schema";
import { EntityDef as User } from "./User/Schema"; import { EntityDef as User } from "./User/Schema";
export type EntityDict = { export declare type EntityDict = {
modi: Modi; modi: Modi;
modiEntity: ModiEntity; modiEntity: ModiEntity;
oper: Oper; oper: Oper;

View File

@ -1,9 +1,9 @@
import { ActionDef } from "../../types/Action"; import { ActionDef } from "../../types/Action";
import { GenericAction } from "../../actions/action"; import { GenericAction } from "../../actions/action";
export type IState = 'active' | 'applied' | 'abandoned'; export declare type IState = 'active' | 'applied' | 'abandoned';
export type IAction = 'apply' | 'abandon'; export declare type IAction = 'apply' | 'abandon';
export type ParticularAction = IAction; export declare type ParticularAction = IAction;
export type Action = GenericAction | ParticularAction; export declare type Action = GenericAction | ParticularAction;
export declare const actions: string[]; export declare const actions: string[];
export declare const ActionDefDict: { export declare const ActionDefDict: {
iState: ActionDef<IAction, IState>; iState: ActionDef<IAction, IState>;

View File

@ -8,7 +8,7 @@ var IActionDef = {
}, },
is: 'active' is: 'active'
}; };
exports.actions = ["count", "stat", "download", "select", "create", "remove", "update", "apply", "abandon"]; exports.actions = ["count", "stat", "download", "select", "aggregate", "create", "remove", "update", "apply", "abandon"];
exports.ActionDefDict = { exports.ActionDefDict = {
iState: IActionDef iState: IActionDef
}; };

View File

@ -2,11 +2,11 @@ import { String } from "../../types/DataType";
import { Q_DateValue, Q_StringValue, Q_EnumValue, NodeId, MakeFilter, ExprOp, ExpressionKey } from "../../types/Demand"; import { Q_DateValue, Q_StringValue, Q_EnumValue, NodeId, MakeFilter, ExprOp, ExpressionKey } from "../../types/Demand";
import { OneOf } from "../../types/Polyfill"; import { OneOf } from "../../types/Polyfill";
import * as SubQuery from "../_SubQuery"; import * as SubQuery from "../_SubQuery";
import { FormCreateData, FormUpdateData, DeduceAggregation, Operation as OakOperation, MakeAction as OakMakeAction, EntityShape, AggregationResult } from "../../types/Entity"; import { FormCreateData, FormUpdateData, DeduceAggregation, Operation as OakOperation, Selection as OakSelection, MakeAction as OakMakeAction, EntityShape, AggregationResult } from "../../types/Entity";
import { Action, ParticularAction, IState } from "./Action"; import { Action, ParticularAction, IState } from "./Action";
import * as ModiEntity from "../ModiEntity/Schema"; import * as ModiEntity from "../ModiEntity/Schema";
import * as OperEntity from "../OperEntity/Schema"; import * as OperEntity from "../OperEntity/Schema";
export type OpSchema = EntityShape & { export declare type OpSchema = EntityShape & {
targetEntity: String<32>; targetEntity: String<32>;
entity: String<32>; entity: String<32>;
entityId: String<64>; entityId: String<64>;
@ -16,8 +16,8 @@ export type OpSchema = EntityShape & {
extra?: Object | null; extra?: Object | null;
iState?: IState | null; iState?: IState | null;
}; };
export type OpAttr = keyof OpSchema; export declare type OpAttr = keyof OpSchema;
export type Schema = EntityShape & { export declare type Schema = EntityShape & {
targetEntity: String<32>; targetEntity: String<32>;
entity: String<32>; entity: String<32>;
entityId: String<64>; entityId: String<64>;
@ -33,7 +33,7 @@ export type Schema = EntityShape & {
} & { } & {
[A in ExpressionKey]?: any; [A in ExpressionKey]?: any;
}; };
type AttrFilter = { declare type AttrFilter = {
id: Q_StringValue | SubQuery.ModiIdSubQuery; id: Q_StringValue | SubQuery.ModiIdSubQuery;
$$createAt$$: Q_DateValue; $$createAt$$: Q_DateValue;
$$seq$$: Q_StringValue; $$seq$$: Q_StringValue;
@ -47,8 +47,8 @@ type AttrFilter = {
extra: Object; extra: Object;
iState: Q_EnumValue<IState>; iState: Q_EnumValue<IState>;
}; };
export type Filter = MakeFilter<AttrFilter & ExprOp<OpAttr | string>>; export declare type Filter = MakeFilter<AttrFilter & ExprOp<OpAttr | string>>;
export type Projection = { export declare type Projection = {
"#id"?: NodeId; "#id"?: NodeId;
[k: string]: any; [k: string]: any;
id?: number; id?: number;
@ -76,10 +76,10 @@ export type Projection = {
$entity: "operEntity"; $entity: "operEntity";
}; };
} & Partial<ExprOp<OpAttr | string>>; } & Partial<ExprOp<OpAttr | string>>;
type ModiIdProjection = OneOf<{ declare type ModiIdProjection = OneOf<{
id: number; id: number;
}>; }>;
export type SortAttr = { export declare type SortAttr = {
id: number; id: number;
} | { } | {
$$createAt$$: number; $$createAt$$: number;
@ -100,15 +100,15 @@ export type SortAttr = {
} | { } | {
[k: string]: any; [k: string]: any;
} | OneOf<ExprOp<OpAttr | string>>; } | OneOf<ExprOp<OpAttr | string>>;
export type SortNode = { export declare type SortNode = {
$attr: SortAttr; $attr: SortAttr;
$direction?: "asc" | "desc"; $direction?: "asc" | "desc";
}; };
export type Sorter = SortNode[]; export declare type Sorter = SortNode[];
export type SelectOperation<P extends Object = Projection> = Omit<OakOperation<"select", P, Filter, Sorter>, "id">; export declare type SelectOperation<P extends Object = Projection> = OakSelection<"select", P, Filter, Sorter>;
export type Selection<P extends Object = Projection> = Omit<SelectOperation<P>, "action">; export declare type Selection<P extends Object = Projection> = Omit<SelectOperation<P>, "action">;
export type Aggregation = Omit<DeduceAggregation<Projection, Filter, Sorter>, "id">; export declare type Aggregation = DeduceAggregation<Projection, Filter, Sorter>;
export type CreateOperationData = FormCreateData<Omit<OpSchema, "entity" | "entityId">> & ({ export declare type CreateOperationData = FormCreateData<Omit<OpSchema, "entity" | "entityId">> & ({
entity?: string; entity?: string;
entityId?: string; entityId?: string;
[K: string]: any; [K: string]: any;
@ -116,20 +116,20 @@ export type CreateOperationData = FormCreateData<Omit<OpSchema, "entity" | "enti
modiEntity$modi?: OakOperation<"create", Omit<ModiEntity.CreateOperationData, "modi" | "modiId">[]> | Array<OakOperation<"create", Omit<ModiEntity.CreateOperationData, "modi" | "modiId">>>; modiEntity$modi?: OakOperation<"create", Omit<ModiEntity.CreateOperationData, "modi" | "modiId">[]> | Array<OakOperation<"create", Omit<ModiEntity.CreateOperationData, "modi" | "modiId">>>;
operEntity$entity?: OakOperation<"create", Omit<OperEntity.CreateOperationData, "entity" | "entityId">[]> | Array<OakOperation<"create", Omit<OperEntity.CreateOperationData, "entity" | "entityId">>>; operEntity$entity?: OakOperation<"create", Omit<OperEntity.CreateOperationData, "entity" | "entityId">[]> | Array<OakOperation<"create", Omit<OperEntity.CreateOperationData, "entity" | "entityId">>>;
}; };
export type CreateSingleOperation = OakOperation<"create", CreateOperationData>; export declare type CreateSingleOperation = OakOperation<"create", CreateOperationData>;
export type CreateMultipleOperation = OakOperation<"create", Array<CreateOperationData>>; export declare type CreateMultipleOperation = OakOperation<"create", Array<CreateOperationData>>;
export type CreateOperation = CreateSingleOperation | CreateMultipleOperation; export declare type CreateOperation = CreateSingleOperation | CreateMultipleOperation;
export type UpdateOperationData = FormUpdateData<OpSchema> & { export declare type UpdateOperationData = FormUpdateData<OpSchema> & {
[k: string]: any; [k: string]: any;
modiEntitys$modi?: OakOperation<"create", Omit<ModiEntity.CreateOperationData, "modi" | "modiId">[]> | Array<OakOperation<"create", Omit<ModiEntity.CreateOperationData, "modi" | "modiId">>>; modiEntity$modi?: OakOperation<"create", Omit<ModiEntity.CreateOperationData, "modi" | "modiId">[]> | Array<OakOperation<"create", Omit<ModiEntity.CreateOperationData, "modi" | "modiId">>>;
operEntitys$entity?: OakOperation<"create", Omit<OperEntity.CreateOperationData, "entity" | "entityId">[]> | Array<OakOperation<"create", Omit<OperEntity.CreateOperationData, "entity" | "entityId">>>; operEntity$entity?: OakOperation<"create", Omit<OperEntity.CreateOperationData, "entity" | "entityId">[]> | Array<OakOperation<"create", Omit<OperEntity.CreateOperationData, "entity" | "entityId">>>;
}; };
export type UpdateOperation = OakOperation<"update" | ParticularAction | string, UpdateOperationData, Filter, Sorter>; export declare type UpdateOperation = OakOperation<"update" | ParticularAction | string, UpdateOperationData, Filter, Sorter>;
export type RemoveOperationData = {}; export declare type RemoveOperationData = {};
export type RemoveOperation = OakOperation<"remove", RemoveOperationData, Filter, Sorter>; export declare type RemoveOperation = OakOperation<"remove", RemoveOperationData, Filter, Sorter>;
export type Operation = CreateOperation | UpdateOperation | RemoveOperation; export declare type Operation = CreateOperation | UpdateOperation | RemoveOperation;
export type ModiIdSubQuery = Selection<ModiIdProjection>; export declare type ModiIdSubQuery = Selection<ModiIdProjection>;
export type EntityDef = { export declare type EntityDef = {
Schema: Schema; Schema: Schema;
OpSchema: OpSchema; OpSchema: OpSchema;
Action: OakMakeAction<Action> | string; Action: OakMakeAction<Action> | string;

View File

@ -2,17 +2,17 @@ import { String, ForeignKey } from "../../types/DataType";
import { Q_DateValue, Q_StringValue, Q_EnumValue, NodeId, MakeFilter, ExprOp, ExpressionKey } from "../../types/Demand"; import { Q_DateValue, Q_StringValue, Q_EnumValue, NodeId, MakeFilter, ExprOp, ExpressionKey } from "../../types/Demand";
import { OneOf } from "../../types/Polyfill"; import { OneOf } from "../../types/Polyfill";
import * as SubQuery from "../_SubQuery"; import * as SubQuery from "../_SubQuery";
import { FormCreateData, FormUpdateData, DeduceAggregation, Operation as OakOperation, MakeAction as OakMakeAction, EntityShape } from "../../types/Entity"; import { FormCreateData, FormUpdateData, DeduceAggregation, Operation as OakOperation, Selection as OakSelection, MakeAction as OakMakeAction, EntityShape } from "../../types/Entity";
import { AppendOnlyAction } from "../../actions/action"; import { AppendOnlyAction } from "../../actions/action";
import * as Modi from "../Modi/Schema"; import * as Modi from "../Modi/Schema";
import * as User from "../User/Schema"; import * as User from "../User/Schema";
export type OpSchema = EntityShape & { export declare type OpSchema = EntityShape & {
modiId: ForeignKey<"modi">; modiId: ForeignKey<"modi">;
entity: "user" | string; entity: "user" | string;
entityId: String<64>; entityId: String<64>;
}; };
export type OpAttr = keyof OpSchema; export declare type OpAttr = keyof OpSchema;
export type Schema = EntityShape & { export declare type Schema = EntityShape & {
modiId: ForeignKey<"modi">; modiId: ForeignKey<"modi">;
entity: "user" | string; entity: "user" | string;
entityId: String<64>; entityId: String<64>;
@ -21,7 +21,7 @@ export type Schema = EntityShape & {
} & { } & {
[A in ExpressionKey]?: any; [A in ExpressionKey]?: any;
}; };
type AttrFilter<E> = { declare type AttrFilter<E> = {
id: Q_StringValue | SubQuery.ModiEntityIdSubQuery; id: Q_StringValue | SubQuery.ModiEntityIdSubQuery;
$$createAt$$: Q_DateValue; $$createAt$$: Q_DateValue;
$$seq$$: Q_StringValue; $$seq$$: Q_StringValue;
@ -32,8 +32,8 @@ type AttrFilter<E> = {
entityId: Q_StringValue; entityId: Q_StringValue;
user: User.Filter; user: User.Filter;
}; };
export type Filter<E = Q_EnumValue<"user" | string>> = MakeFilter<AttrFilter<E> & ExprOp<OpAttr | string>>; export declare type Filter<E = Q_EnumValue<"user" | string>> = MakeFilter<AttrFilter<E> & ExprOp<OpAttr | string>>;
export type Projection = { export declare type Projection = {
"#id"?: NodeId; "#id"?: NodeId;
[k: string]: any; [k: string]: any;
id?: number; id?: number;
@ -46,16 +46,16 @@ export type Projection = {
entityId?: number; entityId?: number;
user?: User.Projection; user?: User.Projection;
} & Partial<ExprOp<OpAttr | string>>; } & Partial<ExprOp<OpAttr | string>>;
type ModiEntityIdProjection = OneOf<{ declare type ModiEntityIdProjection = OneOf<{
id: number; id: number;
}>; }>;
type ModiIdProjection = OneOf<{ declare type ModiIdProjection = OneOf<{
modiId: number; modiId: number;
}>; }>;
type UserIdProjection = OneOf<{ declare type UserIdProjection = OneOf<{
entityId: number; entityId: number;
}>; }>;
export type SortAttr = { export declare type SortAttr = {
id: number; id: number;
} | { } | {
$$createAt$$: number; $$createAt$$: number;
@ -76,15 +76,15 @@ export type SortAttr = {
} | { } | {
[k: string]: any; [k: string]: any;
} | OneOf<ExprOp<OpAttr | string>>; } | OneOf<ExprOp<OpAttr | string>>;
export type SortNode = { export declare type SortNode = {
$attr: SortAttr; $attr: SortAttr;
$direction?: "asc" | "desc"; $direction?: "asc" | "desc";
}; };
export type Sorter = SortNode[]; export declare type Sorter = SortNode[];
export type SelectOperation<P extends Object = Projection> = Omit<OakOperation<"select", P, Filter, Sorter>, "id">; export declare type SelectOperation<P extends Object = Projection> = OakSelection<"select", P, Filter, Sorter>;
export type Selection<P extends Object = Projection> = Omit<SelectOperation<P>, "action">; export declare type Selection<P extends Object = Projection> = Omit<SelectOperation<P>, "action">;
export type Aggregation = Omit<DeduceAggregation<Projection, Filter, Sorter>, "id">; export declare type Aggregation = DeduceAggregation<Projection, Filter, Sorter>;
export type CreateOperationData = FormCreateData<Omit<OpSchema, "entity" | "entityId" | "modiId">> & (({ export declare type CreateOperationData = FormCreateData<Omit<OpSchema, "entity" | "entityId" | "modiId">> & (({
modiId?: never; modiId?: never;
modi: Modi.CreateSingleOperation; modi: Modi.CreateSingleOperation;
} | { } | {
@ -108,10 +108,10 @@ export type CreateOperationData = FormCreateData<Omit<OpSchema, "entity" | "enti
entityId?: string; entityId?: string;
[K: string]: any; [K: string]: any;
}); });
export type CreateSingleOperation = OakOperation<"create", CreateOperationData>; export declare type CreateSingleOperation = OakOperation<"create", CreateOperationData>;
export type CreateMultipleOperation = OakOperation<"create", Array<CreateOperationData>>; export declare type CreateMultipleOperation = OakOperation<"create", Array<CreateOperationData>>;
export type CreateOperation = CreateSingleOperation | CreateMultipleOperation; export declare type CreateOperation = CreateSingleOperation | CreateMultipleOperation;
export type UpdateOperationData = FormUpdateData<Omit<OpSchema, "entity" | "entityId" | "modiId">> & (({ export declare type UpdateOperationData = FormUpdateData<Omit<OpSchema, "entity" | "entityId" | "modiId">> & (({
modi: Modi.CreateSingleOperation; modi: Modi.CreateSingleOperation;
modiId?: never; modiId?: never;
} | { } | {
@ -133,20 +133,20 @@ export type UpdateOperationData = FormUpdateData<Omit<OpSchema, "entity" | "enti
}) & { }) & {
[k: string]: any; [k: string]: any;
}; };
export type UpdateOperation = OakOperation<"update" | string, UpdateOperationData, Filter, Sorter>; export declare type UpdateOperation = OakOperation<"update" | string, UpdateOperationData, Filter, Sorter>;
export type RemoveOperationData = {} & (({ export declare type RemoveOperationData = {} & (({
modi?: Modi.UpdateOperation | Modi.RemoveOperation; modi?: Modi.UpdateOperation | Modi.RemoveOperation;
})) & ({ })) & ({
user?: User.UpdateOperation | User.RemoveOperation; user?: User.UpdateOperation | User.RemoveOperation;
} | { } | {
[k: string]: any; [k: string]: any;
}); });
export type RemoveOperation = OakOperation<"remove", RemoveOperationData, Filter, Sorter>; export declare type RemoveOperation = OakOperation<"remove", RemoveOperationData, Filter, Sorter>;
export type Operation = CreateOperation | UpdateOperation | RemoveOperation; export declare type Operation = CreateOperation | UpdateOperation | RemoveOperation;
export type ModiIdSubQuery = Selection<ModiIdProjection>; export declare type ModiIdSubQuery = Selection<ModiIdProjection>;
export type UserIdSubQuery = Selection<UserIdProjection>; export declare type UserIdSubQuery = Selection<UserIdProjection>;
export type ModiEntityIdSubQuery = Selection<ModiEntityIdProjection>; export declare type ModiEntityIdSubQuery = Selection<ModiEntityIdProjection>;
export type EntityDef = { export declare type EntityDef = {
Schema: Schema; Schema: Schema;
OpSchema: OpSchema; OpSchema: OpSchema;
Action: OakMakeAction<AppendOnlyAction> | string; Action: OakMakeAction<AppendOnlyAction> | string;

View File

@ -2,19 +2,19 @@ import { String, ForeignKey } from "../../types/DataType";
import { Q_DateValue, Q_StringValue, NodeId, MakeFilter, ExprOp, ExpressionKey } from "../../types/Demand"; import { Q_DateValue, Q_StringValue, NodeId, MakeFilter, ExprOp, ExpressionKey } from "../../types/Demand";
import { OneOf } from "../../types/Polyfill"; import { OneOf } from "../../types/Polyfill";
import * as SubQuery from "../_SubQuery"; import * as SubQuery from "../_SubQuery";
import { FormCreateData, FormUpdateData, DeduceAggregation, Operation as OakOperation, MakeAction as OakMakeAction, EntityShape, AggregationResult } from "../../types/Entity"; import { FormCreateData, FormUpdateData, DeduceAggregation, Operation as OakOperation, Selection as OakSelection, MakeAction as OakMakeAction, EntityShape, AggregationResult } from "../../types/Entity";
import { AppendOnlyAction } from "../../actions/action"; import { AppendOnlyAction } from "../../actions/action";
import * as User from "../User/Schema"; import * as User from "../User/Schema";
import * as OperEntity from "../OperEntity/Schema"; import * as OperEntity from "../OperEntity/Schema";
export type OpSchema = EntityShape & { export declare type OpSchema = EntityShape & {
action: String<16>; action: String<16>;
data: Object; data: Object;
filter?: Object | null; filter?: Object | null;
extra?: Object | null; extra?: Object | null;
operatorId?: ForeignKey<"user"> | null; operatorId?: ForeignKey<"user"> | null;
}; };
export type OpAttr = keyof OpSchema; export declare type OpAttr = keyof OpSchema;
export type Schema = EntityShape & { export declare type Schema = EntityShape & {
action: String<16>; action: String<16>;
data: Object; data: Object;
filter?: Object | null; filter?: Object | null;
@ -26,7 +26,7 @@ export type Schema = EntityShape & {
} & { } & {
[A in ExpressionKey]?: any; [A in ExpressionKey]?: any;
}; };
type AttrFilter = { declare type AttrFilter = {
id: Q_StringValue | SubQuery.OperIdSubQuery; id: Q_StringValue | SubQuery.OperIdSubQuery;
$$createAt$$: Q_DateValue; $$createAt$$: Q_DateValue;
$$seq$$: Q_StringValue; $$seq$$: Q_StringValue;
@ -38,8 +38,8 @@ type AttrFilter = {
operatorId: Q_StringValue | SubQuery.UserIdSubQuery; operatorId: Q_StringValue | SubQuery.UserIdSubQuery;
operator: User.Filter; operator: User.Filter;
}; };
export type Filter = MakeFilter<AttrFilter & ExprOp<OpAttr | string>>; export declare type Filter = MakeFilter<AttrFilter & ExprOp<OpAttr | string>>;
export type Projection = { export declare type Projection = {
"#id"?: NodeId; "#id"?: NodeId;
[k: string]: any; [k: string]: any;
id?: number; id?: number;
@ -59,13 +59,13 @@ export type Projection = {
$entity: "operEntity"; $entity: "operEntity";
}; };
} & Partial<ExprOp<OpAttr | string>>; } & Partial<ExprOp<OpAttr | string>>;
type OperIdProjection = OneOf<{ declare type OperIdProjection = OneOf<{
id: number; id: number;
}>; }>;
type UserIdProjection = OneOf<{ declare type UserIdProjection = OneOf<{
operatorId: number; operatorId: number;
}>; }>;
export type SortAttr = { export declare type SortAttr = {
id: number; id: number;
} | { } | {
$$createAt$$: number; $$createAt$$: number;
@ -82,15 +82,15 @@ export type SortAttr = {
} | { } | {
[k: string]: any; [k: string]: any;
} | OneOf<ExprOp<OpAttr | string>>; } | OneOf<ExprOp<OpAttr | string>>;
export type SortNode = { export declare type SortNode = {
$attr: SortAttr; $attr: SortAttr;
$direction?: "asc" | "desc"; $direction?: "asc" | "desc";
}; };
export type Sorter = SortNode[]; export declare type Sorter = SortNode[];
export type SelectOperation<P extends Object = Projection> = Omit<OakOperation<"select", P, Filter, Sorter>, "id">; export declare type SelectOperation<P extends Object = Projection> = OakSelection<"select", P, Filter, Sorter>;
export type Selection<P extends Object = Projection> = Omit<SelectOperation<P>, "action">; export declare type Selection<P extends Object = Projection> = Omit<SelectOperation<P>, "action">;
export type Aggregation = Omit<DeduceAggregation<Projection, Filter, Sorter>, "id">; export declare type Aggregation = DeduceAggregation<Projection, Filter, Sorter>;
export type CreateOperationData = FormCreateData<Omit<OpSchema, "operatorId">> & (({ export declare type CreateOperationData = FormCreateData<Omit<OpSchema, "operatorId">> & (({
operatorId?: never; operatorId?: never;
operator?: User.CreateSingleOperation; operator?: User.CreateSingleOperation;
} | { } | {
@ -101,10 +101,10 @@ export type CreateOperationData = FormCreateData<Omit<OpSchema, "operatorId">> &
})) & { })) & {
operEntity$oper?: OakOperation<"create", Omit<OperEntity.CreateOperationData, "oper" | "operId">[]> | Array<OakOperation<"create", Omit<OperEntity.CreateOperationData, "oper" | "operId">>>; operEntity$oper?: OakOperation<"create", Omit<OperEntity.CreateOperationData, "oper" | "operId">[]> | Array<OakOperation<"create", Omit<OperEntity.CreateOperationData, "oper" | "operId">>>;
}; };
export type CreateSingleOperation = OakOperation<"create", CreateOperationData>; export declare type CreateSingleOperation = OakOperation<"create", CreateOperationData>;
export type CreateMultipleOperation = OakOperation<"create", Array<CreateOperationData>>; export declare type CreateMultipleOperation = OakOperation<"create", Array<CreateOperationData>>;
export type CreateOperation = CreateSingleOperation | CreateMultipleOperation; export declare type CreateOperation = CreateSingleOperation | CreateMultipleOperation;
export type UpdateOperationData = FormUpdateData<Omit<OpSchema, "operatorId">> & (({ export declare type UpdateOperationData = FormUpdateData<Omit<OpSchema, "operatorId">> & (({
operator: User.CreateSingleOperation; operator: User.CreateSingleOperation;
operatorId?: never; operatorId?: never;
} | { } | {
@ -118,17 +118,17 @@ export type UpdateOperationData = FormUpdateData<Omit<OpSchema, "operatorId">> &
operatorId?: String<64> | null; operatorId?: String<64> | null;
})) & { })) & {
[k: string]: any; [k: string]: any;
operEntitys$oper?: OakOperation<"create", Omit<OperEntity.CreateOperationData, "oper" | "operId">[]> | Array<OakOperation<"create", Omit<OperEntity.CreateOperationData, "oper" | "operId">>>; operEntity$oper?: OakOperation<"create", Omit<OperEntity.CreateOperationData, "oper" | "operId">[]> | Array<OakOperation<"create", Omit<OperEntity.CreateOperationData, "oper" | "operId">>>;
}; };
export type UpdateOperation = OakOperation<"update" | string, UpdateOperationData, Filter, Sorter>; export declare type UpdateOperation = OakOperation<"update" | string, UpdateOperationData, Filter, Sorter>;
export type RemoveOperationData = {} & (({ export declare type RemoveOperationData = {} & (({
operator?: User.UpdateOperation | User.RemoveOperation; operator?: User.UpdateOperation | User.RemoveOperation;
})); }));
export type RemoveOperation = OakOperation<"remove", RemoveOperationData, Filter, Sorter>; export declare type RemoveOperation = OakOperation<"remove", RemoveOperationData, Filter, Sorter>;
export type Operation = CreateOperation | UpdateOperation | RemoveOperation; export declare type Operation = CreateOperation | UpdateOperation | RemoveOperation;
export type UserIdSubQuery = Selection<UserIdProjection>; export declare type UserIdSubQuery = Selection<UserIdProjection>;
export type OperIdSubQuery = Selection<OperIdProjection>; export declare type OperIdSubQuery = Selection<OperIdProjection>;
export type EntityDef = { export declare type EntityDef = {
Schema: Schema; Schema: Schema;
OpSchema: OpSchema; OpSchema: OpSchema;
Action: OakMakeAction<AppendOnlyAction> | string; Action: OakMakeAction<AppendOnlyAction> | string;

View File

@ -2,18 +2,18 @@ import { String, ForeignKey } from "../../types/DataType";
import { Q_DateValue, Q_StringValue, Q_EnumValue, NodeId, MakeFilter, ExprOp, ExpressionKey } from "../../types/Demand"; import { Q_DateValue, Q_StringValue, Q_EnumValue, NodeId, MakeFilter, ExprOp, ExpressionKey } from "../../types/Demand";
import { OneOf } from "../../types/Polyfill"; import { OneOf } from "../../types/Polyfill";
import * as SubQuery from "../_SubQuery"; import * as SubQuery from "../_SubQuery";
import { FormCreateData, FormUpdateData, DeduceAggregation, Operation as OakOperation, MakeAction as OakMakeAction, EntityShape } from "../../types/Entity"; import { FormCreateData, FormUpdateData, DeduceAggregation, Operation as OakOperation, Selection as OakSelection, MakeAction as OakMakeAction, EntityShape } from "../../types/Entity";
import { AppendOnlyAction } from "../../actions/action"; import { AppendOnlyAction } from "../../actions/action";
import * as Oper from "../Oper/Schema"; import * as Oper from "../Oper/Schema";
import * as Modi from "../Modi/Schema"; import * as Modi from "../Modi/Schema";
import * as User from "../User/Schema"; import * as User from "../User/Schema";
export type OpSchema = EntityShape & { export declare type OpSchema = EntityShape & {
operId: ForeignKey<"oper">; operId: ForeignKey<"oper">;
entity: "modi" | "user" | string; entity: "modi" | "user" | string;
entityId: String<64>; entityId: String<64>;
}; };
export type OpAttr = keyof OpSchema; export declare type OpAttr = keyof OpSchema;
export type Schema = EntityShape & { export declare type Schema = EntityShape & {
operId: ForeignKey<"oper">; operId: ForeignKey<"oper">;
entity: "modi" | "user" | string; entity: "modi" | "user" | string;
entityId: String<64>; entityId: String<64>;
@ -23,7 +23,7 @@ export type Schema = EntityShape & {
} & { } & {
[A in ExpressionKey]?: any; [A in ExpressionKey]?: any;
}; };
type AttrFilter<E> = { declare type AttrFilter<E> = {
id: Q_StringValue | SubQuery.OperEntityIdSubQuery; id: Q_StringValue | SubQuery.OperEntityIdSubQuery;
$$createAt$$: Q_DateValue; $$createAt$$: Q_DateValue;
$$seq$$: Q_StringValue; $$seq$$: Q_StringValue;
@ -35,8 +35,8 @@ type AttrFilter<E> = {
modi: Modi.Filter; modi: Modi.Filter;
user: User.Filter; user: User.Filter;
}; };
export type Filter<E = Q_EnumValue<"modi" | "user" | string>> = MakeFilter<AttrFilter<E> & ExprOp<OpAttr | string>>; export declare type Filter<E = Q_EnumValue<"modi" | "user" | string>> = MakeFilter<AttrFilter<E> & ExprOp<OpAttr | string>>;
export type Projection = { export declare type Projection = {
"#id"?: NodeId; "#id"?: NodeId;
[k: string]: any; [k: string]: any;
id?: number; id?: number;
@ -50,19 +50,19 @@ export type Projection = {
modi?: Modi.Projection; modi?: Modi.Projection;
user?: User.Projection; user?: User.Projection;
} & Partial<ExprOp<OpAttr | string>>; } & Partial<ExprOp<OpAttr | string>>;
type OperEntityIdProjection = OneOf<{ declare type OperEntityIdProjection = OneOf<{
id: number; id: number;
}>; }>;
type OperIdProjection = OneOf<{ declare type OperIdProjection = OneOf<{
operId: number; operId: number;
}>; }>;
type ModiIdProjection = OneOf<{ declare type ModiIdProjection = OneOf<{
entityId: number; entityId: number;
}>; }>;
type UserIdProjection = OneOf<{ declare type UserIdProjection = OneOf<{
entityId: number; entityId: number;
}>; }>;
export type SortAttr = { export declare type SortAttr = {
id: number; id: number;
} | { } | {
$$createAt$$: number; $$createAt$$: number;
@ -85,15 +85,15 @@ export type SortAttr = {
} | { } | {
[k: string]: any; [k: string]: any;
} | OneOf<ExprOp<OpAttr | string>>; } | OneOf<ExprOp<OpAttr | string>>;
export type SortNode = { export declare type SortNode = {
$attr: SortAttr; $attr: SortAttr;
$direction?: "asc" | "desc"; $direction?: "asc" | "desc";
}; };
export type Sorter = SortNode[]; export declare type Sorter = SortNode[];
export type SelectOperation<P extends Object = Projection> = Omit<OakOperation<"select", P, Filter, Sorter>, "id">; export declare type SelectOperation<P extends Object = Projection> = OakSelection<"select", P, Filter, Sorter>;
export type Selection<P extends Object = Projection> = Omit<SelectOperation<P>, "action">; export declare type Selection<P extends Object = Projection> = Omit<SelectOperation<P>, "action">;
export type Aggregation = Omit<DeduceAggregation<Projection, Filter, Sorter>, "id">; export declare type Aggregation = DeduceAggregation<Projection, Filter, Sorter>;
export type CreateOperationData = FormCreateData<Omit<OpSchema, "entity" | "entityId" | "operId">> & (({ export declare type CreateOperationData = FormCreateData<Omit<OpSchema, "entity" | "entityId" | "operId">> & (({
operId?: never; operId?: never;
oper: Oper.CreateSingleOperation; oper: Oper.CreateSingleOperation;
} | { } | {
@ -125,10 +125,10 @@ export type CreateOperationData = FormCreateData<Omit<OpSchema, "entity" | "enti
entityId?: string; entityId?: string;
[K: string]: any; [K: string]: any;
}); });
export type CreateSingleOperation = OakOperation<"create", CreateOperationData>; export declare type CreateSingleOperation = OakOperation<"create", CreateOperationData>;
export type CreateMultipleOperation = OakOperation<"create", Array<CreateOperationData>>; export declare type CreateMultipleOperation = OakOperation<"create", Array<CreateOperationData>>;
export type CreateOperation = CreateSingleOperation | CreateMultipleOperation; export declare type CreateOperation = CreateSingleOperation | CreateMultipleOperation;
export type UpdateOperationData = FormUpdateData<Omit<OpSchema, "entity" | "entityId" | "operId">> & (({ export declare type UpdateOperationData = FormUpdateData<Omit<OpSchema, "entity" | "entityId" | "operId">> & (({
oper: Oper.CreateSingleOperation; oper: Oper.CreateSingleOperation;
operId?: never; operId?: never;
} | { } | {
@ -148,21 +148,21 @@ export type UpdateOperationData = FormUpdateData<Omit<OpSchema, "entity" | "enti
}) & { }) & {
[k: string]: any; [k: string]: any;
}; };
export type UpdateOperation = OakOperation<"update" | string, UpdateOperationData, Filter, Sorter>; export declare type UpdateOperation = OakOperation<"update" | string, UpdateOperationData, Filter, Sorter>;
export type RemoveOperationData = {} & ({ export declare type RemoveOperationData = {} & ({
modi?: Modi.UpdateOperation | Modi.RemoveOperation; modi?: Modi.UpdateOperation | Modi.RemoveOperation;
} | { } | {
user?: User.UpdateOperation | User.RemoveOperation; user?: User.UpdateOperation | User.RemoveOperation;
} | { } | {
[k: string]: any; [k: string]: any;
}); });
export type RemoveOperation = OakOperation<"remove", RemoveOperationData, Filter, Sorter>; export declare type RemoveOperation = OakOperation<"remove", RemoveOperationData, Filter, Sorter>;
export type Operation = CreateOperation | UpdateOperation | RemoveOperation; export declare type Operation = CreateOperation | UpdateOperation | RemoveOperation;
export type OperIdSubQuery = Selection<OperIdProjection>; export declare type OperIdSubQuery = Selection<OperIdProjection>;
export type ModiIdSubQuery = Selection<ModiIdProjection>; export declare type ModiIdSubQuery = Selection<ModiIdProjection>;
export type UserIdSubQuery = Selection<UserIdProjection>; export declare type UserIdSubQuery = Selection<UserIdProjection>;
export type OperEntityIdSubQuery = Selection<OperEntityIdProjection>; export declare type OperEntityIdSubQuery = Selection<OperEntityIdProjection>;
export type EntityDef = { export declare type EntityDef = {
Schema: Schema; Schema: Schema;
OpSchema: OpSchema; OpSchema: OpSchema;
Action: OakMakeAction<AppendOnlyAction> | string; Action: OakMakeAction<AppendOnlyAction> | string;

View File

@ -2,18 +2,18 @@ import { String, Text } from "../../types/DataType";
import { Q_DateValue, Q_StringValue, NodeId, MakeFilter, ExprOp, ExpressionKey } from "../../types/Demand"; import { Q_DateValue, Q_StringValue, NodeId, MakeFilter, ExprOp, ExpressionKey } from "../../types/Demand";
import { OneOf } from "../../types/Polyfill"; import { OneOf } from "../../types/Polyfill";
import * as SubQuery from "../_SubQuery"; import * as SubQuery from "../_SubQuery";
import { FormCreateData, FormUpdateData, DeduceAggregation, Operation as OakOperation, MakeAction as OakMakeAction, EntityShape, AggregationResult } from "../../types/Entity"; import { FormCreateData, FormUpdateData, DeduceAggregation, Operation as OakOperation, Selection as OakSelection, MakeAction as OakMakeAction, EntityShape, AggregationResult } from "../../types/Entity";
import { GenericAction, RelationAction } from "../../actions/action"; import { GenericAction, RelationAction } from "../../actions/action";
import * as Oper from "../Oper/Schema"; import * as Oper from "../Oper/Schema";
import * as OperEntity from "../OperEntity/Schema"; import * as OperEntity from "../OperEntity/Schema";
import * as ModiEntity from "../ModiEntity/Schema"; import * as ModiEntity from "../ModiEntity/Schema";
export type OpSchema = EntityShape & { export declare type OpSchema = EntityShape & {
name?: String<16> | null; name?: String<16> | null;
nickname?: String<64> | null; nickname?: String<64> | null;
password?: Text | null; password?: Text | null;
}; };
export type OpAttr = keyof OpSchema; export declare type OpAttr = keyof OpSchema;
export type Schema = EntityShape & { export declare type Schema = EntityShape & {
name?: String<16> | null; name?: String<16> | null;
nickname?: String<64> | null; nickname?: String<64> | null;
password?: Text | null; password?: Text | null;
@ -26,7 +26,7 @@ export type Schema = EntityShape & {
} & { } & {
[A in ExpressionKey]?: any; [A in ExpressionKey]?: any;
}; };
type AttrFilter = { declare type AttrFilter = {
id: Q_StringValue | SubQuery.UserIdSubQuery; id: Q_StringValue | SubQuery.UserIdSubQuery;
$$createAt$$: Q_DateValue; $$createAt$$: Q_DateValue;
$$seq$$: Q_StringValue; $$seq$$: Q_StringValue;
@ -35,8 +35,8 @@ type AttrFilter = {
nickname: Q_StringValue; nickname: Q_StringValue;
password: Q_StringValue; password: Q_StringValue;
}; };
export type Filter = MakeFilter<AttrFilter & ExprOp<OpAttr | string>>; export declare type Filter = MakeFilter<AttrFilter & ExprOp<OpAttr | string>>;
export type Projection = { export declare type Projection = {
"#id"?: NodeId; "#id"?: NodeId;
[k: string]: any; [k: string]: any;
id?: number; id?: number;
@ -65,10 +65,10 @@ export type Projection = {
$entity: "modiEntity"; $entity: "modiEntity";
}; };
} & Partial<ExprOp<OpAttr | string>>; } & Partial<ExprOp<OpAttr | string>>;
type UserIdProjection = OneOf<{ declare type UserIdProjection = OneOf<{
id: number; id: number;
}>; }>;
export type SortAttr = { export declare type SortAttr = {
id: number; id: number;
} | { } | {
$$createAt$$: number; $$createAt$$: number;
@ -85,34 +85,34 @@ export type SortAttr = {
} | { } | {
[k: string]: any; [k: string]: any;
} | OneOf<ExprOp<OpAttr | string>>; } | OneOf<ExprOp<OpAttr | string>>;
export type SortNode = { export declare type SortNode = {
$attr: SortAttr; $attr: SortAttr;
$direction?: "asc" | "desc"; $direction?: "asc" | "desc";
}; };
export type Sorter = SortNode[]; export declare type Sorter = SortNode[];
export type SelectOperation<P extends Object = Projection> = Omit<OakOperation<"select", P, Filter, Sorter>, "id">; export declare type SelectOperation<P extends Object = Projection> = OakSelection<"select", P, Filter, Sorter>;
export type Selection<P extends Object = Projection> = Omit<SelectOperation<P>, "action">; export declare type Selection<P extends Object = Projection> = Omit<SelectOperation<P>, "action">;
export type Aggregation = Omit<DeduceAggregation<Projection, Filter, Sorter>, "id">; export declare type Aggregation = DeduceAggregation<Projection, Filter, Sorter>;
export type CreateOperationData = FormCreateData<OpSchema> & { export declare type CreateOperationData = FormCreateData<OpSchema> & {
oper$operator?: OakOperation<"create", Omit<Oper.CreateOperationData, "operator" | "operatorId">[]> | Array<OakOperation<"create", Omit<Oper.CreateOperationData, "operator" | "operatorId">>>; oper$operator?: OakOperation<"create", Omit<Oper.CreateOperationData, "operator" | "operatorId">[]> | Array<OakOperation<"create", Omit<Oper.CreateOperationData, "operator" | "operatorId">>>;
operEntity$entity?: OakOperation<"create", Omit<OperEntity.CreateOperationData, "entity" | "entityId">[]> | Array<OakOperation<"create", Omit<OperEntity.CreateOperationData, "entity" | "entityId">>>; operEntity$entity?: OakOperation<"create", Omit<OperEntity.CreateOperationData, "entity" | "entityId">[]> | Array<OakOperation<"create", Omit<OperEntity.CreateOperationData, "entity" | "entityId">>>;
modiEntity$entity?: OakOperation<"create", Omit<ModiEntity.CreateOperationData, "entity" | "entityId">[]> | Array<OakOperation<"create", Omit<ModiEntity.CreateOperationData, "entity" | "entityId">>>; modiEntity$entity?: OakOperation<"create", Omit<ModiEntity.CreateOperationData, "entity" | "entityId">[]> | Array<OakOperation<"create", Omit<ModiEntity.CreateOperationData, "entity" | "entityId">>>;
}; };
export type CreateSingleOperation = OakOperation<"create", CreateOperationData>; export declare type CreateSingleOperation = OakOperation<"create", CreateOperationData>;
export type CreateMultipleOperation = OakOperation<"create", Array<CreateOperationData>>; export declare type CreateMultipleOperation = OakOperation<"create", Array<CreateOperationData>>;
export type CreateOperation = CreateSingleOperation | CreateMultipleOperation; export declare type CreateOperation = CreateSingleOperation | CreateMultipleOperation;
export type UpdateOperationData = FormUpdateData<OpSchema> & { export declare type UpdateOperationData = FormUpdateData<OpSchema> & {
[k: string]: any; [k: string]: any;
opers$operator?: OakOperation<"create", Omit<Oper.CreateOperationData, "operator" | "operatorId">[]> | Array<OakOperation<"create", Omit<Oper.CreateOperationData, "operator" | "operatorId">>>; oper$operator?: OakOperation<"create", Omit<Oper.CreateOperationData, "operator" | "operatorId">[]> | Array<OakOperation<"create", Omit<Oper.CreateOperationData, "operator" | "operatorId">>>;
operEntitys$entity?: OakOperation<"create", Omit<OperEntity.CreateOperationData, "entity" | "entityId">[]> | Array<OakOperation<"create", Omit<OperEntity.CreateOperationData, "entity" | "entityId">>>; operEntity$entity?: OakOperation<"create", Omit<OperEntity.CreateOperationData, "entity" | "entityId">[]> | Array<OakOperation<"create", Omit<OperEntity.CreateOperationData, "entity" | "entityId">>>;
modiEntitys$entity?: OakOperation<"create", Omit<ModiEntity.CreateOperationData, "entity" | "entityId">[]> | Array<OakOperation<"create", Omit<ModiEntity.CreateOperationData, "entity" | "entityId">>>; modiEntity$entity?: OakOperation<"create", Omit<ModiEntity.CreateOperationData, "entity" | "entityId">[]> | Array<OakOperation<"create", Omit<ModiEntity.CreateOperationData, "entity" | "entityId">>>;
}; };
export type UpdateOperation = OakOperation<"update" | RelationAction | string, UpdateOperationData, Filter, Sorter>; export declare type UpdateOperation = OakOperation<"update" | RelationAction | string, UpdateOperationData, Filter, Sorter>;
export type RemoveOperationData = {}; export declare type RemoveOperationData = {};
export type RemoveOperation = OakOperation<"remove", RemoveOperationData, Filter, Sorter>; export declare type RemoveOperation = OakOperation<"remove", RemoveOperationData, Filter, Sorter>;
export type Operation = CreateOperation | UpdateOperation | RemoveOperation; export declare type Operation = CreateOperation | UpdateOperation | RemoveOperation;
export type UserIdSubQuery = Selection<UserIdProjection>; export declare type UserIdSubQuery = Selection<UserIdProjection>;
export type EntityDef = { export declare type EntityDef = {
Schema: Schema; Schema: Schema;
OpSchema: OpSchema; OpSchema: OpSchema;
Action: OakMakeAction<GenericAction | RelationAction> | string; Action: OakMakeAction<GenericAction | RelationAction> | string;

View File

@ -3,31 +3,31 @@ import * as ModiEntity from "./ModiEntity/Schema";
import * as Oper from "./Oper/Schema"; import * as Oper from "./Oper/Schema";
import * as OperEntity from "./OperEntity/Schema"; import * as OperEntity from "./OperEntity/Schema";
import * as User from "./User/Schema"; import * as User from "./User/Schema";
export type ModiIdSubQuery = { export declare type ModiIdSubQuery = {
[K in "$in" | "$nin"]?: (ModiEntity.ModiIdSubQuery & { [K in "$in" | "$nin"]?: (ModiEntity.ModiIdSubQuery & {
entity: "modiEntity"; entity: "modiEntity";
}) | (Modi.ModiIdSubQuery & { }) | (Modi.ModiIdSubQuery & {
entity: "modi"; entity: "modi";
}) | any; }) | any;
}; };
export type ModiEntityIdSubQuery = { export declare type ModiEntityIdSubQuery = {
[K in "$in" | "$nin"]?: (ModiEntity.ModiEntityIdSubQuery & { [K in "$in" | "$nin"]?: (ModiEntity.ModiEntityIdSubQuery & {
entity: "modiEntity"; entity: "modiEntity";
}) | any; }) | any;
}; };
export type OperIdSubQuery = { export declare type OperIdSubQuery = {
[K in "$in" | "$nin"]?: (OperEntity.OperIdSubQuery & { [K in "$in" | "$nin"]?: (OperEntity.OperIdSubQuery & {
entity: "operEntity"; entity: "operEntity";
}) | (Oper.OperIdSubQuery & { }) | (Oper.OperIdSubQuery & {
entity: "oper"; entity: "oper";
}) | any; }) | any;
}; };
export type OperEntityIdSubQuery = { export declare type OperEntityIdSubQuery = {
[K in "$in" | "$nin"]?: (OperEntity.OperEntityIdSubQuery & { [K in "$in" | "$nin"]?: (OperEntity.OperEntityIdSubQuery & {
entity: "operEntity"; entity: "operEntity";
}) | any; }) | any;
}; };
export type UserIdSubQuery = { export declare type UserIdSubQuery = {
[K in "$in" | "$nin"]?: (Oper.UserIdSubQuery & { [K in "$in" | "$nin"]?: (Oper.UserIdSubQuery & {
entity: "oper"; entity: "oper";
}) | (User.UserIdSubQuery & { }) | (User.UserIdSubQuery & {

View File

@ -652,12 +652,12 @@ function analyzeEntity(filename, path, program, relativePath) {
return ele2.name.getText() === 'name'; return ele2.name.getText() === 'name';
}); });
(0, assert_1.default)(ts.isStringLiteral(nameProperty.initializer)); (0, assert_1.default)(ts.isStringLiteral(nameProperty.initializer));
var indexName = nameProperty.initializer.text; var nameText = nameProperty.initializer.text;
if (indexNameDict_1[indexName]) { if (indexNameDict_1[nameText]) {
throw new Error("\u300C".concat(filename, "\u300D\u7D22\u5F15\u5B9A\u4E49\u91CD\u540D\u300C").concat(indexName, "\u300D")); throw new Error("\u300C".concat(filename, "\u300D\u7D22\u5F15\u5B9A\u4E49\u91CD\u540D\u300C").concat(nameText, "\u300D"));
} }
(0, lodash_1.assign)(indexNameDict_1, (_a = {}, (0, lodash_1.assign)(indexNameDict_1, (_a = {},
_a[indexName] = true, _a[nameText] = true,
_a)); _a));
var configProperty = properties.find(function (ele2) { var configProperty = properties.find(function (ele2) {
(0, assert_1.default)(ts.isPropertyAssignment(ele2)); (0, assert_1.default)(ts.isPropertyAssignment(ele2));
@ -695,10 +695,10 @@ function analyzeEntity(filename, path, program, relativePath) {
return ele3.name.text === indexAttrName; return ele3.name.text === indexAttrName;
}); });
if (!schemaNode) { if (!schemaNode) {
throw new Error("\u300C".concat(filename, "\u300D\u4E2D\u7D22\u5F15\u300C").concat(indexName, "\u300D\u7684\u5C5E\u6027\u300C").concat(indexAttrName, "\u300D\u5B9A\u4E49\u975E\u6CD5")); throw new Error("\u300C".concat(filename, "\u300D\u4E2D\u7D22\u5F15\u300C").concat(nameText, "\u300D\u7684\u5C5E\u6027\u300C").concat(indexAttrName, "\u300D\u5B9A\u4E49\u975E\u6CD5"));
} }
var type = schemaNode.type, name_1 = schemaNode.name; var type = schemaNode.type, name_1 = schemaNode.name;
var entity = (0, string_1.firstLetterLowerCase)(moduleName); var entity = moduleName;
var _a = ManyToOne, _b = entity, manyToOneSet = _a[_b]; var _a = ManyToOne, _b = entity, manyToOneSet = _a[_b];
if (ts.isTypeReferenceNode(type)) { if (ts.isTypeReferenceNode(type)) {
var typeName = type.typeName; var typeName = type.typeName;
@ -712,14 +712,19 @@ function analyzeEntity(filename, path, program, relativePath) {
if (!manyToOneItem) { if (!manyToOneItem) {
// 如果不是外键则不能是Text, File // 如果不是外键则不能是Text, File
if (isFulltextIndex) { if (isFulltextIndex) {
(0, assert_1.default)(['Text', 'String'].includes(text2_1), "\u300C".concat(filename, "\u300D\u4E2D\u5168\u6587\u7D22\u5F15\u300C").concat(indexName, "\u300D\u5B9A\u4E49\u7684\u5C5E\u6027\u300C").concat(indexAttrName, "\u300D\u7C7B\u578B\u975E\u6CD5\uFF0C\u53EA\u80FD\u662FText/String")); (0, assert_1.default)(['Text', 'String'].includes(text2_1), "\u300C".concat(filename, "\u300D\u4E2D\u5168\u6587\u7D22\u5F15\u300C").concat(nameText, "\u300D\u5B9A\u4E49\u7684\u5C5E\u6027\u300C").concat(indexAttrName, "\u300D\u7C7B\u578B\u975E\u6CD5\uFF0C\u53EA\u80FD\u662FText/String"));
} }
else { else {
(0, assert_1.default)(!DataType_1.unIndexedTypes.includes(text2_1), "\u300C".concat(filename, "\u300D\u4E2D\u7D22\u5F15\u300C").concat(indexName, "\u300D\u7684\u5C5E\u6027\u300C").concat(indexAttrName, "\u300D\u7684\u7C7B\u578B\u4E3A\u300C").concat(text2_1, "\u300D\uFF0C\u4E0D\u53EF\u7D22\u5F15")); (0, assert_1.default)(!DataType_1.unIndexedTypes.includes(text2_1), "\u300C".concat(filename, "\u300D\u4E2D\u7D22\u5F15\u300C").concat(nameText, "\u300D\u7684\u5C5E\u6027\u300C").concat(indexAttrName, "\u300D\u7684\u7C7B\u578B\u4E3A\u300C").concat(text2_1, "\u300D\uFF0C\u4E0D\u53EF\u7D22\u5F15"));
} }
} }
else { else {
(0, assert_1.default)(!isFulltextIndex, "\u300C".concat(filename, "\u300D\u4E2D\u5168\u6587\u7D22\u5F15\u300C").concat(indexName, "\u300D\u7684\u5C5E\u6027\u300C").concat(indexAttrName, "\u300D\u7C7B\u578B\u975E\u6CD5\uFF0C\u53EA\u80FD\u4E3AText/String")); (0, assert_1.default)(!isFulltextIndex, "\u300C".concat(filename, "\u300D\u4E2D\u5168\u6587\u7D22\u5F15\u300C").concat(nameText, "\u300D\u7684\u5C5E\u6027\u300C").concat(indexAttrName, "\u300D\u7C7B\u578B\u975E\u6CD5\uFF0C\u53EA\u80FD\u4E3AText/String"));
// 在这里把外键加上Id这样storageSchema才能正常通过
// 这里的写法不太好未来TS版本高了可能会有问题。by Xc 20230131
Object.assign(nameProperty, {
initializer: factory.createStringLiteral("".concat(indexAttrName, "Id")),
});
} }
} }
else { else {
@ -727,8 +732,8 @@ function analyzeEntity(filename, path, program, relativePath) {
} }
} }
else { else {
(0, assert_1.default)(!isFulltextIndex, "\u300C".concat(filename, "\u300D\u4E2D\u5168\u6587\u7D22\u5F15\u300C").concat(indexName, "\u300D\u7684\u5C5E\u6027\u300C").concat(indexAttrName, "\u300D\u7C7B\u578B\u53EA\u80FD\u4E3AText/String")); (0, assert_1.default)(!isFulltextIndex, "\u300C".concat(filename, "\u300D\u4E2D\u5168\u6587\u7D22\u5F15\u300C").concat(nameText, "\u300D\u7684\u5C5E\u6027\u300C").concat(indexAttrName, "\u300D\u7C7B\u578B\u53EA\u80FD\u4E3AText/String"));
(0, assert_1.default)(ts.isUnionTypeNode(type) || ts.isLiteralTypeNode(type), "".concat(entity, "\u4E2D\u7D22\u5F15\u300C").concat(indexName, "\u300D\u7684\u5C5E\u6027").concat(name_1.text, "\u6709\u5B9A\u4E49\u975E\u6CD5")); (0, assert_1.default)(ts.isUnionTypeNode(type) || ts.isLiteralTypeNode(type), "".concat(entity, "\u4E2D\u7D22\u5F15\u300C").concat(nameText, "\u300D\u7684\u5C5E\u6027").concat(name_1.text, "\u6709\u5B9A\u4E49\u975E\u6CD5"));
} }
} }
}); });
@ -1077,6 +1082,7 @@ function constructFilter(statements, entity) {
break; break;
} }
case 'Int': case 'Int':
case 'Uint':
case 'Float': case 'Float':
case 'Double': { case 'Double': {
type2 = factory.createTypeReferenceNode(factory.createIdentifier('Q_NumberValue')); type2 = factory.createTypeReferenceNode(factory.createIdentifier('Q_NumberValue'));
@ -1784,14 +1790,11 @@ function constructActions(statements, entity) {
// Selection // Selection
statements.push(factory.createTypeAliasDeclaration(undefined, [factory.createModifier(ts.SyntaxKind.ExportKeyword)], factory.createIdentifier("SelectOperation"), [ statements.push(factory.createTypeAliasDeclaration(undefined, [factory.createModifier(ts.SyntaxKind.ExportKeyword)], factory.createIdentifier("SelectOperation"), [
factory.createTypeParameterDeclaration(undefined, factory.createIdentifier("P"), factory.createTypeReferenceNode(factory.createIdentifier("Object"), undefined), factory.createTypeReferenceNode(factory.createIdentifier("Projection"), undefined)) factory.createTypeParameterDeclaration(undefined, factory.createIdentifier("P"), factory.createTypeReferenceNode(factory.createIdentifier("Object"), undefined), factory.createTypeReferenceNode(factory.createIdentifier("Projection"), undefined))
], factory.createTypeReferenceNode(factory.createIdentifier("Omit"), [ ], factory.createTypeReferenceNode(factory.createIdentifier("OakSelection"), [
factory.createTypeReferenceNode(factory.createIdentifier("OakOperation"), [ factory.createLiteralTypeNode(factory.createStringLiteral("select")),
factory.createLiteralTypeNode(factory.createStringLiteral("select")), factory.createTypeReferenceNode(factory.createIdentifier("P"), undefined),
factory.createTypeReferenceNode(factory.createIdentifier("P"), undefined), factory.createTypeReferenceNode(factory.createIdentifier("Filter"), undefined),
factory.createTypeReferenceNode(factory.createIdentifier("Filter"), undefined), factory.createTypeReferenceNode(factory.createIdentifier("Sorter"), undefined)
factory.createTypeReferenceNode(factory.createIdentifier("Sorter"), undefined)
]),
factory.createLiteralTypeNode(factory.createStringLiteral("id"))
])), factory.createTypeAliasDeclaration(undefined, [factory.createModifier(ts.SyntaxKind.ExportKeyword)], factory.createIdentifier("Selection"), [ ])), factory.createTypeAliasDeclaration(undefined, [factory.createModifier(ts.SyntaxKind.ExportKeyword)], factory.createIdentifier("Selection"), [
factory.createTypeParameterDeclaration(undefined, factory.createIdentifier("P"), factory.createTypeReferenceNode(factory.createIdentifier("Object"), undefined), factory.createTypeReferenceNode(factory.createIdentifier("Projection"), undefined)) factory.createTypeParameterDeclaration(undefined, factory.createIdentifier("P"), factory.createTypeReferenceNode(factory.createIdentifier("Object"), undefined), factory.createTypeReferenceNode(factory.createIdentifier("Projection"), undefined))
], factory.createTypeReferenceNode(factory.createIdentifier("Omit"), [ ], factory.createTypeReferenceNode(factory.createIdentifier("Omit"), [
@ -1799,13 +1802,10 @@ function constructActions(statements, entity) {
factory.createTypeReferenceNode(factory.createIdentifier("P"), undefined) factory.createTypeReferenceNode(factory.createIdentifier("P"), undefined)
]), ]),
factory.createLiteralTypeNode(factory.createStringLiteral("action")) factory.createLiteralTypeNode(factory.createStringLiteral("action"))
])), factory.createTypeAliasDeclaration(undefined, [factory.createToken(ts.SyntaxKind.ExportKeyword)], factory.createIdentifier("Aggregation"), undefined, factory.createTypeReferenceNode(factory.createIdentifier("Omit"), [ ])), factory.createTypeAliasDeclaration(undefined, [factory.createToken(ts.SyntaxKind.ExportKeyword)], factory.createIdentifier("Aggregation"), undefined, factory.createTypeReferenceNode(factory.createIdentifier("DeduceAggregation"), [
factory.createTypeReferenceNode(factory.createIdentifier("DeduceAggregation"), [ factory.createTypeReferenceNode(factory.createIdentifier("Projection"), undefined),
factory.createTypeReferenceNode(factory.createIdentifier("Projection"), undefined), factory.createTypeReferenceNode(factory.createIdentifier("Filter"), undefined),
factory.createTypeReferenceNode(factory.createIdentifier("Filter"), undefined), factory.createTypeReferenceNode(factory.createIdentifier("Sorter"), undefined)
factory.createTypeReferenceNode(factory.createIdentifier("Sorter"), undefined)
]),
factory.createLiteralTypeNode(factory.createStringLiteral("id"))
]))); ])));
// Exportation // Exportation
// 已经废弃by Xc 2023.01.08 // 已经废弃by Xc 2023.01.08
@ -2297,7 +2297,7 @@ function constructActions(statements, entity) {
var _loop_9 = function (entityName) { var _loop_9 = function (entityName) {
var entityNameLc = (0, string_1.firstLetterLowerCase)(entityName); var entityNameLc = (0, string_1.firstLetterLowerCase)(entityName);
foreignKeySet[entityName].forEach(function (foreignKey) { foreignKeySet[entityName].forEach(function (foreignKey) {
var identifier = "".concat(entityNameLc, "s$").concat(foreignKey); var identifier = "".concat(entityNameLc, "$").concat(foreignKey);
var otmCreateOperationDataNode = factory.createTypeReferenceNode(factory.createIdentifier("Omit"), [ var otmCreateOperationDataNode = factory.createTypeReferenceNode(factory.createIdentifier("Omit"), [
factory.createTypeReferenceNode(createForeignRef(entity, entityName, 'CreateOperationData'), undefined), factory.createTypeReferenceNode(createForeignRef(entity, entityName, 'CreateOperationData'), undefined),
factory.createUnionTypeNode(foreignKey === 'entity' ? [ factory.createUnionTypeNode(foreignKey === 'entity' ? [
@ -2612,6 +2612,7 @@ var initialStatements = function () { return [
factory.createImportDeclaration(undefined, undefined, factory.createImportClause(false, undefined, factory.createNamedImports([ factory.createImportDeclaration(undefined, undefined, factory.createImportClause(false, undefined, factory.createNamedImports([
factory.createImportSpecifier(false, undefined, factory.createIdentifier('String')), factory.createImportSpecifier(false, undefined, factory.createIdentifier('String')),
factory.createImportSpecifier(false, undefined, factory.createIdentifier('Int')), factory.createImportSpecifier(false, undefined, factory.createIdentifier('Int')),
factory.createImportSpecifier(false, undefined, factory.createIdentifier('Uint')),
factory.createImportSpecifier(false, undefined, factory.createIdentifier('Float')), factory.createImportSpecifier(false, undefined, factory.createIdentifier('Float')),
factory.createImportSpecifier(false, undefined, factory.createIdentifier('Double')), factory.createImportSpecifier(false, undefined, factory.createIdentifier('Double')),
factory.createImportSpecifier(false, undefined, factory.createIdentifier('Boolean')), factory.createImportSpecifier(false, undefined, factory.createIdentifier('Boolean')),
@ -2653,6 +2654,7 @@ var initialStatements = function () { return [
factory.createImportSpecifier(false, undefined, factory.createIdentifier("FormUpdateData")), factory.createImportSpecifier(false, undefined, factory.createIdentifier("FormUpdateData")),
factory.createImportSpecifier(false, undefined, factory.createIdentifier("DeduceAggregation")), factory.createImportSpecifier(false, undefined, factory.createIdentifier("DeduceAggregation")),
factory.createImportSpecifier(false, factory.createIdentifier("Operation"), factory.createIdentifier("OakOperation")), factory.createImportSpecifier(false, factory.createIdentifier("Operation"), factory.createIdentifier("OakOperation")),
factory.createImportSpecifier(false, factory.createIdentifier("Selection"), factory.createIdentifier("OakSelection")),
factory.createImportSpecifier(false, factory.createIdentifier("MakeAction"), factory.createIdentifier("OakMakeAction")), factory.createImportSpecifier(false, factory.createIdentifier("MakeAction"), factory.createIdentifier("OakMakeAction")),
factory.createImportSpecifier(false, undefined, factory.createIdentifier("EntityShape")), factory.createImportSpecifier(false, undefined, factory.createIdentifier("EntityShape")),
factory.createImportSpecifier(false, undefined, factory.createIdentifier("AggregationResult")), factory.createImportSpecifier(false, undefined, factory.createIdentifier("AggregationResult")),

View File

@ -529,7 +529,7 @@ var CascadeStore = /** @class */ (function (_super) {
var _g = tslib_1.__read(relation, 2), entityOtm_1 = _g[0], foreignKey_2 = _g[1]; var _g = tslib_1.__read(relation, 2), entityOtm_1 = _g[0], foreignKey_2 = _g[1];
var otmOperations = data[attr]; var otmOperations = data[attr];
var dealWithOneToMany = function (otm) { var dealWithOneToMany = function (otm) {
var _a, _b, _c, _d; var _a, _b, _c, _d, _e;
var actionOtm = otm.action, dataOtm = otm.data, filterOtm = otm.filter; var actionOtm = otm.action, dataOtm = otm.data, filterOtm = otm.filter;
if (!foreignKey_2) { if (!foreignKey_2) {
// 基于entity/entityId的one-to-many // 基于entity/entityId的one-to-many
@ -550,7 +550,7 @@ var CascadeStore = /** @class */ (function (_super) {
} }
else if (actionOtm === 'create') { else if (actionOtm === 'create') {
// 这里先假设A必是update的filter上一定有id否则用户界面上应该设计不出来这样的操作 // 这里先假设A必是update的filter上一定有id否则用户界面上应该设计不出来这样的操作
// todo 这个假设成立吗?等遇到create/create一对多的case再完善 // todo 这个假设对watcher等后台行为可能不成立等遇到create/create一对多的case再完善
var id_2 = filter.id; var id_2 = filter.id;
(0, assert_1.default)(typeof id_2 === 'string'); (0, assert_1.default)(typeof id_2 === 'string');
if (dataOtm instanceof Array) { if (dataOtm instanceof Array) {
@ -569,12 +569,10 @@ var CascadeStore = /** @class */ (function (_super) {
else { else {
// 这里先假设A必是update的filter上一定有id否则用户界面上应该设计不出来这样的操作 // 这里先假设A必是update的filter上一定有id否则用户界面上应该设计不出来这样的操作
// 这个倒是好像不可能出现create/update的一对多如果遇到了再完善 // 这个倒是好像不可能出现create/update的一对多如果遇到了再完善
var id = filter.id;
Object.assign(otm, { Object.assign(otm, {
filter: (0, filter_1.addFilterSegment)({ filter: (0, filter_1.addFilterSegment)((_a = {},
entity: entity, _a[entity] = filter,
entityId: id, _a), filterOtm),
}, filterOtm),
}); });
if (action === 'remove' && actionOtm === 'update') { if (action === 'remove' && actionOtm === 'update') {
Object.assign(dataOtm, { Object.assign(dataOtm, {
@ -597,14 +595,14 @@ var CascadeStore = /** @class */ (function (_super) {
}); });
} }
else { else {
Object.assign(dataOtm, (_a = {}, Object.assign(dataOtm, (_b = {},
_a[foreignKey_2] = id_3, _b[foreignKey_2] = id_3,
_a)); _b));
} }
} }
else if (actionOtm === 'create') { else if (actionOtm === 'create') {
// 这里先假设A必是update的filter上一定有id否则用户界面上应该设计不出来这样的操作 // 这里先假设A必是update的filter上一定有id否则用户界面上应该设计不出来这样的操作
// todo 这个假设成立吗等遇到create/create一对多的case再完善 // todo 这个假设在后台可能不成立,等遇到了再说
var id_4 = filter.id; var id_4 = filter.id;
(0, assert_1.default)(typeof id_4 === 'string'); (0, assert_1.default)(typeof id_4 === 'string');
if (dataOtm instanceof Array) { if (dataOtm instanceof Array) {
@ -616,28 +614,26 @@ var CascadeStore = /** @class */ (function (_super) {
}); });
} }
else { else {
Object.assign(dataOtm, (_b = {}, Object.assign(dataOtm, (_c = {},
_b[foreignKey_2] = id_4, _c[foreignKey_2] = id_4,
_b)); _c));
} }
} }
else { else {
// 这里先假设A必是update的filter上一定有id否则用户界面上应该设计不出来这样的操作 // update可能出现上层filter不是根据id的userEntityGrant的过期触发的wechatQrCode的过期见general中的userEntityGrant的trigger
// 这个倒是好像不可能出现create/update的一对多如果遇到了再完善
var id = filter.id;
Object.assign(otm, { Object.assign(otm, {
filter: (0, filter_1.addFilterSegment)((_c = {}, filter: (0, filter_1.addFilterSegment)((_d = {},
_c[foreignKey_2] = id, _d[foreignKey_2.slice(0, foreignKey_2.length - 2)] = filter,
_c), filterOtm), _d), filterOtm),
}); });
if (action === 'remove' && actionOtm === 'update') { if (action === 'remove' && actionOtm === 'update') {
Object.assign(dataOtm, (_d = {}, Object.assign(dataOtm, (_e = {},
_d[foreignKey_2] = null, _e[foreignKey_2] = null,
_d)); _e));
} }
} }
} }
afterFns.push(function () { return cascadeUpdate.call(_this, entityOtm_1, otm, context, option2); }); beforeFns.push(function () { return cascadeUpdate.call(_this, entityOtm_1, otm, context, option2); });
}; };
if (otmOperations instanceof Array) { if (otmOperations instanceof Array) {
try { try {

View File

@ -16,7 +16,7 @@ export declare class TriggerExecutor<ED extends EntityDict & BaseEntityDict> {
private contextBuilder; private contextBuilder;
constructor(contextBuilder: (cxtString: string) => Promise<AsyncContext<ED>>, logger?: Logger); constructor(contextBuilder: (cxtString: string) => Promise<AsyncContext<ED>>, logger?: Logger);
registerChecker<T extends keyof ED, Cxt extends AsyncContext<ED>>(checker: Checker<ED, T, Cxt>): void; registerChecker<T extends keyof ED, Cxt extends AsyncContext<ED>>(checker: Checker<ED, T, Cxt>): void;
getCheckers<T extends keyof ED>(entity: T, action: ED[T]['Action'], checkerTypes?: CheckerType[]): Trigger<ED, T, AsyncContext<ED>>[]; getCheckers<T extends keyof ED>(entity: T, action: ED[T]['Action'], checkerTypes?: CheckerType[]): Trigger<ED, T, AsyncContext<ED>>[] | undefined;
registerTrigger<T extends keyof ED, Cxt extends AsyncContext<ED>>(trigger: Trigger<ED, T, Cxt>): void; registerTrigger<T extends keyof ED, Cxt extends AsyncContext<ED>>(trigger: Trigger<ED, T, Cxt>): void;
unregisterTrigger<T extends keyof ED, Cxt extends AsyncContext<ED>>(trigger: Trigger<ED, T, Cxt>): void; unregisterTrigger<T extends keyof ED, Cxt extends AsyncContext<ED>>(trigger: Trigger<ED, T, Cxt>): void;
private preCommitTrigger; private preCommitTrigger;

View File

@ -2,6 +2,9 @@
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.analyzeActionDefDict = exports.getFullProjection = void 0; exports.analyzeActionDefDict = exports.getFullProjection = void 0;
var tslib_1 = require("tslib"); var tslib_1 = require("tslib");
var types_1 = require("../types");
var lodash_1 = require("../utils/lodash");
var filter_1 = require("./filter");
function getFullProjection(entity, schema) { function getFullProjection(entity, schema) {
var attributes = schema[entity].attributes; var attributes = schema[entity].attributes;
var projection = { var projection = {
@ -20,56 +23,116 @@ function getFullProjection(entity, schema) {
} }
exports.getFullProjection = getFullProjection; exports.getFullProjection = getFullProjection;
function makeIntrinsicWatchers(schema) { function makeIntrinsicWatchers(schema) {
var _this = this;
var watchers = []; var watchers = [];
var _loop_1 = function (entity) { for (var entity in schema) {
var attributes = schema[entity].attributes; var attributes = schema[entity].attributes;
var now = Date.now();
var expiresAt = attributes.expiresAt, expired = attributes.expired; var expiresAt = attributes.expiresAt, expired = attributes.expired;
if (expiresAt && expiresAt.type === 'datetime' && expired && expired.type === 'boolean') { if (expiresAt && expiresAt.type === 'datetime' && expired && expired.type === 'boolean') {
// 如果有定义expiresAt和expired则自动生成一个检查的watcher // 如果有定义expiresAt和expired则自动生成一个检查的watcher
watchers.push({ watchers.push({
entity: entity, entity: entity,
name: "\u5BF9\u8C61".concat(entity, "\u4E0A\u7684\u8FC7\u671F\u81EA\u52A8watcher"), name: "\u5BF9\u8C61".concat(entity, "\u4E0A\u7684\u8FC7\u671F\u81EA\u52A8watcher"),
filter: function () { return tslib_1.__awaiter(_this, void 0, void 0, function () { filter: function () {
return tslib_1.__generator(this, function (_a) { return {
return [2 /*return*/, { expired: false,
expired: false, expiresAt: {
expiresAt: { $lte: Date.now(),
$lte: now, },
}, };
}]; },
});
}); },
action: 'update', action: 'update',
actionData: { actionData: {
expired: true, expired: true,
}, },
}); });
} }
};
for (var entity in schema) {
_loop_1(entity);
} }
return watchers; return watchers;
} }
function checkUniqueBetweenRows(rows, uniqAttrs) {
// 先检查这些行本身之间有无unique冲突
var uniqRows = (0, lodash_1.uniqBy)(rows, function (d) {
var e_1, _a;
var s = '';
try {
for (var uniqAttrs_1 = tslib_1.__values(uniqAttrs), uniqAttrs_1_1 = uniqAttrs_1.next(); !uniqAttrs_1_1.done; uniqAttrs_1_1 = uniqAttrs_1.next()) {
var a = uniqAttrs_1_1.value;
if (d[a] === null || d[a] === undefined) {
s + d.id;
}
else {
s + "-".concat(d[a]);
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (uniqAttrs_1_1 && !uniqAttrs_1_1.done && (_a = uniqAttrs_1.return)) _a.call(uniqAttrs_1);
}
finally { if (e_1) throw e_1.error; }
}
return s;
});
if (uniqRows.length < rows.length) {
throw new types_1.OakUniqueViolationException([{
attrs: uniqAttrs,
}]);
}
}
function checkCountLessThan(count, uniqAttrs, than, id) {
if (than === void 0) { than = 0; }
if (count instanceof Promise) {
return count.then(function (count2) {
if (count2 > than) {
throw new types_1.OakUniqueViolationException([{
id: id,
attrs: uniqAttrs,
}]);
}
});
}
if (count > than) {
throw new types_1.OakUniqueViolationException([{
id: id,
attrs: uniqAttrs,
}]);
}
}
function checkUnique(entity, row, context, uniqAttrs, extraFilter) {
var filter = (0, lodash_1.pick)(row, uniqAttrs);
for (var a in filter) {
if (filter[a] === null || filter[a] === undefined) {
delete filter[a];
}
}
if (Object.keys(filter).length < uniqAttrs.length) {
// 说明有null值不需要检查约束
return;
}
var filter2 = extraFilter ? (0, filter_1.addFilterSegment)([filter, extraFilter]) : filter;
var count = context.count(entity, { filter: filter2 }, { dontCollect: true });
return checkCountLessThan(count, uniqAttrs, 0, row.id);
}
function analyzeActionDefDict(schema, actionDefDict) { function analyzeActionDefDict(schema, actionDefDict) {
var _a;
var checkers = []; var checkers = [];
var triggers = []; var triggers = [];
// action状态转换矩阵相应的checker
for (var entity in actionDefDict) { for (var entity in actionDefDict) {
var _loop_2 = function (attr) { var _loop_1 = function (attr) {
var def = actionDefDict[entity][attr]; var def = actionDefDict[entity][attr];
var _a = def, stm = _a.stm, is = _a.is; var _b = def, stm = _b.stm, is = _b.is;
var _loop_3 = function (action) { var _loop_3 = function (action) {
var _b, _c; var _c, _d;
var actionStm = stm[action]; var actionStm = stm[action];
var conditionalFilter = typeof actionStm[0] === 'string' ? (_b = {}, var conditionalFilter = typeof actionStm[0] === 'string' ? (_c = {},
_b[attr] = actionStm[0], _c[attr] = actionStm[0],
_b) : (_c = {}, _c) : (_d = {},
_c[attr] = { _d[attr] = {
$in: actionStm[0], $in: actionStm[0],
}, },
_c); _d);
checkers.push({ checkers.push({
action: action, action: action,
type: 'row', type: 'row',
@ -123,9 +186,144 @@ function analyzeActionDefDict(schema, actionDefDict) {
} }
}; };
for (var attr in actionDefDict[entity]) { for (var attr in actionDefDict[entity]) {
_loop_2(attr); _loop_1(attr);
} }
} }
var _loop_2 = function (entity) {
var e_2, _e;
var indexes = schema[entity].indexes;
if (indexes) {
var _loop_4 = function (index) {
if ((_a = index.config) === null || _a === void 0 ? void 0 : _a.unique) {
var attributes = index.attributes;
var uniqAttrs_2 = attributes.map(function (ele) { return ele.name; });
checkers.push({
entity: entity,
action: 'create',
type: 'logical',
priority: 20,
checker: function (operation, context) {
var data = operation.data;
if (data instanceof Array) {
checkUniqueBetweenRows(data, uniqAttrs_2);
var checkResult = data.map(function (ele) { return checkUnique(entity, ele, context, uniqAttrs_2); });
if (checkResult[0] instanceof Promise) {
return Promise.all(checkResult).then(function () { return undefined; });
}
}
else {
return checkUnique(entity, data, context, uniqAttrs_2);
}
}
}, {
entity: entity,
action: 'update',
type: 'logical',
priority: 20,
checker: function (operation, context) {
var e_3, _a, e_4, _b, _c;
var _d = operation, data = _d.data, operationFilter = _d.filter;
var attrs = Object.keys(data);
var refAttrs = (0, lodash_1.intersection)(attrs, uniqAttrs_2);
if (refAttrs.length === 0) {
// 如果本次更新和unique约束的属性之间没有交集则直接返回
return;
}
try {
for (var refAttrs_1 = (e_3 = void 0, tslib_1.__values(refAttrs)), refAttrs_1_1 = refAttrs_1.next(); !refAttrs_1_1.done; refAttrs_1_1 = refAttrs_1.next()) {
var attr = refAttrs_1_1.value;
// 如果有更新为null值不用再检查约束
if (data[attr] === null || data[attr] === undefined) {
return;
}
}
}
catch (e_3_1) { e_3 = { error: e_3_1 }; }
finally {
try {
if (refAttrs_1_1 && !refAttrs_1_1.done && (_a = refAttrs_1.return)) _a.call(refAttrs_1);
}
finally { if (e_3) throw e_3.error; }
}
if (refAttrs.length === uniqAttrs_2.length) {
// 如果更新了全部属性,直接检查
var filter = (0, lodash_1.pick)(data, refAttrs);
// 在这些行以外的行不和更新后的键值冲突
var count = context.count(entity, {
filter: (0, filter_1.addFilterSegment)([filter, {
$not: operationFilter,
}]),
}, { dontCollect: true });
var checkCount = checkCountLessThan(count, uniqAttrs_2);
// 更新的行只能有一行
var rowCount = context.count(entity, {
filter: operationFilter,
}, { dontCollect: true });
var checkRowCount = checkCountLessThan(rowCount, uniqAttrs_2, 1);
// 如果更新的行数为零似乎也可以但这应该不可能出现吧by Xc 20230131
if (checkRowCount instanceof Promise) {
return Promise.all([checkCount, checkRowCount]).then(function () { return undefined; });
}
}
// 否则需要结合本行现有的属性来进行检查
var projection = { id: 1 };
try {
for (var uniqAttrs_3 = (e_4 = void 0, tslib_1.__values(uniqAttrs_2)), uniqAttrs_3_1 = uniqAttrs_3.next(); !uniqAttrs_3_1.done; uniqAttrs_3_1 = uniqAttrs_3.next()) {
var attr = uniqAttrs_3_1.value;
Object.assign(projection, (_c = {},
_c[attr] = 1,
_c));
}
}
catch (e_4_1) { e_4 = { error: e_4_1 }; }
finally {
try {
if (uniqAttrs_3_1 && !uniqAttrs_3_1.done && (_b = uniqAttrs_3.return)) _b.call(uniqAttrs_3);
}
finally { if (e_4) throw e_4.error; }
}
var checkWithRows = function (rows2) {
var rows22 = rows2.map(function (ele) { return Object.assign(ele, data); });
// 先检查这些行本身之间是否冲突
checkUniqueBetweenRows(rows22, uniqAttrs_2);
var checkResults = rows22.map(function (row) { return checkUnique(entity, row, context, uniqAttrs_2, {
$not: operationFilter
}); });
if (checkResults[0] instanceof Promise) {
return Promise.all(checkResults).then(function () { return undefined; });
}
};
var currentRows = context.select(entity, {
data: projection,
filter: operationFilter,
}, { dontCollect: true });
if (currentRows instanceof Promise) {
return currentRows.then(function (row2) { return checkWithRows(row2); });
}
return checkWithRows(currentRows);
}
});
}
};
try {
for (var indexes_1 = (e_2 = void 0, tslib_1.__values(indexes)), indexes_1_1 = indexes_1.next(); !indexes_1_1.done; indexes_1_1 = indexes_1.next()) {
var index = indexes_1_1.value;
_loop_4(index);
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (indexes_1_1 && !indexes_1_1.done && (_e = indexes_1.return)) _e.call(indexes_1);
}
finally { if (e_2) throw e_2.error; }
}
}
};
// unique索引相应的checker
for (var entity in schema) {
_loop_2(entity);
}
return { return {
triggers: triggers, triggers: triggers,
checkers: checkers, checkers: checkers,

10
lib/types/Action.d.ts vendored
View File

@ -1,18 +1,18 @@
import { CascadeRelationItem, EntityDict } from "./Entity"; import { CascadeRelationItem, EntityDict } from "./Entity";
import { GenericAction } from '../actions/action'; import { GenericAction } from '../actions/action';
export type Action = string; export declare type Action = string;
export type State = string; export declare type State = string;
export type ActionDef<A extends Action, S extends State> = { export declare type ActionDef<A extends Action, S extends State> = {
stm: { stm: {
[a in A]: [p: S | S[], n: S]; [a in A]: [p: S | S[], n: S];
}; };
is?: S; is?: S;
}; };
export type ActionDictOfEntityDict<E extends EntityDict> = { export declare type ActionDictOfEntityDict<E extends EntityDict> = {
[T in keyof E]?: { [T in keyof E]?: {
[A in keyof E[T]['OpSchema']]?: ActionDef<string, string>; [A in keyof E[T]['OpSchema']]?: ActionDef<string, string>;
}; };
}; };
export type CascadeActionAuth<A extends Action = ''> = { export declare type CascadeActionAuth<A extends Action = ''> = {
[K in A | GenericAction]?: CascadeRelationItem | (CascadeRelationItem | CascadeRelationItem[])[]; [K in A | GenericAction]?: CascadeRelationItem | (CascadeRelationItem | CascadeRelationItem[])[];
}; };

18
lib/types/Auth.d.ts vendored
View File

@ -2,12 +2,12 @@ import { CascadeActionAuth, CascadeRelationAuth } from ".";
import { AsyncContext } from "../store/AsyncRowStore"; import { AsyncContext } from "../store/AsyncRowStore";
import { SyncContext } from "../store/SyncRowStore"; import { SyncContext } from "../store/SyncRowStore";
import { EntityDict, OperateOption, SelectOption } from "../types/Entity"; import { EntityDict, OperateOption, SelectOption } from "../types/Entity";
export type CheckerType = 'relation' | 'row' | 'data' | 'logical' | 'logicalRelation'; export declare type CheckerType = 'relation' | 'row' | 'data' | 'logical' | 'logicalRelation';
/** /**
* conditionalFilter是指该action发生时operation所操作的行中有满足conditionalFilter的行 * conditionalFilter是指该action发生时operation所操作的行中有满足conditionalFilter的行
* trigger的filter条件trigger中的说明 * trigger的filter条件trigger中的说明
*/ */
export type DataChecker<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> = { export declare type DataChecker<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> = {
priority?: number; priority?: number;
type: 'data'; type: 'data';
entity: T; entity: T;
@ -15,7 +15,7 @@ export type DataChecker<ED extends EntityDict, T extends keyof ED, Cxt extends A
checker: (data: ED[T]['Create']['data'] | ED[T]['Update']['data'], context: Cxt) => void | Promise<void>; checker: (data: ED[T]['Create']['data'] | ED[T]['Update']['data'], context: Cxt) => void | Promise<void>;
conditionalFilter?: ED[T]['Update']['filter'] | ((operation: ED[T]['Operation'], context: Cxt, option: OperateOption) => ED[T]['Update']['filter'] | Promise<ED[T]['Selection']['filter']>); conditionalFilter?: ED[T]['Update']['filter'] | ((operation: ED[T]['Operation'], context: Cxt, option: OperateOption) => ED[T]['Update']['filter'] | Promise<ED[T]['Selection']['filter']>);
}; };
export type RowChecker<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> = { export declare type RowChecker<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> = {
priority?: number; priority?: number;
type: 'row'; type: 'row';
entity: T; entity: T;
@ -28,7 +28,7 @@ export type RowChecker<ED extends EntityDict, T extends keyof ED, Cxt extends As
}; };
conditionalFilter?: ED[T]['Update']['filter'] | ((operation: ED[T]['Operation'], context: Cxt, option: OperateOption) => ED[T]['Update']['filter'] | Promise<ED[T]['Update']['filter']>); conditionalFilter?: ED[T]['Update']['filter'] | ((operation: ED[T]['Operation'], context: Cxt, option: OperateOption) => ED[T]['Update']['filter'] | Promise<ED[T]['Update']['filter']>);
}; };
export type RelationChecker<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> = { export declare type RelationChecker<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> = {
priority?: number; priority?: number;
type: 'relation'; type: 'relation';
entity: T; entity: T;
@ -38,7 +38,7 @@ export type RelationChecker<ED extends EntityDict, T extends keyof ED, Cxt exten
errMsg: string; errMsg: string;
conditionalFilter?: ED[T]['Update']['filter'] | ((operation: ED[T]['Operation'], context: Cxt, option: OperateOption) => ED[T]['Update']['filter'] | Promise<ED[T]['Selection']['filter']>); conditionalFilter?: ED[T]['Update']['filter'] | ((operation: ED[T]['Operation'], context: Cxt, option: OperateOption) => ED[T]['Update']['filter'] | Promise<ED[T]['Selection']['filter']>);
}; };
export type LogicalChecker<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> = { export declare type LogicalChecker<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> = {
priority?: number; priority?: number;
type: 'logical'; type: 'logical';
when?: 'after'; when?: 'after';
@ -47,7 +47,7 @@ export type LogicalChecker<ED extends EntityDict, T extends keyof ED, Cxt extend
checker: (operation: ED[T]['Operation'] | ED[T]['Selection'], context: Cxt, option: OperateOption | SelectOption) => void | Promise<void>; checker: (operation: ED[T]['Operation'] | ED[T]['Selection'], context: Cxt, option: OperateOption | SelectOption) => void | Promise<void>;
conditionalFilter?: ED[T]['Update']['filter'] | ((operation: ED[T]['Operation'], context: Cxt, option: OperateOption) => ED[T]['Update']['filter']); conditionalFilter?: ED[T]['Update']['filter'] | ((operation: ED[T]['Operation'], context: Cxt, option: OperateOption) => ED[T]['Update']['filter']);
}; };
export type LogicalRelationChecker<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> = { export declare type LogicalRelationChecker<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> = {
priority?: number; priority?: number;
type: 'logicalRelation'; type: 'logicalRelation';
when?: 'after'; when?: 'after';
@ -56,11 +56,11 @@ export type LogicalRelationChecker<ED extends EntityDict, T extends keyof ED, Cx
checker: (operation: ED[T]['Operation'] | ED[T]['Selection'], context: Cxt, option: OperateOption | SelectOption) => void | Promise<void>; checker: (operation: ED[T]['Operation'] | ED[T]['Selection'], context: Cxt, option: OperateOption | SelectOption) => void | Promise<void>;
conditionalFilter?: ED[T]['Update']['filter'] | ((operation: ED[T]['Operation'], context: Cxt, option: OperateOption) => ED[T]['Update']['filter']); conditionalFilter?: ED[T]['Update']['filter'] | ((operation: ED[T]['Operation'], context: Cxt, option: OperateOption) => ED[T]['Update']['filter']);
}; };
export type Checker<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> = DataChecker<ED, T, Cxt> | RowChecker<ED, T, Cxt> | RelationChecker<ED, T, Cxt> | LogicalChecker<ED, T, Cxt> | LogicalRelationChecker<ED, T, Cxt>; export declare type Checker<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> = DataChecker<ED, T, Cxt> | RowChecker<ED, T, Cxt> | RelationChecker<ED, T, Cxt> | LogicalChecker<ED, T, Cxt> | LogicalRelationChecker<ED, T, Cxt>;
export type AuthDef<ED extends EntityDict, T extends keyof ED> = { export declare type AuthDef<ED extends EntityDict, T extends keyof ED> = {
relationAuth?: CascadeRelationAuth<NonNullable<ED[T]['Relation']>>; relationAuth?: CascadeRelationAuth<NonNullable<ED[T]['Relation']>>;
actionAuth?: CascadeActionAuth<ED[T]['Action']>; actionAuth?: CascadeActionAuth<ED[T]['Action']>;
}; };
export type AuthDefDict<ED extends EntityDict> = { export declare type AuthDefDict<ED extends EntityDict> = {
[K in keyof ED]?: AuthDef<ED, K>; [K in keyof ED]?: AuthDef<ED, K>;
}; };

View File

@ -1,18 +1,18 @@
import { Geo, SingleGeo } from "./Geo"; import { Geo, SingleGeo } from "./Geo";
export type Int<L extends 1 | 2 | 4 | 8> = number; export declare type Int<L extends 1 | 2 | 4 | 8> = number;
export type Uint<L extends 1 | 2 | 4 | 8> = number; export declare type Uint<L extends 1 | 2 | 4 | 8> = number;
export type Double<P extends number, S extends number> = number; export declare type Double<P extends number, S extends number> = number;
export type Float<P extends number, S extends number> = number; export declare type Float<P extends number, S extends number> = number;
export type String<L extends number> = string; export declare type String<L extends number> = string;
export type Text = string; export declare type Text = string;
export type Image = string; export declare type Image = string;
export type File = string; export declare type File = string;
export type Datetime = number | Date; export declare type Datetime = number | Date;
export type Boolean = boolean; export declare type Boolean = boolean;
export type PrimaryKey = string; export declare type PrimaryKey = string;
export type ForeignKey<E extends string> = string; export declare type ForeignKey<E extends string> = string;
export type Sequence = string; export declare type Sequence = string;
export { Geo, SingleGeo } from './Geo'; export { Geo, SingleGeo } from './Geo';
export type DataTypes = number | string | Datetime | Geo | Object | SingleGeo; export declare type DataTypes = number | string | Datetime | Geo | Object | SingleGeo;
export declare const types: string[]; export declare const types: string[];
export declare const unIndexedTypes: string[]; export declare const unIndexedTypes: string[];

46
lib/types/Demand.d.ts vendored
View File

@ -1,12 +1,12 @@
import { RefOrExpression } from "./Expression"; import { RefOrExpression } from "./Expression";
import { OneOf } from "./Polyfill"; import { OneOf } from "./Polyfill";
export declare const EXPRESSION_PREFIX = "$expr"; export declare const EXPRESSION_PREFIX = "$expr";
export type NodeId = `node-${number}`; export declare type NodeId = `node-${number}`;
export type ExpressionKey = '$expr' | '$expr1' | '$expr2' | '$expr3' | '$expr4' | '$expr5' | '$expr6' | '$expr7' | '$expr8' | '$expr9' | '$expr10' | '$expr11' | '$expr12' | '$expr13' | '$expr14' | '$expr15' | '$expr16' | '$expr17' | '$expr18' | '$expr19' | '$expr20'; export declare type ExpressionKey = '$expr' | '$expr1' | '$expr2' | '$expr3' | '$expr4' | '$expr5' | '$expr6' | '$expr7' | '$expr8' | '$expr9' | '$expr10' | '$expr11' | '$expr12' | '$expr13' | '$expr14' | '$expr15' | '$expr16' | '$expr17' | '$expr18' | '$expr19' | '$expr20';
export type ExprOp<A> = { export declare type ExprOp<A> = {
[K in ExpressionKey]: RefOrExpression<A>; [K in ExpressionKey]: RefOrExpression<A>;
}; };
export type Q_NumberComparisonValue = number | OneOf<{ export declare type Q_NumberComparisonValue = number | OneOf<{
$gt: number; $gt: number;
$lt: number; $lt: number;
$gte: number; $gte: number;
@ -17,7 +17,7 @@ export type Q_NumberComparisonValue = number | OneOf<{
$nin: number[]; $nin: number[];
$between: [number, number]; $between: [number, number];
}>; }>;
export type Q_StringComparisonValue = string | OneOf<{ export declare type Q_StringComparisonValue = string | OneOf<{
$gt: string; $gt: string;
$lt: string; $lt: string;
$gte: string; $gte: string;
@ -30,44 +30,44 @@ export type Q_StringComparisonValue = string | OneOf<{
$in: string[]; $in: string[];
$nin: string[]; $nin: string[];
}>; }>;
export type Q_BooleanComparisonValue = boolean; export declare type Q_BooleanComparisonValue = boolean;
export type Q_DateComparisonValue = Q_NumberComparisonValue; export declare type Q_DateComparisonValue = Q_NumberComparisonValue;
export type Q_EnumComparisonValue<E> = E | OneOf<{ export declare type Q_EnumComparisonValue<E> = E | OneOf<{
$in: E[]; $in: E[];
$nin: E[]; $nin: E[];
}>; }>;
export type Q_ExistsValue = { export declare type Q_ExistsValue = {
$exists: boolean; $exists: boolean;
}; };
export type Q_NumberValue = Q_NumberComparisonValue | Q_ExistsValue; export declare type Q_NumberValue = Q_NumberComparisonValue | Q_ExistsValue;
export type Q_StringValue = Q_StringComparisonValue | Q_ExistsValue; export declare type Q_StringValue = Q_StringComparisonValue | Q_ExistsValue;
export type Q_BooleanValue = Q_BooleanComparisonValue | Q_ExistsValue; export declare type Q_BooleanValue = Q_BooleanComparisonValue | Q_ExistsValue;
export type Q_DateValue = Q_DateComparisonValue | Q_ExistsValue; export declare type Q_DateValue = Q_DateComparisonValue | Q_ExistsValue;
export type Q_EnumValue<E> = Q_EnumComparisonValue<E> | Q_ExistsValue; export declare type Q_EnumValue<E> = Q_EnumComparisonValue<E> | Q_ExistsValue;
export type Q_State<S> = S | { export declare type Q_State<S> = S | {
$in: S[]; $in: S[];
} | { } | {
$nin: S[]; $nin: S[];
} | Q_ExistsValue; } | Q_ExistsValue;
export type Q_FullTextValue = { export declare type Q_FullTextValue = {
$search: string; $search: string;
$language?: 'zh_CN' | 'en_US'; $language?: 'zh_CN' | 'en_US';
}; };
export type Q_FullTextKey = '$text'; export declare type Q_FullTextKey = '$text';
export type FulltextFilter = { export declare type FulltextFilter = {
[F in Q_FullTextKey]?: Q_FullTextValue; [F in Q_FullTextKey]?: Q_FullTextValue;
}; };
type Q_LogicKey = '$and' | '$or'; declare type Q_LogicKey = '$and' | '$or';
type Q_LinearLogicKey = '$not'; declare type Q_LinearLogicKey = '$not';
export type MakeFilterWrapper<F extends Object> = { export declare type MakeFilterWrapper<F extends Object> = {
[Q in Q_LogicKey]?: Array<MakeFilterWrapper<F>>; [Q in Q_LogicKey]?: Array<MakeFilterWrapper<F>>;
} & { } & {
[Q in Q_LinearLogicKey]?: MakeFilterWrapper<F>; [Q in Q_LinearLogicKey]?: MakeFilterWrapper<F>;
} & Partial<F>; } & Partial<F>;
export type MakeFilter<F extends Object> = { export declare type MakeFilter<F extends Object> = {
'#id'?: NodeId; '#id'?: NodeId;
} & MakeFilterWrapper<F>; } & MakeFilterWrapper<F>;
export type RefAttr<A> = { export declare type RefAttr<A> = {
'#attr': A; '#attr': A;
} | { } | {
'#refId': NodeId; '#refId': NodeId;

View File

@ -8,4 +8,4 @@ export interface EndpointItem<ED extends EntityDict, BackCxt extends AsyncContex
method: 'get' | 'post' | 'put' | 'delete'; method: 'get' | 'post' | 'put' | 'delete';
fn: (context: BackCxt, params: Record<string, string>, headers: IncomingHttpHeaders, req: IncomingMessage, body?: any) => Promise<any>; fn: (context: BackCxt, params: Record<string, string>, headers: IncomingHttpHeaders, req: IncomingMessage, body?: any) => Promise<any>;
} }
export type Endpoint<ED extends EntityDict, BackCxt extends AsyncContext<ED>> = EndpointItem<ED, BackCxt> | EndpointItem<ED, BackCxt>[]; export declare type Endpoint<ED extends EntityDict, BackCxt extends AsyncContext<ED>> = EndpointItem<ED, BackCxt> | EndpointItem<ED, BackCxt>[];

101
lib/types/Entity.d.ts vendored
View File

@ -1,11 +1,12 @@
import { ReadOnlyAction } from '../actions/action';
import { PrimaryKey, Sequence } from './DataType'; import { PrimaryKey, Sequence } from './DataType';
type TriggerDataAttributeType = '$$triggerData$$'; declare type TriggerDataAttributeType = '$$triggerData$$';
type TriggerTimestampAttributeType = '$$triggerTimestamp$$'; declare type TriggerTimestampAttributeType = '$$triggerTimestamp$$';
type PrimaryKeyAttributeType = 'id'; declare type PrimaryKeyAttributeType = 'id';
type CreateAtAttributeType = '$$createAt$$'; declare type CreateAtAttributeType = '$$createAt$$';
type UpdateAtAttributeType = '$$updateAt$$'; declare type UpdateAtAttributeType = '$$updateAt$$';
type DeleteAtAttributeType = '$$deleteAt$$'; declare type DeleteAtAttributeType = '$$deleteAt$$';
type SeqAttributeType = '$$seq$$'; declare type SeqAttributeType = '$$seq$$';
export declare const TriggerDataAttribute = "$$triggerData$$"; export declare const TriggerDataAttribute = "$$triggerData$$";
export declare const TriggerTimestampAttribute = "$$triggerTimestamp$$"; export declare const TriggerTimestampAttribute = "$$triggerTimestamp$$";
export declare const PrimaryKeyAttribute = "id"; export declare const PrimaryKeyAttribute = "id";
@ -13,14 +14,14 @@ export declare const CreateAtAttribute = "$$createAt$$";
export declare const UpdateAtAttribute = "$$updateAt$$"; export declare const UpdateAtAttribute = "$$updateAt$$";
export declare const DeleteAtAttribute = "$$deleteAt$$"; export declare const DeleteAtAttribute = "$$deleteAt$$";
export declare const SeqAttribute = "$$seq$$"; export declare const SeqAttribute = "$$seq$$";
export type InstinctiveAttributes = PrimaryKeyAttributeType | CreateAtAttributeType | UpdateAtAttributeType | DeleteAtAttributeType | TriggerDataAttributeType | TriggerTimestampAttributeType | SeqAttributeType; export declare type InstinctiveAttributes = PrimaryKeyAttributeType | CreateAtAttributeType | UpdateAtAttributeType | DeleteAtAttributeType | TriggerDataAttributeType | TriggerTimestampAttributeType | SeqAttributeType;
export declare const initinctiveAttributes: string[]; export declare const initinctiveAttributes: string[];
type FilterPart<A extends string, F extends Object | undefined> = { declare type FilterPart<A extends string, F extends Object | undefined> = {
filter?: A extends 'create' ? undefined : F; filter?: A extends 'create' ? undefined : F;
indexFrom?: A extends 'create' ? undefined : number; indexFrom?: A extends 'create' ? undefined : number;
count?: A extends 'create' ? undefined : number; count?: A extends 'create' ? undefined : number;
}; };
export type SelectOption = { export declare type SelectOption = {
dontCollect?: boolean; dontCollect?: boolean;
blockTrigger?: true; blockTrigger?: true;
obscure?: boolean; obscure?: boolean;
@ -28,7 +29,7 @@ export type SelectOption = {
includedDeleted?: true; includedDeleted?: true;
dummy?: 1; dummy?: 1;
}; };
export type OperateOption = { export declare type OperateOption = {
blockTrigger?: true; blockTrigger?: true;
dontCollect?: boolean; dontCollect?: boolean;
dontCreateOper?: boolean; dontCreateOper?: boolean;
@ -38,13 +39,19 @@ export type OperateOption = {
modiParentEntity?: string; modiParentEntity?: string;
dummy?: 1; dummy?: 1;
}; };
export type FormUpdateData<SH extends GeneralEntityShape> = Partial<{ export declare type FormUpdateData<SH extends GeneralEntityShape> = Partial<{
[K in keyof Omit<SH, InstinctiveAttributes>]: SH[K] | null; [K in keyof Omit<SH, InstinctiveAttributes>]: SH[K] | null;
}>; }>;
export type FormCreateData<SH extends GeneralEntityShape> = Partial<Omit<SH, InstinctiveAttributes>> & { export declare type FormCreateData<SH extends GeneralEntityShape> = Partial<Omit<SH, InstinctiveAttributes>> & {
id: string; id: string;
}; };
export type Operation<A extends string, D extends Projection, F extends Filter | undefined = undefined, S extends Sorter | undefined = undefined> = { export declare type Operation<A extends string, D extends Projection, F extends Filter | undefined = undefined, S extends Sorter | undefined = undefined> = {
id: string;
action: A;
data: D;
sorter?: S;
} & FilterPart<A, F>;
export declare type Selection<A extends ReadOnlyAction, D extends Projection, F extends Filter | undefined = undefined, S extends Sorter | undefined = undefined> = {
id?: string; id?: string;
action: A; action: A;
data: D; data: D;
@ -60,14 +67,14 @@ export interface EntityShape {
interface GeneralEntityShape extends EntityShape { interface GeneralEntityShape extends EntityShape {
[K: string]: any; [K: string]: any;
} }
export type MakeAction<A extends string> = A; export declare type MakeAction<A extends string> = A;
export interface EntityDef { export interface EntityDef {
Schema: GeneralEntityShape; Schema: GeneralEntityShape;
OpSchema: GeneralEntityShape; OpSchema: GeneralEntityShape;
Action: string; Action: string;
ParticularAction?: string; ParticularAction?: string;
Selection: Omit<Operation<'select', Projection, Filter, Sorter>, 'action'>; Selection: Omit<Selection<'select', Projection, Filter, Sorter>, 'action'>;
Aggregation: Omit<DeduceAggregation<Projection, Filter, Sorter>, 'action'>; Aggregation: DeduceAggregation<Projection, Filter, Sorter>;
Operation: CUDOperation; Operation: CUDOperation;
Create: CreateOperation; Create: CreateOperation;
CreateSingle: CreateSingleOperation; CreateSingle: CreateSingleOperation;
@ -82,79 +89,79 @@ export interface EntityDict {
export interface OtmSubProjection extends Omit<Operation<'select', any, any, any>, 'action'> { export interface OtmSubProjection extends Omit<Operation<'select', any, any, any>, 'action'> {
$entity: string; $entity: string;
} }
export type AggregationOp = `#max-${number}` | `#min-${number}` | `#avg-${number}` | `#count-${number}` | `#sum-${number}`; export declare type AggregationOp = `#max-${number}` | `#min-${number}` | `#avg-${number}` | `#count-${number}` | `#sum-${number}`;
export type DeduceAggregationData<P extends Projection> = { export declare type DeduceAggregationData<P extends Projection> = {
[A in AggregationOp]?: P; [A in AggregationOp]?: P;
} & { } & {
'#aggr'?: P; '#aggr'?: P;
}; };
export type AggregationResult<SH extends GeneralEntityShape> = Array<{ export declare type AggregationResult<SH extends GeneralEntityShape> = Array<{
[A in AggregationOp]?: number | string; [A in AggregationOp]?: number | string;
} & { } & {
'#data'?: Partial<SH>; '#data'?: Partial<SH>;
}>; }>;
export type AttrFilter<SH extends GeneralEntityShape> = { export declare type AttrFilter<SH extends GeneralEntityShape> = {
[K in keyof SH]?: any; [K in keyof SH]?: any;
}; };
type SortAttr = { declare type SortAttr = {
[K: string]: any; [K: string]: any;
}; };
type SorterItem = { declare type SorterItem = {
$attr: SortAttr; $attr: SortAttr;
$direction?: "asc" | "desc"; $direction?: "asc" | "desc";
}; };
type Sorter = Array<SorterItem>; declare type Sorter = Array<SorterItem>;
type Filter = { declare type Filter = {
[K: string]: any; [K: string]: any;
}; };
type Projection = { declare type Projection = {
[K: string]: any; [K: string]: any;
}; };
export type DeduceAggregation<P extends Projection, F extends Filter, S extends Sorter> = Omit<Operation<'aggregate', DeduceAggregationData<P>, F, S>, 'action'>; export declare type DeduceAggregation<P extends Projection, F extends Filter, S extends Sorter> = Omit<Selection<'aggregate', DeduceAggregationData<P>, F, S>, 'action'>;
type CreateOperationData = { declare type CreateOperationData = {
id: string; id: string;
[K: string]: any; [K: string]: any;
}; };
type CreateSingleOperation = Operation<'create', CreateOperationData, undefined, undefined>; declare type CreateSingleOperation = Operation<'create', CreateOperationData, undefined, undefined>;
type CreateMultipleOperation = Operation<'create', Array<CreateOperationData>, undefined, undefined>; declare type CreateMultipleOperation = Operation<'create', Array<CreateOperationData>, undefined, undefined>;
type CreateOperation = CreateSingleOperation | CreateMultipleOperation; declare type CreateOperation = CreateSingleOperation | CreateMultipleOperation;
type UpdateOperationData = { declare type UpdateOperationData = {
id?: never; id?: never;
[k: string]: any; [k: string]: any;
}; };
export type UpdateOperation = Operation<string, UpdateOperationData, Filter, Sorter>; export declare type UpdateOperation = Operation<string, UpdateOperationData, Filter, Sorter>;
type RemoveOperationData = { declare type RemoveOperationData = {
[k: string]: any; [k: string]: any;
}; };
export type RemoveOperation = Operation<'remove', RemoveOperationData, Filter, Sorter>; export declare type RemoveOperation = Operation<'remove', RemoveOperationData, Filter, Sorter>;
export type CUDOperation = CreateOperation | UpdateOperation | RemoveOperation; export declare type CUDOperation = CreateOperation | UpdateOperation | RemoveOperation;
export type CreateOpResult<ED extends EntityDict, T extends keyof ED> = { export declare type CreateOpResult<ED extends EntityDict, T extends keyof ED> = {
a: 'c'; a: 'c';
e: T; e: T;
d: ED[T]['OpSchema'] | ED[T]['OpSchema'][]; d: ED[T]['OpSchema'] | ED[T]['OpSchema'][];
}; };
export type UpdateOpResult<ED extends EntityDict, T extends keyof ED> = { export declare type UpdateOpResult<ED extends EntityDict, T extends keyof ED> = {
a: 'u'; a: 'u';
e: T; e: T;
d: UpdateOperationData; d: UpdateOperationData;
f?: Filter; f?: Filter;
}; };
export type RemoveOpResult<ED extends EntityDict, T extends keyof ED> = { export declare type RemoveOpResult<ED extends EntityDict, T extends keyof ED> = {
a: 'r'; a: 'r';
e: T; e: T;
f?: Filter; f?: Filter;
}; };
export type RelationHierarchy<R extends string> = { export declare type RelationHierarchy<R extends string> = {
[K in R]?: R[]; [K in R]?: R[];
}; };
export type CascadeRelationItem = { export declare type CascadeRelationItem = {
cascadePath: string; cascadePath: string;
relations?: string[]; relations?: string[];
}; };
export type CascadeRelationAuth<R extends string> = { export declare type CascadeRelationAuth<R extends string> = {
[K in R]?: CascadeRelationItem | (CascadeRelationItem | CascadeRelationItem[])[]; [K in R]?: CascadeRelationItem | (CascadeRelationItem | CascadeRelationItem[])[];
}; };
export type SelectOpResult<ED extends EntityDict> = { export declare type SelectOpResult<ED extends EntityDict> = {
a: 's'; a: 's';
d: { d: {
[T in keyof ED]?: { [T in keyof ED]?: {
@ -162,14 +169,14 @@ export type SelectOpResult<ED extends EntityDict> = {
}; };
}; };
}; };
export type OpRecord<ED extends EntityDict> = CreateOpResult<ED, keyof ED> | UpdateOpResult<ED, keyof ED> | RemoveOpResult<ED, keyof ED> | SelectOpResult<ED>; export declare type OpRecord<ED extends EntityDict> = CreateOpResult<ED, keyof ED> | UpdateOpResult<ED, keyof ED> | RemoveOpResult<ED, keyof ED> | SelectOpResult<ED>;
export type OperationResult<ED extends EntityDict> = { export declare type OperationResult<ED extends EntityDict> = {
[K in keyof ED]?: { [K in keyof ED]?: {
[A in ED[K]['Action']]?: number; [A in ED[K]['Action']]?: number;
}; };
}; };
export type ActionType = 'readOnly' | 'appendOnly' | 'excludeUpdate' | 'excludeRemove' | 'crud'; export declare type ActionType = 'readOnly' | 'appendOnly' | 'excludeUpdate' | 'excludeRemove' | 'crud';
export type Configuration = { export declare type Configuration = {
actionType?: ActionType; actionType?: ActionType;
static?: boolean; static?: boolean;
}; };

View File

@ -5,6 +5,16 @@ export declare class OakException extends Error {
} }
export declare class OakDataException extends OakException { export declare class OakDataException extends OakException {
} }
export declare class OakUniqueViolationException extends OakException {
rows: Array<{
id?: string;
attrs: string[];
}>;
constructor(rows: Array<{
id?: string;
attrs: string[];
}>, message?: string);
}
export declare class OakImportDataParseException extends OakException { export declare class OakImportDataParseException extends OakException {
line: number; line: number;
header?: string; header?: string;

View File

@ -1,6 +1,6 @@
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.makeException = exports.OakDeadlock = exports.OakCongruentRowExists = exports.OakRowLockedException = exports.OakUnloggedInException = exports.OakUserUnpermittedException = exports.OakInputIllegalException = exports.OakRowInconsistencyException = exports.OakUserException = exports.OakExternalException = exports.OakRowUnexistedException = exports.OakOperExistedException = exports.OakImportDataParseException = exports.OakDataException = exports.OakException = void 0; exports.makeException = exports.OakDeadlock = exports.OakCongruentRowExists = exports.OakRowLockedException = exports.OakUnloggedInException = exports.OakUserUnpermittedException = exports.OakInputIllegalException = exports.OakRowInconsistencyException = exports.OakUserException = exports.OakExternalException = exports.OakRowUnexistedException = exports.OakOperExistedException = exports.OakImportDataParseException = exports.OakUniqueViolationException = exports.OakDataException = exports.OakException = void 0;
var tslib_1 = require("tslib"); var tslib_1 = require("tslib");
var OakException = /** @class */ (function (_super) { var OakException = /** @class */ (function (_super) {
tslib_1.__extends(OakException, _super); tslib_1.__extends(OakException, _super);
@ -36,6 +36,16 @@ var OakDataException = /** @class */ (function (_super) {
return OakDataException; return OakDataException;
}(OakException)); }(OakException));
exports.OakDataException = OakDataException; exports.OakDataException = OakDataException;
var OakUniqueViolationException = /** @class */ (function (_super) {
tslib_1.__extends(OakUniqueViolationException, _super);
function OakUniqueViolationException(rows, message) {
var _this = _super.call(this, message || '您更新的数据违反了唯一性约束') || this;
_this.rows = rows;
return _this;
}
return OakUniqueViolationException;
}(OakException));
exports.OakUniqueViolationException = OakUniqueViolationException;
var OakImportDataParseException = /** @class */ (function (_super) { var OakImportDataParseException = /** @class */ (function (_super) {
tslib_1.__extends(OakImportDataParseException, _super); tslib_1.__extends(OakImportDataParseException, _super);
// message必传描述具体错误的数据内容 // message必传描述具体错误的数据内容
@ -257,6 +267,12 @@ function makeException(data) {
case 'OakDeadlock': { case 'OakDeadlock': {
return new OakDeadlock(data.message); return new OakDeadlock(data.message);
} }
case 'OakDataException': {
return new OakDataException(data.message);
}
case 'OakUniqueViolationException': {
return new OakUniqueViolationException(data.rows, data.message);
}
case 'OakImportDataParseException': { case 'OakImportDataParseException': {
return new OakImportDataParseException(data.message, data.line, data.header); return new OakImportDataParseException(data.message, data.line, data.header);
} }

View File

@ -1,8 +1,8 @@
import { RefAttr } from "./Demand"; import { RefAttr } from "./Demand";
import { Geo } from "./Geo"; import { Geo } from "./Geo";
export type RefOrExpression<A> = RefAttr<A> | Expression<A>; export declare type RefOrExpression<A> = RefAttr<A> | Expression<A>;
type MathType<A> = RefOrExpression<A> | number; declare type MathType<A> = RefOrExpression<A> | number;
type StringType<A> = RefOrExpression<A> | string; declare type StringType<A> = RefOrExpression<A> | string;
interface Add<A> { interface Add<A> {
$add: (MathType<A>)[]; $add: (MathType<A>)[];
} }
@ -30,8 +30,8 @@ interface Ceil<A> {
interface Pow<A> { interface Pow<A> {
$pow: [MathType<A>, MathType<A>]; $pow: [MathType<A>, MathType<A>];
} }
type MathExpression<A> = Add<A> | Subtract<A> | Multiply<A> | Divide<A> | Abs<A> | Round<A> | Floor<A> | Ceil<A> | Pow<A>; declare type MathExpression<A> = Add<A> | Subtract<A> | Multiply<A> | Divide<A> | Abs<A> | Round<A> | Floor<A> | Ceil<A> | Pow<A>;
type CmpType<A> = RefOrExpression<A> | string | number; declare type CmpType<A> = RefOrExpression<A> | string | number;
interface Gt<A> { interface Gt<A> {
$gt: [CmpType<A>, CmpType<A>]; $gt: [CmpType<A>, CmpType<A>];
} }
@ -59,14 +59,14 @@ interface EndsWith<A> {
interface Includes<A> { interface Includes<A> {
$includes: [RefOrExpression<A> | string, RefOrExpression<A> | string]; $includes: [RefOrExpression<A> | string, RefOrExpression<A> | string];
} }
type CompareExpression<A> = Lt<A> | Gt<A> | Lte<A> | Gte<A> | Eq<A> | Ne<A> | StartsWith<A> | EndsWith<A> | Includes<A>; declare type CompareExpression<A> = Lt<A> | Gt<A> | Lte<A> | Gte<A> | Eq<A> | Ne<A> | StartsWith<A> | EndsWith<A> | Includes<A>;
interface BoolTrue<A> { interface BoolTrue<A> {
$true: Expression<A>; $true: Expression<A>;
} }
interface BoolFalse<A> { interface BoolFalse<A> {
$false: Expression<A>; $false: Expression<A>;
} }
type BoolExpression<A> = BoolTrue<A> | BoolFalse<A>; declare type BoolExpression<A> = BoolTrue<A> | BoolFalse<A>;
interface LogicAnd<A> { interface LogicAnd<A> {
$and: Expression<A>[]; $and: Expression<A>[];
} }
@ -76,7 +76,7 @@ interface LogicOr<A> {
interface LogicNot<A> { interface LogicNot<A> {
$not: Expression<A>; $not: Expression<A>;
} }
type LogicExpression<A> = LogicAnd<A> | LogicOr<A> | LogicNot<A>; declare type LogicExpression<A> = LogicAnd<A> | LogicOr<A> | LogicNot<A>;
interface DateYear<A> { interface DateYear<A> {
$year: RefOrExpression<A> | Date | number; $year: RefOrExpression<A> | Date | number;
} }
@ -110,18 +110,18 @@ interface DateCeiling<A> {
interface DateFloor<A> { interface DateFloor<A> {
$dateFloor: [RefOrExpression<A> | Date | number, 'y' | 'M' | 'd' | 'h' | 'm' | 's']; $dateFloor: [RefOrExpression<A> | Date | number, 'y' | 'M' | 'd' | 'h' | 'm' | 's'];
} }
type DateExpression<A> = DateYear<A> | DateMonth<A> | DateWeekday<A> | DateWeekOfYear<A> | DateDay<A> | DateDayOfYear<A> | DateDayOfMonth<A> | DateDayOfWeek<A> | DateDiff<A> | DateCeiling<A> | DateFloor<A>; declare type DateExpression<A> = DateYear<A> | DateMonth<A> | DateWeekday<A> | DateWeekOfYear<A> | DateDay<A> | DateDayOfYear<A> | DateDayOfMonth<A> | DateDayOfWeek<A> | DateDiff<A> | DateCeiling<A> | DateFloor<A>;
interface StringConcat<A> { interface StringConcat<A> {
$concat: StringType<A>[]; $concat: StringType<A>[];
} }
type StringExpression<A> = StringConcat<A>; declare type StringExpression<A> = StringConcat<A>;
interface GeoContains<A> { interface GeoContains<A> {
$contains: [RefOrExpression<A> | Geo, RefOrExpression<A> | Geo]; $contains: [RefOrExpression<A> | Geo, RefOrExpression<A> | Geo];
} }
interface GeoDistance<A> { interface GeoDistance<A> {
$distance: [RefOrExpression<A> | Geo, RefOrExpression<A> | Geo]; $distance: [RefOrExpression<A> | Geo, RefOrExpression<A> | Geo];
} }
type GeoExpression<A> = GeoContains<A> | GeoDistance<A>; declare type GeoExpression<A> = GeoContains<A> | GeoDistance<A>;
interface AggrCountExpression<A> { interface AggrCountExpression<A> {
$$count: RefOrExpression<A>; $$count: RefOrExpression<A>;
} }
@ -137,9 +137,9 @@ interface AggrMinExpression<A> {
interface AggrAvgExpression<A> { interface AggrAvgExpression<A> {
$$avg: RefOrExpression<A>; $$avg: RefOrExpression<A>;
} }
export type AggrExpression<A> = AggrAvgExpression<A> | AggrCountExpression<A> | AggrSumExpression<A> | AggrMaxExpression<A> | AggrMinExpression<A>; export declare type AggrExpression<A> = AggrAvgExpression<A> | AggrCountExpression<A> | AggrSumExpression<A> | AggrMaxExpression<A> | AggrMinExpression<A>;
export type Expression<A> = GeoExpression<A> | DateExpression<A> | LogicExpression<A> | BoolExpression<A> | CompareExpression<A> | MathExpression<A> | StringExpression<A> | AggrExpression<A>; export declare type Expression<A> = GeoExpression<A> | DateExpression<A> | LogicExpression<A> | BoolExpression<A> | CompareExpression<A> | MathExpression<A> | StringExpression<A> | AggrExpression<A>;
export type ExpressionConstant = Geo | number | Date | string | boolean; export declare type ExpressionConstant = Geo | number | Date | string | boolean;
export declare function isGeoExpression<A>(expression: any): expression is GeoExpression<A>; export declare function isGeoExpression<A>(expression: any): expression is GeoExpression<A>;
export declare function isDateExpression<A>(expression: any): expression is DateExpression<A>; export declare function isDateExpression<A>(expression: any): expression is DateExpression<A>;
export declare function isLogicExpression<A>(expression: any): expression is LogicExpression<A>; export declare function isLogicExpression<A>(expression: any): expression is LogicExpression<A>;

12
lib/types/Geo.d.ts vendored
View File

@ -1,8 +1,8 @@
export type Point = [number, number]; export declare type Point = [number, number];
export type Path = Array<Point>; export declare type Path = Array<Point>;
export type Polygon = Array<Path>; export declare type Polygon = Array<Path>;
export type Circle = [Point, number]; export declare type Circle = [Point, number];
export type SingleGeo = { export declare type SingleGeo = {
type: 'point'; type: 'point';
coordinate: Point; coordinate: Point;
} | { } | {
@ -15,4 +15,4 @@ export type SingleGeo = {
type: 'circle'; type: 'circle';
coordinate: Circle; coordinate: Circle;
}; };
export type Geo = SingleGeo | SingleGeo[]; export declare type Geo = SingleGeo | SingleGeo[];

10
lib/types/Locale.d.ts vendored
View File

@ -1,17 +1,17 @@
import { EntityShape } from "./Entity"; import { EntityShape } from "./Entity";
type Language = 'zh_CN' | 'en_US'; declare type Language = 'zh_CN' | 'en_US';
type LocaleOfSchema<S extends Record<string, any>> = { declare type LocaleOfSchema<S extends Record<string, any>> = {
[A in keyof Required<Omit<S, keyof EntityShape>>]: string; [A in keyof Required<Omit<S, keyof EntityShape>>]: string;
}; };
type LocaleOfStringEnum<A extends string> = { declare type LocaleOfStringEnum<A extends string> = {
[K in A]: string; [K in A]: string;
}; };
type LocaleOfValue<V extends Record<string, string>> = { declare type LocaleOfValue<V extends Record<string, string>> = {
[K in keyof V]: { [K in keyof V]: {
[K2 in V[K]]: string; [K2 in V[K]]: string;
}; };
}; };
export type LocaleDef<Sc extends Record<string, any>, Ac extends string, R extends string, V extends Record<string, string>> = { export declare type LocaleDef<Sc extends Record<string, any>, Ac extends string, R extends string, V extends Record<string, string>> = {
[L in Language]?: { [L in Language]?: {
attr: LocaleOfSchema<Sc> & { attr: LocaleOfSchema<Sc> & {
[A in keyof V]: string; [A in keyof V]: string;

View File

@ -1,23 +1,23 @@
export type OmitInferKey<T, R> = { export declare type OmitInferKey<T, R> = {
[K in keyof T as T extends R ? never : K]: T[K]; [K in keyof T as T extends R ? never : K]: T[K];
}; };
export type OmitInferValue<T, R> = { export declare type OmitInferValue<T, R> = {
[K in keyof T as T extends R ? never : K]: T[K]; [K in keyof T as T extends R ? never : K]: T[K];
}; };
export type ValueOf<Obj> = Obj[keyof Obj]; export declare type ValueOf<Obj> = Obj[keyof Obj];
export type OneOnly<Obj, Key extends keyof Obj> = { export declare type OneOnly<Obj, Key extends keyof Obj> = {
[key in Exclude<keyof Obj, Key>]?: undefined; [key in Exclude<keyof Obj, Key>]?: undefined;
} & Pick<Obj, Key>; } & Pick<Obj, Key>;
export type OneOfByKey<Obj> = { export declare type OneOfByKey<Obj> = {
[key in keyof Obj]: OneOnly<Obj, key>; [key in keyof Obj]: OneOnly<Obj, key>;
}; };
export type OneOf<Obj> = ValueOf<OneOfByKey<Obj>>; export declare type OneOf<Obj> = ValueOf<OneOfByKey<Obj>>;
type IsOptional<T, K extends keyof T> = { declare type IsOptional<T, K extends keyof T> = {
[K1 in Exclude<keyof T, K>]: T[K1]; [K1 in Exclude<keyof T, K>]: T[K1];
} & { } & {
K?: T[K]; K?: T[K];
} extends T ? K : never; } extends T ? K : never;
export type OptionalKeys<T> = { export declare type OptionalKeys<T> = {
[K in keyof T]: IsOptional<T, K>; [K in keyof T]: IsOptional<T, K>;
}[keyof T]; }[keyof T];
export {}; export {};

4
lib/types/Port.d.ts vendored
View File

@ -1,6 +1,6 @@
import { AsyncContext } from "../store/AsyncRowStore"; import { AsyncContext } from "../store/AsyncRowStore";
import { EntityDict } from "./Entity"; import { EntityDict } from "./Entity";
export type Exportation<ED extends EntityDict, T extends keyof ED, K extends string> = { export declare type Exportation<ED extends EntityDict, T extends keyof ED, K extends string> = {
name: string; name: string;
id: string; id: string;
entity: T; entity: T;
@ -8,7 +8,7 @@ export type Exportation<ED extends EntityDict, T extends keyof ED, K extends str
headers: K[]; headers: K[];
fn: (data: ED[T]['Schema']) => Partial<Record<K, string | number | boolean | null>>; fn: (data: ED[T]['Schema']) => Partial<Record<K, string | number | boolean | null>>;
}; };
export type Importation<ED extends EntityDict, T extends keyof ED, K extends string> = { export declare type Importation<ED extends EntityDict, T extends keyof ED, K extends string> = {
name: string; name: string;
id: string; id: string;
entity: T; entity: T;

View File

@ -1,6 +1,6 @@
import { OperationResult, EntityDict } from './Entity'; import { OperationResult, EntityDict } from './Entity';
import { StorageSchema } from './Storage'; import { StorageSchema } from './Storage';
export type TxnOption = { export declare type TxnOption = {
isolationLevel: 'repeatable read' | 'serializable'; isolationLevel: 'repeatable read' | 'serializable';
}; };
export declare abstract class RowStore<ED extends EntityDict> { export declare abstract class RowStore<ED extends EntityDict> {

View File

@ -1,7 +1,7 @@
import { ActionType } from '.'; import { ActionType } from '.';
import { EntityDict, EntityShape, InstinctiveAttributes } from './Entity'; import { EntityDict, EntityShape, InstinctiveAttributes } from './Entity';
import { DataType, DataTypeParams } from './schema/DataTypes'; import { DataType, DataTypeParams } from './schema/DataTypes';
export type Ref = 'ref'; export declare type Ref = 'ref';
export interface Column<SH extends EntityShape> { export interface Column<SH extends EntityShape> {
name: keyof SH | `${string}State`; name: keyof SH | `${string}State`;
size?: number; size?: number;
@ -27,12 +27,12 @@ export interface Attribute {
unique?: boolean; unique?: boolean;
sequenceStart?: number; sequenceStart?: number;
} }
export type Attributes<SH extends EntityShape> = Omit<{ export declare type Attributes<SH extends EntityShape> = Omit<{
[attrName in keyof SH]: Attribute; [attrName in keyof SH]: Attribute;
}, InstinctiveAttributes>; }, InstinctiveAttributes>;
export interface EntityConfig { export interface EntityConfig {
} }
export type UniqConstraint<SH extends EntityShape> = { export declare type UniqConstraint<SH extends EntityShape> = {
attributes: Array<keyof SH>; attributes: Array<keyof SH>;
type?: string; type?: string;
}; };
@ -51,6 +51,6 @@ export interface StorageDesc<SH extends EntityShape> {
relation?: string[]; relation?: string[];
view?: true; view?: true;
} }
export type StorageSchema<ED extends EntityDict> = { export declare type StorageSchema<ED extends EntityDict> = {
[K in keyof ED]: StorageDesc<ED[K]['OpSchema']>; [K in keyof ED]: StorageDesc<ED[K]['OpSchema']>;
}; };

View File

@ -1,11 +1,11 @@
import { EntityDict } from './Entity'; import { EntityDict } from './Entity';
import { AsyncContext } from "../store/AsyncRowStore"; import { AsyncContext } from "../store/AsyncRowStore";
type RoutineFn<ED extends EntityDict, Cxt extends AsyncContext<ED>> = (context: Cxt) => Promise<string>; declare type RoutineFn<ED extends EntityDict, Cxt extends AsyncContext<ED>> = (context: Cxt) => Promise<string>;
export type Routine<ED extends EntityDict, Cxt extends AsyncContext<ED>> = { export declare type Routine<ED extends EntityDict, Cxt extends AsyncContext<ED>> = {
name: string; name: string;
fn: RoutineFn<ED, Cxt>; fn: RoutineFn<ED, Cxt>;
}; };
export type Timer<ED extends EntityDict, Cxt extends AsyncContext<ED>> = { export declare type Timer<ED extends EntityDict, Cxt extends AsyncContext<ED>> = {
name: string; name: string;
cron: string; cron: string;
fn: RoutineFn<ED, Cxt>; fn: RoutineFn<ED, Cxt>;

View File

@ -24,7 +24,7 @@ export interface CreateTriggerCrossTxn<ED extends EntityDict, T extends keyof ED
when: 'commit'; when: 'commit';
strict?: 'takeEasy' | 'makeSure'; strict?: 'takeEasy' | 'makeSure';
} }
export type CreateTrigger<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> = CreateTriggerInTxn<ED, T, Cxt> | CreateTriggerCrossTxn<ED, T, Cxt>; export declare type CreateTrigger<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> = CreateTriggerInTxn<ED, T, Cxt> | CreateTriggerCrossTxn<ED, T, Cxt>;
/** /**
* update trigger如果带有filter * update trigger如果带有filter
* filter条件和trigger所定义的filter是否有交集 * filter条件和trigger所定义的filter是否有交集
@ -46,7 +46,7 @@ export interface UpdateTriggerCrossTxn<ED extends EntityDict, T extends keyof ED
when: 'commit'; when: 'commit';
strict?: 'takeEasy' | 'makeSure'; strict?: 'takeEasy' | 'makeSure';
} }
export type UpdateTrigger<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> = UpdateTriggerInTxn<ED, T, Cxt> | UpdateTriggerCrossTxn<ED, T, Cxt>; export declare type UpdateTrigger<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> = UpdateTriggerInTxn<ED, T, Cxt> | UpdateTriggerCrossTxn<ED, T, Cxt>;
/** /**
* update trigger一样remove trigger如果带有filter * update trigger一样remove trigger如果带有filter
* filter条件和trigger所定义的filter是否有交集 * filter条件和trigger所定义的filter是否有交集
@ -67,7 +67,7 @@ export interface RemoveTriggerCrossTxn<ED extends EntityDict, T extends keyof ED
when: 'commit'; when: 'commit';
strict?: 'takeEasy' | 'makeSure'; strict?: 'takeEasy' | 'makeSure';
} }
export type RemoveTrigger<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> = RemoveTriggerInTxn<ED, T, Cxt> | RemoveTriggerCrossTxn<ED, T, Cxt>; export declare type RemoveTrigger<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> = RemoveTriggerInTxn<ED, T, Cxt> | RemoveTriggerCrossTxn<ED, T, Cxt>;
export interface SelectTriggerBase<ED extends EntityDict, T extends keyof ED> extends TriggerBase<ED, T> { export interface SelectTriggerBase<ED extends EntityDict, T extends keyof ED> extends TriggerBase<ED, T> {
action: 'select'; action: 'select';
} }
@ -88,8 +88,8 @@ export interface SelectTriggerAfter<ED extends EntityDict, T extends keyof ED, C
result: Partial<ED[T]['Schema']>[]; result: Partial<ED[T]['Schema']>[];
}, context: Cxt, params?: SelectOption) => Promise<number> | number; }, context: Cxt, params?: SelectOption) => Promise<number> | number;
} }
export type SelectTrigger<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> = SelectTriggerBefore<ED, T, Cxt> | SelectTriggerAfter<ED, T, Cxt>; export declare type SelectTrigger<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> = SelectTriggerBefore<ED, T, Cxt> | SelectTriggerAfter<ED, T, Cxt>;
export type Trigger<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> = CreateTrigger<ED, T, Cxt> | UpdateTrigger<ED, T, Cxt> | RemoveTrigger<ED, T, Cxt> | SelectTrigger<ED, T, Cxt>; export declare type Trigger<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED> | SyncContext<ED>> = CreateTrigger<ED, T, Cxt> | UpdateTrigger<ED, T, Cxt> | RemoveTrigger<ED, T, Cxt> | SelectTrigger<ED, T, Cxt>;
export interface TriggerEntityShape extends EntityShape { export interface TriggerEntityShape extends EntityShape {
$$triggerData$$?: { $$triggerData$$?: {
name: string; name: string;

View File

@ -1,6 +1,6 @@
import { AsyncContext } from "../store/AsyncRowStore"; import { AsyncContext } from "../store/AsyncRowStore";
import { EntityDict, OperationResult } from "./Entity"; import { EntityDict, OperationResult } from "./Entity";
type ActionData<ED extends EntityDict, T extends keyof ED> = ED[T]['Update']['data'] | ED[T]['Remove']['data']; declare type ActionData<ED extends EntityDict, T extends keyof ED> = ED[T]['Update']['data'] | ED[T]['Remove']['data'];
export interface BBWatcher<ED extends EntityDict, T extends keyof ED> { export interface BBWatcher<ED extends EntityDict, T extends keyof ED> {
name: string; name: string;
entity: T; entity: T;
@ -15,5 +15,5 @@ export interface WBWatcher<ED extends EntityDict, T extends keyof ED, Cxt extend
projection: ED[T]['Selection']['data'] | (() => Promise<ED[T]['Selection']['data']>); projection: ED[T]['Selection']['data'] | (() => Promise<ED[T]['Selection']['data']>);
fn: (context: Cxt, data: Partial<ED[T]['Schema']>[]) => Promise<OperationResult<ED>>; fn: (context: Cxt, data: Partial<ED[T]['Schema']>[]) => Promise<OperationResult<ED>>;
} }
export type Watcher<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED>> = BBWatcher<ED, T> | WBWatcher<ED, T, Cxt>; export declare type Watcher<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED>> = BBWatcher<ED, T> | WBWatcher<ED, T, Cxt>;
export {}; export {};

View File

@ -1,28 +1,28 @@
/** /**
* Column types used for @PrimaryGeneratedColumn() decorator. * Column types used for @PrimaryGeneratedColumn() decorator.
*/ */
export type PrimaryGeneratedColumnType = "int" | "int2" | "int4" | "int8" | "integer" | "tinyint" | "smallint" | "mediumint" | "bigint" | "dec" | "decimal" | "smalldecimal" | "fixed" | "numeric" | "number"; export declare type PrimaryGeneratedColumnType = "int" | "int2" | "int4" | "int8" | "integer" | "tinyint" | "smallint" | "mediumint" | "bigint" | "dec" | "decimal" | "smalldecimal" | "fixed" | "numeric" | "number";
/** /**
* Column types where spatial properties are used. * Column types where spatial properties are used.
*/ */
export type SpatialColumnType = "geometry" | "geography" | "st_geometry" | "st_point"; export declare type SpatialColumnType = "geometry" | "geography" | "st_geometry" | "st_point";
/** /**
* Column types where precision and scale properties are used. * Column types where precision and scale properties are used.
*/ */
export type WithPrecisionColumnType = "float" | "double" | "dec" | "decimal" | "smalldecimal" | "fixed" | "numeric" | "real" | "double precision" | "number" | "datetime" | "datetime2" | "datetimeoffset" | "time" | "time with time zone" | "time without time zone" | "timestamp" | "timestamp without time zone" | "timestamp with time zone" | "timestamp with local time zone"; export declare type WithPrecisionColumnType = "float" | "double" | "dec" | "decimal" | "smalldecimal" | "fixed" | "numeric" | "real" | "double precision" | "number" | "datetime" | "datetime2" | "datetimeoffset" | "time" | "time with time zone" | "time without time zone" | "timestamp" | "timestamp without time zone" | "timestamp with time zone" | "timestamp with local time zone";
/** /**
* Column types where column length is used. * Column types where column length is used.
*/ */
export type WithLengthColumnType = "character varying" | "varying character" | "char varying" | "nvarchar" | "national varchar" | "character" | "native character" | "varchar" | "char" | "nchar" | "national char" | "varchar2" | "nvarchar2" | "alphanum" | "shorttext" | "raw" | "binary" | "varbinary" | "string"; export declare type WithLengthColumnType = "character varying" | "varying character" | "char varying" | "nvarchar" | "national varchar" | "character" | "native character" | "varchar" | "char" | "nchar" | "national char" | "varchar2" | "nvarchar2" | "alphanum" | "shorttext" | "raw" | "binary" | "varbinary" | "string";
export type WithWidthColumnType = "tinyint" | "smallint" | "mediumint" | "int" | "bigint"; export declare type WithWidthColumnType = "tinyint" | "smallint" | "mediumint" | "int" | "bigint";
/** /**
* All other regular column types. * All other regular column types.
*/ */
export type SimpleColumnType = "simple-array" | "simple-json" | "simple-enum" | "int2" | "integer" | "int4" | "int8" | "int64" | "unsigned big int" | "float" | "float4" | "float8" | "smallmoney" | "money" | "boolean" | "bool" | "tinyblob" | "tinytext" | "mediumblob" | "mediumtext" | "blob" | "text" | "ntext" | "citext" | "hstore" | "longblob" | "longtext" | "alphanum" | "shorttext" | "bytes" | "bytea" | "long" | "raw" | "long raw" | "bfile" | "clob" | "nclob" | "image" | "timetz" | "timestamptz" | "timestamp with local time zone" | "smalldatetime" | "date" | "interval year to month" | "interval day to second" | "interval" | "year" | "seconddate" | "point" | "line" | "lseg" | "box" | "circle" | "path" | "polygon" | "geography" | "geometry" | "linestring" | "multipoint" | "multilinestring" | "multipolygon" | "geometrycollection" | "st_geometry" | "st_point" | "int4range" | "int8range" | "numrange" | "tsrange" | "tstzrange" | "daterange" | "enum" | "set" | "cidr" | "inet" | "macaddr" | "bit" | "bit varying" | "varbit" | "tsvector" | "tsquery" | "uuid" | "xml" | "json" | "jsonb" | "varbinary" | "hierarchyid" | "sql_variant" | "rowid" | "urowid" | "uniqueidentifier" | "rowversion" | "array" | "cube" | "ltree" | "object" | "array" | "function" | "sequence"; export declare type SimpleColumnType = "simple-array" | "simple-json" | "simple-enum" | "int2" | "integer" | "int4" | "int8" | "int64" | "unsigned big int" | "float" | "float4" | "float8" | "smallmoney" | "money" | "boolean" | "bool" | "tinyblob" | "tinytext" | "mediumblob" | "mediumtext" | "blob" | "text" | "ntext" | "citext" | "hstore" | "longblob" | "longtext" | "alphanum" | "shorttext" | "bytes" | "bytea" | "long" | "raw" | "long raw" | "bfile" | "clob" | "nclob" | "image" | "timetz" | "timestamptz" | "timestamp with local time zone" | "smalldatetime" | "date" | "interval year to month" | "interval day to second" | "interval" | "year" | "seconddate" | "point" | "line" | "lseg" | "box" | "circle" | "path" | "polygon" | "geography" | "geometry" | "linestring" | "multipoint" | "multilinestring" | "multipolygon" | "geometrycollection" | "st_geometry" | "st_point" | "int4range" | "int8range" | "numrange" | "tsrange" | "tstzrange" | "daterange" | "enum" | "set" | "cidr" | "inet" | "macaddr" | "bit" | "bit varying" | "varbit" | "tsvector" | "tsquery" | "uuid" | "xml" | "json" | "jsonb" | "varbinary" | "hierarchyid" | "sql_variant" | "rowid" | "urowid" | "uniqueidentifier" | "rowversion" | "array" | "cube" | "ltree" | "object" | "array" | "function" | "sequence";
/** /**
* Any column type column can be. * Any column type column can be.
*/ */
export type DataType = WithPrecisionColumnType | WithLengthColumnType | WithWidthColumnType | SpatialColumnType | SimpleColumnType; export declare type DataType = WithPrecisionColumnType | WithLengthColumnType | WithWidthColumnType | SpatialColumnType | SimpleColumnType;
export interface DataTypeParams { export interface DataTypeParams {
length?: number; length?: number;
width?: number; width?: number;

View File

@ -1,4 +1,4 @@
type Mode = 'S' | 'X'; declare type Mode = 'S' | 'X';
/** /**
* *
* *

2
lib/utils/uuid.d.ts vendored
View File

@ -3,7 +3,7 @@ export declare function sequentialUuid({ random }: {
}): string; }): string;
export declare function shrinkUuidTo32Bytes(uuid: string): string; export declare function shrinkUuidTo32Bytes(uuid: string): string;
export declare function expandUuidTo36Bytes(uuidShrinked: string): string; export declare function expandUuidTo36Bytes(uuidShrinked: string): string;
export type GenerateIdOption = { export declare type GenerateIdOption = {
shuffle?: boolean; shuffle?: boolean;
}; };
export declare function generateNewIdAsync(option?: GenerateIdOption): Promise<string>; export declare function generateNewIdAsync(option?: GenerateIdOption): Promise<string>;

View File

@ -105,7 +105,7 @@ function sequentialUuid(_a) {
} }
exports.sequentialUuid = sequentialUuid; exports.sequentialUuid = sequentialUuid;
function shrinkUuidTo32Bytes(uuid) { function shrinkUuidTo32Bytes(uuid) {
return uuid.replaceAll('-', ''); return uuid.replace(/\-/g, '');
} }
exports.shrinkUuidTo32Bytes = shrinkUuidTo32Bytes; exports.shrinkUuidTo32Bytes = shrinkUuidTo32Bytes;
function expandUuidTo36Bytes(uuidShrinked) { function expandUuidTo36Bytes(uuidShrinked) {

View File

@ -1,5 +1,5 @@
type ValidatorFunction = (text: string, size?: number) => string | boolean; declare type ValidatorFunction = (text: string, size?: number) => string | boolean;
type ValidatorMoneyFunction = (text: string, zero?: boolean) => string | boolean; declare type ValidatorMoneyFunction = (text: string, zero?: boolean) => string | boolean;
export declare const isMobile: ValidatorFunction; export declare const isMobile: ValidatorFunction;
export declare const isPassword: ValidatorFunction; export declare const isPassword: ValidatorFunction;
export declare const isCaptcha: ValidatorFunction; export declare const isCaptcha: ValidatorFunction;

View File

@ -1,6 +1,6 @@
{ {
"name": "oak-domain", "name": "oak-domain",
"version": "2.4.1", "version": "2.4.2",
"author": { "author": {
"name": "XuChang" "name": "XuChang"
}, },

View File

@ -1,12 +1,12 @@
import { ActionDef } from '../types/Action'; import { ActionDef } from '../types/Action';
export type ReadOnlyAction = 'select' | 'count' | 'stat' | 'download'; export type ReadOnlyAction = 'select' | 'count' | 'stat' | 'download' | 'aggregate';
export type AppendOnlyAction = ReadOnlyAction | 'create'; export type AppendOnlyAction = ReadOnlyAction | 'create';
export type ExcludeUpdateAction = AppendOnlyAction | 'remove'; export type ExcludeUpdateAction = AppendOnlyAction | 'remove';
export type ExcludeRemoveAction = AppendOnlyAction | 'update'; export type ExcludeRemoveAction = AppendOnlyAction | 'update';
export type GenericAction = 'update' | ExcludeUpdateAction; export type GenericAction = 'update' | ExcludeUpdateAction;
export type RelationAction = 'grant' | 'revoke'; export type RelationAction = 'grant' | 'revoke';
export const readOnlyActions = ['count', 'stat', 'download', 'select']; export const readOnlyActions = ['count', 'stat', 'download', 'select', 'aggregate'];
export const appendOnlyActions = readOnlyActions.concat('create'); export const appendOnlyActions = readOnlyActions.concat('create');
export const excludeUpdateActions = appendOnlyActions.concat('remove'); export const excludeUpdateActions = appendOnlyActions.concat('remove');
export const exludeRemoveActions = appendOnlyActions.concat('update'); export const exludeRemoveActions = appendOnlyActions.concat('update');

View File

@ -1,9 +1,8 @@
import PathLib from 'path'; import PathLib from 'path';
import assert from 'assert'; import assert from 'assert';
import { execSync } from 'child_process';
import { writeFileSync, readdirSync, mkdirSync, fstat } from 'fs'; import { writeFileSync, readdirSync, mkdirSync, fstat } from 'fs';
import { emptydirSync } from 'fs-extra'; import { emptydirSync } from 'fs-extra';
import { assign, cloneDeep, difference, identity, intersection, keys, uniq, uniqBy } from 'lodash'; import { assign, cloneDeep, difference, identity, intersection, keys, pull, uniq, uniqBy } from 'lodash';
import * as ts from 'typescript'; import * as ts from 'typescript';
const { factory } = ts; const { factory } = ts;
import { import {
@ -952,12 +951,12 @@ function analyzeEntity(filename: string, path: string, program: ts.Program, rela
} }
) as ts.PropertyAssignment; ) as ts.PropertyAssignment;
assert(ts.isStringLiteral(nameProperty.initializer)); assert(ts.isStringLiteral(nameProperty.initializer));
const indexName = nameProperty.initializer.text; const nameText = nameProperty.initializer.text;
if (indexNameDict[indexName]) { if (indexNameDict[nameText]) {
throw new Error(`${filename}」索引定义重名「${indexName}`); throw new Error(`${filename}」索引定义重名「${nameText}`);
} }
assign(indexNameDict, { assign(indexNameDict, {
[indexName]: true, [nameText]: true,
}); });
const configProperty = properties.find( const configProperty = properties.find(
@ -1010,11 +1009,11 @@ function analyzeEntity(filename: string, path: string, program: ts.Program, rela
} }
) as ts.PropertySignature; ) as ts.PropertySignature;
if (!schemaNode) { if (!schemaNode) {
throw new Error(`${filename}」中索引「${indexName}」的属性「${indexAttrName}」定义非法`); throw new Error(`${filename}」中索引「${nameText}」的属性「${indexAttrName}」定义非法`);
} }
const { type, name } = schemaNode; const { type, name } = schemaNode;
const entity = firstLetterLowerCase(moduleName); const entity = moduleName;
const { [entity]: manyToOneSet } = ManyToOne; const { [entity]: manyToOneSet } = ManyToOne;
if (ts.isTypeReferenceNode(type!)) { if (ts.isTypeReferenceNode(type!)) {
const { typeName } = type; const { typeName } = type;
@ -1027,14 +1026,19 @@ function analyzeEntity(filename: string, path: string, program: ts.Program, rela
if (!manyToOneItem) { if (!manyToOneItem) {
// 如果不是外键则不能是Text, File // 如果不是外键则不能是Text, File
if (isFulltextIndex) { if (isFulltextIndex) {
assert(['Text', 'String'].includes(text2), `${filename}」中全文索引「${indexName}」定义的属性「${indexAttrName}」类型非法只能是Text/String`); assert(['Text', 'String'].includes(text2), `${filename}」中全文索引「${nameText}」定义的属性「${indexAttrName}」类型非法只能是Text/String`);
} }
else { else {
assert(!unIndexedTypes.includes(text2), `${filename}」中索引「${indexName}」的属性「${indexAttrName}」的类型为「${text2}」,不可索引`); assert(!unIndexedTypes.includes(text2), `${filename}」中索引「${nameText}」的属性「${indexAttrName}」的类型为「${text2}」,不可索引`);
} }
} }
else { else {
assert(!isFulltextIndex, `${filename}」中全文索引「${indexName}」的属性「${indexAttrName}」类型非法只能为Text/String`); assert(!isFulltextIndex, `${filename}」中全文索引「${nameText}」的属性「${indexAttrName}」类型非法只能为Text/String`);
// 在这里把外键加上Id这样storageSchema才能正常通过
// 这里的写法不太好未来TS版本高了可能会有问题。by Xc 20230131
Object.assign(nameProperty, {
initializer: factory.createStringLiteral(`${indexAttrName}Id`),
});
} }
} }
else { else {
@ -1042,8 +1046,8 @@ function analyzeEntity(filename: string, path: string, program: ts.Program, rela
} }
} }
else { else {
assert(!isFulltextIndex, `${filename}」中全文索引「${indexName}」的属性「${indexAttrName}」类型只能为Text/String`); assert(!isFulltextIndex, `${filename}」中全文索引「${nameText}」的属性「${indexAttrName}」类型只能为Text/String`);
assert(ts.isUnionTypeNode(type!) || ts.isLiteralTypeNode(type!), `${entity}中索引「${indexName}」的属性${(<ts.Identifier>name).text}有定义非法`); assert(ts.isUnionTypeNode(type!) || ts.isLiteralTypeNode(type!), `${entity}中索引「${nameText}」的属性${(<ts.Identifier>name).text}有定义非法`);
} }
} }
} }
@ -1587,6 +1591,7 @@ function constructFilter(statements: Array<ts.Statement>, entity: string) {
break; break;
} }
case 'Int': case 'Int':
case 'Uint':
case 'Float': case 'Float':
case 'Double': { case 'Double': {
type2 = factory.createTypeReferenceNode( type2 = factory.createTypeReferenceNode(
@ -2814,27 +2819,21 @@ function constructActions(statements: Array<ts.Statement>, entity: string) {
) )
], ],
factory.createTypeReferenceNode( factory.createTypeReferenceNode(
factory.createIdentifier("Omit"), factory.createIdentifier("OakSelection"),
[ [
factory.createLiteralTypeNode(factory.createStringLiteral("select")),
factory.createTypeReferenceNode( factory.createTypeReferenceNode(
factory.createIdentifier("OakOperation"), factory.createIdentifier("P"),
[ undefined
factory.createLiteralTypeNode(factory.createStringLiteral("select")),
factory.createTypeReferenceNode(
factory.createIdentifier("P"),
undefined
),
factory.createTypeReferenceNode(
factory.createIdentifier("Filter"),
undefined
),
factory.createTypeReferenceNode(
factory.createIdentifier("Sorter"),
undefined
)
]
), ),
factory.createLiteralTypeNode(factory.createStringLiteral("id")) factory.createTypeReferenceNode(
factory.createIdentifier("Filter"),
undefined
),
factory.createTypeReferenceNode(
factory.createIdentifier("Sorter"),
undefined
)
] ]
) )
), ),
@ -2878,26 +2877,20 @@ function constructActions(statements: Array<ts.Statement>, entity: string) {
factory.createIdentifier("Aggregation"), factory.createIdentifier("Aggregation"),
undefined, undefined,
factory.createTypeReferenceNode( factory.createTypeReferenceNode(
factory.createIdentifier("Omit"), factory.createIdentifier("DeduceAggregation"),
[ [
factory.createTypeReferenceNode( factory.createTypeReferenceNode(
factory.createIdentifier("DeduceAggregation"), factory.createIdentifier("Projection"),
[ undefined
factory.createTypeReferenceNode(
factory.createIdentifier("Projection"),
undefined
),
factory.createTypeReferenceNode(
factory.createIdentifier("Filter"),
undefined
),
factory.createTypeReferenceNode(
factory.createIdentifier("Sorter"),
undefined
)
]
), ),
factory.createLiteralTypeNode(factory.createStringLiteral("id")) factory.createTypeReferenceNode(
factory.createIdentifier("Filter"),
undefined
),
factory.createTypeReferenceNode(
factory.createIdentifier("Sorter"),
undefined
)
] ]
) )
) )
@ -3775,7 +3768,7 @@ function constructActions(statements: Array<ts.Statement>, entity: string) {
const entityNameLc = firstLetterLowerCase(entityName); const entityNameLc = firstLetterLowerCase(entityName);
foreignKeySet[entityName].forEach( foreignKeySet[entityName].forEach(
(foreignKey) => { (foreignKey) => {
const identifier = `${entityNameLc}s$${foreignKey}`; const identifier = `${entityNameLc}$${foreignKey}`;
const otmCreateOperationDataNode = factory.createTypeReferenceNode( const otmCreateOperationDataNode = factory.createTypeReferenceNode(
factory.createIdentifier("Omit"), factory.createIdentifier("Omit"),
@ -4340,6 +4333,11 @@ const initialStatements = () => [
undefined, undefined,
factory.createIdentifier('Int') factory.createIdentifier('Int')
), ),
factory.createImportSpecifier(
false,
undefined,
factory.createIdentifier('Uint')
),
factory.createImportSpecifier( factory.createImportSpecifier(
false, false,
undefined, undefined,
@ -4529,6 +4527,11 @@ const initialStatements = () => [
factory.createIdentifier("Operation"), factory.createIdentifier("Operation"),
factory.createIdentifier("OakOperation") factory.createIdentifier("OakOperation")
), ),
factory.createImportSpecifier(
false,
factory.createIdentifier("Selection"),
factory.createIdentifier("OakSelection")
),
factory.createImportSpecifier( factory.createImportSpecifier(
false, false,
factory.createIdentifier("MakeAction"), factory.createIdentifier("MakeAction"),

View File

@ -669,7 +669,7 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
assert(relation instanceof Array); assert(relation instanceof Array);
const [entityOtm, foreignKey] = relation; const [entityOtm, foreignKey] = relation;
const otmOperations = data[attr]; const otmOperations = data[attr];
const dealWithOneToMany = (otm: ED[keyof ED]['Update']) => { const dealWithOneToMany = (otm: ED[keyof ED]['Update'] | ED[keyof ED]['Create']) => {
const { action: actionOtm, data: dataOtm, filter: filterOtm } = otm; const { action: actionOtm, data: dataOtm, filter: filterOtm } = otm;
if (!foreignKey) { if (!foreignKey) {
// 基于entity/entityId的one-to-many // 基于entity/entityId的one-to-many
@ -692,7 +692,7 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
} }
else if (actionOtm === 'create') { else if (actionOtm === 'create') {
// 这里先假设A必是update的filter上一定有id否则用户界面上应该设计不出来这样的操作 // 这里先假设A必是update的filter上一定有id否则用户界面上应该设计不出来这样的操作
// todo 这个假设成立吗?等遇到create/create一对多的case再完善 // todo 这个假设对watcher等后台行为可能不成立等遇到create/create一对多的case再完善
const { id } = filter!; const { id } = filter!;
assert(typeof id === 'string'); assert(typeof id === 'string');
if (dataOtm instanceof Array) { if (dataOtm instanceof Array) {
@ -713,11 +713,9 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
else { else {
// 这里先假设A必是update的filter上一定有id否则用户界面上应该设计不出来这样的操作 // 这里先假设A必是update的filter上一定有id否则用户界面上应该设计不出来这样的操作
// 这个倒是好像不可能出现create/update的一对多如果遇到了再完善 // 这个倒是好像不可能出现create/update的一对多如果遇到了再完善
const { id } = filter!;
Object.assign(otm, { Object.assign(otm, {
filter: addFilterSegment({ filter: addFilterSegment({
entity, [entity]: filter,
entityId: id,
}, filterOtm), }, filterOtm),
}); });
if (action === 'remove' && actionOtm === 'update') { if (action === 'remove' && actionOtm === 'update') {
@ -747,7 +745,7 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
} }
else if (actionOtm === 'create') { else if (actionOtm === 'create') {
// 这里先假设A必是update的filter上一定有id否则用户界面上应该设计不出来这样的操作 // 这里先假设A必是update的filter上一定有id否则用户界面上应该设计不出来这样的操作
// todo 这个假设成立吗等遇到create/create一对多的case再完善 // todo 这个假设在后台可能不成立,等遇到了再说
const { id } = filter!; const { id } = filter!;
assert(typeof id === 'string'); assert(typeof id === 'string');
if (dataOtm instanceof Array) { if (dataOtm instanceof Array) {
@ -764,12 +762,10 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
} }
} }
else { else {
// 这里先假设A必是update的filter上一定有id否则用户界面上应该设计不出来这样的操作 // update可能出现上层filter不是根据id的userEntityGrant的过期触发的wechatQrCode的过期见general中的userEntityGrant的trigger
// 这个倒是好像不可能出现create/update的一对多如果遇到了再完善
const { id } = filter!;
Object.assign(otm, { Object.assign(otm, {
filter: addFilterSegment({ filter: addFilterSegment({
[foreignKey]: id, [foreignKey.slice(0, foreignKey.length - 2)]: filter,
}, filterOtm), }, filterOtm),
}); });
if (action === 'remove' && actionOtm === 'update') { if (action === 'remove' && actionOtm === 'update') {
@ -780,7 +776,7 @@ export abstract class CascadeStore<ED extends EntityDict & BaseEntityDict> exten
} }
} }
afterFns.push(() => cascadeUpdate.call(this, entityOtm!, otm, context, option2)); beforeFns.push(() => cascadeUpdate.call(this, entityOtm!, otm, context, option2));
}; };
if (otmOperations instanceof Array) { if (otmOperations instanceof Array) {

View File

@ -1,6 +1,8 @@
import { ActionDictOfEntityDict, BBWatcher, Checker, EntityDict, StorageSchema, Trigger, RowChecker } from "../types"; import { ActionDictOfEntityDict, BBWatcher, Checker, EntityDict, StorageSchema, Trigger, RowChecker, OakDataException, OakUniqueViolationException } from "../types";
import { SyncContext } from "./SyncRowStore"; import { SyncContext } from "./SyncRowStore";
import { AsyncContext } from "./AsyncRowStore"; import { AsyncContext } from "./AsyncRowStore";
import { uniqBy, pick, intersection } from '../utils/lodash';
import { addFilterSegment } from "./filter";
export function getFullProjection<ED extends EntityDict, T extends keyof ED>(entity: T, schema: StorageSchema<ED>) { export function getFullProjection<ED extends EntityDict, T extends keyof ED>(entity: T, schema: StorageSchema<ED>) {
const { attributes } = schema[entity]; const { attributes } = schema[entity];
@ -24,18 +26,17 @@ function makeIntrinsicWatchers<ED extends EntityDict>(schema: StorageSchema<ED>)
for (const entity in schema) { for (const entity in schema) {
const { attributes } = schema[entity]; const { attributes } = schema[entity];
const now = Date.now();
const { expiresAt, expired } = attributes; const { expiresAt, expired } = attributes;
if (expiresAt && expiresAt.type === 'datetime' && expired && expired.type === 'boolean') { if (expiresAt && expiresAt.type === 'datetime' && expired && expired.type === 'boolean') {
// 如果有定义expiresAt和expired则自动生成一个检查的watcher // 如果有定义expiresAt和expired则自动生成一个检查的watcher
watchers.push({ watchers.push({
entity, entity,
name: `对象${entity}上的过期自动watcher`, name: `对象${entity}上的过期自动watcher`,
filter: async () => { filter: () => {
return { return {
expired: false, expired: false,
expiresAt: { expiresAt: {
$lte: now, $lte: Date.now(),
}, },
}; };
}, },
@ -50,9 +51,75 @@ function makeIntrinsicWatchers<ED extends EntityDict>(schema: StorageSchema<ED>)
return watchers; return watchers;
} }
function checkUniqueBetweenRows(rows: Record<string, any>[], uniqAttrs: string[]) {
// 先检查这些行本身之间有无unique冲突
const uniqRows = uniqBy(rows, (d) => {
let s = '';
for (const a of uniqAttrs) {
if (d[a as string] === null || d[a as string] === undefined) {
s + d.id;
}
else {
s + `-${d[a as string]}`;
}
}
return s;
});
if (uniqRows.length < rows.length) {
throw new OakUniqueViolationException([{
attrs: uniqAttrs,
}]);
}
}
function checkCountLessThan(count: number | Promise<number>, uniqAttrs: string[], than: number = 0, id?: string) {
if (count instanceof Promise) {
return count.then(
(count2) => {
if (count2 > than) {
throw new OakUniqueViolationException([{
id,
attrs: uniqAttrs,
}]);
}
}
)
}
if (count > than) {
throw new OakUniqueViolationException([{
id,
attrs: uniqAttrs,
}]);
}
}
function checkUnique<ED extends EntityDict, Cxt extends SyncContext<ED> | AsyncContext<ED>>(
entity: keyof ED,
row: Record<string, any>,
context: Cxt,
uniqAttrs: string[],
extraFilter?: ED[keyof ED]['Selection']['filter']
) {
const filter = pick(row, uniqAttrs);
for (const a in filter) {
if (filter[a] === null || filter[a] === undefined) {
delete filter[a];
}
}
if (Object.keys(filter).length < uniqAttrs.length) {
// 说明有null值不需要检查约束
return;
}
const filter2 = extraFilter ? addFilterSegment([filter, extraFilter]) : filter;
const count = context.count(entity, { filter: filter2 }, { dontCollect: true });
return checkCountLessThan(count, uniqAttrs, 0, row.id)
}
export function analyzeActionDefDict<ED extends EntityDict, Cxt extends SyncContext<ED> | AsyncContext<ED>>(schema: StorageSchema<ED>, actionDefDict: ActionDictOfEntityDict<ED>) { export function analyzeActionDefDict<ED extends EntityDict, Cxt extends SyncContext<ED> | AsyncContext<ED>>(schema: StorageSchema<ED>, actionDefDict: ActionDictOfEntityDict<ED>) {
const checkers: Array<Checker<ED, keyof ED, Cxt>> = []; const checkers: Array<Checker<ED, keyof ED, Cxt>> = [];
const triggers: Array<Trigger<ED, keyof ED, Cxt>> = []; const triggers: Array<Trigger<ED, keyof ED, Cxt>> = [];
// action状态转换矩阵相应的checker
for (const entity in actionDefDict) { for (const entity in actionDefDict) {
for (const attr in actionDefDict[entity]) { for (const attr in actionDefDict[entity]) {
const def = actionDefDict[entity]![attr]; const def = actionDefDict[entity]![attr];
@ -117,6 +184,125 @@ export function analyzeActionDefDict<ED extends EntityDict, Cxt extends SyncCont
} }
} }
// unique索引相应的checker
for (const entity in schema) {
const { indexes } = schema[entity];
if (indexes) {
for (const index of indexes) {
if (index.config?.unique) {
const { attributes } = index;
const uniqAttrs = attributes.map(ele => ele.name as string);
checkers.push({
entity,
action: 'create',
type: 'logical',
priority: 20, // 优先级要放在最高所有前置的checker/trigger将数据完整之后再在这里检测
checker: (operation, context) => {
const { data } = operation;
if (data instanceof Array) {
checkUniqueBetweenRows(data, uniqAttrs);
const checkResult = data.map(
ele => checkUnique<ED, Cxt>(entity, ele, context, uniqAttrs)
);
if (checkResult[0] instanceof Promise) {
return Promise.all(checkResult).then(
() => undefined
);
}
}
else {
return checkUnique<ED, Cxt>(entity, data, context, uniqAttrs);
}
}
}, {
entity,
action: 'update', // 只检查update其它状态转换的action应该不会涉及unique约束的属性
type: 'logical',
priority: 20, // 优先级要放在最高所有前置的checker/trigger将数据完整之后再在这里检测
checker: (operation, context) => {
const { data, filter: operationFilter } = operation as ED[keyof ED]['Update'];
const attrs = Object.keys(data);
const refAttrs = intersection(attrs, uniqAttrs);
if (refAttrs.length === 0) {
// 如果本次更新和unique约束的属性之间没有交集则直接返回
return;
}
for (const attr of refAttrs) {
// 如果有更新为null值不用再检查约束
if (data[attr as string] === null || data[attr as string] === undefined) {
return;
}
}
if (refAttrs.length === uniqAttrs.length) {
// 如果更新了全部属性,直接检查
const filter = pick(data, refAttrs);
// 在这些行以外的行不和更新后的键值冲突
const count = context.count(entity, {
filter: addFilterSegment([filter, {
$not: operationFilter,
}]),
}, { dontCollect: true });
const checkCount = checkCountLessThan(count, uniqAttrs);
// 更新的行只能有一行
const rowCount = context.count(entity, {
filter: operationFilter,
}, { dontCollect: true });
const checkRowCount = checkCountLessThan(rowCount, uniqAttrs, 1);
// 如果更新的行数为零似乎也可以但这应该不可能出现吧by Xc 20230131
if (checkRowCount instanceof Promise) {
return Promise.all([checkCount, checkRowCount]).then(
() => undefined
);
}
}
// 否则需要结合本行现有的属性来进行检查
const projection = { id: 1 };
for (const attr of uniqAttrs) {
Object.assign(projection, {
[attr]: 1,
});
}
const checkWithRows = (rows2: ED[keyof ED]['Schema'][]) => {
const rows22 = rows2.map(
ele => Object.assign(ele, data)
);
// 先检查这些行本身之间是否冲突
checkUniqueBetweenRows(rows22, uniqAttrs);
const checkResults = rows22.map(
(row) => checkUnique<ED, Cxt>(entity, row, context, uniqAttrs, {
$not: operationFilter
})
);
if (checkResults[0] instanceof Promise) {
return Promise.all(checkResults).then(
() => undefined
);
}
};
const currentRows = context.select(entity, {
data: projection,
filter: operationFilter,
}, { dontCollect: true });
if (currentRows instanceof Promise) {
return currentRows.then(
(row2) => checkWithRows(row2 as ED[keyof ED]['Schema'][])
);
}
return checkWithRows(currentRows as ED[keyof ED]['Schema'][]);
}
});
}
}
}
}
return { return {
triggers, triggers,
checkers, checkers,

View File

@ -24,7 +24,7 @@ const triggers: Trigger<EntityDict, 'modi', AsyncContext<EntityDict>>[] = [
for (const modi of modies) { for (const modi of modies) {
const { targetEntity, id, action, data, filter} = modi; const { targetEntity, id, action, data, filter} = modi;
await context.operate(targetEntity as keyof EntityDict, { await context.operate(targetEntity as keyof EntityDict, {
id, id: id!,
action: action as EntityDict[keyof EntityDict]['Action'], action: action as EntityDict[keyof EntityDict]['Action'],
data: data as EntityDict[keyof EntityDict]['Update']['data'], data: data as EntityDict[keyof EntityDict]['Update']['data'],
filter: filter as EntityDict[keyof EntityDict]['Update']['filter'], filter: filter as EntityDict[keyof EntityDict]['Update']['filter'],

View File

@ -1,3 +1,4 @@
import { ReadOnlyAction } from '../actions/action';
import { PrimaryKey, Sequence } from './DataType'; import { PrimaryKey, Sequence } from './DataType';
type TriggerDataAttributeType = '$$triggerData$$'; type TriggerDataAttributeType = '$$triggerData$$';
@ -55,7 +56,17 @@ export type Operation<A extends string,
D extends Projection, D extends Projection,
F extends Filter | undefined = undefined, F extends Filter | undefined = undefined,
S extends Sorter | undefined = undefined> = { S extends Sorter | undefined = undefined> = {
id?: string; // 为了一致性每个operation也应当保证唯一id id: string; // 为了一致性每个operation也应当保证唯一id
action: A;
data: D;
sorter?: S;
} & FilterPart<A, F>;
export type Selection<A extends ReadOnlyAction,
D extends Projection,
F extends Filter | undefined = undefined,
S extends Sorter | undefined = undefined> = {
id?: string; // selection的id可传可不传如果传意味着该select会记录在oper中
action: A; action: A;
data: D; data: D;
sorter?: S; sorter?: S;
@ -81,8 +92,8 @@ export interface EntityDef {
OpSchema: GeneralEntityShape; OpSchema: GeneralEntityShape;
Action: string; Action: string;
ParticularAction?: string; ParticularAction?: string;
Selection: Omit<Operation<'select', Projection, Filter, Sorter>, 'action'>; Selection: Omit<Selection<'select', Projection, Filter, Sorter>, 'action'>;
Aggregation: Omit<DeduceAggregation<Projection, Filter, Sorter>, 'action'>; Aggregation: DeduceAggregation<Projection, Filter, Sorter>;
Operation: CUDOperation; Operation: CUDOperation;
Create: CreateOperation; Create: CreateOperation;
CreateSingle: CreateSingleOperation; CreateSingle: CreateSingleOperation;
@ -140,7 +151,7 @@ type Projection = {
export type DeduceAggregation< export type DeduceAggregation<
P extends Projection, P extends Projection,
F extends Filter, F extends Filter,
S extends Sorter> = Omit<Operation<'aggregate', DeduceAggregationData<P>, F, S>, 'action'>; S extends Sorter> = Omit<Selection<'aggregate', DeduceAggregationData<P>, F, S>, 'action'>;
type CreateOperationData = { type CreateOperationData = {
id: string; id: string;

View File

@ -26,6 +26,20 @@ export class OakDataException extends OakException {
// 表示由数据层发现的异常 // 表示由数据层发现的异常
} }
export class OakUniqueViolationException extends OakException {
rows: Array<{
id?: string;
attrs: string[];
}>;
constructor(rows: Array<{
id?: string;
attrs: string[];
}>, message?: string) {
super(message || '您更新的数据违反了唯一性约束');
this.rows = rows;
}
}
export class OakImportDataParseException extends OakException { export class OakImportDataParseException extends OakException {
line: number; line: number;
header?: string; header?: string;
@ -232,6 +246,12 @@ export function makeException(data: {
case 'OakDeadlock': { case 'OakDeadlock': {
return new OakDeadlock(data.message); return new OakDeadlock(data.message);
} }
case 'OakDataException': {
return new OakDataException(data.message);
}
case 'OakUniqueViolationException': {
return new OakUniqueViolationException(data.rows, data.message);
}
case 'OakImportDataParseException': { case 'OakImportDataParseException': {
return new OakImportDataParseException(data.message!, data.line, data.header); return new OakImportDataParseException(data.message!, data.line, data.header);
} }

View File

@ -127,7 +127,7 @@ export function sequentialUuid({ random }: { random: Uint8Array }) {
} }
export function shrinkUuidTo32Bytes(uuid: string) { export function shrinkUuidTo32Bytes(uuid: string) {
return uuid.replaceAll('-', ''); return uuid.replace(/\-/g, '');
} }
export function expandUuidTo36Bytes(uuidShrinked: string) { export function expandUuidTo36Bytes(uuidShrinked: string) {