@autter/runtime-node 1.4.0 → 1.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.
- package/README.md +202 -17
- package/dist/chunk-ARN26OK6.cjs +810 -0
- package/dist/chunk-FBKYOHU2.js +1942 -0
- package/dist/chunk-OY2HTUWY.js +810 -0
- package/dist/chunk-UGNPCOIW.cjs +202 -0
- package/dist/chunk-UKYTXZOQ.cjs +1942 -0
- package/dist/chunk-Y4T7SQMO.js +202 -0
- package/dist/cli.cjs +60 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +60 -0
- package/dist/index.cjs +1558 -1140
- package/dist/index.d.cts +563 -44
- package/dist/index.d.ts +563 -44
- package/dist/index.js +1372 -919
- package/dist/sinks-CPGDyfU8.d.cts +341 -0
- package/dist/sinks-CPGDyfU8.d.ts +341 -0
- package/dist/testing.cjs +121 -0
- package/dist/testing.d.cts +57 -0
- package/dist/testing.d.ts +57 -0
- package/dist/testing.js +121 -0
- package/package.json +18 -5
package/dist/testing.cjs
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
var _chunkUKYTXZOQcjs = require('./chunk-UKYTXZOQ.cjs');
|
|
6
|
+
require('./chunk-ARN26OK6.cjs');
|
|
7
|
+
|
|
8
|
+
// src/testing.ts
|
|
9
|
+
function captureRuntime() {
|
|
10
|
+
const sink = _chunkUKYTXZOQcjs.memorySink.call(void 0, );
|
|
11
|
+
const remove = _chunkUKYTXZOQcjs.addRuntimeSink.call(void 0, sink);
|
|
12
|
+
return {
|
|
13
|
+
get events() {
|
|
14
|
+
return [...sink.events];
|
|
15
|
+
},
|
|
16
|
+
get operations() {
|
|
17
|
+
return sink.events.filter(_chunkUKYTXZOQcjs.isSummary);
|
|
18
|
+
},
|
|
19
|
+
get logs() {
|
|
20
|
+
return sink.events.filter((event) => !_chunkUKYTXZOQcjs.isSummary.call(void 0, event));
|
|
21
|
+
},
|
|
22
|
+
get exceptions() {
|
|
23
|
+
return [...sink.exceptions];
|
|
24
|
+
},
|
|
25
|
+
byRequestId: (requestId) => sink.events.filter((event) => event.attributes["autter.request.id"] === requestId),
|
|
26
|
+
clear: () => sink.clear(),
|
|
27
|
+
stop: () => {
|
|
28
|
+
remove();
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function partialMatch(actual, expected) {
|
|
33
|
+
if (expected && typeof expected === "object" && !Array.isArray(expected)) {
|
|
34
|
+
if (!actual || typeof actual !== "object") return false;
|
|
35
|
+
return Object.entries(expected).every(
|
|
36
|
+
([key, value]) => partialMatch(actual[key], value)
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
if (Array.isArray(expected))
|
|
40
|
+
return Array.isArray(actual) && expected.length === actual.length && expected.every((item, i) => partialMatch(actual[i], item));
|
|
41
|
+
return Object.is(actual, expected);
|
|
42
|
+
}
|
|
43
|
+
var OperationExpectation = class {
|
|
44
|
+
constructor(event) {
|
|
45
|
+
this.event = event;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
get attributes() {
|
|
49
|
+
return this.event.attributes;
|
|
50
|
+
}
|
|
51
|
+
fail(message) {
|
|
52
|
+
const error = new Error(
|
|
53
|
+
`expectOperation(${JSON.stringify(this.attributes["autter.operation.name"])}): ${message}`
|
|
54
|
+
);
|
|
55
|
+
error.name = "AssertionError";
|
|
56
|
+
throw error;
|
|
57
|
+
}
|
|
58
|
+
toHaveOutcome(outcome) {
|
|
59
|
+
const actual = this.attributes["autter.operation.outcome"];
|
|
60
|
+
if (actual !== outcome) this.fail(`expected outcome ${outcome}, got ${String(actual)}`);
|
|
61
|
+
return this;
|
|
62
|
+
}
|
|
63
|
+
toHaveKind(kind) {
|
|
64
|
+
const actual = this.attributes["autter.operation.kind"];
|
|
65
|
+
if (actual !== kind) this.fail(`expected kind ${kind}, got ${String(actual)}`);
|
|
66
|
+
return this;
|
|
67
|
+
}
|
|
68
|
+
/** Deep partial match against the summary attributes. */
|
|
69
|
+
toHaveContext(expected) {
|
|
70
|
+
if (!partialMatch(this.attributes, expected))
|
|
71
|
+
this.fail(`context does not match ${JSON.stringify(expected)}`);
|
|
72
|
+
return this;
|
|
73
|
+
}
|
|
74
|
+
toHaveStep(name, status) {
|
|
75
|
+
const steps = _nullishCoalesce(this.attributes["autter.operation.steps"], () => ( []));
|
|
76
|
+
if (!steps.some((step) => step.name === name && (!status || step.status === status)))
|
|
77
|
+
this.fail(`no step ${name}${status ? ` (${status})` : ""}`);
|
|
78
|
+
return this;
|
|
79
|
+
}
|
|
80
|
+
toHaveErrorCode(code) {
|
|
81
|
+
const actual = this.attributes["autter.error.code"];
|
|
82
|
+
if (actual !== code) this.fail(`expected error code ${code}, got ${String(actual)}`);
|
|
83
|
+
return this;
|
|
84
|
+
}
|
|
85
|
+
toHaveLog(message, level) {
|
|
86
|
+
const logs = _nullishCoalesce(this.attributes["autter.operation.logs"], () => ( []));
|
|
87
|
+
const ok = logs.some(
|
|
88
|
+
(log) => (typeof message === "string" ? log.message === message : message.test(log.message)) && (!level || log.level === level)
|
|
89
|
+
);
|
|
90
|
+
if (!ok) this.fail(`no inline log ${String(message)}`);
|
|
91
|
+
return this;
|
|
92
|
+
}
|
|
93
|
+
toHaveRequestId(requestId) {
|
|
94
|
+
const actual = this.attributes["autter.request.id"];
|
|
95
|
+
if (requestId === void 0 ? typeof actual !== "string" : actual !== requestId)
|
|
96
|
+
this.fail(`expected request id ${_nullishCoalesce(requestId, () => ( "(any)"))}, got ${String(actual)}`);
|
|
97
|
+
return this;
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
function expectOperation(source, name) {
|
|
101
|
+
const events = Array.isArray(source) ? source.filter(_chunkUKYTXZOQcjs.isSummary) : source.operations;
|
|
102
|
+
const matches = events.filter((event2) => {
|
|
103
|
+
const actual = String(_nullishCoalesce(event2.attributes["autter.operation.name"], () => ( "")));
|
|
104
|
+
return typeof name === "string" ? actual === name : name.test(actual);
|
|
105
|
+
});
|
|
106
|
+
const event = matches[matches.length - 1];
|
|
107
|
+
if (!event) {
|
|
108
|
+
const seen = events.map((e) => e.attributes["autter.operation.name"]);
|
|
109
|
+
const error = new Error(
|
|
110
|
+
`expectOperation: no operation named ${String(name)} (saw ${JSON.stringify(seen)})`
|
|
111
|
+
);
|
|
112
|
+
error.name = "AssertionError";
|
|
113
|
+
throw error;
|
|
114
|
+
}
|
|
115
|
+
return new OperationExpectation(event);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
exports.captureRuntime = captureRuntime; exports.expectOperation = expectOperation; exports.memorySink = _chunkUKYTXZOQcjs.memorySink;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { R as RuntimeEvent, a as RuntimeOutcome, C as CapturedException } from './sinks-CPGDyfU8.cjs';
|
|
2
|
+
export { M as MemorySink, m as memorySink } from './sinks-CPGDyfU8.cjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Test helpers — `@autter/runtime-node/testing`. No ingester, no network:
|
|
6
|
+
* every record the SDK would export is kept in memory.
|
|
7
|
+
*
|
|
8
|
+
* import { captureRuntime, expectOperation } from "@autter/runtime-node/testing";
|
|
9
|
+
*
|
|
10
|
+
* const runtime = captureRuntime();
|
|
11
|
+
* await request(app).post("/checkout").expect(402);
|
|
12
|
+
* expectOperation(runtime, "POST /checkout")
|
|
13
|
+
* .toHaveOutcome("degraded")
|
|
14
|
+
* .toHaveErrorCode("billing.declined");
|
|
15
|
+
* runtime.stop();
|
|
16
|
+
*
|
|
17
|
+
* Works with or without initAutterServer/initAutterLogging; before init it
|
|
18
|
+
* replaces the default console output instead of adding to it.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
interface RuntimeCapture {
|
|
22
|
+
/** Every record, in emission order. */
|
|
23
|
+
readonly events: RuntimeEvent[];
|
|
24
|
+
/** Operation and request summaries. */
|
|
25
|
+
readonly operations: RuntimeEvent[];
|
|
26
|
+
/** Plain log records (warn/error and records outside operations). */
|
|
27
|
+
readonly logs: RuntimeEvent[];
|
|
28
|
+
/** Every captureException call (including boundary captures). */
|
|
29
|
+
readonly exceptions: CapturedException[];
|
|
30
|
+
/** All records stamped with this request id. */
|
|
31
|
+
byRequestId(requestId: string): RuntimeEvent[];
|
|
32
|
+
clear(): void;
|
|
33
|
+
/** Detach from the logger. */
|
|
34
|
+
stop(): void;
|
|
35
|
+
}
|
|
36
|
+
declare function captureRuntime(): RuntimeCapture;
|
|
37
|
+
declare class OperationExpectation {
|
|
38
|
+
readonly event: RuntimeEvent;
|
|
39
|
+
constructor(event: RuntimeEvent);
|
|
40
|
+
get attributes(): Record<string, unknown>;
|
|
41
|
+
private fail;
|
|
42
|
+
toHaveOutcome(outcome: RuntimeOutcome): this;
|
|
43
|
+
toHaveKind(kind: "request" | "operation"): this;
|
|
44
|
+
/** Deep partial match against the summary attributes. */
|
|
45
|
+
toHaveContext(expected: Record<string, unknown>): this;
|
|
46
|
+
toHaveStep(name: string, status?: "succeeded" | "failed"): this;
|
|
47
|
+
toHaveErrorCode(code: string): this;
|
|
48
|
+
toHaveLog(message: string | RegExp, level?: string): this;
|
|
49
|
+
toHaveRequestId(requestId?: string): this;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Find the most recent summary named `name` (exact string or RegExp) and
|
|
53
|
+
* return chainable assertions. Throws when no such summary exists.
|
|
54
|
+
*/
|
|
55
|
+
declare function expectOperation(source: RuntimeCapture | RuntimeEvent[], name: string | RegExp): OperationExpectation;
|
|
56
|
+
|
|
57
|
+
export { CapturedException, OperationExpectation, type RuntimeCapture, RuntimeEvent, captureRuntime, expectOperation };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { R as RuntimeEvent, a as RuntimeOutcome, C as CapturedException } from './sinks-CPGDyfU8.js';
|
|
2
|
+
export { M as MemorySink, m as memorySink } from './sinks-CPGDyfU8.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Test helpers — `@autter/runtime-node/testing`. No ingester, no network:
|
|
6
|
+
* every record the SDK would export is kept in memory.
|
|
7
|
+
*
|
|
8
|
+
* import { captureRuntime, expectOperation } from "@autter/runtime-node/testing";
|
|
9
|
+
*
|
|
10
|
+
* const runtime = captureRuntime();
|
|
11
|
+
* await request(app).post("/checkout").expect(402);
|
|
12
|
+
* expectOperation(runtime, "POST /checkout")
|
|
13
|
+
* .toHaveOutcome("degraded")
|
|
14
|
+
* .toHaveErrorCode("billing.declined");
|
|
15
|
+
* runtime.stop();
|
|
16
|
+
*
|
|
17
|
+
* Works with or without initAutterServer/initAutterLogging; before init it
|
|
18
|
+
* replaces the default console output instead of adding to it.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
interface RuntimeCapture {
|
|
22
|
+
/** Every record, in emission order. */
|
|
23
|
+
readonly events: RuntimeEvent[];
|
|
24
|
+
/** Operation and request summaries. */
|
|
25
|
+
readonly operations: RuntimeEvent[];
|
|
26
|
+
/** Plain log records (warn/error and records outside operations). */
|
|
27
|
+
readonly logs: RuntimeEvent[];
|
|
28
|
+
/** Every captureException call (including boundary captures). */
|
|
29
|
+
readonly exceptions: CapturedException[];
|
|
30
|
+
/** All records stamped with this request id. */
|
|
31
|
+
byRequestId(requestId: string): RuntimeEvent[];
|
|
32
|
+
clear(): void;
|
|
33
|
+
/** Detach from the logger. */
|
|
34
|
+
stop(): void;
|
|
35
|
+
}
|
|
36
|
+
declare function captureRuntime(): RuntimeCapture;
|
|
37
|
+
declare class OperationExpectation {
|
|
38
|
+
readonly event: RuntimeEvent;
|
|
39
|
+
constructor(event: RuntimeEvent);
|
|
40
|
+
get attributes(): Record<string, unknown>;
|
|
41
|
+
private fail;
|
|
42
|
+
toHaveOutcome(outcome: RuntimeOutcome): this;
|
|
43
|
+
toHaveKind(kind: "request" | "operation"): this;
|
|
44
|
+
/** Deep partial match against the summary attributes. */
|
|
45
|
+
toHaveContext(expected: Record<string, unknown>): this;
|
|
46
|
+
toHaveStep(name: string, status?: "succeeded" | "failed"): this;
|
|
47
|
+
toHaveErrorCode(code: string): this;
|
|
48
|
+
toHaveLog(message: string | RegExp, level?: string): this;
|
|
49
|
+
toHaveRequestId(requestId?: string): this;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Find the most recent summary named `name` (exact string or RegExp) and
|
|
53
|
+
* return chainable assertions. Throws when no such summary exists.
|
|
54
|
+
*/
|
|
55
|
+
declare function expectOperation(source: RuntimeCapture | RuntimeEvent[], name: string | RegExp): OperationExpectation;
|
|
56
|
+
|
|
57
|
+
export { CapturedException, OperationExpectation, type RuntimeCapture, RuntimeEvent, captureRuntime, expectOperation };
|
package/dist/testing.js
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import {
|
|
2
|
+
addRuntimeSink,
|
|
3
|
+
isSummary,
|
|
4
|
+
memorySink
|
|
5
|
+
} from "./chunk-FBKYOHU2.js";
|
|
6
|
+
import "./chunk-OY2HTUWY.js";
|
|
7
|
+
|
|
8
|
+
// src/testing.ts
|
|
9
|
+
function captureRuntime() {
|
|
10
|
+
const sink = memorySink();
|
|
11
|
+
const remove = addRuntimeSink(sink);
|
|
12
|
+
return {
|
|
13
|
+
get events() {
|
|
14
|
+
return [...sink.events];
|
|
15
|
+
},
|
|
16
|
+
get operations() {
|
|
17
|
+
return sink.events.filter(isSummary);
|
|
18
|
+
},
|
|
19
|
+
get logs() {
|
|
20
|
+
return sink.events.filter((event) => !isSummary(event));
|
|
21
|
+
},
|
|
22
|
+
get exceptions() {
|
|
23
|
+
return [...sink.exceptions];
|
|
24
|
+
},
|
|
25
|
+
byRequestId: (requestId) => sink.events.filter((event) => event.attributes["autter.request.id"] === requestId),
|
|
26
|
+
clear: () => sink.clear(),
|
|
27
|
+
stop: () => {
|
|
28
|
+
remove();
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function partialMatch(actual, expected) {
|
|
33
|
+
if (expected && typeof expected === "object" && !Array.isArray(expected)) {
|
|
34
|
+
if (!actual || typeof actual !== "object") return false;
|
|
35
|
+
return Object.entries(expected).every(
|
|
36
|
+
([key, value]) => partialMatch(actual[key], value)
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
if (Array.isArray(expected))
|
|
40
|
+
return Array.isArray(actual) && expected.length === actual.length && expected.every((item, i) => partialMatch(actual[i], item));
|
|
41
|
+
return Object.is(actual, expected);
|
|
42
|
+
}
|
|
43
|
+
var OperationExpectation = class {
|
|
44
|
+
constructor(event) {
|
|
45
|
+
this.event = event;
|
|
46
|
+
}
|
|
47
|
+
event;
|
|
48
|
+
get attributes() {
|
|
49
|
+
return this.event.attributes;
|
|
50
|
+
}
|
|
51
|
+
fail(message) {
|
|
52
|
+
const error = new Error(
|
|
53
|
+
`expectOperation(${JSON.stringify(this.attributes["autter.operation.name"])}): ${message}`
|
|
54
|
+
);
|
|
55
|
+
error.name = "AssertionError";
|
|
56
|
+
throw error;
|
|
57
|
+
}
|
|
58
|
+
toHaveOutcome(outcome) {
|
|
59
|
+
const actual = this.attributes["autter.operation.outcome"];
|
|
60
|
+
if (actual !== outcome) this.fail(`expected outcome ${outcome}, got ${String(actual)}`);
|
|
61
|
+
return this;
|
|
62
|
+
}
|
|
63
|
+
toHaveKind(kind) {
|
|
64
|
+
const actual = this.attributes["autter.operation.kind"];
|
|
65
|
+
if (actual !== kind) this.fail(`expected kind ${kind}, got ${String(actual)}`);
|
|
66
|
+
return this;
|
|
67
|
+
}
|
|
68
|
+
/** Deep partial match against the summary attributes. */
|
|
69
|
+
toHaveContext(expected) {
|
|
70
|
+
if (!partialMatch(this.attributes, expected))
|
|
71
|
+
this.fail(`context does not match ${JSON.stringify(expected)}`);
|
|
72
|
+
return this;
|
|
73
|
+
}
|
|
74
|
+
toHaveStep(name, status) {
|
|
75
|
+
const steps = this.attributes["autter.operation.steps"] ?? [];
|
|
76
|
+
if (!steps.some((step) => step.name === name && (!status || step.status === status)))
|
|
77
|
+
this.fail(`no step ${name}${status ? ` (${status})` : ""}`);
|
|
78
|
+
return this;
|
|
79
|
+
}
|
|
80
|
+
toHaveErrorCode(code) {
|
|
81
|
+
const actual = this.attributes["autter.error.code"];
|
|
82
|
+
if (actual !== code) this.fail(`expected error code ${code}, got ${String(actual)}`);
|
|
83
|
+
return this;
|
|
84
|
+
}
|
|
85
|
+
toHaveLog(message, level) {
|
|
86
|
+
const logs = this.attributes["autter.operation.logs"] ?? [];
|
|
87
|
+
const ok = logs.some(
|
|
88
|
+
(log) => (typeof message === "string" ? log.message === message : message.test(log.message)) && (!level || log.level === level)
|
|
89
|
+
);
|
|
90
|
+
if (!ok) this.fail(`no inline log ${String(message)}`);
|
|
91
|
+
return this;
|
|
92
|
+
}
|
|
93
|
+
toHaveRequestId(requestId) {
|
|
94
|
+
const actual = this.attributes["autter.request.id"];
|
|
95
|
+
if (requestId === void 0 ? typeof actual !== "string" : actual !== requestId)
|
|
96
|
+
this.fail(`expected request id ${requestId ?? "(any)"}, got ${String(actual)}`);
|
|
97
|
+
return this;
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
function expectOperation(source, name) {
|
|
101
|
+
const events = Array.isArray(source) ? source.filter(isSummary) : source.operations;
|
|
102
|
+
const matches = events.filter((event2) => {
|
|
103
|
+
const actual = String(event2.attributes["autter.operation.name"] ?? "");
|
|
104
|
+
return typeof name === "string" ? actual === name : name.test(actual);
|
|
105
|
+
});
|
|
106
|
+
const event = matches[matches.length - 1];
|
|
107
|
+
if (!event) {
|
|
108
|
+
const seen = events.map((e) => e.attributes["autter.operation.name"]);
|
|
109
|
+
const error = new Error(
|
|
110
|
+
`expectOperation: no operation named ${String(name)} (saw ${JSON.stringify(seen)})`
|
|
111
|
+
);
|
|
112
|
+
error.name = "AssertionError";
|
|
113
|
+
throw error;
|
|
114
|
+
}
|
|
115
|
+
return new OperationExpectation(event);
|
|
116
|
+
}
|
|
117
|
+
export {
|
|
118
|
+
captureRuntime,
|
|
119
|
+
expectOperation,
|
|
120
|
+
memorySink
|
|
121
|
+
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@autter/runtime-node",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Autter Runtime for Node.js: same-origin browser relay
|
|
3
|
+
"version": "1.6.0",
|
|
4
|
+
"description": "Autter Runtime for Node.js: request wide events, coded errors, operation logging, same-origin browser relay and a curated OpenTelemetry server tracker",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./dist/index.cjs",
|
|
@@ -12,7 +12,16 @@
|
|
|
12
12
|
"types": "./dist/index.d.ts",
|
|
13
13
|
"import": "./dist/index.js",
|
|
14
14
|
"require": "./dist/index.cjs"
|
|
15
|
-
}
|
|
15
|
+
},
|
|
16
|
+
"./testing": {
|
|
17
|
+
"types": "./dist/testing.d.ts",
|
|
18
|
+
"import": "./dist/testing.js",
|
|
19
|
+
"require": "./dist/testing.cjs"
|
|
20
|
+
},
|
|
21
|
+
"./package.json": "./package.json"
|
|
22
|
+
},
|
|
23
|
+
"bin": {
|
|
24
|
+
"autter-runtime": "./dist/cli.js"
|
|
16
25
|
},
|
|
17
26
|
"files": [
|
|
18
27
|
"dist"
|
|
@@ -23,8 +32,8 @@
|
|
|
23
32
|
"directory": "packages/runtime-node"
|
|
24
33
|
},
|
|
25
34
|
"scripts": {
|
|
26
|
-
"build": "
|
|
27
|
-
"test": "npm run build && npm run build -w @autter/otlp-ingester && node --test test/*.test.mjs"
|
|
35
|
+
"build": "node ../../scripts/ensure-built.mjs runtime-core && tsup",
|
|
36
|
+
"test": "npm run build -w @autter/runtime-core && npm run build && npm run build -w @autter/otlp-ingester && node --test test/*.test.mjs"
|
|
28
37
|
},
|
|
29
38
|
"dependencies": {
|
|
30
39
|
"@opentelemetry/api": "^1.9.0",
|
|
@@ -39,7 +48,11 @@
|
|
|
39
48
|
"@opentelemetry/semantic-conventions": "^1.28.0"
|
|
40
49
|
},
|
|
41
50
|
"devDependencies": {
|
|
51
|
+
"@autter/runtime-core": "0.0.0",
|
|
42
52
|
"@types/node": "^22.10.0",
|
|
53
|
+
"express": "^4.21.2",
|
|
54
|
+
"fastify": "^5.12.5",
|
|
55
|
+
"koa": "^3.2.1",
|
|
43
56
|
"tsup": "^8.3.5",
|
|
44
57
|
"typescript": "^5.7.0"
|
|
45
58
|
},
|