blokctl 0.6.10 ā 0.6.12
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.js +50 -24
- package/package.json +2 -2
|
@@ -17,7 +17,7 @@ const exec = util.promisify(child_process.exec);
|
|
|
17
17
|
const HOME_DIR = `${os.homedir()}/.blok`;
|
|
18
18
|
const GITHUB_REPO_LOCAL = `${HOME_DIR}/blok`;
|
|
19
19
|
const GITHUB_REPO_REMOTE = "https://github.com/well-prado/blok.git";
|
|
20
|
-
const GITHUB_REPO_RELEASE_TAG = "v0.6.
|
|
20
|
+
const GITHUB_REPO_RELEASE_TAG = "v0.6.12";
|
|
21
21
|
fsExtra.ensureDirSync(HOME_DIR);
|
|
22
22
|
const options = {
|
|
23
23
|
baseDir: HOME_DIR,
|
|
@@ -264,15 +264,15 @@ export async function createProject(opts, version, currentPath = false, localRep
|
|
|
264
264
|
const triggerConfigs = selectedTriggers.map((kind) => createTriggerConfig(kind));
|
|
265
265
|
const mountedOnHttp = new Set();
|
|
266
266
|
if (selectedTriggers.includes("http")) {
|
|
267
|
-
for (const kind of ["sse", "websocket"]) {
|
|
267
|
+
for (const kind of ["sse", "websocket", "webhook"]) {
|
|
268
268
|
if (selectedTriggers.includes(kind))
|
|
269
269
|
mountedOnHttp.add(kind);
|
|
270
270
|
}
|
|
271
271
|
}
|
|
272
272
|
const spawnedTriggerConfigs = triggerConfigs.filter((tc) => !mountedOnHttp.has(tc.kind));
|
|
273
273
|
const primaryTrigger = selectedTriggers[0];
|
|
274
|
-
const primaryTriggerDir = primaryTrigger === "pubsub" || primaryTrigger === "queue"
|
|
275
|
-
? `${repoSource}/triggers/${primaryTrigger === "queue" ? "worker" : primaryTrigger}/template`
|
|
274
|
+
const primaryTriggerDir = primaryTrigger === "pubsub" || primaryTrigger === "queue" || primaryTrigger === "worker"
|
|
275
|
+
? `${repoSource}/triggers/${primaryTrigger === "queue" || primaryTrigger === "worker" ? "worker" : primaryTrigger}/template`
|
|
276
276
|
: `${repoSource}/triggers/${primaryTrigger}`;
|
|
277
277
|
const baseFiles = ["package.json", "tsconfig.json", ".env.example", ".gitignore", "vitest.config.ts"];
|
|
278
278
|
for (const file of baseFiles) {
|
|
@@ -318,8 +318,8 @@ export async function createProject(opts, version, currentPath = false, localRep
|
|
|
318
318
|
for (const triggerKind of selectedTriggers) {
|
|
319
319
|
const triggerDestDir = `${dirPath}/src/triggers/${triggerKind}`;
|
|
320
320
|
fsExtra.ensureDirSync(triggerDestDir);
|
|
321
|
-
if (triggerKind === "pubsub" || triggerKind === "queue") {
|
|
322
|
-
const templatePkgDir = triggerKind === "queue" ? "worker" : triggerKind;
|
|
321
|
+
if (triggerKind === "pubsub" || triggerKind === "queue" || triggerKind === "worker") {
|
|
322
|
+
const templatePkgDir = triggerKind === "queue" || triggerKind === "worker" ? "worker" : triggerKind;
|
|
323
323
|
const templateDir = `${repoSource}/triggers/${templatePkgDir}/template/src`;
|
|
324
324
|
if (fsExtra.existsSync(templateDir)) {
|
|
325
325
|
fsExtra.copySync(templateDir, triggerDestDir);
|
|
@@ -332,7 +332,7 @@ export async function createProject(opts, version, currentPath = false, localRep
|
|
|
332
332
|
if (triggerKind === "pubsub") {
|
|
333
333
|
updatePubSubProvider(triggerDestDir, pubsubProvider);
|
|
334
334
|
}
|
|
335
|
-
else if (triggerKind === "queue") {
|
|
335
|
+
else if (triggerKind === "queue" || triggerKind === "worker") {
|
|
336
336
|
updateQueueProvider(triggerDestDir, queueProvider);
|
|
337
337
|
}
|
|
338
338
|
}
|
|
@@ -383,7 +383,14 @@ export async function createProject(opts, version, currentPath = false, localRep
|
|
|
383
383
|
fsExtra.writeFileSync(`${dirPath}/src/Nodes.ts`, sharedNodesContent);
|
|
384
384
|
const sharedWorkflowsContent = generateSharedWorkflowsFile(selectedTriggers);
|
|
385
385
|
fsExtra.writeFileSync(`${dirPath}/src/Workflows.ts`, sharedWorkflowsContent);
|
|
386
|
+
const triggersWithRealTemplate = new Set(["worker", "queue", "pubsub"]);
|
|
386
387
|
for (const triggerKind of selectedTriggers) {
|
|
388
|
+
if (triggersWithRealTemplate.has(triggerKind)) {
|
|
389
|
+
continue;
|
|
390
|
+
}
|
|
391
|
+
if (mountedOnHttp.has(triggerKind)) {
|
|
392
|
+
continue;
|
|
393
|
+
}
|
|
387
394
|
const entryContent = generateTriggerEntryFile(triggerKind, selectedTriggers);
|
|
388
395
|
fsExtra.writeFileSync(`${dirPath}/src/triggers/${triggerKind}/index.ts`, entryContent);
|
|
389
396
|
}
|
|
@@ -426,7 +433,7 @@ export async function createProject(opts, version, currentPath = false, localRep
|
|
|
426
433
|
fsExtra.ensureDirSync(`${dirPath}/infra/metrics`);
|
|
427
434
|
fsExtra.copySync(`${repoSource}/infra/metrics`, `${dirPath}/infra/metrics`);
|
|
428
435
|
fsExtra.removeSync(`${dirPath}/public/metric`);
|
|
429
|
-
if (selectedTriggers.includes("queue")) {
|
|
436
|
+
if (selectedTriggers.includes("queue") || selectedTriggers.includes("worker")) {
|
|
430
437
|
fsExtra.ensureDirSync(`${dirPath}/infra/development`);
|
|
431
438
|
fsExtra.copySync(`${repoSource}/infra/development`, `${dirPath}/infra/development`);
|
|
432
439
|
}
|
|
@@ -478,7 +485,7 @@ export async function createProject(opts, version, currentPath = false, localRep
|
|
|
478
485
|
"@blokjs/trigger-websocket": "triggers/websocket",
|
|
479
486
|
"@blokjs/trigger-worker": "triggers/worker",
|
|
480
487
|
};
|
|
481
|
-
const BLOKJS_DEP_RANGE = "^0.6.
|
|
488
|
+
const BLOKJS_DEP_RANGE = "^0.6.12";
|
|
482
489
|
for (const depGroup of ["dependencies", "devDependencies", "peerDependencies"]) {
|
|
483
490
|
const deps = packageJsonContent[depGroup];
|
|
484
491
|
if (!deps)
|
|
@@ -547,7 +554,8 @@ export async function createProject(opts, version, currentPath = false, localRep
|
|
|
547
554
|
? `file:${path.resolve(repoSource, "triggers/pubsub")}`
|
|
548
555
|
: BLOKJS_DEP_RANGE;
|
|
549
556
|
}
|
|
550
|
-
|
|
557
|
+
const needsTriggerWorker = selectedTriggers.includes("queue") || selectedTriggers.includes("worker") || examples;
|
|
558
|
+
if (needsTriggerWorker) {
|
|
551
559
|
triggerPackageDeps["@blokjs/trigger-worker"] = localRepoPath
|
|
552
560
|
? `file:${path.resolve(repoSource, "triggers/worker")}`
|
|
553
561
|
: BLOKJS_DEP_RANGE;
|
|
@@ -721,7 +729,7 @@ export async function createProject(opts, version, currentPath = false, localRep
|
|
|
721
729
|
console.log(` ${rc.label}: http://localhost:${rc.port}/health`);
|
|
722
730
|
}
|
|
723
731
|
}
|
|
724
|
-
if (selectedTriggers.includes("queue") && queueProvider === "redis") {
|
|
732
|
+
if ((selectedTriggers.includes("queue") || selectedTriggers.includes("worker")) && queueProvider === "redis") {
|
|
725
733
|
console.log(color.cyan("\nš¦ Redis Setup (for Queue trigger):"));
|
|
726
734
|
console.log(" Start Redis with Docker:");
|
|
727
735
|
console.log(color.dim(" cd infra/development"));
|
|
@@ -729,7 +737,7 @@ export async function createProject(opts, version, currentPath = false, localRep
|
|
|
729
737
|
console.log(color.dim(" docker compose up -d redis redis-commander"));
|
|
730
738
|
console.log(" Redis Commander UI: http://localhost:8081");
|
|
731
739
|
}
|
|
732
|
-
if (selectedTriggers.includes("queue") && queueProvider === "nats") {
|
|
740
|
+
if ((selectedTriggers.includes("queue") || selectedTriggers.includes("worker")) && queueProvider === "nats") {
|
|
733
741
|
console.log(color.cyan("\nš¦ NATS JetStream Setup (for Queue trigger):"));
|
|
734
742
|
console.log(" Start NATS with Docker:");
|
|
735
743
|
console.log(color.dim(" cd infra/development"));
|
|
@@ -799,8 +807,8 @@ function generateSharedWorkflowsFile(triggers) {
|
|
|
799
807
|
imports.push('import OnPubSubMessage from "./workflows/pubsub/messages/on-message";');
|
|
800
808
|
workflowEntries.push('\t"on-pubsub-message": OnPubSubMessage,');
|
|
801
809
|
}
|
|
802
|
-
else if (trigger === "queue") {
|
|
803
|
-
imports.push(
|
|
810
|
+
else if (trigger === "queue" || trigger === "worker") {
|
|
811
|
+
imports.push(`import ProcessJob from "./workflows/${trigger}/jobs/process-job";`);
|
|
804
812
|
workflowEntries.push('\t"process-job": ProcessJob,');
|
|
805
813
|
}
|
|
806
814
|
}
|
|
@@ -820,12 +828,14 @@ function generateTriggerEntryFile(triggerKind, selectedTriggers = [triggerKind])
|
|
|
820
828
|
if (triggerKind === "http") {
|
|
821
829
|
const sseAlsoSelected = selectedTriggers.includes("sse");
|
|
822
830
|
const wsAlsoSelected = selectedTriggers.includes("websocket");
|
|
823
|
-
const
|
|
831
|
+
const webhookAlsoSelected = selectedTriggers.includes("webhook");
|
|
832
|
+
const needsShared = sseAlsoSelected || wsAlsoSelected || webhookAlsoSelected;
|
|
824
833
|
const sharedHelperImports = needsShared
|
|
825
834
|
? `\nimport { NodeMap, WorkflowRegistry } from "@blokjs/runner";\nimport sharedNodes from "../../Nodes";\nimport sharedWorkflows from "../../Workflows";`
|
|
826
835
|
: "";
|
|
827
836
|
const sseImports = sseAlsoSelected ? `\nimport SSETrigger from "@blokjs/trigger-sse";` : "";
|
|
828
837
|
const wsImports = wsAlsoSelected ? `\nimport WebSocketTrigger from "@blokjs/trigger-websocket";` : "";
|
|
838
|
+
const webhookImports = webhookAlsoSelected ? `\nimport WebhookTrigger from "@blokjs/trigger-webhook";` : "";
|
|
829
839
|
const sharedBootstrapPrelude = needsShared
|
|
830
840
|
? `\n\n // Build a NodeMap from the shared Nodes record; both SSE and
|
|
831
841
|
// WebSocket triggers consume this via setNodeMap so they can
|
|
@@ -848,15 +858,15 @@ function generateTriggerEntryFile(triggerKind, selectedTriggers = [triggerKind])
|
|
|
848
858
|
for (const [name, wf] of Object.entries(sharedWorkflows)) {
|
|
849
859
|
const w = wf as {
|
|
850
860
|
name?: string;
|
|
851
|
-
trigger?: { sse?: unknown; websocket?: unknown };
|
|
852
|
-
_config?: { name?: string; trigger?: { sse?: unknown; websocket?: unknown } };
|
|
861
|
+
trigger?: { sse?: unknown; websocket?: unknown; webhook?: unknown };
|
|
862
|
+
_config?: { name?: string; trigger?: { sse?: unknown; websocket?: unknown; webhook?: unknown } };
|
|
853
863
|
};
|
|
854
864
|
const triggerCfg = w._config?.trigger ?? w.trigger;
|
|
855
865
|
if (!triggerCfg) continue;
|
|
856
|
-
if (!triggerCfg.sse && !triggerCfg.websocket) continue;
|
|
866
|
+
if (!triggerCfg.sse && !triggerCfg.websocket && !triggerCfg.webhook) continue;
|
|
857
867
|
const resolvedName = w._config?.name ?? w.name ?? name;
|
|
858
868
|
if (registry.get(resolvedName)) continue;
|
|
859
|
-
const kind = triggerCfg.sse ? "sse" : "websocket";
|
|
869
|
+
const kind = triggerCfg.sse ? "sse" : triggerCfg.websocket ? "websocket" : "webhook";
|
|
860
870
|
registry.register({
|
|
861
871
|
name: resolvedName,
|
|
862
872
|
source: \`\${kind}:\${name}\`,
|
|
@@ -893,10 +903,26 @@ function generateTriggerEntryFile(triggerKind, selectedTriggers = [triggerKind])
|
|
|
893
903
|
});
|
|
894
904
|
await wsTrigger.listen();`
|
|
895
905
|
: "";
|
|
896
|
-
const
|
|
906
|
+
const webhookBootstrap = webhookAlsoSelected
|
|
907
|
+
? `\n // Mount Webhook trigger on the HTTP process's shared Hono app.
|
|
908
|
+
// WebhookTrigger.constructor(app, httpTrigger?) mirrors SSE / WS ā
|
|
909
|
+
// when an HttpTrigger is supplied, the webhook trigger registers
|
|
910
|
+
// its /webhooks/<provider> routes inside addPreCatchAllHook so they
|
|
911
|
+
// win Hono's first-match dispatch over the legacy workflow catch-
|
|
912
|
+
// all. The shared @blokjs/trigger-webhook singleton this creates
|
|
913
|
+
// is also what @blokjs/hmac-verify (and other webhook-aware helpers)
|
|
914
|
+
// look up at run time.
|
|
915
|
+
const webhookTrigger = new WebhookTrigger(this.httpTrigger.getApp(), this.httpTrigger);
|
|
916
|
+
webhookTrigger.setNodeMap({
|
|
917
|
+
nodes: subTriggerNodeMap,
|
|
918
|
+
workflows: sharedWorkflows as unknown as Parameters<typeof webhookTrigger.setNodeMap>[0]["workflows"],
|
|
919
|
+
});
|
|
920
|
+
await webhookTrigger.listen();`
|
|
921
|
+
: "";
|
|
922
|
+
const fullBootstrap = `${sharedBootstrapPrelude}${sseBootstrap}${wsBootstrap}${webhookBootstrap}`;
|
|
897
923
|
return `import { DefaultLogger } from "@blokjs/runner";
|
|
898
924
|
import { type Span, metrics, trace } from "@opentelemetry/api";
|
|
899
|
-
import HttpTrigger from "./runner/HttpTrigger";${sharedHelperImports}${sseImports}${wsImports}
|
|
925
|
+
import HttpTrigger from "./runner/HttpTrigger";${sharedHelperImports}${sseImports}${wsImports}${webhookImports}
|
|
900
926
|
|
|
901
927
|
export default class App {
|
|
902
928
|
private httpTrigger: HttpTrigger = <HttpTrigger>{};
|
|
@@ -1370,7 +1396,7 @@ function fixRunnerImportPaths(triggerDestDir, triggerKind) {
|
|
|
1370
1396
|
else if (triggerKind === "pubsub") {
|
|
1371
1397
|
fileFixes.push({ file: `${triggerDestDir}/runner/PubSubServer.ts`, up: "../../../" });
|
|
1372
1398
|
}
|
|
1373
|
-
else if (triggerKind === "queue") {
|
|
1399
|
+
else if (triggerKind === "queue" || triggerKind === "worker") {
|
|
1374
1400
|
fileFixes.push({ file: `${triggerDestDir}/runner/WorkerServer.ts`, up: "../../../" });
|
|
1375
1401
|
}
|
|
1376
1402
|
for (const { file, up } of fileFixes) {
|
|
@@ -1485,7 +1511,7 @@ function getProviderDependencies(triggers, pubsubProvider, queueProvider) {
|
|
|
1485
1511
|
if (triggers.includes("pubsub") && pubsubProviderDeps[pubsubProvider]) {
|
|
1486
1512
|
Object.assign(deps, pubsubProviderDeps[pubsubProvider]);
|
|
1487
1513
|
}
|
|
1488
|
-
if (triggers.includes("queue") && queueProviderDeps[queueProvider]) {
|
|
1514
|
+
if ((triggers.includes("queue") || triggers.includes("worker")) && queueProviderDeps[queueProvider]) {
|
|
1489
1515
|
Object.assign(deps, queueProviderDeps[queueProvider]);
|
|
1490
1516
|
}
|
|
1491
1517
|
return deps;
|
|
@@ -1532,7 +1558,7 @@ NATS_STREAM_NAME=blok-queue`,
|
|
|
1532
1558
|
if (triggers.includes("pubsub") && pubsubEnvVars[pubsubProvider]) {
|
|
1533
1559
|
lines.push(pubsubEnvVars[pubsubProvider]);
|
|
1534
1560
|
}
|
|
1535
|
-
if (triggers.includes("queue") && queueEnvVars[queueProvider]) {
|
|
1561
|
+
if ((triggers.includes("queue") || triggers.includes("worker")) && queueEnvVars[queueProvider]) {
|
|
1536
1562
|
lines.push(queueEnvVars[queueProvider]);
|
|
1537
1563
|
}
|
|
1538
1564
|
return lines.join("\n");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "blokctl",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.12",
|
|
4
4
|
"author": "Deskree Technologies Inc.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"description": "cli for blok",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"keywords": ["blokctl", "cli", "blok", "blok"],
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@ai-sdk/openai": "^1.3.22",
|
|
33
|
-
"@blokjs/runner": "^0.6.
|
|
33
|
+
"@blokjs/runner": "^0.6.12",
|
|
34
34
|
"@clack/prompts": "^1.0.0",
|
|
35
35
|
"ai": "^4.3.16",
|
|
36
36
|
"better-sqlite3": "^12.6.2",
|