blokctl 1.1.0 → 1.3.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/dist/commands/create/project.d.ts +5 -0
- package/dist/commands/create/project.js +164 -27
- package/dist/commands/create/utils/Examples.d.ts +4 -4
- package/dist/commands/create/utils/Examples.js +77 -105
- package/dist/commands/create/workflow.js +8 -6
- package/dist/commands/dev/index.js +39 -1
- package/dist/commands/install/node.d.ts +1 -0
- package/dist/commands/install/node.js +3 -39
- package/dist/commands/migrate/index.js +25 -0
- package/dist/commands/migrate/nodesTs.d.ts +31 -0
- package/dist/commands/migrate/nodesTs.js +484 -0
- package/dist/commands/migrate/refs.d.ts +15 -0
- package/dist/commands/migrate/refs.js +706 -0
- package/dist/commands/nodes/index.js +10 -0
- package/dist/commands/nodes/listNodes.d.ts +2 -0
- package/dist/commands/nodes/listNodes.js +20 -15
- package/dist/commands/nodes/syncNodes.d.ts +7 -0
- package/dist/commands/nodes/syncNodes.js +138 -0
- package/dist/commands/nodes/syncNodes.test.d.ts +1 -0
- package/dist/commands/nodes/syncNodes.test.js +322 -0
- package/dist/commands/publish/workflow.d.ts +1 -0
- package/dist/commands/publish/workflow.js +9 -0
- package/dist/commands/publish/workflow.test.d.ts +1 -0
- package/dist/commands/publish/workflow.test.js +22 -0
- package/dist/commands/runtime/add.js +92 -29
- package/dist/commands/runtime/index.js +1 -0
- package/dist/services/observability-stack.real-prometheus.test.d.ts +1 -0
- package/dist/services/observability-stack.real-prometheus.test.js +95 -0
- package/dist/services/observability-stack.real-tempo.test.d.ts +1 -0
- package/dist/services/observability-stack.real-tempo.test.js +86 -0
- package/dist/services/runtime-detector.d.ts +2 -0
- package/dist/services/runtime-detector.js +35 -11
- package/dist/services/runtime-setup.d.ts +1 -0
- package/dist/services/runtime-setup.js +17 -7
- package/dist/studio-dist/assets/index-QEvKRE4T.js +42 -0
- package/dist/studio-dist/index.html +1 -1
- package/package.json +3 -2
- package/dist/studio-dist/assets/index-CnFqCRQe.js +0 -42
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import type { OptionValues } from "commander";
|
|
2
2
|
export declare function createProject(opts: OptionValues, version: string, currentPath?: boolean, localRepoPath?: string): Promise<void>;
|
|
3
|
+
export declare function generateSharedNodesFile(_triggers: string[], _repoSource: string): string;
|
|
4
|
+
export declare function generateSharedWorkflowsFile(triggers: string[], runtimeKinds?: string[], examples?: boolean): string;
|
|
5
|
+
export declare function generateTriggerEntryFile(triggerKind: string, selectedTriggers?: string[]): string;
|
|
6
|
+
export declare function generateCronExampleWorkflowFile(): string;
|
|
7
|
+
export declare function generateCronServerFile(): string;
|
|
3
8
|
export declare function updateQueueProvider(triggerDestDir: string, provider: string, explicit: boolean): void;
|
|
4
9
|
export declare function getProviderDependencies(triggers: string[], pubsubProvider: string, queueProvider: string, explicitQueueProvider?: boolean): Record<string, string>;
|
|
5
10
|
export declare function getProviderEnvVars(triggers: string[], pubsubProvider: string, queueProvider: string, explicitQueueProvider?: boolean): string;
|
|
@@ -14,7 +14,7 @@ import { rewriteObservabilityEnvBlock } from "../../services/observability-mutat
|
|
|
14
14
|
import { manager as pm } from "../../services/package-manager.js";
|
|
15
15
|
import { detectRuntimes } from "../../services/runtime-detector.js";
|
|
16
16
|
import { createTriggerConfig, generateRuntimeEnvVars, generateSupervisordConfig, generateTriggerEnvVars, generateTriggerSupervisordConfig, setupRuntime, writeProjectConfig, } from "../../services/runtime-setup.js";
|
|
17
|
-
import { computeDefaultConstraint } from "../../services/semver-utils.js";
|
|
17
|
+
import { computeDefaultConstraint, formatVersionMismatch, satisfiesConstraint } from "../../services/semver-utils.js";
|
|
18
18
|
import { resolveObservabilitySelection } from "../observability/apply.js";
|
|
19
19
|
import { OBSERVABILITY_MODULE_IDS, allObservabilityModules, getObservabilityModule, } from "../observability/descriptor.js";
|
|
20
20
|
import { agents_md, claude_md, examples_url, node_file, package_dependencies, package_dev_dependencies, } from "./utils/Examples.js";
|
|
@@ -22,7 +22,7 @@ const exec = util.promisify(child_process.exec);
|
|
|
22
22
|
const HOME_DIR = `${os.homedir()}/.blok`;
|
|
23
23
|
const GITHUB_REPO_LOCAL = `${HOME_DIR}/blok`;
|
|
24
24
|
const GITHUB_REPO_REMOTE = "https://github.com/well-prado/blok.git";
|
|
25
|
-
const GITHUB_REPO_RELEASE_TAG = "v1.
|
|
25
|
+
const GITHUB_REPO_RELEASE_TAG = "v1.3.0";
|
|
26
26
|
const RUNTIME_HELLO_EXAMPLES = {
|
|
27
27
|
go: "runtime-go-hello.ts",
|
|
28
28
|
rust: "runtime-rust-hello.ts",
|
|
@@ -55,7 +55,7 @@ export async function createProject(opts, version, currentPath = false, localRep
|
|
|
55
55
|
let examples = opts.examples ?? false;
|
|
56
56
|
let selectedRuntimeKinds = opts.runtimes ? parseCommaSeparated(opts.runtimes) : ["node"];
|
|
57
57
|
let selectedManager = opts.packageManager || "npm";
|
|
58
|
-
let pubsubProvider = opts.pubsubProvider || "
|
|
58
|
+
let pubsubProvider = opts.pubsubProvider || "nats";
|
|
59
59
|
let queueProvider = opts.queueProvider || "kafka";
|
|
60
60
|
let explicitQueueProvider = Boolean(opts.queueProvider);
|
|
61
61
|
let selectedObsTier = opts.obsStack ? parseObsTier(opts.obsStack) : "none";
|
|
@@ -154,6 +154,7 @@ export async function createProject(opts, version, currentPath = false, localRep
|
|
|
154
154
|
? p.select({
|
|
155
155
|
message: "Select Pub/Sub provider",
|
|
156
156
|
options: [
|
|
157
|
+
{ label: "NATS (local, zero cloud setup)", value: "nats" },
|
|
157
158
|
{ label: "Google Cloud Pub/Sub", value: "gcp" },
|
|
158
159
|
{ label: "AWS SNS/SQS", value: "aws" },
|
|
159
160
|
{ label: "Azure Service Bus", value: "azure" },
|
|
@@ -212,7 +213,7 @@ export async function createProject(opts, version, currentPath = false, localRep
|
|
|
212
213
|
});
|
|
213
214
|
projectName = blokctlProject.projectName;
|
|
214
215
|
selectedTriggers = blokctlProject.triggers;
|
|
215
|
-
pubsubProvider = blokctlProject.pubsubProvider || "
|
|
216
|
+
pubsubProvider = blokctlProject.pubsubProvider || "nats";
|
|
216
217
|
explicitQueueProvider = blokctlProject.queueProvider != null;
|
|
217
218
|
queueProvider = blokctlProject.queueProvider || "kafka";
|
|
218
219
|
selectedRuntimeKinds = blokctlProject.runtimes;
|
|
@@ -453,6 +454,14 @@ export async function createProject(opts, version, currentPath = false, localRep
|
|
|
453
454
|
fsExtra.ensureDirSync(wsServerDir);
|
|
454
455
|
fsExtra.writeFileSync(`${wsServerDir}/WSServer.ts`, generateWSServerFile());
|
|
455
456
|
}
|
|
457
|
+
if (selectedTriggers.includes("cron")) {
|
|
458
|
+
const cronServerDir = `${dirPath}/src/triggers/cron/runner`;
|
|
459
|
+
fsExtra.ensureDirSync(cronServerDir);
|
|
460
|
+
fsExtra.writeFileSync(`${cronServerDir}/CronServer.ts`, generateCronServerFile());
|
|
461
|
+
const cronWorkflowDir = `${dirPath}/src/workflows/cron`;
|
|
462
|
+
fsExtra.ensureDirSync(cronWorkflowDir);
|
|
463
|
+
fsExtra.writeFileSync(`${cronWorkflowDir}/heartbeat.ts`, generateCronExampleWorkflowFile());
|
|
464
|
+
}
|
|
456
465
|
for (const triggerKind of selectedTriggers) {
|
|
457
466
|
const triggerNodesDir = `${repoSource}/triggers/${triggerKind}/src/nodes`;
|
|
458
467
|
if (fsExtra.existsSync(triggerNodesDir)) {
|
|
@@ -500,13 +509,7 @@ export async function createProject(opts, version, currentPath = false, localRep
|
|
|
500
509
|
fsExtra.ensureDirSync(`${dirPath}/infra/milvus`);
|
|
501
510
|
fsExtra.copySync(`${repoSource}/infra/development`, `${dirPath}/infra/postgresql`);
|
|
502
511
|
fsExtra.copySync(`${repoSource}/infra/milvus`, `${dirPath}/infra/milvus`);
|
|
503
|
-
|
|
504
|
-
const examplesNodesContent = needsHelpers
|
|
505
|
-
? node_file
|
|
506
|
-
.replace(`import type { NodeBase } from "@blokjs/shared";`, `import type { NodeBase } from "@blokjs/shared";\nimport { HELPER_NODES } from "@blokjs/helpers";`)
|
|
507
|
-
.replace(`} = {\n\t"@blokjs/api-call": ApiCall,`, `} = {\n\t...HELPER_NODES,\n\t"@blokjs/api-call": ApiCall,`)
|
|
508
|
-
: node_file;
|
|
509
|
-
fsExtra.writeFileSync(`${dirPath}/src/Nodes.ts`, examplesNodesContent);
|
|
512
|
+
fsExtra.writeFileSync(`${dirPath}/src/Nodes.ts`, node_file);
|
|
510
513
|
fsExtra.copySync(`${repoSource}/sdk`, `${dirPath}/public/sdk`);
|
|
511
514
|
const tsExamplesSrc = `${repoSource}/examples/ts-workflows`;
|
|
512
515
|
const tsExamplesDest = `${dirPath}/src/workflows/examples`;
|
|
@@ -551,7 +554,7 @@ export async function createProject(opts, version, currentPath = false, localRep
|
|
|
551
554
|
"@blokjs/trigger-worker": "triggers/worker",
|
|
552
555
|
"@blokjs/core": "core/core",
|
|
553
556
|
};
|
|
554
|
-
const BLOKJS_DEP_RANGE = "^1.
|
|
557
|
+
const BLOKJS_DEP_RANGE = "^1.3.0";
|
|
555
558
|
for (const depGroup of ["dependencies", "devDependencies", "peerDependencies"]) {
|
|
556
559
|
const deps = packageJsonContent[depGroup];
|
|
557
560
|
if (!deps)
|
|
@@ -636,6 +639,16 @@ export async function createProject(opts, version, currentPath = false, localRep
|
|
|
636
639
|
? `file:${path.resolve(repoSource, "triggers/worker")}`
|
|
637
640
|
: BLOKJS_DEP_RANGE;
|
|
638
641
|
}
|
|
642
|
+
if (selectedTriggers.includes("cron")) {
|
|
643
|
+
triggerPackageDeps["@blokjs/trigger-cron"] = localRepoPath
|
|
644
|
+
? `file:${path.resolve(repoSource, "triggers/cron")}`
|
|
645
|
+
: BLOKJS_DEP_RANGE;
|
|
646
|
+
}
|
|
647
|
+
if (selectedTriggers.includes("grpc")) {
|
|
648
|
+
triggerPackageDeps["@blokjs/trigger-grpc"] = localRepoPath
|
|
649
|
+
? `file:${path.resolve(repoSource, "triggers/grpc")}`
|
|
650
|
+
: BLOKJS_DEP_RANGE;
|
|
651
|
+
}
|
|
639
652
|
if (selectedTriggers.includes("sse")) {
|
|
640
653
|
const sseDeps = {
|
|
641
654
|
"@blokjs/api-call": localRepoPath
|
|
@@ -705,6 +718,14 @@ export async function createProject(opts, version, currentPath = false, localRep
|
|
|
705
718
|
const rt = detectedRuntimes.find((r) => r.kind === kind);
|
|
706
719
|
if (!rt)
|
|
707
720
|
continue;
|
|
721
|
+
if (rt.minVersion) {
|
|
722
|
+
const constraint = computeDefaultConstraint(rt.minVersion);
|
|
723
|
+
if (!rt.version || !satisfiesConstraint(rt.version, constraint)) {
|
|
724
|
+
console.log(`\n${formatVersionMismatch(rt.label, rt.version, constraint, rt.installHint)}`);
|
|
725
|
+
console.log(color.yellow(` Skipping ${rt.label} setup. After upgrading, add it with \`blokctl runtime add ${rt.kind}\`.\n`));
|
|
726
|
+
continue;
|
|
727
|
+
}
|
|
728
|
+
}
|
|
708
729
|
try {
|
|
709
730
|
const config = await setupRuntime(rt, repoSource, dirPath, s);
|
|
710
731
|
runtimeConfigs.push(config);
|
|
@@ -858,20 +879,21 @@ export async function createProject(opts, version, currentPath = false, localRep
|
|
|
858
879
|
console.log(error.message);
|
|
859
880
|
}
|
|
860
881
|
}
|
|
861
|
-
function generateSharedNodesFile(
|
|
882
|
+
export function generateSharedNodesFile(_triggers, _repoSource) {
|
|
862
883
|
const imports = [
|
|
863
884
|
'import { dirname, join } from "node:path";',
|
|
864
885
|
'import { fileURLToPath } from "node:url";',
|
|
865
886
|
'import ApiCall from "@blokjs/api-call";',
|
|
866
887
|
'import IfElse from "@blokjs/if-else";',
|
|
888
|
+
'import { HELPER_NODES } from "@blokjs/helpers";',
|
|
867
889
|
'import { discoverNodes } from "@blokjs/runner";',
|
|
868
890
|
'import type { NodeBase } from "@blokjs/shared";',
|
|
869
891
|
];
|
|
870
|
-
const explicit = [
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
892
|
+
const explicit = [
|
|
893
|
+
"ApiCall as unknown as NodeBase",
|
|
894
|
+
"IfElse as unknown as NodeBase",
|
|
895
|
+
"...(Object.values(HELPER_NODES) as unknown as NodeBase[])",
|
|
896
|
+
];
|
|
875
897
|
return `${imports.join("\n")}
|
|
876
898
|
|
|
877
899
|
// Published nodes (npm) are registered explicitly below. Your OWN nodes under
|
|
@@ -890,32 +912,42 @@ for (const node of [${explicit.join(", ")}, ...local]) {
|
|
|
890
912
|
export default nodes;
|
|
891
913
|
`;
|
|
892
914
|
}
|
|
893
|
-
function generateSharedWorkflowsFile(triggers, runtimeKinds = [], examples = false) {
|
|
915
|
+
export function generateSharedWorkflowsFile(triggers, runtimeKinds = [], examples = false) {
|
|
894
916
|
const imports = [];
|
|
895
917
|
const workflowEntries = [];
|
|
896
918
|
for (const trigger of triggers) {
|
|
897
919
|
if (trigger === "http") {
|
|
898
|
-
imports.push("// HTTP workflows are auto-discovered from workflows/json/");
|
|
920
|
+
imports.push("// HTTP JSON workflows are auto-discovered from workflows/json/");
|
|
921
|
+
imports.push('import CountriesHandleDsl from "./workflows/http/countries-handle-dsl";');
|
|
922
|
+
workflowEntries.push('\t"countries-dsl": await CountriesHandleDsl,');
|
|
899
923
|
}
|
|
900
924
|
else if (trigger === "sse") {
|
|
901
925
|
imports.push('import SSEStreamDemo from "./workflows/sse/events/stream-demo";');
|
|
902
|
-
workflowEntries.push('\t"sse-stream-demo": SSEStreamDemo,');
|
|
926
|
+
workflowEntries.push('\t"sse-stream-demo": await SSEStreamDemo,');
|
|
903
927
|
if (triggers.includes("http")) {
|
|
904
928
|
imports.push('import SSEPublishDemo from "./workflows/sse/events/publish-demo";');
|
|
905
|
-
workflowEntries.push('\t"sse-publish-demo": SSEPublishDemo,');
|
|
929
|
+
workflowEntries.push('\t"sse-publish-demo": await SSEPublishDemo,');
|
|
906
930
|
}
|
|
907
931
|
}
|
|
908
932
|
else if (trigger === "websocket") {
|
|
909
933
|
imports.push('import WSEchoDemo from "./workflows/websocket/events/echo-demo";');
|
|
910
|
-
workflowEntries.push('\t"ws-echo-demo": WSEchoDemo,');
|
|
934
|
+
workflowEntries.push('\t"ws-echo-demo": await WSEchoDemo,');
|
|
911
935
|
}
|
|
912
936
|
else if (trigger === "pubsub") {
|
|
913
937
|
imports.push('import OnPubSubMessage from "./workflows/pubsub/messages/on-message";');
|
|
914
|
-
workflowEntries.push('\t"on-pubsub-message": OnPubSubMessage,');
|
|
938
|
+
workflowEntries.push('\t"on-pubsub-message": await OnPubSubMessage,');
|
|
939
|
+
if (triggers.includes("http")) {
|
|
940
|
+
imports.push('import PublishOrder from "./workflows/pubsub/publish-order";');
|
|
941
|
+
workflowEntries.push('\t"publish-order": await PublishOrder,');
|
|
942
|
+
}
|
|
915
943
|
}
|
|
916
944
|
else if (trigger === "queue" || trigger === "worker") {
|
|
917
945
|
imports.push(`import ProcessJob from "./workflows/${trigger}/jobs/process-job";`);
|
|
918
|
-
workflowEntries.push('\t"process-job": ProcessJob,');
|
|
946
|
+
workflowEntries.push('\t"process-job": await ProcessJob,');
|
|
947
|
+
}
|
|
948
|
+
else if (trigger === "cron") {
|
|
949
|
+
imports.push('import CronHeartbeat from "./workflows/cron/heartbeat";');
|
|
950
|
+
workflowEntries.push('\t"cron-heartbeat": await CronHeartbeat,');
|
|
919
951
|
}
|
|
920
952
|
}
|
|
921
953
|
if (examples) {
|
|
@@ -945,7 +977,7 @@ ${entriesSection}
|
|
|
945
977
|
export default workflows;
|
|
946
978
|
`;
|
|
947
979
|
}
|
|
948
|
-
function generateTriggerEntryFile(triggerKind, selectedTriggers = [triggerKind]) {
|
|
980
|
+
export function generateTriggerEntryFile(triggerKind, selectedTriggers = [triggerKind]) {
|
|
949
981
|
if (triggerKind === "http") {
|
|
950
982
|
const sseAlsoSelected = selectedTriggers.includes("sse");
|
|
951
983
|
const wsAlsoSelected = selectedTriggers.includes("websocket");
|
|
@@ -1285,6 +1317,63 @@ export default class App {
|
|
|
1285
1317
|
if (process.env.DISABLE_TRIGGER_RUN !== "true") {
|
|
1286
1318
|
new App().run();
|
|
1287
1319
|
}
|
|
1320
|
+
`;
|
|
1321
|
+
}
|
|
1322
|
+
if (triggerKind === "cron") {
|
|
1323
|
+
return `import { DefaultLogger } from "@blokjs/runner";
|
|
1324
|
+
import { type Span, metrics, trace } from "@opentelemetry/api";
|
|
1325
|
+
import CronServer from "./runner/CronServer";
|
|
1326
|
+
|
|
1327
|
+
export default class App {
|
|
1328
|
+
private cronServer: CronServer = <CronServer>{};
|
|
1329
|
+
protected trigger_initializer = 0;
|
|
1330
|
+
protected initializer = 0;
|
|
1331
|
+
protected tracer = trace.getTracer(
|
|
1332
|
+
process.env.PROJECT_NAME || "trigger-cron-server",
|
|
1333
|
+
process.env.PROJECT_VERSION || "0.0.1",
|
|
1334
|
+
);
|
|
1335
|
+
private logger = new DefaultLogger();
|
|
1336
|
+
protected app_cold_start = metrics.getMeter("default").createGauge("initialization", {
|
|
1337
|
+
description: "Application cold start",
|
|
1338
|
+
});
|
|
1339
|
+
|
|
1340
|
+
constructor() {
|
|
1341
|
+
this.initializer = performance.now();
|
|
1342
|
+
this.cronServer = new CronServer();
|
|
1343
|
+
}
|
|
1344
|
+
|
|
1345
|
+
async run() {
|
|
1346
|
+
this.tracer.startActiveSpan("initialization", async (span: Span) => {
|
|
1347
|
+
await this.cronServer.listen();
|
|
1348
|
+
this.initializer = performance.now() - this.initializer;
|
|
1349
|
+
|
|
1350
|
+
this.logger.log(\`Cron trigger initialized in \${(this.initializer).toFixed(2)}ms\`);
|
|
1351
|
+
this.app_cold_start.record(this.initializer, {
|
|
1352
|
+
pid: process.pid,
|
|
1353
|
+
env: process.env.NODE_ENV,
|
|
1354
|
+
app: process.env.APP_NAME,
|
|
1355
|
+
});
|
|
1356
|
+
span.end();
|
|
1357
|
+
});
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1360
|
+
|
|
1361
|
+
if (process.env.DISABLE_TRIGGER_RUN !== "true") {
|
|
1362
|
+
new App().run();
|
|
1363
|
+
}
|
|
1364
|
+
`;
|
|
1365
|
+
}
|
|
1366
|
+
if (triggerKind === "grpc") {
|
|
1367
|
+
return `import { GrpcServer } from "@blokjs/trigger-grpc";
|
|
1368
|
+
import nodes from "../../Nodes";
|
|
1369
|
+
import workflows from "../../Workflows";
|
|
1370
|
+
|
|
1371
|
+
const host = process.env.GRPC_HOST || "0.0.0.0";
|
|
1372
|
+
const port = Number(process.env.GRPC_PORT || process.env.PORT || 4003);
|
|
1373
|
+
|
|
1374
|
+
if (process.env.DISABLE_TRIGGER_RUN !== "true") {
|
|
1375
|
+
new GrpcServer({ host, port, nodes, workflows }).start();
|
|
1376
|
+
}
|
|
1288
1377
|
`;
|
|
1289
1378
|
}
|
|
1290
1379
|
return `// Entry point for ${triggerKind} trigger
|
|
@@ -1292,6 +1381,45 @@ if (process.env.DISABLE_TRIGGER_RUN !== "true") {
|
|
|
1292
1381
|
console.log("${triggerKind} trigger not yet implemented");
|
|
1293
1382
|
`;
|
|
1294
1383
|
}
|
|
1384
|
+
export function generateCronExampleWorkflowFile() {
|
|
1385
|
+
return `import { node, step, workflow } from "@blokjs/core";
|
|
1386
|
+
|
|
1387
|
+
/**
|
|
1388
|
+
* Cron heartbeat — fires on a schedule, NOT on an HTTP request. \`blokctl dev\`
|
|
1389
|
+
* boots it via src/triggers/cron/index.ts and it fires every minute. The
|
|
1390
|
+
* schedule accepts an optional leading seconds field (e.g. \`* * * * * *\` for
|
|
1391
|
+
* every second). Add more cron workflows by exporting them and registering
|
|
1392
|
+
* them in src/Workflows.ts.
|
|
1393
|
+
*/
|
|
1394
|
+
export default workflow(
|
|
1395
|
+
"Cron Heartbeat",
|
|
1396
|
+
{ version: "1.0.0", trigger: { cron: { schedule: "* * * * *", timezone: "UTC" } } },
|
|
1397
|
+
() => {
|
|
1398
|
+
step("heartbeat", node("@blokjs/expr"), { expression: "({ ok: true, at: Date.now() })" }, { ephemeral: true });
|
|
1399
|
+
},
|
|
1400
|
+
);
|
|
1401
|
+
`;
|
|
1402
|
+
}
|
|
1403
|
+
export function generateCronServerFile() {
|
|
1404
|
+
return `import { CronTrigger } from "@blokjs/trigger-cron";
|
|
1405
|
+
import nodes from "../../../Nodes";
|
|
1406
|
+
import workflows from "../../../Workflows";
|
|
1407
|
+
|
|
1408
|
+
/**
|
|
1409
|
+
* CronServer — the cron trigger for this project.
|
|
1410
|
+
*
|
|
1411
|
+
* CronTrigger.listen() populates the NodeMap, registers workflows with the
|
|
1412
|
+
* WorkflowRegistry, then schedules a CronJob for every workflow whose trigger
|
|
1413
|
+
* is \`{ cron: { schedule, timezone? } }\`. There is no port to bind — the
|
|
1414
|
+
* scheduled job timers keep the process alive. Non-cron workflows sharing this
|
|
1415
|
+
* Workflows.ts are ignored by the scheduler (they run under their own trigger).
|
|
1416
|
+
*/
|
|
1417
|
+
export default class CronServer extends CronTrigger {
|
|
1418
|
+
protected nodes: Record<string, import("@blokjs/runner").BlokService<unknown>> = nodes;
|
|
1419
|
+
protected workflows: Record<string, import("@blokjs/helper").WorkflowV2Builder> = workflows;
|
|
1420
|
+
}
|
|
1421
|
+
`;
|
|
1422
|
+
}
|
|
1295
1423
|
function generateSSEServerFile() {
|
|
1296
1424
|
return `import { serve } from "@hono/node-server";
|
|
1297
1425
|
import { DefaultLogger, NodeMap, WorkflowRegistry } from "@blokjs/runner";
|
|
@@ -1578,8 +1706,12 @@ function updatePubSubProvider(triggerDestDir, provider) {
|
|
|
1578
1706
|
},
|
|
1579
1707
|
};
|
|
1580
1708
|
const config = adapterConfigs[provider];
|
|
1581
|
-
if (!config)
|
|
1709
|
+
if (!config) {
|
|
1710
|
+
content = content.replace(/import \{ GCPPubSubAdapter, PubSubTrigger \} from ["']@blokjs\/trigger-pubsub["'];/, 'import { PubSubTrigger } from "@blokjs/trigger-pubsub";');
|
|
1711
|
+
content = content.replace(/\n\tprotected adapter = new GCPPubSubAdapter\(\{[\s\S]*?\}\);\n/, "");
|
|
1712
|
+
fsExtra.writeFileSync(serverPath, content);
|
|
1582
1713
|
return;
|
|
1714
|
+
}
|
|
1583
1715
|
content = content.replace(/import \{ (\w+), (\w+) \} from ["']@blokjs\/trigger-pubsub["'];/, `import { ${config.importName}, PubSubTrigger } from "@blokjs/trigger-pubsub";`);
|
|
1584
1716
|
content = content.replace(/(export default class \w+ extends PubSubTrigger \{[\s\S]*?)\n\tprotected adapter = new \w+\(\{[\s\S]*?\}\);/, `$1\n\tprotected adapter = ${config.init};`);
|
|
1585
1717
|
fsExtra.writeFileSync(serverPath, content);
|
|
@@ -1637,6 +1769,7 @@ export function updateQueueProvider(triggerDestDir, provider, explicit) {
|
|
|
1637
1769
|
export function getProviderDependencies(triggers, pubsubProvider, queueProvider, explicitQueueProvider = false) {
|
|
1638
1770
|
const deps = {};
|
|
1639
1771
|
const pubsubProviderDeps = {
|
|
1772
|
+
nats: { nats: "^2.28.0" },
|
|
1640
1773
|
gcp: { "@google-cloud/pubsub": "^5.0.0" },
|
|
1641
1774
|
aws: { "@aws-sdk/client-sns": "^3.980.0", "@aws-sdk/client-sqs": "^3.980.0" },
|
|
1642
1775
|
azure: { "@azure/service-bus": "^7.9.5" },
|
|
@@ -1661,6 +1794,10 @@ export function getProviderDependencies(triggers, pubsubProvider, queueProvider,
|
|
|
1661
1794
|
export function getProviderEnvVars(triggers, pubsubProvider, queueProvider, explicitQueueProvider = false) {
|
|
1662
1795
|
const lines = [];
|
|
1663
1796
|
const pubsubEnvVars = {
|
|
1797
|
+
nats: `
|
|
1798
|
+
# NATS (local pub/sub broker — zero cloud setup)
|
|
1799
|
+
NATS_SERVERS=localhost:4222
|
|
1800
|
+
BLOK_PUBSUB_ADAPTER=nats`,
|
|
1664
1801
|
gcp: `
|
|
1665
1802
|
# Google Cloud Pub/Sub
|
|
1666
1803
|
GCP_PROJECT_ID=my-project
|