bazis 0.128.0 → 0.130.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/core/access/Access.module.ts +36 -0
- package/core/access/catalog/AccessCatalog.ts +73 -0
- package/core/access/catalog/IAccessCatalog.service.ts +17 -0
- package/core/access/catalog/moduleFields.ts +153 -0
- package/core/access/catalog/permissions.ts +127 -0
- package/core/access/check/Access.ts +191 -0
- package/core/access/check/IAccess.service.ts +20 -0
- package/core/access/check/accessConfig.ts +18 -0
- package/core/access/check/can.ts +21 -0
- package/core/access/check/conditions.ts +132 -0
- package/core/access/check/filter.ts +132 -0
- package/core/access/contracts/AccessPolicy.ts +29 -0
- package/core/access/contracts/AttributeLookup.ts +17 -0
- package/core/access/contracts/References.ts +33 -0
- package/core/access/contracts/errors.ts +13 -0
- package/core/access/contracts/types.ts +66 -0
- package/core/access/generated/deps.ts +14 -0
- package/core/access/http/AccessCatalog.controller.ts +51 -0
- package/core/access/index.ts +35 -0
- package/core/access/roles/RolesAccessPolicy.ts +64 -0
- package/core/access/roles/roles.ts +62 -0
- package/core/access/testing/index.ts +54 -0
- package/core/background/BackgroundService.ts +1 -1
- package/core/di/README.md +5 -5
- package/core/di/errors/ClassDependenciesMismatchError.ts +1 -1
- package/core/di/internal/GraphValidator.ts +1 -1
- package/core/di/module/autoDeps.ts +11 -1
- package/core/di/module/createContainer.ts +1 -1
- package/core/di/module/providerSelection.ts +1 -1
- package/core/grpc/{GrpcClient.ts → GrpcClientBase.ts} +1 -1
- package/core/grpc/grpcClients.ts +79 -0
- package/core/grpc/index.ts +2 -2
- package/core/http/options.ts +1 -1
- package/core/http-client/httpClients.ts +82 -0
- package/core/http-client/index.ts +11 -91
- package/core/infra/connectors/codex/CodexAppServerClient.ts +1 -1
- package/core/scripts/di-generate-target.ts +9 -0
- package/core/scripts/di-generate.ts +177 -9
- package/core/workflow/definitions_module/WorkflowDefinitions.module.ts +15 -11
- package/core/workflow/definitions_module/access/Definitions.permissions.ts +23 -0
- package/core/workflow/definitions_module/access/Process.references.ts +27 -0
- package/core/workflow/definitions_module/code/CodeProcessCatalog.ts +4 -3
- package/core/workflow/definitions_module/code/CodeProcessPublisher.ts +2 -2
- package/core/workflow/definitions_module/http/Processes.controller.ts +23 -14
- package/core/workflow/definitions_module/services/IWorkflowDefinitions.service.ts +9 -0
- package/core/workflow/definitions_module/services/WorkflowDefinitions.service.ts +4 -0
- package/core/workflow/generated/deps.ts +56 -0
- package/core/workflow/index.ts +1 -1
- package/core/workflow/internal/WorkflowTools.ts +2 -2
- package/core/workflow/internal/http.ts +18 -17
- package/core/workflow/runtime_module/WorkflowRuntime.module.ts +17 -34
- package/core/workflow/runtime_module/access/Runtime.permissions.ts +28 -0
- package/core/workflow/runtime_module/background/WorkflowRetention.ts +1 -1
- package/core/workflow/runtime_module/background/WorkflowWorker.ts +1 -10
- package/core/workflow/runtime_module/config/Runtime.config.ts +11 -1
- package/core/workflow/runtime_module/http/Events.controller.ts +5 -3
- package/core/workflow/runtime_module/http/Instances.controller.ts +25 -15
- package/core/workflow/runtime_module/internal/WorkflowEngine.ts +4 -3
- package/core/workflow/runtime_module/services/IWorkflowRuntime.service.ts +3 -0
- package/core/workflow/runtime_module/services/WorkflowRuntime.service.ts +16 -5
- package/core/workflow/tasks_module/WorkflowTasks.module.ts +8 -10
- package/core/workflow/tasks_module/access/Tasks.permissions.ts +13 -0
- package/core/workflow/tasks_module/events/TaskEvents.ts +29 -8
- package/core/workflow/tasks_module/http/Tasks.controller.ts +21 -12
- package/core/workflow/tasks_module/services/IWorkflowTasks.service.ts +8 -3
- package/core/workflow/tasks_module/services/WorkflowTasks.service.ts +41 -42
- package/core/workflow/testing/index.ts +1 -0
- package/index.ts +1 -1
- package/library/http-client/{HttpClient.ts → HttpClientBase.ts} +5 -5
- package/library/http-client/HttpClientFactory.ts +5 -5
- package/library/http-client/index.ts +3 -3
- package/library/terminal/messages.ts +2 -2
- package/package.json +3 -1
- package/core/grpc/grpcClientProvider.ts +0 -9
- package/core/workflow/access/WorkflowAccess.ts +0 -52
|
@@ -31,6 +31,13 @@ const FRAMEWORK_SOURCE = ((): string | null => {
|
|
|
31
31
|
})();
|
|
32
32
|
const FRAMEWORK_ROOT = FRAMEWORK_SOURCE ?? "src/bazis";
|
|
33
33
|
const isFrameworkSourcePath = (file: string): boolean => FRAMEWORK_SOURCE !== null && file.startsWith(`${FRAMEWORK_SOURCE}/`);
|
|
34
|
+
/**
|
|
35
|
+
* Packs of the framework's own checkout whose DI wiring ships inside the
|
|
36
|
+
* package (`framework.packs` of bazis.config.json): an application's codegen
|
|
37
|
+
* skips node_modules, so the pack carries `<pack>/generated/deps.ts` itself.
|
|
38
|
+
*/
|
|
39
|
+
let frameworkPacks: readonly string[] = [];
|
|
40
|
+
const isFrameworkPackPath = (file: string): boolean => frameworkPacks.some((pack) => file.startsWith(`${pack}/`));
|
|
34
41
|
const APP_GENERATED_DIR = "src/generated/bazis";
|
|
35
42
|
let activeGeneratedDir = APP_GENERATED_DIR;
|
|
36
43
|
const plannedWrites = new Map<string, string>();
|
|
@@ -163,8 +170,9 @@ function readRequestedTarget(): string | undefined {
|
|
|
163
170
|
throw new Error(`BAZIS_CODEGEN_TARGET_UNKNOWN: ${target ?? ""}`);
|
|
164
171
|
}
|
|
165
172
|
|
|
166
|
-
// Framework internals: their classes are excluded from the auto-deps map
|
|
167
|
-
//
|
|
173
|
+
// Framework internals: their classes are excluded from the auto-deps map of a
|
|
174
|
+
// target. Packs listed in `framework.packs` get their own generated wiring
|
|
175
|
+
// (generateFrameworkPack); the rest still wire their services explicitly.
|
|
168
176
|
const FRAMEWORK_INTERNAL_PREFIXES = FRAMEWORK_SOURCE === null ? [] : [
|
|
169
177
|
"core/di/", "core/kernel/", "core/http/", "core/grpc/", "core/http-client/", "core/background/",
|
|
170
178
|
"core/agent/", "core/websocket/", "core/cache/", "library/validation/", "library/boundary/",
|
|
@@ -251,7 +259,8 @@ let program: ts.Program;
|
|
|
251
259
|
let programFiles = new Map<string, ts.SourceFile>();
|
|
252
260
|
// Framework sources outside the scanned project (node_modules/bazis, vendor/bazis).
|
|
253
261
|
// Only their class and token names are read, so app constructor dependencies on
|
|
254
|
-
// framework classes are not discarded as unknown; their own wiring ships with them
|
|
262
|
+
// framework classes are not discarded as unknown; their own wiring ships with them
|
|
263
|
+
// (`<pack>/generated/deps.ts` of the framework packs).
|
|
255
264
|
let installedFrameworkSources: ts.SourceFile[] = [];
|
|
256
265
|
let sourceFilePathSet = new Set<string>();
|
|
257
266
|
let checker: ts.TypeChecker;
|
|
@@ -348,6 +357,7 @@ async function runConfiguredTargets(): Promise<void> {
|
|
|
348
357
|
const totalStartedAt = performance.now();
|
|
349
358
|
const configStartedAt = performance.now();
|
|
350
359
|
const config = await readCodegenConfig();
|
|
360
|
+
frameworkPacks = FRAMEWORK_SOURCE === null ? [] : (config.framework?.packs ?? []);
|
|
351
361
|
await planStaleGeneratedTargetRemoval(Object.keys(config.targets));
|
|
352
362
|
// Test sources remain excluded from the broad candidate scan. A test-only
|
|
353
363
|
// target can still opt a single fixture in explicitly through its declared
|
|
@@ -434,6 +444,7 @@ async function runConfiguredTargets(): Promise<void> {
|
|
|
434
444
|
eligible += metrics.eligible;
|
|
435
445
|
candidates += metrics.candidates;
|
|
436
446
|
}
|
|
447
|
+
for (const pack of frameworkPacks) generateFrameworkPack(pack);
|
|
437
448
|
const targetMs = performance.now() - targetStartedAt;
|
|
438
449
|
const writeStartedAt = performance.now();
|
|
439
450
|
await commitPlannedWrites();
|
|
@@ -444,7 +455,7 @@ async function runConfiguredTargets(): Promise<void> {
|
|
|
444
455
|
|
|
445
456
|
function createSourceCandidateIndex(files: ReadonlyMap<string, ts.SourceFile>): ReadonlyMap<string, boolean> {
|
|
446
457
|
for (const [file, source] of files) {
|
|
447
|
-
if (!FRAMEWORK_INTERNAL_PREFIXES.some((prefix) => file.startsWith(prefix))) collectDiClassRegistrations(source);
|
|
458
|
+
if (!FRAMEWORK_INTERNAL_PREFIXES.some((prefix) => file.startsWith(prefix)) && !isFrameworkPackPath(file)) collectDiClassRegistrations(source);
|
|
448
459
|
}
|
|
449
460
|
return new Map([...files].map(([file, source]) => [file, sourceHasCodegenCandidate(source)]));
|
|
450
461
|
}
|
|
@@ -511,15 +522,16 @@ async function generateTarget(name: string, reachable: Set<string>, production:
|
|
|
511
522
|
resetTargetAnalysis(reachable, generatedDir);
|
|
512
523
|
for (const { source } of sourceEntries) collectListRequestClasses(source);
|
|
513
524
|
for (const { filePath, source } of sourceEntries) {
|
|
514
|
-
if (!FRAMEWORK_INTERNAL_PREFIXES.some((prefix) => filePath.startsWith(prefix))) collectDiClassRegistrations(source);
|
|
525
|
+
if (!FRAMEWORK_INTERNAL_PREFIXES.some((prefix) => filePath.startsWith(prefix)) && !isFrameworkPackPath(filePath)) collectDiClassRegistrations(source);
|
|
515
526
|
}
|
|
516
527
|
const prepassMs = performance.now() - startedAt;
|
|
517
528
|
for (const source of installedFrameworkSources) collectTokenDescriptions(source);
|
|
518
529
|
for (const { filePath, source } of sourceEntries) {
|
|
519
530
|
fatalErrors.push(...analyzeOrmPredicates(checker, source));
|
|
520
531
|
collectTokenDescriptions(source);
|
|
521
|
-
if (!FRAMEWORK_INTERNAL_PREFIXES.some((prefix) => filePath.startsWith(prefix))) {
|
|
532
|
+
if (!FRAMEWORK_INTERNAL_PREFIXES.some((prefix) => filePath.startsWith(prefix)) && !isFrameworkPackPath(filePath)) {
|
|
522
533
|
collectClassDeps(source);
|
|
534
|
+
collectProviderFormErrors(source);
|
|
523
535
|
collectGrpcBindings(source);
|
|
524
536
|
toolCodegenSources.push({ filePath, sourceFile: source });
|
|
525
537
|
}
|
|
@@ -575,6 +587,72 @@ function classifyToolWarnings(toolWarnings: readonly string[]): void {
|
|
|
575
587
|
}
|
|
576
588
|
}
|
|
577
589
|
|
|
590
|
+
/**
|
|
591
|
+
* The wiring of one framework pack: constructor dependencies of the classes
|
|
592
|
+
* its modules register, written to `<pack>/generated/deps.ts`. The pack's
|
|
593
|
+
* `index.ts` imports that file, so the package carries its own wiring and
|
|
594
|
+
* framework modules register `singleton(IContract, Implementation)` like an
|
|
595
|
+
* application does.
|
|
596
|
+
*/
|
|
597
|
+
function generateFrameworkPack(pack: string): void {
|
|
598
|
+
const files = new Set([...programFiles.keys()].filter((file) => file.startsWith(`${pack}/`)));
|
|
599
|
+
if (!files.has(`${pack}/index.ts`)) throw new Error(`BAZIS_CODEGEN_CONFIG_INVALID: framework pack ${pack} has no index.ts`);
|
|
600
|
+
resetTargetAnalysis(files, `${pack}/generated`);
|
|
601
|
+
// Tokens, configs and classes the pack depends on may live anywhere in the framework.
|
|
602
|
+
for (const source of programFiles.values()) collectTokenDescriptions(source);
|
|
603
|
+
for (const { source } of sourceEntries) collectDiClassRegistrations(source);
|
|
604
|
+
for (const { source } of sourceEntries) collectClassDeps(source);
|
|
605
|
+
for (const { source } of sourceEntries) collectProviderFormErrors(source);
|
|
606
|
+
resolveConfigViewDeps();
|
|
607
|
+
validateDepsAgainstKnownTokens();
|
|
608
|
+
failOnFatalErrors();
|
|
609
|
+
stageWrite(`${pack}/generated/deps.ts`, renderFrameworkPackDeps(pack));
|
|
610
|
+
for (const warning of warnings) reportWarning(warning);
|
|
611
|
+
reportInfo(`[di:generate] framework pack=${pack} deps=${classDeps.size}`);
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
function renderFrameworkPackDeps(pack: string): string {
|
|
615
|
+
const generatedDir = `${pack}/generated`;
|
|
616
|
+
const entries = [...classDeps.entries()].sort(([left], [right]) =>
|
|
617
|
+
left.name!.text.localeCompare(right.name!.text)
|
|
618
|
+
|| left.getSourceFile().fileName.localeCompare(right.getSourceFile().fileName)
|
|
619
|
+
|| left.pos - right.pos);
|
|
620
|
+
const references = new Map<ts.ClassDeclaration, string>();
|
|
621
|
+
for (const [declaration] of entries) references.set(declaration, declaration.name!.text);
|
|
622
|
+
for (const [, dependencies] of entries) {
|
|
623
|
+
for (const dependency of dependencies) {
|
|
624
|
+
if (dependency.target && !references.has(dependency.target)) references.set(dependency.target, dependency.target.name!.text);
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
const di = (file: string) => JSON.stringify(toModuleSpecifierFrom(generatedDir, `${FRAMEWORK_SOURCE}/core/di/${file}`));
|
|
628
|
+
const lines = ["// This file is auto-generated by `bun run di:generate` (framework.packs of bazis.config.json).", "// Do not edit manually."];
|
|
629
|
+
const helpers = ["lazyDependency", "optionalDependency"].filter((helper) => entries.some(([, deps]) =>
|
|
630
|
+
deps.some((dep) => dep.target && (helper === "lazyDependency" ? dep.lazy : dep.optional))));
|
|
631
|
+
if (helpers.length > 0) lines.push(`import { ${helpers.join(", ")} } from ${di("provider/index.ts")};`);
|
|
632
|
+
lines.push(`import { registerFrameworkClassDeps } from ${di("module/autoDeps.ts")};`);
|
|
633
|
+
const byFile = new Map<string, string[]>();
|
|
634
|
+
for (const [declaration, reference] of references) {
|
|
635
|
+
const name = dependencyClassExportName(declaration);
|
|
636
|
+
if (!name) throw new Error(`BAZIS_DI_CLASS_UNIMPORTABLE: ${sourceLocation(declaration)}`);
|
|
637
|
+
const specifier = toModuleSpecifierFrom(generatedDir, normalizeProjectPath(declaration.getSourceFile().fileName));
|
|
638
|
+
byFile.set(specifier, [...(byFile.get(specifier) ?? []), name === reference ? name : `${name} as ${reference}`]);
|
|
639
|
+
}
|
|
640
|
+
for (const [specifier, names] of [...byFile].sort(([left], [right]) => left.localeCompare(right))) {
|
|
641
|
+
lines.push(`import { ${names.sort().join(", ")} } from ${JSON.stringify(specifier)};`);
|
|
642
|
+
}
|
|
643
|
+
lines.push("", "registerFrameworkClassDeps([");
|
|
644
|
+
for (const [declaration, dependencies] of entries) {
|
|
645
|
+
const values = dependencies.map((dependency) => {
|
|
646
|
+
if (!dependency.target) return JSON.stringify(dependency.optional ? `optional:${dependency.name}` : dependency.name);
|
|
647
|
+
const reference = references.get(dependency.target)!;
|
|
648
|
+
return dependency.lazy ? `lazyDependency(${reference})` : dependency.optional ? `optionalDependency(${reference})` : reference;
|
|
649
|
+
});
|
|
650
|
+
lines.push(` [${references.get(declaration)}, [${values.join(", ")}]],`);
|
|
651
|
+
}
|
|
652
|
+
lines.push("]);");
|
|
653
|
+
return `${lines.join("\n")}\n`;
|
|
654
|
+
}
|
|
655
|
+
|
|
578
656
|
function failOnFatalErrors(): void {
|
|
579
657
|
if (fatalErrors.length === 0) {
|
|
580
658
|
return;
|
|
@@ -797,7 +875,7 @@ function resolveConfigViewDeps(): void {
|
|
|
797
875
|
if (needsInferredDiDeps(declaration)) {
|
|
798
876
|
fatalErrors.push(prefixes.length === 0
|
|
799
877
|
? `BAZIS_DI_CONFIG_UNKNOWN: ${sourceLocation(declaration)}: constructor parameter ${index + 1} of "${declaration.name?.text}" has type "ConfigView<${typeName}>", but no defineConfig<${typeName}>(...) declaration was found. Declare the configuration with an explicit type argument, for example defineConfig<${typeName}>("name", { default: {...} }).`
|
|
800
|
-
: `BAZIS_DI_CONFIG_AMBIGUOUS: ${sourceLocation(declaration)}: constructor parameter ${index + 1} of "${declaration.name?.text}" has type "ConfigView<${typeName}>", which matches several declarations: ${prefixes.map((prefix) => `"${prefix}"`).join(", ")}. Give each declaration its own type
|
|
878
|
+
: `BAZIS_DI_CONFIG_AMBIGUOUS: ${sourceLocation(declaration)}: constructor parameter ${index + 1} of "${declaration.name?.text}" has type "ConfigView<${typeName}>", which matches several declarations: ${prefixes.map((prefix) => `"${prefix}"`).join(", ")}. Give each declaration its own type.`);
|
|
801
879
|
}
|
|
802
880
|
changed = false;
|
|
803
881
|
break;
|
|
@@ -833,7 +911,7 @@ function validateDepsAgainstKnownTokens(): void {
|
|
|
833
911
|
// would fail later, far from the cause. Other classes need no entry.
|
|
834
912
|
if (needsInferredDiDeps(declaration)) {
|
|
835
913
|
fatalErrors.push(declaration.members.some(ts.isConstructorDeclaration)
|
|
836
|
-
? `BAZIS_DI_DEPENDENCY_UNKNOWN: ${sourceLocation(declaration)}: constructor parameter ${index + 1} of "${declaration.name?.text}" has type "${depName}", which is neither a DI token (createToken) nor a class known to codegen. Register it
|
|
914
|
+
? `BAZIS_DI_DEPENDENCY_UNKNOWN: ${sourceLocation(declaration)}: constructor parameter ${index + 1} of "${declaration.name?.text}" has type "${depName}", which is neither a DI token (createToken) nor a class known to codegen. Register it in a module or import it from the framework package.`
|
|
837
915
|
: `BAZIS_DI_CONSTRUCTOR_UNRESOLVED: ${sourceLocation(declaration)}: inherited constructor dependency "${depName}" has no known DI token.`);
|
|
838
916
|
}
|
|
839
917
|
break;
|
|
@@ -847,7 +925,7 @@ function collectClassDeps(source: ts.SourceFile): void {
|
|
|
847
925
|
const result = readConstructorTypeNames(node);
|
|
848
926
|
if (result.unsupportedParameter !== undefined && needsInferredDiDeps(node)) {
|
|
849
927
|
const { index, name, type } = result.unsupportedParameter;
|
|
850
|
-
fatalErrors.push(`BAZIS_DI_DEPENDENCY_UNKNOWN: ${sourceLocation(node)}: constructor parameter ${index + 1} "${name}" of "${node.name.text}" has type "${type}", which cannot be injected: DI resolves dependencies by class, contract or token, and a plain type does not say which value to inject. Declare a token with the same name as a type alias (export type Prefix = string; export const Prefix = createToken<Prefix>("Prefix"))
|
|
928
|
+
fatalErrors.push(`BAZIS_DI_DEPENDENCY_UNKNOWN: ${sourceLocation(node)}: constructor parameter ${index + 1} "${name}" of "${node.name.text}" has type "${type}", which cannot be injected: DI resolves dependencies by class, contract or token, and a plain type does not say which value to inject. Declare a token with the same name as a type alias (export type Prefix = string; export const Prefix = createToken<Prefix>("Prefix")), register a value with singletonValue(Prefix, "…") and type the parameter with it: prefix: Prefix.`);
|
|
851
929
|
}
|
|
852
930
|
if (result.unsupportedInheritedParameter !== undefined && needsInferredDiDeps(node)) {
|
|
853
931
|
fatalErrors.push(`BAZIS_DI_CONSTRUCTOR_UNRESOLVED: ${sourceLocation(node)}: cannot infer inherited constructor parameter "${result.unsupportedInheritedParameter}" for "${node.name.text}". The parameter needs a runtime DI token or an explicit value/factory binding.`);
|
|
@@ -951,6 +1029,96 @@ function collectDiClassRegistrations(source: ts.SourceFile): void {
|
|
|
951
1029
|
visit(source);
|
|
952
1030
|
}
|
|
953
1031
|
|
|
1032
|
+
/**
|
|
1033
|
+
* A module registers its services only in the agreed forms (docs/guide
|
|
1034
|
+
* fundamentals/dependency-injection.md): a class under its contract, a ready
|
|
1035
|
+
* value, an asynchronously created resource, event subscribers. Constructor dependencies come from codegen, so a
|
|
1036
|
+
* dependency list, a factory or a low-level `DI.*` provider is a fatal error
|
|
1037
|
+
* with the agreed form in the message.
|
|
1038
|
+
*/
|
|
1039
|
+
function collectProviderFormErrors(source: ts.SourceFile): void {
|
|
1040
|
+
// Inside the function: the script runs before later top-level constants are initialized.
|
|
1041
|
+
const AGREED_PROVIDERS = "scoped(IService, Service), singleton(IService, Service), transient(IService, Service) (or the class alone), singletonValue(TOKEN, value), singletonAsyncFactory(TOKEN, [deps], async factory) or ...withEventSubscribers(Class)";
|
|
1042
|
+
const CLASS_LISTS = ["controllers", "grpcControllers", "gateways", "background", "tools", "grpcClients", "httpClients"];
|
|
1043
|
+
const callee = (call: ts.CallExpression): { file?: string; name?: string } => {
|
|
1044
|
+
let symbol = checker.getSymbolAtLocation(call.expression);
|
|
1045
|
+
if (symbol && (symbol.flags & ts.SymbolFlags.Alias)) symbol = checker.getAliasedSymbol(symbol);
|
|
1046
|
+
const declaration = symbol?.declarations?.find((entry) => ts.isFunctionDeclaration(entry) || ts.isMethodDeclaration(entry));
|
|
1047
|
+
const name = declaration && "name" in declaration && declaration.name && ts.isIdentifier(declaration.name) ? declaration.name.text : undefined;
|
|
1048
|
+
return { file: declaration?.getSourceFile().fileName.replace(/\\/g, "/"), name };
|
|
1049
|
+
};
|
|
1050
|
+
const resolved = <T extends ts.Node>(expression: ts.Expression, is: (node: ts.Node) => node is T): T | undefined => {
|
|
1051
|
+
let current: ts.Expression = expression;
|
|
1052
|
+
for (let depth = 0; depth < 5; depth++) {
|
|
1053
|
+
if (is(current)) return current;
|
|
1054
|
+
if (ts.isParenthesizedExpression(current) || ts.isAsExpression(current) || ts.isSatisfiesExpression(current)) { current = current.expression; continue; }
|
|
1055
|
+
let symbol = checker.getSymbolAtLocation(current);
|
|
1056
|
+
if (symbol && (symbol.flags & ts.SymbolFlags.Alias)) symbol = checker.getAliasedSymbol(symbol);
|
|
1057
|
+
const declaration = symbol?.valueDeclaration;
|
|
1058
|
+
if (!declaration || !ts.isVariableDeclaration(declaration) || !declaration.initializer) return undefined;
|
|
1059
|
+
current = declaration.initializer;
|
|
1060
|
+
}
|
|
1061
|
+
return undefined;
|
|
1062
|
+
};
|
|
1063
|
+
const text = (node: ts.Node): string => {
|
|
1064
|
+
const value = node.getText().replace(/\s+/g, " ");
|
|
1065
|
+
return value.length > 90 ? `${value.slice(0, 87)}...` : value;
|
|
1066
|
+
};
|
|
1067
|
+
const checkProvider = (module: string, element: ts.Expression): void => {
|
|
1068
|
+
if (ts.isSpreadElement(element)) {
|
|
1069
|
+
const call = resolved(element.expression, ts.isCallExpression);
|
|
1070
|
+
const target = call && callee(call);
|
|
1071
|
+
if (target?.name === "withEventSubscribers" && target.file?.endsWith("/core/kernel/events/eventSubscribers.ts")) return;
|
|
1072
|
+
fatalErrors.push(`BAZIS_DI_PROVIDER_FORM: ${sourceLocation(element)}: providers of ${module}: "${text(element)}" is not an agreed registration. Agreed forms: ${AGREED_PROVIDERS}.`);
|
|
1073
|
+
return;
|
|
1074
|
+
}
|
|
1075
|
+
const call = ts.isCallExpression(element) ? element : undefined;
|
|
1076
|
+
const target = call && callee(call);
|
|
1077
|
+
if (call && target?.file?.endsWith("/core/di/module/shortcuts.ts")) {
|
|
1078
|
+
if (["scoped", "singleton", "transient"].includes(target.name ?? "")) {
|
|
1079
|
+
if (call.arguments.length <= 2) return;
|
|
1080
|
+
fatalErrors.push(`BAZIS_DI_PROVIDER_FORM: ${sourceLocation(element)}: providers of ${module}: "${text(element)}" passes a dependency list. Remove it: codegen reads the constructor. Agreed forms: ${AGREED_PROVIDERS}.`);
|
|
1081
|
+
return;
|
|
1082
|
+
}
|
|
1083
|
+
if (target.name === "singletonValue" && call.arguments.length === 2) return;
|
|
1084
|
+
// A resource that is created asynchronously (a connection): created at startup.
|
|
1085
|
+
if (target.name === "singletonAsyncFactory" && call.arguments.length === 3) return;
|
|
1086
|
+
}
|
|
1087
|
+
fatalErrors.push(`BAZIS_DI_PROVIDER_FORM: ${sourceLocation(element)}: providers of ${module}: "${text(element)}" is not an agreed registration. A computed service is a class with a constructor: scoped(IService, Service). Agreed forms: ${AGREED_PROVIDERS}.`);
|
|
1088
|
+
};
|
|
1089
|
+
const checkModule = (module: string, argument: ts.Expression | undefined): void => {
|
|
1090
|
+
const object = argument && resolved(argument, ts.isObjectLiteralExpression);
|
|
1091
|
+
if (!object) return;
|
|
1092
|
+
for (const property of object.properties) {
|
|
1093
|
+
if (!ts.isPropertyAssignment(property)) continue;
|
|
1094
|
+
const field = property.name.getText().replace(/["']/g, "");
|
|
1095
|
+
if (field !== "providers" && !CLASS_LISTS.includes(field)) continue;
|
|
1096
|
+
const list = resolved(property.initializer, ts.isArrayLiteralExpression);
|
|
1097
|
+
if (!list) {
|
|
1098
|
+
fatalErrors.push(`BAZIS_DI_PROVIDER_FORM: ${sourceLocation(property)}: ${field} of ${module} must be an array written in the module.`);
|
|
1099
|
+
continue;
|
|
1100
|
+
}
|
|
1101
|
+
for (const element of list.elements) {
|
|
1102
|
+
if (field === "providers") checkProvider(module, element);
|
|
1103
|
+
else if (!ts.isIdentifier(element) && !ts.isPropertyAccessExpression(element)) {
|
|
1104
|
+
fatalErrors.push(`BAZIS_DI_PROVIDER_FORM: ${sourceLocation(element)}: ${field} of ${module}: "${text(element)}" — list the class itself; its constructor dependencies come from codegen.`);
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
}
|
|
1108
|
+
};
|
|
1109
|
+
const visit = (node: ts.Node): void => {
|
|
1110
|
+
if (ts.isClassDeclaration(node)) {
|
|
1111
|
+
for (const decorator of ts.getDecorators(node) ?? []) {
|
|
1112
|
+
if (!ts.isCallExpression(decorator.expression)) continue;
|
|
1113
|
+
const target = callee(decorator.expression);
|
|
1114
|
+
if (target.name === "Module" && target.file?.endsWith("/core/di/module/Module.ts")) checkModule(node.name?.text ?? "<anonymous module>", decorator.expression.arguments[0]);
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
ts.forEachChild(node, visit);
|
|
1118
|
+
};
|
|
1119
|
+
visit(source);
|
|
1120
|
+
}
|
|
1121
|
+
|
|
954
1122
|
function hasStaticClassDeps(node: ts.ClassDeclaration): boolean {
|
|
955
1123
|
if (!node.name) return false;
|
|
956
1124
|
const symbol = checker.getSymbolAtLocation(node.name);
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AccessModule } from "../../access";
|
|
2
|
+
import { HOSTED_SERVICE, Module, scoped, singleton } from "../../di";
|
|
2
3
|
import { SystemWorkflowClock, WorkflowClock } from "../contracts/WorkflowClock";
|
|
3
4
|
import { WorkflowTools } from "../internal/WorkflowTools";
|
|
5
|
+
import { definitionsPermissions } from "./access/Definitions.permissions";
|
|
6
|
+
import { ProcessReferences } from "./access/Process.references";
|
|
4
7
|
import { CodeProcessCatalog } from "./code/CodeProcessCatalog";
|
|
5
8
|
import { CodeProcessPublisher } from "./code/CodeProcessPublisher";
|
|
6
|
-
import { codeProcessesOf } from "./code/codeProcesses";
|
|
7
9
|
import { ProcessesController } from "./http/Processes.controller";
|
|
8
10
|
import { DefinitionsDbContext, definitionsStore } from "./model/Definitions.dbContext";
|
|
9
11
|
import { WfProcess } from "./model/WfProcess.model";
|
|
@@ -13,20 +15,22 @@ import { WorkflowDefinitions } from "./services/WorkflowDefinitions.service";
|
|
|
13
15
|
|
|
14
16
|
/**
|
|
15
17
|
* The process catalog: drafts and published versions, and the processes
|
|
16
|
-
* declared in code ([passport](MODULE.md)).
|
|
17
|
-
* framework's classes are not covered by the application's codegen.
|
|
18
|
+
* declared in code ([passport](MODULE.md)).
|
|
18
19
|
*/
|
|
19
20
|
@Module({
|
|
21
|
+
imports: [AccessModule],
|
|
22
|
+
permissions: definitionsPermissions,
|
|
23
|
+
references: { "workflow.process": ProcessReferences },
|
|
20
24
|
ormBazis: { context: DefinitionsDbContext, entities: [WfProcess, WfVersion], ownedStore: definitionsStore, registerRepositories: false },
|
|
21
25
|
providers: [
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
scoped(
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
singleton(WorkflowClock, SystemWorkflowClock),
|
|
27
|
+
singleton(WorkflowTools),
|
|
28
|
+
singleton(CodeProcessCatalog),
|
|
29
|
+
scoped(IWorkflowDefinitions, WorkflowDefinitions),
|
|
30
|
+
scoped(ProcessReferences),
|
|
31
|
+
singleton(HOSTED_SERVICE, CodeProcessPublisher),
|
|
28
32
|
],
|
|
29
|
-
controllers: [
|
|
33
|
+
controllers: [ProcessesController],
|
|
30
34
|
exports: [IWorkflowDefinitions, WorkflowTools, WorkflowClock],
|
|
31
35
|
})
|
|
32
36
|
export class WorkflowDefinitionsModule {}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { definePermissions } from "../../../access";
|
|
2
|
+
|
|
3
|
+
const process = { ref: "workflow.process", column: "key" };
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The rights of the process catalog (WORKFLOW-002 §6.2). A process is one per
|
|
7
|
+
* application, so these have no partition until `WorkflowPartitions` connects
|
|
8
|
+
* processes to partitions (stage 4).
|
|
9
|
+
*/
|
|
10
|
+
export const definitionsPermissions = definePermissions({
|
|
11
|
+
"workflow.processes.read": {
|
|
12
|
+
title: { en: "See processes", ru: "Видеть процессы" },
|
|
13
|
+
on: { process },
|
|
14
|
+
},
|
|
15
|
+
"workflow.processes.manage": {
|
|
16
|
+
title: { en: "Edit processes", ru: "Редактировать процессы" },
|
|
17
|
+
on: { process },
|
|
18
|
+
},
|
|
19
|
+
"workflow.processes.publish": {
|
|
20
|
+
title: { en: "Publish processes", ru: "Публиковать процессы" },
|
|
21
|
+
on: { process },
|
|
22
|
+
},
|
|
23
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { References, type ReferenceItem, type ReferencePage } from "../../../access";
|
|
2
|
+
import type { DefinitionsDbContext } from "../model/Definitions.dbContext";
|
|
3
|
+
|
|
4
|
+
/** Reference kind `workflow.process`: what an administrator picks in a condition. */
|
|
5
|
+
export class ProcessReferences extends References {
|
|
6
|
+
constructor(private readonly db: DefinitionsDbContext) {
|
|
7
|
+
super();
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
async exists(ids: readonly string[]): Promise<ReadonlySet<string>> {
|
|
11
|
+
return new Set((await this.describe(ids)).map((item) => item.id));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
async describe(ids: readonly string[]): Promise<readonly ReferenceItem[]> {
|
|
15
|
+
if (ids.length === 0) return [];
|
|
16
|
+
const rows = await this.db.processes.asNoTracking().where((p) => p.key.in([...ids])).toList();
|
|
17
|
+
return rows.map((row) => ({ id: row.key, title: row.title }));
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async search(text: string, _context: unknown, page: ReferencePage): Promise<readonly ReferenceItem[]> {
|
|
21
|
+
const found = text.trim();
|
|
22
|
+
let source = this.db.processes.asNoTracking();
|
|
23
|
+
if (found !== "") source = source.where((p) => p.key.contains(found, { ignoreCase: true }).or(p.title.contains(found, { ignoreCase: true })));
|
|
24
|
+
const rows = await source.orderBy((p) => p.key).skip(page.offset).take(page.limit).toList();
|
|
25
|
+
return rows.map((row) => ({ id: row.key, title: row.title }));
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ServiceProvider } from "../../../di";
|
|
2
|
+
import { codeProcessesOf, type OwnedCodeProcess } from "./codeProcesses";
|
|
2
3
|
|
|
3
4
|
/** The processes declared in the application's modules, by key: which module owns a key. */
|
|
4
5
|
export class CodeProcessCatalog {
|
|
5
6
|
private readonly byKey: ReadonlyMap<string, OwnedCodeProcess>;
|
|
6
7
|
|
|
7
|
-
constructor(
|
|
8
|
-
this.byKey = new Map([...
|
|
8
|
+
constructor(services: ServiceProvider) {
|
|
9
|
+
this.byKey = new Map([...codeProcessesOf(services)].sort((a, b) => a.process.key.localeCompare(b.process.key)).map((entry) => [entry.process.key, entry]));
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
/** The module whose `processes` declare `key`; `undefined` for a process of the catalog. */
|
|
@@ -2,7 +2,7 @@ import { markConfigurationError, type ServiceProvider } from "../../../di";
|
|
|
2
2
|
import type { HostedService } from "../../../di/extensions/hosted-service";
|
|
3
3
|
import { LOGGER } from "../../../kernel";
|
|
4
4
|
import { WorkflowTools } from "../../internal/WorkflowTools";
|
|
5
|
-
import {
|
|
5
|
+
import { IWorkflowDefinitions } from "../services/IWorkflowDefinitions.service";
|
|
6
6
|
import { CodeProcessCatalog } from "./CodeProcessCatalog";
|
|
7
7
|
import { definitionProblems, WorkflowSetupError } from "./codeProcesses";
|
|
8
8
|
|
|
@@ -30,7 +30,7 @@ export class CodeProcessPublisher implements HostedService {
|
|
|
30
30
|
}
|
|
31
31
|
const scope = this.services.createScope();
|
|
32
32
|
try {
|
|
33
|
-
const results = await scope.resolve(
|
|
33
|
+
const results = await scope.resolve(IWorkflowDefinitions).publishCode(entries);
|
|
34
34
|
this.services.tryResolve(LOGGER)?.info("workflow processes from code", {
|
|
35
35
|
published: results.filter((result) => result.published).map((result) => `${result.key} v${result.version}`),
|
|
36
36
|
unchanged: results.filter((result) => !result.published).map((result) => result.key),
|
|
@@ -1,28 +1,31 @@
|
|
|
1
1
|
import { contextOnlyController } from "../../../http/Routing/contextOnlyControllers";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { can } from "../../../access";
|
|
3
|
+
import { Authorize, Controller, Created, Get, Patch, Post, Put, type HttpContext } from "../../../http";
|
|
4
|
+
import { body, callerOf, optionalInteger, optionalString, pagingQuery, param, requiredString } from "../../internal/http";
|
|
4
5
|
import { WorkflowError } from "../../contracts/WorkflowError";
|
|
5
6
|
import { IWorkflowDefinitions } from "../services/IWorkflowDefinitions.service";
|
|
6
7
|
|
|
7
|
-
/** The process catalog over HTTP (WORKFLOW-001 §3); rights
|
|
8
|
+
/** The process catalog over HTTP (WORKFLOW-001 §3); rights are `workflow.processes.*` (WORKFLOW-002 §6.2). */
|
|
8
9
|
@Controller("workflow")
|
|
9
10
|
export class ProcessesController {
|
|
10
11
|
constructor(private readonly definitions: IWorkflowDefinitions) {}
|
|
11
12
|
|
|
12
13
|
@Get("processes")
|
|
14
|
+
@Authorize(can("workflow.processes.read"))
|
|
13
15
|
async list(ctx: HttpContext) {
|
|
14
|
-
await
|
|
16
|
+
const { access } = await callerOf(ctx);
|
|
15
17
|
const archived = ctx.query("archived");
|
|
16
18
|
if (archived !== undefined && archived !== "true" && archived !== "false") throw new WorkflowError("invalid_input", "archived must be true or false");
|
|
17
|
-
const page = await this.definitions.list({ ...pagingQuery(ctx), archived: archived === undefined ? undefined : archived === "true", search: optionalString(ctx.query("search"), "search") });
|
|
19
|
+
const page = await this.definitions.list({ ...pagingQuery(ctx), access: await access.filter("workflow.processes.read"), archived: archived === undefined ? undefined : archived === "true", search: optionalString(ctx.query("search"), "search") });
|
|
18
20
|
return { data: page.items, meta: { total: page.total } };
|
|
19
21
|
}
|
|
20
22
|
|
|
21
23
|
@Post("processes")
|
|
24
|
+
@Authorize(can("workflow.processes.manage"))
|
|
22
25
|
async create(ctx: HttpContext) {
|
|
23
26
|
const request = await body(ctx);
|
|
24
27
|
const key = requiredString(request.key, "key", 64);
|
|
25
|
-
const actor = await
|
|
28
|
+
const { actor } = await callerOf(ctx, "workflow.processes.manage", { process: key });
|
|
26
29
|
const process = await this.definitions.create({
|
|
27
30
|
key,
|
|
28
31
|
title: requiredString(request.title, "title"),
|
|
@@ -33,17 +36,19 @@ export class ProcessesController {
|
|
|
33
36
|
}
|
|
34
37
|
|
|
35
38
|
@Get("processes/:key")
|
|
39
|
+
@Authorize(can("workflow.processes.read"))
|
|
36
40
|
async get(ctx: HttpContext) {
|
|
37
41
|
const key = param(ctx, "key");
|
|
38
|
-
await
|
|
42
|
+
await callerOf(ctx, "workflow.processes.read", { process: key });
|
|
39
43
|
return await this.definitions.get(key);
|
|
40
44
|
}
|
|
41
45
|
|
|
42
46
|
@Patch("processes/:key")
|
|
47
|
+
@Authorize(can("workflow.processes.manage"))
|
|
43
48
|
async update(ctx: HttpContext) {
|
|
44
49
|
const key = param(ctx, "key");
|
|
45
50
|
const request = await body(ctx);
|
|
46
|
-
const actor = await
|
|
51
|
+
const { actor } = await callerOf(ctx, "workflow.processes.manage", { process: key });
|
|
47
52
|
if (request.archived !== undefined && typeof request.archived !== "boolean") throw new WorkflowError("invalid_input", "archived must be a boolean");
|
|
48
53
|
return await this.definitions.update(key, {
|
|
49
54
|
...(request.title === undefined ? {} : { title: requiredString(request.title, "title") }),
|
|
@@ -54,40 +59,44 @@ export class ProcessesController {
|
|
|
54
59
|
}
|
|
55
60
|
|
|
56
61
|
@Put("processes/:key/draft")
|
|
62
|
+
@Authorize(can("workflow.processes.manage"))
|
|
57
63
|
async saveDraft(ctx: HttpContext) {
|
|
58
64
|
const key = param(ctx, "key");
|
|
59
65
|
const request = await body(ctx);
|
|
60
|
-
const actor = await
|
|
66
|
+
const { actor } = await callerOf(ctx, "workflow.processes.manage", { process: key });
|
|
61
67
|
return await this.definitions.saveDraft(key, request.document, actor);
|
|
62
68
|
}
|
|
63
69
|
|
|
64
70
|
@Post("processes/:key/publish")
|
|
71
|
+
@Authorize(can("workflow.processes.publish"))
|
|
65
72
|
async publish(ctx: HttpContext) {
|
|
66
73
|
const key = param(ctx, "key");
|
|
67
|
-
const actor = await
|
|
74
|
+
const { actor } = await callerOf(ctx, "workflow.processes.publish", { process: key });
|
|
68
75
|
const version = await this.definitions.publish(key, actor);
|
|
69
76
|
return Created(`${ctx.path.replace(/\/publish$/, "")}/versions/${version.version}`, version);
|
|
70
77
|
}
|
|
71
78
|
|
|
72
79
|
@Get("processes/:key/versions")
|
|
80
|
+
@Authorize(can("workflow.processes.read"))
|
|
73
81
|
async versions(ctx: HttpContext) {
|
|
74
82
|
const key = param(ctx, "key");
|
|
75
|
-
await
|
|
83
|
+
await callerOf(ctx, "workflow.processes.read", { process: key });
|
|
76
84
|
return { data: await this.definitions.versions(key) };
|
|
77
85
|
}
|
|
78
86
|
|
|
79
87
|
@Get("processes/:key/versions/:version")
|
|
88
|
+
@Authorize(can("workflow.processes.read"))
|
|
80
89
|
async version(ctx: HttpContext) {
|
|
81
90
|
const key = param(ctx, "key");
|
|
82
|
-
await
|
|
91
|
+
await callerOf(ctx, "workflow.processes.read", { process: key });
|
|
83
92
|
const version = optionalInteger(param(ctx, "version"), "version");
|
|
84
93
|
if (version === undefined) throw new WorkflowError("invalid_input", "version must be an integer");
|
|
85
94
|
return await this.definitions.version(key, version);
|
|
86
95
|
}
|
|
87
96
|
|
|
88
97
|
@Get("tools")
|
|
89
|
-
|
|
90
|
-
|
|
98
|
+
@Authorize(can("workflow.processes.read"))
|
|
99
|
+
async tools() {
|
|
91
100
|
return { data: this.definitions.tools() };
|
|
92
101
|
}
|
|
93
102
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import type { AccessFilter } from "../../../access";
|
|
1
2
|
import type { AgentToolContract } from "../../../agent";
|
|
2
3
|
import type { ProcessDocument, ProcessIssue } from "../../../../library/workflow";
|
|
3
4
|
import type { WorkflowActor, WorkflowPage, WorkflowPaging } from "../../contracts/types";
|
|
5
|
+
import type { OwnedCodeProcess } from "../code/codeProcesses";
|
|
4
6
|
|
|
5
7
|
export interface ProcessSummary {
|
|
6
8
|
readonly key: string;
|
|
@@ -52,6 +54,8 @@ export interface UpdateProcess {
|
|
|
52
54
|
}
|
|
53
55
|
|
|
54
56
|
export interface ProcessListQuery extends WorkflowPaging {
|
|
57
|
+
/** Which processes the caller may see, from `IAccess`; without it the calling code has decided. */
|
|
58
|
+
readonly access?: AccessFilter;
|
|
55
59
|
readonly archived?: boolean;
|
|
56
60
|
/** Part of the key or title, case-insensitive. */
|
|
57
61
|
readonly search?: string;
|
|
@@ -87,4 +91,9 @@ export abstract class IWorkflowDefinitions {
|
|
|
87
91
|
abstract retentionPolicies(): Promise<readonly { readonly key: string; readonly retentionDays: number }[]>;
|
|
88
92
|
/** The Tools a service task may call, with their input and output schemas. */
|
|
89
93
|
abstract tools(): readonly AgentToolContract[];
|
|
94
|
+
/**
|
|
95
|
+
* Publishes the processes of `@Module({ processes })` as `{ kind: "system", id: "code" }`
|
|
96
|
+
* (WORKFLOW-001 §14): called once at start by the framework, not by the application.
|
|
97
|
+
*/
|
|
98
|
+
abstract publishCode(entries: readonly OwnedCodeProcess[]): Promise<readonly { readonly key: string; readonly version: number | null; readonly published: boolean }[]>;
|
|
90
99
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { grantsToWhere } from "../../../access";
|
|
1
2
|
import { createHash } from "node:crypto";
|
|
2
3
|
import { UniqueViolationError } from "../../../orm";
|
|
3
4
|
import type { AgentToolContract } from "../../../agent";
|
|
@@ -38,7 +39,10 @@ export class WorkflowDefinitions extends IWorkflowDefinitions {
|
|
|
38
39
|
|
|
39
40
|
async list(query: ProcessListQuery = {}): Promise<WorkflowPage<ProcessSummary>> {
|
|
40
41
|
const { limit, offset } = pagingOf(query);
|
|
42
|
+
const where = query.access === undefined ? "all" : grantsToWhere(query.access);
|
|
43
|
+
if (where === "none") return { items: [], total: 0 };
|
|
41
44
|
let source = this.db.processes.asNoTracking();
|
|
45
|
+
if (where !== "all") source = source.where(() => where);
|
|
42
46
|
if (query.archived === true) source = source.where((p) => p.archivedAt.isNotNull());
|
|
43
47
|
if (query.archived === false) source = source.where((p) => p.archivedAt.isNull());
|
|
44
48
|
if (query.search !== undefined && query.search.trim() !== "") {
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// This file is auto-generated by `bun run di:generate` (framework.packs of bazis.config.json).
|
|
2
|
+
// Do not edit manually.
|
|
3
|
+
import { registerFrameworkClassDeps } from "../../di/module/autoDeps";
|
|
4
|
+
import { DbContextOptions } from "../../../library/orm/DbContextOptions";
|
|
5
|
+
import { ServiceProvider } from "../../di/ServiceProvider";
|
|
6
|
+
import { EventBus } from "../../kernel/events/EventBus";
|
|
7
|
+
import { WorkflowClock } from "../contracts/WorkflowClock";
|
|
8
|
+
import { ProcessReferences } from "../definitions_module/access/Process.references";
|
|
9
|
+
import { CodeProcessCatalog } from "../definitions_module/code/CodeProcessCatalog";
|
|
10
|
+
import { CodeProcessPublisher } from "../definitions_module/code/CodeProcessPublisher";
|
|
11
|
+
import { ProcessesController } from "../definitions_module/http/Processes.controller";
|
|
12
|
+
import { DefinitionsDbContext } from "../definitions_module/model/Definitions.dbContext";
|
|
13
|
+
import { IWorkflowDefinitions } from "../definitions_module/services/IWorkflowDefinitions.service";
|
|
14
|
+
import { WorkflowDefinitions } from "../definitions_module/services/WorkflowDefinitions.service";
|
|
15
|
+
import { WorkflowTools } from "../internal/WorkflowTools";
|
|
16
|
+
import { WorkflowRetention } from "../runtime_module/background/WorkflowRetention";
|
|
17
|
+
import { WorkflowWorker } from "../runtime_module/background/WorkflowWorker";
|
|
18
|
+
import { EventsController } from "../runtime_module/http/Events.controller";
|
|
19
|
+
import { InstancesController } from "../runtime_module/http/Instances.controller";
|
|
20
|
+
import { GraphCache } from "../runtime_module/internal/GraphCache";
|
|
21
|
+
import { Schedules } from "../runtime_module/internal/Schedules";
|
|
22
|
+
import { TimerStep } from "../runtime_module/internal/TimerStep";
|
|
23
|
+
import { ToolStep } from "../runtime_module/internal/ToolStep";
|
|
24
|
+
import { WorkflowEngine } from "../runtime_module/internal/WorkflowEngine";
|
|
25
|
+
import { RuntimeDbContext } from "../runtime_module/model/Runtime.dbContext";
|
|
26
|
+
import { IWorkflowRuntime } from "../runtime_module/services/IWorkflowRuntime.service";
|
|
27
|
+
import { WorkflowRuntime } from "../runtime_module/services/WorkflowRuntime.service";
|
|
28
|
+
import { TaskEvents } from "../tasks_module/events/TaskEvents";
|
|
29
|
+
import { TasksController } from "../tasks_module/http/Tasks.controller";
|
|
30
|
+
import { TasksDbContext } from "../tasks_module/model/Tasks.dbContext";
|
|
31
|
+
import { IWorkflowTasks } from "../tasks_module/services/IWorkflowTasks.service";
|
|
32
|
+
import { WorkflowTasks } from "../tasks_module/services/WorkflowTasks.service";
|
|
33
|
+
|
|
34
|
+
registerFrameworkClassDeps([
|
|
35
|
+
[CodeProcessCatalog, [ServiceProvider]],
|
|
36
|
+
[CodeProcessPublisher, [ServiceProvider]],
|
|
37
|
+
[DefinitionsDbContext, [DbContextOptions]],
|
|
38
|
+
[EventsController, [IWorkflowRuntime]],
|
|
39
|
+
[InstancesController, [IWorkflowRuntime]],
|
|
40
|
+
[ProcessesController, [IWorkflowDefinitions]],
|
|
41
|
+
[ProcessReferences, [DefinitionsDbContext]],
|
|
42
|
+
[RuntimeDbContext, [DbContextOptions]],
|
|
43
|
+
[Schedules, [RuntimeDbContext, WorkflowEngine, IWorkflowDefinitions]],
|
|
44
|
+
[TaskEvents, [TasksDbContext]],
|
|
45
|
+
[TasksController, [IWorkflowTasks]],
|
|
46
|
+
[TasksDbContext, [DbContextOptions]],
|
|
47
|
+
[TimerStep, [RuntimeDbContext, WorkflowEngine]],
|
|
48
|
+
[ToolStep, [RuntimeDbContext, WorkflowEngine, WorkflowTools]],
|
|
49
|
+
[WorkflowDefinitions, [DefinitionsDbContext, WorkflowTools, CodeProcessCatalog, WorkflowClock]],
|
|
50
|
+
[WorkflowEngine, [RuntimeDbContext, IWorkflowDefinitions, GraphCache, EventBus, ServiceProvider, WorkflowClock, "optional:Logger"]],
|
|
51
|
+
[WorkflowRetention, [ServiceProvider, "Config:workflow"]],
|
|
52
|
+
[WorkflowRuntime, [RuntimeDbContext, WorkflowEngine, IWorkflowDefinitions, ServiceProvider]],
|
|
53
|
+
[WorkflowTasks, [TasksDbContext, IWorkflowRuntime, WorkflowClock]],
|
|
54
|
+
[WorkflowTools, [ServiceProvider]],
|
|
55
|
+
[WorkflowWorker, [ServiceProvider, "Config:workflow"]],
|
|
56
|
+
]);
|