@ocpp-debugkit/core 0.1.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 (54) hide show
  1. package/LICENSE +201 -0
  2. package/dist/__fixtures__/connector-fault.d.ts +116 -0
  3. package/dist/__fixtures__/connector-fault.d.ts.map +1 -0
  4. package/dist/__fixtures__/connector-fault.js +231 -0
  5. package/dist/__fixtures__/connector-fault.js.map +1 -0
  6. package/dist/__fixtures__/failed-auth.d.ts +64 -0
  7. package/dist/__fixtures__/failed-auth.d.ts.map +1 -0
  8. package/dist/__fixtures__/failed-auth.js +173 -0
  9. package/dist/__fixtures__/failed-auth.js.map +1 -0
  10. package/dist/__fixtures__/normal-session.d.ts +108 -0
  11. package/dist/__fixtures__/normal-session.d.ts.map +1 -0
  12. package/dist/__fixtures__/normal-session.js +261 -0
  13. package/dist/__fixtures__/normal-session.js.map +1 -0
  14. package/dist/detection.d.ts +23 -0
  15. package/dist/detection.d.ts.map +1 -0
  16. package/dist/detection.js +226 -0
  17. package/dist/detection.js.map +1 -0
  18. package/dist/fixtures/index.d.ts +298 -0
  19. package/dist/fixtures/index.d.ts.map +1 -0
  20. package/dist/fixtures/index.js +19 -0
  21. package/dist/fixtures/index.js.map +1 -0
  22. package/dist/index.d.ts +14 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +22 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/normalizer.d.ts +83 -0
  27. package/dist/normalizer.d.ts.map +1 -0
  28. package/dist/normalizer.js +289 -0
  29. package/dist/normalizer.js.map +1 -0
  30. package/dist/parser.d.ts +53 -0
  31. package/dist/parser.d.ts.map +1 -0
  32. package/dist/parser.js +282 -0
  33. package/dist/parser.js.map +1 -0
  34. package/dist/schemas.d.ts +68 -0
  35. package/dist/schemas.d.ts.map +1 -0
  36. package/dist/schemas.js +81 -0
  37. package/dist/schemas.js.map +1 -0
  38. package/dist/summarizer.d.ts +25 -0
  39. package/dist/summarizer.d.ts.map +1 -0
  40. package/dist/summarizer.js +47 -0
  41. package/dist/summarizer.js.map +1 -0
  42. package/dist/timeline.d.ts +26 -0
  43. package/dist/timeline.d.ts.map +1 -0
  44. package/dist/timeline.js +318 -0
  45. package/dist/timeline.js.map +1 -0
  46. package/dist/types.d.ts +160 -0
  47. package/dist/types.d.ts.map +1 -0
  48. package/dist/types.js +9 -0
  49. package/dist/types.js.map +1 -0
  50. package/dist/validator.d.ts +33 -0
  51. package/dist/validator.d.ts.map +1 -0
  52. package/dist/validator.js +122 -0
  53. package/dist/validator.js.map +1 -0
  54. package/package.json +61 -0
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Event normalizer — transforms raw trace event inputs into canonical
3
+ * `Event` objects with classified message type, direction, and timestamps.
4
+ *
5
+ * @see ADR-0003 (canonical event model)
6
+ * @see ADR-0004 (message direction)
7
+ * @see ADR-0005 (timestamp normalization)
8
+ */
9
+ import type { Direction, Event, MessageType, TraceEventInput, RawOcppMessage } from './types.js';
10
+ /**
11
+ * Infer the direction of a Call message from its action name (ADR-0004).
12
+ * - If the action is known to be CS→CSMS, return 'CS_TO_CSMS'.
13
+ * - If the action is known to be CSMS→CS, return 'CSMS_TO_CS'.
14
+ * - If the action is not recognized, return 'UNKNOWN'.
15
+ *
16
+ * For CallResult/CallError, the direction is the reverse of the original Call.
17
+ * Since we don't have the original Call's direction here, we infer based on
18
+ * the matched Call's action. For responses without a matched Call, we use
19
+ * 'UNKNOWN'.
20
+ */
21
+ export declare function inferDirection(messageType: MessageType, action: string | null): Direction;
22
+ /**
23
+ * Determine the reverse direction for a response.
24
+ * Call CS→CSMS → Response CSMS→CS, and vice versa.
25
+ */
26
+ export declare function reverseDirection(dir: Direction): Direction;
27
+ /**
28
+ * Normalize a timestamp to epoch milliseconds.
29
+ *
30
+ * Accepts:
31
+ * - ISO 8601 strings (UTC or with offset)
32
+ * - Unix epoch in milliseconds (number >= 10^12)
33
+ * - Unix epoch in seconds (number < 10^12)
34
+ * - null/undefined → null
35
+ *
36
+ * @returns epoch milliseconds, or null if the timestamp is missing or invalid.
37
+ */
38
+ export declare function normalizeTimestamp(timestamp: string | number | null | undefined): number | null;
39
+ /**
40
+ * Classify the OCPP message type from the raw message array.
41
+ * - [2, ...] → 'Call'
42
+ * - [3, ...] → 'CallResult'
43
+ * - [4, ...] → 'CallError'
44
+ */
45
+ export declare function classifyMessageType(message: RawOcppMessage): MessageType;
46
+ /**
47
+ * Extract the action name from a Call message.
48
+ * Only Call messages have an action (at index 2).
49
+ */
50
+ export declare function extractAction(message: RawOcppMessage): string | null;
51
+ /**
52
+ * Extract the payload from any message type.
53
+ * - Call: index 3
54
+ * - CallResult: index 2
55
+ * - CallError: index 4 (ErrorDetails)
56
+ */
57
+ export declare function extractPayload(message: RawOcppMessage): unknown;
58
+ /**
59
+ * Extract error code from a CallError message (index 2).
60
+ */
61
+ export declare function extractErrorCode(message: RawOcppMessage): string | null;
62
+ /**
63
+ * Extract error description from a CallError message (index 3).
64
+ */
65
+ export declare function extractErrorDescription(message: RawOcppMessage): string | null;
66
+ /**
67
+ * Normalize an array of raw trace event inputs into canonical `Event` objects.
68
+ *
69
+ * This function:
70
+ * 1. Classifies the message type (Call/CallResult/CallError)
71
+ * 2. Extracts action, payload, error fields
72
+ * 3. Normalizes timestamps to epoch milliseconds
73
+ * 4. Resolves direction: uses explicit direction if provided, otherwise
74
+ * infers from action name (for Calls) or from the matched Call (for responses)
75
+ * 5. Generates sequential event IDs
76
+ *
77
+ * Events are NOT reordered (ADR-0005). Out-of-order timestamps are preserved
78
+ * as-is; the caller can detect them after normalization.
79
+ *
80
+ * @see ADR-0003, ADR-0004, ADR-0005
81
+ */
82
+ export declare function normalizeEvents(inputs: TraceEventInput[]): Event[];
83
+ //# sourceMappingURL=normalizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalizer.d.ts","sourceRoot":"","sources":["../src/normalizer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AA0DjG;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAUzF;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,SAAS,GAAG,SAAS,CAS1D;AAaD;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAgC/F;AAMD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,cAAc,GAAG,WAAW,CAaxE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI,CAMpE;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAW/D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI,CAMvE;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI,CAM9E;AAMD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,KAAK,EAAE,CAoDlE"}
@@ -0,0 +1,289 @@
1
+ /**
2
+ * Event normalizer — transforms raw trace event inputs into canonical
3
+ * `Event` objects with classified message type, direction, and timestamps.
4
+ *
5
+ * @see ADR-0003 (canonical event model)
6
+ * @see ADR-0004 (message direction)
7
+ * @see ADR-0005 (timestamp normalization)
8
+ */
9
+ // ---------------------------------------------------------------------------
10
+ // Direction inference (ADR-0004)
11
+ // ---------------------------------------------------------------------------
12
+ /**
13
+ * Actions initiated by the Charge Point (CS → CSMS).
14
+ * These are OCPP 1.6 actions sent FROM the station TO the CSMS.
15
+ */
16
+ const CS_TO_CSMS_ACTIONS = new Set([
17
+ 'BootNotification',
18
+ 'Heartbeat',
19
+ 'Authorize',
20
+ 'StartTransaction',
21
+ 'StopTransaction',
22
+ 'StatusNotification',
23
+ 'MeterValues',
24
+ 'DataTransfer',
25
+ 'DiagnosticsStatusNotification',
26
+ 'FirmwareStatusNotification',
27
+ 'SecurityEventNotification',
28
+ 'SignCertificate',
29
+ 'SignedFirmwareStatusNotification',
30
+ 'LogStatusNotification',
31
+ ]);
32
+ /**
33
+ * Actions initiated by the CSMS (CSMS → CS).
34
+ * These are OCPP 1.6 actions sent FROM the CSMS TO the station.
35
+ */
36
+ const CSMS_TO_CS_ACTIONS = new Set([
37
+ 'Reset',
38
+ 'RemoteStartTransaction',
39
+ 'RemoteStopTransaction',
40
+ 'GetConfiguration',
41
+ 'ChangeConfiguration',
42
+ 'SetChargingProfile',
43
+ 'ClearChargingProfile',
44
+ 'ChangeAvailability',
45
+ 'ReserveNow',
46
+ 'CancelReservation',
47
+ 'DataTransfer',
48
+ 'GetLocalListVersion',
49
+ 'SendLocalList',
50
+ 'TriggerMessage',
51
+ 'UnlockConnector',
52
+ 'GetDiagnostics',
53
+ 'UpdateFirmware',
54
+ 'ExtendedTriggerMessage',
55
+ 'GetLog',
56
+ 'SignedUpdateFirmware',
57
+ 'CertificateSigned',
58
+ 'DeleteCertificate',
59
+ 'GetInstalledCertificateIds',
60
+ 'InstallCertificate',
61
+ ]);
62
+ /**
63
+ * Infer the direction of a Call message from its action name (ADR-0004).
64
+ * - If the action is known to be CS→CSMS, return 'CS_TO_CSMS'.
65
+ * - If the action is known to be CSMS→CS, return 'CSMS_TO_CS'.
66
+ * - If the action is not recognized, return 'UNKNOWN'.
67
+ *
68
+ * For CallResult/CallError, the direction is the reverse of the original Call.
69
+ * Since we don't have the original Call's direction here, we infer based on
70
+ * the matched Call's action. For responses without a matched Call, we use
71
+ * 'UNKNOWN'.
72
+ */
73
+ export function inferDirection(messageType, action) {
74
+ if (messageType === 'Call' && action !== null) {
75
+ if (CS_TO_CSMS_ACTIONS.has(action))
76
+ return 'CS_TO_CSMS';
77
+ if (CSMS_TO_CS_ACTIONS.has(action))
78
+ return 'CSMS_TO_CS';
79
+ return 'UNKNOWN';
80
+ }
81
+ // For CallResult/CallError, direction should be the reverse of the Call.
82
+ // We can't know for certain without matching — return UNKNOWN.
83
+ // The parser will resolve this after matching Calls to responses.
84
+ return 'UNKNOWN';
85
+ }
86
+ /**
87
+ * Determine the reverse direction for a response.
88
+ * Call CS→CSMS → Response CSMS→CS, and vice versa.
89
+ */
90
+ export function reverseDirection(dir) {
91
+ switch (dir) {
92
+ case 'CS_TO_CSMS':
93
+ return 'CSMS_TO_CS';
94
+ case 'CSMS_TO_CS':
95
+ return 'CS_TO_CSMS';
96
+ case 'UNKNOWN':
97
+ return 'UNKNOWN';
98
+ }
99
+ }
100
+ // ---------------------------------------------------------------------------
101
+ // Timestamp normalization (ADR-0005)
102
+ // ---------------------------------------------------------------------------
103
+ /**
104
+ * Threshold for distinguishing Unix epoch seconds from milliseconds.
105
+ * Values below 10^12 are treated as seconds; above as milliseconds.
106
+ * (10^12 = year ~33658 in ms, year ~2001 in s)
107
+ */
108
+ const EPOCH_MS_THRESHOLD = 1e12;
109
+ /**
110
+ * Normalize a timestamp to epoch milliseconds.
111
+ *
112
+ * Accepts:
113
+ * - ISO 8601 strings (UTC or with offset)
114
+ * - Unix epoch in milliseconds (number >= 10^12)
115
+ * - Unix epoch in seconds (number < 10^12)
116
+ * - null/undefined → null
117
+ *
118
+ * @returns epoch milliseconds, or null if the timestamp is missing or invalid.
119
+ */
120
+ export function normalizeTimestamp(timestamp) {
121
+ if (timestamp === null || timestamp === undefined) {
122
+ return null;
123
+ }
124
+ if (typeof timestamp === 'number') {
125
+ if (!Number.isFinite(timestamp)) {
126
+ return null;
127
+ }
128
+ // Detect seconds vs milliseconds
129
+ return timestamp < EPOCH_MS_THRESHOLD ? Math.round(timestamp * 1000) : Math.round(timestamp);
130
+ }
131
+ if (typeof timestamp === 'string') {
132
+ const trimmed = timestamp.trim();
133
+ if (trimmed === '') {
134
+ return null;
135
+ }
136
+ // Try parsing as a number first (stringified epoch)
137
+ const asNum = Number(trimmed);
138
+ if (Number.isFinite(asNum)) {
139
+ return asNum < EPOCH_MS_THRESHOLD ? Math.round(asNum * 1000) : Math.round(asNum);
140
+ }
141
+ // Parse as ISO 8601
142
+ const parsed = Date.parse(trimmed);
143
+ if (Number.isNaN(parsed)) {
144
+ return null;
145
+ }
146
+ return parsed;
147
+ }
148
+ return null;
149
+ }
150
+ // ---------------------------------------------------------------------------
151
+ // Message type classification
152
+ // ---------------------------------------------------------------------------
153
+ /**
154
+ * Classify the OCPP message type from the raw message array.
155
+ * - [2, ...] → 'Call'
156
+ * - [3, ...] → 'CallResult'
157
+ * - [4, ...] → 'CallError'
158
+ */
159
+ export function classifyMessageType(message) {
160
+ const typeId = message[0];
161
+ switch (typeId) {
162
+ case 2:
163
+ return 'Call';
164
+ case 3:
165
+ return 'CallResult';
166
+ case 4:
167
+ return 'CallError';
168
+ default:
169
+ // Should not happen — schema validation prevents this
170
+ return 'Call';
171
+ }
172
+ }
173
+ /**
174
+ * Extract the action name from a Call message.
175
+ * Only Call messages have an action (at index 2).
176
+ */
177
+ export function extractAction(message) {
178
+ if (message[0] === 2 && message.length >= 3) {
179
+ const action = message[2];
180
+ return typeof action === 'string' ? action : null;
181
+ }
182
+ return null;
183
+ }
184
+ /**
185
+ * Extract the payload from any message type.
186
+ * - Call: index 3
187
+ * - CallResult: index 2
188
+ * - CallError: index 4 (ErrorDetails)
189
+ */
190
+ export function extractPayload(message) {
191
+ switch (message[0]) {
192
+ case 2:
193
+ return message[3] ?? null;
194
+ case 3:
195
+ return message[2] ?? null;
196
+ case 4:
197
+ return message[4] ?? null;
198
+ default:
199
+ return null;
200
+ }
201
+ }
202
+ /**
203
+ * Extract error code from a CallError message (index 2).
204
+ */
205
+ export function extractErrorCode(message) {
206
+ if (message[0] === 4 && message.length >= 3) {
207
+ const code = message[2];
208
+ return typeof code === 'string' ? code : null;
209
+ }
210
+ return null;
211
+ }
212
+ /**
213
+ * Extract error description from a CallError message (index 3).
214
+ */
215
+ export function extractErrorDescription(message) {
216
+ if (message[0] === 4 && message.length >= 4) {
217
+ const desc = message[3];
218
+ return typeof desc === 'string' ? desc : null;
219
+ }
220
+ return null;
221
+ }
222
+ // ---------------------------------------------------------------------------
223
+ // normalizeEvents()
224
+ // ---------------------------------------------------------------------------
225
+ /**
226
+ * Normalize an array of raw trace event inputs into canonical `Event` objects.
227
+ *
228
+ * This function:
229
+ * 1. Classifies the message type (Call/CallResult/CallError)
230
+ * 2. Extracts action, payload, error fields
231
+ * 3. Normalizes timestamps to epoch milliseconds
232
+ * 4. Resolves direction: uses explicit direction if provided, otherwise
233
+ * infers from action name (for Calls) or from the matched Call (for responses)
234
+ * 5. Generates sequential event IDs
235
+ *
236
+ * Events are NOT reordered (ADR-0005). Out-of-order timestamps are preserved
237
+ * as-is; the caller can detect them after normalization.
238
+ *
239
+ * @see ADR-0003, ADR-0004, ADR-0005
240
+ */
241
+ export function normalizeEvents(inputs) {
242
+ // First pass: create events with best-effort direction
243
+ const events = inputs.map((input, index) => {
244
+ const message = input.message;
245
+ const messageType = classifyMessageType(message);
246
+ const action = extractAction(message);
247
+ // Use explicit direction, or infer from action for Call messages.
248
+ // An explicit direction (including 'UNKNOWN') is respected as-is.
249
+ // Only infer when direction is not provided at all (undefined).
250
+ let direction = input.direction;
251
+ if (direction === undefined && messageType === 'Call' && action !== null) {
252
+ direction = inferDirection(messageType, action);
253
+ }
254
+ if (direction === undefined) {
255
+ direction = 'UNKNOWN';
256
+ }
257
+ return {
258
+ id: `evt-${String(index + 1).padStart(4, '0')}`,
259
+ messageId: message[1],
260
+ timestamp: normalizeTimestamp(input.timestamp),
261
+ direction,
262
+ messageType,
263
+ action,
264
+ payload: extractPayload(message),
265
+ errorCode: extractErrorCode(message),
266
+ errorDescription: extractErrorDescription(message),
267
+ rawMessage: message,
268
+ };
269
+ });
270
+ // Second pass: resolve response directions by matching to their original Calls.
271
+ // Build a map of messageId → Call direction.
272
+ const callDirections = new Map();
273
+ for (const event of events) {
274
+ if (event.messageType === 'Call' && event.direction !== 'UNKNOWN') {
275
+ callDirections.set(event.messageId, event.direction);
276
+ }
277
+ }
278
+ // For CallResult/CallError with UNKNOWN direction, infer from the matched Call
279
+ for (const event of events) {
280
+ if (event.direction === 'UNKNOWN' && event.messageType !== 'Call') {
281
+ const callDir = callDirections.get(event.messageId);
282
+ if (callDir) {
283
+ event.direction = reverseDirection(callDir);
284
+ }
285
+ }
286
+ }
287
+ return events;
288
+ }
289
+ //# sourceMappingURL=normalizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalizer.js","sourceRoot":"","sources":["../src/normalizer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Trace parser — accepts untrusted input in JSON Object, JSONL, or bare array
3
+ * format and produces normalized `Event` objects with warnings for malformed
4
+ * entries.
5
+ *
6
+ * Security:
7
+ * - Safe JSON parsing with try/catch
8
+ * - Input size limit (10 MB)
9
+ * - Event count limit (10,000)
10
+ * - Zod schema validation prevents prototype pollution
11
+ * - Malformed individual events are skipped with a `ParseWarning`
12
+ * - Structural errors (invalid JSON, missing events array) fail fast
13
+ *
14
+ * @see ADR-0002 (input trace formats)
15
+ * @see ADR-0007 (malformed trace handling)
16
+ * @see docs/trace-format-spec.md
17
+ */
18
+ import type { ParseResult } from './types.js';
19
+ /** Maximum input size in bytes (10 MB). */
20
+ export declare const MAX_INPUT_SIZE_BYTES: number;
21
+ /** Maximum number of events after parsing. */
22
+ export declare const MAX_EVENT_COUNT = 10000;
23
+ /** Error thrown when input exceeds size limits or has structural problems. */
24
+ export declare class ParseError extends Error {
25
+ constructor(message: string);
26
+ }
27
+ /**
28
+ * Detect the trace format by examining the input string.
29
+ *
30
+ * - JSONL: multiple lines, first non-empty line starts with `{` and parses as JSON
31
+ * - JSON Object: starts with `{`
32
+ * - Bare Array: starts with `[`
33
+ *
34
+ * This function does NOT validate the full content — it just determines
35
+ * which parsing strategy to use.
36
+ */
37
+ export type TraceFormat = 'json-object' | 'jsonl' | 'bare-array';
38
+ /**
39
+ * Parse a trace from a raw string input.
40
+ *
41
+ * Accepts:
42
+ * - JSON Object format (metadata + events array)
43
+ * - JSONL format (one event per line)
44
+ * - Bare array format (array of raw OCPP message arrays)
45
+ *
46
+ * @param input - Raw trace string (untrusted)
47
+ * @returns ParseResult with normalized events and warnings for malformed entries
48
+ * @throws {ParseError} for structural errors (invalid JSON, missing events, size/count limits exceeded)
49
+ *
50
+ * @see ADR-0002, ADR-0007
51
+ */
52
+ export declare function parseTrace(input: string): ParseResult;
53
+ //# sourceMappingURL=parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AASH,OAAO,KAAK,EAAS,WAAW,EAAiC,MAAM,YAAY,CAAC;AAMpF,2CAA2C;AAC3C,eAAO,MAAM,oBAAoB,QAAmB,CAAC;AAErD,8CAA8C;AAC9C,eAAO,MAAM,eAAe,QAAS,CAAC;AAMtC,8EAA8E;AAC9E,qBAAa,UAAW,SAAQ,KAAK;gBACvB,OAAO,EAAE,MAAM;CAI5B;AAoCD;;;;;;;;;GASG;AACH,MAAM,MAAM,WAAW,GAAG,aAAa,GAAG,OAAO,GAAG,YAAY,CAAC;AAiLjE;;;;;;;;;;;;;GAaG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CA4DrD"}