@futdevpro/fsm-dynamo 1.20.23 → 1.20.25
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/build/_modules/game/_models/seeded-random-registry.control-model.d.ts +71 -0
- package/build/_modules/game/_models/seeded-random-registry.control-model.d.ts.map +1 -0
- package/build/_modules/game/_models/seeded-random-registry.control-model.js +129 -0
- package/build/_modules/game/_models/seeded-random-registry.control-model.js.map +1 -0
- package/build/_modules/game/_models/seeded-random-registry.interface.d.ts +27 -0
- package/build/_modules/game/_models/seeded-random-registry.interface.d.ts.map +1 -0
- package/build/_modules/game/_models/seeded-random-registry.interface.js +3 -0
- package/build/_modules/game/_models/seeded-random-registry.interface.js.map +1 -0
- package/build/_modules/game/index.d.ts +2 -0
- package/build/_modules/game/index.d.ts.map +1 -1
- package/build/_modules/game/index.js +2 -0
- package/build/_modules/game/index.js.map +1 -1
- package/build/_modules/request-safety/_collections/request-safety-inspector.util.d.ts +56 -0
- package/build/_modules/request-safety/_collections/request-safety-inspector.util.d.ts.map +1 -0
- package/build/_modules/request-safety/_collections/request-safety-inspector.util.js +189 -0
- package/build/_modules/request-safety/_collections/request-safety-inspector.util.js.map +1 -0
- package/build/_modules/request-safety/_enums/request-safety-finding.type-enum.d.ts +37 -0
- package/build/_modules/request-safety/_enums/request-safety-finding.type-enum.d.ts.map +1 -0
- package/build/_modules/request-safety/_enums/request-safety-finding.type-enum.js +41 -0
- package/build/_modules/request-safety/_enums/request-safety-finding.type-enum.js.map +1 -0
- package/build/_modules/request-safety/_models/request-safety.interface.d.ts +67 -0
- package/build/_modules/request-safety/_models/request-safety.interface.d.ts.map +1 -0
- package/build/_modules/request-safety/_models/request-safety.interface.js +3 -0
- package/build/_modules/request-safety/_models/request-safety.interface.js.map +1 -0
- package/build/_modules/request-safety/index.d.ts +4 -0
- package/build/_modules/request-safety/index.d.ts.map +1 -0
- package/build/_modules/request-safety/index.js +7 -0
- package/build/_modules/request-safety/index.js.map +1 -0
- package/package.json +11 -2
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { DyFM_SeededRandom } from './seeded-random.control-model';
|
|
2
|
+
import { DyFM_SeededRandomRegistry_Diagnostics, DyFM_SeededRandomRegistry_State } from './seeded-random-registry.interface';
|
|
3
|
+
/**
|
|
4
|
+
* BFR-WARFACTORY-009 — **gyökér-seedelt, FÜGGETLEN RNG-stream registry.**
|
|
5
|
+
*
|
|
6
|
+
* ⚠️ **A megoldandó baj:** a `DyFM_SeededRandom` egyetlen sorozat. Ha a játék minden véletlenét
|
|
7
|
+
* egyetlen példányból húzza, akkor **egy harci dobás hozzáadása eltolja a térkép-generálást, a
|
|
8
|
+
* loot-ot, az azonosítókat és a tutorial-állapotot is** — ugyanaz a mentés más világot ad, mert
|
|
9
|
+
* közben egy csatában eggyel többször dobtunk. Ez a determinizmus leggyakoribb, legnehezebben
|
|
10
|
+
* észrevehető elvesztése.
|
|
11
|
+
*
|
|
12
|
+
* ⭐ A megoldás: **egy gyökér-seed → sok, névvel azonosított, egymástól független stream.** A
|
|
13
|
+
* `'combat'` csatorna fogyasztása nem érinti a `'worldgen'`-t, viszont ugyanabból a gyökér-seedből
|
|
14
|
+
* az egész készlet **reprodukálható**.
|
|
15
|
+
*
|
|
16
|
+
* ⚠️ **A származtatás determinisztikus és név-alapú** (`<rootSeed>::<channel>`), nem sorrend-alapú.
|
|
17
|
+
* Ez tudatos: ha a streameket a létrehozásuk sorrendje szerint származtatnánk, egy ÚJ csatorna
|
|
18
|
+
* bevezetése — vagy csak a kód átrendezése — elmozdítaná az összes utána következő sorozatot.
|
|
19
|
+
* Névvel a `'combat'` mindig ugyanaz, függetlenül attól, hány másik csatorna létezik.
|
|
20
|
+
*
|
|
21
|
+
* ⛔ A registry **nem** hoz létre csatornát a hívó tudta nélkül a `get()`-en kívül: az `require()`
|
|
22
|
+
* ismeretlen névre **dob**, mert egy elgépelt csatornanév különben csendben egy vadonatúj, üres
|
|
23
|
+
* sorozatot adna — és a hiba csak a reprodukálhatóság elvesztésekor derülne ki.
|
|
24
|
+
*/
|
|
25
|
+
export declare class DyFM_SeededRandomRegistry_ControlModel {
|
|
26
|
+
private readonly rootSeed;
|
|
27
|
+
private readonly streams;
|
|
28
|
+
private constructor();
|
|
29
|
+
/** Új registry egy gyökér-seedből. Csatornák igény szerint, a `get()` hívásakor jönnek létre. */
|
|
30
|
+
static fromRootSeed(rootSeed: string | number): DyFM_SeededRandomRegistry_ControlModel;
|
|
31
|
+
/**
|
|
32
|
+
* Registry visszatöltése mentett állapotból — minden csatorna ott folytatódik, ahol abbamaradt.
|
|
33
|
+
*
|
|
34
|
+
* @throws {Error} ha a `contractVersion` nem az ismert alak. ⚠️ Ez SZÁNDÉKOSAN dob: egy nem
|
|
35
|
+
* értelmezhető mentés-payload csendben elfogadva friss, üres streameket adna, és a játékos
|
|
36
|
+
* mentése némán más világot generálna.
|
|
37
|
+
*/
|
|
38
|
+
static fromState(state: DyFM_SeededRandomRegistry_State): DyFM_SeededRandomRegistry_ControlModel;
|
|
39
|
+
/**
|
|
40
|
+
* Egy nevesített stream. Ugyanarra a névre **mindig ugyanaz a példány** (tehát a sorozat
|
|
41
|
+
* folytatódik, nem indul újra); ismeretlen névre determinisztikusan **létrehozza**.
|
|
42
|
+
*/
|
|
43
|
+
get(channel: string): DyFM_SeededRandom;
|
|
44
|
+
/**
|
|
45
|
+
* Egy MÁR LÉTEZŐ stream. Ismeretlen névre **dob**.
|
|
46
|
+
*
|
|
47
|
+
* ⭐ Ez a `get()` szigorú párja: ahol a hívó tudja, hogy a csatornának léteznie kell (pl. mentés
|
|
48
|
+
* betöltése után), ott egy elgépelt név ne csendben új, üres sorozatot adjon.
|
|
49
|
+
*/
|
|
50
|
+
require(channel: string): DyFM_SeededRandom;
|
|
51
|
+
/** Létezik-e már a csatorna (létrehozás NÉLKÜL). */
|
|
52
|
+
has(channel: string): boolean;
|
|
53
|
+
/**
|
|
54
|
+
* A teljes registry mentheto allapota — ezt kell a save-payloadba tenni.
|
|
55
|
+
*
|
|
56
|
+
* A csatornak ABECESORRENDBEN kerulnek bele: igy ket azonos allapotu registry
|
|
57
|
+
* szerializalt alakja BAJTRA egyezik, ami a mentes-osszehasonlitast es a teszt-asszerciot
|
|
58
|
+
* determinisztikussa teszi.
|
|
59
|
+
*/
|
|
60
|
+
getState(): DyFM_SeededRandomRegistry_State;
|
|
61
|
+
/**
|
|
62
|
+
* Fuggetlen masolat a TELJES registry-rol. A klon minden csatornaja ott folytatja, ahol az
|
|
63
|
+
* eredeti tart, de a ketto tovabbiakban nem befolyasolja egymast.
|
|
64
|
+
*
|
|
65
|
+
* Tipikus hasznalat: „mi lenne, ha" elore-szimulacio a fo-jatekmenet elrontasa nelkul.
|
|
66
|
+
*/
|
|
67
|
+
clone(): DyFM_SeededRandomRegistry_ControlModel;
|
|
68
|
+
/** Tartalom-mentes diagnosztika: a szerkezet, nem a sorozatok kimenete. */
|
|
69
|
+
getDiagnostics(): DyFM_SeededRandomRegistry_Diagnostics;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=seeded-random-registry.control-model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seeded-random-registry.control-model.d.ts","sourceRoot":"","sources":["../../../../src/_modules/game/_models/seeded-random-registry.control-model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EACL,qCAAqC,EAAE,+BAA+B,EACvE,MAAM,oCAAoC,CAAC;AAE5C;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,sCAAsC;IAK/C,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAH3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwE;IAEhG,OAAO;IAIP,iGAAiG;IACjG,MAAM,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,sCAAsC;IAItF;;;;;;OAMG;IACH,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,+BAA+B,GAAG,sCAAsC;IAehG;;;OAGG;IACH,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB;IAoBvC;;;;;OAKG;IACH,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB;IAW3C,oDAAoD;IACpD,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAI7B;;;;;;OAMG;IACH,QAAQ,IAAI,+BAA+B;IAc3C;;;;;OAKG;IACH,KAAK,IAAI,sCAAsC;IAI/C,2EAA2E;IAC3E,cAAc,IAAI,qCAAqC;CASxD"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DyFM_SeededRandomRegistry_ControlModel = void 0;
|
|
4
|
+
const seeded_random_control_model_1 = require("./seeded-random.control-model");
|
|
5
|
+
/**
|
|
6
|
+
* BFR-WARFACTORY-009 — **gyökér-seedelt, FÜGGETLEN RNG-stream registry.**
|
|
7
|
+
*
|
|
8
|
+
* ⚠️ **A megoldandó baj:** a `DyFM_SeededRandom` egyetlen sorozat. Ha a játék minden véletlenét
|
|
9
|
+
* egyetlen példányból húzza, akkor **egy harci dobás hozzáadása eltolja a térkép-generálást, a
|
|
10
|
+
* loot-ot, az azonosítókat és a tutorial-állapotot is** — ugyanaz a mentés más világot ad, mert
|
|
11
|
+
* közben egy csatában eggyel többször dobtunk. Ez a determinizmus leggyakoribb, legnehezebben
|
|
12
|
+
* észrevehető elvesztése.
|
|
13
|
+
*
|
|
14
|
+
* ⭐ A megoldás: **egy gyökér-seed → sok, névvel azonosított, egymástól független stream.** A
|
|
15
|
+
* `'combat'` csatorna fogyasztása nem érinti a `'worldgen'`-t, viszont ugyanabból a gyökér-seedből
|
|
16
|
+
* az egész készlet **reprodukálható**.
|
|
17
|
+
*
|
|
18
|
+
* ⚠️ **A származtatás determinisztikus és név-alapú** (`<rootSeed>::<channel>`), nem sorrend-alapú.
|
|
19
|
+
* Ez tudatos: ha a streameket a létrehozásuk sorrendje szerint származtatnánk, egy ÚJ csatorna
|
|
20
|
+
* bevezetése — vagy csak a kód átrendezése — elmozdítaná az összes utána következő sorozatot.
|
|
21
|
+
* Névvel a `'combat'` mindig ugyanaz, függetlenül attól, hány másik csatorna létezik.
|
|
22
|
+
*
|
|
23
|
+
* ⛔ A registry **nem** hoz létre csatornát a hívó tudta nélkül a `get()`-en kívül: az `require()`
|
|
24
|
+
* ismeretlen névre **dob**, mert egy elgépelt csatornanév különben csendben egy vadonatúj, üres
|
|
25
|
+
* sorozatot adna — és a hiba csak a reprodukálhatóság elvesztésekor derülne ki.
|
|
26
|
+
*/
|
|
27
|
+
class DyFM_SeededRandomRegistry_ControlModel {
|
|
28
|
+
rootSeed;
|
|
29
|
+
streams = new Map();
|
|
30
|
+
constructor(rootSeed) {
|
|
31
|
+
this.rootSeed = rootSeed;
|
|
32
|
+
}
|
|
33
|
+
/** Új registry egy gyökér-seedből. Csatornák igény szerint, a `get()` hívásakor jönnek létre. */
|
|
34
|
+
static fromRootSeed(rootSeed) {
|
|
35
|
+
return new DyFM_SeededRandomRegistry_ControlModel(`${rootSeed}`);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Registry visszatöltése mentett állapotból — minden csatorna ott folytatódik, ahol abbamaradt.
|
|
39
|
+
*
|
|
40
|
+
* @throws {Error} ha a `contractVersion` nem az ismert alak. ⚠️ Ez SZÁNDÉKOSAN dob: egy nem
|
|
41
|
+
* értelmezhető mentés-payload csendben elfogadva friss, üres streameket adna, és a játékos
|
|
42
|
+
* mentése némán más világot generálna.
|
|
43
|
+
*/
|
|
44
|
+
static fromState(state) {
|
|
45
|
+
if (state?.contractVersion !== 'dyfm-seeded-random-registry/1') {
|
|
46
|
+
throw new Error('DyFM_SeededRandomRegistry: unknown or missing contractVersion.');
|
|
47
|
+
}
|
|
48
|
+
const registry = new DyFM_SeededRandomRegistry_ControlModel(`${state.rootSeed ?? ''}`);
|
|
49
|
+
for (const channel of Object.keys(state.channels ?? {})) {
|
|
50
|
+
registry.streams.set(channel, seeded_random_control_model_1.DyFM_SeededRandom.fromState(state.channels[channel]));
|
|
51
|
+
}
|
|
52
|
+
return registry;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Egy nevesített stream. Ugyanarra a névre **mindig ugyanaz a példány** (tehát a sorozat
|
|
56
|
+
* folytatódik, nem indul újra); ismeretlen névre determinisztikusan **létrehozza**.
|
|
57
|
+
*/
|
|
58
|
+
get(channel) {
|
|
59
|
+
const name = `${channel ?? ''}`.trim();
|
|
60
|
+
if (!name.length) {
|
|
61
|
+
throw new Error('DyFM_SeededRandomRegistry: a channel name is required.');
|
|
62
|
+
}
|
|
63
|
+
const existing = this.streams.get(name);
|
|
64
|
+
if (existing) {
|
|
65
|
+
return existing;
|
|
66
|
+
}
|
|
67
|
+
// Nev-alapu szarmaztatas: a `'combat'` mindig ugyanaz, fuggetlenul attol, hany masik csatorna
|
|
68
|
+
// letezik es milyen sorrendben jottek letre.
|
|
69
|
+
const stream = seeded_random_control_model_1.DyFM_SeededRandom.fromSeed(`${this.rootSeed}::${name}`);
|
|
70
|
+
this.streams.set(name, stream);
|
|
71
|
+
return stream;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Egy MÁR LÉTEZŐ stream. Ismeretlen névre **dob**.
|
|
75
|
+
*
|
|
76
|
+
* ⭐ Ez a `get()` szigorú párja: ahol a hívó tudja, hogy a csatornának léteznie kell (pl. mentés
|
|
77
|
+
* betöltése után), ott egy elgépelt név ne csendben új, üres sorozatot adjon.
|
|
78
|
+
*/
|
|
79
|
+
require(channel) {
|
|
80
|
+
const name = `${channel ?? ''}`.trim();
|
|
81
|
+
const existing = this.streams.get(name);
|
|
82
|
+
if (!existing) {
|
|
83
|
+
throw new Error(`DyFM_SeededRandomRegistry: unknown channel "${name}".`);
|
|
84
|
+
}
|
|
85
|
+
return existing;
|
|
86
|
+
}
|
|
87
|
+
/** Létezik-e már a csatorna (létrehozás NÉLKÜL). */
|
|
88
|
+
has(channel) {
|
|
89
|
+
return this.streams.has(`${channel ?? ''}`.trim());
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* A teljes registry mentheto allapota — ezt kell a save-payloadba tenni.
|
|
93
|
+
*
|
|
94
|
+
* A csatornak ABECESORRENDBEN kerulnek bele: igy ket azonos allapotu registry
|
|
95
|
+
* szerializalt alakja BAJTRA egyezik, ami a mentes-osszehasonlitast es a teszt-asszerciot
|
|
96
|
+
* determinisztikussa teszi.
|
|
97
|
+
*/
|
|
98
|
+
getState() {
|
|
99
|
+
const channels = {};
|
|
100
|
+
for (const name of [...this.streams.keys()].sort()) {
|
|
101
|
+
channels[name] = this.streams.get(name).getState();
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
contractVersion: 'dyfm-seeded-random-registry/1',
|
|
105
|
+
rootSeed: this.rootSeed,
|
|
106
|
+
channels: channels,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Fuggetlen masolat a TELJES registry-rol. A klon minden csatornaja ott folytatja, ahol az
|
|
111
|
+
* eredeti tart, de a ketto tovabbiakban nem befolyasolja egymast.
|
|
112
|
+
*
|
|
113
|
+
* Tipikus hasznalat: „mi lenne, ha" elore-szimulacio a fo-jatekmenet elrontasa nelkul.
|
|
114
|
+
*/
|
|
115
|
+
clone() {
|
|
116
|
+
return DyFM_SeededRandomRegistry_ControlModel.fromState(this.getState());
|
|
117
|
+
}
|
|
118
|
+
/** Tartalom-mentes diagnosztika: a szerkezet, nem a sorozatok kimenete. */
|
|
119
|
+
getDiagnostics() {
|
|
120
|
+
const channels = [...this.streams.keys()].sort();
|
|
121
|
+
return {
|
|
122
|
+
rootSeed: this.rootSeed,
|
|
123
|
+
channels: channels,
|
|
124
|
+
channelCount: channels.length,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
exports.DyFM_SeededRandomRegistry_ControlModel = DyFM_SeededRandomRegistry_ControlModel;
|
|
129
|
+
//# sourceMappingURL=seeded-random-registry.control-model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seeded-random-registry.control-model.js","sourceRoot":"","sources":["../../../../src/_modules/game/_models/seeded-random-registry.control-model.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { DyFM_SeededRandom_State } from './seeded-random-state.interface';
|
|
2
|
+
/**
|
|
3
|
+
* BFR-WARFACTORY-009 — a stream-registry MENTHETŐ állapota.
|
|
4
|
+
*
|
|
5
|
+
* ⚠️ **Verziózott**, mert ez egy mentés-payload: egy régi mentés betöltésekor tudni kell, hogy a
|
|
6
|
+
* benne lévő alak még értelmezhető-e. Verzió nélkül a formátum-változás néma adatromlás lenne.
|
|
7
|
+
*/
|
|
8
|
+
export interface DyFM_SeededRandomRegistry_State {
|
|
9
|
+
readonly contractVersion: 'dyfm-seeded-random-registry/1';
|
|
10
|
+
/** A gyökér-seed — ebből származik MINDEN csatorna. */
|
|
11
|
+
readonly rootSeed: string;
|
|
12
|
+
/** Csatornanév → az adott stream pillanatnyi állapota. */
|
|
13
|
+
readonly channels: Readonly<Record<string, DyFM_SeededRandom_State>>;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* BFR-WARFACTORY-009 — tartalom-mentes diagnosztika a registry-ről.
|
|
17
|
+
*
|
|
18
|
+
* A csatornanevek a HÍVÓ sajátjai (`'combat'`, `'worldgen'`…), tehát nem titkok — de a
|
|
19
|
+
* *sorozatokból* semmi nem kerül ide: a diagnosztika a szerkezetet írja le, nem a kimenetet.
|
|
20
|
+
*/
|
|
21
|
+
export interface DyFM_SeededRandomRegistry_Diagnostics {
|
|
22
|
+
readonly rootSeed: string;
|
|
23
|
+
/** A létrehozott csatornák nevei, ábécésorrendben (stabil kimenet). */
|
|
24
|
+
readonly channels: readonly string[];
|
|
25
|
+
readonly channelCount: number;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=seeded-random-registry.interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seeded-random-registry.interface.d.ts","sourceRoot":"","sources":["../../../../src/_modules/game/_models/seeded-random-registry.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAE1E;;;;;GAKG;AACH,MAAM,WAAW,+BAA+B;IAC9C,QAAQ,CAAC,eAAe,EAAE,+BAA+B,CAAC;IAC1D,uDAAuD;IACvD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,0DAA0D;IAC1D,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC,CAAC;CACtE;AAED;;;;;GAKG;AACH,MAAM,WAAW,qCAAqC;IACpD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,uEAAuE;IACvE,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seeded-random-registry.interface.js","sourceRoot":"","sources":["../../../../src/_modules/game/_models/seeded-random-registry.interface.ts"],"names":[],"mappings":""}
|
|
@@ -6,6 +6,8 @@ export * from './_models/audio-mixer.control-model';
|
|
|
6
6
|
export * from './_models/audio-scale.interface';
|
|
7
7
|
export * from './_models/seeded-random-state.interface';
|
|
8
8
|
export * from './_models/seeded-random.control-model';
|
|
9
|
+
export * from './_models/seeded-random-registry.interface';
|
|
10
|
+
export * from './_models/seeded-random-registry.control-model';
|
|
9
11
|
export * from './_collections/audio-mixer.util';
|
|
10
12
|
export * from './_collections/audio-scale.util';
|
|
11
13
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/_modules/game/index.ts"],"names":[],"mappings":"AACA,cAAc,6BAA6B,CAAC;AAG5C,cAAc,wCAAwC,CAAC;AACvD,cAAc,0CAA0C,CAAC;AACzD,cAAc,uCAAuC,CAAC;AACtD,cAAc,qCAAqC,CAAC;AACpD,cAAc,iCAAiC,CAAC;AAChD,cAAc,yCAAyC,CAAC;AACxD,cAAc,uCAAuC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/_modules/game/index.ts"],"names":[],"mappings":"AACA,cAAc,6BAA6B,CAAC;AAG5C,cAAc,wCAAwC,CAAC;AACvD,cAAc,0CAA0C,CAAC;AACzD,cAAc,uCAAuC,CAAC;AACtD,cAAc,qCAAqC,CAAC;AACpD,cAAc,iCAAiC,CAAC;AAChD,cAAc,yCAAyC,CAAC;AACxD,cAAc,uCAAuC,CAAC;AACtD,cAAc,4CAA4C,CAAC;AAC3D,cAAc,gDAAgD,CAAC;AAG/D,cAAc,iCAAiC,CAAC;AAChD,cAAc,iCAAiC,CAAC"}
|
|
@@ -11,6 +11,8 @@ tslib_1.__exportStar(require("./_models/audio-mixer.control-model"), exports);
|
|
|
11
11
|
tslib_1.__exportStar(require("./_models/audio-scale.interface"), exports);
|
|
12
12
|
tslib_1.__exportStar(require("./_models/seeded-random-state.interface"), exports);
|
|
13
13
|
tslib_1.__exportStar(require("./_models/seeded-random.control-model"), exports);
|
|
14
|
+
tslib_1.__exportStar(require("./_models/seeded-random-registry.interface"), exports);
|
|
15
|
+
tslib_1.__exportStar(require("./_models/seeded-random-registry.control-model"), exports);
|
|
14
16
|
// COLLECTIONS
|
|
15
17
|
tslib_1.__exportStar(require("./_collections/audio-mixer.util"), exports);
|
|
16
18
|
tslib_1.__exportStar(require("./_collections/audio-scale.util"), exports);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/_modules/game/index.ts"],"names":[],"mappings":";;;AAAA,QAAQ;AACR,sEAA4C;AAE5C,SAAS;AACT,iFAAuD;AACvD,mFAAyD;AACzD,gFAAsD;AACtD,8EAAoD;AACpD,0EAAgD;AAChD,kFAAwD;AACxD,gFAAsD;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/_modules/game/index.ts"],"names":[],"mappings":";;;AAAA,QAAQ;AACR,sEAA4C;AAE5C,SAAS;AACT,iFAAuD;AACvD,mFAAyD;AACzD,gFAAsD;AACtD,8EAAoD;AACpD,0EAAgD;AAChD,kFAAwD;AACxD,gFAAsD;AACtD,qFAA2D;AAC3D,yFAA+D;AAE/D,cAAc;AACd,0EAAgD;AAChD,0EAAgD"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { DyFM_RequestSafetyPolicy_Interface, DyFM_RequestSafetyResult_Interface } from '../_models/request-safety.interface';
|
|
2
|
+
/**
|
|
3
|
+
* BFR-CTM-034 — cross-runtime, content-free request safety inspector.
|
|
4
|
+
*
|
|
5
|
+
* ⚠️ **What this is for:** a value is about to cross a boundary (browser → transport, or transport →
|
|
6
|
+
* state mutation / provider dispatch). Once it has crossed, masking it afterwards is too late — the
|
|
7
|
+
* value has already been serialized, stored or sent. This inspector runs BEFORE that, and answers a
|
|
8
|
+
* single question: *may this cross?* — without ever repeating what it saw.
|
|
9
|
+
*
|
|
10
|
+
* ⛔ **No side effects, by construction.** No logging, no network, no storage, no timers, no `Math.random`,
|
|
11
|
+
* no environment access. That is not stylistic: the inspector runs on hostile input, so anything it
|
|
12
|
+
* touched would become an attack surface, and anything it logged would re-leak the value it rejected.
|
|
13
|
+
* The same source therefore runs unchanged in a browser, a Worker and Node.
|
|
14
|
+
*/
|
|
15
|
+
export declare class DyFM_RequestSafetyInspector_Util {
|
|
16
|
+
/**
|
|
17
|
+
* Format/invisible characters that hide a value from a naive matcher while remaining meaningful to a
|
|
18
|
+
* human reader or a downstream parser: zero-width space/non-joiner/joiner, word joiner, BOM, the
|
|
19
|
+
* bidirectional overrides, and the soft hyphen.
|
|
20
|
+
*
|
|
21
|
+
* ⭐ These are removed AFTER NFKC. NFKC alone does not drop them, so a `password` key would
|
|
22
|
+
* still slip past a forbidden-key set that only normalizes.
|
|
23
|
+
*/
|
|
24
|
+
private static readonly formatObfuscators;
|
|
25
|
+
/**
|
|
26
|
+
* Normalizes a string for matching: NFKC, then format-obfuscator removal, then case folding.
|
|
27
|
+
*
|
|
28
|
+
* ⚠️ The order matters. NFKC first folds the full-width and compatibility forms (`password`,
|
|
29
|
+
* `𝐩𝐚𝐬𝐬𝐰𝐨𝐫𝐝`) onto their ASCII equivalents; only then can the invisible-character strip and the
|
|
30
|
+
* case fold see a plain string. Reversing the steps leaves obfuscated forms unmatched.
|
|
31
|
+
*/
|
|
32
|
+
static normalize(value: string): string;
|
|
33
|
+
/**
|
|
34
|
+
* Inspects `input` against a caller-owned policy.
|
|
35
|
+
*
|
|
36
|
+
* Fail-closed everywhere: an invalid policy, an unsupported value type, a hostile prototype, an
|
|
37
|
+
* accessor or a blown budget all DECLINE. There is no path that returns `accepted: true` because the
|
|
38
|
+
* inspector could not decide.
|
|
39
|
+
*
|
|
40
|
+
* @returns a content-free outcome; the input itself is never echoed in any form.
|
|
41
|
+
*/
|
|
42
|
+
static inspect(input: unknown, policy: DyFM_RequestSafetyPolicy_Interface): DyFM_RequestSafetyResult_Interface;
|
|
43
|
+
/** A string vizsgalata: budget, kanari, tiltott ertek-mintak, nem tamogatott kepessegek. */
|
|
44
|
+
private static inspectString;
|
|
45
|
+
/**
|
|
46
|
+
* Egy minta-csoport illesztese, csoportonként LEGFELJEBB EGY leletet szamolva.
|
|
47
|
+
*
|
|
48
|
+
* ⚠️ A `lastIndex` szandekosan nullazva: egy `/g` flag-es minta allapotot visz magaval, es a hivo
|
|
49
|
+
* altal atadott, ujrahasznalt RegExp kulonben a MASODIK hivasnal mast talalna, mint az elson —
|
|
50
|
+
* ugyanarra a bemenetre. Ez a fajta nem-determinizmus egy biztonsagi kapunal elfogadhatatlan.
|
|
51
|
+
*/
|
|
52
|
+
private static recordPatternHit;
|
|
53
|
+
/** A policy strukturalis ervenyessege. Barmelyik hianyzo budget = ervenytelen. */
|
|
54
|
+
private static isPolicyValid;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=request-safety-inspector.util.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-safety-inspector.util.d.ts","sourceRoot":"","sources":["../../../../src/_modules/request-safety/_collections/request-safety-inspector.util.ts"],"names":[],"mappings":"AACA,OAAO,EACL,kCAAkC,EAAE,kCAAkC,EACvE,MAAM,qCAAqC,CAAC;AAE7C;;;;;;;;;;;;GAYG;AACH,qBAAa,gCAAgC;IAE3C;;;;;;;OAOG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CACkB;IAE3D;;;;;;OAMG;IACH,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAOvC;;;;;;;;OAQG;IACH,MAAM,CAAC,OAAO,CACZ,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,kCAAkC,GACzC,kCAAkC;IA6HrC,4FAA4F;IAC5F,OAAO,CAAC,MAAM,CAAC,aAAa;IA8B5B;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAuB/B,kFAAkF;IAClF,OAAO,CAAC,MAAM,CAAC,aAAa;CAY7B"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DyFM_RequestSafetyInspector_Util = void 0;
|
|
4
|
+
const request_safety_finding_type_enum_1 = require("../_enums/request-safety-finding.type-enum");
|
|
5
|
+
/**
|
|
6
|
+
* BFR-CTM-034 — cross-runtime, content-free request safety inspector.
|
|
7
|
+
*
|
|
8
|
+
* ⚠️ **What this is for:** a value is about to cross a boundary (browser → transport, or transport →
|
|
9
|
+
* state mutation / provider dispatch). Once it has crossed, masking it afterwards is too late — the
|
|
10
|
+
* value has already been serialized, stored or sent. This inspector runs BEFORE that, and answers a
|
|
11
|
+
* single question: *may this cross?* — without ever repeating what it saw.
|
|
12
|
+
*
|
|
13
|
+
* ⛔ **No side effects, by construction.** No logging, no network, no storage, no timers, no `Math.random`,
|
|
14
|
+
* no environment access. That is not stylistic: the inspector runs on hostile input, so anything it
|
|
15
|
+
* touched would become an attack surface, and anything it logged would re-leak the value it rejected.
|
|
16
|
+
* The same source therefore runs unchanged in a browser, a Worker and Node.
|
|
17
|
+
*/
|
|
18
|
+
class DyFM_RequestSafetyInspector_Util {
|
|
19
|
+
/**
|
|
20
|
+
* Format/invisible characters that hide a value from a naive matcher while remaining meaningful to a
|
|
21
|
+
* human reader or a downstream parser: zero-width space/non-joiner/joiner, word joiner, BOM, the
|
|
22
|
+
* bidirectional overrides, and the soft hyphen.
|
|
23
|
+
*
|
|
24
|
+
* ⭐ These are removed AFTER NFKC. NFKC alone does not drop them, so a `password` key would
|
|
25
|
+
* still slip past a forbidden-key set that only normalizes.
|
|
26
|
+
*/
|
|
27
|
+
static formatObfuscators = /[\u00ad\u200b-\u200f\u202a-\u202e\u2060-\u2064\ufeff]/g;
|
|
28
|
+
/**
|
|
29
|
+
* Normalizes a string for matching: NFKC, then format-obfuscator removal, then case folding.
|
|
30
|
+
*
|
|
31
|
+
* ⚠️ The order matters. NFKC first folds the full-width and compatibility forms (`password`,
|
|
32
|
+
* `𝐩𝐚𝐬𝐬𝐰𝐨𝐫𝐝`) onto their ASCII equivalents; only then can the invisible-character strip and the
|
|
33
|
+
* case fold see a plain string. Reversing the steps leaves obfuscated forms unmatched.
|
|
34
|
+
*/
|
|
35
|
+
static normalize(value) {
|
|
36
|
+
return `${value ?? ''}`
|
|
37
|
+
.normalize('NFKC')
|
|
38
|
+
.replace(DyFM_RequestSafetyInspector_Util.formatObfuscators, '')
|
|
39
|
+
.toLowerCase();
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Inspects `input` against a caller-owned policy.
|
|
43
|
+
*
|
|
44
|
+
* Fail-closed everywhere: an invalid policy, an unsupported value type, a hostile prototype, an
|
|
45
|
+
* accessor or a blown budget all DECLINE. There is no path that returns `accepted: true` because the
|
|
46
|
+
* inspector could not decide.
|
|
47
|
+
*
|
|
48
|
+
* @returns a content-free outcome; the input itself is never echoed in any form.
|
|
49
|
+
*/
|
|
50
|
+
static inspect(input, policy) {
|
|
51
|
+
const counts = {};
|
|
52
|
+
let inspectedNodes = 0;
|
|
53
|
+
const namespace = typeof policy?.namespace === 'string' ? policy.namespace.trim() : '';
|
|
54
|
+
const record = (finding) => {
|
|
55
|
+
const code = `${namespace}:${finding}`;
|
|
56
|
+
counts[code] = (counts[code] ?? 0) + 1;
|
|
57
|
+
};
|
|
58
|
+
if (!DyFM_RequestSafetyInspector_Util.isPolicyValid(policy)) {
|
|
59
|
+
// A hibas policy NEM "nincs szabaly, tehat mehet" — az a leghangosabb fail-open lenne.
|
|
60
|
+
const code = `${namespace || 'unknown'}:${request_safety_finding_type_enum_1.DyFM_RequestSafetyFinding_Type.invalidPolicy}`;
|
|
61
|
+
return {
|
|
62
|
+
contractVersion: 'dyfm-request-safety/1',
|
|
63
|
+
accepted: false,
|
|
64
|
+
findingCodes: [code],
|
|
65
|
+
findingCounts: { [code]: 1 },
|
|
66
|
+
inspectedNodes: 0,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
const forbiddenKeys = new Set((policy.forbiddenKeys ?? []).map((key) => DyFM_RequestSafetyInspector_Util.normalize(key)));
|
|
70
|
+
const canaries = (policy.canaries ?? []).map((canary) => DyFM_RequestSafetyInspector_Util.normalize(canary));
|
|
71
|
+
// ⚠️ A ciklus-vedelem a MEGLATOGATOTT objektumok halmaza, nem melyseg-szamlalo: egy `a.b.a`
|
|
72
|
+
// onhivatkozas veges melysegben is vegtelen bejarast okozna.
|
|
73
|
+
const seen = new Set();
|
|
74
|
+
const walk = (value, depth) => {
|
|
75
|
+
if (inspectedNodes >= policy.maxNodes) {
|
|
76
|
+
record(request_safety_finding_type_enum_1.DyFM_RequestSafetyFinding_Type.nodeBudget);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
inspectedNodes++;
|
|
80
|
+
if (depth > policy.maxDepth) {
|
|
81
|
+
record(request_safety_finding_type_enum_1.DyFM_RequestSafetyFinding_Type.depthBudget);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
if (value === null || typeof value === 'boolean' || typeof value === 'number') {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
if (typeof value === 'string') {
|
|
88
|
+
DyFM_RequestSafetyInspector_Util.inspectString(value, policy, canaries, record);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
if (typeof value === 'undefined') {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if (typeof value !== 'object') {
|
|
95
|
+
// fuggveny, symbol, bigint — a kontraktus nem hordozza oket
|
|
96
|
+
record(request_safety_finding_type_enum_1.DyFM_RequestSafetyFinding_Type.unsupportedValueType);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
if (seen.has(value)) {
|
|
100
|
+
record(request_safety_finding_type_enum_1.DyFM_RequestSafetyFinding_Type.cycle);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
seen.add(value);
|
|
104
|
+
if (Array.isArray(value)) {
|
|
105
|
+
for (const item of value) {
|
|
106
|
+
walk(item, depth + 1);
|
|
107
|
+
}
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
const prototype = Object.getPrototypeOf(value);
|
|
111
|
+
if (prototype !== Object.prototype && prototype !== null) {
|
|
112
|
+
// Date, Map, class-peldany, `__proto__`-val megmergezett objektum: a szerializalt alak nem
|
|
113
|
+
// egyezne azzal, amit itt lattunk — tehat az ellenorzes ertelmet vesztene.
|
|
114
|
+
record(request_safety_finding_type_enum_1.DyFM_RequestSafetyFinding_Type.unsupportedPrototype);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
for (const key of Object.getOwnPropertyNames(value)) {
|
|
118
|
+
if (forbiddenKeys.has(DyFM_RequestSafetyInspector_Util.normalize(key))) {
|
|
119
|
+
record(request_safety_finding_type_enum_1.DyFM_RequestSafetyFinding_Type.forbiddenKey);
|
|
120
|
+
}
|
|
121
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
122
|
+
if (descriptor && (descriptor.get || descriptor.set)) {
|
|
123
|
+
// ⛔ SOHA nem olvassuk ki: egy getter a hivo kodjat futtatna le a mi vizsgalatunk kozben.
|
|
124
|
+
record(request_safety_finding_type_enum_1.DyFM_RequestSafetyFinding_Type.accessor);
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
walk(descriptor?.value, depth + 1);
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
walk(input, 0);
|
|
131
|
+
const findingCodes = Object.keys(counts).sort();
|
|
132
|
+
return {
|
|
133
|
+
contractVersion: 'dyfm-request-safety/1',
|
|
134
|
+
accepted: findingCodes.length === 0,
|
|
135
|
+
findingCodes: findingCodes,
|
|
136
|
+
findingCounts: counts,
|
|
137
|
+
inspectedNodes: inspectedNodes,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
/** A string vizsgalata: budget, kanari, tiltott ertek-mintak, nem tamogatott kepessegek. */
|
|
141
|
+
static inspectString(value, policy, canaries, record) {
|
|
142
|
+
const normalized = DyFM_RequestSafetyInspector_Util.normalize(value);
|
|
143
|
+
if (normalized.length > policy.maxStringLength) {
|
|
144
|
+
record(request_safety_finding_type_enum_1.DyFM_RequestSafetyFinding_Type.stringBudget);
|
|
145
|
+
}
|
|
146
|
+
for (const canary of canaries) {
|
|
147
|
+
if (canary.length > 0 && normalized.includes(canary)) {
|
|
148
|
+
record(request_safety_finding_type_enum_1.DyFM_RequestSafetyFinding_Type.canary);
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
DyFM_RequestSafetyInspector_Util.recordPatternHit(normalized, policy.sensitiveValuePatterns, request_safety_finding_type_enum_1.DyFM_RequestSafetyFinding_Type.sensitiveValue, record);
|
|
153
|
+
DyFM_RequestSafetyInspector_Util.recordPatternHit(normalized, policy.unsupportedCapabilityPatterns, request_safety_finding_type_enum_1.DyFM_RequestSafetyFinding_Type.unsupportedCapability, record);
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Egy minta-csoport illesztese, csoportonként LEGFELJEBB EGY leletet szamolva.
|
|
157
|
+
*
|
|
158
|
+
* ⚠️ A `lastIndex` szandekosan nullazva: egy `/g` flag-es minta allapotot visz magaval, es a hivo
|
|
159
|
+
* altal atadott, ujrahasznalt RegExp kulonben a MASODIK hivasnal mast talalna, mint az elson —
|
|
160
|
+
* ugyanarra a bemenetre. Ez a fajta nem-determinizmus egy biztonsagi kapunal elfogadhatatlan.
|
|
161
|
+
*/
|
|
162
|
+
static recordPatternHit(normalized, patterns, finding, record) {
|
|
163
|
+
for (const pattern of patterns ?? []) {
|
|
164
|
+
pattern.lastIndex = 0;
|
|
165
|
+
const matched = pattern.test(normalized);
|
|
166
|
+
// ⚠️ UTANA is nullazunk: a `/g` minta a sikeres `test()` utan a talalat vegen hagyja a
|
|
167
|
+
// `lastIndex`-et. A hivo UGYANAZT a RegExp-peldanyt hasznalhatja mashol is — ha elmozdulva
|
|
168
|
+
// adnank vissza, a sajat kovetkezo `test()`-je mast talalna. A vizsgalonak a hivo allapotat
|
|
169
|
+
// pontosan ugy kell hagynia, ahogy kapta. (Merve: `lastIndex` 6 maradt a nullazas nelkul.)
|
|
170
|
+
pattern.lastIndex = 0;
|
|
171
|
+
if (matched) {
|
|
172
|
+
record(finding);
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
/** A policy strukturalis ervenyessege. Barmelyik hianyzo budget = ervenytelen. */
|
|
178
|
+
static isPolicyValid(policy) {
|
|
179
|
+
if (!policy || typeof policy !== 'object') {
|
|
180
|
+
return false;
|
|
181
|
+
}
|
|
182
|
+
if (typeof policy.namespace !== 'string' || policy.namespace.trim().length === 0) {
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
return [policy.maxDepth, policy.maxNodes, policy.maxStringLength].every((budget) => Number.isSafeInteger(budget) && budget > 0);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
exports.DyFM_RequestSafetyInspector_Util = DyFM_RequestSafetyInspector_Util;
|
|
189
|
+
//# sourceMappingURL=request-safety-inspector.util.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-safety-inspector.util.js","sourceRoot":"","sources":["../../../../src/_modules/request-safety/_collections/request-safety-inspector.util.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BFR-CTM-034 — the closed, content-free finding vocabulary.
|
|
3
|
+
*
|
|
4
|
+
* ⛔ These codes are the ONLY thing an inspection may say about *why* it declined. They deliberately
|
|
5
|
+
* describe the **class** of problem, never the offending value, key, path or pattern: a finding that
|
|
6
|
+
* echoes what it found turns a safety check into the very leak it was meant to prevent.
|
|
7
|
+
*
|
|
8
|
+
* The caller prefixes them with its own namespace, so two products can never confuse each other's
|
|
9
|
+
* findings while still sharing this vocabulary.
|
|
10
|
+
*/
|
|
11
|
+
export declare enum DyFM_RequestSafetyFinding_Type {
|
|
12
|
+
/** A key matched the caller's forbidden-key set (after normalization). */
|
|
13
|
+
forbiddenKey = "forbidden-key",
|
|
14
|
+
/** A string value matched one of the caller's sensitive-value patterns. */
|
|
15
|
+
sensitiveValue = "sensitive-value",
|
|
16
|
+
/** A string value matched one of the caller's unsupported-capability patterns. */
|
|
17
|
+
unsupportedCapability = "unsupported-capability",
|
|
18
|
+
/** A caller-planted canary was found — proof that a rejected value reached the boundary. */
|
|
19
|
+
canary = "canary",
|
|
20
|
+
/** The graph contains a cycle. */
|
|
21
|
+
cycle = "cycle",
|
|
22
|
+
/** Nesting exceeded the caller's depth budget. */
|
|
23
|
+
depthBudget = "depth-budget",
|
|
24
|
+
/** The node count exceeded the caller's budget. */
|
|
25
|
+
nodeBudget = "node-budget",
|
|
26
|
+
/** A string exceeded the caller's length budget. */
|
|
27
|
+
stringBudget = "string-budget",
|
|
28
|
+
/** A property is defined by an accessor (getter/setter) — reading it could execute caller code. */
|
|
29
|
+
accessor = "accessor",
|
|
30
|
+
/** An object's prototype is neither `Object.prototype` nor `null`. */
|
|
31
|
+
unsupportedPrototype = "unsupported-prototype",
|
|
32
|
+
/** A value is of a type the contract does not carry (function, symbol, bigint, class instance…). */
|
|
33
|
+
unsupportedValueType = "unsupported-value-type",
|
|
34
|
+
/** The policy itself is invalid — fail-closed, the input is never inspected. */
|
|
35
|
+
invalidPolicy = "invalid-policy"
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=request-safety-finding.type-enum.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-safety-finding.type-enum.d.ts","sourceRoot":"","sources":["../../../../src/_modules/request-safety/_enums/request-safety-finding.type-enum.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,oBAAY,8BAA8B;IACxC,0EAA0E;IAC1E,YAAY,kBAAkB;IAC9B,2EAA2E;IAC3E,cAAc,oBAAoB;IAClC,kFAAkF;IAClF,qBAAqB,2BAA2B;IAChD,4FAA4F;IAC5F,MAAM,WAAW;IACjB,kCAAkC;IAClC,KAAK,UAAU;IACf,kDAAkD;IAClD,WAAW,iBAAiB;IAC5B,mDAAmD;IACnD,UAAU,gBAAgB;IAC1B,oDAAoD;IACpD,YAAY,kBAAkB;IAC9B,mGAAmG;IACnG,QAAQ,aAAa;IACrB,sEAAsE;IACtE,oBAAoB,0BAA0B;IAC9C,oGAAoG;IACpG,oBAAoB,2BAA2B;IAC/C,gFAAgF;IAChF,aAAa,mBAAmB;CACjC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DyFM_RequestSafetyFinding_Type = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* BFR-CTM-034 — the closed, content-free finding vocabulary.
|
|
6
|
+
*
|
|
7
|
+
* ⛔ These codes are the ONLY thing an inspection may say about *why* it declined. They deliberately
|
|
8
|
+
* describe the **class** of problem, never the offending value, key, path or pattern: a finding that
|
|
9
|
+
* echoes what it found turns a safety check into the very leak it was meant to prevent.
|
|
10
|
+
*
|
|
11
|
+
* The caller prefixes them with its own namespace, so two products can never confuse each other's
|
|
12
|
+
* findings while still sharing this vocabulary.
|
|
13
|
+
*/
|
|
14
|
+
var DyFM_RequestSafetyFinding_Type;
|
|
15
|
+
(function (DyFM_RequestSafetyFinding_Type) {
|
|
16
|
+
/** A key matched the caller's forbidden-key set (after normalization). */
|
|
17
|
+
DyFM_RequestSafetyFinding_Type["forbiddenKey"] = "forbidden-key";
|
|
18
|
+
/** A string value matched one of the caller's sensitive-value patterns. */
|
|
19
|
+
DyFM_RequestSafetyFinding_Type["sensitiveValue"] = "sensitive-value";
|
|
20
|
+
/** A string value matched one of the caller's unsupported-capability patterns. */
|
|
21
|
+
DyFM_RequestSafetyFinding_Type["unsupportedCapability"] = "unsupported-capability";
|
|
22
|
+
/** A caller-planted canary was found — proof that a rejected value reached the boundary. */
|
|
23
|
+
DyFM_RequestSafetyFinding_Type["canary"] = "canary";
|
|
24
|
+
/** The graph contains a cycle. */
|
|
25
|
+
DyFM_RequestSafetyFinding_Type["cycle"] = "cycle";
|
|
26
|
+
/** Nesting exceeded the caller's depth budget. */
|
|
27
|
+
DyFM_RequestSafetyFinding_Type["depthBudget"] = "depth-budget";
|
|
28
|
+
/** The node count exceeded the caller's budget. */
|
|
29
|
+
DyFM_RequestSafetyFinding_Type["nodeBudget"] = "node-budget";
|
|
30
|
+
/** A string exceeded the caller's length budget. */
|
|
31
|
+
DyFM_RequestSafetyFinding_Type["stringBudget"] = "string-budget";
|
|
32
|
+
/** A property is defined by an accessor (getter/setter) — reading it could execute caller code. */
|
|
33
|
+
DyFM_RequestSafetyFinding_Type["accessor"] = "accessor";
|
|
34
|
+
/** An object's prototype is neither `Object.prototype` nor `null`. */
|
|
35
|
+
DyFM_RequestSafetyFinding_Type["unsupportedPrototype"] = "unsupported-prototype";
|
|
36
|
+
/** A value is of a type the contract does not carry (function, symbol, bigint, class instance…). */
|
|
37
|
+
DyFM_RequestSafetyFinding_Type["unsupportedValueType"] = "unsupported-value-type";
|
|
38
|
+
/** The policy itself is invalid — fail-closed, the input is never inspected. */
|
|
39
|
+
DyFM_RequestSafetyFinding_Type["invalidPolicy"] = "invalid-policy";
|
|
40
|
+
})(DyFM_RequestSafetyFinding_Type || (exports.DyFM_RequestSafetyFinding_Type = DyFM_RequestSafetyFinding_Type = {}));
|
|
41
|
+
//# sourceMappingURL=request-safety-finding.type-enum.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-safety-finding.type-enum.js","sourceRoot":"","sources":["../../../../src/_modules/request-safety/_enums/request-safety-finding.type-enum.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;GASG;AACH,IAAY,8BAyBX;AAzBD,WAAY,8BAA8B;IACxC,0EAA0E;IAC1E,gEAA8B,CAAA;IAC9B,2EAA2E;IAC3E,oEAAkC,CAAA;IAClC,kFAAkF;IAClF,kFAAgD,CAAA;IAChD,4FAA4F;IAC5F,mDAAiB,CAAA;IACjB,kCAAkC;IAClC,iDAAe,CAAA;IACf,kDAAkD;IAClD,8DAA4B,CAAA;IAC5B,mDAAmD;IACnD,4DAA0B,CAAA;IAC1B,oDAAoD;IACpD,gEAA8B,CAAA;IAC9B,mGAAmG;IACnG,uDAAqB,CAAA;IACrB,sEAAsE;IACtE,gFAA8C,CAAA;IAC9C,oGAAoG;IACpG,iFAA+C,CAAA;IAC/C,gFAAgF;IAChF,kEAAgC,CAAA;AAClC,CAAC,EAzBW,8BAA8B,8CAA9B,8BAA8B,QAyBzC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { DyFM_RequestSafetyFinding_Type } from '../_enums/request-safety-finding.type-enum';
|
|
2
|
+
/**
|
|
3
|
+
* BFR-CTM-034 — the caller-owned inspection policy.
|
|
4
|
+
*
|
|
5
|
+
* ⚠️ **Every product rule lives here, not in the framework.** The bedrock deliberately does NOT decide
|
|
6
|
+
* that an API mention, a URL or a credential-looking string is invalid — one product forbids external
|
|
7
|
+
* network access, another is built on it. Hard-coding that judgement would make this primitive
|
|
8
|
+
* unusable for half the fleet and would silently impose one product's contract on the others.
|
|
9
|
+
*
|
|
10
|
+
* What the framework owns is the *mechanics*: normalization, cycle-safe traversal, budgets and the
|
|
11
|
+
* content-free outcome. What the caller owns is *what counts as unsafe*.
|
|
12
|
+
*/
|
|
13
|
+
export interface DyFM_RequestSafetyPolicy_Interface {
|
|
14
|
+
/**
|
|
15
|
+
* Stable caller namespace, prefixed onto every finding code (e.g. `ctm-r5`).
|
|
16
|
+
*
|
|
17
|
+
* Two products can then share this vocabulary without their findings becoming ambiguous in a shared
|
|
18
|
+
* log or dashboard.
|
|
19
|
+
*/
|
|
20
|
+
readonly namespace: string;
|
|
21
|
+
/**
|
|
22
|
+
* Keys the caller refuses to transport. Matched against the **normalized** key, so a key hidden with
|
|
23
|
+
* zero-width joiners or full-width characters is still caught.
|
|
24
|
+
*/
|
|
25
|
+
readonly forbiddenKeys?: readonly string[];
|
|
26
|
+
/** Patterns for values the caller treats as secret/PII. Matched against the normalized string. */
|
|
27
|
+
readonly sensitiveValuePatterns?: readonly RegExp[];
|
|
28
|
+
/** Patterns for capabilities the caller's product contract does not support. */
|
|
29
|
+
readonly unsupportedCapabilityPatterns?: readonly RegExp[];
|
|
30
|
+
/**
|
|
31
|
+
* Exact canary strings the caller planted upstream.
|
|
32
|
+
*
|
|
33
|
+
* ⭐ A canary hit is qualitatively different from the other findings: it proves a value the caller
|
|
34
|
+
* already rejected **reached this boundary anyway**, i.e. an earlier guard leaked.
|
|
35
|
+
*/
|
|
36
|
+
readonly canaries?: readonly string[];
|
|
37
|
+
/** Maximum nesting depth. The root is depth 0. */
|
|
38
|
+
readonly maxDepth: number;
|
|
39
|
+
/** Maximum number of inspected nodes (values), including the root. */
|
|
40
|
+
readonly maxNodes: number;
|
|
41
|
+
/** Maximum length of any single string, measured AFTER normalization. */
|
|
42
|
+
readonly maxStringLength: number;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* BFR-CTM-034 — the content-free inspection outcome.
|
|
46
|
+
*
|
|
47
|
+
* ⛔ **There is deliberately no field that could carry the offending data.** No matched text, no key,
|
|
48
|
+
* no pattern source, no object path, no payload fragment, no stack. Only: which classes of problem
|
|
49
|
+
* occurred, and how many times. A reviewer can act on this; an attacker learns nothing from it, and a
|
|
50
|
+
* log that captures it cannot become a secondary leak.
|
|
51
|
+
*/
|
|
52
|
+
export interface DyFM_RequestSafetyResult_Interface {
|
|
53
|
+
readonly contractVersion: 'dyfm-request-safety/1';
|
|
54
|
+
/** `false` if ANY finding occurred — the inspection is deny-only and fail-closed. */
|
|
55
|
+
readonly accepted: boolean;
|
|
56
|
+
/** Namespaced, de-duplicated finding codes, e.g. `ctm-r5:forbidden-key`. Sorted for stability. */
|
|
57
|
+
readonly findingCodes: readonly string[];
|
|
58
|
+
/** How many times each finding class occurred. Aggregate only — never per-occurrence detail. */
|
|
59
|
+
readonly findingCounts: Readonly<Record<string, number>>;
|
|
60
|
+
/** How many nodes were actually inspected (bounded by `maxNodes`). */
|
|
61
|
+
readonly inspectedNodes: number;
|
|
62
|
+
}
|
|
63
|
+
/** BFR-CTM-034 — an internal, per-run finding tally. Never leaves the module in this shape. */
|
|
64
|
+
export interface DyFM_RequestSafetyTally_Interface {
|
|
65
|
+
readonly finding: DyFM_RequestSafetyFinding_Type;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=request-safety.interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-safety.interface.d.ts","sourceRoot":"","sources":["../../../../src/_modules/request-safety/_models/request-safety.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,MAAM,4CAA4C,CAAC;AAE5F;;;;;;;;;;GAUG;AACH,MAAM,WAAW,kCAAkC;IACjD;;;;;OAKG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C,kGAAkG;IAClG,QAAQ,CAAC,sBAAsB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpD,gFAAgF;IAChF,QAAQ,CAAC,6BAA6B,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3D;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,kDAAkD;IAClD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,sEAAsE;IACtE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,yEAAyE;IACzE,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;CAClC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,kCAAkC;IACjD,QAAQ,CAAC,eAAe,EAAE,uBAAuB,CAAC;IAClD,qFAAqF;IACrF,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,kGAAkG;IAClG,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,gGAAgG;IAChG,QAAQ,CAAC,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACzD,sEAAsE;IACtE,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED,+FAA+F;AAC/F,MAAM,WAAW,iCAAiC;IAChD,QAAQ,CAAC,OAAO,EAAE,8BAA8B,CAAC;CAClD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-safety.interface.js","sourceRoot":"","sources":["../../../../src/_modules/request-safety/_models/request-safety.interface.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/_modules/request-safety/index.ts"],"names":[],"mappings":"AAAA,cAAc,8CAA8C,CAAC;AAC7D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,oCAAoC,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
tslib_1.__exportStar(require("./_collections/request-safety-inspector.util"), exports);
|
|
5
|
+
tslib_1.__exportStar(require("./_enums/request-safety-finding.type-enum"), exports);
|
|
6
|
+
tslib_1.__exportStar(require("./_models/request-safety.interface"), exports);
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/_modules/request-safety/index.ts"],"names":[],"mappings":";;;AAAA,uFAA6D;AAC7D,oFAA0D;AAC1D,6EAAmD"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@futdevpro/fsm-dynamo",
|
|
3
|
-
"version": "1.20.
|
|
3
|
+
"version": "1.20.25",
|
|
4
4
|
"description": "Full Stack Model Collection for Dynamic (NodeJS-Typescript) Framework called Dynamo, by Future Development Ltd.",
|
|
5
5
|
"DyBu_settings": {
|
|
6
6
|
"packageType": "full-stack-package",
|
|
@@ -131,6 +131,12 @@
|
|
|
131
131
|
"types": "./build/_modules/crypto/index.d.ts",
|
|
132
132
|
"typings": "./build/_modules/crypto/index.d.ts"
|
|
133
133
|
},
|
|
134
|
+
"./request-safety": {
|
|
135
|
+
"default": "./build/_modules/request-safety/index.js",
|
|
136
|
+
"module": "./build/_modules/request-safety/index.js",
|
|
137
|
+
"types": "./build/_modules/request-safety/index.d.ts",
|
|
138
|
+
"typings": "./build/_modules/request-safety/index.d.ts"
|
|
139
|
+
},
|
|
134
140
|
"./deployment": {
|
|
135
141
|
"default": "./build/_modules/deployment/index.js",
|
|
136
142
|
"module": "./build/_modules/deployment/index.js",
|
|
@@ -257,6 +263,9 @@
|
|
|
257
263
|
"crypto": [
|
|
258
264
|
"build/_modules/crypto/index.d.ts"
|
|
259
265
|
],
|
|
266
|
+
"request-safety": [
|
|
267
|
+
"build/_modules/request-safety/index.d.ts"
|
|
268
|
+
],
|
|
260
269
|
"deployment": [
|
|
261
270
|
"build/_modules/deployment/index.d.ts"
|
|
262
271
|
],
|
|
@@ -321,7 +330,7 @@
|
|
|
321
330
|
"uuid": "~11.1.1"
|
|
322
331
|
},
|
|
323
332
|
"devDependencies": {
|
|
324
|
-
"@futdevpro/dynamo-eslint": "1.20.
|
|
333
|
+
"@futdevpro/dynamo-eslint": "1.20.14",
|
|
325
334
|
"@types/jasmine": "~4.3.5",
|
|
326
335
|
"@typescript-eslint/eslint-plugin": "^8.41.0",
|
|
327
336
|
"@typescript-eslint/parser": "^8.41.0",
|