@flusys/nestjs-entity-builder 9.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +111 -0
- package/config/entity-builder.constants.d.ts +6 -0
- package/config/event-actions.d.ts +8 -0
- package/config/index.d.ts +3 -0
- package/config/message-keys.d.ts +542 -0
- package/controllers/entity-definition.controller.d.ts +40 -0
- package/controllers/field-definition.controller.d.ts +22 -0
- package/controllers/flow-definition.controller.d.ts +51 -0
- package/controllers/flow-execution.controller.d.ts +21 -0
- package/controllers/flow-runtime.controller.d.ts +24 -0
- package/controllers/index.d.ts +5 -0
- package/docs/entity-builder-swagger.config.d.ts +3 -0
- package/docs/index.d.ts +1 -0
- package/dtos/entity-definition.dto.d.ts +58 -0
- package/dtos/field-definition.dto.d.ts +42 -0
- package/dtos/flow.dto.d.ts +76 -0
- package/dtos/index.d.ts +3 -0
- package/dtos/schema-change.dto.d.ts +53 -0
- package/entities/entity-definition.entity.d.ts +15 -0
- package/entities/field-definition.entity.d.ts +23 -0
- package/entities/flow-definition.entity.d.ts +14 -0
- package/entities/flow-execution.entity.d.ts +19 -0
- package/entities/flow-version.entity.d.ts +10 -0
- package/entities/index.d.ts +14 -0
- package/entities/schema-change-log.entity.d.ts +15 -0
- package/enums/ddl-operation.enum.d.ts +13 -0
- package/enums/entity-status.enum.d.ts +5 -0
- package/enums/field-type.enum.d.ts +15 -0
- package/enums/index.d.ts +3 -0
- package/fesm/21.js +576 -0
- package/fesm/362.js +1074 -0
- package/fesm/458.js +649 -0
- package/fesm/582.js +1247 -0
- package/fesm/677.js +7534 -0
- package/fesm/719.js +3597 -0
- package/fesm/794.js +979 -0
- package/fesm/913.js +1620 -0
- package/fesm/config/index.js +126 -0
- package/fesm/controllers/index.js +27 -0
- package/fesm/docs/index.js +82 -0
- package/fesm/dtos/index.js +327 -0
- package/fesm/entities/index.js +18 -0
- package/fesm/enums/index.js +97 -0
- package/fesm/guards/index.js +226 -0
- package/fesm/index.js +548 -0
- package/fesm/interfaces/index.js +80 -0
- package/fesm/modules/index.js +25 -0
- package/fesm/rule-engine/index.js +21 -0
- package/fesm/runtime.js +85 -0
- package/fesm/services/index.js +526 -0
- package/flow-engine/flow-api-key.d.ts +6 -0
- package/flow-engine/flow-code-sandbox.d.ts +5 -0
- package/flow-engine/flow-engine.d.ts +22 -0
- package/flow-engine/flow-graph.validator.d.ts +20 -0
- package/flow-engine/flow-http.client.d.ts +15 -0
- package/flow-engine/flow-input.validator.d.ts +7 -0
- package/flow-engine/flow-node-handlers.d.ts +5 -0
- package/flow-engine/flow-rate-limiter.d.ts +8 -0
- package/flow-engine/flow-reference.d.ts +7 -0
- package/flow-engine/flow-run.types.d.ts +131 -0
- package/flow-engine/flow.errors.d.ts +27 -0
- package/flow-engine/flow.types.d.ts +315 -0
- package/flow-engine/index.d.ts +4 -0
- package/flow-engine/redact.d.ts +3 -0
- package/flow-engine/ssrf-guard.d.ts +6 -0
- package/guards/flow-access.guard.d.ts +11 -0
- package/guards/index.d.ts +1 -0
- package/index.d.ts +11 -0
- package/interfaces/entity-builder-module.interface.d.ts +28 -0
- package/interfaces/field-definition.interface.d.ts +33 -0
- package/interfaces/flow-definition.interface.d.ts +24 -0
- package/interfaces/generic-record.interface.d.ts +15 -0
- package/interfaces/index.d.ts +5 -0
- package/interfaces/reference-provider.interface.d.ts +8 -0
- package/interfaces/schema-dialect-adapter.interface.d.ts +15 -0
- package/modules/entity-builder.module.d.ts +10 -0
- package/modules/index.d.ts +1 -0
- package/package.json +93 -0
- package/rule-engine/index.d.ts +3 -0
- package/rule-engine/rule-engine.service.d.ts +40 -0
- package/rule-engine/rule-evaluation-context.interface.d.ts +28 -0
- package/rule-engine/rule-ip.d.ts +3 -0
- package/rule-engine/rule-permission.d.ts +10 -0
- package/rule-engine/rule-regex.d.ts +4 -0
- package/rule-engine/rule-values.d.ts +5 -0
- package/rule-engine/rule.interface.d.ts +79 -0
- package/services/database-error.mapper.d.ts +2 -0
- package/services/definition-cache.service.d.ts +8 -0
- package/services/entity-builder-config.service.d.ts +12 -0
- package/services/entity-builder-datasource.provider.d.ts +24 -0
- package/services/entity-definition.service.d.ts +17 -0
- package/services/entity-flow-scaffold.d.ts +27 -0
- package/services/entity-permission.service.d.ts +8 -0
- package/services/field-definition.service.d.ts +17 -0
- package/services/field-type-conversion.d.ts +15 -0
- package/services/field-value-validator.d.ts +17 -0
- package/services/flow-definition.service.d.ts +62 -0
- package/services/flow-execution.service.d.ts +38 -0
- package/services/flow-executor.service.d.ts +41 -0
- package/services/flow-reference.provider.d.ts +13 -0
- package/services/flow-runtime.service.d.ts +30 -0
- package/services/generic-entity-service.factory.d.ts +12 -0
- package/services/generic-entity.service.d.ts +67 -0
- package/services/identifier-rules.d.ts +9 -0
- package/services/index.d.ts +26 -0
- package/services/reference-rewrite.d.ts +7 -0
- package/services/reference-scanner.service.d.ts +10 -0
- package/services/schema-change-executor.service.d.ts +39 -0
- package/services/schema-change.types.d.ts +59 -0
- package/services/schema-columns.d.ts +26 -0
- package/services/schema-dialect-adapter.service.d.ts +13 -0
- package/services/schema-evolution.service.d.ts +67 -0
- package/services/schema-registry.service.d.ts +13 -0
- package/services/schema-sync.service.d.ts +28 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type IIdentity } from '@flusys/nestjs-shared/interfaces';
|
|
2
|
+
import { type EntityStatus } from '../enums/entity-status.enum.js';
|
|
3
|
+
import { type FieldType } from '../enums/field-type.enum.js';
|
|
4
|
+
export interface IEntityDefinition extends IIdentity {
|
|
5
|
+
code: string;
|
|
6
|
+
label: string;
|
|
7
|
+
description: string | null;
|
|
8
|
+
tableName: string;
|
|
9
|
+
status: EntityStatus;
|
|
10
|
+
schemaVersion: number;
|
|
11
|
+
isSoftDeleteEnabled: boolean;
|
|
12
|
+
isAuditEnabled: boolean;
|
|
13
|
+
uiConfig: Record<string, unknown> | null;
|
|
14
|
+
}
|
|
15
|
+
export interface IFieldDefinition extends IIdentity {
|
|
16
|
+
entityDefinitionId: string;
|
|
17
|
+
code: string;
|
|
18
|
+
label: string;
|
|
19
|
+
fieldType: FieldType;
|
|
20
|
+
dbType: string;
|
|
21
|
+
nullable: boolean;
|
|
22
|
+
unique: boolean;
|
|
23
|
+
isIndexed: boolean;
|
|
24
|
+
defaultValue: unknown | null;
|
|
25
|
+
validationRules: Record<string, unknown> | null;
|
|
26
|
+
selectOptions: unknown[] | null;
|
|
27
|
+
relationTargetEntityId: string | null;
|
|
28
|
+
order: number;
|
|
29
|
+
uiConfig: Record<string, unknown> | null;
|
|
30
|
+
isSearchable: boolean;
|
|
31
|
+
isSystemField: boolean;
|
|
32
|
+
deprecatedAt: Date | null;
|
|
33
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type IIdentity } from '@flusys/nestjs-shared/interfaces';
|
|
2
|
+
import { type IFlowEdge, type IFlowNode } from '../flow-engine/flow.types.js';
|
|
3
|
+
export interface IFlowDefinition extends IIdentity {
|
|
4
|
+
name: string;
|
|
5
|
+
slug: string;
|
|
6
|
+
description: string | null;
|
|
7
|
+
isActive: boolean;
|
|
8
|
+
retainExecutions: number;
|
|
9
|
+
nodes: IFlowNode[];
|
|
10
|
+
edges: IFlowEdge[];
|
|
11
|
+
version: number;
|
|
12
|
+
draft: IFlowSnapshot | null;
|
|
13
|
+
}
|
|
14
|
+
export declare const FLOW_VERSIONED_FIELDS: readonly ["name", "slug", "description", "isActive", "retainExecutions", "nodes", "edges"];
|
|
15
|
+
export type IFlowSnapshot = Pick<IFlowDefinition, (typeof FLOW_VERSIONED_FIELDS)[number]>;
|
|
16
|
+
export interface IFlowVersion {
|
|
17
|
+
id: string;
|
|
18
|
+
flowId: string;
|
|
19
|
+
version: number;
|
|
20
|
+
note: string | null;
|
|
21
|
+
publishedAt: Date | null;
|
|
22
|
+
publishedById: string | null;
|
|
23
|
+
definition?: IFlowSnapshot;
|
|
24
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type ObjectLiteral } from 'typeorm';
|
|
2
|
+
export interface IGenericRecord extends ObjectLiteral {
|
|
3
|
+
id: string;
|
|
4
|
+
[key: string]: unknown;
|
|
5
|
+
}
|
|
6
|
+
export declare const RECORD_FILTER_OPS: readonly ["eq", "ne", "gt", "gte", "lt", "lte", "in", "is_null", "not_null"];
|
|
7
|
+
export type RecordFilterOp = (typeof RECORD_FILTER_OPS)[number];
|
|
8
|
+
export interface IRecordFilterCondition {
|
|
9
|
+
op: RecordFilterOp;
|
|
10
|
+
value?: unknown;
|
|
11
|
+
}
|
|
12
|
+
export declare const RECORD_FILTER_LIMITS: {
|
|
13
|
+
readonly MAX_IN_VALUES: 100;
|
|
14
|
+
};
|
|
15
|
+
export declare function isRecordFilterCondition(value: unknown): value is IRecordFilterCondition;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type EntityManager } from 'typeorm';
|
|
2
|
+
import { type ISchemaImpact } from '../services/schema-change.types.js';
|
|
3
|
+
export interface IEntityReferenceProvider {
|
|
4
|
+
findEntityReferences(entityCode: string): Promise<ISchemaImpact[]>;
|
|
5
|
+
findFieldReferences(entityCode: string, fieldCode: string): Promise<ISchemaImpact[]>;
|
|
6
|
+
rewriteFieldReferences(entityCode: string, from: string, to: string, manager?: EntityManager): Promise<number>;
|
|
7
|
+
}
|
|
8
|
+
export declare const FLOW_REFERENCE_PROVIDER = "FLOW_REFERENCE_PROVIDER";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type ColumnType, type QueryRunner } from 'typeorm';
|
|
2
|
+
import { type FieldType } from '../enums/field-type.enum.js';
|
|
3
|
+
export type SupportedDbDriver = 'postgres' | 'mysql';
|
|
4
|
+
export interface IColumnSizing {
|
|
5
|
+
length?: string;
|
|
6
|
+
precision?: number;
|
|
7
|
+
scale?: number;
|
|
8
|
+
}
|
|
9
|
+
export interface ISchemaDialectAdapter {
|
|
10
|
+
mapFieldType(fieldType: FieldType, driver: SupportedDbDriver): ColumnType;
|
|
11
|
+
getColumnSizing(fieldType: FieldType, driver?: SupportedDbDriver): IColumnSizing;
|
|
12
|
+
maxIdentifierLength(driver: SupportedDbDriver): number;
|
|
13
|
+
acquireEntityLock(queryRunner: QueryRunner, lockKey: string, driver: SupportedDbDriver): Promise<void>;
|
|
14
|
+
releaseEntityLock(queryRunner: QueryRunner, lockKey: string, driver: SupportedDbDriver): Promise<void>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type DynamicModule } from '@nestjs/common';
|
|
2
|
+
import { type EntityBuilderModuleAsyncOptions, type EntityBuilderModuleOptions } from '../interfaces/entity-builder-module.interface.js';
|
|
3
|
+
export declare class EntityBuilderModule {
|
|
4
|
+
private static readonly CONTROLLERS;
|
|
5
|
+
private static readonly EXPORTS;
|
|
6
|
+
static forRoot(options: EntityBuilderModuleOptions): DynamicModule;
|
|
7
|
+
static forRootAsync(options: EntityBuilderModuleAsyncOptions): DynamicModule;
|
|
8
|
+
private static buildProviders;
|
|
9
|
+
private static buildAsyncProviders;
|
|
10
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './entity-builder.module.js';
|
package/package.json
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@flusys/nestjs-entity-builder",
|
|
3
|
+
"version": "9.0.0",
|
|
4
|
+
"description": "Dynamic entity builder module - runtime entity/field metadata, driven DDL, and generic CRUD",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./fesm/index.js",
|
|
7
|
+
"module": "./fesm/index.js",
|
|
8
|
+
"types": "./index.d.ts",
|
|
9
|
+
"sideEffects": false,
|
|
10
|
+
"keywords": [
|
|
11
|
+
"nestjs",
|
|
12
|
+
"@flusys",
|
|
13
|
+
"entity-builder",
|
|
14
|
+
"dynamic-entities",
|
|
15
|
+
"ddl",
|
|
16
|
+
"schema",
|
|
17
|
+
"backendless"
|
|
18
|
+
],
|
|
19
|
+
"license": "UNLICENSED",
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"types": "./index.d.ts",
|
|
23
|
+
"import": "./fesm/index.js"
|
|
24
|
+
},
|
|
25
|
+
"./config": {
|
|
26
|
+
"types": "./config/index.d.ts",
|
|
27
|
+
"import": "./fesm/config/index.js"
|
|
28
|
+
},
|
|
29
|
+
"./controllers": {
|
|
30
|
+
"types": "./controllers/index.d.ts",
|
|
31
|
+
"import": "./fesm/controllers/index.js"
|
|
32
|
+
},
|
|
33
|
+
"./docs": {
|
|
34
|
+
"types": "./docs/index.d.ts",
|
|
35
|
+
"import": "./fesm/docs/index.js"
|
|
36
|
+
},
|
|
37
|
+
"./dtos": {
|
|
38
|
+
"types": "./dtos/index.d.ts",
|
|
39
|
+
"import": "./fesm/dtos/index.js"
|
|
40
|
+
},
|
|
41
|
+
"./entities": {
|
|
42
|
+
"types": "./entities/index.d.ts",
|
|
43
|
+
"import": "./fesm/entities/index.js"
|
|
44
|
+
},
|
|
45
|
+
"./enums": {
|
|
46
|
+
"types": "./enums/index.d.ts",
|
|
47
|
+
"import": "./fesm/enums/index.js"
|
|
48
|
+
},
|
|
49
|
+
"./guards": {
|
|
50
|
+
"types": "./guards/index.d.ts",
|
|
51
|
+
"import": "./fesm/guards/index.js"
|
|
52
|
+
},
|
|
53
|
+
"./interfaces": {
|
|
54
|
+
"types": "./interfaces/index.d.ts",
|
|
55
|
+
"import": "./fesm/interfaces/index.js"
|
|
56
|
+
},
|
|
57
|
+
"./modules": {
|
|
58
|
+
"types": "./modules/index.d.ts",
|
|
59
|
+
"import": "./fesm/modules/index.js"
|
|
60
|
+
},
|
|
61
|
+
"./rule-engine": {
|
|
62
|
+
"types": "./rule-engine/index.d.ts",
|
|
63
|
+
"import": "./fesm/rule-engine/index.js"
|
|
64
|
+
},
|
|
65
|
+
"./services": {
|
|
66
|
+
"types": "./services/index.d.ts",
|
|
67
|
+
"import": "./fesm/services/index.js"
|
|
68
|
+
},
|
|
69
|
+
"./*": {
|
|
70
|
+
"types": "./*.d.ts",
|
|
71
|
+
"import": "./fesm/*.js"
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
"peerDependencies": {
|
|
75
|
+
"@nestjs/common": "^12.0.0",
|
|
76
|
+
"@nestjs/config": "^12.0.0",
|
|
77
|
+
"@nestjs/core": "^12.0.0",
|
|
78
|
+
"@nestjs/platform-express": "^12.0.0",
|
|
79
|
+
"@nestjs/swagger": "^12.0.0",
|
|
80
|
+
"@nestjs/typeorm": "^12.0.0",
|
|
81
|
+
"class-transformer": "^0.5.1",
|
|
82
|
+
"class-validator": "^0.15.0",
|
|
83
|
+
"typeorm": "^0.3.0",
|
|
84
|
+
"express": "^5.0.0",
|
|
85
|
+
"rxjs": "^7.8.0"
|
|
86
|
+
},
|
|
87
|
+
"dependencies": {
|
|
88
|
+
"@flusys/nestjs-core": "9.0.0",
|
|
89
|
+
"@flusys/nestjs-shared": "9.0.0",
|
|
90
|
+
"re2js": "^2.8.6",
|
|
91
|
+
"quickjs-emscripten": "^0.32.0"
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { type IPermissionResolver } from '@flusys/nestjs-shared/interfaces';
|
|
2
|
+
import { SharedPermissionCacheService } from '@flusys/nestjs-shared/modules';
|
|
3
|
+
import { type IRulePermissionResolver, type RuleEvaluationContext } from './rule-evaluation-context.interface.js';
|
|
4
|
+
import { type RuleCondition, type RuleExpression, type RuleGroup } from './rule.interface.js';
|
|
5
|
+
interface IEvaluationBudget {
|
|
6
|
+
lookups?: number;
|
|
7
|
+
permissions?: IRulePermissionResolver;
|
|
8
|
+
}
|
|
9
|
+
export declare class RuleEngineService {
|
|
10
|
+
private readonly permissionResolver?;
|
|
11
|
+
private readonly permissionCache?;
|
|
12
|
+
constructor(permissionResolver?: IPermissionResolver | undefined, permissionCache?: SharedPermissionCacheService | undefined);
|
|
13
|
+
createPermissionResolver(user: RuleEvaluationContext['user']): IRulePermissionResolver;
|
|
14
|
+
evaluateGroup(group: RuleGroup, ctx: RuleEvaluationContext, depth?: number, budget?: IEvaluationBudget): Promise<boolean>;
|
|
15
|
+
private every;
|
|
16
|
+
evaluateCondition(condition: RuleCondition, ctx: RuleEvaluationContext, budget?: IEvaluationBudget): Promise<boolean>;
|
|
17
|
+
private resolveConditionLeft;
|
|
18
|
+
private resolveConditionValue;
|
|
19
|
+
resolveExpression(expression: RuleExpression, ctx: RuleEvaluationContext, budget?: IEvaluationBudget): Promise<unknown>;
|
|
20
|
+
resolveHtml(expression: RuleExpression, ctx: RuleEvaluationContext): Promise<unknown>;
|
|
21
|
+
private resolveLookup;
|
|
22
|
+
private resolveTemplate;
|
|
23
|
+
private resolveFieldReference;
|
|
24
|
+
private getPath;
|
|
25
|
+
private resolveFunction;
|
|
26
|
+
private hasPermissions;
|
|
27
|
+
private toText;
|
|
28
|
+
private toTime;
|
|
29
|
+
private toDurationUnit;
|
|
30
|
+
private toUtcOffset;
|
|
31
|
+
private ordered;
|
|
32
|
+
private toContainerCheck;
|
|
33
|
+
private isEmptyValue;
|
|
34
|
+
private hasIntersection;
|
|
35
|
+
private toNumber;
|
|
36
|
+
private tryToNumber;
|
|
37
|
+
private applyArithmetic;
|
|
38
|
+
private assertWithinLimits;
|
|
39
|
+
}
|
|
40
|
+
export {};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type ILoggedUserInfo } from '@flusys/nestjs-shared/interfaces';
|
|
2
|
+
export interface IRuleLookupQuery {
|
|
3
|
+
filter: Record<string, unknown>;
|
|
4
|
+
sort?: Record<string, 'ASC' | 'DESC'>;
|
|
5
|
+
limit: number;
|
|
6
|
+
}
|
|
7
|
+
export interface IRuleLookupResolver {
|
|
8
|
+
find(entityCode: string, query: IRuleLookupQuery): Promise<{
|
|
9
|
+
rows: Record<string, unknown>[];
|
|
10
|
+
total: number;
|
|
11
|
+
}>;
|
|
12
|
+
}
|
|
13
|
+
export interface IRulePermissionResolver {
|
|
14
|
+
granted(branchId: string | null | undefined): Promise<string[]>;
|
|
15
|
+
}
|
|
16
|
+
export interface RuleEvaluationContext {
|
|
17
|
+
input?: Record<string, unknown> | unknown[];
|
|
18
|
+
context?: Record<string, Record<string, unknown>>;
|
|
19
|
+
vars?: Record<string, unknown>;
|
|
20
|
+
loop?: {
|
|
21
|
+
item: unknown;
|
|
22
|
+
index: number;
|
|
23
|
+
};
|
|
24
|
+
request?: Record<string, unknown>;
|
|
25
|
+
user: ILoggedUserInfo | null;
|
|
26
|
+
lookupResolver?: IRuleLookupResolver;
|
|
27
|
+
permissions?: IRulePermissionResolver;
|
|
28
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type ILoggedUserInfo, type IPermissionResolver } from '@flusys/nestjs-shared/interfaces';
|
|
2
|
+
import { type SharedPermissionCacheService } from '@flusys/nestjs-shared/modules';
|
|
3
|
+
import { type IRulePermissionResolver } from './rule-evaluation-context.interface.js';
|
|
4
|
+
export interface IRulePermissionSources {
|
|
5
|
+
resolver?: IPermissionResolver;
|
|
6
|
+
cache?: SharedPermissionCacheService;
|
|
7
|
+
}
|
|
8
|
+
export declare function createRulePermissionResolver(user: ILoggedUserInfo | null, sources: IRulePermissionSources): IRulePermissionResolver;
|
|
9
|
+
export declare function parsePermissionCodes(value: unknown): string[];
|
|
10
|
+
export declare function toBranchArgument(args: unknown[], index: number): string | null | undefined;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export type RulePatternProblem = 'too_long' | 'invalid' | 'too_complex';
|
|
2
|
+
export declare function rulePatternProblem(pattern: string): RulePatternProblem | null;
|
|
3
|
+
export declare function matchesPattern(input: unknown, pattern: unknown): boolean;
|
|
4
|
+
export declare function extractPattern(input: unknown, pattern: unknown, group?: unknown): string | null;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const ISO_DATE_PREFIX: RegExp;
|
|
2
|
+
export declare function parseDateText(text: string): number;
|
|
3
|
+
export declare function valuesEqual(a: unknown, b: unknown): boolean;
|
|
4
|
+
export declare const includesValue: (list: readonly unknown[], value: unknown) => boolean;
|
|
5
|
+
export declare const equalsOperand: (value: unknown) => unknown;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { type RecordFilterOp } from '../interfaces/generic-record.interface.js';
|
|
2
|
+
export type RuleLogicOperator = 'AND' | 'OR' | 'NOT';
|
|
3
|
+
export declare const RULE_COMPARISON_OPERATORS: readonly ["equals", "not_equals", "greater_than", "less_than", "greater_or_equal", "less_or_equal", "contains", "not_contains", "starts_with", "ends_with", "is_empty", "is_not_empty", "in", "not_in", "is_any_of", "is_none_of", "is_true", "is_false", "matches", "not_matches"];
|
|
4
|
+
export type RuleComparisonOperator = (typeof RULE_COMPARISON_OPERATORS)[number];
|
|
5
|
+
export interface RuleCondition {
|
|
6
|
+
field?: string;
|
|
7
|
+
left?: RuleExpression;
|
|
8
|
+
comparison: RuleComparisonOperator;
|
|
9
|
+
value?: unknown | {
|
|
10
|
+
$field: string;
|
|
11
|
+
} | {
|
|
12
|
+
$expr: RuleExpression;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export interface RuleGroup {
|
|
16
|
+
operator: RuleLogicOperator;
|
|
17
|
+
conditions: Array<RuleCondition | RuleGroup>;
|
|
18
|
+
}
|
|
19
|
+
export declare function isRuleGroup(node: RuleCondition | RuleGroup): node is RuleGroup;
|
|
20
|
+
export type RuleArithmeticOp = 'sum' | 'subtract' | 'multiply' | 'divide' | 'min' | 'max';
|
|
21
|
+
export declare const RULE_PERMISSION_FUNCTIONS: readonly ["HAS_PERMISSION", "HAS_ANY_PERMISSION", "HAS_ALL_PERMISSIONS"];
|
|
22
|
+
export type RulePermissionFunctionName = (typeof RULE_PERMISSION_FUNCTIONS)[number];
|
|
23
|
+
export declare const RULE_REQUEST_FUNCTIONS: readonly ["HEADER", "QUERY_PARAM", "IP_IN_RANGE"];
|
|
24
|
+
export type RuleRequestFunctionName = (typeof RULE_REQUEST_FUNCTIONS)[number];
|
|
25
|
+
export type RuleTextFunctionName = 'LOWER' | 'UPPER' | 'TRIM' | 'LENGTH' | 'SPLIT_PART' | 'REGEX_EXTRACT' | 'REPLACE' | 'TO_NUMBER';
|
|
26
|
+
export type RuleFunctionName = 'NOW' | 'UUID' | 'CURRENT_USER_ID' | 'COALESCE' | 'ROUND' | 'DATE_DIFF' | 'START_OF_DAY' | 'END_OF_DAY' | 'ADD_DURATION' | RulePermissionFunctionName | RuleRequestFunctionName | RuleTextFunctionName;
|
|
27
|
+
export declare function isPermissionFunction(name: unknown): name is RulePermissionFunctionName;
|
|
28
|
+
export declare const RULE_DURATION_UNITS: readonly ["second", "minute", "hour", "day"];
|
|
29
|
+
export type RuleDurationUnit = (typeof RULE_DURATION_UNITS)[number];
|
|
30
|
+
export type RuleLookupMode = 'exists' | 'count' | 'first';
|
|
31
|
+
export interface RuleLookupFilterCondition {
|
|
32
|
+
op: RecordFilterOp;
|
|
33
|
+
value?: RuleExpression;
|
|
34
|
+
}
|
|
35
|
+
export interface RuleLookupExpression {
|
|
36
|
+
type: 'lookup';
|
|
37
|
+
entity: string;
|
|
38
|
+
filter: Record<string, RuleExpression | RuleLookupFilterCondition>;
|
|
39
|
+
mode: RuleLookupMode;
|
|
40
|
+
field?: string;
|
|
41
|
+
sort?: {
|
|
42
|
+
field: string;
|
|
43
|
+
direction: 'ASC' | 'DESC';
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
export type RuleExpression = {
|
|
47
|
+
type: 'literal';
|
|
48
|
+
value: string | number | boolean | null;
|
|
49
|
+
} | {
|
|
50
|
+
type: 'field_ref';
|
|
51
|
+
ref: string;
|
|
52
|
+
} | {
|
|
53
|
+
type: 'arithmetic';
|
|
54
|
+
op: RuleArithmeticOp;
|
|
55
|
+
operands: RuleExpression[];
|
|
56
|
+
} | {
|
|
57
|
+
type: 'concat';
|
|
58
|
+
parts: RuleExpression[];
|
|
59
|
+
} | {
|
|
60
|
+
type: 'function';
|
|
61
|
+
name: RuleFunctionName;
|
|
62
|
+
args: RuleExpression[];
|
|
63
|
+
} | {
|
|
64
|
+
type: 'template';
|
|
65
|
+
template: string;
|
|
66
|
+
} | RuleLookupExpression;
|
|
67
|
+
export declare const RULE_TEMPLATE_MAX_LENGTH = 4000;
|
|
68
|
+
export declare const RULE_ENGINE_LIMITS: {
|
|
69
|
+
readonly MAX_GROUP_DEPTH: 8;
|
|
70
|
+
readonly MAX_CONDITIONS_PER_GROUP: 100;
|
|
71
|
+
readonly MAX_LOOKUPS: 10;
|
|
72
|
+
readonly MAX_REGEX_PATTERN_LENGTH: 500;
|
|
73
|
+
readonly MAX_REGEX_INPUT_LENGTH: 10000;
|
|
74
|
+
readonly MAX_REGEX_REPEAT: 100;
|
|
75
|
+
readonly MAX_REGEX_REPEAT_EXPANSION: 300;
|
|
76
|
+
readonly MAX_UTC_OFFSET_MINUTES: 840;
|
|
77
|
+
readonly MAX_PERMISSION_CODES: 50;
|
|
78
|
+
readonly MAX_IP_RANGES: 100;
|
|
79
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { HybridCache } from '@flusys/nestjs-shared/classes';
|
|
2
|
+
import { UtilsService } from '@flusys/nestjs-shared/modules';
|
|
3
|
+
export declare class DefinitionCacheService {
|
|
4
|
+
private readonly cacheManager;
|
|
5
|
+
private readonly utilsService;
|
|
6
|
+
constructor(cacheManager: HybridCache, utilsService: UtilsService);
|
|
7
|
+
clearAll(tenantId?: string): Promise<void>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type DatabaseMode, type ITenantDatabaseConfig } from '@flusys/nestjs-core';
|
|
2
|
+
import { type IModuleConfigService } from '@flusys/nestjs-shared/interfaces';
|
|
3
|
+
import { type EntityBuilderModuleOptions } from '../interfaces/entity-builder-module.interface.js';
|
|
4
|
+
export declare class EntityBuilderConfigService implements IModuleConfigService {
|
|
5
|
+
private readonly options;
|
|
6
|
+
constructor(options: EntityBuilderModuleOptions);
|
|
7
|
+
isCompanyFeatureEnabled(tenant?: ITenantDatabaseConfig): boolean;
|
|
8
|
+
getDatabaseMode(): DatabaseMode;
|
|
9
|
+
isMultiTenant(): boolean;
|
|
10
|
+
getOptions(): EntityBuilderModuleOptions;
|
|
11
|
+
getConfig(): import("../index.js").IEntityBuilderConfig | undefined;
|
|
12
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { MultiTenantDataSourceService } from '@flusys/nestjs-shared/modules';
|
|
2
|
+
import { type IDatabaseConfig, type ITenantDatabaseConfig } from '@flusys/nestjs-core';
|
|
3
|
+
import { type Request } from 'express';
|
|
4
|
+
import { DataSource, type EntitySchema, type ObjectLiteral, type QueryRunner, type Repository } from 'typeorm';
|
|
5
|
+
import { type SupportedDbDriver } from '../interfaces/schema-dialect-adapter.interface.js';
|
|
6
|
+
import { EntityBuilderConfigService } from './entity-builder-config.service.js';
|
|
7
|
+
export declare class EntityBuilderDataSourceProvider extends MultiTenantDataSourceService {
|
|
8
|
+
protected static readonly tenantConnections: Map<string, DataSource>;
|
|
9
|
+
protected static singleDataSource: DataSource | null;
|
|
10
|
+
protected static readonly tenantsRegistry: Map<string, ITenantDatabaseConfig>;
|
|
11
|
+
protected static initialized: boolean;
|
|
12
|
+
protected static readonly connectionLocks: Map<string, Promise<DataSource>>;
|
|
13
|
+
protected static singleConnectionLock: Promise<DataSource> | null;
|
|
14
|
+
private static readonly registeredSchemas;
|
|
15
|
+
private static readonly rebuildLocks;
|
|
16
|
+
constructor(configService: EntityBuilderConfigService, request?: Request);
|
|
17
|
+
private static buildParentOptions;
|
|
18
|
+
private get statics();
|
|
19
|
+
protected createDataSourceFromConfig(config: IDatabaseConfig): Promise<DataSource>;
|
|
20
|
+
getDriver(): Promise<SupportedDbDriver>;
|
|
21
|
+
registerDynamicSchema(schema: EntitySchema): Promise<void>;
|
|
22
|
+
getDynamicRepository<T extends ObjectLiteral>(schema: EntitySchema<T>): Promise<Repository<T>>;
|
|
23
|
+
getQueryRunner(): Promise<QueryRunner>;
|
|
24
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ApiService, HybridCache } from '@flusys/nestjs-shared/classes';
|
|
2
|
+
import { UtilsService } from '@flusys/nestjs-shared/modules';
|
|
3
|
+
import { type ILoggedUserInfo } from '@flusys/nestjs-shared/interfaces';
|
|
4
|
+
import { type SelectQueryBuilder } from 'typeorm';
|
|
5
|
+
import { type UpdateEntityDefinitionDto, type CreateEntityDefinitionDto } from '../dtos/entity-definition.dto.js';
|
|
6
|
+
import { EntityDefinition } from '../entities/entity-definition.entity.js';
|
|
7
|
+
import { type IEntityDefinition } from '../interfaces/field-definition.interface.js';
|
|
8
|
+
import { EntityBuilderDataSourceProvider } from './entity-builder-datasource.provider.js';
|
|
9
|
+
export declare class EntityDefinitionService extends ApiService<CreateEntityDefinitionDto, UpdateEntityDefinitionDto, IEntityDefinition, EntityDefinition> {
|
|
10
|
+
protected cacheManager: HybridCache;
|
|
11
|
+
protected utilsService: UtilsService;
|
|
12
|
+
constructor(cacheManager: HybridCache, utilsService: UtilsService, dataSourceProvider: EntityBuilderDataSourceProvider);
|
|
13
|
+
protected getSelectQuery(query: SelectQueryBuilder<EntityDefinition>, user: ILoggedUserInfo | null, select?: string[]): Promise<{
|
|
14
|
+
query: SelectQueryBuilder<EntityDefinition>;
|
|
15
|
+
isRaw: boolean;
|
|
16
|
+
}>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type EntityFlowEndpoint } from '../config/entity-builder.constants.js';
|
|
2
|
+
import { FieldType } from '../enums/field-type.enum.js';
|
|
3
|
+
import { type CreateFlowDefinitionDto } from '../dtos/flow.dto.js';
|
|
4
|
+
export interface IEntityFlowField {
|
|
5
|
+
code: string;
|
|
6
|
+
label?: string;
|
|
7
|
+
fieldType: FieldType;
|
|
8
|
+
nullable?: boolean;
|
|
9
|
+
defaultValue?: unknown;
|
|
10
|
+
selectOptions?: unknown[] | null;
|
|
11
|
+
validationRules?: Record<string, unknown> | null;
|
|
12
|
+
}
|
|
13
|
+
export interface IEntityFlowSource {
|
|
14
|
+
code: string;
|
|
15
|
+
label: string;
|
|
16
|
+
fields: IEntityFlowField[];
|
|
17
|
+
}
|
|
18
|
+
type FlowInputLabel = 'id' | 'ids' | 'search';
|
|
19
|
+
export interface IEntityFlowTexts {
|
|
20
|
+
names?: Partial<Record<EntityFlowEndpoint, string>>;
|
|
21
|
+
inputLabels?: Partial<Record<FlowInputLabel, string>>;
|
|
22
|
+
noMatchMessage?: string;
|
|
23
|
+
}
|
|
24
|
+
export declare const ENTITY_FLOW_PATHS: Record<EntityFlowEndpoint, string>;
|
|
25
|
+
export declare const entityFlowSlug: (entityCode: string) => string;
|
|
26
|
+
export declare function buildEntityFlow(entity: IEntityFlowSource, endpoints: readonly EntityFlowEndpoint[], texts?: IEntityFlowTexts): CreateFlowDefinitionDto;
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type IPermissionActionRegistry } from '@flusys/nestjs-shared';
|
|
2
|
+
import { EntityDefinition } from '../entities/entity-definition.entity.js';
|
|
3
|
+
export declare class EntityPermissionService {
|
|
4
|
+
private readonly actionRegistry?;
|
|
5
|
+
constructor(actionRegistry?: IPermissionActionRegistry | undefined);
|
|
6
|
+
provisionForEntity(definition: EntityDefinition): Promise<void>;
|
|
7
|
+
deprovisionForEntity(definition: Pick<EntityDefinition, 'code'>): Promise<void>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ApiService, HybridCache } from '@flusys/nestjs-shared/classes';
|
|
2
|
+
import { UtilsService } from '@flusys/nestjs-shared/modules';
|
|
3
|
+
import { type ILoggedUserInfo } from '@flusys/nestjs-shared/interfaces';
|
|
4
|
+
import { type SelectQueryBuilder } from 'typeorm';
|
|
5
|
+
import { type UpdateFieldDefinitionDto, type CreateFieldDefinitionDto } from '../dtos/field-definition.dto.js';
|
|
6
|
+
import { FieldDefinition } from '../entities/field-definition.entity.js';
|
|
7
|
+
import { type IFieldDefinition } from '../interfaces/field-definition.interface.js';
|
|
8
|
+
import { EntityBuilderDataSourceProvider } from './entity-builder-datasource.provider.js';
|
|
9
|
+
export declare class FieldDefinitionService extends ApiService<CreateFieldDefinitionDto, UpdateFieldDefinitionDto, IFieldDefinition, FieldDefinition> {
|
|
10
|
+
protected cacheManager: HybridCache;
|
|
11
|
+
protected utilsService: UtilsService;
|
|
12
|
+
constructor(cacheManager: HybridCache, utilsService: UtilsService, dataSourceProvider: EntityBuilderDataSourceProvider);
|
|
13
|
+
protected getSelectQuery(query: SelectQueryBuilder<FieldDefinition>, user: ILoggedUserInfo | null, select?: string[]): Promise<{
|
|
14
|
+
query: SelectQueryBuilder<FieldDefinition>;
|
|
15
|
+
isRaw: boolean;
|
|
16
|
+
}>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type IMessageRef } from '@flusys/nestjs-shared/interfaces';
|
|
2
|
+
import { FieldType } from '../enums/field-type.enum.js';
|
|
3
|
+
import { type SupportedDbDriver } from '../interfaces/schema-dialect-adapter.interface.js';
|
|
4
|
+
export interface ITypeConversion {
|
|
5
|
+
supported: boolean;
|
|
6
|
+
reason?: IMessageRef;
|
|
7
|
+
noDbChange?: boolean;
|
|
8
|
+
using?: (column: string) => string;
|
|
9
|
+
prechecks: Array<{
|
|
10
|
+
description: IMessageRef;
|
|
11
|
+
badRowsWhere: (column: string, driver: SupportedDbDriver) => string;
|
|
12
|
+
}>;
|
|
13
|
+
lossy?: IMessageRef;
|
|
14
|
+
}
|
|
15
|
+
export declare function planTypeConversion(from: FieldType, to: FieldType, driver: SupportedDbDriver): ITypeConversion;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type IValidationError } from '@flusys/nestjs-shared/exceptions';
|
|
2
|
+
import { type IMessageRef } from '@flusys/nestjs-shared/interfaces';
|
|
3
|
+
import { FieldType } from '../enums/field-type.enum.js';
|
|
4
|
+
export type IFieldError = IValidationError & IMessageRef;
|
|
5
|
+
export interface IValidatableField {
|
|
6
|
+
code: string;
|
|
7
|
+
label: string;
|
|
8
|
+
fieldType: FieldType;
|
|
9
|
+
nullable: boolean;
|
|
10
|
+
defaultValue: unknown;
|
|
11
|
+
selectOptions: unknown[] | null;
|
|
12
|
+
validationRules: Record<string, unknown> | null;
|
|
13
|
+
}
|
|
14
|
+
export declare function validateRecord(fields: IValidatableField[], values: Record<string, unknown>, mode: 'insert' | 'update'): {
|
|
15
|
+
values: Record<string, unknown>;
|
|
16
|
+
errors: IFieldError[];
|
|
17
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { type IPermissionActionRegistry } from '@flusys/nestjs-shared';
|
|
2
|
+
import { ApiService, HybridCache } from '@flusys/nestjs-shared/classes';
|
|
3
|
+
import { type DeleteDto } from '@flusys/nestjs-shared/dtos';
|
|
4
|
+
import { type ICompanyAccessResolver, type IEmailAdapter, type ILoggedUserInfo, type INotificationAdapter } from '@flusys/nestjs-shared/interfaces';
|
|
5
|
+
import { SharedPermissionCacheService, UtilsService } from '@flusys/nestjs-shared/modules';
|
|
6
|
+
import { NotFoundException } from '@nestjs/common';
|
|
7
|
+
import { type QueryRunner } from 'typeorm';
|
|
8
|
+
import { type CreateFlowDefinitionDto, type UpdateFlowDefinitionDto } from '../dtos/flow.dto.js';
|
|
9
|
+
import { FlowDefinition } from '../entities/flow-definition.entity.js';
|
|
10
|
+
import { type IFlowValidationResult } from '../flow-engine/flow-graph.validator.js';
|
|
11
|
+
import { type IFlowEndpoint, type IFlowSettings } from '../flow-engine/flow.types.js';
|
|
12
|
+
import { type IFlowDefinition, type IFlowSnapshot, type IFlowVersion } from '../interfaces/flow-definition.interface.js';
|
|
13
|
+
import { EntityBuilderDataSourceProvider } from './entity-builder-datasource.provider.js';
|
|
14
|
+
export declare const defaultFlowPermissionCode: (slug: string) => string;
|
|
15
|
+
export declare const flowNotFound: () => NotFoundException;
|
|
16
|
+
export declare const isPublished: (flow: Pick<FlowDefinition, "version">) => boolean;
|
|
17
|
+
export declare function snapshotOf(source: Partial<IFlowSnapshot>): IFlowSnapshot;
|
|
18
|
+
export declare const workingCopy: (flow: FlowDefinition) => IFlowSnapshot;
|
|
19
|
+
type FlowSettingsSource = Pick<Partial<CreateFlowDefinitionDto>, 'nodes' | 'edges'> & {
|
|
20
|
+
slug: string;
|
|
21
|
+
};
|
|
22
|
+
export declare function toFlowSettings(dto: FlowSettingsSource): IFlowSettings;
|
|
23
|
+
export declare class FlowDefinitionService extends ApiService<CreateFlowDefinitionDto, UpdateFlowDefinitionDto, IFlowDefinition, FlowDefinition> {
|
|
24
|
+
protected cacheManager: HybridCache;
|
|
25
|
+
protected utilsService: UtilsService;
|
|
26
|
+
private readonly provider;
|
|
27
|
+
private readonly permissionCache;
|
|
28
|
+
private readonly actionRegistry?;
|
|
29
|
+
private readonly notifications?;
|
|
30
|
+
private readonly email?;
|
|
31
|
+
private readonly companyAccess?;
|
|
32
|
+
constructor(cacheManager: HybridCache, utilsService: UtilsService, provider: EntityBuilderDataSourceProvider, permissionCache: SharedPermissionCacheService, actionRegistry?: IPermissionActionRegistry | undefined, notifications?: INotificationAdapter | undefined, email?: IEmailAdapter | undefined, companyAccess?: ICompanyAccessResolver | undefined);
|
|
33
|
+
findOrFail(id: string): Promise<FlowDefinition>;
|
|
34
|
+
validate(settings: IFlowSettings): Promise<IFlowValidationResult>;
|
|
35
|
+
private callersOf;
|
|
36
|
+
private assertNotCalled;
|
|
37
|
+
private assertCallersKept;
|
|
38
|
+
private assertCallsStillValid;
|
|
39
|
+
private assertEndpointsNotCalled;
|
|
40
|
+
private assertSaveable;
|
|
41
|
+
assertMayAuthor(settings: IFlowSettings, user: ILoggedUserInfo | null): Promise<void>;
|
|
42
|
+
assertMayCreate(user: ILoggedUserInfo | null): Promise<void>;
|
|
43
|
+
assertMayTest(settings: IFlowSettings, endpoint: IFlowEndpoint | undefined, user: ILoggedUserInfo | null, run: {
|
|
44
|
+
mode: 'dry_run' | 'live';
|
|
45
|
+
draft: boolean;
|
|
46
|
+
saved: boolean;
|
|
47
|
+
}): Promise<void>;
|
|
48
|
+
private assertHasPermission;
|
|
49
|
+
protected beforeInsertOperation(dto: CreateFlowDefinitionDto | CreateFlowDefinitionDto[], user: ILoggedUserInfo | null, _qr: QueryRunner): Promise<void>;
|
|
50
|
+
protected beforeUpdateOperation(dto: UpdateFlowDefinitionDto | UpdateFlowDefinitionDto[], user: ILoggedUserInfo | null, _qr: QueryRunner): Promise<void>;
|
|
51
|
+
protected convertSingleDtoToEntity(dto: CreateFlowDefinitionDto | UpdateFlowDefinitionDto, user: ILoggedUserInfo | null): Promise<FlowDefinition>;
|
|
52
|
+
publish(id: string, note: string | undefined, user: ILoggedUserInfo | null): Promise<FlowDefinition>;
|
|
53
|
+
listVersions(flowId: string): Promise<IFlowVersion[]>;
|
|
54
|
+
getVersion(flowId: string, version: number): Promise<IFlowVersion>;
|
|
55
|
+
restoreVersion(flowId: string, version: number, user: ILoggedUserInfo | null): Promise<FlowDefinition>;
|
|
56
|
+
discardDraft(flowId: string, user: ILoggedUserInfo | null): Promise<FlowDefinition>;
|
|
57
|
+
private saveDraft;
|
|
58
|
+
private clearCaches;
|
|
59
|
+
protected beforeDeleteOperation(dto: DeleteDto, user: ILoggedUserInfo | null, _qr: QueryRunner): Promise<void>;
|
|
60
|
+
private provisionPermissions;
|
|
61
|
+
}
|
|
62
|
+
export {};
|