sabre-client 0.5.0 → 0.5.1
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.es.md +29 -5
- package/README.md +29 -5
- package/dist/anonymize.d.ts +54 -0
- package/dist/anonymize.js +111 -0
- package/dist/anonymize.js.map +1 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/{reservation-history-bKDqkf8T.d.ts → reservation-history-BKRFlxpA.d.ts} +5 -1
- package/dist/testing.d.ts +10 -55
- package/dist/testing.js.map +1 -1
- package/package.json +5 -1
package/README.es.md
CHANGED
|
@@ -12,13 +12,14 @@ SDK de TypeScript para las APIs de Sabre.
|
|
|
12
12
|
|
|
13
13
|
## Estado
|
|
14
14
|
|
|
15
|
-
La `0.5.
|
|
15
|
+
La `0.5.1` está publicada con el dist-tag `next` mientras se prueba; `latest` sigue en la `0.4.1`.
|
|
16
16
|
Cubre el Tier 1 y el Tier 2 del flujo de Air Booking por REST, el Tier 3 (sesiones SOAP y colas) y
|
|
17
17
|
el Tier 4: actividad de colas, historial del PNR, la cola de mensajes `S`, `selection` en `list` y
|
|
18
|
-
`onRawRequest`.
|
|
18
|
+
`onRawRequest`. La línea `0.5` trae tres cambios incompatibles (ver
|
|
19
|
+
[Actualizar desde la 0.4](#actualizar-desde-la-04)).
|
|
19
20
|
|
|
20
21
|
```sh
|
|
21
|
-
npm install sabre-client@next # 0.5.
|
|
22
|
+
npm install sabre-client@next # 0.5.1
|
|
22
23
|
npm install sabre-client # 0.4.1
|
|
23
24
|
```
|
|
24
25
|
|
|
@@ -445,7 +446,15 @@ mensajes** del PCC: tiene mensajes y no PNR, y Sabre no la lista, así que `list
|
|
|
445
446
|
lanza un `TypeError` sin llamar a Sabre. Se recorre a mano: `access({ queue: 'S' })` devuelve el
|
|
446
447
|
primer mensaje (`kind: 'message'`) e `ignore()` el siguiente, sin sacarlo de la cola. `process` y
|
|
447
448
|
`place` dentro de la `S` lanzan un `TypeError` sin llamar a Sabre. `remove()` manda `QR`, pero
|
|
448
|
-
todavía no hay evidencia de qué hace Sabre con el mensaje.
|
|
449
|
+
todavía no hay evidencia de qué hace Sabre con el mensaje. Para distinguirla, `isMessageQueue(queue)`
|
|
450
|
+
devuelve `true` solo con `'S'`, y `MESSAGE_QUEUE` es `'S'`:
|
|
451
|
+
|
|
452
|
+
```ts
|
|
453
|
+
import { isMessageQueue } from 'sabre-client';
|
|
454
|
+
|
|
455
|
+
const { queues } = await session.queue.count();
|
|
456
|
+
const pnrQueues = queues.filter(({ queue }) => !isMessageQueue(queue));
|
|
457
|
+
```
|
|
449
458
|
|
|
450
459
|
> **Migración desde la 0.4.x**: `count` devolvía la cola `S` como `{ name: 'S' }`, que Sabre
|
|
451
460
|
> rechaza (`INVALID QUEUE NAME FORMAT`). Ahora devuelve `'S'`. Un código como
|
|
@@ -623,13 +632,20 @@ fake.openSessions; // 0: la sesión se cerró
|
|
|
623
632
|
forma (`… <alias> H`).
|
|
624
633
|
- `queueFakePnrs(fixture)` convierte una grabación en los PNR del fake: primero los de `list`, en
|
|
625
634
|
orden, con su `Line`, y el párrafo que mostró `access`, `ignore`, `remove` o `place` para cada
|
|
626
|
-
uno. La cola la eliges tú, y puedes juntar fixtures
|
|
635
|
+
uno. La cola la eliges tú, y puedes juntar fixtures. Los PNR de `queueFixtures` no traen
|
|
636
|
+
`primaryPassenger`: el `list` se grabó sin `primaryPassenger: true` (`/LN`), así que Sabre no
|
|
637
|
+
mandó el nombre. Si necesitas uno, agrégalo con un `map`:
|
|
627
638
|
|
|
628
639
|
```ts
|
|
629
640
|
const fake = createQueueFake({
|
|
630
641
|
queues: { '9': queueFakePnrs(queueFixtures.walk), '50': [] },
|
|
631
642
|
pnrs: queueFakePnrs(queueFixtures.place),
|
|
632
643
|
});
|
|
644
|
+
|
|
645
|
+
const withPassenger = queueFakePnrs(queueFixtures.walk).map((pnr, index) => ({
|
|
646
|
+
...pnr,
|
|
647
|
+
primaryPassenger: `TEST/PASSENGER${index + 1}`,
|
|
648
|
+
}));
|
|
633
649
|
```
|
|
634
650
|
|
|
635
651
|
`examples/queue-review.mjs` es un ejemplo completo, y su test lo corre contra el fake.
|
|
@@ -648,6 +664,14 @@ anonymizer.maskParagraph(item.paragraph); // líneas en formato de host
|
|
|
648
664
|
if (anonymizer.leaks(safe).length > 0) throw new Error('quedan datos reales');
|
|
649
665
|
```
|
|
650
666
|
|
|
667
|
+
En un bundle de navegador, impórtalo de `sabre-client/anonymize`. Trae solo `createAnonymizer`,
|
|
668
|
+
`isSafeHostLine` y sus tipos, sin el fake ni las `queueFixtures`, que `sabre-client/testing` lleva
|
|
669
|
+
en un solo módulo (unos 230 KB) que los bundlers no pueden descartar:
|
|
670
|
+
|
|
671
|
+
```ts
|
|
672
|
+
import { isSafeHostLine } from 'sabre-client/anonymize';
|
|
673
|
+
```
|
|
674
|
+
|
|
651
675
|
- Cada localizador recibe un alias (`AAAAAA`, `AAAAAB`…), el mismo en todos los lugares donde
|
|
652
676
|
aparece, también en los textos que pasen después por el mismo anonimizador. `PassengerName` pasa
|
|
653
677
|
a `PASAJERO/UNO`, `Group` a `GRUPO`, `AgentSine` a `AAA` (salvo `SABRE`), `PseudoCityCode` a
|
package/README.md
CHANGED
|
@@ -12,13 +12,14 @@ TypeScript SDK for the Sabre APIs.
|
|
|
12
12
|
|
|
13
13
|
## Status
|
|
14
14
|
|
|
15
|
-
`0.5.
|
|
15
|
+
`0.5.1` is published under the `next` dist-tag while it is tested; `latest` stays on `0.4.1`.
|
|
16
16
|
It covers Tier 1 and Tier 2 of the Air Booking flow over REST, Tier 3 (SOAP sessions and queues)
|
|
17
17
|
and Tier 4: queue activity, PNR history, the `S` message queue, `selection` in `list` and
|
|
18
|
-
`onRawRequest`.
|
|
18
|
+
`onRawRequest`. The `0.5` line has three breaking changes (see
|
|
19
|
+
[Upgrading from 0.4](#upgrading-from-04)).
|
|
19
20
|
|
|
20
21
|
```sh
|
|
21
|
-
npm install sabre-client@next # 0.5.
|
|
22
|
+
npm install sabre-client@next # 0.5.1
|
|
22
23
|
npm install sabre-client # 0.4.1
|
|
23
24
|
```
|
|
24
25
|
|
|
@@ -441,7 +442,15 @@ The queues returned by `count` can be passed straight to the other operations. `
|
|
|
441
442
|
throws a `TypeError` without calling Sabre. Walk it by hand: `access({ queue: 'S' })` returns the
|
|
442
443
|
first message (`kind: 'message'`) and `ignore()` the next one, leaving it in the queue. `process`
|
|
443
444
|
and `place` inside `S` throw a `TypeError` without calling Sabre. `remove()` sends `QR`, but there
|
|
444
|
-
is no evidence yet of what Sabre does with the message.
|
|
445
|
+
is no evidence yet of what Sabre does with the message. To tell it apart, `isMessageQueue(queue)`
|
|
446
|
+
returns `true` only for `'S'`, and `MESSAGE_QUEUE` is `'S'`:
|
|
447
|
+
|
|
448
|
+
```ts
|
|
449
|
+
import { isMessageQueue } from 'sabre-client';
|
|
450
|
+
|
|
451
|
+
const { queues } = await session.queue.count();
|
|
452
|
+
const pnrQueues = queues.filter(({ queue }) => !isMessageQueue(queue));
|
|
453
|
+
```
|
|
445
454
|
|
|
446
455
|
> **Migrating from 0.4.x**: `count` used to return the `S` queue as `{ name: 'S' }`, which Sabre
|
|
447
456
|
> rejects (`INVALID QUEUE NAME FORMAT`). It now returns `'S'`. Code that does
|
|
@@ -616,13 +625,20 @@ fake.openSessions; // 0: the session was closed
|
|
|
616
625
|
`AAAAAG`–`AAAAAH`), and their signature lines keep their shape (`… <alias> H`).
|
|
617
626
|
- `queueFakePnrs(fixture)` turns a recording into the fake's PNRs: those of `list` first, in
|
|
618
627
|
order, with their `Line`, and the paragraph `access`, `ignore`, `remove` or `place` showed for
|
|
619
|
-
each one. You choose the queue, and you can mix fixtures
|
|
628
|
+
each one. You choose the queue, and you can mix fixtures. The PNRs of `queueFixtures` have no
|
|
629
|
+
`primaryPassenger`: `list` was recorded without `primaryPassenger: true` (`/LN`), so Sabre did
|
|
630
|
+
not send the name. If you need one, add it with a `map`:
|
|
620
631
|
|
|
621
632
|
```ts
|
|
622
633
|
const fake = createQueueFake({
|
|
623
634
|
queues: { '9': queueFakePnrs(queueFixtures.walk), '50': [] },
|
|
624
635
|
pnrs: queueFakePnrs(queueFixtures.place),
|
|
625
636
|
});
|
|
637
|
+
|
|
638
|
+
const withPassenger = queueFakePnrs(queueFixtures.walk).map((pnr, index) => ({
|
|
639
|
+
...pnr,
|
|
640
|
+
primaryPassenger: `TEST/PASSENGER${index + 1}`,
|
|
641
|
+
}));
|
|
626
642
|
```
|
|
627
643
|
|
|
628
644
|
`examples/queue-review.mjs` is a full example, and its test runs it against the fake.
|
|
@@ -641,6 +657,14 @@ anonymizer.maskParagraph(item.paragraph); // host-format lines
|
|
|
641
657
|
if (anonymizer.leaks(safe).length > 0) throw new Error('real data left');
|
|
642
658
|
```
|
|
643
659
|
|
|
660
|
+
In a browser bundle, import it from `sabre-client/anonymize` instead. It has only
|
|
661
|
+
`createAnonymizer`, `isSafeHostLine` and their types, without the fake or `queueFixtures`, which
|
|
662
|
+
`sabre-client/testing` carries in a single module (about 230 KB) that bundlers cannot drop:
|
|
663
|
+
|
|
664
|
+
```ts
|
|
665
|
+
import { isSafeHostLine } from 'sabre-client/anonymize';
|
|
666
|
+
```
|
|
667
|
+
|
|
644
668
|
- Each locator gets an alias (`AAAAAA`, `AAAAAB`…), the same one everywhere it appears, also in
|
|
645
669
|
later texts passed to the same anonymizer. `PassengerName` becomes `PASAJERO/UNO`, `Group`
|
|
646
670
|
becomes `GRUPO`, `AgentSine` becomes `AAA` (except `SABRE`), `PseudoCityCode` becomes `XXXX`,
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/** Qué dato real quedó en un texto: lo que devuelve `Anonymizer.leaks`. */
|
|
2
|
+
type AnonymizerLeak = 'secreto' | 'localizador' | 'nombre' | 'línea del PNR' | 'token';
|
|
3
|
+
interface AnonymizerOptions {
|
|
4
|
+
/**
|
|
5
|
+
* Valores que nunca deben quedar: credenciales, usuario, PCC. Cada uno pasa a `XXXX` donde
|
|
6
|
+
* aparezca. Se ignoran los que no son string o tienen menos de 3 caracteres.
|
|
7
|
+
*/
|
|
8
|
+
secrets?: ReadonlyArray<string | undefined>;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Una anonimización con memoria: el mismo localizador da siempre el mismo alias y el mismo
|
|
12
|
+
* pasajero el mismo nombre falso, en todos los textos que pasen por ella. Una por grabación.
|
|
13
|
+
*/
|
|
14
|
+
interface Anonymizer {
|
|
15
|
+
/**
|
|
16
|
+
* Un sobre SOAP o cualquier texto con su XML (también un JSON con XML adentro):
|
|
17
|
+
* - cada `UniqueID@ID` pasa a un alias (`AAAAAA`, `AAAAAB`…), y el localizador real se reemplaza
|
|
18
|
+
* por su alias en todo el texto;
|
|
19
|
+
* - `PassengerName` a `PASAJERO/UNO`, `PASAJERO/DOS`…, y `Group` a `GRUPO`;
|
|
20
|
+
* - `AgentSine` a `AAA` (salvo `SABRE`), `PseudoCityCode` a `XXXX` y `LNIATA` a `XXXXXX`;
|
|
21
|
+
* - cada `<Text>` pasa por `maskLine`;
|
|
22
|
+
* - los `secrets`, a `XXXX`.
|
|
23
|
+
*/
|
|
24
|
+
anonymize(text: string): string;
|
|
25
|
+
/**
|
|
26
|
+
* Una línea del PNR en formato de host. Las de la lista blanca (`isSafeHostLine`) quedan tal
|
|
27
|
+
* cual; en las demás, letras a `X` y dígitos a `9`. La cabecera `QUEUE LIST FOR <PCC>` solo
|
|
28
|
+
* tapa el PCC, y `RECEIVED FROM - ` conserva el prefijo. La línea de firma
|
|
29
|
+
* (`… HHMM/DDMMMYY <localizador> H`) conserva su forma, y el localizador solo si ya es un alias:
|
|
30
|
+
* de ella sale el localizador del PNR siguiente en `place` dentro de una cola. Llamarla después
|
|
31
|
+
* de dar alias a los localizadores.
|
|
32
|
+
*/
|
|
33
|
+
maskLine(line: string): string;
|
|
34
|
+
/** `maskLine` sobre cada línea de un párrafo, p. ej. `QueueItem.paragraph`. */
|
|
35
|
+
maskParagraph(lines: readonly string[]): string[];
|
|
36
|
+
/** El alias de un localizador: lo asigna la primera vez, en orden (`AAAAAA`, `AAAAAB`…). */
|
|
37
|
+
aliasOf(locator: string): string;
|
|
38
|
+
/**
|
|
39
|
+
* Qué datos reales siguen en `text`, sin repetir: un `secret`, un localizador o un nombre que ya
|
|
40
|
+
* tienen alias, una línea del PNR que se enmascaró, o un token de sesión. Vacío si no queda
|
|
41
|
+
* ninguno. Sirve para no escribir una fixture que todavía trae datos reales.
|
|
42
|
+
*/
|
|
43
|
+
leaks(text: string): AnonymizerLeak[];
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Si una línea del PNR en formato de host queda tal cual al anonimizar: está en la lista blanca de
|
|
47
|
+
* #96 (líneas vacías, avisos PIC como `011 SEE REMARKS`, títulos de sección como `REMARKS`, el fin
|
|
48
|
+
* de cola).
|
|
49
|
+
*/
|
|
50
|
+
declare function isSafeHostLine(line: string): boolean;
|
|
51
|
+
/** Ver `Anonymizer`. */
|
|
52
|
+
declare function createAnonymizer(options?: AnonymizerOptions): Anonymizer;
|
|
53
|
+
|
|
54
|
+
export { type Anonymizer, type AnonymizerLeak, type AnonymizerOptions, createAnonymizer, isSafeHostLine };
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
// src/testing/anonymize.ts
|
|
2
|
+
var NAMES = ["UNO", "DOS", "TRES", "CUATRO", "CINCO", "SEIS", "SIETE", "OCHO", "NUEVE", "DIEZ"];
|
|
3
|
+
var SAFE_LINES = [
|
|
4
|
+
/^\s*$/,
|
|
5
|
+
// Aviso PIC: 011 SEE REMARKS. Sin dígitos después del número: una línea de `list`
|
|
6
|
+
// (`100 ABC123 PLT MAM 01JUN26 1948`) también empieza con 3 dígitos y trae el sine.
|
|
7
|
+
/^\s*\d{3}\s{2,}[A-Z][A-Z ,./-]*$/,
|
|
8
|
+
/^\s*END OF DISPLAY FOR REQUESTED DATA\s*$/,
|
|
9
|
+
/^\s*(TKT\/TIME LIMIT|PHONES|REMARKS|ADDRESS|INVOICED|GENERAL FACTS|[A-Z0-9]{2} FACTS|NO ITIN)\s*$/,
|
|
10
|
+
/^\s*PASSENGER EMAIL DATA EXISTS\s+\*PE TO DISPLAY ALL\s*$/
|
|
11
|
+
];
|
|
12
|
+
function isSafeHostLine(line) {
|
|
13
|
+
return SAFE_LINES.some((pattern) => pattern.test(line));
|
|
14
|
+
}
|
|
15
|
+
var ENTITIES = { amp: "&", lt: "<", gt: ">", quot: '"', apos: "'" };
|
|
16
|
+
var decode = (text) => text.replace(/&(amp|lt|gt|quot|apos);/g, (_, entity) => ENTITIES[entity] ?? "");
|
|
17
|
+
var encode = (text) => text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
18
|
+
var masked = (text) => text.replace(/\p{L}/gu, "X").replace(/\p{N}/gu, "9");
|
|
19
|
+
function createAnonymizer(options = {}) {
|
|
20
|
+
const secrets = (options.secrets ?? []).filter((value) => typeof value === "string" && value.length >= 3).sort((a, b) => b.length - a.length);
|
|
21
|
+
const redactSecrets = (text) => secrets.reduce((value, secret) => value.split(secret).join("XXXX"), text);
|
|
22
|
+
const locatorAliases = /* @__PURE__ */ new Map();
|
|
23
|
+
const realNames = /* @__PURE__ */ new Map();
|
|
24
|
+
const maskedLines = /* @__PURE__ */ new Set();
|
|
25
|
+
const aliasOf = (locator) => {
|
|
26
|
+
let alias = locatorAliases.get(locator);
|
|
27
|
+
if (alias === void 0) {
|
|
28
|
+
const n = locatorAliases.size;
|
|
29
|
+
const letters = [17576, 676, 26, 1].map((size) => String.fromCharCode(65 + Math.floor(n / size) % 26)).join("");
|
|
30
|
+
alias = `AA${letters}`;
|
|
31
|
+
locatorAliases.set(locator, alias);
|
|
32
|
+
}
|
|
33
|
+
return alias;
|
|
34
|
+
};
|
|
35
|
+
const fakeName = (name) => {
|
|
36
|
+
let fake = realNames.get(name);
|
|
37
|
+
if (fake === void 0) {
|
|
38
|
+
fake = `PASAJERO/${NAMES[realNames.size] ?? realNames.size + 1}`;
|
|
39
|
+
realNames.set(name, fake);
|
|
40
|
+
}
|
|
41
|
+
return fake;
|
|
42
|
+
};
|
|
43
|
+
function anonymizeLine(line) {
|
|
44
|
+
if (isSafeHostLine(line)) return line;
|
|
45
|
+
const header = /^(\s*QUEUE LIST FOR )\S+(\s+QUEUE )(\S+)\s*$/.exec(line);
|
|
46
|
+
if (header !== null) return `${header[1]}XXXX${header[2]}${header[3]}`;
|
|
47
|
+
const received = /^(\s*RECEIVED FROM - )(.*)$/.exec(line);
|
|
48
|
+
const signature = /^(.*\s)(\d{4}\/\d{2}[A-Z]{3}\d{2})(\s+)([A-Z0-9]{6})(\s+H\s*)$/.exec(line);
|
|
49
|
+
const aliases = new Set(locatorAliases.values());
|
|
50
|
+
let result;
|
|
51
|
+
if (received !== null) {
|
|
52
|
+
result = `${received[1]}${masked(received[2] ?? "")}`;
|
|
53
|
+
} else if (signature !== null) {
|
|
54
|
+
const [, before = "", stamp = "", gap = "", locator = "", end = ""] = signature;
|
|
55
|
+
result = `${masked(before)}${masked(stamp)}${gap}${aliases.has(locator) ? locator : masked(locator)}${end}`;
|
|
56
|
+
} else {
|
|
57
|
+
result = masked(line);
|
|
58
|
+
}
|
|
59
|
+
if (line.trim().length >= 4 && result.trim() !== line.trim()) maskedLines.add(line.trim());
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
function anonymize(body) {
|
|
63
|
+
let text = String(body).replace(
|
|
64
|
+
/(<(?:\w+:)?UniqueID\b[^>]*\bID=")([^"]+)(")/g,
|
|
65
|
+
(_, a, locator, b) => `${a}${aliasOf(locator)}${b}`
|
|
66
|
+
);
|
|
67
|
+
for (const [locator, alias] of locatorAliases) text = text.split(locator).join(alias);
|
|
68
|
+
text = text.replace(
|
|
69
|
+
/(<(?:\w+:)?PassengerName>)([^<]*)(<\/)/g,
|
|
70
|
+
(_, a, name, b) => `${a}${fakeName(decode(name))}${b}`
|
|
71
|
+
);
|
|
72
|
+
text = text.replace(
|
|
73
|
+
/(<(?:\w+:)?Group>)([^<]*)(<\/)/g,
|
|
74
|
+
(_, a, value, b) => value === "" ? `${a}${b}` : `${a}GRUPO${b}`
|
|
75
|
+
);
|
|
76
|
+
text = text.replace(
|
|
77
|
+
/(\bAgentSine=")([^"]*)(")/g,
|
|
78
|
+
(_, a, sine, b) => `${a}${sine === "SABRE" ? sine : "AAA"}${b}`
|
|
79
|
+
);
|
|
80
|
+
text = text.replace(/(\bPseudoCityCode=")([^"]*)(")/g, "$1XXXX$3");
|
|
81
|
+
text = text.replace(/(\bLNIATA=")([^"]*)(")/g, "$1XXXXXX$3");
|
|
82
|
+
text = text.replace(
|
|
83
|
+
/(<(?:\w+:)?Text\b[^>/]*>)([\s\S]*?)(<\/(?:\w+:)?Text>)/g,
|
|
84
|
+
(_, a, line, b) => `${a}${encode(anonymizeLine(decode(line)))}${b}`
|
|
85
|
+
);
|
|
86
|
+
return redactSecrets(text);
|
|
87
|
+
}
|
|
88
|
+
const maskLine = (line) => redactSecrets(anonymizeLine(line));
|
|
89
|
+
function leaks(text) {
|
|
90
|
+
const found = [
|
|
91
|
+
...secrets.filter((secret) => text.includes(secret)).map(() => "secreto"),
|
|
92
|
+
...[...locatorAliases.keys()].filter((locator) => text.includes(locator)).map(() => "localizador"),
|
|
93
|
+
...[...realNames.keys()].filter((realName) => realName.length >= 3 && text.includes(realName)).map(() => "nombre"),
|
|
94
|
+
...[...maskedLines].filter((line) => text.includes(line)).map(() => "l\xEDnea del PNR"),
|
|
95
|
+
.../IceSess|Shared\/IDL/.test(text) ? ["token"] : []
|
|
96
|
+
];
|
|
97
|
+
return [...new Set(found)];
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
anonymize,
|
|
101
|
+
maskLine,
|
|
102
|
+
maskParagraph: (lines) => lines.map(maskLine),
|
|
103
|
+
aliasOf,
|
|
104
|
+
leaks
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
export {
|
|
108
|
+
createAnonymizer,
|
|
109
|
+
isSafeHostLine
|
|
110
|
+
};
|
|
111
|
+
//# sourceMappingURL=anonymize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/testing/anonymize.ts"],"sourcesContent":["// Anonimización de las respuestas de colas grabadas (la regla de #96, ADR-018), la misma que usan\n// los scripts que graban fixtures. Exportada para que los consumidores no la repitan (ADR-027, D1).\n// Solo Web Standard APIs: corre en cualquier runtime.\n\n/** Qué dato real quedó en un texto: lo que devuelve `Anonymizer.leaks`. */\nexport type AnonymizerLeak = 'secreto' | 'localizador' | 'nombre' | 'línea del PNR' | 'token';\n\nexport interface AnonymizerOptions {\n /**\n * Valores que nunca deben quedar: credenciales, usuario, PCC. Cada uno pasa a `XXXX` donde\n * aparezca. Se ignoran los que no son string o tienen menos de 3 caracteres.\n */\n secrets?: ReadonlyArray<string | undefined>;\n}\n\n/**\n * Una anonimización con memoria: el mismo localizador da siempre el mismo alias y el mismo\n * pasajero el mismo nombre falso, en todos los textos que pasen por ella. Una por grabación.\n */\nexport interface Anonymizer {\n /**\n * Un sobre SOAP o cualquier texto con su XML (también un JSON con XML adentro):\n * - cada `UniqueID@ID` pasa a un alias (`AAAAAA`, `AAAAAB`…), y el localizador real se reemplaza\n * por su alias en todo el texto;\n * - `PassengerName` a `PASAJERO/UNO`, `PASAJERO/DOS`…, y `Group` a `GRUPO`;\n * - `AgentSine` a `AAA` (salvo `SABRE`), `PseudoCityCode` a `XXXX` y `LNIATA` a `XXXXXX`;\n * - cada `<Text>` pasa por `maskLine`;\n * - los `secrets`, a `XXXX`.\n */\n anonymize(text: string): string;\n /**\n * Una línea del PNR en formato de host. Las de la lista blanca (`isSafeHostLine`) quedan tal\n * cual; en las demás, letras a `X` y dígitos a `9`. La cabecera `QUEUE LIST FOR <PCC>` solo\n * tapa el PCC, y `RECEIVED FROM - ` conserva el prefijo. La línea de firma\n * (`… HHMM/DDMMMYY <localizador> H`) conserva su forma, y el localizador solo si ya es un alias:\n * de ella sale el localizador del PNR siguiente en `place` dentro de una cola. Llamarla después\n * de dar alias a los localizadores.\n */\n maskLine(line: string): string;\n /** `maskLine` sobre cada línea de un párrafo, p. ej. `QueueItem.paragraph`. */\n maskParagraph(lines: readonly string[]): string[];\n /** El alias de un localizador: lo asigna la primera vez, en orden (`AAAAAA`, `AAAAAB`…). */\n aliasOf(locator: string): string;\n /**\n * Qué datos reales siguen en `text`, sin repetir: un `secret`, un localizador o un nombre que ya\n * tienen alias, una línea del PNR que se enmascaró, o un token de sesión. Vacío si no queda\n * ninguno. Sirve para no escribir una fixture que todavía trae datos reales.\n */\n leaks(text: string): AnonymizerLeak[];\n}\n\nconst NAMES = ['UNO', 'DOS', 'TRES', 'CUATRO', 'CINCO', 'SEIS', 'SIETE', 'OCHO', 'NUEVE', 'DIEZ'];\n\n/** Líneas de un PNR en formato de host que quedan tal cual: no traen datos del pasajero. */\nconst SAFE_LINES: readonly RegExp[] = [\n /^\\s*$/,\n // Aviso PIC: 011 SEE REMARKS. Sin dígitos después del número: una línea de `list`\n // (`100 ABC123 PLT MAM 01JUN26 1948`) también empieza con 3 dígitos y trae el sine.\n /^\\s*\\d{3}\\s{2,}[A-Z][A-Z ,./-]*$/,\n /^\\s*END OF DISPLAY FOR REQUESTED DATA\\s*$/,\n /^\\s*(TKT\\/TIME LIMIT|PHONES|REMARKS|ADDRESS|INVOICED|GENERAL FACTS|[A-Z0-9]{2} FACTS|NO ITIN)\\s*$/,\n /^\\s*PASSENGER EMAIL DATA EXISTS\\s+\\*PE TO DISPLAY ALL\\s*$/,\n];\n\n/**\n * Si una línea del PNR en formato de host queda tal cual al anonimizar: está en la lista blanca de\n * #96 (líneas vacías, avisos PIC como `011 SEE REMARKS`, títulos de sección como `REMARKS`, el fin\n * de cola).\n */\nexport function isSafeHostLine(line: string): boolean {\n return SAFE_LINES.some((pattern) => pattern.test(line));\n}\n\nconst ENTITIES: Record<string, string> = { amp: '&', lt: '<', gt: '>', quot: '\"', apos: \"'\" };\nconst decode = (text: string) => text.replace(/&(amp|lt|gt|quot|apos);/g, (_, entity: string) => ENTITIES[entity] ?? '');\nconst encode = (text: string) => text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');\nconst masked = (text: string) => text.replace(/\\p{L}/gu, 'X').replace(/\\p{N}/gu, '9');\n\n/** Ver `Anonymizer`. */\nexport function createAnonymizer(options: AnonymizerOptions = {}): Anonymizer {\n const secrets = (options.secrets ?? [])\n .filter((value): value is string => typeof value === 'string' && value.length >= 3)\n .sort((a, b) => b.length - a.length);\n const redactSecrets = (text: string) => secrets.reduce((value, secret) => value.split(secret).join('XXXX'), text);\n const locatorAliases = new Map<string, string>();\n const realNames = new Map<string, string>();\n const maskedLines = new Set<string>();\n\n const aliasOf = (locator: string): string => {\n let alias = locatorAliases.get(locator);\n if (alias === undefined) {\n const n = locatorAliases.size;\n // Base 26 en cuatro letras: `AAAAAA`, `AAAAAB`… y sigue en letras después del 676 (`AAABAA`).\n const letters = [17576, 676, 26, 1].map((size) => String.fromCharCode(65 + (Math.floor(n / size) % 26))).join('');\n alias = `AA${letters}`;\n locatorAliases.set(locator, alias);\n }\n return alias;\n };\n const fakeName = (name: string): string => {\n let fake = realNames.get(name);\n if (fake === undefined) {\n fake = `PASAJERO/${NAMES[realNames.size] ?? realNames.size + 1}`;\n realNames.set(name, fake);\n }\n return fake;\n };\n\n function anonymizeLine(line: string): string {\n if (isSafeHostLine(line)) return line;\n const header = /^(\\s*QUEUE LIST FOR )\\S+(\\s+QUEUE )(\\S+)\\s*$/.exec(line);\n if (header !== null) return `${header[1]}XXXX${header[2]}${header[3]}`;\n const received = /^(\\s*RECEIVED FROM - )(.*)$/.exec(line);\n const signature = /^(.*\\s)(\\d{4}\\/\\d{2}[A-Z]{3}\\d{2})(\\s+)([A-Z0-9]{6})(\\s+H\\s*)$/.exec(line);\n const aliases = new Set(locatorAliases.values());\n let result: string;\n if (received !== null) {\n result = `${received[1]}${masked(received[2] ?? '')}`;\n } else if (signature !== null) {\n const [, before = '', stamp = '', gap = '', locator = '', end = ''] = signature;\n result = `${masked(before)}${masked(stamp)}${gap}${aliases.has(locator) ? locator : masked(locator)}${end}`;\n } else {\n result = masked(line);\n }\n if (line.trim().length >= 4 && result.trim() !== line.trim()) maskedLines.add(line.trim());\n return result;\n }\n\n function anonymize(body: string): string {\n let text = String(body).replace(\n /(<(?:\\w+:)?UniqueID\\b[^>]*\\bID=\")([^\"]+)(\")/g,\n (_, a: string, locator: string, b: string) => `${a}${aliasOf(locator)}${b}`,\n );\n for (const [locator, alias] of locatorAliases) text = text.split(locator).join(alias);\n text = text.replace(\n /(<(?:\\w+:)?PassengerName>)([^<]*)(<\\/)/g,\n (_, a: string, name: string, b: string) => `${a}${fakeName(decode(name))}${b}`,\n );\n text = text.replace(/(<(?:\\w+:)?Group>)([^<]*)(<\\/)/g, (_, a: string, value: string, b: string) =>\n value === '' ? `${a}${b}` : `${a}GRUPO${b}`,\n );\n text = text.replace(/(\\bAgentSine=\")([^\"]*)(\")/g, (_, a: string, sine: string, b: string) =>\n `${a}${sine === 'SABRE' ? sine : 'AAA'}${b}`,\n );\n text = text.replace(/(\\bPseudoCityCode=\")([^\"]*)(\")/g, '$1XXXX$3');\n // La dirección de la terminal (`stl:HostCommand@LNIATA`, en `session.command()`).\n text = text.replace(/(\\bLNIATA=\")([^\"]*)(\")/g, '$1XXXXXX$3');\n text = text.replace(\n /(<(?:\\w+:)?Text\\b[^>/]*>)([\\s\\S]*?)(<\\/(?:\\w+:)?Text>)/g,\n (_, a: string, line: string, b: string) => `${a}${encode(anonymizeLine(decode(line)))}${b}`,\n );\n return redactSecrets(text);\n }\n\n const maskLine = (line: string) => redactSecrets(anonymizeLine(line));\n\n function leaks(text: string): AnonymizerLeak[] {\n const found: AnonymizerLeak[] = [\n ...secrets.filter((secret) => text.includes(secret)).map((): AnonymizerLeak => 'secreto'),\n ...[...locatorAliases.keys()].filter((locator) => text.includes(locator)).map((): AnonymizerLeak => 'localizador'),\n ...[...realNames.keys()]\n .filter((realName) => realName.length >= 3 && text.includes(realName))\n .map((): AnonymizerLeak => 'nombre'),\n ...[...maskedLines].filter((line) => text.includes(line)).map((): AnonymizerLeak => 'línea del PNR'),\n ...(/IceSess|Shared\\/IDL/.test(text) ? (['token'] as const) : []),\n ];\n return [...new Set(found)];\n }\n\n return {\n anonymize,\n maskLine,\n maskParagraph: (lines) => lines.map(maskLine),\n aliasOf,\n leaks,\n };\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
1
|
+
import { e as RetryOptions, S as SabreError, f as SabreRawResponseCallback, g as SabreRawRequestCallback, h as SabreWarning, i as SabreBusinessError, O as OtaAirLowFareSearchRq, G as GroupedItineraryResponse, B as BargainFinderMaxRequest, I as ItineraryGroup, j as Itinerary, k as RequestOptions, l as BargainFinderMaxResponse, Q as QueueRef, m as QueueActivityRequest, n as QueueActivityOptions, o as QueueActivityResponse, p as ReservationHistoryOptions, q as ReservationHistoryResponse } from './reservation-history-BKRFlxpA.js';
|
|
2
|
+
export { r as BaggageAllowanceDesc, s as BaggageInformation, C as CurrencyConversion, F as Fare, t as FareComponent, u as FareComponentDesc, v as FareComponentDescSegment, w as FareComponentSegment, x as FareComponentSegmentDetail, y as FareMessage, z as ItineraryMessage, L as Leg, A as LegDesc, D as LegDescription, E as LegSchedule, H as LegScheduleRef, J as LowFareSearchFlight, K as LowFareSearchLocation, M as LowFareSearchOriginDestination, N as LowFareSearchPassengerTypeQuantity, P as LowFareSearchRequestorId, T as LowFareSearchSource, U as LowFareSearchTpaExtensions, V as LowFareSearchTravelPreferences, W as LowFareSearchTravelerInfoSummary, X as MESSAGE_QUEUE, Y as ObFeeDesc, Z as PassengerInfo, _ as PassengerTotalFare, $ as PricingInformation, a0 as QueueActivity, a as QueueActivityCounters, a1 as Ref, d as ReservationHistoryAccounting, b as ReservationHistoryFlightSegment, c as ReservationHistoryText, R as ReservationHistoryTransaction, a2 as SabreBusinessErrorOptions, a3 as SabreErrorOptions, a4 as SabreGatewayError, a5 as SabreGatewayErrorOptions, a6 as SabreOrchestrationError, a7 as SabreOrchestrationErrorOptions, a8 as SabreProtocol, a9 as SabreRawRequest, aa as SabreRawResponse, ab as SabreServiceErrorOptions, ac as SabreSessionError, ad as SabreSessionErrorKind, ae as SabreSessionErrorOptions, af as ScheduleCarrier, ag as ScheduleDesc, ah as ScheduleEndpoint, ai as ScheduleEquipment, aj as TaxDesc, ak as TaxSummaryDesc, al as TotalFare, am as ValidatingCarrierDesc, an as isMessageQueue } from './reservation-history-BKRFlxpA.js';
|
|
3
3
|
|
|
4
4
|
/** Token ATK tal cual se guarda: tiempos absolutos, para que otro proceso sepa cuánto le queda. */
|
|
5
5
|
interface StoredToken {
|
|
@@ -4356,6 +4356,6 @@ interface BookingFlightDetailsSource {
|
|
|
4356
4356
|
*/
|
|
4357
4357
|
declare function buildBookingFlightDetails(source: BookingFlightDetailsSource): FlightDetails;
|
|
4358
4358
|
|
|
4359
|
-
declare const VERSION = "0.5.
|
|
4359
|
+
declare const VERSION = "0.5.1";
|
|
4360
4360
|
|
|
4361
4361
|
export { Air, BargainFinderMaxRequest, BargainFinderMaxResponse, type BookContactInformation, type BookGenericSeat, type BookSeat, type BookTraveler, type Booking, type BookingAccountingFormOfPaymentTypeEnum, type BookingAccountingItem, type BookingAccountingItemCreationTypeEnum, type BookingAddress, type BookingAgency, type BookingAgencyCommission, type BookingAncillary, type BookingAncillarySourceEnum, type BookingAncillaryStatusNameEnum, type BookingAssociatedArrivalFlight, type BookingAssociatedFlightDetails, type BookingBaggageAllowance, type BookingBaggagePolicy, type BookingBasicFormOfPayment, type BookingBrandAttribute, type BookingCar, type BookingCarItem, type BookingCarReference, type BookingCarRentalSite, type BookingCardHolder, type BookingCommission, type BookingCommonOtherServiceInformation, type BookingContactInformation, type BookingCouponStatus, type BookingCouponStatusCodeEnum, type BookingCouponStatusEnum, type BookingCreationDetails, type BookingCruise, type BookingCruiseItem, type BookingCruiseReference, type BookingDateRangeRefundPenalty, type BookingDocumentSubTypeEnum, type BookingDocumentTypeEnum, type BookingEmployerIdTypeEnum, type BookingFare, type BookingFareApplicationTypeEnum, type BookingFareComponent, type BookingFareCreationDetails, type BookingFareDifferenceBreakdown, type BookingFareOffer, type BookingFareRule, type BookingFareRulePenalty, type BookingFareRulePenaltyApplicabilityEnum, type BookingFareService, type BookingFlight, type BookingFlightApplicabilityTypeEnum, type BookingFlightDetailsSource, type BookingFlightItem, type BookingFlightReference, type BookingFlightReferenceCoupon, type BookingFlightSourceEnum, type BookingFlightTicket, type BookingForceHotelUpdateDetails, type BookingFormOfPaymentResponse, type BookingFormOfPaymentTripTypeEnum, type BookingFormOfPaymentTypeResponseEnum, type BookingFormOfPaymentUseTypeEnum, type BookingFutureTicketingPolicy, type BookingGenderEnum, type BookingGenericAddress, type BookingGenericFormOfPayment, type BookingGenericTotalValues, type BookingGoodsAndServicesTax, type BookingGuaranteePaymentTypeEnum, type BookingGuaranteeTypeNameEnum, type BookingHandlingFee, type BookingHiddenStop, type BookingHotel, type BookingHotelAddress, type BookingHotelDateRangeRefundPenalty, type BookingHotelItem, type BookingHotelPaymentPolicyEnum, type BookingHotelPenaltyValue, type BookingHotelReference, type BookingHotelSourceEnum, type BookingIdentityDocument, type BookingIdentityDocumentReference, type BookingInitialSellingFare, type BookingItemReference, type BookingJourney, type BookingLoyaltyProgram, BookingManagement, type BookingManualApproval, type BookingMeal, type BookingMealDescriptionEnum, type BookingNonElectronicTicket, type BookingNonElectronicTicketStatusEnum, type BookingOriginalTotalValues, type BookingOtherServiceInformation, type BookingPassportTypeResponseEnum, type BookingPhone, type BookingPhoneResponse, type BookingPricingStatusCodeEnum, type BookingPricingStatusNameEnum, type BookingPricingTypeCodeEnum, type BookingPricingTypeNameEnum, type BookingProfile, type BookingProgramTypeEnum, type BookingRateInterval, type BookingReasonForIssuanceEnum, type BookingRemark, type BookingRemarkTypeEnum, type BookingResponseError, type BookingRoom, type BookingRoomExtraResponse, type BookingRoomExtrasNameEnum, type BookingSeat, type BookingSeatSelection, type BookingSegmentBasicAttributes, type BookingSegmentBasics, type BookingSegmentReference, type BookingSource, type BookingSpecialService, type BookingStatusNameEnum, type BookingStrongCustomerAuthentication, type BookingTariffBasisTypeEnum, type BookingTax, type BookingTaxComponent, type BookingTicketCoupon, type BookingTicketStatusEnum, type BookingTotalPayments, type BookingTotalValues, type BookingTrain, type BookingTrainItem, type BookingTrainReference, type BookingTraveler, type BookingTravelerTypeEnum, type BookingTravelersEmployer, type BookingTravelersGroup, type BookingValue, type BookingVehicleTypeNameEnum, type BookingVirtualCard, type BookingVisaTypeResponseEnum, type BookingVoucher, type BrandedFare, type BuildCredentialsOptions, type BuildCredentialsOptionsV2, type BuildCredentialsOptionsV3, type BuiltCredentialsV2, type BuiltCredentialsV3, type CancelBookingErrorPolicy, type CancelBookingNotification, type CancelBookingOptions, type CancelBookingRequest, type CancelBookingResponse, type CancelSegmentReference, type CreateBookingErrorPolicy, type CreateBookingOptions, type CreateBookingRequest, type CreateBookingResponse, type CreateBookingResponseError, type FlightDetails, type FlightStatusCode, type FlightTicketOperation, type FlightToBook, type GetBookingExtraFeatures, type GetBookingOptions, type GetBookingRequest, type GetBookingResponse, type GetBookingReturnOnly, type GetSeatsRequest, type GetSeatsResponse, GroupedItineraryResponse, type HostDateDirection, Itinerary, ItineraryGroup, type OpenSessionOptions, OtaAirLowFareSearchRq, type PassengerPricing, type PaymentMethod, type PriceComparison, type PriceComparisonType, type PricedSeat, type PricingDetails, type PricingQualifiers, type QueueAccessOptions, type QueueAccessRequest, QueueActivityOptions, QueueActivityRequest, QueueActivityResponse, type QueueCount, type QueueCountOptions, type QueueCountRequest, type QueueCountResponse, type QueueEndReason, type QueueItem, type QueueListEntry, type QueueListOptions, type QueueListRequest, type QueueListResponse, QueueManagement, type QueueMessage, type QueueNavigationOptions, type QueueParagraph, type QueueParagraphAirSegment, type QueueParagraphMessage, type QueueParagraphOptions, type QueueParagraphOtherSegment, type QueueParagraphPassenger, type QueueParagraphReceivedFrom, type QueueParagraphSegment, type QueueParagraphTicketing, type QueueParagraphTicketingEntry, type QueuePlaceOptions, type QueuePlaceRemark, type QueuePlaceRequest, type QueuePlaceResponse, type QueuePlaceResult, type QueuePlaceTarget, type QueuePlacement, type QueueProcessAction, type QueueProcessRequest, type QueueProcessResult, QueueRef, type QueueRemoveRequest, type QueueRemoveTarget, type QueueSelection, type QueueState, type QueueStep, type RawSeatAvailabilityRs, type RefundDocumentsType, RequestOptions, ReservationHistoryOptions, ReservationHistoryResponse, type ResolveHostDateOptions, RetryOptions, type RevalidateItineraryRequest, type RevalidateItineraryRequestSource, type RevalidateItineraryResponse, Sabre, type SabreAuthVersion, SabreBusinessError, type SabreCommandOptions, type SabreCommandResponse, type SabreConfig, type SabreConfigFromCredentials, type SabreConfigV2, type SabreConfigV2FromCredentials, type SabreConfigV3, type SabreCredentials, type SabreCredentialsAnyVersion, type SabreCredentialsV2, type SabreEnvironment, SabreError, SabreLegacy, type SabreLogEvent, type SabreLogLevel, type SabreLogger, SabreRawRequestCallback, SabreRawResponseCallback, SabreSession, type SabreTokenStore, SabreWarning, type Seat, type SeatAreaPreference, type SeatAvailabilityByPayloadRq, type SeatAvailabilityByPnrLocatorRq, type SeatAvailabilityIssue, type SeatAvailabilityRequestSource, type SeatAvailabilityResponse, type SeatCabinAisle, type SeatCabinCompartment, type SeatCabinFacility, type SeatCabinLayout, type SeatCabinRowPosition, type SeatCharacteristic, type SeatDisplayOnlyItem, type SeatFareComponent, type SeatFareDetail, type SeatFareSegmentAssociation, type SeatFlightLeg, type SeatKeyValuePair, type SeatLoyaltyProgramAccount, type SeatMap, type SeatOfferItem, type SeatOfferItemDetails, type SeatPassenger, type SeatPassengerPayloadRq, type SeatPassengerRs, type SeatPriceBreakdown, type SeatPriceDefinition, type SeatRow, type SeatSegment, type SeatSegmentPayloadRq, type SeatSegmentRs, type SeatServiceDefinition, type SeatSpecialServiceRequest, type SeatTax, SessionReservation, type SpecificFare, type StoredToken, type TicketingPolicy, type TravelerPhone, type TravelerTitle, VERSION, buildBookingFlightDetails, buildCredentials, buildRevalidateItineraryRequest, buildSeatAvailabilityRequest, parseQueueParagraph, parseQueuePlaceRemark, resolveHostDate };
|
package/dist/index.js
CHANGED
|
@@ -3748,8 +3748,9 @@ function fareComponent(fareComponentId, component) {
|
|
|
3748
3748
|
}
|
|
3749
3749
|
|
|
3750
3750
|
// src/index.ts
|
|
3751
|
-
var VERSION = "0.5.
|
|
3751
|
+
var VERSION = "0.5.1";
|
|
3752
3752
|
export {
|
|
3753
|
+
MESSAGE_QUEUE,
|
|
3753
3754
|
Sabre,
|
|
3754
3755
|
SabreBusinessError,
|
|
3755
3756
|
SabreError,
|
|
@@ -3763,6 +3764,7 @@ export {
|
|
|
3763
3764
|
buildCredentials,
|
|
3764
3765
|
buildRevalidateItineraryRequest,
|
|
3765
3766
|
buildSeatAvailabilityRequest,
|
|
3767
|
+
isMessageQueue,
|
|
3766
3768
|
parseQueueParagraph,
|
|
3767
3769
|
parseQueuePlaceRemark,
|
|
3768
3770
|
resolveHostDate
|