@flusys/nestjs-entity-builder 9.2.0 → 9.2.1

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.
Files changed (52) hide show
  1. package/README.md +40 -22
  2. package/config/entity-builder.constants.d.ts +1 -0
  3. package/config/message-keys.d.ts +11 -2
  4. package/controllers/definition-bundle.controller.d.ts +2 -2
  5. package/controllers/entity-definition.controller.d.ts +0 -1
  6. package/controllers/field-definition.controller.d.ts +0 -1
  7. package/controllers/flow-definition.controller.d.ts +2 -1
  8. package/controllers/flow-runtime.controller.d.ts +4 -3
  9. package/fesm/21.js +13 -5
  10. package/fesm/{458.js → 28.js} +104 -62
  11. package/fesm/677.js +1234 -469
  12. package/fesm/794.js +1 -1
  13. package/fesm/857.js +1 -2
  14. package/fesm/870.js +415 -332
  15. package/fesm/897.js +23 -29
  16. package/fesm/946.js +67 -42
  17. package/fesm/config/index.js +10 -14
  18. package/fesm/docs/index.js +1 -1
  19. package/fesm/guards/index.js +15 -9
  20. package/fesm/index.js +25 -25
  21. package/fesm/modules/index.js +4 -3
  22. package/fesm/services/index.js +29 -58
  23. package/flow-engine/flow-code-runner.d.ts +16 -0
  24. package/flow-engine/flow-graph.validator.d.ts +1 -0
  25. package/flow-engine/flow-input.validator.d.ts +14 -0
  26. package/flow-engine/flow-run.types.d.ts +15 -0
  27. package/flow-engine/flow.types.d.ts +1 -1
  28. package/guards/designer-writable.interceptor.d.ts +1 -0
  29. package/interfaces/definition-bundle.interface.d.ts +2 -0
  30. package/interfaces/entity-builder-module.interface.d.ts +9 -0
  31. package/modules/entity-builder.module.d.ts +1 -0
  32. package/modules/index.d.ts +1 -0
  33. package/modules/tenant-context-id.strategy.d.ts +16 -0
  34. package/package.json +3 -4
  35. package/services/definition-bundle.diff.d.ts +0 -2
  36. package/services/definition-bundle.file.d.ts +2 -1
  37. package/services/definition-bundle.service.d.ts +0 -1
  38. package/services/entity-builder-config.service.d.ts +3 -0
  39. package/services/entity-builder-datasource.provider.d.ts +1 -0
  40. package/services/field-value-validator.d.ts +7 -0
  41. package/services/flow-definition.service.d.ts +10 -2
  42. package/services/flow-executor.service.d.ts +3 -0
  43. package/services/flow-runtime.service.d.ts +6 -1
  44. package/services/generic-entity-service.factory.d.ts +5 -1
  45. package/services/generic-entity.service.d.ts +24 -2
  46. package/services/identifier-rules.d.ts +0 -1
  47. package/services/save-loaded.d.ts +2 -0
  48. package/services/schema-columns.d.ts +7 -2
  49. package/services/schema-evolution.service.d.ts +8 -2
  50. package/services/schema-registry.service.d.ts +12 -0
  51. package/services/schema-sync.service.d.ts +3 -1
  52. package/flow-engine/flow-code-sandbox.d.ts +0 -5
@@ -60,6 +60,9 @@ export interface IFlowRunState {
60
60
  savedUpTo?: IFlowSavePoint;
61
61
  callStack: string[];
62
62
  pendingEvents: IPendingEvent[];
63
+ publisher?: {
64
+ chain: Promise<void>;
65
+ };
63
66
  trace: IFlowTraceEntry[];
64
67
  response?: {
65
68
  status: number;
@@ -79,6 +82,7 @@ export interface IFlowEnv {
79
82
  companyMembers?(companyId: string, branchIds?: string[]): Promise<string[]>;
80
83
  assertPermissions(logic: ILogicNode, user: ILoggedUserInfo | null): Promise<void>;
81
84
  allowPrivateHttp: boolean;
85
+ codeModules: Record<string, string>;
82
86
  notifications?: INotificationAdapter;
83
87
  email?: IEmailAdapter;
84
88
  }
@@ -89,6 +93,16 @@ export interface IFlowEntityAccess {
89
93
  }, user: ILoggedUserInfo | null, options?: IFlowWriteOptions): Promise<IGenericRecord>;
90
94
  delete(id: string, user: ILoggedUserInfo | null, options?: IFlowWriteOptions): Promise<'deleted' | 'purged'>;
91
95
  findById(id: string, options?: IFlowReadOptions): Promise<IGenericRecord>;
96
+ batchInsertable?: boolean;
97
+ prepareInsert?(dto: Record<string, unknown>): Record<string, unknown>;
98
+ firstMissingRelation?(rows: Record<string, unknown>[], queryRunner: QueryRunner): Promise<{
99
+ index: number;
100
+ error: Error;
101
+ } | null>;
102
+ updateLoaded?(row: IGenericRecord, dto: Record<string, unknown>, user: ILoggedUserInfo | null, options?: IFlowWriteOptions): Promise<IGenericRecord>;
103
+ insertValidated?(rows: Record<string, unknown>[], user: ILoggedUserInfo | null, options: IFlowWriteOptions & {
104
+ queryRunner: QueryRunner;
105
+ }): Promise<IGenericRecord[]>;
92
106
  getAll(search: string | undefined, dto: {
93
107
  filter?: Record<string, unknown>;
94
108
  sort?: Record<string, 'ASC' | 'DESC'>;
@@ -107,6 +121,7 @@ export interface IFlowReadOptions {
107
121
  }
108
122
  export interface IFlowWriteOptions extends IFlowReadOptions {
109
123
  publishEvents?: boolean;
124
+ statementTimeoutMs?: number;
110
125
  }
111
126
  export interface INodeResult {
112
127
  output?: unknown;
@@ -288,6 +288,7 @@ export declare const FLOW_LIMITS: {
288
288
  readonly MAX_EMAIL_TEMPLATE_SLUG_LENGTH: 255;
289
289
  readonly MAX_HTTP_TIMEOUT_MS: 15000;
290
290
  readonly MAX_HTTP_RESPONSE_BYTES: 1000000;
291
+ readonly DEFAULT_QUERY_LIMIT: 50;
291
292
  readonly MAX_QUERY_LIMIT: 200;
292
293
  readonly MAX_WRITE_ITEMS: 1000;
293
294
  readonly DEFAULT_WRITE_FILTER_LIMIT: 100;
@@ -307,7 +308,6 @@ export declare const FLOW_LIMITS: {
307
308
  readonly MIN_CODE_TIMEOUT_MS: 10;
308
309
  readonly MAX_CODE_TIMEOUT_MS: 5000;
309
310
  readonly CODE_MEMORY_LIMIT_BYTES: number;
310
- readonly CODE_STACK_SIZE_BYTES: number;
311
311
  readonly MAX_CODE_OUTPUT_BYTES: 1000000;
312
312
  readonly MAX_CODE_LOG_LINES: 50;
313
313
  readonly MAX_CODE_LOG_LINE_CHARS: 500;
@@ -3,6 +3,7 @@ import { Reflector } from '@nestjs/core';
3
3
  import { type Observable } from 'rxjs';
4
4
  import { EntityBuilderConfigService } from '../services/entity-builder-config.service.js';
5
5
  export declare const DesignerWrites: (...handlers: string[]) => import("@nestjs/common").CustomDecorator<string>;
6
+ export declare const DesignerAllowsRepair: () => import("@nestjs/common").CustomDecorator<string>;
6
7
  export declare class DesignerWritableInterceptor implements NestInterceptor {
7
8
  private readonly reflector;
8
9
  private readonly config;
@@ -87,6 +87,8 @@ export interface IBundleImportPlan {
87
87
  export interface IBundleSettings {
88
88
  readOnly: boolean;
89
89
  variables: string[];
90
+ maxFiles: number;
91
+ maxBytes: number;
90
92
  }
91
93
  export interface IGeneratedApiKey {
92
94
  flowSlug: string;
@@ -5,6 +5,9 @@ export interface IEntityBuilderConfig extends IDataSourceServiceOptions {
5
5
  events?: IModuleEventsConfig;
6
6
  flows?: {
7
7
  allowPrivateHttp?: boolean;
8
+ code?: {
9
+ modules?: Record<string, string>;
10
+ };
8
11
  };
9
12
  bundles?: {
10
13
  variables?: Record<string, string>;
@@ -12,9 +15,14 @@ export interface IEntityBuilderConfig extends IDataSourceServiceOptions {
12
15
  designer?: {
13
16
  readOnly?: boolean;
14
17
  };
18
+ performance?: {
19
+ fastUpdates?: boolean;
20
+ partialIndexes?: boolean;
21
+ };
15
22
  }
16
23
  export interface EntityBuilderModuleOptions extends IDynamicModuleConfig {
17
24
  bootstrapAppConfig?: IBootstrapAppConfig;
25
+ tenantScopedServices?: boolean;
18
26
  config?: IEntityBuilderConfig;
19
27
  providers?: Provider[];
20
28
  }
@@ -23,6 +31,7 @@ export interface EntityBuilderOptionsFactory {
23
31
  }
24
32
  export interface EntityBuilderModuleAsyncOptions extends Pick<ModuleMetadata, 'imports'> {
25
33
  global?: boolean;
34
+ tenantScopedServices?: boolean;
26
35
  includeController?: boolean;
27
36
  bootstrapAppConfig?: IBootstrapAppConfig;
28
37
  useFactory?: (...args: any[]) => Promise<IEntityBuilderConfig> | IEntityBuilderConfig;
@@ -5,6 +5,7 @@ export declare class EntityBuilderModule {
5
5
  private static readonly EXPORTS;
6
6
  static forRoot(options: EntityBuilderModuleOptions): DynamicModule;
7
7
  static forRootAsync(options: EntityBuilderModuleAsyncOptions): DynamicModule;
8
+ private static tenantScoped;
8
9
  private static buildProviders;
9
10
  private static buildAsyncProviders;
10
11
  }
@@ -1 +1,2 @@
1
1
  export * from './entity-builder.module.js';
2
+ export * from './tenant-context-id.strategy.js';
@@ -0,0 +1,16 @@
1
+ import { type ContextId, type ContextIdResolver, type ContextIdStrategy } from '@nestjs/core';
2
+ export interface ITenantContextIdStrategyOptions {
3
+ tenants?: Iterable<string> | ((tenantId: string) => boolean);
4
+ maxTenants?: number;
5
+ }
6
+ type TenantRequest = {
7
+ headers?: Record<string, unknown>;
8
+ };
9
+ export declare class TenantContextIdStrategy implements ContextIdStrategy<TenantRequest> {
10
+ private readonly tenantContexts;
11
+ private readonly isTenant;
12
+ private readonly maxTenants;
13
+ constructor(options?: ITenantContextIdStrategyOptions);
14
+ attach(contextId: ContextId, request: TenantRequest): ContextIdResolver | undefined;
15
+ }
16
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flusys/nestjs-entity-builder",
3
- "version": "9.2.0",
3
+ "version": "9.2.1",
4
4
  "description": "Dynamic entity builder module - runtime entity/field metadata, driven DDL, and generic CRUD",
5
5
  "type": "module",
6
6
  "main": "./fesm/index.js",
@@ -85,8 +85,7 @@
85
85
  "rxjs": "^7.8.0"
86
86
  },
87
87
  "dependencies": {
88
- "@flusys/nestjs-core": "9.2.0",
89
- "@flusys/nestjs-shared": "9.2.0",
90
- "quickjs-emscripten": "^0.32.0"
88
+ "@flusys/nestjs-core": "9.2.1",
89
+ "@flusys/nestjs-shared": "9.2.1"
91
90
  }
92
91
  }
@@ -54,8 +54,6 @@ export interface IEntityDiff {
54
54
  extras: IBundleExtra[];
55
55
  blockers: IMessageRef[];
56
56
  }
57
- export declare const FIELD_COMPARED_KEYS: readonly ["label", "fieldType", "nullable", "unique", "isIndexed", "defaultValue", "validationRules", "selectOptions", "relationTarget", "order", "uiConfig", "isSearchable"];
58
- export declare const ENTITY_COMPARED_KEYS: readonly ["label", "description", "uiConfig", "isSoftDeleteEnabled", "isAuditEnabled", "status"];
59
57
  export declare function matchDefinitions<B extends {
60
58
  id: string;
61
59
  code: string;
@@ -4,4 +4,5 @@ export interface IUploadedBundleFile {
4
4
  size: number;
5
5
  originalname?: string;
6
6
  }
7
- export declare function readBundleFile(file: IUploadedBundleFile | undefined): IDefinitionBundle;
7
+ export declare function readBundleFile(file: IUploadedBundleFile | undefined, source?: string): IDefinitionBundle;
8
+ export declare function readBundleFiles(files: IUploadedBundleFile[] | undefined): IDefinitionBundle;
@@ -16,7 +16,6 @@ export declare class DefinitionBundleService {
16
16
  private readonly dialect;
17
17
  private readonly actionRegistry?;
18
18
  constructor(provider: EntityBuilderDataSourceProvider, config: EntityBuilderConfigService, schemaSync: SchemaSyncService, evolution: SchemaEvolutionService, flows: FlowDefinitionService, dialect: SchemaDialectAdapterService, actionRegistry?: IPermissionActionRegistry | undefined);
19
- private variables;
20
19
  export(dto: ExportBundleDto): Promise<IBundleExport>;
21
20
  private leftBehind;
22
21
  private loadEntities;
@@ -9,6 +9,9 @@ export declare class EntityBuilderConfigService implements IModuleConfigService
9
9
  isMultiTenant(): boolean;
10
10
  getOptions(): EntityBuilderModuleOptions;
11
11
  getConfig(): import("../index.js").IEntityBuilderConfig | undefined;
12
+ isFastUpdatesEnabled(): boolean;
13
+ isPartialIndexesEnabled(): boolean;
12
14
  isDesignerReadOnly(): boolean;
15
+ getCodeModules(): Record<string, string>;
13
16
  getBundleVariables(): Record<string, string>;
14
17
  }
@@ -19,6 +19,7 @@ export declare class EntityBuilderDataSourceProvider extends MultiTenantDataSour
19
19
  protected createDataSourceFromConfig(config: IDatabaseConfig): Promise<DataSource>;
20
20
  getDriver(): Promise<SupportedDbDriver>;
21
21
  registerDynamicSchema(schema: EntitySchema): Promise<void>;
22
+ registerDynamicSchemas(schemas: EntitySchema[]): Promise<void>;
22
23
  getDynamicRepository<T extends ObjectLiteral>(schema: EntitySchema<T>): Promise<Repository<T>>;
23
24
  getQueryRunner(): Promise<QueryRunner>;
24
25
  }
@@ -11,6 +11,13 @@ export interface IValidatableField {
11
11
  selectOptions: unknown[] | null;
12
12
  validationRules: Record<string, unknown> | null;
13
13
  }
14
+ export declare const valueRulesOf: (field: {
15
+ code: string;
16
+ label?: string | null;
17
+ fieldType: FieldType;
18
+ selectOptions?: unknown[] | null;
19
+ validationRules?: Record<string, unknown> | null;
20
+ }) => IValidatableField;
14
21
  export declare function validateRecord(fields: IValidatableField[], values: Record<string, unknown>, mode: 'insert' | 'update'): {
15
22
  values: Record<string, unknown>;
16
23
  errors: IFieldError[];
@@ -10,6 +10,7 @@ import { FlowDefinition } from '../entities/flow-definition.entity.js';
10
10
  import { type IFlowValidationResult } from '../flow-engine/flow-graph.validator.js';
11
11
  import { type IFlowEndpoint, type IFlowSettings } from '../flow-engine/flow.types.js';
12
12
  import { type IFlowDefinition, type IFlowSnapshot, type IFlowVersion } from '../interfaces/flow-definition.interface.js';
13
+ import { EntityBuilderConfigService } from './entity-builder-config.service.js';
13
14
  import { EntityBuilderDataSourceProvider } from './entity-builder-datasource.provider.js';
14
15
  export declare const defaultFlowPermissionCode: (slug: string) => string;
15
16
  export declare const flowPermissions: (endpoint: Pick<IFlowEndpoint, "permissions">, slug: string) => ILogicNode;
@@ -31,9 +32,11 @@ export declare class FlowDefinitionService extends ApiService<CreateFlowDefiniti
31
32
  private readonly notifications?;
32
33
  private readonly email?;
33
34
  private readonly companyAccess?;
34
- constructor(cacheManager: HybridCache, utilsService: UtilsService, provider: EntityBuilderDataSourceProvider, permissionCache: SharedPermissionCacheService, actionRegistry?: IPermissionActionRegistry | undefined, notifications?: INotificationAdapter | undefined, email?: IEmailAdapter | undefined, companyAccess?: ICompanyAccessResolver | undefined);
35
+ private readonly config?;
36
+ constructor(cacheManager: HybridCache, utilsService: UtilsService, provider: EntityBuilderDataSourceProvider, permissionCache: SharedPermissionCacheService, actionRegistry?: IPermissionActionRegistry | undefined, notifications?: INotificationAdapter | undefined, email?: IEmailAdapter | undefined, companyAccess?: ICompanyAccessResolver | undefined, config?: EntityBuilderConfigService | undefined);
35
37
  findOrFail(id: string): Promise<FlowDefinition>;
36
38
  validate(settings: IFlowSettings): Promise<IFlowValidationResult>;
39
+ codePackages(): string[];
37
40
  private callersOf;
38
41
  private assertNotCalled;
39
42
  private assertCallersKept;
@@ -57,7 +60,12 @@ export declare class FlowDefinitionService extends ApiService<CreateFlowDefiniti
57
60
  restoreVersion(flowId: string, version: number, user: ILoggedUserInfo | null): Promise<FlowDefinition>;
58
61
  discardDraft(flowId: string, user: ILoggedUserInfo | null): Promise<FlowDefinition>;
59
62
  private saveDraft;
60
- protected beforeDeleteOperation(dto: DeleteDto, user: ILoggedUserInfo | null, _qr: QueryRunner): Promise<void>;
63
+ delete(option: DeleteDto, user: ILoggedUserInfo | null): Promise<null>;
64
+ protected beforeDeleteOperation(dto: DeleteDto, _user: ILoggedUserInfo | null, _qr: QueryRunner): Promise<void>;
65
+ protected afterDeleteOperation(deleted: Array<{
66
+ id: string;
67
+ }>, _dto: DeleteDto, _user: ILoggedUserInfo | null, qr: QueryRunner): Promise<void>;
68
+ private deprovisionPermissions;
61
69
  private provisionPermissions;
62
70
  }
63
71
  export {};
@@ -27,6 +27,7 @@ export declare class FlowExecutorService {
27
27
  private readonly email?;
28
28
  private readonly branchHierarchy?;
29
29
  private readonly logger;
30
+ private readonly inFlight;
30
31
  constructor(provider: EntityBuilderDataSourceProvider, ruleEngine: RuleEngineService, moduleRef: ModuleRef, permissionCache: SharedPermissionCacheService, config: EntityBuilderConfigService, companyAccess?: ICompanyAccessResolver | undefined, notifications?: INotificationAdapter | undefined, email?: IEmailAdapter | undefined, branchHierarchy?: IBranchHierarchyResolver | undefined);
31
32
  run(flow: IFlowSettings, options: IFlowRunOptions): Promise<IFlowRunResult>;
32
33
  private execute;
@@ -37,5 +38,7 @@ export declare class FlowExecutorService {
37
38
  private findCallable;
38
39
  private assertMayCall;
39
40
  private createEnv;
41
+ private publishAfterCommit;
42
+ whenPublished(): Promise<void>;
40
43
  private publishPendingEvents;
41
44
  }
@@ -1,4 +1,6 @@
1
+ import { HybridCache } from '@flusys/nestjs-shared/classes';
1
2
  import { type ILoggedUserInfo, type IMessageRef } from '@flusys/nestjs-shared/interfaces';
3
+ import { UtilsService } from '@flusys/nestjs-shared/modules';
2
4
  import { type TestFlowDto } from '../dtos/flow.dto.js';
3
5
  import { FlowDefinition } from '../entities/flow-definition.entity.js';
4
6
  import { type IFlowRunResult } from '../flow-engine/flow-run.types.js';
@@ -19,8 +21,11 @@ export declare class FlowRuntimeService {
19
21
  private readonly executor;
20
22
  private readonly executions;
21
23
  private readonly definitions;
22
- constructor(provider: EntityBuilderDataSourceProvider, executor: FlowExecutorService, executions: FlowExecutionService, definitions: FlowDefinitionService);
24
+ private readonly cache?;
25
+ private readonly utils?;
26
+ constructor(provider: EntityBuilderDataSourceProvider, executor: FlowExecutorService, executions: FlowExecutionService, definitions: FlowDefinitionService, cache?: HybridCache | undefined, utils?: UtilsService | undefined);
23
27
  findActive(slug: string): Promise<FlowDefinition | null>;
28
+ private activeFlowKey;
24
29
  tenantScope(): string;
25
30
  handle(flow: FlowDefinition, endpoint: IFlowEndpoint, body: unknown, caller: IFlowCaller, user: ILoggedUserInfo | null): Promise<IFlowRunResult>;
26
31
  testRun(dto: TestFlowDto, user: ILoggedUserInfo | null, caller: IFlowCaller): Promise<{
@@ -1,12 +1,16 @@
1
1
  import { type QueryRunner } from 'typeorm';
2
+ import { EntityBuilderConfigService } from './entity-builder-config.service.js';
2
3
  import { EntityBuilderDataSourceProvider } from './entity-builder-datasource.provider.js';
3
4
  import { GenericEntityService } from './generic-entity.service.js';
4
5
  import { SchemaRegistryService } from './schema-registry.service.js';
5
6
  export declare class GenericEntityServiceFactory {
6
7
  private readonly schemaRegistry;
7
8
  private readonly dataSourceProvider;
8
- constructor(schemaRegistry: SchemaRegistryService, dataSourceProvider: EntityBuilderDataSourceProvider);
9
+ private readonly config?;
10
+ private readonly relatedById;
11
+ constructor(schemaRegistry: SchemaRegistryService, dataSourceProvider: EntityBuilderDataSourceProvider, config?: EntityBuilderConfigService | undefined);
9
12
  forEntityCode(entityCode: string, queryRunner?: QueryRunner): Promise<GenericEntityService>;
10
13
  forEntityDefinitionId(entityDefinitionId: string, queryRunner?: QueryRunner): Promise<GenericEntityService>;
14
+ private related;
11
15
  private build;
12
16
  }
@@ -1,4 +1,5 @@
1
1
  import { type ILoggedUserInfo } from '@flusys/nestjs-shared/interfaces';
2
+ import { BadRequestException } from '@nestjs/common';
2
3
  import { type EntitySchema, type QueryRunner } from 'typeorm';
3
4
  import { EntityDefinition } from '../entities/entity-definition.entity.js';
4
5
  import { FieldDefinition } from '../entities/field-definition.entity.js';
@@ -19,9 +20,14 @@ export interface IGenericQuery {
19
20
  export interface IGenericWriteOptions {
20
21
  queryRunner?: QueryRunner;
21
22
  publishEvents?: boolean;
23
+ statementTimeoutMs?: number;
22
24
  }
25
+ export declare const statementTimeoutSql: (timeoutMs: number) => string;
23
26
  export declare const ACTOR_BRANCH_METADATA_KEY = "_actorBranchId";
24
27
  export declare function actorMetadata(user: ILoggedUserInfo | null): Record<string, unknown>;
28
+ export interface IGenericEntityOptions {
29
+ fastUpdates?: boolean;
30
+ }
25
31
  export type RelatedServiceResolver = (entityDefinitionId: string, queryRunner?: QueryRunner) => Promise<GenericEntityService>;
26
32
  export declare class GenericEntityService {
27
33
  private readonly definition;
@@ -29,35 +35,51 @@ export declare class GenericEntityService {
29
35
  private readonly fields;
30
36
  private readonly dataSourceProvider;
31
37
  private readonly resolveRelated?;
38
+ private readonly options;
32
39
  private repository?;
33
40
  private readonly activeFieldCodes;
34
41
  private readonly presentSystemColumns;
35
- constructor(definition: EntityDefinition, schema: EntitySchema, fields: FieldDefinition[], dataSourceProvider: EntityBuilderDataSourceProvider, resolveRelated?: RelatedServiceResolver | undefined);
42
+ constructor(definition: EntityDefinition, schema: EntitySchema, fields: FieldDefinition[], dataSourceProvider: EntityBuilderDataSourceProvider, resolveRelated?: RelatedServiceResolver | undefined, options?: IGenericEntityOptions);
36
43
  get entityCode(): string;
37
44
  private validateValues;
38
45
  private throwIfInvalid;
46
+ private invalid;
39
47
  private assertRelationsExist;
48
+ private relatedNotFound;
49
+ private existingRelatedIds;
40
50
  private notFound;
41
51
  private auditFields;
42
- private stampDeletedBy;
43
52
  private ensureActive;
44
53
  private repositoryFor;
45
54
  private ensureRepository;
46
55
  private validateKeys;
47
56
  insert(dto: Record<string, unknown>, user: ILoggedUserInfo | null, options?: IGenericWriteOptions): Promise<IGenericRecord>;
57
+ prepareInsert(dto: Record<string, unknown>): Record<string, unknown>;
58
+ firstMissingRelation(rows: Record<string, unknown>[], queryRunner: QueryRunner): Promise<{
59
+ index: number;
60
+ error: BadRequestException;
61
+ } | null>;
62
+ insertValidated(rows: Record<string, unknown>[], user: ILoggedUserInfo | null, options: IGenericWriteOptions & {
63
+ queryRunner: QueryRunner;
64
+ }): Promise<IGenericRecord[]>;
65
+ get batchInsertable(): boolean;
66
+ private missingRelations;
48
67
  update(dto: Record<string, unknown> & {
49
68
  id: string;
50
69
  }, user: ILoggedUserInfo | null, options?: IGenericWriteOptions): Promise<IGenericRecord>;
51
70
  private insertRow;
71
+ updateLoaded(row: IGenericRecord, dto: Record<string, unknown>, user: ILoggedUserInfo | null, options?: IGenericWriteOptions): Promise<IGenericRecord>;
52
72
  private updateRow;
53
73
  private assertUpdatable;
54
74
  delete(id: string, user: ILoggedUserInfo | null, options?: IGenericWriteOptions): Promise<'deleted' | 'purged'>;
55
75
  findById(id: string, options?: IGenericReadOptions): Promise<IGenericRecord>;
56
76
  exists(id: string, options?: IGenericReadOptions): Promise<boolean>;
77
+ existingIds(ids: string[], options?: IGenericReadOptions): Promise<Set<string>>;
57
78
  getAll(search: string | undefined, query: IGenericQuery, options?: IGenericReadOptions): Promise<{
58
79
  data: IGenericRecord[];
59
80
  total: number;
60
81
  }>;
82
+ private totalOf;
61
83
  private applyFilter;
62
84
  private conditionSql;
63
85
  private listOperand;
@@ -1,5 +1,4 @@
1
1
  import { type FieldType } from '../enums/field-type.enum.js';
2
- export declare const RESERVED_WORDS: Set<string>;
3
2
  export declare function assertValidIdentifier(code: string, kind: 'entity' | 'field'): void;
4
3
  export declare function assertIndexableField(field: {
5
4
  code: string;
@@ -0,0 +1,2 @@
1
+ import { type EntityTarget, type ObjectLiteral, type QueryRunner } from 'typeorm';
2
+ export declare function saveLoaded<T extends ObjectLiteral>(queryRunner: QueryRunner, target: EntityTarget<T>, entity: T, databaseEntity: T): Promise<T>;
@@ -4,7 +4,10 @@ import { FieldType } from '../enums/field-type.enum.js';
4
4
  import { type SupportedDbDriver } from '../interfaces/schema-dialect-adapter.interface.js';
5
5
  import { type SchemaDialectAdapterService } from './schema-dialect-adapter.service.js';
6
6
  export declare const SYSTEM_COLUMN_NAMES: readonly ["id", "created_at", "updated_at", "deleted_at", "created_by_id", "updated_by_id", "deleted_by_id"];
7
- export declare const NON_INDEXABLE_FIELD_TYPES: readonly FieldType[];
7
+ export declare const indexedByDefault: (spec: {
8
+ fieldType: FieldType;
9
+ isIndexed?: boolean | null;
10
+ }) => boolean;
8
11
  export declare const isIndexableFieldType: (fieldType: FieldType) => boolean;
9
12
  export interface ISystemColumnFlags {
10
13
  isSoftDeleteEnabled: boolean;
@@ -15,7 +18,9 @@ export declare const softDeleteColumn: () => TableColumn;
15
18
  export declare const auditColumns: (driver: SupportedDbDriver) => TableColumn[];
16
19
  export declare const sameColumns: (columnNames: string[], expected: string[]) => boolean;
17
20
  export declare function indexName(prefix: 'idx' | 'uq', table: string, column: string, maxLength: number): string;
18
- export declare const plainIndex: (table: string, column: string, driver: SupportedDbDriver, adapter: SchemaDialectAdapterService) => TableIndex;
21
+ export declare const LIVE_ROWS_WHERE = "\"deleted_at\" IS NULL";
22
+ export declare const plainIndex: (table: string, column: string, driver: SupportedDbDriver, adapter: SchemaDialectAdapterService, liveOnly?: boolean) => TableIndex;
23
+ export declare const isLiveRowsIndex: (index: Pick<TableIndex, "where">) => boolean;
19
24
  export declare const tableUnique: (table: string, column: string, driver: SupportedDbDriver, adapter: SchemaDialectAdapterService) => TableUnique;
20
25
  export declare function addUnique(qr: QueryRunner, table: Table, column: string, driver: SupportedDbDriver, adapter: SchemaDialectAdapterService): Promise<void>;
21
26
  export declare function buildFieldColumn(field: Pick<FieldDefinition, 'code' | 'fieldType' | 'dbType' | 'nullable' | 'unique'>, driver: SupportedDbDriver, adapter: SchemaDialectAdapterService, options: {
@@ -6,6 +6,7 @@ import { EntityPermissionService } from './entity-permission.service.js';
6
6
  import { ReferenceScannerService } from './reference-scanner.service.js';
7
7
  import { SchemaChangeExecutor } from './schema-change-executor.service.js';
8
8
  import { type ISchemaChangeApplied, type ISchemaChangePlan } from './schema-change.types.js';
9
+ import { EntityBuilderConfigService } from './entity-builder-config.service.js';
9
10
  import { SchemaDialectAdapterService } from './schema-dialect-adapter.service.js';
10
11
  export type SchemaFindingKind = 'missing_table' | 'missing_column' | 'extra_column' | 'type_mismatch' | 'nullability_mismatch' | 'missing_index' | 'missing_unique' | 'stale_metadata';
11
12
  export interface ISchemaFinding extends IMessageRef {
@@ -28,13 +29,14 @@ export declare class SchemaEvolutionService {
28
29
  private readonly executor;
29
30
  private readonly references;
30
31
  private readonly permissions;
31
- constructor(dataSourceProvider: EntityBuilderDataSourceProvider, adapter: SchemaDialectAdapterService, executor: SchemaChangeExecutor, references: ReferenceScannerService, permissions: EntityPermissionService);
32
+ private readonly config?;
33
+ constructor(dataSourceProvider: EntityBuilderDataSourceProvider, adapter: SchemaDialectAdapterService, executor: SchemaChangeExecutor, references: ReferenceScannerService, permissions: EntityPermissionService, config?: EntityBuilderConfigService | undefined);
32
34
  plan(request: SchemaChangeRequestDto, user: ILoggedUserInfo | null): Promise<ISchemaChangePlan>;
33
35
  apply(request: SchemaChangeRequestDto, user: ILoggedUserInfo | null, options?: {
34
36
  fieldId?: string;
35
37
  }): Promise<ISchemaChangeApplied>;
36
38
  inspect(entityDefinitionId: string): Promise<ISchemaCheckResult>;
37
- history(entityDefinitionId: string, limit?: number): Promise<SchemaChangeLog[]>;
39
+ history(entityDefinitionId: string): Promise<SchemaChangeLog[]>;
38
40
  private loadEntity;
39
41
  private loadField;
40
42
  private definitions;
@@ -56,12 +58,16 @@ export declare class SchemaEvolutionService {
56
58
  private dropUniques;
57
59
  private hasUnique;
58
60
  private indexOn;
61
+ private liveOnly;
62
+ private hasPlainIndex;
63
+ private rebuildPlainIndex;
59
64
  private prepareAddField;
60
65
  private prepareUpdateField;
61
66
  private prepareDeprecateField;
62
67
  private prepareRestoreField;
63
68
  private preparePurgeField;
64
69
  private prepareUpdateEntity;
70
+ private reshapePlainIndexes;
65
71
  private relationsInto;
66
72
  private prepareDropEntity;
67
73
  private diff;
@@ -1,12 +1,24 @@
1
1
  import { EntitySchema, type QueryRunner } from 'typeorm';
2
+ import { EntityDefinition } from '../entities/entity-definition.entity.js';
3
+ import { FieldDefinition } from '../entities/field-definition.entity.js';
2
4
  import { EntityBuilderDataSourceProvider } from './entity-builder-datasource.provider.js';
3
5
  import { SchemaDialectAdapterService } from './schema-dialect-adapter.service.js';
6
+ export interface IResolvedSchema {
7
+ schema: EntitySchema;
8
+ fields: FieldDefinition[];
9
+ }
4
10
  export declare class SchemaRegistryService {
5
11
  private readonly dataSourceProvider;
6
12
  private readonly dialectAdapter;
7
13
  private static readonly cache;
14
+ private static readonly warming;
15
+ private readonly logger;
8
16
  constructor(dataSourceProvider: EntityBuilderDataSourceProvider, dialectAdapter: SchemaDialectAdapterService);
9
17
  getSchema(entityDefinitionId: string, queryRunner?: QueryRunner): Promise<EntitySchema>;
18
+ resolve(definition: EntityDefinition, queryRunner?: QueryRunner): Promise<IResolvedSchema>;
19
+ warmUp(queryRunner?: QueryRunner): Promise<void>;
20
+ private registerAll;
21
+ private store;
10
22
  invalidate(entityDefinitionId: string): void;
11
23
  private cacheKey;
12
24
  private buildEntitySchema;
@@ -6,6 +6,7 @@ import { EntityPermissionService } from './entity-permission.service.js';
6
6
  import { FlowDefinitionService } from './flow-definition.service.js';
7
7
  import { SchemaChangeExecutor } from './schema-change-executor.service.js';
8
8
  import { type ISchemaChangePlan } from './schema-change.types.js';
9
+ import { EntityBuilderConfigService } from './entity-builder-config.service.js';
9
10
  import { SchemaDialectAdapterService } from './schema-dialect-adapter.service.js';
10
11
  export interface ICreatedEntity {
11
12
  definition: EntityDefinition;
@@ -21,8 +22,9 @@ export declare class SchemaSyncService {
21
22
  private readonly executor;
22
23
  private readonly entityPermissionService;
23
24
  private readonly flowDefinitionService;
25
+ private readonly config?;
24
26
  private readonly logger;
25
- constructor(dataSourceProvider: EntityBuilderDataSourceProvider, dialectAdapter: SchemaDialectAdapterService, executor: SchemaChangeExecutor, entityPermissionService: EntityPermissionService, flowDefinitionService: FlowDefinitionService);
27
+ constructor(dataSourceProvider: EntityBuilderDataSourceProvider, dialectAdapter: SchemaDialectAdapterService, executor: SchemaChangeExecutor, entityPermissionService: EntityPermissionService, flowDefinitionService: FlowDefinitionService, config?: EntityBuilderConfigService | undefined);
26
28
  private validateCreateRequest;
27
29
  private createTarget;
28
30
  private createRun;
@@ -1,5 +0,0 @@
1
- export interface ICodeRunResult {
2
- output: unknown;
3
- logs: string[];
4
- }
5
- export declare function runSandboxedCode(code: string, ctx: Record<string, unknown>, timeoutMs: number, node: string): Promise<ICodeRunResult>;