diff --git a/lib/base-app-domain/ActionDefDict.d.ts b/lib/base-app-domain/ActionDefDict.d.ts index 70e53b0..e60f600 100644 --- a/lib/base-app-domain/ActionDefDict.d.ts +++ b/lib/base-app-domain/ActionDefDict.d.ts @@ -1,5 +1,8 @@ export declare const ActionDefDict: { modi: { - iState: import("../types").ActionDef; + iState: import("../types").ActionDef; + }; + user: { + userState: import("../types").ActionDef; }; }; diff --git a/lib/base-app-domain/ActionDefDict.js b/lib/base-app-domain/ActionDefDict.js index 3c459d2..3577b73 100644 --- a/lib/base-app-domain/ActionDefDict.js +++ b/lib/base-app-domain/ActionDefDict.js @@ -2,6 +2,8 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.ActionDefDict = void 0; var Action_1 = require("./Modi/Action"); +var Action_2 = require("./User/Action"); exports.ActionDefDict = { - modi: Action_1.ActionDefDict + modi: Action_1.ActionDefDict, + user: Action_2.ActionDefDict }; diff --git a/lib/base-app-domain/EntityDict.d.ts b/lib/base-app-domain/EntityDict.d.ts index cb81cf2..3d22998 100644 --- a/lib/base-app-domain/EntityDict.d.ts +++ b/lib/base-app-domain/EntityDict.d.ts @@ -3,10 +3,12 @@ import { EntityDef as ModiEntity } from "./ModiEntity/Schema"; import { EntityDef as Oper } from "./Oper/Schema"; import { EntityDef as OperEntity } from "./OperEntity/Schema"; import { EntityDef as User } from "./User/Schema"; +import { EntityDef as UserEntityGrant } from "./UserEntityGrant/Schema"; export declare type EntityDict = { modi: Modi; modiEntity: ModiEntity; oper: Oper; operEntity: OperEntity; user: User; + userEntityGrant: UserEntityGrant; }; diff --git a/lib/base-app-domain/Modi/Action.d.ts b/lib/base-app-domain/Modi/Action.d.ts index e22999c..0cae5fa 100644 --- a/lib/base-app-domain/Modi/Action.d.ts +++ b/lib/base-app-domain/Modi/Action.d.ts @@ -1,10 +1,10 @@ import { ActionDef } from "../../types/Action"; import { GenericAction } from "../../actions/action"; -export declare type IState = 'active' | 'applied' | 'abandoned'; -export declare type IAction = 'apply' | 'abandon'; +export declare type IState = 'active' | 'applied' | 'abandoned' | string; +export declare type IAction = 'apply' | 'abandon' | string; export declare type ParticularAction = IAction; -export declare type Action = GenericAction | ParticularAction; +export declare type Action = GenericAction | ParticularAction | string; export declare const actions: string[]; export declare const ActionDefDict: { - iState: ActionDef; + iState: ActionDef; }; diff --git a/lib/base-app-domain/ModiEntity/Schema.d.ts b/lib/base-app-domain/ModiEntity/Schema.d.ts index 571f43b..d7ec3fc 100644 --- a/lib/base-app-domain/ModiEntity/Schema.d.ts +++ b/lib/base-app-domain/ModiEntity/Schema.d.ts @@ -6,18 +6,20 @@ import { FormCreateData, FormUpdateData, DeduceAggregation, Operation as OakOper import { AppendOnlyAction } from "../../actions/action"; import * as Modi from "../Modi/Schema"; import * as User from "../User/Schema"; +import * as UserEntityGrant from "../UserEntityGrant/Schema"; export declare type OpSchema = EntityShape & { modiId: ForeignKey<"modi">; - entity: "user" | string; + entity: "user" | "userEntityGrant" | string; entityId: String<64>; }; export declare type OpAttr = keyof OpSchema; export declare type Schema = EntityShape & { modiId: ForeignKey<"modi">; - entity: "user" | string; + entity: "user" | "userEntityGrant" | string; entityId: String<64>; modi: Modi.Schema; user?: User.Schema; + userEntityGrant?: UserEntityGrant.Schema; } & { [A in ExpressionKey]?: any; }; @@ -31,8 +33,9 @@ declare type AttrFilter = { entity: E; entityId: Q_StringValue; user: User.Filter; + userEntityGrant: UserEntityGrant.Filter; }; -export declare type Filter> = MakeFilter & ExprOp>; +export declare type Filter> = MakeFilter & ExprOp>; export declare type Projection = { "#id"?: NodeId; [k: string]: any; @@ -45,6 +48,7 @@ export declare type Projection = { entity?: number; entityId?: number; user?: User.Projection; + userEntityGrant?: UserEntityGrant.Projection; } & Partial>; declare type ModiEntityIdProjection = OneOf<{ id: number; @@ -55,6 +59,9 @@ declare type ModiIdProjection = OneOf<{ declare type UserIdProjection = OneOf<{ entityId: number; }>; +declare type UserEntityGrantIdProjection = OneOf<{ + entityId: number; +}>; export declare type SortAttr = { id: number; } | { @@ -73,6 +80,8 @@ export declare type SortAttr = { entityId: number; } | { user: User.SortAttr; +} | { + userEntityGrant: UserEntityGrant.SortAttr; } | { [k: string]: any; } | OneOf>; @@ -103,6 +112,17 @@ export declare type CreateOperationData = FormCreateData; +} | { + entity?: never; + entityId?: never; + userEntityGrant: UserEntityGrant.CreateSingleOperation; +} | { + entity: "userEntityGrant"; + entityId: String<64>; + userEntityGrant: UserEntityGrant.UpdateOperation; +} | { + entity: "userEntityGrant"; + entityId: String<64>; } | { entity?: string; entityId?: string; @@ -128,7 +148,11 @@ export declare type UpdateOperationData = FormUpdateData | null; }) & { [k: string]: any; @@ -138,6 +162,8 @@ export declare type RemoveOperationData = {} & (({ modi?: Modi.UpdateOperation | Modi.RemoveOperation; })) & ({ user?: User.UpdateOperation | User.RemoveOperation; +} | { + userEntityGrant?: UserEntityGrant.UpdateOperation | UserEntityGrant.RemoveOperation; } | { [k: string]: any; }); @@ -145,6 +171,7 @@ export declare type RemoveOperation = OakOperation<"remove", RemoveOperationData export declare type Operation = CreateOperation | UpdateOperation | RemoveOperation; export declare type ModiIdSubQuery = Selection; export declare type UserIdSubQuery = Selection; +export declare type UserEntityGrantIdSubQuery = Selection; export declare type ModiEntityIdSubQuery = Selection; export declare type EntityDef = { Schema: Schema; diff --git a/lib/base-app-domain/ModiEntity/Storage.js b/lib/base-app-domain/ModiEntity/Storage.js index 5b23dcd..7b8a078 100644 --- a/lib/base-app-domain/ModiEntity/Storage.js +++ b/lib/base-app-domain/ModiEntity/Storage.js @@ -13,7 +13,7 @@ exports.desc = { params: { length: 32 }, - ref: ["user"] + ref: ["user", "userEntityGrant"] }, entityId: { type: "varchar", diff --git a/lib/base-app-domain/OperEntity/Schema.d.ts b/lib/base-app-domain/OperEntity/Schema.d.ts index 77b67c6..8497388 100644 --- a/lib/base-app-domain/OperEntity/Schema.d.ts +++ b/lib/base-app-domain/OperEntity/Schema.d.ts @@ -7,19 +7,21 @@ import { AppendOnlyAction } from "../../actions/action"; import * as Oper from "../Oper/Schema"; import * as Modi from "../Modi/Schema"; import * as User from "../User/Schema"; +import * as UserEntityGrant from "../UserEntityGrant/Schema"; export declare type OpSchema = EntityShape & { operId: ForeignKey<"oper">; - entity: "modi" | "user" | string; + entity: "modi" | "user" | "userEntityGrant" | string; entityId: String<64>; }; export declare type OpAttr = keyof OpSchema; export declare type Schema = EntityShape & { operId: ForeignKey<"oper">; - entity: "modi" | "user" | string; + entity: "modi" | "user" | "userEntityGrant" | string; entityId: String<64>; oper: Oper.Schema; modi?: Modi.Schema; user?: User.Schema; + userEntityGrant?: UserEntityGrant.Schema; } & { [A in ExpressionKey]?: any; }; @@ -34,8 +36,9 @@ declare type AttrFilter = { entityId: Q_StringValue; modi: Modi.Filter; user: User.Filter; + userEntityGrant: UserEntityGrant.Filter; }; -export declare type Filter> = MakeFilter & ExprOp>; +export declare type Filter> = MakeFilter & ExprOp>; export declare type Projection = { "#id"?: NodeId; [k: string]: any; @@ -49,6 +52,7 @@ export declare type Projection = { entityId?: number; modi?: Modi.Projection; user?: User.Projection; + userEntityGrant?: UserEntityGrant.Projection; } & Partial>; declare type OperEntityIdProjection = OneOf<{ id: number; @@ -62,6 +66,9 @@ declare type ModiIdProjection = OneOf<{ declare type UserIdProjection = OneOf<{ entityId: number; }>; +declare type UserEntityGrantIdProjection = OneOf<{ + entityId: number; +}>; export declare type SortAttr = { id: number; } | { @@ -82,6 +89,8 @@ export declare type SortAttr = { modi: Modi.SortAttr; } | { user: User.SortAttr; +} | { + userEntityGrant: UserEntityGrant.SortAttr; } | { [k: string]: any; } | OneOf>; @@ -120,6 +129,17 @@ export declare type CreateOperationData = FormCreateData; +} | { + entity?: never; + entityId?: never; + userEntityGrant: UserEntityGrant.CreateSingleOperation; +} | { + entity: "userEntityGrant"; + entityId: String<64>; + userEntityGrant: UserEntityGrant.UpdateOperation; +} | { + entity: "userEntityGrant"; + entityId: String<64>; } | { entity?: string; entityId?: string; @@ -143,7 +163,11 @@ export declare type UpdateOperationData = FormUpdateData | null; }) & { [k: string]: any; @@ -153,6 +177,8 @@ export declare type RemoveOperationData = {} & ({ modi?: Modi.UpdateOperation | Modi.RemoveOperation; } | { user?: User.UpdateOperation | User.RemoveOperation; +} | { + userEntityGrant?: UserEntityGrant.UpdateOperation | UserEntityGrant.RemoveOperation; } | { [k: string]: any; }); @@ -161,6 +187,7 @@ export declare type Operation = CreateOperation | UpdateOperation | RemoveOperat export declare type OperIdSubQuery = Selection; export declare type ModiIdSubQuery = Selection; export declare type UserIdSubQuery = Selection; +export declare type UserEntityGrantIdSubQuery = Selection; export declare type OperEntityIdSubQuery = Selection; export declare type EntityDef = { Schema: Schema; diff --git a/lib/base-app-domain/OperEntity/Storage.js b/lib/base-app-domain/OperEntity/Storage.js index 3056ed0..8d775ea 100644 --- a/lib/base-app-domain/OperEntity/Storage.js +++ b/lib/base-app-domain/OperEntity/Storage.js @@ -13,7 +13,7 @@ exports.desc = { params: { length: 32 }, - ref: ["modi", "user"] + ref: ["modi", "user", "userEntityGrant"] }, entityId: { type: "varchar", diff --git a/lib/base-app-domain/Storage.js b/lib/base-app-domain/Storage.js index ec6c76a..a08efa8 100644 --- a/lib/base-app-domain/Storage.js +++ b/lib/base-app-domain/Storage.js @@ -6,10 +6,12 @@ var Storage_2 = require("./ModiEntity/Storage"); var Storage_3 = require("./Oper/Storage"); var Storage_4 = require("./OperEntity/Storage"); var Storage_5 = require("./User/Storage"); +var Storage_6 = require("./UserEntityGrant/Storage"); exports.storageSchema = { modi: Storage_1.desc, modiEntity: Storage_2.desc, oper: Storage_3.desc, operEntity: Storage_4.desc, - user: Storage_5.desc + user: Storage_5.desc, + userEntityGrant: Storage_6.desc }; diff --git a/lib/base-app-domain/User/Action.d.ts b/lib/base-app-domain/User/Action.d.ts new file mode 100644 index 0000000..84cc307 --- /dev/null +++ b/lib/base-app-domain/User/Action.d.ts @@ -0,0 +1,10 @@ +import { ActionDef } from "../../types/Action"; +import { GenericAction, RelationAction } from "../../actions/action"; +export declare type UserAction = 'mergeTo' | string; +export declare type UserState = 'normal' | 'merged' | string; +export declare type ParticularAction = UserAction; +export declare type Action = GenericAction | ParticularAction | RelationAction | string; +export declare const actions: string[]; +export declare const ActionDefDict: { + userState: ActionDef; +}; diff --git a/lib/base-app-domain/User/Action.js b/lib/base-app-domain/User/Action.js new file mode 100644 index 0000000..8b02943 --- /dev/null +++ b/lib/base-app-domain/User/Action.js @@ -0,0 +1,12 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ActionDefDict = exports.actions = void 0; +exports.actions = ["count", "stat", "download", "select", "aggregate", "create", "remove", "update", "grant", "revoke", "mergeTo"]; +var UserActionDef = { + stm: { + mergeTo: ['normal', 'merged'] + } +}; +exports.ActionDefDict = { + userState: UserActionDef +}; diff --git a/lib/base-app-domain/User/Schema.d.ts b/lib/base-app-domain/User/Schema.d.ts index 54a81c5..6f2d79c 100644 --- a/lib/base-app-domain/User/Schema.d.ts +++ b/lib/base-app-domain/User/Schema.d.ts @@ -1,9 +1,10 @@ -import { String, Text } from "../../types/DataType"; -import { Q_DateValue, Q_StringValue, NodeId, MakeFilter, ExprOp, ExpressionKey } from "../../types/Demand"; +import { String, Text, ForeignKey } from "../../types/DataType"; +import { Q_DateValue, Q_StringValue, Q_EnumValue, NodeId, MakeFilter, ExprOp, ExpressionKey } from "../../types/Demand"; import { OneOf } from "../../types/Polyfill"; import * as SubQuery from "../_SubQuery"; 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 { Action, ParticularAction, UserState } from "./Action"; +import { RelationAction } from "../../actions/action"; import * as Oper from "../Oper/Schema"; import * as OperEntity from "../OperEntity/Schema"; import * as ModiEntity from "../ModiEntity/Schema"; @@ -11,14 +12,21 @@ export declare type OpSchema = EntityShape & { name?: String<16> | null; nickname?: String<64> | null; password?: Text | null; + refId?: ForeignKey<"user"> | null; + userState?: UserState | null; }; export declare type OpAttr = keyof OpSchema; export declare type Schema = EntityShape & { name?: String<16> | null; nickname?: String<64> | null; password?: Text | null; + refId?: ForeignKey<"user"> | null; + userState?: UserState | null; + ref?: Schema | null; oper$operator?: Array; oper$operator$$aggr?: AggregationResult; + user$ref?: Array; + user$ref$$aggr?: AggregationResult; operEntity$entity?: Array; operEntity$entity$$aggr?: AggregationResult; modiEntity$entity?: Array; @@ -34,6 +42,9 @@ declare type AttrFilter = { name: Q_StringValue; nickname: Q_StringValue; password: Q_StringValue; + refId: Q_StringValue | SubQuery.UserIdSubQuery; + ref: Filter; + userState: Q_EnumValue; }; export declare type Filter = MakeFilter>; export declare type Projection = { @@ -46,12 +57,21 @@ export declare type Projection = { name?: number; nickname?: number; password?: number; + refId?: number; + ref?: Projection; + userState?: number; oper$operator?: Oper.Selection & { $entity: "oper"; }; oper$operator$$aggr?: Oper.Aggregation & { $entity: "oper"; }; + user$ref?: Selection & { + $entity: "user"; + }; + user$ref$$aggr?: Aggregation & { + $entity: "user"; + }; operEntity$entity?: OperEntity.Selection & { $entity: "operEntity"; }; @@ -67,6 +87,7 @@ export declare type Projection = { } & Partial>; declare type UserIdProjection = OneOf<{ id: number; + refId: number; }>; export declare type SortAttr = { id: number; @@ -82,6 +103,12 @@ export declare type SortAttr = { nickname: number; } | { password: number; +} | { + refId: number; +} | { + ref: SortAttr; +} | { + userState: number; } | { [k: string]: any; } | OneOf>; @@ -93,29 +120,53 @@ export declare type Sorter = SortNode[]; export declare type SelectOperation

= OakSelection<"select", P, Filter, Sorter>; export declare type Selection

= Omit, "action">; export declare type Aggregation = DeduceAggregation; -export declare type CreateOperationData = FormCreateData & { +export declare type CreateOperationData = FormCreateData> & (({ + refId?: never; + ref?: CreateSingleOperation; +} | { + refId: String<64>; + ref?: UpdateOperation; +} | { + refId?: String<64>; +})) & { oper$operator?: OakOperation<"create", Omit[]> | Array>>; + user$ref?: OakOperation, Filter> | OakOperation<"create", Omit[]> | Array> | OakOperation, Filter>>; operEntity$entity?: OakOperation<"create", Omit[]> | Array>>; modiEntity$entity?: OakOperation<"create", Omit[]> | Array>>; }; export declare type CreateSingleOperation = OakOperation<"create", CreateOperationData>; export declare type CreateMultipleOperation = OakOperation<"create", Array>; export declare type CreateOperation = CreateSingleOperation | CreateMultipleOperation; -export declare type UpdateOperationData = FormUpdateData & { +export declare type UpdateOperationData = FormUpdateData> & (({ + ref: CreateSingleOperation; + refId?: never; +} | { + ref: UpdateOperation; + refId?: never; +} | { + ref: RemoveOperation; + refId?: never; +} | { + ref?: never; + refId?: String<64> | null; +})) & { [k: string]: any; oper$operator?: OakOperation<"create", Omit[]> | Array>>; + user$ref?: UpdateOperation | RemoveOperation | OakOperation<"create", Omit[]> | Array> | UpdateOperation | RemoveOperation>; operEntity$entity?: OakOperation<"create", Omit[]> | Array>>; modiEntity$entity?: OakOperation<"create", Omit[]> | Array>>; }; -export declare type UpdateOperation = OakOperation<"update" | RelationAction | string, UpdateOperationData, Filter, Sorter>; -export declare type RemoveOperationData = {}; +export declare type UpdateOperation = OakOperation<"update" | ParticularAction | RelationAction | string, UpdateOperationData, Filter, Sorter>; +export declare type RemoveOperationData = {} & (({ + ref?: UpdateOperation | RemoveOperation; +})); export declare type RemoveOperation = OakOperation<"remove", RemoveOperationData, Filter, Sorter>; export declare type Operation = CreateOperation | UpdateOperation | RemoveOperation; export declare type UserIdSubQuery = Selection; export declare type EntityDef = { Schema: Schema; OpSchema: OpSchema; - Action: OakMakeAction | string; + Action: OakMakeAction | string; Selection: Selection; Aggregation: Aggregation; Operation: Operation; @@ -124,5 +175,6 @@ export declare type EntityDef = { Remove: RemoveOperation; CreateSingle: CreateSingleOperation; CreateMulti: CreateMultipleOperation; + ParticularAction: ParticularAction; }; export {}; diff --git a/lib/base-app-domain/User/Storage.js b/lib/base-app-domain/User/Storage.js index 75d26fc..ec86925 100644 --- a/lib/base-app-domain/User/Storage.js +++ b/lib/base-app-domain/User/Storage.js @@ -1,6 +1,7 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.desc = void 0; +var Action_1 = require("./Action"); var action_1 = require("../../actions/action"); exports.desc = { attributes: { @@ -18,8 +19,18 @@ exports.desc = { }, password: { type: "text" + }, + refId: { + type: "ref", + ref: "user" + }, + userState: { + type: "varchar", + params: { + length: 24 + } } }, actionType: "crud", - actions: action_1.genericActions.concat(action_1.relationActions) + actions: Action_1.actions.concat(action_1.relationActions) }; diff --git a/lib/base-app-domain/UserEntityGrant/Schema.d.ts b/lib/base-app-domain/UserEntityGrant/Schema.d.ts new file mode 100644 index 0000000..6e2d17b --- /dev/null +++ b/lib/base-app-domain/UserEntityGrant/Schema.d.ts @@ -0,0 +1,121 @@ +import { String } from "../../types/DataType"; +import { Q_DateValue, Q_StringValue, NodeId, MakeFilter, ExprOp, ExpressionKey } from "../../types/Demand"; +import { OneOf } from "../../types/Polyfill"; +import * as SubQuery from "../_SubQuery"; +import { FormCreateData, FormUpdateData, DeduceAggregation, Operation as OakOperation, Selection as OakSelection, MakeAction as OakMakeAction, EntityShape, AggregationResult } from "../../types/Entity"; +import { GenericAction } from "../../actions/action"; +import * as OperEntity from "../OperEntity/Schema"; +import * as ModiEntity from "../ModiEntity/Schema"; +export declare type OpSchema = EntityShape & { + entity: String<32>; + entityId: String<64>; + relation: String<32>; +}; +export declare type OpAttr = keyof OpSchema; +export declare type Schema = EntityShape & { + entity: String<32>; + entityId: String<64>; + relation: String<32>; + operEntity$entity?: Array; + operEntity$entity$$aggr?: AggregationResult; + modiEntity$entity?: Array; + modiEntity$entity$$aggr?: AggregationResult; +} & { + [A in ExpressionKey]?: any; +}; +declare type AttrFilter = { + id: Q_StringValue | SubQuery.UserEntityGrantIdSubQuery; + $$createAt$$: Q_DateValue; + $$seq$$: Q_StringValue; + $$updateAt$$: Q_DateValue; + entity: Q_StringValue; + entityId: Q_StringValue; + relation: Q_StringValue; +}; +export declare type Filter = MakeFilter>; +export declare type Projection = { + "#id"?: NodeId; + [k: string]: any; + id?: number; + $$createAt$$?: number; + $$updateAt$$?: number; + $$seq$$?: number; + entity?: number; + entityId?: number; + relation?: number; + operEntity$entity?: OperEntity.Selection & { + $entity: "operEntity"; + }; + operEntity$entity$$aggr?: OperEntity.Aggregation & { + $entity: "operEntity"; + }; + modiEntity$entity?: ModiEntity.Selection & { + $entity: "modiEntity"; + }; + modiEntity$entity$$aggr?: ModiEntity.Aggregation & { + $entity: "modiEntity"; + }; +} & Partial>; +declare type UserEntityGrantIdProjection = OneOf<{ + id: number; +}>; +export declare type SortAttr = { + id: number; +} | { + $$createAt$$: number; +} | { + $$seq$$: number; +} | { + $$updateAt$$: number; +} | { + entity: number; +} | { + entityId: number; +} | { + relation: number; +} | { + [k: string]: any; +} | OneOf>; +export declare type SortNode = { + $attr: SortAttr; + $direction?: "asc" | "desc"; +}; +export declare type Sorter = SortNode[]; +export declare type SelectOperation

= OakSelection<"select", P, Filter, Sorter>; +export declare type Selection

= Omit, "action">; +export declare type Aggregation = DeduceAggregation; +export declare type CreateOperationData = FormCreateData> & ({ + entity?: string; + entityId?: string; + [K: string]: any; +}) & { + operEntity$entity?: OakOperation<"create", Omit[]> | Array>>; + modiEntity$entity?: OakOperation<"create", Omit[]> | Array>>; +}; +export declare type CreateSingleOperation = OakOperation<"create", CreateOperationData>; +export declare type CreateMultipleOperation = OakOperation<"create", Array>; +export declare type CreateOperation = CreateSingleOperation | CreateMultipleOperation; +export declare type UpdateOperationData = FormUpdateData & { + [k: string]: any; + operEntity$entity?: OakOperation<"create", Omit[]> | Array>>; + modiEntity$entity?: OakOperation<"create", Omit[]> | Array>>; +}; +export declare type UpdateOperation = OakOperation<"update" | string, UpdateOperationData, Filter, Sorter>; +export declare type RemoveOperationData = {}; +export declare type RemoveOperation = OakOperation<"remove", RemoveOperationData, Filter, Sorter>; +export declare type Operation = CreateOperation | UpdateOperation | RemoveOperation; +export declare type UserEntityGrantIdSubQuery = Selection; +export declare type EntityDef = { + Schema: Schema; + OpSchema: OpSchema; + Action: OakMakeAction | string; + Selection: Selection; + Aggregation: Aggregation; + Operation: Operation; + Create: CreateOperation; + Update: UpdateOperation; + Remove: RemoveOperation; + CreateSingle: CreateSingleOperation; + CreateMulti: CreateMultipleOperation; +}; +export {}; diff --git a/lib/base-app-domain/UserEntityGrant/Schema.js b/lib/base-app-domain/UserEntityGrant/Schema.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/lib/base-app-domain/UserEntityGrant/Schema.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/lib/base-app-domain/UserEntityGrant/Storage.d.ts b/lib/base-app-domain/UserEntityGrant/Storage.d.ts new file mode 100644 index 0000000..606c158 --- /dev/null +++ b/lib/base-app-domain/UserEntityGrant/Storage.d.ts @@ -0,0 +1,3 @@ +import { StorageDesc } from "../../types/Storage"; +import { OpSchema } from "./Schema"; +export declare const desc: StorageDesc; diff --git a/lib/base-app-domain/UserEntityGrant/Storage.js b/lib/base-app-domain/UserEntityGrant/Storage.js new file mode 100644 index 0000000..952b3bd --- /dev/null +++ b/lib/base-app-domain/UserEntityGrant/Storage.js @@ -0,0 +1,28 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.desc = void 0; +var action_1 = require("../../actions/action"); +exports.desc = { + attributes: { + entity: { + type: "varchar", + params: { + length: 32 + } + }, + entityId: { + type: "varchar", + params: { + length: 64 + } + }, + relation: { + type: "varchar", + params: { + length: 32 + } + } + }, + actionType: "crud", + actions: action_1.genericActions +}; diff --git a/lib/base-app-domain/_SubQuery.d.ts b/lib/base-app-domain/_SubQuery.d.ts index 4b68ed6..9394204 100644 --- a/lib/base-app-domain/_SubQuery.d.ts +++ b/lib/base-app-domain/_SubQuery.d.ts @@ -3,6 +3,7 @@ import * as ModiEntity from "./ModiEntity/Schema"; import * as Oper from "./Oper/Schema"; import * as OperEntity from "./OperEntity/Schema"; import * as User from "./User/Schema"; +import * as UserEntityGrant from "./UserEntityGrant/Schema"; export declare type ModiIdSubQuery = { [K in "$in" | "$nin"]?: (ModiEntity.ModiIdSubQuery & { entity: "modiEntity"; @@ -32,5 +33,12 @@ export declare type UserIdSubQuery = { entity: "oper"; }) | (User.UserIdSubQuery & { entity: "user"; + }) | (User.UserIdSubQuery & { + entity: "user"; + }) | any; +}; +export declare type UserEntityGrantIdSubQuery = { + [K in "$in" | "$nin"]?: (UserEntityGrant.UserEntityGrantIdSubQuery & { + entity: "userEntityGrant"; }) | any; }; diff --git a/lib/checkers/index.js b/lib/checkers/index.js index 2482056..497eee8 100644 --- a/lib/checkers/index.js +++ b/lib/checkers/index.js @@ -7,7 +7,7 @@ var modi_1 = require("../store/modi"); function createDynamicCheckers(schema, authDict) { var checkers = []; checkers.push.apply(checkers, tslib_1.__spreadArray([], tslib_1.__read((0, modi_1.createModiRelatedCheckers)(schema)), false)); - // checkers.push(...createRemoveCheckers(schema)); + checkers.push.apply(checkers, tslib_1.__spreadArray([], tslib_1.__read((0, checker_1.createRemoveCheckers)(schema)), false)); if (authDict) { checkers.push.apply(checkers, tslib_1.__spreadArray([], tslib_1.__read((0, checker_1.createAuthCheckers)(schema, authDict)), false)); } diff --git a/lib/compiler/schemalBuilder.js b/lib/compiler/schemalBuilder.js index d33a45b..e60d455 100644 --- a/lib/compiler/schemalBuilder.js +++ b/lib/compiler/schemalBuilder.js @@ -51,6 +51,20 @@ function addRelationship(many, one, key, notNull) { _b)); } } +/** + * 对relationship去重。一旦发生对象重定义这里就有可能重复 + */ +function uniqRelationships() { + for (var entity in ManyToOne) { + ManyToOne[entity] = (0, lodash_1.uniqBy)(ManyToOne[entity], function (ele) { return "".concat(ele[0], "-").concat(ele[1]); }); + } + for (var entity in OneToMany) { + OneToMany[entity] = (0, lodash_1.uniqBy)(OneToMany[entity], function (ele) { return "".concat(ele[0], "-").concat(ele[1]); }); + } + for (var entity in ReversePointerRelations) { + OneToMany[entity] = (0, lodash_1.uniq)(OneToMany[entity]); + } +} function createForeignRef(entity, foreignKey, ref) { if (entity === foreignKey) { return factory.createIdentifier(ref); @@ -317,9 +331,10 @@ function analyzeEntity(filename, path, program, relativePath) { var sourceFile = program.getSourceFile(fullPath); var moduleName = filename.split('.')[0]; if (Schema.hasOwnProperty(moduleName)) { - if (!path.includes('oak-general-business')) { - console.log("\u51FA\u73B0\u4E86\u540C\u540D\u7684Entity\u5B9A\u4E49\u300C".concat(moduleName, "\u300D\uFF0C\u5C06\u4F7F\u7528\u60A8\u6240\u5B9A\u4E49\u7684\u5BF9\u8C61\u7ED3\u6784\u53D6\u4EE3\u6389\u9ED8\u8BA4\u5BF9\u8C61\uFF0C\u8BF7\u786E\u8BA4")); - } + delete ActionAsts[moduleName]; + delete SchemaAsts[moduleName]; + // removeFromRelationShip(moduleName); + console.warn("\u51FA\u73B0\u4E86\u540C\u540D\u7684Entity\u5B9A\u4E49\u300C".concat(moduleName, "\u300D\uFF0C\u5C06\u4F7F\u7528").concat(fullPath, "\u53D6\u4EE3\u6389\u9ED8\u8BA4\u5BF9\u8C61\uFF0C\u8BF7\u68C0\u67E5\u65B0\u7684\u5BF9\u8C61\u7ED3\u6784\u53CA\u76F8\u5173\u5E38\u91CF\u5B9A\u4E49\u4E0E\u539F\u6709\u7684\u517C\u5BB9\uFF0C\u5426\u5219\u539F\u6709\u5BF9\u8C61\u7684\u76F8\u5173\u903B\u8F91\u4F1A\u51FA\u73B0\u4E0D\u53EF\u77E5\u5F02\u5E38")); } var referencedSchemas = []; var schemaAttrs = []; @@ -340,7 +355,7 @@ function analyzeEntity(filename, path, program, relativePath) { // let relationHierarchy: ts.ObjectLiteralExpression | undefined = undefined; // let reverseCascadeRelationHierarchy: ts.ObjectLiteralExpression | undefined = undefined; ts.forEachChild(sourceFile, function (node) { - var _a, _b, _c, _d; + var _a, _b, _c, _d, _e; if (ts.isImportDeclaration(node)) { var entityImported = getEntityImported(node); if (entityImported) { @@ -389,7 +404,9 @@ function analyzeEntity(filename, path, program, relativePath) { && referencedSchemas.includes(typeArguments[0].typeName.text), "\u300C".concat(filename, "\u300D\u975E\u6CD5\u7684\u5C5E\u6027\u5B9A\u4E49\u300C").concat(attrName, "\u300D")); var reverseEntity = typeArguments[0].typeName.text; if (ReversePointerRelations[reverseEntity]) { - ReversePointerRelations[reverseEntity].push(moduleName); + if (!ReversePointerRelations[reverseEntity].includes(moduleName)) { + ReversePointerRelations[reverseEntity].push(moduleName); + } } else { (0, lodash_1.assign)(ReversePointerRelations, (_a = {}, @@ -520,6 +537,9 @@ function analyzeEntity(filename, path, program, relativePath) { if (hasRelationDef || moduleName === 'User') { actionDefNodes.push(factory.createTypeReferenceNode('RelationAction', undefined)); } + if (process.env.COMPLING_AS_LIB) { + actionDefNodes.push(factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword)); + } pushStatementIntoActionAst(moduleName, factory.createTypeAliasDeclaration(undefined, [factory.createModifier(ts.SyntaxKind.ExportKeyword)], factory.createIdentifier("Action"), undefined, factory.createUnionTypeNode(actionDefNodes)), sourceFile); dealWithActions(moduleName, filename, node.type, program, sourceFile, !!hasRelationDef || moduleName === 'User'); } @@ -558,12 +578,35 @@ function analyzeEntity(filename, path, program, relativePath) { _d)); addRelationship(relationEntityName, 'User', 'user', true); addRelationship(relationEntityName, moduleName, entityLc, true); + // 对UserEntityGrant对象,建立相应的反指关系 + if (ReversePointerRelations['UserEntityGrant']) { + if (!ReversePointerRelations['UserEntityGrant'].includes(moduleName)) { + ReversePointerRelations['UserEntityGrant'].push(moduleName); + } + } + else { + (0, lodash_1.assign)(ReversePointerRelations, (_e = {}, + _e['UserEntityGrant'] = [moduleName], + _e)); + } hasRelationDef = node; } else if (node.name.text.endsWith('Action') || node.name.text.endsWith('State')) { (0, assert_1.default)(!localeDef, "\u3010".concat(filename, "\u3011locale\u5B9A\u4E49\u987B\u5728Action/State\u4E4B\u540E")); hasActionOrStateDef = true; - pushStatementIntoActionAst(moduleName, factory.updateTypeAliasDeclaration(node, node.decorators, [factory.createModifier(ts.SyntaxKind.ExportKeyword)], node.name, node.typeParameters, node.type), sourceFile); + var type = node.type; + if (ts.isUnionTypeNode(type)) { + pushStatementIntoActionAst(moduleName, factory.updateTypeAliasDeclaration(node, node.decorators, [factory.createModifier(ts.SyntaxKind.ExportKeyword)], node.name, node.typeParameters, process.env.COMPLING_AS_LIB ? factory.createUnionTypeNode(tslib_1.__spreadArray(tslib_1.__spreadArray([], tslib_1.__read(type.types), false), [ + factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword) + ], false)) : type), sourceFile); + } + else { + (0, assert_1.default)(ts.isLiteralTypeNode(type) || ts.isTypeReferenceNode(type), "".concat(moduleName, " - ").concat(node.name)); + pushStatementIntoActionAst(moduleName, factory.updateTypeAliasDeclaration(node, node.decorators, [factory.createModifier(ts.SyntaxKind.ExportKeyword)], node.name, node.typeParameters, process.env.COMPLING_AS_LIB ? factory.createUnionTypeNode([ + type, + factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword) + ]) : type), sourceFile); + } } else if (beforeSchema) { // 本地规定的一些形状定义,直接使用 @@ -3291,6 +3334,7 @@ function analyzeEntities(inputDir, relativePath) { analyzeEntity(filename, inputDir, program, relativePath); }); analyzeInModi(); + uniqRelationships(); } exports.analyzeEntities = analyzeEntities; function buildSchema(outputDir) { diff --git a/lib/entities/User.d.ts b/lib/entities/User.d.ts index 2d435f8..37a5ae1 100644 --- a/lib/entities/User.d.ts +++ b/lib/entities/User.d.ts @@ -4,4 +4,5 @@ export interface Schema extends EntityShape { name?: String<16>; nickname?: String<64>; password?: Text; + ref?: Schema; } diff --git a/lib/entities/User.js b/lib/entities/User.js index 6835a96..f7bd201 100644 --- a/lib/entities/User.js +++ b/lib/entities/User.js @@ -1,12 +1,28 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); ; +var UserActionDef = { + stm: { + mergeTo: ['normal', 'merged'], + }, +}; var locale = { zh_CN: { attr: { name: '姓名', nickname: '昵称', password: '密码', + ref: '指向用户', + userState: '状态', }, + action: { + mergeTo: '合并', + }, + v: { + userState: { + normal: '正常', + merged: '已被合并', + }, + } }, }; diff --git a/lib/entities/UserEntityGrant.d.ts b/lib/entities/UserEntityGrant.d.ts new file mode 100644 index 0000000..222192d --- /dev/null +++ b/lib/entities/UserEntityGrant.d.ts @@ -0,0 +1,7 @@ +import { String } from '../types/DataType'; +import { EntityShape } from '../types/Entity'; +export interface Schema extends EntityShape { + entity: String<32>; + entityId: String<64>; + relation: String<32>; +} diff --git a/lib/entities/UserEntityGrant.js b/lib/entities/UserEntityGrant.js new file mode 100644 index 0000000..f186147 --- /dev/null +++ b/lib/entities/UserEntityGrant.js @@ -0,0 +1,12 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +; +var locale = { + zh_CN: { + attr: { + relation: '关系', + entity: '关联对象', + entityId: '关联对象id', + }, + }, +}; diff --git a/lib/store/checker.js b/lib/store/checker.js index c5ca2bd..a7e1a33 100644 --- a/lib/store/checker.js +++ b/lib/store/checker.js @@ -546,8 +546,8 @@ function createRemoveCheckers(schema) { } }; for (var entity in schema) { - if (['operEntity'].includes(entity)) { - continue; // OperEntity会指向每一个对象,不必处理 + if (['operEntity', 'modiEntity', 'userEntityGrant'].includes(entity)) { + continue; // 系统功能性数据,不用处理 } var attributes = schema[entity].attributes; for (var attr in attributes) { @@ -565,7 +565,7 @@ function createRemoveCheckers(schema) { } } // 当删除一时,要确认多上面没有指向一的数据 - var entities = (0, lodash_1.intersection)(Object.keys(OneToManyMatrix), Object.keys(OneToManyOnEntityMatrix)); + var entities = (0, lodash_1.union)(Object.keys(OneToManyMatrix), Object.keys(OneToManyOnEntityMatrix)); var _loop_3 = function (entity) { checkers.push({ entity: entity, diff --git a/lib/store/modi.js b/lib/store/modi.js index 3cc1f0a..e912483 100644 --- a/lib/store/modi.js +++ b/lib/store/modi.js @@ -2,6 +2,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); exports.createModiRelatedTriggers = exports.createModiRelatedCheckers = exports.abandonModis = exports.applyModis = exports.createOperationsFromModies = void 0; var tslib_1 = require("tslib"); +var types_1 = require("../types"); var action_1 = require("../actions/action"); var lodash_1 = require("../utils/lodash"); var uuid_1 = require("../utils/uuid"); @@ -154,35 +155,52 @@ function createModiRelatedTriggers(schema) { if (inModi) { // 当关联modi的对象被删除时,对应的modi也删除 triggers.push({ - name: "\u5F53\u5220\u9664".concat(entity, "\u5BF9\u8C61\u65F6\uFF0C\u5220\u9664\u76F8\u5173\u8054\u8FD8\u6D3B\u8DC3\u7684modi"), + name: "\u5F53\u5220\u9664".concat(entity, "\u5BF9\u8C61\u65F6\uFF0C\u5220\u9664\u76F8\u5173\u8054\u7684modi\u7684modiEntity"), action: 'remove', entity: entity, when: 'after', + priority: types_1.REMOVE_CASCADE_PRIORITY, fn: function (_a, context, option) { var operation = _a.operation; return tslib_1.__awaiter(_this, void 0, void 0, function () { - var data, id, _b, _c, _d; - var _e; - return tslib_1.__generator(this, function (_f) { - switch (_f.label) { + var data, id, _b, _c, _d, _e, _f, _g; + var _h, _j; + return tslib_1.__generator(this, function (_k) { + switch (_k.label) { case 0: data = operation.data; id = data.id; _c = (_b = context).operate; - _d = ['modi']; - _e = {}; + _d = ['modiEntity']; + _h = {}; return [4 /*yield*/, (0, uuid_1.generateNewIdAsync)()]; - case 1: return [4 /*yield*/, _c.apply(_b, _d.concat([(_e.id = _f.sent(), - _e.action = 'remove', - _e.data = {}, - _e.filter = { + case 1: return [4 /*yield*/, _c.apply(_b, _d.concat([(_h.id = _k.sent(), + _h.action = 'remove', + _h.data = {}, + _h.filter = { + modi: { + entity: entity, + entityId: id, + }, + }, + _h), { dontCollect: true }]))]; + case 2: + _k.sent(); + _f = (_e = context).operate; + _g = ['modi']; + _j = {}; + return [4 /*yield*/, (0, uuid_1.generateNewIdAsync)()]; + case 3: return [4 /*yield*/, _f.apply(_e, _g.concat([(_j.id = _k.sent(), + _j.action = 'remove', + _j.data = {}, + _j.filter = { entity: entity, entityId: id, }, - _e), option]))]; - case 2: - _f.sent(); - return [2 /*return*/, 1]; + _j), { dontCollect: true }]))]; + case 4: + _k.sent(); + return [2 /*return*/, 0]; } }); }); diff --git a/lib/types/Trigger.d.ts b/lib/types/Trigger.d.ts index 178e994..efe1037 100644 --- a/lib/types/Trigger.d.ts +++ b/lib/types/Trigger.d.ts @@ -12,6 +12,7 @@ export declare const TRIGGER_MIN_PRIORITY = 1; export declare const TRIGGER_MAX_PRIORITY = 99; export declare const DATA_CHECKER_DEFAULT_PRIORITY = 60; export declare const CHECKER_DEFAULT_PRIORITY = 99; +export declare const REMOVE_CASCADE_PRIORITY = 70; interface TriggerBase { checkerType?: CheckerType; entity: T; diff --git a/lib/types/Trigger.js b/lib/types/Trigger.js index 9d5bc2d..4fc7005 100644 --- a/lib/types/Trigger.js +++ b/lib/types/Trigger.js @@ -1,6 +1,6 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.CHECKER_DEFAULT_PRIORITY = exports.DATA_CHECKER_DEFAULT_PRIORITY = exports.TRIGGER_MAX_PRIORITY = exports.TRIGGER_MIN_PRIORITY = exports.TRIGGER_DEFAULT_PRIORITY = void 0; +exports.REMOVE_CASCADE_PRIORITY = exports.CHECKER_DEFAULT_PRIORITY = exports.DATA_CHECKER_DEFAULT_PRIORITY = exports.TRIGGER_MAX_PRIORITY = exports.TRIGGER_MIN_PRIORITY = exports.TRIGGER_DEFAULT_PRIORITY = void 0; /** * 优先级越小,越早执行。定义在1~99之间 */ @@ -9,6 +9,7 @@ exports.TRIGGER_MIN_PRIORITY = 1; exports.TRIGGER_MAX_PRIORITY = 99; exports.DATA_CHECKER_DEFAULT_PRIORITY = 60; exports.CHECKER_DEFAULT_PRIORITY = 99; +exports.REMOVE_CASCADE_PRIORITY = 70; ; ; ; diff --git a/package.json b/package.json index 2cd07fc..3c262a9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "oak-domain", - "version": "2.4.4", + "version": "2.5.1", "author": { "name": "XuChang" }, diff --git a/src/checkers/index.ts b/src/checkers/index.ts index 936b230..3ecb67b 100644 --- a/src/checkers/index.ts +++ b/src/checkers/index.ts @@ -8,7 +8,7 @@ import { StorageSchema, EntityDict as BaseEntityDict, Checker, AuthDef, AuthDefD export function createDynamicCheckers | SyncContext>(schema: StorageSchema, authDict?: AuthDefDict){ const checkers: Checker[] = []; checkers.push(...createModiRelatedCheckers(schema)); - // checkers.push(...createRemoveCheckers(schema)); + checkers.push(...createRemoveCheckers(schema)); if (authDict) { checkers.push(...createAuthCheckers(schema, authDict)); } diff --git a/src/compiler/schemalBuilder.ts b/src/compiler/schemalBuilder.ts index 22c22ad..b7d0f1a 100644 --- a/src/compiler/schemalBuilder.ts +++ b/src/compiler/schemalBuilder.ts @@ -139,6 +139,22 @@ function addRelationship(many: string, one: string, key: string, notNull: boolea } } +/** + * 对relationship去重。一旦发生对象重定义这里就有可能重复 + */ +function uniqRelationships() { + for (const entity in ManyToOne) { + ManyToOne[entity] = uniqBy(ManyToOne[entity], (ele) => `${ele[0]}-${ele[1]}`); + } + for (const entity in OneToMany) { + OneToMany[entity] = uniqBy(OneToMany[entity], (ele) => `${ele[0]}-${ele[1]}`); + } + for (const entity in ReversePointerRelations) { + OneToMany[entity] = uniq(OneToMany[entity]); + } +} + + function createForeignRef(entity: string, foreignKey: string, ref: string) { if (entity === foreignKey) { return factory.createIdentifier(ref) @@ -477,9 +493,10 @@ function analyzeEntity(filename: string, path: string, program: ts.Program, rela const moduleName = filename.split('.')[0]; if (Schema.hasOwnProperty(moduleName)) { - if (!path.includes('oak-general-business')) { - console.log(`出现了同名的Entity定义「${moduleName}」,将使用您所定义的对象结构取代掉默认对象,请确认`); - } + delete ActionAsts[moduleName]; + delete SchemaAsts[moduleName]; + // removeFromRelationShip(moduleName); + console.warn(`出现了同名的Entity定义「${moduleName}」,将使用${fullPath}取代掉默认对象,请检查新的对象结构及相关常量定义与原有的兼容,否则原有对象的相关逻辑会出现不可知异常`); } const referencedSchemas: string[] = []; const schemaAttrs: ts.TypeElement[] = []; @@ -565,7 +582,9 @@ function analyzeEntity(filename: string, path: string, program: ts.Program, rela `「${filename}」非法的属性定义「${attrName}」`); const reverseEntity = typeArguments![0].typeName.text; if (ReversePointerRelations[reverseEntity]) { - ReversePointerRelations[reverseEntity].push(moduleName); + if (!ReversePointerRelations[reverseEntity].includes(moduleName)) { + ReversePointerRelations[reverseEntity].push(moduleName); + } } else { assign(ReversePointerRelations, { @@ -721,7 +740,7 @@ function analyzeEntity(filename: string, path: string, program: ts.Program, rela 'ParticularAction', undefined ) - ]; + ] as ts.TypeNode[]; if (hasRelationDef || moduleName === 'User') { actionDefNodes.push( factory.createTypeReferenceNode( @@ -730,6 +749,11 @@ function analyzeEntity(filename: string, path: string, program: ts.Program, rela ) ); } + if (process.env.COMPLING_AS_LIB) { + actionDefNodes.push( + factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword) + ); + } pushStatementIntoActionAst( moduleName, factory.createTypeAliasDeclaration( @@ -819,21 +843,55 @@ function analyzeEntity(filename: string, path: string, program: ts.Program, rela addRelationship(relationEntityName, 'User', 'user', true); addRelationship(relationEntityName, moduleName, entityLc, true); + // 对UserEntityGrant对象,建立相应的反指关系 + if (ReversePointerRelations['UserEntityGrant']) { + if (!ReversePointerRelations['UserEntityGrant'].includes(moduleName)) { + ReversePointerRelations['UserEntityGrant'].push(moduleName); + } + } + else { + assign(ReversePointerRelations, { + ['UserEntityGrant']: [moduleName], + }); + } + hasRelationDef = node; } else if (node.name.text.endsWith('Action') || node.name.text.endsWith('State')) { assert(!localeDef, `【${filename}】locale定义须在Action/State之后`); hasActionOrStateDef = true; - pushStatementIntoActionAst(moduleName, - factory.updateTypeAliasDeclaration( - node, - node.decorators, - [factory.createModifier(ts.SyntaxKind.ExportKeyword)], - node.name, - node.typeParameters, - node.type - ), - sourceFile!); + const { type } = node; + if (ts.isUnionTypeNode(type)) { + pushStatementIntoActionAst(moduleName, + factory.updateTypeAliasDeclaration( + node, + node.decorators, + [factory.createModifier(ts.SyntaxKind.ExportKeyword)], + node.name, + node.typeParameters, + process.env.COMPLING_AS_LIB ? factory.createUnionTypeNode([ + ...type.types, + factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword) + ]) : type + ), + sourceFile!); + } + else { + assert(ts.isLiteralTypeNode(type) || ts.isTypeReferenceNode(type), `${moduleName} - ${node.name}`); + pushStatementIntoActionAst(moduleName, + factory.updateTypeAliasDeclaration( + node, + node.decorators, + [factory.createModifier(ts.SyntaxKind.ExportKeyword)], + node.name, + node.typeParameters, + process.env.COMPLING_AS_LIB ? factory.createUnionTypeNode([ + type, + factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword) + ]) : type + ), + sourceFile!); + } } else if (beforeSchema) { // 本地规定的一些形状定义,直接使用 @@ -5237,7 +5295,7 @@ function constructAttributes(entity: string): ts.PropertyAssignment[] { ele => factory.createStringLiteral(ele) ), false - ) + ) ) ); } @@ -6146,6 +6204,7 @@ export function analyzeEntities(inputDir: string, relativePath?: string) { } ); analyzeInModi(); + uniqRelationships(); } export function buildSchema(outputDir: string): void { diff --git a/src/entities/User.ts b/src/entities/User.ts index f6ac8dd..0962a3b 100644 --- a/src/entities/User.ts +++ b/src/entities/User.ts @@ -1,20 +1,45 @@ import { String, Int, Text, Image, Datetime } from '../types/DataType'; import { LocaleDef } from '../types/Locale'; import { EntityShape } from '../types/Entity'; +import { ActionDef } from '../types/Action'; export interface Schema extends EntityShape { name?: String<16>; nickname?: String<64>; password?: Text; + ref?: Schema; }; +type UserAction = 'mergeTo'; +type UserState = 'normal' | 'merged'; -const locale: LocaleDef = { +type Action = UserAction; + +const UserActionDef: ActionDef = { + stm: { + mergeTo: ['normal', 'merged'], + }, +}; + +const locale: LocaleDef = { zh_CN: { attr: { name: '姓名', nickname: '昵称', password: '密码', + ref: '指向用户', + userState: '状态', }, + action: { + mergeTo: '合并', + }, + v: { + userState: { + normal: '正常', + merged: '已被合并', + }, + } }, }; \ No newline at end of file diff --git a/src/entities/UserEntityGrant.ts b/src/entities/UserEntityGrant.ts new file mode 100644 index 0000000..8586b7d --- /dev/null +++ b/src/entities/UserEntityGrant.ts @@ -0,0 +1,24 @@ +import { String } from '../types/DataType'; +import { LocaleDef } from '../types/Locale'; +import { EntityShape } from '../types/Entity'; + +export interface Schema extends EntityShape { + entity: String<32>; + entityId: String<64>; + relation: String<32>; +}; + +const locale: LocaleDef< + Schema, + '', + '', + {} +> = { + zh_CN: { + attr: { + relation: '关系', + entity: '关联对象', + entityId: '关联对象id', + }, + }, +}; diff --git a/src/store/checker.ts b/src/store/checker.ts index a5277f5..9d9639c 100644 --- a/src/store/checker.ts +++ b/src/store/checker.ts @@ -10,7 +10,7 @@ import { AsyncContext } from "./AsyncRowStore"; import { getFullProjection } from './actionDef'; import { SyncContext } from './SyncRowStore'; import { firstLetterUpperCase } from '../utils/string'; -import { intersection, uniq, difference } from '../utils/lodash'; +import { union, uniq, difference } from '../utils/lodash'; import { judgeRelation } from './relation'; export function translateCheckerInAsyncContext< @@ -518,8 +518,8 @@ export function createRemoveCheckers { const { data } = operation; const { id } = data; + await context.operate('modiEntity', { + id: await generateNewIdAsync(), + action: 'remove', + data: {}, + filter: { + modi: { + entity, + entityId: id, + }, + } + }, { dontCollect: true }); await context.operate('modi', { id: await generateNewIdAsync(), action: 'remove', @@ -168,8 +180,8 @@ export function createModiRelatedTriggers); } diff --git a/src/types/Trigger.ts b/src/types/Trigger.ts index 75e91d8..330b687 100644 --- a/src/types/Trigger.ts +++ b/src/types/Trigger.ts @@ -13,6 +13,7 @@ export const TRIGGER_MIN_PRIORITY = 1; export const TRIGGER_MAX_PRIORITY = 99; export const DATA_CHECKER_DEFAULT_PRIORITY = 60; export const CHECKER_DEFAULT_PRIORITY = 99; +export const REMOVE_CASCADE_PRIORITY = 70; interface TriggerBase { checkerType?: CheckerType;