Separate a receipt's fields on any whitespace, not only a space
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Csos3Vfm66NrAywQUe3e4V
This commit is contained in:
+5
-4
@@ -56,17 +56,18 @@ export type Dlr = {
|
|||||||
statusMsg: MessageState;
|
statusMsg: MessageState;
|
||||||
};
|
};
|
||||||
|
|
||||||
const field = (name: string) => new RegExp(`\\b${name}:([^ ]*)`, 'i');
|
const field = (name: string) => new RegExp(`\\b${name}:(\\S*)`, 'i');
|
||||||
|
|
||||||
const patterns = {
|
const patterns = {
|
||||||
dlvrd: field('dlvrd'),
|
dlvrd: field('dlvrd'),
|
||||||
doneDate: /\bdone date:([^ ]*)/i,
|
doneDate: field('done date'),
|
||||||
err: field('err'),
|
err: field('err'),
|
||||||
id: field('id'),
|
id: field('id'),
|
||||||
stat: field('stat'),
|
stat: field('stat'),
|
||||||
sub: field('sub'),
|
sub: field('sub'),
|
||||||
submitDate: /\bsubmit date:([^ ]*)/i,
|
submitDate: field('submit date'),
|
||||||
text: /\btext:(.*)$/i,
|
// The last field, and the only one that may hold a space: it carries the message's own start.
|
||||||
|
text: /\btext:([^\r\n]*)/i,
|
||||||
};
|
};
|
||||||
|
|
||||||
function toNumber(value: string | undefined): number | undefined {
|
function toNumber(value: string | undefined): number | undefined {
|
||||||
|
|||||||
+10
-3
@@ -5,7 +5,7 @@ import { dlrFromPdu, parseReceipt, receiptCodes } from '../src/dlr.ts';
|
|||||||
import { objToPdu, pduToObj } from '../src/pdu.ts';
|
import { objToPdu, pduToObj } from '../src/pdu.ts';
|
||||||
import type { PduObject, TlvInput } from '../src/pdu.ts';
|
import type { PduObject, TlvInput } from '../src/pdu.ts';
|
||||||
|
|
||||||
const receiptText = 'id:0195f0c7 sub:001 dlvrd:001 submit date:2508251430 done date:2508251431 stat:DELIVRD err:000 text:hello';
|
const receiptText = 'id:0195f0c7 sub:001 dlvrd:001 submit date:2508251430 done date:2508251431 stat:DELIVRD err:000 text:hello there';
|
||||||
|
|
||||||
function deliverSm(
|
function deliverSm(
|
||||||
message: Buffer | string,
|
message: Buffer | string,
|
||||||
@@ -44,7 +44,14 @@ describe('parseReceipt()', () => {
|
|||||||
assert.equal(receipt.doneDate, '2508251431');
|
assert.equal(receipt.doneDate, '2508251431');
|
||||||
assert.equal(receipt.stat, 'DELIVRD');
|
assert.equal(receipt.stat, 'DELIVRD');
|
||||||
assert.equal(receipt.err, '000');
|
assert.equal(receipt.err, '000');
|
||||||
assert.equal(receipt.text, 'hello');
|
assert.equal(receipt.text, 'hello there');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('takes any whitespace between the fields, not only a space', () => {
|
||||||
|
const wrapped = 'id:0195f0c7\r\nsub:001\ndlvrd:001\tsubmit date:2508251430\r\ndone date:2508251431'
|
||||||
|
+ '\r\nstat:DELIVRD\r\nerr:000\r\ntext:hello there\r\n';
|
||||||
|
|
||||||
|
assert.deepEqual(parseReceipt(wrapped), parseReceipt(receiptText));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('does not confuse "done date" with "submit date"', () => {
|
test('does not confuse "done date" with "submit date"', () => {
|
||||||
@@ -204,7 +211,7 @@ describe('dlrFromPdu()', () => {
|
|||||||
|
|
||||||
assert.ok(dlr?.receipt);
|
assert.ok(dlr?.receipt);
|
||||||
assert.equal(dlr.receipt.sub, 1);
|
assert.equal(dlr.receipt.sub, 1);
|
||||||
assert.equal(dlr.receipt.text, 'hello');
|
assert.equal(dlr.receipt.text, 'hello there');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('reads the id in the notation the peer writes receipts in', () => {
|
test('reads the id in the notation the peer writes receipts in', () => {
|
||||||
|
|||||||
@@ -170,11 +170,6 @@ session message is a change to every call site.
|
|||||||
- [ ] **Coverage reporting.** `node --test --experimental-test-coverage` works today; nothing
|
- [ ] **Coverage reporting.** `node --test --experimental-test-coverage` works today; nothing
|
||||||
publishes the numbers.
|
publishes the numbers.
|
||||||
|
|
||||||
- [ ] **A receipt whose fields are separated by anything but a space reads as one field.**
|
|
||||||
`parseReceipt()` takes `id:` as everything up to the next space, so a peer writing CRLF
|
|
||||||
between fields yields an id of `1a2b\r\nstat:DELIVRD` — one nothing correlates and no
|
|
||||||
notation can read. Every field pattern has the same shape. Raised by review, 2026-08-30.
|
|
||||||
|
|
||||||
- [ ] **An `onReceipt` hook.** Receipt text is only loosely specified and operators disagree on it,
|
- [ ] **An `onReceipt` hook.** Receipt text is only loosely specified and operators disagree on it,
|
||||||
but `dlrFromPdu()` is wired into `IncomingRequests` with no seam of its own: an application
|
but `dlrFromPdu()` is wired into `IncomingRequests` with no seam of its own: an application
|
||||||
facing a format we do not parse has to take the whole PDU on `onRequest` and reimplement the
|
facing a format we do not parse has to take the whole PDU on `onRequest` and reimplement the
|
||||||
|
|||||||
Reference in New Issue
Block a user