@blokjs/shared 0.6.17 → 0.6.19
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/utils/Mapper.d.ts +14 -1
- package/dist/utils/Mapper.js +29 -2
- package/dist/utils/Mapper.js.map +1 -1
- package/package.json +2 -1
- package/CHANGELOG.md +0 -69
- package/__tests__/unit/BlokError.test.ts +0 -294
- package/__tests__/unit/GlobalError.test.ts +0 -93
- package/__tests__/unit/GlobalLogger.test.ts +0 -77
- package/__tests__/unit/Metrics.test.ts +0 -77
- package/__tests__/unit/NodeBase.test.ts +0 -290
- package/__tests__/unit/Trigger.test.ts +0 -23
- package/__tests__/unit/utils/CpuUsage.test.ts +0 -102
- package/__tests__/unit/utils/Mapper.test.ts +0 -393
- package/__tests__/unit/utils/MapperResolutionError.test.ts +0 -64
- package/__tests__/unit/utils/MemoryUsage.test.ts +0 -121
- package/__tests__/unit/utils/Time.test.ts +0 -60
- package/tsconfig.json +0 -19
- package/vitest.config.ts +0 -29
package/dist/utils/Mapper.d.ts
CHANGED
|
@@ -65,9 +65,22 @@ declare class Mapper {
|
|
|
65
65
|
* resolve a step's `inputs` against the live `ctx` before the
|
|
66
66
|
* step runs.
|
|
67
67
|
*
|
|
68
|
-
*
|
|
68
|
+
* Plain object/array values are recursed into; primitive non-string
|
|
69
69
|
* values are left untouched. Null values are NOT recursed (avoids
|
|
70
70
|
* a TypeError on `for (const k in null)`).
|
|
71
|
+
*
|
|
72
|
+
* **CLASS INSTANCES ARE NOT RECURSED.** Step `inputs` are always plain
|
|
73
|
+
* JSON-like data, so resolution is unaffected. But a step's resolved
|
|
74
|
+
* config can embed framework objects with custom prototypes — most
|
|
75
|
+
* dangerously a `SubworkflowNode` instance (inside a forEach `steps`
|
|
76
|
+
* array) whose `globalOptions.workflows` holds EVERY registered
|
|
77
|
+
* workflow's definition. Recursing into those made the mapper evaluate
|
|
78
|
+
* (and mutate, in place) every OTHER workflow's `js/...` expressions
|
|
79
|
+
* against the current ctx — surfacing as `Failed to resolve` errors
|
|
80
|
+
* referencing an unrelated workflow's expression, or a hard failure in
|
|
81
|
+
* strict mode. Limiting recursion to plain containers cuts that whole
|
|
82
|
+
* object graph off at the boundary. (Regression: cross-workflow
|
|
83
|
+
* expression leak via forEach + subworkflow.)
|
|
71
84
|
*/
|
|
72
85
|
replaceObjectStrings(obj: ParamsDictionary, ctx: Context, data: ParamsDictionary): void;
|
|
73
86
|
/**
|
package/dist/utils/Mapper.js
CHANGED
|
@@ -133,6 +133,20 @@ function toInterpolatedString(value) {
|
|
|
133
133
|
return String(value);
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
|
+
/**
|
|
137
|
+
* Is `value` a plain container the mapper may safely recurse into — a plain
|
|
138
|
+
* object (prototype `Object.prototype` or null) or an array? Class instances
|
|
139
|
+
* (RunnerNode, SubworkflowNode, WorkflowV2Builder, Date, Buffer, Map, …) have
|
|
140
|
+
* a custom prototype and are NOT recursed: step inputs are always plain data,
|
|
141
|
+
* and recursing into framework instances can reach internal object graphs
|
|
142
|
+
* (e.g. `globalOptions.workflows`) that must never be resolved as inputs.
|
|
143
|
+
*/
|
|
144
|
+
function isPlainContainer(value) {
|
|
145
|
+
if (Array.isArray(value))
|
|
146
|
+
return true;
|
|
147
|
+
const proto = Object.getPrototypeOf(value);
|
|
148
|
+
return proto === Object.prototype || proto === null;
|
|
149
|
+
}
|
|
136
150
|
// =============================================================================
|
|
137
151
|
// Mapper
|
|
138
152
|
// =============================================================================
|
|
@@ -143,9 +157,22 @@ class Mapper {
|
|
|
143
157
|
* resolve a step's `inputs` against the live `ctx` before the
|
|
144
158
|
* step runs.
|
|
145
159
|
*
|
|
146
|
-
*
|
|
160
|
+
* Plain object/array values are recursed into; primitive non-string
|
|
147
161
|
* values are left untouched. Null values are NOT recursed (avoids
|
|
148
162
|
* a TypeError on `for (const k in null)`).
|
|
163
|
+
*
|
|
164
|
+
* **CLASS INSTANCES ARE NOT RECURSED.** Step `inputs` are always plain
|
|
165
|
+
* JSON-like data, so resolution is unaffected. But a step's resolved
|
|
166
|
+
* config can embed framework objects with custom prototypes — most
|
|
167
|
+
* dangerously a `SubworkflowNode` instance (inside a forEach `steps`
|
|
168
|
+
* array) whose `globalOptions.workflows` holds EVERY registered
|
|
169
|
+
* workflow's definition. Recursing into those made the mapper evaluate
|
|
170
|
+
* (and mutate, in place) every OTHER workflow's `js/...` expressions
|
|
171
|
+
* against the current ctx — surfacing as `Failed to resolve` errors
|
|
172
|
+
* referencing an unrelated workflow's expression, or a hard failure in
|
|
173
|
+
* strict mode. Limiting recursion to plain containers cuts that whole
|
|
174
|
+
* object graph off at the boundary. (Regression: cross-workflow
|
|
175
|
+
* expression leak via forEach + subworkflow.)
|
|
149
176
|
*/
|
|
150
177
|
replaceObjectStrings(obj, ctx, data) {
|
|
151
178
|
for (const key in obj) {
|
|
@@ -162,7 +189,7 @@ class Mapper {
|
|
|
162
189
|
// (a much larger refactor).
|
|
163
190
|
obj[key] = this.replaceString(value, ctx, data);
|
|
164
191
|
}
|
|
165
|
-
else if (value !== null && typeof value === "object") {
|
|
192
|
+
else if (value !== null && typeof value === "object" && isPlainContainer(value)) {
|
|
166
193
|
this.replaceObjectStrings(value, ctx, data);
|
|
167
194
|
}
|
|
168
195
|
}
|
package/dist/utils/Mapper.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Mapper.js","sourceRoot":"","sources":["../../src/utils/Mapper.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"Mapper.js","sourceRoot":"","sources":["../../src/utils/Mapper.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/CHANGELOG.md
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
# @blokjs/shared
|
|
2
|
-
|
|
3
|
-
## 0.2.0
|
|
4
|
-
|
|
5
|
-
### Minor Changes
|
|
6
|
-
|
|
7
|
-
- Initial public release of Blok packages.
|
|
8
|
-
|
|
9
|
-
This release includes:
|
|
10
|
-
|
|
11
|
-
- Core packages: @blokjs/shared, @blokjs/helper, @blokjs/runner
|
|
12
|
-
- Node packages: @blokjs/api-call, @blokjs/if-else, @blokjs/react
|
|
13
|
-
- Trigger packages: pubsub, queue, webhook, websocket, worker, cron, grpc
|
|
14
|
-
- CLI tool: blokctl
|
|
15
|
-
- Editor support: @blokjs/lsp-server, @blokjs/syntax
|
|
16
|
-
|
|
17
|
-
## 0.0.9
|
|
18
|
-
|
|
19
|
-
### Patch Changes
|
|
20
|
-
|
|
21
|
-
- Python3 runtime implemented in the runner
|
|
22
|
-
|
|
23
|
-
## 0.0.8
|
|
24
|
-
|
|
25
|
-
### Patch Changes
|
|
26
|
-
|
|
27
|
-
- Added examples and create project' command to include examples and 'create node' command with options for type ('module' or 'class') and template ('class' or 'ui')
|
|
28
|
-
|
|
29
|
-
## 0.0.7
|
|
30
|
-
|
|
31
|
-
### Patch Changes
|
|
32
|
-
|
|
33
|
-
- Added support for YAML, XML and TOML in the workflow file. Upgraded package version recommended by Dependabot.
|
|
34
|
-
|
|
35
|
-
## 0.0.6
|
|
36
|
-
|
|
37
|
-
### Patch Changes
|
|
38
|
-
|
|
39
|
-
- Updated the quickstart mdx and fixed api-call error issue with rest
|
|
40
|
-
|
|
41
|
-
## 0.0.5
|
|
42
|
-
|
|
43
|
-
### Patch Changes
|
|
44
|
-
|
|
45
|
-
- Implemented a react node and the chatbot demo page
|
|
46
|
-
|
|
47
|
-
## 0.0.4
|
|
48
|
-
|
|
49
|
-
### Patch Changes
|
|
50
|
-
|
|
51
|
-
- Improved Loki metrics
|
|
52
|
-
|
|
53
|
-
## 0.0.3
|
|
54
|
-
|
|
55
|
-
### Patch Changes
|
|
56
|
-
|
|
57
|
-
- Improved and extended the open telemetry feature
|
|
58
|
-
|
|
59
|
-
## 0.0.2
|
|
60
|
-
|
|
61
|
-
### Patch Changes
|
|
62
|
-
|
|
63
|
-
- Fixed open telemetry issues and types
|
|
64
|
-
|
|
65
|
-
## 0.0.1
|
|
66
|
-
|
|
67
|
-
### Patch Changes
|
|
68
|
-
|
|
69
|
-
- Fixed issue with the cli node creation test
|
|
@@ -1,294 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import BlokError, {
|
|
3
|
-
DEFAULT_HTTP_STATUS,
|
|
4
|
-
DEFAULT_RETRYABLE,
|
|
5
|
-
ErrorCategory,
|
|
6
|
-
ErrorSeverity,
|
|
7
|
-
type NodeErrorPayload,
|
|
8
|
-
} from "../../src/BlokError";
|
|
9
|
-
import GlobalError from "../../src/GlobalError";
|
|
10
|
-
|
|
11
|
-
describe("BlokError", () => {
|
|
12
|
-
describe("factory methods", () => {
|
|
13
|
-
const factories = [
|
|
14
|
-
{ name: "validation", method: BlokError.validation, expected: ErrorCategory.VALIDATION },
|
|
15
|
-
{ name: "configuration", method: BlokError.configuration, expected: ErrorCategory.CONFIGURATION },
|
|
16
|
-
{ name: "dependency", method: BlokError.dependency, expected: ErrorCategory.DEPENDENCY },
|
|
17
|
-
{ name: "timeout", method: BlokError.timeout, expected: ErrorCategory.TIMEOUT },
|
|
18
|
-
{ name: "permission", method: BlokError.permission, expected: ErrorCategory.PERMISSION },
|
|
19
|
-
{ name: "rateLimit", method: BlokError.rateLimit, expected: ErrorCategory.RATE_LIMIT },
|
|
20
|
-
{ name: "notFound", method: BlokError.notFound, expected: ErrorCategory.NOT_FOUND },
|
|
21
|
-
{ name: "conflict", method: BlokError.conflict, expected: ErrorCategory.CONFLICT },
|
|
22
|
-
{ name: "cancelled", method: BlokError.cancelled, expected: ErrorCategory.CANCELLED },
|
|
23
|
-
{ name: "internal", method: BlokError.internal, expected: ErrorCategory.INTERNAL },
|
|
24
|
-
{ name: "protocol", method: BlokError.protocol, expected: ErrorCategory.PROTOCOL },
|
|
25
|
-
{ name: "data", method: BlokError.data, expected: ErrorCategory.DATA },
|
|
26
|
-
];
|
|
27
|
-
|
|
28
|
-
for (const { name, method, expected } of factories) {
|
|
29
|
-
it(`${name}() creates an error with the right category`, () => {
|
|
30
|
-
const err = method({ code: "TEST", message: "test" });
|
|
31
|
-
expect(err.category).toBe(expected);
|
|
32
|
-
expect(err).toBeInstanceOf(BlokError);
|
|
33
|
-
expect(err).toBeInstanceOf(GlobalError);
|
|
34
|
-
expect(err).toBeInstanceOf(Error);
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
it("each factory applies the default http_status for its category", () => {
|
|
39
|
-
for (const { method, expected } of factories) {
|
|
40
|
-
const err = method({ code: "TEST", message: "test" });
|
|
41
|
-
expect(err.httpStatus).toBe(DEFAULT_HTTP_STATUS[expected]);
|
|
42
|
-
expect(err.context.code).toBe(DEFAULT_HTTP_STATUS[expected]);
|
|
43
|
-
}
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it("each factory applies the default retryable hint for its category", () => {
|
|
47
|
-
for (const { method, expected } of factories) {
|
|
48
|
-
const err = method({ code: "TEST", message: "test" });
|
|
49
|
-
expect(err.retryable).toBe(DEFAULT_RETRYABLE[expected]);
|
|
50
|
-
}
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it("defaults severity to ERROR", () => {
|
|
54
|
-
const err = BlokError.dependency({ code: "X", message: "x" });
|
|
55
|
-
expect(err.severity).toBe(ErrorSeverity.ERROR);
|
|
56
|
-
});
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
describe("constructor options", () => {
|
|
60
|
-
it("preserves all human-readable fields", () => {
|
|
61
|
-
const err = BlokError.dependency({
|
|
62
|
-
code: "POSTGRES_CONNECT_TIMEOUT",
|
|
63
|
-
message: "Could not connect to Postgres within 5s",
|
|
64
|
-
description: "Tried host=localhost port=5432; timeout=5000ms",
|
|
65
|
-
remediation: "Check DATABASE_URL env var and network reachability",
|
|
66
|
-
docUrl: "https://blok.dev/errors/POSTGRES_CONNECT_TIMEOUT",
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
expect(err.errorCode).toBe("POSTGRES_CONNECT_TIMEOUT");
|
|
70
|
-
expect(err.message).toBe("Could not connect to Postgres within 5s");
|
|
71
|
-
expect(err.description).toContain("port=5432");
|
|
72
|
-
expect(err.remediation).toContain("DATABASE_URL");
|
|
73
|
-
expect(err.docUrl).toContain("POSTGRES_CONNECT_TIMEOUT");
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
it("allows overriding httpStatus", () => {
|
|
77
|
-
const err = BlokError.dependency({ code: "X", message: "x", httpStatus: 503 });
|
|
78
|
-
expect(err.httpStatus).toBe(503);
|
|
79
|
-
expect(err.context.code).toBe(503);
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
it("allows overriding retryable + retryAfterMs", () => {
|
|
83
|
-
const err = BlokError.dependency({
|
|
84
|
-
code: "X",
|
|
85
|
-
message: "x",
|
|
86
|
-
retryable: false,
|
|
87
|
-
retryAfterMs: 0,
|
|
88
|
-
});
|
|
89
|
-
expect(err.retryable).toBe(false);
|
|
90
|
-
expect(err.retryAfterMs).toBe(0);
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
it("allows overriding severity", () => {
|
|
94
|
-
const err = BlokError.timeout({
|
|
95
|
-
code: "X",
|
|
96
|
-
message: "x",
|
|
97
|
-
severity: ErrorSeverity.FATAL,
|
|
98
|
-
});
|
|
99
|
-
expect(err.severity).toBe(ErrorSeverity.FATAL);
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
it("captures structured details", () => {
|
|
103
|
-
const err = BlokError.validation({
|
|
104
|
-
code: "VALIDATION_FAILED",
|
|
105
|
-
message: "schema mismatch",
|
|
106
|
-
details: { issues: [{ path: "email", message: "invalid" }] },
|
|
107
|
-
});
|
|
108
|
-
expect(err.details).toEqual({ issues: [{ path: "email", message: "invalid" }] });
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
it("captures contextSnapshot", () => {
|
|
112
|
-
const snapshot = { inputs: { foo: "bar" }, varsKeys: ["a", "b"] };
|
|
113
|
-
const err = BlokError.internal({
|
|
114
|
-
code: "OOPS",
|
|
115
|
-
message: "oops",
|
|
116
|
-
contextSnapshot: snapshot,
|
|
117
|
-
});
|
|
118
|
-
expect(err.contextSnapshot).toEqual(snapshot);
|
|
119
|
-
});
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
describe("cause chain", () => {
|
|
123
|
-
it("flattens a single Error cause", () => {
|
|
124
|
-
const inner = new Error("connect ECONNREFUSED");
|
|
125
|
-
const outer = BlokError.dependency({
|
|
126
|
-
code: "DB_DOWN",
|
|
127
|
-
message: "Database unreachable",
|
|
128
|
-
cause: inner,
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
expect(outer.causes).toHaveLength(1);
|
|
132
|
-
expect(outer.causes[0].message).toBe("connect ECONNREFUSED");
|
|
133
|
-
expect(outer.causes[0].category).toBe(ErrorCategory.INTERNAL);
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
it("flattens a BlokError cause without re-wrapping its own causes", () => {
|
|
137
|
-
const root = BlokError.timeout({ code: "DNS_TIMEOUT", message: "dns timed out" });
|
|
138
|
-
const middle = BlokError.dependency({ code: "DB_DOWN", message: "db unreachable", cause: root });
|
|
139
|
-
const top = BlokError.internal({ code: "REQUEST_FAILED", message: "request failed", cause: middle });
|
|
140
|
-
|
|
141
|
-
expect(top.causes).toHaveLength(2);
|
|
142
|
-
expect(top.causes[0].code).toBe("DB_DOWN");
|
|
143
|
-
expect(top.causes[1].code).toBe("DNS_TIMEOUT");
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
it("returns an empty causes array when no cause is provided", () => {
|
|
147
|
-
const err = BlokError.internal({ code: "X", message: "x" });
|
|
148
|
-
expect(err.causes).toHaveLength(0);
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
it("does not infinite-loop on circular causes", () => {
|
|
152
|
-
const a = new Error("a");
|
|
153
|
-
const b = new Error("b");
|
|
154
|
-
(a as Error & { cause?: Error }).cause = b;
|
|
155
|
-
(b as Error & { cause?: Error }).cause = a;
|
|
156
|
-
|
|
157
|
-
expect(() => BlokError.internal({ code: "CYCLE", message: "circular", cause: a })).not.toThrow();
|
|
158
|
-
});
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
describe("GlobalError compatibility", () => {
|
|
162
|
-
it("populates context.code with httpStatus", () => {
|
|
163
|
-
const err = BlokError.notFound({ code: "USER_NOT_FOUND", message: "no user" });
|
|
164
|
-
expect(err.context.code).toBe(404);
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
it("populates context.name with node when provided", () => {
|
|
168
|
-
const err = BlokError.dependency({ code: "X", message: "x", node: "fetch-user" });
|
|
169
|
-
expect(err.context.name).toBe("fetch-user");
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
it("populates context.json with the full payload", () => {
|
|
173
|
-
const err = BlokError.dependency({
|
|
174
|
-
code: "DB_DOWN",
|
|
175
|
-
message: "db down",
|
|
176
|
-
description: "host unreachable",
|
|
177
|
-
remediation: "check network",
|
|
178
|
-
});
|
|
179
|
-
const payload = err.context.json as unknown as NodeErrorPayload;
|
|
180
|
-
expect(payload.code).toBe("DB_DOWN");
|
|
181
|
-
expect(payload.category).toBe(ErrorCategory.DEPENDENCY);
|
|
182
|
-
expect(payload.description).toBe("host unreachable");
|
|
183
|
-
expect(payload.remediation).toBe("check network");
|
|
184
|
-
});
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
describe("toJSON / fromJSON round-trip", () => {
|
|
188
|
-
it("preserves every field", () => {
|
|
189
|
-
const inner = BlokError.timeout({
|
|
190
|
-
code: "INNER_TIMEOUT",
|
|
191
|
-
message: "inner timed out",
|
|
192
|
-
});
|
|
193
|
-
const original = BlokError.dependency({
|
|
194
|
-
code: "DB_DOWN",
|
|
195
|
-
message: "Database unreachable",
|
|
196
|
-
description: "Tried host=db port=5432",
|
|
197
|
-
remediation: "Check DATABASE_URL",
|
|
198
|
-
docUrl: "https://blok.dev/errors/DB_DOWN",
|
|
199
|
-
cause: inner,
|
|
200
|
-
retryable: true,
|
|
201
|
-
retryAfterMs: 5000,
|
|
202
|
-
details: { sqlState: "08001" },
|
|
203
|
-
contextSnapshot: { inputs: { query: "SELECT 1" } },
|
|
204
|
-
httpStatus: 503,
|
|
205
|
-
severity: ErrorSeverity.WARN,
|
|
206
|
-
node: "store-tutorial",
|
|
207
|
-
sdk: "blok-python3",
|
|
208
|
-
sdkVersion: "1.0.0",
|
|
209
|
-
runtimeKind: "runtime.python3",
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
const json = original.toJSON();
|
|
213
|
-
const restored = BlokError.fromJSON(json);
|
|
214
|
-
|
|
215
|
-
expect(restored.errorCode).toBe(original.errorCode);
|
|
216
|
-
expect(restored.category).toBe(original.category);
|
|
217
|
-
expect(restored.severity).toBe(original.severity);
|
|
218
|
-
expect(restored.message).toBe(original.message);
|
|
219
|
-
expect(restored.description).toBe(original.description);
|
|
220
|
-
expect(restored.remediation).toBe(original.remediation);
|
|
221
|
-
expect(restored.docUrl).toBe(original.docUrl);
|
|
222
|
-
expect(restored.retryable).toBe(original.retryable);
|
|
223
|
-
expect(restored.retryAfterMs).toBe(original.retryAfterMs);
|
|
224
|
-
expect(restored.details).toEqual(original.details);
|
|
225
|
-
expect(restored.contextSnapshot).toEqual(original.contextSnapshot);
|
|
226
|
-
expect(restored.httpStatus).toBe(original.httpStatus);
|
|
227
|
-
expect(restored.nodeName).toBe(original.nodeName);
|
|
228
|
-
expect(restored.sdk).toBe(original.sdk);
|
|
229
|
-
expect(restored.sdkVersion).toBe(original.sdkVersion);
|
|
230
|
-
expect(restored.runtimeKind).toBe(original.runtimeKind);
|
|
231
|
-
expect(restored.causes).toEqual(original.causes);
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
it("toJSON produces an ISO timestamp for `at`", () => {
|
|
235
|
-
const err = BlokError.internal({ code: "X", message: "x" });
|
|
236
|
-
const json = err.toJSON();
|
|
237
|
-
expect(json.at).toMatch(/^\d{4}-\d{2}-\d{2}T/);
|
|
238
|
-
expect(new Date(json.at).getTime()).not.toBeNaN();
|
|
239
|
-
});
|
|
240
|
-
});
|
|
241
|
-
|
|
242
|
-
describe("fromUnknown", () => {
|
|
243
|
-
it("passes BlokError through unchanged", () => {
|
|
244
|
-
const original = BlokError.dependency({ code: "X", message: "x" });
|
|
245
|
-
const wrapped = BlokError.fromUnknown(original);
|
|
246
|
-
expect(wrapped).toBe(original);
|
|
247
|
-
});
|
|
248
|
-
|
|
249
|
-
it("wraps a plain Error as INTERNAL with UNCAUGHT_<NAME> code", () => {
|
|
250
|
-
const err = new TypeError("bad type");
|
|
251
|
-
const wrapped = BlokError.fromUnknown(err);
|
|
252
|
-
expect(wrapped.category).toBe(ErrorCategory.INTERNAL);
|
|
253
|
-
expect(wrapped.errorCode).toBe("UNCAUGHT_TYPEERROR");
|
|
254
|
-
expect(wrapped.message).toBe("bad type");
|
|
255
|
-
expect(wrapped.causes).toHaveLength(1);
|
|
256
|
-
});
|
|
257
|
-
|
|
258
|
-
it("wraps a string as INTERNAL/UNCAUGHT_ERROR", () => {
|
|
259
|
-
const wrapped = BlokError.fromUnknown("oops");
|
|
260
|
-
expect(wrapped.category).toBe(ErrorCategory.INTERNAL);
|
|
261
|
-
expect(wrapped.errorCode).toBe("UNCAUGHT_ERROR");
|
|
262
|
-
expect(wrapped.message).toBe("oops");
|
|
263
|
-
});
|
|
264
|
-
|
|
265
|
-
it("wraps a non-Error value as INTERNAL/UNCAUGHT_ERROR with stringified message", () => {
|
|
266
|
-
const wrapped = BlokError.fromUnknown({ weird: true });
|
|
267
|
-
expect(wrapped.category).toBe(ErrorCategory.INTERNAL);
|
|
268
|
-
expect(wrapped.errorCode).toBe("UNCAUGHT_ERROR");
|
|
269
|
-
expect(wrapped.message).toContain("weird");
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
it("preserves a pre-existing GlobalError code and json", () => {
|
|
273
|
-
const ge = new GlobalError("legacy");
|
|
274
|
-
ge.setCode(403);
|
|
275
|
-
ge.setJson({ origin: "auth" });
|
|
276
|
-
const wrapped = BlokError.fromUnknown(ge);
|
|
277
|
-
expect(wrapped.httpStatus).toBe(403);
|
|
278
|
-
expect(wrapped.details).toEqual({ origin: "auth" });
|
|
279
|
-
});
|
|
280
|
-
|
|
281
|
-
it("uses ctx overrides for node/sdk/sdkVersion/runtimeKind", () => {
|
|
282
|
-
const wrapped = BlokError.fromUnknown(new Error("x"), {
|
|
283
|
-
node: "step-1",
|
|
284
|
-
sdk: "blok-go",
|
|
285
|
-
sdkVersion: "1.0.0",
|
|
286
|
-
runtimeKind: "runtime.go",
|
|
287
|
-
});
|
|
288
|
-
expect(wrapped.nodeName).toBe("step-1");
|
|
289
|
-
expect(wrapped.sdk).toBe("blok-go");
|
|
290
|
-
expect(wrapped.sdkVersion).toBe("1.0.0");
|
|
291
|
-
expect(wrapped.runtimeKind).toBe("runtime.go");
|
|
292
|
-
});
|
|
293
|
-
});
|
|
294
|
-
});
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import GlobalError from "../../src/GlobalError";
|
|
3
|
-
|
|
4
|
-
describe("GlobalError", () => {
|
|
5
|
-
describe("constructor", () => {
|
|
6
|
-
it("should create error with message string", () => {
|
|
7
|
-
const error = new GlobalError("test error");
|
|
8
|
-
expect(error.message).toBe("test error");
|
|
9
|
-
expect(error.context.message).toBe("test error");
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
it("should extend Error", () => {
|
|
13
|
-
const error = new GlobalError("test");
|
|
14
|
-
expect(error).toBeInstanceOf(Error);
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
it("should set prototype correctly for instanceof", () => {
|
|
18
|
-
const error = new GlobalError("test");
|
|
19
|
-
expect(error).toBeInstanceOf(GlobalError);
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
it("should handle undefined message", () => {
|
|
23
|
-
const error = new GlobalError(undefined);
|
|
24
|
-
expect(error.context.message).toBeUndefined();
|
|
25
|
-
});
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
describe("setCode", () => {
|
|
29
|
-
it("should set code on context", () => {
|
|
30
|
-
const error = new GlobalError("test");
|
|
31
|
-
error.setCode(404);
|
|
32
|
-
expect(error.context.code).toBe(404);
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
it("should handle undefined code", () => {
|
|
36
|
-
const error = new GlobalError("test");
|
|
37
|
-
error.setCode(undefined);
|
|
38
|
-
expect(error.context.code).toBeUndefined();
|
|
39
|
-
});
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
describe("setJson", () => {
|
|
43
|
-
it("should set json on context", () => {
|
|
44
|
-
const json = { key: "value" };
|
|
45
|
-
const error = new GlobalError("test");
|
|
46
|
-
error.setJson(json);
|
|
47
|
-
expect(error.context.json).toEqual(json);
|
|
48
|
-
});
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
describe("setStack", () => {
|
|
52
|
-
it("should set stack on context", () => {
|
|
53
|
-
const error = new GlobalError("test");
|
|
54
|
-
error.setStack("Error\n at test.ts:1");
|
|
55
|
-
expect(error.context.stack).toBe("Error\n at test.ts:1");
|
|
56
|
-
});
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
describe("setName", () => {
|
|
60
|
-
it("should set name on context", () => {
|
|
61
|
-
const error = new GlobalError("test");
|
|
62
|
-
error.setName("my-node");
|
|
63
|
-
expect(error.context.name).toBe("my-node");
|
|
64
|
-
});
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
describe("hasJson", () => {
|
|
68
|
-
it("should return false when no json set", () => {
|
|
69
|
-
const error = new GlobalError("test");
|
|
70
|
-
expect(error.hasJson()).toBe(false);
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
it("should return true when json is set", () => {
|
|
74
|
-
const error = new GlobalError("test");
|
|
75
|
-
error.setJson({ key: "value" });
|
|
76
|
-
expect(error.hasJson()).toBe(true);
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
describe("toString", () => {
|
|
81
|
-
it("should return JSON string when json is set", () => {
|
|
82
|
-
const error = new GlobalError("test");
|
|
83
|
-
const json = { key: "value" };
|
|
84
|
-
error.setJson(json);
|
|
85
|
-
expect(error.toString()).toBe(JSON.stringify(json));
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
it("should return message string when no json", () => {
|
|
89
|
-
const error = new GlobalError("test error");
|
|
90
|
-
expect(error.toString()).toBe("test error");
|
|
91
|
-
});
|
|
92
|
-
});
|
|
93
|
-
});
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import GlobalLogger from "../../src/GlobalLogger";
|
|
3
|
-
|
|
4
|
-
class TestLogger extends GlobalLogger {
|
|
5
|
-
log(message: string): void {
|
|
6
|
-
this.logs.push(message);
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
logLevel(level: string, message: string): void {
|
|
10
|
-
this.logs.push(`[${level}] ${message}`);
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
error(message: string, stack: string): void {
|
|
14
|
-
this.logs.push(`ERROR: ${message} - ${stack}`);
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
describe("GlobalLogger", () => {
|
|
19
|
-
it("should initialize with empty logs array", () => {
|
|
20
|
-
const logger = new TestLogger();
|
|
21
|
-
expect(logger.getLogs()).toEqual([]);
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
describe("getLogs", () => {
|
|
25
|
-
it("should return logs after logging", () => {
|
|
26
|
-
const logger = new TestLogger();
|
|
27
|
-
logger.log("msg1");
|
|
28
|
-
logger.log("msg2");
|
|
29
|
-
expect(logger.getLogs()).toEqual(["msg1", "msg2"]);
|
|
30
|
-
});
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
describe("getLogsAsText", () => {
|
|
34
|
-
it("should join logs with newline", () => {
|
|
35
|
-
const logger = new TestLogger();
|
|
36
|
-
logger.log("line1");
|
|
37
|
-
logger.log("line2");
|
|
38
|
-
expect(logger.getLogsAsText()).toBe("line1\nline2");
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
it("should return empty string for no logs", () => {
|
|
42
|
-
const logger = new TestLogger();
|
|
43
|
-
expect(logger.getLogsAsText()).toBe("");
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
describe("getLogsAsBase64", () => {
|
|
48
|
-
it("should return base64 encoded logs", () => {
|
|
49
|
-
const logger = new TestLogger();
|
|
50
|
-
logger.log("hello");
|
|
51
|
-
const expected = Buffer.from("hello").toString("base64");
|
|
52
|
-
expect(logger.getLogsAsBase64()).toBe(expected);
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it("should return base64 of empty string for no logs", () => {
|
|
56
|
-
const logger = new TestLogger();
|
|
57
|
-
const expected = Buffer.from("").toString("base64");
|
|
58
|
-
expect(logger.getLogsAsBase64()).toBe(expected);
|
|
59
|
-
});
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
describe("logLevel", () => {
|
|
63
|
-
it("should format with level prefix", () => {
|
|
64
|
-
const logger = new TestLogger();
|
|
65
|
-
logger.logLevel("WARN", "something happened");
|
|
66
|
-
expect(logger.getLogs()).toEqual(["[WARN] something happened"]);
|
|
67
|
-
});
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
describe("error", () => {
|
|
71
|
-
it("should format error with stack", () => {
|
|
72
|
-
const logger = new TestLogger();
|
|
73
|
-
logger.error("fail", "stack trace");
|
|
74
|
-
expect(logger.getLogs()).toEqual(["ERROR: fail - stack trace"]);
|
|
75
|
-
});
|
|
76
|
-
});
|
|
77
|
-
});
|