@blokjs/helper 0.2.1 → 0.6.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.
Files changed (46) hide show
  1. package/dist/components/AddElse.d.ts +15 -0
  2. package/dist/components/AddIf.d.ts +15 -0
  3. package/dist/components/StepNode.d.ts +6 -0
  4. package/dist/components/StepNode.js +8 -0
  5. package/dist/components/StepNode.js.map +1 -1
  6. package/dist/components/Trigger.d.ts +10 -2
  7. package/dist/components/Trigger.js +16 -5
  8. package/dist/components/Trigger.js.map +1 -1
  9. package/dist/components/branch.d.ts +44 -0
  10. package/dist/components/branch.js +57 -0
  11. package/dist/components/branch.js.map +1 -0
  12. package/dist/components/forEach.d.ts +53 -0
  13. package/dist/components/forEach.js +64 -0
  14. package/dist/components/forEach.js.map +1 -0
  15. package/dist/components/loop.d.ts +52 -0
  16. package/dist/components/loop.js +54 -0
  17. package/dist/components/loop.js.map +1 -0
  18. package/dist/components/switchOn.d.ts +68 -0
  19. package/dist/components/switchOn.js +76 -0
  20. package/dist/components/switchOn.js.map +1 -0
  21. package/dist/components/tryCatch.d.ts +63 -0
  22. package/dist/components/tryCatch.js +68 -0
  23. package/dist/components/tryCatch.js.map +1 -0
  24. package/dist/components/workflowV2.d.ts +83 -0
  25. package/dist/components/workflowV2.js +84 -0
  26. package/dist/components/workflowV2.js.map +1 -0
  27. package/dist/index.d.ts +12 -3
  28. package/dist/index.js +25 -4
  29. package/dist/index.js.map +1 -1
  30. package/dist/proxy/$.d.ts +102 -0
  31. package/dist/proxy/$.js +130 -0
  32. package/dist/proxy/$.js.map +1 -0
  33. package/dist/types/StepOpts.d.ts +723 -3
  34. package/dist/types/StepOpts.js +702 -3
  35. package/dist/types/StepOpts.js.map +1 -1
  36. package/dist/types/TriggerOpts.d.ts +1600 -35
  37. package/dist/types/TriggerOpts.js +601 -29
  38. package/dist/types/TriggerOpts.js.map +1 -1
  39. package/dist/types/WorkflowOpts.d.ts +478 -28
  40. package/dist/types/WorkflowOpts.js +66 -3
  41. package/dist/types/WorkflowOpts.js.map +1 -1
  42. package/dist/utils/parseDuration.d.ts +33 -0
  43. package/dist/utils/parseDuration.js +78 -0
  44. package/dist/utils/parseDuration.js.map +1 -0
  45. package/dist/workflow.schema.json +662 -0
  46. package/package.json +6 -6
@@ -0,0 +1,76 @@
1
+ import { unwrapProxies } from "../proxy/$";
2
+ /**
3
+ * Create a switch step — N-way branch keyed on a value. First matching
4
+ * case wins; an optional `default` block runs when no case matches.
5
+ *
6
+ * Authoring note: the function is named `switchOn` because `switch` is
7
+ * a JavaScript reserved word. The resulting step object's discriminator
8
+ * field is `switch`, matching the JSON shape exactly.
9
+ *
10
+ * @example
11
+ * switchOn({
12
+ * id: "route-by-event",
13
+ * on: $.req.headers["x-github-event"],
14
+ * cases: [
15
+ * { when: "push", do: [{ id: "h", subworkflow: "handle-push" }] },
16
+ * {
17
+ * when: ["pull_request", "pull_request_review"],
18
+ * do: [{ id: "h", subworkflow: "handle-pr-event" }],
19
+ * },
20
+ * ],
21
+ * default: [
22
+ * { id: "log-unknown", use: "@blokjs/log",
23
+ * inputs: { level: "warn", message: "unknown github event" } },
24
+ * ],
25
+ * })
26
+ */
27
+ export function switchOn(opts) {
28
+ if (!opts || typeof opts !== "object") {
29
+ throw new Error("switchOn() requires an options object.");
30
+ }
31
+ if (!opts.id || typeof opts.id !== "string") {
32
+ throw new Error("switchOn() requires a non-empty `id` string.");
33
+ }
34
+ if (opts.on === undefined) {
35
+ throw new Error(`switchOn("${opts.id}") requires \`on\` (the value or expression to match against).`);
36
+ }
37
+ if (!Array.isArray(opts.cases) || opts.cases.length === 0) {
38
+ throw new Error(`switchOn("${opts.id}") requires \`cases\` to be a non-empty array.`);
39
+ }
40
+ for (let i = 0; i < opts.cases.length; i++) {
41
+ const c = opts.cases[i];
42
+ if (!c || typeof c !== "object") {
43
+ throw new Error(`switchOn("${opts.id}") cases[${i}] must be an object with \`when\` and \`do\`.`);
44
+ }
45
+ if (c.when === undefined) {
46
+ throw new Error(`switchOn("${opts.id}") cases[${i}] is missing \`when\` (the match value).`);
47
+ }
48
+ if (!Array.isArray(c.do) || c.do.length === 0) {
49
+ throw new Error(`switchOn("${opts.id}") cases[${i}] \`do\` must be a non-empty array of steps.`);
50
+ }
51
+ }
52
+ if (opts.default !== undefined) {
53
+ if (!Array.isArray(opts.default) || opts.default.length === 0) {
54
+ throw new Error(`switchOn("${opts.id}") \`default\` must be a non-empty array of steps when set.`);
55
+ }
56
+ }
57
+ const onExpr = unwrapProxies(opts.on);
58
+ const cases = opts.cases.map((c) => ({
59
+ when: unwrapProxies(c.when),
60
+ do: unwrapProxies(c.do),
61
+ }));
62
+ const result = {
63
+ id: opts.id,
64
+ switch: {
65
+ on: onExpr,
66
+ cases,
67
+ ...(opts.default !== undefined ? { default: unwrapProxies(opts.default) } : {}),
68
+ },
69
+ };
70
+ if (opts.active === false)
71
+ result.active = false;
72
+ if (opts.stop === true)
73
+ result.stop = true;
74
+ return result;
75
+ }
76
+ //# sourceMappingURL=switchOn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"switchOn.js","sourceRoot":"","sources":["../../src/components/switchOn.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ import type { V2Step, V2TryCatchStep } from "../types/StepOpts";
2
+ /**
3
+ * Author-facing options for {@link tryCatch}.
4
+ *
5
+ * `try` and `catch` are required and non-empty; `finally` is optional.
6
+ *
7
+ * Inside the `catch` block, `$.error.message`, `$.error.name`, and
8
+ * `$.error.stack` resolve at run time to the captured error info. In
9
+ * `try` and `finally`, `$.error` is undefined (the JS-like contract).
10
+ */
11
+ export interface TryCatchOpts {
12
+ /** Stable identifier — visible in traces, referenced as `$.state[id]`. */
13
+ id: string;
14
+ /** Sub-pipeline run first. If any step throws, control jumps to `catch`. */
15
+ try: V2Step[];
16
+ /**
17
+ * Sub-pipeline run when `try` throws. Has access to `$.error.{message,name,stack}`.
18
+ * Errors thrown inside `catch` propagate — they DO NOT re-trigger catch.
19
+ */
20
+ catch: V2Step[];
21
+ /**
22
+ * Sub-pipeline run unconditionally after try/catch. Runs even if `catch`
23
+ * itself throws. Errors thrown inside `finally` propagate.
24
+ */
25
+ finally?: V2Step[];
26
+ /** Skip this step at runtime. Default true (active). */
27
+ active?: boolean;
28
+ /** Halt the workflow after this step completes. */
29
+ stop?: boolean;
30
+ }
31
+ /**
32
+ * Create a tryCatch step — JS-like exception handling for sub-pipelines.
33
+ *
34
+ * Semantics mirror JavaScript's `try/catch/finally`:
35
+ * - `try` runs first.
36
+ * - On throw, `ctx.error` is set and `catch` runs.
37
+ * - `finally` runs unconditionally (after try success, after caught error,
38
+ * and after an uncaught throw from inside `catch`).
39
+ * - State mutations from any block are visible to subsequent top-level steps.
40
+ *
41
+ * @example
42
+ * tryCatch({
43
+ * id: "signup-saga",
44
+ * try: [
45
+ * { id: "create", use: "user-create", inputs: { email: $.req.body.email } },
46
+ * { id: "notify", use: "email-send", inputs: { to: $.state.create.email } },
47
+ * ],
48
+ * catch: [
49
+ * branch({
50
+ * id: "rollback-if-needed",
51
+ * when: '$.state.create !== undefined',
52
+ * then: [{ id: "del", use: "user-delete", inputs: { userId: $.state.create.id } }],
53
+ * }),
54
+ * { id: "respond-fail", use: "@blokjs/respond",
55
+ * inputs: { status: 500, body: { error: $.error.message } } },
56
+ * ],
57
+ * finally: [
58
+ * { id: "metric", use: "@blokjs/metrics-emit",
59
+ * inputs: { event: "signup-attempt" } },
60
+ * ],
61
+ * })
62
+ */
63
+ export declare function tryCatch(opts: TryCatchOpts): V2TryCatchStep;
@@ -0,0 +1,68 @@
1
+ import { unwrapProxies } from "../proxy/$";
2
+ /**
3
+ * Create a tryCatch step — JS-like exception handling for sub-pipelines.
4
+ *
5
+ * Semantics mirror JavaScript's `try/catch/finally`:
6
+ * - `try` runs first.
7
+ * - On throw, `ctx.error` is set and `catch` runs.
8
+ * - `finally` runs unconditionally (after try success, after caught error,
9
+ * and after an uncaught throw from inside `catch`).
10
+ * - State mutations from any block are visible to subsequent top-level steps.
11
+ *
12
+ * @example
13
+ * tryCatch({
14
+ * id: "signup-saga",
15
+ * try: [
16
+ * { id: "create", use: "user-create", inputs: { email: $.req.body.email } },
17
+ * { id: "notify", use: "email-send", inputs: { to: $.state.create.email } },
18
+ * ],
19
+ * catch: [
20
+ * branch({
21
+ * id: "rollback-if-needed",
22
+ * when: '$.state.create !== undefined',
23
+ * then: [{ id: "del", use: "user-delete", inputs: { userId: $.state.create.id } }],
24
+ * }),
25
+ * { id: "respond-fail", use: "@blokjs/respond",
26
+ * inputs: { status: 500, body: { error: $.error.message } } },
27
+ * ],
28
+ * finally: [
29
+ * { id: "metric", use: "@blokjs/metrics-emit",
30
+ * inputs: { event: "signup-attempt" } },
31
+ * ],
32
+ * })
33
+ */
34
+ export function tryCatch(opts) {
35
+ if (!opts || typeof opts !== "object") {
36
+ throw new Error("tryCatch() requires an options object.");
37
+ }
38
+ if (!opts.id || typeof opts.id !== "string") {
39
+ throw new Error("tryCatch() requires a non-empty `id` string.");
40
+ }
41
+ if (!Array.isArray(opts.try) || opts.try.length === 0) {
42
+ throw new Error(`tryCatch("${opts.id}") requires \`try\` to be a non-empty array of steps.`);
43
+ }
44
+ if (!Array.isArray(opts.catch) || opts.catch.length === 0) {
45
+ throw new Error(`tryCatch("${opts.id}") requires \`catch\` to be a non-empty array of steps.`);
46
+ }
47
+ if (opts.finally !== undefined) {
48
+ if (!Array.isArray(opts.finally) || opts.finally.length === 0) {
49
+ throw new Error(`tryCatch("${opts.id}") \`finally\` must be a non-empty array of steps when set.`);
50
+ }
51
+ }
52
+ const tryBlock = unwrapProxies(opts.try);
53
+ const catchBlock = unwrapProxies(opts.catch);
54
+ const result = {
55
+ id: opts.id,
56
+ tryCatch: {
57
+ try: tryBlock,
58
+ catch: catchBlock,
59
+ ...(opts.finally !== undefined ? { finally: unwrapProxies(opts.finally) } : {}),
60
+ },
61
+ };
62
+ if (opts.active === false)
63
+ result.active = false;
64
+ if (opts.stop === true)
65
+ result.stop = true;
66
+ return result;
67
+ }
68
+ //# sourceMappingURL=tryCatch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tryCatch.js","sourceRoot":"","sources":["../../src/components/tryCatch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAiC3C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAkB;IAC1C,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;IAC3D,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,OAAO,IAAI,CAAC,EAAE,KAAK,QAAQ,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IACjE,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvD,MAAM,IAAI,KAAK,CAAC,aAAa,IAAI,CAAC,EAAE,uDAAuD,CAAC,CAAC;IAC9F,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3D,MAAM,IAAI,KAAK,CAAC,aAAa,IAAI,CAAC,EAAE,yDAAyD,CAAC,CAAC;IAChG,CAAC;IACD,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAChC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/D,MAAM,IAAI,KAAK,CAAC,aAAa,IAAI,CAAC,EAAE,6DAA6D,CAAC,CAAC;QACpG,CAAC;IACF,CAAC;IAED,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,GAAG,CAAa,CAAC;IACrD,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,CAAC,KAAK,CAAa,CAAC;IACzD,MAAM,MAAM,GAAmB;QAC9B,EAAE,EAAE,IAAI,CAAC,EAAE;QACX,QAAQ,EAAE;YACT,GAAG,EAAE,QAAQ;YACb,KAAK,EAAE,UAAU;YACjB,GAAG,CAAC,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,aAAa,CAAC,IAAI,CAAC,OAAO,CAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC3F;KACD,CAAC;IACF,IAAI,IAAI,CAAC,MAAM,KAAK,KAAK;QAAG,MAA+C,CAAC,MAAM,GAAG,KAAK,CAAC;IAC3F,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI;QAAG,MAA6C,CAAC,IAAI,GAAG,IAAI,CAAC;IACnF,OAAO,MAAM,CAAC;AACf,CAAC"}
@@ -0,0 +1,83 @@
1
+ import { type V2Step } from "../types/StepOpts";
2
+ import type { WorkflowV2 } from "../types/WorkflowOpts";
3
+ /**
4
+ * V2 workflow author input — strict TypeScript shape with the user-facing
5
+ * fields the lowercase `workflow()` factory accepts.
6
+ */
7
+ export interface WorkflowOpts {
8
+ /** Workflow display name. Min 3 characters. Shown in Studio. */
9
+ name: string;
10
+ /** Semantic version (x.x.x). Used for trace recording and audit. */
11
+ version: string;
12
+ /** What this workflow does. Optional but recommended. */
13
+ description?: string;
14
+ /**
15
+ * Trigger configuration. Most workflows use a single key:
16
+ * `{ http: { method: "GET" } }`
17
+ * `{ cron: { schedule: "0 * * * *" } }`
18
+ * `{ queue: { provider: "kafka", topic: "..." } }`
19
+ *
20
+ * See `TRIGGER_SCHEMAS` for per-kind shapes. Validated per-kind at
21
+ * factory time.
22
+ */
23
+ trigger: Record<string, unknown>;
24
+ /** Pipeline of steps to execute in order. At least one required. */
25
+ steps: V2Step[];
26
+ }
27
+ /**
28
+ * The shape returned by `workflow()`. Tagged with `_blokV2: true` so the
29
+ * scanner / loader can detect a v2-shape default export and route it
30
+ * through the v1→v2 normalizer cleanly. The internal `_config` field
31
+ * mirrors the legacy v1 builder output for back-compat with code that
32
+ * already reads `step._config.trigger` etc.
33
+ */
34
+ export interface WorkflowV2Builder {
35
+ readonly _blokV2: true;
36
+ readonly _config: WorkflowV2;
37
+ /**
38
+ * Serialize the wrapped workflow to a JSON string. Mirrors the
39
+ * `HelperResponse.toJson()` contract so v2 builders are
40
+ * structurally compatible with the v1 workflow registry
41
+ * (`Workflows` map → `LocalStorage.get` fallback).
42
+ */
43
+ toJson(): string;
44
+ }
45
+ /**
46
+ * Lowercase v2 workflow factory. Validates inputs against the v2 schema,
47
+ * compiles any `$` proxy expressions inside step `inputs` into
48
+ * `"js/ctx..."` strings at definition time, and returns a tagged object
49
+ * the runner's normalizer recognizes.
50
+ *
51
+ * Differences from the legacy `Workflow()` (capital W):
52
+ * - **No chaining.** The full workflow is a single object literal —
53
+ * exactly what JSON workflows look like.
54
+ * - **No separate `nodes{}` map.** `inputs` lives on each step.
55
+ * - **Default-store** — every step's output auto-stores in `ctx.state`.
56
+ * Opt out with `ephemeral: true`. Multi-output: `spread: true`. Rename:
57
+ * `as: "<name>"`.
58
+ * - **`branch({when, then, else})`** replaces `addCondition + AddIf + AddElse`.
59
+ * - **`$` proxy** replaces hand-written `js/ctx....` strings with typed
60
+ * property access.
61
+ *
62
+ * @example
63
+ * import { workflow, branch, $ } from "@blokjs/helper";
64
+ *
65
+ * export default workflow({
66
+ * name: "World Countries",
67
+ * version: "1.0.0",
68
+ * trigger: { http: { method: "GET" } },
69
+ * steps: [
70
+ * { id: "fetch", use: "@blokjs/api-call",
71
+ * inputs: { url: "https://countriesnow.space/api/v0.1/countries" } },
72
+ * branch({
73
+ * id: "route",
74
+ * when: $.req.query.kind,
75
+ * then: [{ id: "respond", use: "@blokjs/respond",
76
+ * inputs: { body: $.state.fetch } }],
77
+ * else: [{ id: "fallback", use: "@blokjs/api-call",
78
+ * inputs: { url: "https://catfact.ninja/fact" } }]
79
+ * })
80
+ * ]
81
+ * });
82
+ */
83
+ export declare function workflow(opts: WorkflowOpts): WorkflowV2Builder;
@@ -0,0 +1,84 @@
1
+ import { unwrapProxies } from "../proxy/$";
2
+ import { V2StepSchema } from "../types/StepOpts";
3
+ import { TriggersSchema, validateTriggerConfig } from "../types/TriggerOpts";
4
+ /**
5
+ * Lowercase v2 workflow factory. Validates inputs against the v2 schema,
6
+ * compiles any `$` proxy expressions inside step `inputs` into
7
+ * `"js/ctx..."` strings at definition time, and returns a tagged object
8
+ * the runner's normalizer recognizes.
9
+ *
10
+ * Differences from the legacy `Workflow()` (capital W):
11
+ * - **No chaining.** The full workflow is a single object literal —
12
+ * exactly what JSON workflows look like.
13
+ * - **No separate `nodes{}` map.** `inputs` lives on each step.
14
+ * - **Default-store** — every step's output auto-stores in `ctx.state`.
15
+ * Opt out with `ephemeral: true`. Multi-output: `spread: true`. Rename:
16
+ * `as: "<name>"`.
17
+ * - **`branch({when, then, else})`** replaces `addCondition + AddIf + AddElse`.
18
+ * - **`$` proxy** replaces hand-written `js/ctx....` strings with typed
19
+ * property access.
20
+ *
21
+ * @example
22
+ * import { workflow, branch, $ } from "@blokjs/helper";
23
+ *
24
+ * export default workflow({
25
+ * name: "World Countries",
26
+ * version: "1.0.0",
27
+ * trigger: { http: { method: "GET" } },
28
+ * steps: [
29
+ * { id: "fetch", use: "@blokjs/api-call",
30
+ * inputs: { url: "https://countriesnow.space/api/v0.1/countries" } },
31
+ * branch({
32
+ * id: "route",
33
+ * when: $.req.query.kind,
34
+ * then: [{ id: "respond", use: "@blokjs/respond",
35
+ * inputs: { body: $.state.fetch } }],
36
+ * else: [{ id: "fallback", use: "@blokjs/api-call",
37
+ * inputs: { url: "https://catfact.ninja/fact" } }]
38
+ * })
39
+ * ]
40
+ * });
41
+ */
42
+ export function workflow(opts) {
43
+ if (!opts || typeof opts !== "object") {
44
+ throw new Error("workflow() requires an options object.");
45
+ }
46
+ // Compile $ proxy expressions into js/ strings BEFORE schema validation
47
+ // (the schema sees only strings; proxies would fail z.string().min(1)).
48
+ const compiledSteps = unwrapProxies(opts.steps);
49
+ // Per-step schema check — surface authoring errors loudly.
50
+ for (let i = 0; i < compiledSteps.length; i++) {
51
+ const parsed = V2StepSchema.safeParse(compiledSteps[i]);
52
+ if (!parsed.success) {
53
+ const id = compiledSteps[i]?.id ?? compiledSteps[i]?.name ?? `<step ${i}>`;
54
+ throw new Error(`workflow("${opts.name}") step "${id}" failed validation: ${parsed.error.message}`);
55
+ }
56
+ }
57
+ // Per-kind trigger validation. Mirrors what `Trigger.addTrigger` does
58
+ // in the v1 builder so v2 authors get the same error messages.
59
+ const triggerKeys = Object.keys(opts.trigger ?? {});
60
+ if (triggerKeys.length === 0) {
61
+ throw new Error(`workflow("${opts.name}") requires a trigger.`);
62
+ }
63
+ const validatedTrigger = {};
64
+ for (const kind of triggerKeys) {
65
+ const parsedKind = TriggersSchema.safeParse(kind);
66
+ if (!parsedKind.success) {
67
+ throw new Error(`workflow("${opts.name}") trigger kind "${kind}" is not recognized. Allowed: http, queue, pubsub, worker, cron, webhook, sse, websocket, grpc, manual.`);
68
+ }
69
+ validatedTrigger[kind] = validateTriggerConfig(parsedKind.data, opts.trigger[kind]);
70
+ }
71
+ const _config = {
72
+ name: opts.name,
73
+ version: opts.version,
74
+ description: opts.description,
75
+ trigger: validatedTrigger,
76
+ steps: compiledSteps,
77
+ };
78
+ return Object.freeze({
79
+ _blokV2: true,
80
+ _config,
81
+ toJson: () => JSON.stringify(_config),
82
+ });
83
+ }
84
+ //# sourceMappingURL=workflowV2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflowV2.js","sourceRoot":"","sources":["../../src/components/workflowV2.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAe,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AA+C7E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAkB;IAC1C,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;IAC3D,CAAC;IAED,wEAAwE;IACxE,wEAAwE;IACxE,MAAM,aAAa,GAAG,aAAa,CAAC,IAAI,CAAC,KAAK,CAAa,CAAC;IAE5D,2DAA2D;IAC3D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/C,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;QACxD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACrB,MAAM,EAAE,GACN,aAAa,CAAC,CAAC,CAAqB,EAAE,EAAE,IAAK,aAAa,CAAC,CAAC,CAAuB,EAAE,IAAI,IAAI,SAAS,CAAC,GAAG,CAAC;YAC7G,MAAM,IAAI,KAAK,CAAC,aAAa,IAAI,CAAC,IAAI,YAAY,EAAE,wBAAwB,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACrG,CAAC;IACF,CAAC;IAED,sEAAsE;IACtE,+DAA+D;IAC/D,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;IACpD,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,aAAa,IAAI,CAAC,IAAI,wBAAwB,CAAC,CAAC;IACjE,CAAC;IACD,MAAM,gBAAgB,GAA4B,EAAE,CAAC;IACrD,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;QAChC,MAAM,UAAU,GAAG,cAAc,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAClD,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CACd,aAAa,IAAI,CAAC,IAAI,oBAAoB,IAAI,yGAAyG,CACvJ,CAAC;QACH,CAAC;QACD,gBAAgB,CAAC,IAAI,CAAC,GAAG,qBAAqB,CAAC,UAAU,CAAC,IAAI,EAAG,IAAI,CAAC,OAAmC,CAAC,IAAI,CAAC,CAAC,CAAC;IAClH,CAAC;IAED,MAAM,OAAO,GAAe;QAC3B,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,OAAO,EAAE,gBAAgB;QACzB,KAAK,EAAE,aAAa;KACpB,CAAC;IAEF,OAAO,MAAM,CAAC,MAAM,CAAC;QACpB,OAAO,EAAE,IAAa;QACtB,OAAO;QACP,MAAM,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;KACrC,CAAC,CAAC;AACJ,CAAC"}
package/dist/index.d.ts CHANGED
@@ -4,6 +4,15 @@ import HelperResponse from "./components/HelperResponse";
4
4
  import Step from "./components/StepNode";
5
5
  import Trigger from "./components/Trigger";
6
6
  import Workflow from "./components/Workflow";
7
- import { NodeType, NodeTypeSchema, RuntimeKind, RuntimeKindSchema, StepInputs, StepOpts } from "./types/StepOpts";
8
- import { CronTriggerOpts, CronTriggerOptsSchema, HttpTriggerOptsSchema, PubSubProvider, PubSubProviderSchema, PubSubTriggerOpts, PubSubTriggerOptsSchema, QueueProvider, QueueProviderSchema, QueueTriggerOpts, QueueTriggerOptsSchema, SSETriggerOpts, SSETriggerOptsSchema, TriggerOpts, TriggerOptsSchema, TriggersEnum, TriggersSchema, WebSocketTriggerOpts, WebSocketTriggerOptsSchema, WebhookTriggerOpts, WebhookTriggerOptsSchema, WorkerTriggerOpts, WorkerTriggerOptsSchema } from "./types/TriggerOpts";
9
- export { AddElse, AddIf, ConditionOpts, HelperResponse, NodeType, NodeTypeSchema, RuntimeKind, RuntimeKindSchema, Step, StepInputs, StepOpts, Trigger, Workflow, TriggerOpts, TriggerOptsSchema, HttpTriggerOptsSchema, QueueProvider, QueueProviderSchema, QueueTriggerOpts, QueueTriggerOptsSchema, PubSubProvider, PubSubProviderSchema, PubSubTriggerOpts, PubSubTriggerOptsSchema, WorkerTriggerOpts, WorkerTriggerOptsSchema, CronTriggerOpts, CronTriggerOptsSchema, WebhookTriggerOpts, WebhookTriggerOptsSchema, WebSocketTriggerOpts, WebSocketTriggerOptsSchema, SSETriggerOpts, SSETriggerOptsSchema, TriggersSchema, TriggersEnum, };
7
+ import { type BranchOpts, branch } from "./components/branch";
8
+ import { type ForEachOpts, forEach } from "./components/forEach";
9
+ import { type LoopOpts, loop } from "./components/loop";
10
+ import { type SwitchCase, type SwitchOpts, switchOn } from "./components/switchOn";
11
+ import { type TryCatchOpts, tryCatch } from "./components/tryCatch";
12
+ import { type WorkflowV2Builder, type WorkflowOpts as WorkflowV2Opts, workflow } from "./components/workflowV2";
13
+ import { $, type DollarProxy, type ExprPath, JS_EXPR_TAG, unwrapProxies } from "./proxy/$";
14
+ import { NodeType, NodeTypeSchema, RetryConfig, RetryConfigSchema, RuntimeKind, RuntimeKindSchema, StepInputs, StepOpts, V2BranchStep, V2BranchStepSchema, V2ForEachStep, V2ForEachStepSchema, V2LoopStep, V2LoopStepSchema, V2RegularStep, V2RegularStepSchema, V2Step, V2StepSchema, V2SubworkflowStep, V2SubworkflowStepSchema, V2SwitchStep, V2SwitchStepSchema, V2TryCatchStep, V2TryCatchStepSchema, V2WaitStep, V2WaitStepSchema, isBranchStep, isForEachStep, isLoopStep, isSubworkflowStep, isSwitchStep, isTryCatchStep, isWaitStep } from "./types/StepOpts";
15
+ import { AnyTriggerOpts, ConcurrencyOpts, ConcurrencyOptsFields, ConcurrencyOptsSchema, CronTriggerOpts, CronTriggerOptsSchema, DebounceOpts, DebounceOptsSchema, HTTP_METHODS, HttpMethod, HttpMethodSchema, HttpTriggerOpts, HttpTriggerOptsSchema, PubSubProvider, PubSubProviderSchema, PubSubTriggerOpts, PubSubTriggerOptsSchema, QueueProvider, QueueProviderSchema, QueueTriggerOpts, QueueTriggerOptsSchema, SSETriggerOpts, SSETriggerOptsSchema, SchedulingOpts, SchedulingOptsFields, SchedulingOptsSchema, TRIGGER_SCHEMAS, TriggerConfigMap, TriggerOpts, TriggerOptsSchema, TriggersEnum, TriggersSchema, WebSocketTriggerOpts, WebSocketTriggerOptsSchema, WebhookTriggerOpts, WebhookTriggerOptsSchema, WorkerProvider, WorkerProviderSchema, WorkerTriggerOpts, WorkerTriggerOptsSchema, concurrencyRefinement, makeSchedulingRefinement, validateTriggerConfig } from "./types/TriggerOpts";
16
+ import { WorkflowV2, WorkflowV2Schema } from "./types/WorkflowOpts";
17
+ import { parseDuration, tryParseDuration } from "./utils/parseDuration";
18
+ export { AddElse, AddIf, ConditionOpts, HelperResponse, NodeType, NodeTypeSchema, RuntimeKind, RuntimeKindSchema, Step, StepInputs, StepOpts, Trigger, Workflow, workflow, branch, forEach, loop, switchOn, tryCatch, $, unwrapProxies, type BranchOpts, type ForEachOpts, type LoopOpts, type SwitchOpts, type SwitchCase, type TryCatchOpts, type WorkflowV2Opts, type WorkflowV2Builder, type DollarProxy, type ExprPath, JS_EXPR_TAG, V2Step, V2StepSchema, V2RegularStep, V2RegularStepSchema, V2BranchStep, V2BranchStepSchema, isBranchStep, V2SubworkflowStep, V2SubworkflowStepSchema, isSubworkflowStep, V2WaitStep, V2WaitStepSchema, isWaitStep, V2ForEachStep, V2ForEachStepSchema, isForEachStep, V2LoopStep, V2LoopStepSchema, isLoopStep, V2SwitchStep, V2SwitchStepSchema, isSwitchStep, V2TryCatchStep, V2TryCatchStepSchema, isTryCatchStep, RetryConfig, RetryConfigSchema, WorkflowV2, WorkflowV2Schema, HTTP_METHODS, HttpMethod, HttpMethodSchema, ConcurrencyOpts, ConcurrencyOptsFields, ConcurrencyOptsSchema, concurrencyRefinement, DebounceOpts, DebounceOptsSchema, makeSchedulingRefinement, SchedulingOpts, SchedulingOptsFields, SchedulingOptsSchema, HttpTriggerOpts, HttpTriggerOptsSchema, TriggerOpts, TriggerOptsSchema, QueueProvider, QueueProviderSchema, QueueTriggerOpts, QueueTriggerOptsSchema, PubSubProvider, PubSubProviderSchema, PubSubTriggerOpts, PubSubTriggerOptsSchema, WorkerProvider, WorkerProviderSchema, WorkerTriggerOpts, WorkerTriggerOptsSchema, CronTriggerOpts, CronTriggerOptsSchema, WebhookTriggerOpts, WebhookTriggerOptsSchema, WebSocketTriggerOpts, WebSocketTriggerOptsSchema, SSETriggerOpts, SSETriggerOptsSchema, TriggersSchema, TriggersEnum, TriggerConfigMap, TRIGGER_SCHEMAS, AnyTriggerOpts, validateTriggerConfig, parseDuration, tryParseDuration, };
package/dist/index.js CHANGED
@@ -4,9 +4,30 @@ import HelperResponse from "./components/HelperResponse";
4
4
  import Step from "./components/StepNode";
5
5
  import Trigger from "./components/Trigger";
6
6
  import Workflow from "./components/Workflow";
7
- import { NodeTypeSchema, RuntimeKindSchema } from "./types/StepOpts";
8
- import { CronTriggerOptsSchema, HttpTriggerOptsSchema, PubSubProviderSchema, PubSubTriggerOptsSchema, QueueProviderSchema, QueueTriggerOptsSchema, SSETriggerOptsSchema, TriggerOptsSchema,
7
+ import { branch } from "./components/branch";
8
+ import { forEach } from "./components/forEach";
9
+ import { loop } from "./components/loop";
10
+ import { switchOn } from "./components/switchOn";
11
+ import { tryCatch } from "./components/tryCatch";
12
+ import { workflow } from "./components/workflowV2";
13
+ import { $, JS_EXPR_TAG, unwrapProxies } from "./proxy/$";
14
+ import { NodeTypeSchema, RetryConfigSchema, RuntimeKindSchema, V2BranchStepSchema, V2ForEachStepSchema, V2LoopStepSchema, V2RegularStepSchema, V2StepSchema, V2SubworkflowStepSchema, V2SwitchStepSchema, V2TryCatchStepSchema, V2WaitStepSchema, isBranchStep, isForEachStep, isLoopStep, isSubworkflowStep, isSwitchStep, isTryCatchStep, isWaitStep, } from "./types/StepOpts";
15
+ import { ConcurrencyOptsFields, ConcurrencyOptsSchema, CronTriggerOptsSchema, DebounceOptsSchema,
16
+ // HTTP method enum (canonical names + legacy * preprocess)
17
+ HTTP_METHODS, HttpMethodSchema, HttpTriggerOptsSchema, PubSubProviderSchema, PubSubTriggerOptsSchema, QueueProviderSchema, QueueTriggerOptsSchema, SSETriggerOptsSchema, SchedulingOptsFields, SchedulingOptsSchema,
18
+ // Trigger registry
19
+ TRIGGER_SCHEMAS, TriggerOptsSchema,
9
20
  // Triggers enum
10
- TriggersSchema, WebSocketTriggerOptsSchema, WebhookTriggerOptsSchema, WorkerTriggerOptsSchema, } from "./types/TriggerOpts";
11
- export { AddElse, AddIf, HelperResponse, NodeTypeSchema, RuntimeKindSchema, Step, Trigger, Workflow, TriggerOptsSchema, HttpTriggerOptsSchema, QueueProviderSchema, QueueTriggerOptsSchema, PubSubProviderSchema, PubSubTriggerOptsSchema, WorkerTriggerOptsSchema, CronTriggerOptsSchema, WebhookTriggerOptsSchema, WebSocketTriggerOptsSchema, SSETriggerOptsSchema, TriggersSchema, };
21
+ TriggersSchema, WebSocketTriggerOptsSchema, WebhookTriggerOptsSchema, WorkerProviderSchema, WorkerTriggerOptsSchema, concurrencyRefinement, makeSchedulingRefinement, validateTriggerConfig, } from "./types/TriggerOpts";
22
+ import { WorkflowV2Schema } from "./types/WorkflowOpts";
23
+ import { parseDuration, tryParseDuration } from "./utils/parseDuration";
24
+ export { AddElse, AddIf, HelperResponse, NodeTypeSchema, RuntimeKindSchema, Step, Trigger, Workflow,
25
+ // v2 DSL primitives — the canonical authoring surface
26
+ workflow, branch,
27
+ // v0.5 control-flow primitives
28
+ forEach, loop, switchOn, tryCatch, $, unwrapProxies, JS_EXPR_TAG, V2StepSchema, V2RegularStepSchema, V2BranchStepSchema, isBranchStep, V2SubworkflowStepSchema, isSubworkflowStep, V2WaitStepSchema, isWaitStep, V2ForEachStepSchema, isForEachStep, V2LoopStepSchema, isLoopStep, V2SwitchStepSchema, isSwitchStep, V2TryCatchStepSchema, isTryCatchStep, RetryConfigSchema, WorkflowV2Schema,
29
+ // HTTP method enum
30
+ HTTP_METHODS, HttpMethodSchema, ConcurrencyOptsFields, ConcurrencyOptsSchema, concurrencyRefinement, DebounceOptsSchema, makeSchedulingRefinement, SchedulingOptsFields, SchedulingOptsSchema, HttpTriggerOptsSchema, TriggerOptsSchema, QueueProviderSchema, QueueTriggerOptsSchema, PubSubProviderSchema, PubSubTriggerOptsSchema, WorkerProviderSchema, WorkerTriggerOptsSchema, CronTriggerOptsSchema, WebhookTriggerOptsSchema, WebSocketTriggerOptsSchema, SSETriggerOptsSchema, TriggersSchema, TRIGGER_SCHEMAS, validateTriggerConfig,
31
+ // Duration parser (Tier 2 #5 + #7)
32
+ parseDuration, tryParseDuration, };
12
33
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,sBAAsB,CAAC;AAC3C,OAAO,KAAwB,MAAM,oBAAoB,CAAC;AAC1D,OAAO,cAAc,MAAM,6BAA6B,CAAC;AACzD,OAAO,IAAI,MAAM,uBAAuB,CAAC;AACzC,OAAO,OAAO,MAAM,sBAAsB,CAAC;AAC3C,OAAO,QAAQ,MAAM,uBAAuB,CAAC;AAC7C,OAAO,EAAY,cAAc,EAAe,iBAAiB,EAAwB,MAAM,kBAAkB,CAAC;AAClH,OAAO,EAGN,qBAAqB,EACrB,qBAAqB,EAGrB,oBAAoB,EAEpB,uBAAuB,EAGvB,mBAAmB,EAEnB,sBAAsB,EAGtB,oBAAoB,EAGpB,iBAAiB;AAEjB,gBAAgB;AAChB,cAAc,EAGd,0BAA0B,EAG1B,wBAAwB,EAGxB,uBAAuB,GACvB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACN,OAAO,EACP,KAAK,EAEL,cAAc,EAEd,cAAc,EAEd,iBAAiB,EACjB,IAAI,EAGJ,OAAO,EACP,QAAQ,EAGR,iBAAiB,EACjB,qBAAqB,EAErB,mBAAmB,EAEnB,sBAAsB,EAEtB,oBAAoB,EAEpB,uBAAuB,EAEvB,uBAAuB,EAEvB,qBAAqB,EAErB,wBAAwB,EAExB,0BAA0B,EAE1B,oBAAoB,EACpB,cAAc,GAEd,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,102 @@
1
+ /**
2
+ * The typed `$` proxy — typed sugar over the runtime's `js/...` resolver.
3
+ *
4
+ * Property access on `$` builds a path string at definition time. The
5
+ * `unwrapProxies` deep-walk in the `workflow()` factory replaces each proxy
6
+ * value with its compiled `"js/ctx.<path>"` string before the workflow is
7
+ * handed to the runner. This means:
8
+ *
9
+ * - Authors get IDE autocomplete on `$.req.body.foo`, `$.state.users[0]`, etc.
10
+ * - The runtime sees plain strings (no Proxy traversal at execution time).
11
+ * - The existing `Mapper.jsMapper` resolver works unchanged — it already
12
+ * evaluates `js/...` strings against `ctx`.
13
+ *
14
+ * @example
15
+ * import { workflow, $ } from "@blokjs/helper";
16
+ *
17
+ * workflow({
18
+ * trigger: { http: { method: "GET" } },
19
+ * steps: [
20
+ * { id: "fetch", use: "@blokjs/api-call",
21
+ * inputs: { userId: $.req.params.id } },
22
+ * { id: "respond", use: "@blokjs/respond",
23
+ * inputs: { body: $.state.fetch } }
24
+ * ]
25
+ * });
26
+ * // After `unwrapProxies` runs at definition time:
27
+ * // inputs.userId === "js/ctx.req.params.id"
28
+ * // inputs.body === "js/ctx.state.fetch"
29
+ */
30
+ /** Internal symbol used to detect proxy values during the deep-walk. */
31
+ export declare const JS_EXPR_TAG: unique symbol;
32
+ /**
33
+ * The shape of any sub-path of the `$` proxy. Property and index access
34
+ * are recursive; string conversion produces a `js/ctx....` literal.
35
+ *
36
+ * Typed as `unknown` at the leaves so authors can pass a path anywhere a
37
+ * value of any type is expected without `as` casts.
38
+ */
39
+ export type ExprPath = {
40
+ readonly [key: string]: ExprPath;
41
+ } & {
42
+ toString(): string;
43
+ toJSON(): string;
44
+ };
45
+ /**
46
+ * The top-level `$` proxy. Provides typed access to:
47
+ * - `$.req` — request envelope (alias of `ctx.request`)
48
+ * - `$.prev` — previous step's response envelope (alias of `ctx.response`)
49
+ * - `$.state` — accumulated step outputs by step id
50
+ * - `$.env` — process env mirror
51
+ * - `$.step` — current step metadata (`{ name, index, total, depth }`)
52
+ * - `$.workflow` — current workflow metadata
53
+ *
54
+ * Plus legacy fallbacks for `$.request` (= `$.req`) and `$.response` (= `$.prev`).
55
+ */
56
+ export interface DollarProxy {
57
+ readonly req: ExprPath;
58
+ readonly request: ExprPath;
59
+ readonly prev: ExprPath;
60
+ readonly response: ExprPath;
61
+ readonly state: ExprPath;
62
+ readonly vars: ExprPath;
63
+ readonly env: ExprPath;
64
+ readonly step: ExprPath;
65
+ readonly workflow: ExprPath;
66
+ /**
67
+ * The captured error inside a `tryCatch.catch` block (v0.5).
68
+ * Resolves to `ctx.error`; undefined inside `try`, `finally`, and
69
+ * any step outside a tryCatch. Use `$.error.message`, `$.error.name`,
70
+ * `$.error.stack`.
71
+ */
72
+ readonly error: ExprPath;
73
+ /** Escape hatch — any property; returns a sub-path. */
74
+ readonly [key: string]: ExprPath;
75
+ }
76
+ /**
77
+ * The `$` proxy entry point. All paths root at `ctx`.
78
+ *
79
+ * @see DollarProxy for the typed surface.
80
+ */
81
+ export declare const $: DollarProxy;
82
+ /**
83
+ * Recursively replace any `$` proxy values inside `value` with their
84
+ * compiled `"js/ctx.<path>"` strings.
85
+ *
86
+ * Called by `workflow()` and `branch()` factories at definition time to
87
+ * convert in-memory proxy references into the wire-shape strings the
88
+ * runner's `Mapper` expects.
89
+ *
90
+ * Unwraps:
91
+ * - Proxies → `"js/ctx.<path>"` strings
92
+ * - Plain objects → walked recursively, returning a NEW object
93
+ * - Arrays → walked, returning a NEW array
94
+ *
95
+ * Leaves alone:
96
+ * - Primitives (string, number, boolean, null, undefined)
97
+ * - Class instances (anything with a non-Object prototype)
98
+ * - Functions other than the proxy itself
99
+ *
100
+ * Pure — never mutates the input.
101
+ */
102
+ export declare function unwrapProxies<T>(value: T): T;