@codemation/host 0.0.5 → 0.0.11
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 +3 -3
- package/dist/{PrismaMigrationDeployer-B7cHGrXP.js → AppConfigFactory-DWIz2hy-.js} +104 -58
- package/dist/AppConfigFactory-DWIz2hy-.js.map +1 -0
- package/dist/{client-Yh7-CQud.d.ts → AppConfigFactory-DmHOpg8O.d.ts} +52 -31
- package/dist/{CodemationFrontendBootstrapRequest-CNEk-C4D.js → AppContainerFactory-B5eRpvAa.js} +3269 -3374
- package/dist/AppContainerFactory-B5eRpvAa.js.map +1 -0
- package/dist/{CodemationWhitelabelConfig-DgbjgtrR.d.ts → CodemationAuthConfig-Bh2cCNCI.d.ts} +32 -2
- package/dist/{CodemationConfig-XCkSV2dj.d.ts → CodemationConfig-D2ULNkec.d.ts} +53 -49
- package/dist/CodemationConfigNormalizer-CBLxXaRV.d.ts +9 -0
- package/dist/{CodemationConsumerConfigLoader-scS_RQMy.js → CodemationConsumerConfigLoader-BBzAr6L_.js} +128 -3
- package/dist/CodemationConsumerConfigLoader-BBzAr6L_.js.map +1 -0
- package/dist/{CodemationConsumerConfigLoader-Dmm2TzAA.d.ts → CodemationConsumerConfigLoader-BLvzcfb7.d.ts} +4 -4
- package/dist/CodemationPluginListMerger-B0-e4CJ6.d.ts +391 -0
- package/dist/{CodemationPluginListMerger-BNmaoXQL.js → CodemationPluginListMerger-DrVOw9KP.js} +18 -10
- package/dist/CodemationPluginListMerger-DrVOw9KP.js.map +1 -0
- package/dist/{CredentialServices-DpDpm8mL.d.ts → CredentialServices-BeuMtqYA.d.ts} +3 -3
- package/dist/{CredentialServices-BKBGe7l3.js → CredentialServices-DNb3CZwW.js} +3 -3
- package/dist/CredentialServices-DNb3CZwW.js.map +1 -0
- package/dist/FrontendAppConfig-D50wjj_n.d.ts +27 -0
- package/dist/{WorkflowViewContracts-DCLpTn25.d.ts → FrontendAppConfigFactory-Bj-DZNlt.d.ts} +29 -2
- package/dist/FrontendAppConfigJsonCodec-1_L7H_Qo.d.ts +20 -0
- package/dist/FrontendAppConfigJsonCodec-nOCQI0ag.js +84 -0
- package/dist/FrontendAppConfigJsonCodec-nOCQI0ag.js.map +1 -0
- package/dist/{LogLevelPolicy-4cq9z0TI.d.ts → LogLevelPolicy-BS_NlAOg.d.ts} +2 -2
- package/dist/{ServerLoggerFactory-BRHxIDS7.js → ServerLoggerFactory-BltIIDfQ.js} +4 -129
- package/dist/ServerLoggerFactory-BltIIDfQ.js.map +1 -0
- package/dist/client.d.ts +5 -3
- package/dist/client.js +2 -1
- package/dist/client.js.map +1 -1
- package/dist/consumer.d.ts +5 -4
- package/dist/consumer.js +4 -4
- package/dist/credentials.d.ts +4 -4
- package/dist/credentials.js +3 -3
- package/dist/devServerSidecar.d.ts +1 -1
- package/dist/{index-Bs4F1IsC.d.ts → index-CkiptHb-.d.ts} +19 -20
- package/dist/index.d.ts +14 -19
- package/dist/index.js +12 -11
- package/dist/nextServer.d.ts +244 -9
- package/dist/nextServer.js +8 -8
- package/dist/persistenceServer-CaehMh3M.d.ts +9 -0
- package/dist/{persistenceServer-8tcM2S48.js → persistenceServer-DVeWUbc3.js} +2 -2
- package/dist/{persistenceServer-8tcM2S48.js.map → persistenceServer-DVeWUbc3.js.map} +1 -1
- package/dist/persistenceServer.d.ts +7 -6
- package/dist/persistenceServer.js +4 -4
- package/dist/{server-Dd65rNm6.js → server-C65z_kqm.js} +47 -17
- package/dist/server-C65z_kqm.js.map +1 -0
- package/dist/{server-BBdsATju.d.ts → server-Dyo8qh4k.d.ts} +23 -4
- package/dist/server.d.ts +12 -9
- package/dist/server.js +11 -10
- package/package.json +11 -6
- package/prisma/migrations/20260315063514_init/migration.sql +16 -16
- package/prisma/migrations/20260316090000_workflow_debugger_overlay/migration.sql +9 -9
- package/prisma/migrations/20260317120000_trigger_state_store/migration.sql +3 -3
- package/prisma/migrations/20260317153000_trigger_setup_state/migration.sql +8 -8
- package/prisma/migrations/20260318110000_credentials_v2/migration.sql +49 -49
- package/prisma/migrations/20260319110000_credential_oauth2_material/migration.sql +28 -28
- package/prisma/migrations/20260319200000_codemation_auth_tables/migration.sql +56 -56
- package/prisma/migrations/20260320140000_user_invites_account_status/migration.sql +20 -20
- package/prisma/migrations/20260325120000_workflow_activation/migration.sql +8 -8
- package/prisma/migrations/migration_lock.toml +3 -3
- package/prisma/schema.prisma +179 -179
- package/prisma.config.ts +15 -2
- package/src/application/commands/WorkflowCommandHandlers.ts +9 -0
- package/src/application/dev/BootRuntimeSnapshotHolder.ts +2 -2
- package/src/application/dev/BootRuntimeSummary.types.ts +2 -2
- package/src/application/queries/WorkflowQueryHandlers.ts +7 -0
- package/src/applicationTokens.ts +1 -1
- package/src/bootstrap/AppContainerFactory.ts +584 -0
- package/src/bootstrap/{PreparedCodemationRuntime.ts → AppContainerLifecycle.ts} +3 -8
- package/src/bootstrap/runtime/AppConfigFactory.ts +155 -30
- package/src/bootstrap/runtime/DatabaseMigrations.ts +18 -0
- package/src/bootstrap/runtime/FrontendRuntime.ts +44 -0
- package/src/bootstrap/runtime/WorkerRuntime.ts +55 -0
- package/src/client.ts +7 -0
- package/src/index.ts +15 -5
- package/src/infrastructure/persistence/PrismaMigrationDeployer.ts +2 -2
- package/src/infrastructure/persistence/SchedulerPersistenceCompatibilityValidator.ts +2 -2
- package/src/infrastructure/scheduler/WorkerRuntimeScheduler.ts +16 -0
- package/src/infrastructure/scheduler/bullmq/BullmqNodeExecutionScheduler.ts +47 -0
- package/src/infrastructure/scheduler/bullmq/BullmqScheduler.ts +33 -0
- package/src/infrastructure/scheduler/bullmq/BullmqWorker.ts +48 -0
- package/src/infrastructure/scheduler/bullmq/RedisConnectionOptionsFactory.ts +48 -0
- package/src/nextServer.ts +12 -3
- package/src/persistenceServer.ts +2 -2
- package/src/presentation/config/AppConfig.ts +25 -1
- package/src/presentation/frontend/CodemationFrontendAuthSnapshot.ts +14 -0
- package/src/presentation/frontend/CodemationFrontendAuthSnapshotFactory.ts +84 -0
- package/src/presentation/frontend/CodemationFrontendAuthSnapshotJsonCodec.ts +58 -0
- package/src/presentation/frontend/FrontendAppConfig.ts +10 -0
- package/src/presentation/frontend/FrontendAppConfigFactory.ts +26 -0
- package/src/presentation/frontend/FrontendAppConfigJsonCodec.ts +58 -0
- package/src/presentation/http/CodemationServerGatewayFactory.ts +22 -16
- package/src/presentation/server/AppConfigLoader.ts +39 -0
- package/src/presentation/server/CodemationConsumerAppResolver.ts +2 -2
- package/src/presentation/server/CodemationConsumerConfigLoader.ts +3 -2
- package/src/server.ts +7 -0
- package/vitest.shared.ts +0 -4
- package/dist/CodemationConsumerConfigLoader-scS_RQMy.js.map +0 -1
- package/dist/CodemationFrontendBootstrapRequest-CNEk-C4D.js.map +0 -1
- package/dist/CodemationPluginListMerger-BNmaoXQL.js.map +0 -1
- package/dist/CodemationPluginListMerger-BRYqEk0y.d.ts +0 -793
- package/dist/CredentialServices-BKBGe7l3.js.map +0 -1
- package/dist/PrismaMigrationDeployer-B7cHGrXP.js.map +0 -1
- package/dist/ServerLoggerFactory-BRHxIDS7.js.map +0 -1
- package/dist/persistenceServer-DPSj_-oU.d.ts +0 -37
- package/dist/server-Dd65rNm6.js.map +0 -1
- package/src/bootstrap/CodemationContainerFactory.ts +0 -310
- package/src/bootstrap/CodemationFrontendBootstrapRequest.ts +0 -16
- package/src/bootstrap/CodemationWorkerBootstrapRequest.ts +0 -19
- package/src/bootstrap/PreparedCodemationRuntimeFactory.ts +0 -308
- package/src/bootstrap/boot/CliRuntimeBootService.ts +0 -27
- package/src/bootstrap/boot/FrontendRuntimeBootService.ts +0 -86
- package/src/bootstrap/boot/WorkerRuntimeBootService.ts +0 -64
- package/src/bootstrap/runtime/ResolvedImplementationSelectionFactory.ts +0 -118
- package/src/codemationApplication.ts +0 -311
- package/src/infrastructure/credentials/FrameworkBuiltinCredentialTypesRegistrar.ts +0 -21
- package/src/infrastructure/persistence/DatabasePersistenceResolver.ts +0 -91
- package/src/infrastructure/persistence/generated/prisma/client.d.ts +0 -1
- package/src/infrastructure/persistence/generated/prisma/default.d.ts +0 -1
- package/src/infrastructure/persistence/generated/prisma/edge.d.ts +0 -1
- package/src/infrastructure/persistence/generated/prisma/index.d.ts +0 -4766
- package/src/infrastructure/persistence/generated/prisma/package.json +0 -144
- package/src/infrastructure/persistence/generated/prisma/query_compiler_fast_bg.wasm +0 -0
- package/src/infrastructure/persistence/generated/prisma/runtime/client.d.ts +0 -3358
- package/src/infrastructure/persistence/generated/prisma/runtime/index-browser.d.ts +0 -90
- package/src/infrastructure/persistence/generated/prisma/schema.prisma +0 -35
- package/src/infrastructure/persistence/generated/prisma/wasm-edge-light-loader.mjs +0 -5
- package/src/infrastructure/persistence/generated/prisma/wasm-worker-loader.mjs +0 -5
- package/src/infrastructure/runtime/WorkerRuntimeScheduler.ts +0 -35
- package/src/presentation/config/CodemationApplicationFacade.ts +0 -5
- /package/dist/{decorate-B-N_5S4p.js → decorate-B0PP651O.js} +0 -0
- /package/dist/{decorateParam-BTcc3KNk.js → decorateParam-DrsXNPuw.js} +0 -0
|
@@ -1,308 +0,0 @@
|
|
|
1
|
-
import type { PGlite } from "@electric-sql/pglite";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import type {
|
|
4
|
-
Container,
|
|
5
|
-
RunEventBus,
|
|
6
|
-
TriggerSetupStateRepository,
|
|
7
|
-
WorkflowExecutionRepository,
|
|
8
|
-
} from "@codemation/core";
|
|
9
|
-
import {
|
|
10
|
-
CoreTokens,
|
|
11
|
-
EventPublishingWorkflowExecutionRepository,
|
|
12
|
-
InMemoryRunEventBus,
|
|
13
|
-
instanceCachingFactory,
|
|
14
|
-
SystemClock,
|
|
15
|
-
} from "@codemation/core";
|
|
16
|
-
import {
|
|
17
|
-
ConfigDrivenOffloadPolicy,
|
|
18
|
-
DefaultDrivingScheduler,
|
|
19
|
-
DefaultExecutionContextFactory,
|
|
20
|
-
InlineDrivingScheduler,
|
|
21
|
-
InMemoryBinaryStorage,
|
|
22
|
-
InMemoryRunDataFactory,
|
|
23
|
-
} from "@codemation/core/bootstrap";
|
|
24
|
-
import { RedisRunEventBus } from "@codemation/eventbus-redis";
|
|
25
|
-
import type { BootRuntimeSummary } from "../application/dev/BootRuntimeSummary.types";
|
|
26
|
-
import { BootRuntimeSnapshotHolder } from "../application/dev/BootRuntimeSnapshotHolder";
|
|
27
|
-
import { ApplicationTokens } from "../applicationTokens";
|
|
28
|
-
import { UserAccountService } from "../domain/users/UserAccountServiceRegistry";
|
|
29
|
-
import type { WorkflowRunRepository } from "../domain/runs/WorkflowRunRepository";
|
|
30
|
-
import type { WorkflowDebuggerOverlayRepository } from "../domain/workflows/WorkflowDebuggerOverlayRepository";
|
|
31
|
-
import type { CodemationAuthConfig } from "../presentation/config/CodemationAuthConfig";
|
|
32
|
-
import type { CodemationApplicationRuntimeConfig } from "../presentation/config/CodemationConfig";
|
|
33
|
-
import type { CodemationWhitelabelConfig } from "../presentation/config/CodemationWhitelabelConfig";
|
|
34
|
-
import { CredentialSessionServiceImpl } from "../domain/credentials/CredentialServices";
|
|
35
|
-
import { LocalFilesystemBinaryStorage } from "../infrastructure/binary/LocalFilesystemBinaryStorageRegistry";
|
|
36
|
-
import {
|
|
37
|
-
InMemoryCredentialStore,
|
|
38
|
-
PrismaCredentialStore,
|
|
39
|
-
} from "../infrastructure/persistence/CredentialPersistenceStore";
|
|
40
|
-
import { InMemoryTriggerSetupStateRepository } from "../infrastructure/persistence/InMemoryTriggerSetupStateRepository";
|
|
41
|
-
import { InMemoryWorkflowActivationRepository } from "../infrastructure/persistence/InMemoryWorkflowActivationRepository";
|
|
42
|
-
import { InMemoryWorkflowDebuggerOverlayRepository } from "../infrastructure/persistence/InMemoryWorkflowDebuggerOverlayRepository";
|
|
43
|
-
import { InMemoryWorkflowRunRepository } from "../infrastructure/persistence/InMemoryWorkflowRunRepository";
|
|
44
|
-
import { PrismaClientFactory } from "../infrastructure/persistence/PrismaClientFactory";
|
|
45
|
-
import { PrismaClient } from "../infrastructure/persistence/generated/prisma-client/client.js";
|
|
46
|
-
import { PrismaTriggerSetupStateRepository } from "../infrastructure/persistence/PrismaTriggerSetupStateRepository";
|
|
47
|
-
import { PrismaWorkflowActivationRepository } from "../infrastructure/persistence/PrismaWorkflowActivationRepository";
|
|
48
|
-
import { PrismaWorkflowDebuggerOverlayRepository } from "../infrastructure/persistence/PrismaWorkflowDebuggerOverlayRepository";
|
|
49
|
-
import { PrismaWorkflowRunRepository } from "../infrastructure/persistence/PrismaWorkflowRunRepository";
|
|
50
|
-
import type { ResolvedDatabasePersistence } from "../infrastructure/persistence/DatabasePersistenceResolver";
|
|
51
|
-
import { AppConfigFactory } from "./runtime/AppConfigFactory";
|
|
52
|
-
import type { ResolvedImplementationSelection } from "./runtime/ResolvedImplementationSelectionFactory";
|
|
53
|
-
import { ResolvedImplementationSelectionFactory } from "./runtime/ResolvedImplementationSelectionFactory";
|
|
54
|
-
import { PreparedCodemationRuntime } from "./PreparedCodemationRuntime";
|
|
55
|
-
import type { AppConfig } from "../presentation/config/AppConfig";
|
|
56
|
-
|
|
57
|
-
type PrismaClientResolution = Readonly<{
|
|
58
|
-
prismaClient: PrismaClient;
|
|
59
|
-
ownedPrismaClient?: PrismaClient;
|
|
60
|
-
ownedPglite?: PGlite;
|
|
61
|
-
}>;
|
|
62
|
-
|
|
63
|
-
type PreparedRuntimePersistence = Readonly<{
|
|
64
|
-
workflowExecutionRepository: WorkflowExecutionRepository;
|
|
65
|
-
triggerSetupStateRepository: TriggerSetupStateRepository;
|
|
66
|
-
workflowRunRepository?: WorkflowRunRepository;
|
|
67
|
-
workflowDebuggerOverlayRepository: WorkflowDebuggerOverlayRepository;
|
|
68
|
-
prismaClient?: PrismaClient;
|
|
69
|
-
ownedPrismaClient?: PrismaClient;
|
|
70
|
-
ownedPglite?: PGlite;
|
|
71
|
-
}>;
|
|
72
|
-
|
|
73
|
-
export class PreparedCodemationRuntimeFactory {
|
|
74
|
-
constructor(
|
|
75
|
-
private readonly implementationSelectionFactory: ResolvedImplementationSelectionFactory = new ResolvedImplementationSelectionFactory(),
|
|
76
|
-
private readonly appConfigFactory: AppConfigFactory = new AppConfigFactory(),
|
|
77
|
-
) {}
|
|
78
|
-
|
|
79
|
-
async prepare(
|
|
80
|
-
args: Readonly<{
|
|
81
|
-
container: Container;
|
|
82
|
-
repoRoot: string;
|
|
83
|
-
consumerRoot: string;
|
|
84
|
-
env: NodeJS.ProcessEnv;
|
|
85
|
-
workflowSources: ReadonlyArray<string>;
|
|
86
|
-
runtimeConfig: CodemationApplicationRuntimeConfig;
|
|
87
|
-
applicationAuthConfig: CodemationAuthConfig | undefined;
|
|
88
|
-
whitelabelConfig: CodemationWhitelabelConfig;
|
|
89
|
-
hasConfiguredCredentialSessionServiceRegistration: boolean;
|
|
90
|
-
}>,
|
|
91
|
-
): Promise<PreparedCodemationRuntime> {
|
|
92
|
-
const usesProvidedPrismaClientOverride = this.hasProvidedPrismaClientOverride(args.container);
|
|
93
|
-
const implementationSelection = this.implementationSelectionFactory.resolve({
|
|
94
|
-
consumerRoot: args.consumerRoot,
|
|
95
|
-
env: args.env,
|
|
96
|
-
runtimeConfig: args.runtimeConfig,
|
|
97
|
-
});
|
|
98
|
-
const runtimeSummary = this.createRuntimeSummary(implementationSelection);
|
|
99
|
-
args.container.resolve(BootRuntimeSnapshotHolder).set(runtimeSummary);
|
|
100
|
-
const eventBus = this.createRunEventBus(implementationSelection);
|
|
101
|
-
const persistence = await this.createRunPersistence(args.container, implementationSelection, eventBus);
|
|
102
|
-
const binaryStorage = this.createBinaryStorage(args.repoRoot);
|
|
103
|
-
const appConfig: AppConfig = this.appConfigFactory.create({
|
|
104
|
-
repoRoot: args.repoRoot,
|
|
105
|
-
consumerRoot: args.consumerRoot,
|
|
106
|
-
env: args.env,
|
|
107
|
-
workflowSources: args.workflowSources,
|
|
108
|
-
runtimeConfig: args.runtimeConfig,
|
|
109
|
-
authConfig: args.applicationAuthConfig,
|
|
110
|
-
whitelabelConfig: args.whitelabelConfig,
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
args.container.registerInstance(CoreTokens.RunEventBus, eventBus);
|
|
114
|
-
args.container.registerInstance(CoreTokens.WorkflowExecutionRepository, persistence.workflowExecutionRepository);
|
|
115
|
-
args.container.registerInstance(CoreTokens.TriggerSetupStateRepository, persistence.triggerSetupStateRepository);
|
|
116
|
-
args.container.registerInstance(CoreTokens.RunDataFactory, new InMemoryRunDataFactory());
|
|
117
|
-
args.container.registerInstance(CoreTokens.BinaryStorage, binaryStorage);
|
|
118
|
-
args.container.registerInstance(
|
|
119
|
-
CoreTokens.ExecutionContextFactory,
|
|
120
|
-
new DefaultExecutionContextFactory(binaryStorage),
|
|
121
|
-
);
|
|
122
|
-
args.container.registerInstance(ApplicationTokens.AppConfig, appConfig);
|
|
123
|
-
args.container.registerInstance(ApplicationTokens.Clock, new SystemClock());
|
|
124
|
-
args.container.registerInstance(ApplicationTokens.CodemationAuthConfig, args.applicationAuthConfig);
|
|
125
|
-
args.container.registerInstance(ApplicationTokens.CodemationWhitelabelConfig, args.whitelabelConfig);
|
|
126
|
-
args.container.registerInstance(ApplicationTokens.WebSocketPort, this.resolveWebSocketPort(args.env));
|
|
127
|
-
args.container.registerInstance(ApplicationTokens.WebSocketBindHost, args.env.CODEMATION_WS_BIND_HOST ?? "0.0.0.0");
|
|
128
|
-
args.container.register(UserAccountService, {
|
|
129
|
-
useFactory: instanceCachingFactory((dependencyContainer) => {
|
|
130
|
-
const prismaClient = dependencyContainer.isRegistered(PrismaClient, true)
|
|
131
|
-
? dependencyContainer.resolve(PrismaClient)
|
|
132
|
-
: undefined;
|
|
133
|
-
return new UserAccountService(
|
|
134
|
-
dependencyContainer.resolve(ApplicationTokens.CodemationAuthConfig),
|
|
135
|
-
prismaClient,
|
|
136
|
-
);
|
|
137
|
-
}),
|
|
138
|
-
});
|
|
139
|
-
args.container.registerInstance(
|
|
140
|
-
ApplicationTokens.WorkflowDebuggerOverlayRepository,
|
|
141
|
-
persistence.workflowDebuggerOverlayRepository,
|
|
142
|
-
);
|
|
143
|
-
if (persistence.workflowRunRepository) {
|
|
144
|
-
args.container.registerInstance(ApplicationTokens.WorkflowRunRepository, persistence.workflowRunRepository);
|
|
145
|
-
}
|
|
146
|
-
if (persistence.prismaClient) {
|
|
147
|
-
args.container.registerInstance(PrismaClient, persistence.prismaClient);
|
|
148
|
-
args.container.registerInstance(ApplicationTokens.PrismaClient, persistence.prismaClient);
|
|
149
|
-
}
|
|
150
|
-
const workflowActivationRepository = persistence.prismaClient
|
|
151
|
-
? args.container.resolve(PrismaWorkflowActivationRepository)
|
|
152
|
-
: args.container.resolve(InMemoryWorkflowActivationRepository);
|
|
153
|
-
args.container.registerInstance(ApplicationTokens.WorkflowActivationRepository, workflowActivationRepository);
|
|
154
|
-
if (implementationSelection.databasePersistence.kind !== "none") {
|
|
155
|
-
args.container.registerInstance(ApplicationTokens.CredentialStore, args.container.resolve(PrismaCredentialStore));
|
|
156
|
-
} else {
|
|
157
|
-
args.container.registerInstance(
|
|
158
|
-
ApplicationTokens.CredentialStore,
|
|
159
|
-
args.container.resolve(InMemoryCredentialStore),
|
|
160
|
-
);
|
|
161
|
-
}
|
|
162
|
-
if (!args.hasConfiguredCredentialSessionServiceRegistration) {
|
|
163
|
-
args.container.register(CoreTokens.CredentialSessionService, {
|
|
164
|
-
useFactory: instanceCachingFactory((dependencyContainer) =>
|
|
165
|
-
dependencyContainer.resolve(CredentialSessionServiceImpl),
|
|
166
|
-
),
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
if (implementationSelection.workerRuntimeScheduler) {
|
|
170
|
-
args.container.registerInstance(
|
|
171
|
-
ApplicationTokens.WorkerRuntimeScheduler,
|
|
172
|
-
implementationSelection.workerRuntimeScheduler,
|
|
173
|
-
);
|
|
174
|
-
}
|
|
175
|
-
this.registerRuntimeNodeActivationScheduler(args.container);
|
|
176
|
-
|
|
177
|
-
return new PreparedCodemationRuntime(
|
|
178
|
-
args.container,
|
|
179
|
-
runtimeSummary,
|
|
180
|
-
implementationSelection,
|
|
181
|
-
usesProvidedPrismaClientOverride,
|
|
182
|
-
persistence.ownedPrismaClient ?? null,
|
|
183
|
-
persistence.ownedPglite ?? null,
|
|
184
|
-
);
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
private createRuntimeSummary(selection: ResolvedImplementationSelection): BootRuntimeSummary {
|
|
188
|
-
return {
|
|
189
|
-
databasePersistence: selection.databasePersistence,
|
|
190
|
-
eventBusKind: selection.eventBusKind,
|
|
191
|
-
queuePrefix: selection.queuePrefix,
|
|
192
|
-
schedulerKind: selection.schedulerKind,
|
|
193
|
-
redisUrl: selection.redisUrl,
|
|
194
|
-
};
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
private createRunEventBus(selection: ResolvedImplementationSelection): RunEventBus {
|
|
198
|
-
if (selection.eventBusKind === "redis") {
|
|
199
|
-
return new RedisRunEventBus(this.requireRedisUrl(selection.redisUrl), selection.queuePrefix);
|
|
200
|
-
}
|
|
201
|
-
return new InMemoryRunEventBus();
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
private async createRunPersistence(
|
|
205
|
-
container: Container,
|
|
206
|
-
selection: ResolvedImplementationSelection,
|
|
207
|
-
eventBus: RunEventBus,
|
|
208
|
-
): Promise<PreparedRuntimePersistence> {
|
|
209
|
-
if (selection.databasePersistence.kind === "none") {
|
|
210
|
-
const workflowRunRepository = container.resolve(InMemoryWorkflowRunRepository);
|
|
211
|
-
return {
|
|
212
|
-
workflowRunRepository,
|
|
213
|
-
triggerSetupStateRepository: container.resolve(InMemoryTriggerSetupStateRepository),
|
|
214
|
-
workflowDebuggerOverlayRepository: container.resolve(InMemoryWorkflowDebuggerOverlayRepository),
|
|
215
|
-
workflowExecutionRepository: new EventPublishingWorkflowExecutionRepository(workflowRunRepository, eventBus),
|
|
216
|
-
};
|
|
217
|
-
}
|
|
218
|
-
const prismaClientResolution = await this.resolveInjectedOrOwnedPrismaClient(
|
|
219
|
-
container,
|
|
220
|
-
selection.databasePersistence,
|
|
221
|
-
);
|
|
222
|
-
const childContainer = container.createChildContainer();
|
|
223
|
-
childContainer.registerInstance(PrismaClient, prismaClientResolution.prismaClient);
|
|
224
|
-
const workflowRunRepository = childContainer.resolve(PrismaWorkflowRunRepository);
|
|
225
|
-
const triggerSetupStateRepository = childContainer.resolve(PrismaTriggerSetupStateRepository);
|
|
226
|
-
const workflowDebuggerOverlayRepository = childContainer.resolve(PrismaWorkflowDebuggerOverlayRepository);
|
|
227
|
-
return {
|
|
228
|
-
prismaClient: prismaClientResolution.prismaClient,
|
|
229
|
-
ownedPrismaClient: prismaClientResolution.ownedPrismaClient,
|
|
230
|
-
ownedPglite: prismaClientResolution.ownedPglite,
|
|
231
|
-
workflowRunRepository,
|
|
232
|
-
triggerSetupStateRepository,
|
|
233
|
-
workflowDebuggerOverlayRepository,
|
|
234
|
-
workflowExecutionRepository: new EventPublishingWorkflowExecutionRepository(workflowRunRepository, eventBus),
|
|
235
|
-
};
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
private hasProvidedPrismaClientOverride(container: Container): boolean {
|
|
239
|
-
return container.isRegistered(PrismaClient, true);
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
private async resolveInjectedOrOwnedPrismaClient(
|
|
243
|
-
container: Container,
|
|
244
|
-
persistence: Exclude<ResolvedDatabasePersistence, Readonly<{ kind: "none" }>>,
|
|
245
|
-
): Promise<PrismaClientResolution> {
|
|
246
|
-
if (this.hasProvidedPrismaClientOverride(container)) {
|
|
247
|
-
return {
|
|
248
|
-
prismaClient: container.resolve(PrismaClient),
|
|
249
|
-
};
|
|
250
|
-
}
|
|
251
|
-
const factory = container.resolve(PrismaClientFactory);
|
|
252
|
-
if (persistence.kind === "postgresql") {
|
|
253
|
-
const prismaClient = factory.createPostgres(persistence.databaseUrl);
|
|
254
|
-
return {
|
|
255
|
-
prismaClient,
|
|
256
|
-
ownedPrismaClient: prismaClient,
|
|
257
|
-
};
|
|
258
|
-
}
|
|
259
|
-
if (persistence.kind !== "pglite") {
|
|
260
|
-
throw new Error("Unexpected database persistence mode for Prisma.");
|
|
261
|
-
}
|
|
262
|
-
const { prismaClient, pglite } = await factory.createPglite(persistence.dataDir);
|
|
263
|
-
return {
|
|
264
|
-
prismaClient,
|
|
265
|
-
ownedPrismaClient: prismaClient,
|
|
266
|
-
ownedPglite: pglite,
|
|
267
|
-
};
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
private registerRuntimeNodeActivationScheduler(container: Container): void {
|
|
271
|
-
container.register(CoreTokens.NodeActivationScheduler, {
|
|
272
|
-
useFactory: instanceCachingFactory((dependencyContainer) => {
|
|
273
|
-
const inlineScheduler = dependencyContainer.resolve(InlineDrivingScheduler);
|
|
274
|
-
if (!dependencyContainer.isRegistered(ApplicationTokens.WorkerRuntimeScheduler, true)) {
|
|
275
|
-
return inlineScheduler;
|
|
276
|
-
}
|
|
277
|
-
return new DefaultDrivingScheduler(
|
|
278
|
-
new ConfigDrivenOffloadPolicy(),
|
|
279
|
-
dependencyContainer.resolve(ApplicationTokens.WorkerRuntimeScheduler),
|
|
280
|
-
inlineScheduler,
|
|
281
|
-
);
|
|
282
|
-
}),
|
|
283
|
-
});
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
private createBinaryStorage(repoRoot: string): InMemoryBinaryStorage | LocalFilesystemBinaryStorage {
|
|
287
|
-
if (!repoRoot) {
|
|
288
|
-
return new InMemoryBinaryStorage();
|
|
289
|
-
}
|
|
290
|
-
return new LocalFilesystemBinaryStorage(path.join(repoRoot, ".codemation", "binary"));
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
private requireRedisUrl(redisUrl: string | undefined): string {
|
|
294
|
-
if (!redisUrl) {
|
|
295
|
-
throw new Error("Redis-backed runtime requires runtime.eventBus.redisUrl or REDIS_URL.");
|
|
296
|
-
}
|
|
297
|
-
return redisUrl;
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
private resolveWebSocketPort(env: Readonly<NodeJS.ProcessEnv>): number {
|
|
301
|
-
const rawPort = env.CODEMATION_WS_PORT ?? env.VITE_CODEMATION_WS_PORT;
|
|
302
|
-
const parsedPort = Number(rawPort);
|
|
303
|
-
if (Number.isInteger(parsedPort) && parsedPort > 0) {
|
|
304
|
-
return parsedPort;
|
|
305
|
-
}
|
|
306
|
-
return 3001;
|
|
307
|
-
}
|
|
308
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { PrismaMigrationDeployer } from "../../infrastructure/persistence/PrismaMigrationDeployer";
|
|
2
|
-
import { RuntimeWorkflowActivationPolicy } from "../../infrastructure/persistence/RuntimeWorkflowActivationPolicy";
|
|
3
|
-
import { ApplicationTokens } from "../../applicationTokens";
|
|
4
|
-
import { PreparedCodemationRuntime } from "../PreparedCodemationRuntime";
|
|
5
|
-
|
|
6
|
-
export class CliRuntimeBootService {
|
|
7
|
-
async boot(args: Readonly<{ preparedRuntime: PreparedCodemationRuntime }>): Promise<void> {
|
|
8
|
-
await this.applyDatabaseMigrations(args.preparedRuntime);
|
|
9
|
-
await args.preparedRuntime.container
|
|
10
|
-
.resolve(RuntimeWorkflowActivationPolicy)
|
|
11
|
-
.hydrateFromRepository(args.preparedRuntime.container.resolve(ApplicationTokens.WorkflowActivationRepository));
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
private async applyDatabaseMigrations(preparedRuntime: PreparedCodemationRuntime): Promise<void> {
|
|
15
|
-
const appConfig = preparedRuntime.container.resolve(ApplicationTokens.AppConfig);
|
|
16
|
-
if (
|
|
17
|
-
preparedRuntime.implementationSelection.databasePersistence.kind === "none" ||
|
|
18
|
-
preparedRuntime.usesProvidedPrismaClientOverride ||
|
|
19
|
-
appConfig.env.CODEMATION_SKIP_STARTUP_MIGRATIONS === "true"
|
|
20
|
-
) {
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
await preparedRuntime.container
|
|
24
|
-
.resolve(PrismaMigrationDeployer)
|
|
25
|
-
.deployPersistence(preparedRuntime.implementationSelection.databasePersistence, appConfig.env);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import { CoreTokens } from "@codemation/core";
|
|
2
|
-
import { instanceCachingFactory } from "@codemation/core";
|
|
3
|
-
import { Engine } from "@codemation/core/bootstrap";
|
|
4
|
-
import { PrismaMigrationDeployer } from "../../infrastructure/persistence/PrismaMigrationDeployer";
|
|
5
|
-
import { RuntimeWorkflowActivationPolicy } from "../../infrastructure/persistence/RuntimeWorkflowActivationPolicy";
|
|
6
|
-
import { DevelopmentSessionBypassVerifier } from "../../infrastructure/auth/DevelopmentSessionBypassVerifier";
|
|
7
|
-
import { AuthJsSessionVerifier } from "../../infrastructure/auth/AuthJsSessionVerifier";
|
|
8
|
-
import { ApplicationTokens } from "../../applicationTokens";
|
|
9
|
-
import { WorkflowRunEventWebsocketRelay } from "../../application/websocket/WorkflowRunEventWebsocketRelay";
|
|
10
|
-
import { ApiPaths } from "../../presentation/http/ApiPaths";
|
|
11
|
-
import { WorkflowWebsocketServer } from "../../presentation/websocket/WorkflowWebsocketServer";
|
|
12
|
-
import { PreparedCodemationRuntime } from "../PreparedCodemationRuntime";
|
|
13
|
-
|
|
14
|
-
export class FrontendRuntimeBootService {
|
|
15
|
-
async boot(
|
|
16
|
-
args: Readonly<{
|
|
17
|
-
preparedRuntime: PreparedCodemationRuntime;
|
|
18
|
-
skipPresentationServers?: boolean;
|
|
19
|
-
}>,
|
|
20
|
-
): Promise<void> {
|
|
21
|
-
await this.applyDatabaseMigrations(args.preparedRuntime);
|
|
22
|
-
await this.hydrateWorkflowActivationPolicy(args.preparedRuntime);
|
|
23
|
-
this.registerSessionVerification(args.preparedRuntime);
|
|
24
|
-
args.preparedRuntime.container.registerInstance(CoreTokens.WebhookBasePath, ApiPaths.webhooks());
|
|
25
|
-
if (args.skipPresentationServers === true) {
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
const workflowRepository = args.preparedRuntime.container.resolve(CoreTokens.WorkflowRepository);
|
|
29
|
-
await args.preparedRuntime.container.resolve(Engine).start([...workflowRepository.list()]);
|
|
30
|
-
await args.preparedRuntime.container.resolve(WorkflowWebsocketServer).start();
|
|
31
|
-
await args.preparedRuntime.container.resolve(WorkflowRunEventWebsocketRelay).start();
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
private async applyDatabaseMigrations(preparedRuntime: PreparedCodemationRuntime): Promise<void> {
|
|
35
|
-
const appConfig = preparedRuntime.container.resolve(ApplicationTokens.AppConfig);
|
|
36
|
-
if (
|
|
37
|
-
preparedRuntime.implementationSelection.databasePersistence.kind === "none" ||
|
|
38
|
-
preparedRuntime.usesProvidedPrismaClientOverride ||
|
|
39
|
-
appConfig.env.CODEMATION_SKIP_STARTUP_MIGRATIONS === "true"
|
|
40
|
-
) {
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
await preparedRuntime.container
|
|
44
|
-
.resolve(PrismaMigrationDeployer)
|
|
45
|
-
.deployPersistence(preparedRuntime.implementationSelection.databasePersistence, appConfig.env);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
private async hydrateWorkflowActivationPolicy(preparedRuntime: PreparedCodemationRuntime): Promise<void> {
|
|
49
|
-
await preparedRuntime.container
|
|
50
|
-
.resolve(RuntimeWorkflowActivationPolicy)
|
|
51
|
-
.hydrateFromRepository(preparedRuntime.container.resolve(ApplicationTokens.WorkflowActivationRepository));
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
private registerSessionVerification(preparedRuntime: PreparedCodemationRuntime): void {
|
|
55
|
-
const appConfig = preparedRuntime.container.resolve(ApplicationTokens.AppConfig);
|
|
56
|
-
const env = appConfig.env;
|
|
57
|
-
const authConfig = appConfig.auth;
|
|
58
|
-
const isProduction = env.NODE_ENV === "production";
|
|
59
|
-
if (isProduction && !authConfig) {
|
|
60
|
-
throw new Error("CodemationConfig.auth is required when NODE_ENV is production.");
|
|
61
|
-
}
|
|
62
|
-
if (isProduction && authConfig?.allowUnauthenticatedInDevelopment === true) {
|
|
63
|
-
throw new Error(
|
|
64
|
-
"CodemationAuthConfig.allowUnauthenticatedInDevelopment is not allowed when NODE_ENV is production.",
|
|
65
|
-
);
|
|
66
|
-
}
|
|
67
|
-
const bypassAllowed = !isProduction && authConfig?.allowUnauthenticatedInDevelopment === true;
|
|
68
|
-
if (bypassAllowed) {
|
|
69
|
-
preparedRuntime.container.register(ApplicationTokens.SessionVerifier, {
|
|
70
|
-
useFactory: instanceCachingFactory((dependencyContainer) =>
|
|
71
|
-
dependencyContainer.resolve(DevelopmentSessionBypassVerifier),
|
|
72
|
-
),
|
|
73
|
-
});
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
const secret = env.AUTH_SECRET ?? "";
|
|
77
|
-
if (!secret) {
|
|
78
|
-
throw new Error(
|
|
79
|
-
"AUTH_SECRET is required unless CodemationAuthConfig.allowUnauthenticatedInDevelopment is enabled in a non-production environment.",
|
|
80
|
-
);
|
|
81
|
-
}
|
|
82
|
-
preparedRuntime.container.register(ApplicationTokens.SessionVerifier, {
|
|
83
|
-
useFactory: instanceCachingFactory((dependencyContainer) => dependencyContainer.resolve(AuthJsSessionVerifier)),
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
}
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { CoreTokens } from "@codemation/core";
|
|
2
|
-
import { Engine } from "@codemation/core/bootstrap";
|
|
3
|
-
import type { WorkerRuntimeHandle } from "../../infrastructure/runtime/WorkerRuntimeScheduler";
|
|
4
|
-
import { PrismaMigrationDeployer } from "../../infrastructure/persistence/PrismaMigrationDeployer";
|
|
5
|
-
import { RuntimeWorkflowActivationPolicy } from "../../infrastructure/persistence/RuntimeWorkflowActivationPolicy";
|
|
6
|
-
import { ApplicationTokens } from "../../applicationTokens";
|
|
7
|
-
import { ApiPaths } from "../../presentation/http/ApiPaths";
|
|
8
|
-
import { PreparedCodemationRuntime } from "../PreparedCodemationRuntime";
|
|
9
|
-
|
|
10
|
-
export class WorkerRuntimeBootService {
|
|
11
|
-
async boot(
|
|
12
|
-
args: Readonly<{
|
|
13
|
-
preparedRuntime: PreparedCodemationRuntime;
|
|
14
|
-
queues: ReadonlyArray<string>;
|
|
15
|
-
}>,
|
|
16
|
-
): Promise<Readonly<{ stop: () => Promise<void> }>> {
|
|
17
|
-
await this.applyDatabaseMigrations(args.preparedRuntime);
|
|
18
|
-
await args.preparedRuntime.container
|
|
19
|
-
.resolve(RuntimeWorkflowActivationPolicy)
|
|
20
|
-
.hydrateFromRepository(args.preparedRuntime.container.resolve(ApplicationTokens.WorkflowActivationRepository));
|
|
21
|
-
args.preparedRuntime.container.registerInstance(CoreTokens.WebhookBasePath, ApiPaths.webhooks());
|
|
22
|
-
if (!args.preparedRuntime.container.isRegistered(ApplicationTokens.WorkerRuntimeScheduler, true)) {
|
|
23
|
-
throw new Error("Worker mode requires a BullMQ scheduler backed by a Redis event bus.");
|
|
24
|
-
}
|
|
25
|
-
const workflows = args.preparedRuntime.container.resolve(CoreTokens.WorkflowRepository).list();
|
|
26
|
-
const engine = args.preparedRuntime.container.resolve(Engine);
|
|
27
|
-
await engine.start([...workflows]);
|
|
28
|
-
const workflowsById = new Map(workflows.map((workflow) => [workflow.id, workflow] as const));
|
|
29
|
-
const scheduler = args.preparedRuntime.container.resolve(ApplicationTokens.WorkerRuntimeScheduler);
|
|
30
|
-
const executionLimitsPolicy = args.preparedRuntime.container.resolve(CoreTokens.EngineExecutionLimitsPolicy);
|
|
31
|
-
const worker: WorkerRuntimeHandle = scheduler.createWorker({
|
|
32
|
-
queues: args.queues,
|
|
33
|
-
workflowsById,
|
|
34
|
-
nodeResolver: args.preparedRuntime.container.resolve(CoreTokens.NodeResolver),
|
|
35
|
-
credentialSessions: args.preparedRuntime.container.resolve(CoreTokens.CredentialSessionService),
|
|
36
|
-
workflowExecutionRepository: args.preparedRuntime.container.resolve(CoreTokens.WorkflowExecutionRepository),
|
|
37
|
-
continuation: engine,
|
|
38
|
-
binaryStorage: args.preparedRuntime.container.resolve(CoreTokens.BinaryStorage),
|
|
39
|
-
workflows: args.preparedRuntime.container.resolve(CoreTokens.WorkflowRunnerService),
|
|
40
|
-
executionLimitsPolicy,
|
|
41
|
-
});
|
|
42
|
-
return {
|
|
43
|
-
stop: async () => {
|
|
44
|
-
await worker.stop();
|
|
45
|
-
await scheduler.close();
|
|
46
|
-
await args.preparedRuntime.stop({ stopWebsocketServer: false });
|
|
47
|
-
},
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
private async applyDatabaseMigrations(preparedRuntime: PreparedCodemationRuntime): Promise<void> {
|
|
52
|
-
const appConfig = preparedRuntime.container.resolve(ApplicationTokens.AppConfig);
|
|
53
|
-
if (
|
|
54
|
-
preparedRuntime.implementationSelection.databasePersistence.kind === "none" ||
|
|
55
|
-
preparedRuntime.usesProvidedPrismaClientOverride ||
|
|
56
|
-
appConfig.env.CODEMATION_SKIP_STARTUP_MIGRATIONS === "true"
|
|
57
|
-
) {
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
await preparedRuntime.container
|
|
61
|
-
.resolve(PrismaMigrationDeployer)
|
|
62
|
-
.deployPersistence(preparedRuntime.implementationSelection.databasePersistence, appConfig.env);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
import { BullmqScheduler } from "@codemation/queue-bullmq";
|
|
2
|
-
import type { WorkerRuntimeScheduler } from "../../infrastructure/runtime/WorkerRuntimeScheduler";
|
|
3
|
-
import type { ResolvedDatabasePersistence } from "../../infrastructure/persistence/DatabasePersistenceResolver";
|
|
4
|
-
import { DatabasePersistenceResolver } from "../../infrastructure/persistence/DatabasePersistenceResolver";
|
|
5
|
-
import { SchedulerPersistenceCompatibilityValidator } from "../../infrastructure/persistence/SchedulerPersistenceCompatibilityValidator";
|
|
6
|
-
import type {
|
|
7
|
-
CodemationApplicationRuntimeConfig,
|
|
8
|
-
CodemationEventBusKind,
|
|
9
|
-
CodemationSchedulerKind,
|
|
10
|
-
} from "../../presentation/config/CodemationConfig";
|
|
11
|
-
|
|
12
|
-
export type ResolvedImplementationSelection = Readonly<{
|
|
13
|
-
databasePersistence: ResolvedDatabasePersistence;
|
|
14
|
-
eventBusKind: CodemationEventBusKind;
|
|
15
|
-
queuePrefix: string;
|
|
16
|
-
redisUrl?: string;
|
|
17
|
-
schedulerKind: CodemationSchedulerKind;
|
|
18
|
-
workerRuntimeScheduler?: WorkerRuntimeScheduler;
|
|
19
|
-
}>;
|
|
20
|
-
|
|
21
|
-
export class ResolvedImplementationSelectionFactory {
|
|
22
|
-
constructor(
|
|
23
|
-
private readonly databasePersistenceResolver: DatabasePersistenceResolver = new DatabasePersistenceResolver(),
|
|
24
|
-
private readonly schedulerPersistenceCompatibilityValidator: SchedulerPersistenceCompatibilityValidator = new SchedulerPersistenceCompatibilityValidator(),
|
|
25
|
-
) {}
|
|
26
|
-
|
|
27
|
-
resolve(
|
|
28
|
-
args: Readonly<{
|
|
29
|
-
consumerRoot: string;
|
|
30
|
-
runtimeConfig: CodemationApplicationRuntimeConfig;
|
|
31
|
-
env: Readonly<NodeJS.ProcessEnv>;
|
|
32
|
-
}>,
|
|
33
|
-
): ResolvedImplementationSelection {
|
|
34
|
-
const databasePersistence = this.databasePersistenceResolver.resolve({
|
|
35
|
-
runtimeConfig: args.runtimeConfig,
|
|
36
|
-
env: args.env,
|
|
37
|
-
consumerRoot: args.consumerRoot,
|
|
38
|
-
});
|
|
39
|
-
const redisUrl = args.runtimeConfig.eventBus?.redisUrl ?? args.env.REDIS_URL;
|
|
40
|
-
const schedulerKind = this.resolveSchedulerKind(args.runtimeConfig, args.env, redisUrl);
|
|
41
|
-
const eventBusKind = this.resolveEventBusKind(args.runtimeConfig, args.env, schedulerKind, redisUrl);
|
|
42
|
-
const queuePrefix =
|
|
43
|
-
args.runtimeConfig.scheduler?.queuePrefix ??
|
|
44
|
-
args.runtimeConfig.eventBus?.queuePrefix ??
|
|
45
|
-
args.env.QUEUE_PREFIX ??
|
|
46
|
-
"codemation";
|
|
47
|
-
if (schedulerKind === "bullmq" && eventBusKind !== "redis") {
|
|
48
|
-
throw new Error(
|
|
49
|
-
"BullMQ scheduling requires a Redis event bus so worker events can be forwarded to connected clients.",
|
|
50
|
-
);
|
|
51
|
-
}
|
|
52
|
-
if (eventBusKind === "redis" && !redisUrl) {
|
|
53
|
-
throw new Error("Redis event bus requires runtime.eventBus.redisUrl or REDIS_URL.");
|
|
54
|
-
}
|
|
55
|
-
this.schedulerPersistenceCompatibilityValidator.validate({ schedulerKind, persistence: databasePersistence });
|
|
56
|
-
const workerRuntimeScheduler =
|
|
57
|
-
schedulerKind === "bullmq"
|
|
58
|
-
? new BullmqScheduler({ url: this.requireRedisUrl(redisUrl) }, queuePrefix)
|
|
59
|
-
: undefined;
|
|
60
|
-
return {
|
|
61
|
-
databasePersistence,
|
|
62
|
-
eventBusKind,
|
|
63
|
-
queuePrefix,
|
|
64
|
-
redisUrl,
|
|
65
|
-
schedulerKind,
|
|
66
|
-
workerRuntimeScheduler,
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
private resolveSchedulerKind(
|
|
71
|
-
runtimeConfig: CodemationApplicationRuntimeConfig,
|
|
72
|
-
env: Readonly<NodeJS.ProcessEnv>,
|
|
73
|
-
redisUrl: string | undefined,
|
|
74
|
-
): CodemationSchedulerKind {
|
|
75
|
-
const configuredKind = runtimeConfig.scheduler?.kind ?? this.readSchedulerKind(env.CODEMATION_SCHEDULER);
|
|
76
|
-
if (configuredKind) {
|
|
77
|
-
return configuredKind;
|
|
78
|
-
}
|
|
79
|
-
return redisUrl ? "bullmq" : "local";
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
private resolveEventBusKind(
|
|
83
|
-
runtimeConfig: CodemationApplicationRuntimeConfig,
|
|
84
|
-
env: Readonly<NodeJS.ProcessEnv>,
|
|
85
|
-
schedulerKind: CodemationSchedulerKind,
|
|
86
|
-
redisUrl: string | undefined,
|
|
87
|
-
): CodemationEventBusKind {
|
|
88
|
-
const configuredKind = runtimeConfig.eventBus?.kind ?? this.readEventBusKind(env.CODEMATION_EVENT_BUS);
|
|
89
|
-
if (configuredKind) {
|
|
90
|
-
return configuredKind;
|
|
91
|
-
}
|
|
92
|
-
if (schedulerKind === "bullmq") {
|
|
93
|
-
return "redis";
|
|
94
|
-
}
|
|
95
|
-
return redisUrl ? "redis" : "memory";
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
private readSchedulerKind(value: string | undefined): CodemationSchedulerKind | undefined {
|
|
99
|
-
if (value === "local" || value === "bullmq") {
|
|
100
|
-
return value;
|
|
101
|
-
}
|
|
102
|
-
return undefined;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
private readEventBusKind(value: string | undefined): CodemationEventBusKind | undefined {
|
|
106
|
-
if (value === "memory" || value === "redis") {
|
|
107
|
-
return value;
|
|
108
|
-
}
|
|
109
|
-
return undefined;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
private requireRedisUrl(redisUrl: string | undefined): string {
|
|
113
|
-
if (!redisUrl) {
|
|
114
|
-
throw new Error("Redis-backed runtime requires runtime.eventBus.redisUrl or REDIS_URL.");
|
|
115
|
-
}
|
|
116
|
-
return redisUrl;
|
|
117
|
-
}
|
|
118
|
-
}
|