@futdevpro/nts-dynamo 1.15.465 → 1.15.466
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/messaging/index.d.ts +9 -0
- package/build/_modules/messaging/index.d.ts.map +1 -1
- package/build/_modules/messaging/index.js +10 -0
- package/build/_modules/messaging/index.js.map +1 -1
- package/build/_modules/messaging/input-draft/msg-input-draft-call.interface.d.ts +13 -0
- package/build/_modules/messaging/input-draft/msg-input-draft-call.interface.d.ts.map +1 -0
- package/build/_modules/messaging/input-draft/msg-input-draft-call.interface.js +3 -0
- package/build/_modules/messaging/input-draft/msg-input-draft-call.interface.js.map +1 -0
- package/build/_modules/messaging/input-draft/msg-input-draft-default-settings.const.d.ts +6 -0
- package/build/_modules/messaging/input-draft/msg-input-draft-default-settings.const.d.ts.map +1 -0
- package/build/_modules/messaging/input-draft/msg-input-draft-default-settings.const.js +16 -0
- package/build/_modules/messaging/input-draft/msg-input-draft-default-settings.const.js.map +1 -0
- package/build/_modules/messaging/input-draft/msg-input-draft-routing.util.d.ts +22 -0
- package/build/_modules/messaging/input-draft/msg-input-draft-routing.util.d.ts.map +1 -0
- package/build/_modules/messaging/input-draft/msg-input-draft-routing.util.js +34 -0
- package/build/_modules/messaging/input-draft/msg-input-draft-routing.util.js.map +1 -0
- package/build/_modules/messaging/input-draft/msg-input-draft-save-result.interface.d.ts +15 -0
- package/build/_modules/messaging/input-draft/msg-input-draft-save-result.interface.d.ts.map +1 -0
- package/build/_modules/messaging/input-draft/msg-input-draft-save-result.interface.js +3 -0
- package/build/_modules/messaging/input-draft/msg-input-draft-save-result.interface.js.map +1 -0
- package/build/_modules/messaging/input-draft/msg-input-draft-settings.interface.d.ts +20 -0
- package/build/_modules/messaging/input-draft/msg-input-draft-settings.interface.d.ts.map +1 -0
- package/build/_modules/messaging/input-draft/msg-input-draft-settings.interface.js +3 -0
- package/build/_modules/messaging/input-draft/msg-input-draft-settings.interface.js.map +1 -0
- package/build/_modules/messaging/input-draft/msg-input-draft.controller.d.ts +46 -0
- package/build/_modules/messaging/input-draft/msg-input-draft.controller.d.ts.map +1 -0
- package/build/_modules/messaging/input-draft/msg-input-draft.controller.js +139 -0
- package/build/_modules/messaging/input-draft/msg-input-draft.controller.js.map +1 -0
- package/build/_modules/messaging/input-draft/msg-input-draft.data-model.d.ts +38 -0
- package/build/_modules/messaging/input-draft/msg-input-draft.data-model.d.ts.map +1 -0
- package/build/_modules/messaging/input-draft/msg-input-draft.data-model.js +60 -0
- package/build/_modules/messaging/input-draft/msg-input-draft.data-model.js.map +1 -0
- package/build/_modules/messaging/input-draft/msg-input-draft.data-service.d.ts +55 -0
- package/build/_modules/messaging/input-draft/msg-input-draft.data-service.d.ts.map +1 -0
- package/build/_modules/messaging/input-draft/msg-input-draft.data-service.js +123 -0
- package/build/_modules/messaging/input-draft/msg-input-draft.data-service.js.map +1 -0
- package/build/_modules/messaging/input-draft/msg-input-draft.util.d.ts +20 -0
- package/build/_modules/messaging/input-draft/msg-input-draft.util.d.ts.map +1 -0
- package/build/_modules/messaging/input-draft/msg-input-draft.util.js +71 -0
- package/build/_modules/messaging/input-draft/msg-input-draft.util.js.map +1 -0
- package/package.json +1 -1
|
@@ -8,4 +8,13 @@ export * from './_services/msg-events.service';
|
|
|
8
8
|
export * from './_services/msg-main.control-service';
|
|
9
9
|
export * from './_services/msg-message.data-service';
|
|
10
10
|
export * from './_services/msg.controller';
|
|
11
|
+
export * from './input-draft/msg-input-draft.data-model';
|
|
12
|
+
export * from './input-draft/msg-input-draft-settings.interface';
|
|
13
|
+
export * from './input-draft/msg-input-draft-default-settings.const';
|
|
14
|
+
export * from './input-draft/msg-input-draft-save-result.interface';
|
|
15
|
+
export * from './input-draft/msg-input-draft.util';
|
|
16
|
+
export * from './input-draft/msg-input-draft.data-service';
|
|
17
|
+
export * from './input-draft/msg-input-draft.controller';
|
|
18
|
+
export * from './input-draft/msg-input-draft-routing.util';
|
|
19
|
+
export * from './input-draft/msg-input-draft-call.interface';
|
|
11
20
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/_modules/messaging/index.ts"],"names":[],"mappings":"AASA,cAAc,iCAAiC,CAAC;AAGhD,cAAc,yCAAyC,CAAC;AAGxD,cAAc,kDAAkD,CAAC;AACjE,cAAc,0CAA0C,CAAC;AACzD,cAAc,yBAAyB,CAAC;AAMxC,cAAc,2CAA2C,CAAC;AAC1D,cAAc,gCAAgC,CAAC;AAE/C,cAAc,sCAAsC,CAAC;AACrD,cAAc,sCAAsC,CAAC;AACrD,cAAc,4BAA4B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/_modules/messaging/index.ts"],"names":[],"mappings":"AASA,cAAc,iCAAiC,CAAC;AAGhD,cAAc,yCAAyC,CAAC;AAGxD,cAAc,kDAAkD,CAAC;AACjE,cAAc,0CAA0C,CAAC;AACzD,cAAc,yBAAyB,CAAC;AAMxC,cAAc,2CAA2C,CAAC;AAC1D,cAAc,gCAAgC,CAAC;AAE/C,cAAc,sCAAsC,CAAC;AACrD,cAAc,sCAAsC,CAAC;AACrD,cAAc,4BAA4B,CAAC;AAG3C,cAAc,0CAA0C,CAAC;AACzD,cAAc,kDAAkD,CAAC;AACjE,cAAc,sDAAsD,CAAC;AACrE,cAAc,qDAAqD,CAAC;AACpE,cAAc,oCAAoC,CAAC;AACnD,cAAc,4CAA4C,CAAC;AAC3D,cAAc,0CAA0C,CAAC;AACzD,cAAc,4CAA4C,CAAC;AAC3D,cAAc,8CAA8C,CAAC"}
|
|
@@ -25,4 +25,14 @@ tslib_1.__exportStar(require("./_services/msg-events.service"), exports);
|
|
|
25
25
|
tslib_1.__exportStar(require("./_services/msg-main.control-service"), exports);
|
|
26
26
|
tslib_1.__exportStar(require("./_services/msg-message.data-service"), exports);
|
|
27
27
|
tslib_1.__exportStar(require("./_services/msg.controller"), exports);
|
|
28
|
+
// INPUT DRAFT (BFR-CCAPREVISIONED-030 part 2)
|
|
29
|
+
tslib_1.__exportStar(require("./input-draft/msg-input-draft.data-model"), exports);
|
|
30
|
+
tslib_1.__exportStar(require("./input-draft/msg-input-draft-settings.interface"), exports);
|
|
31
|
+
tslib_1.__exportStar(require("./input-draft/msg-input-draft-default-settings.const"), exports);
|
|
32
|
+
tslib_1.__exportStar(require("./input-draft/msg-input-draft-save-result.interface"), exports);
|
|
33
|
+
tslib_1.__exportStar(require("./input-draft/msg-input-draft.util"), exports);
|
|
34
|
+
tslib_1.__exportStar(require("./input-draft/msg-input-draft.data-service"), exports);
|
|
35
|
+
tslib_1.__exportStar(require("./input-draft/msg-input-draft.controller"), exports);
|
|
36
|
+
tslib_1.__exportStar(require("./input-draft/msg-input-draft-routing.util"), exports);
|
|
37
|
+
tslib_1.__exportStar(require("./input-draft/msg-input-draft-call.interface"), exports);
|
|
28
38
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/_modules/messaging/index.ts"],"names":[],"mappings":";AAAA,EAAE;AACF,mBAAmB;AACnB,EAAE;AACF,mEAAmE;AACnE,4CAA4C;AAC5C,wCAAwC;AACxC,EAAE;;;AAEF,uBAAuB;AACvB,0EAAgD;AAEhD,SAAS;AACT,kFAAwD;AAExD,cAAc;AACd,2FAAiE;AACjE,mFAAyD;AACzD,kEAAwC;AAExC,QAAQ;AACR,2DAA2D;AAE3D,WAAW;AACX,oFAA0D;AAC1D,yEAA+C;AAC/C,kEAAkE;AAClE,+EAAqD;AACrD,+EAAqD;AACrD,qEAA2C"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/_modules/messaging/index.ts"],"names":[],"mappings":";AAAA,EAAE;AACF,mBAAmB;AACnB,EAAE;AACF,mEAAmE;AACnE,4CAA4C;AAC5C,wCAAwC;AACxC,EAAE;;;AAEF,uBAAuB;AACvB,0EAAgD;AAEhD,SAAS;AACT,kFAAwD;AAExD,cAAc;AACd,2FAAiE;AACjE,mFAAyD;AACzD,kEAAwC;AAExC,QAAQ;AACR,2DAA2D;AAE3D,WAAW;AACX,oFAA0D;AAC1D,yEAA+C;AAC/C,kEAAkE;AAClE,+EAAqD;AACrD,+EAAqD;AACrD,qEAA2C;AAE3C,8CAA8C;AAC9C,mFAAyD;AACzD,2FAAiE;AACjE,+FAAqE;AACrE,8FAAoE;AACpE,6EAAmD;AACnD,qFAA2D;AAC3D,mFAAyD;AACzD,qFAA2D;AAC3D,uFAA6D"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Request, Response } from 'express';
|
|
2
|
+
/**
|
|
3
|
+
* BFR-CCAPREVISIONED-030 part 2 - one endpoint call, as the input-draft handlers get it.
|
|
4
|
+
*/
|
|
5
|
+
export interface DyNTS_Msg_InputDraft_Call_Interface {
|
|
6
|
+
/** The incoming request. */
|
|
7
|
+
req: Request;
|
|
8
|
+
/** The answer. */
|
|
9
|
+
res: Response;
|
|
10
|
+
/** The issuer the endpoint resolved (for the logs; the OWNER comes from the auth service). */
|
|
11
|
+
issuer: string;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=msg-input-draft-call.interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"msg-input-draft-call.interface.d.ts","sourceRoot":"","sources":["../../../../src/_modules/messaging/input-draft/msg-input-draft-call.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAE5C;;GAEG;AACH,MAAM,WAAW,mCAAmC;IAClD,4BAA4B;IAC5B,GAAG,EAAE,OAAO,CAAC;IACb,kBAAkB;IAClB,GAAG,EAAE,QAAQ,CAAC;IACd,8FAA8F;IAC9F,MAAM,EAAE,MAAM,CAAC;CAChB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"msg-input-draft-call.interface.js","sourceRoot":"","sources":["../../../../src/_modules/messaging/input-draft/msg-input-draft-call.interface.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { DyNTS_Msg_InputDraft_Settings_Interface } from './msg-input-draft-settings.interface';
|
|
2
|
+
/**
|
|
3
|
+
* BFR-CCAPREVISIONED-030 part 2 - the input-draft defaults: a draft lives 30 days after its last save.
|
|
4
|
+
*/
|
|
5
|
+
export declare const DyNTS_msgInputDraft_defaultSettings: Required<DyNTS_Msg_InputDraft_Settings_Interface>;
|
|
6
|
+
//# sourceMappingURL=msg-input-draft-default-settings.const.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"msg-input-draft-default-settings.const.d.ts","sourceRoot":"","sources":["../../../../src/_modules/messaging/input-draft/msg-input-draft-default-settings.const.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,uCAAuC,EAAE,MAAM,sCAAsC,CAAC;AAE/F;;GAEG;AACH,eAAO,MAAM,mCAAmC,EAAE,QAAQ,CAAC,uCAAuC,CAOjG,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DyNTS_msgInputDraft_defaultSettings = void 0;
|
|
4
|
+
const fsm_dynamo_1 = require("@futdevpro/fsm-dynamo");
|
|
5
|
+
/**
|
|
6
|
+
* BFR-CCAPREVISIONED-030 part 2 - the input-draft defaults: a draft lives 30 days after its last save.
|
|
7
|
+
*/
|
|
8
|
+
exports.DyNTS_msgInputDraft_defaultSettings = {
|
|
9
|
+
route: '/input-draft',
|
|
10
|
+
preProcesses: [],
|
|
11
|
+
maxAgeMs: 30 * fsm_dynamo_1.day,
|
|
12
|
+
maxContentLength: 100000,
|
|
13
|
+
maxFieldKeyLength: 200,
|
|
14
|
+
maxListCount: 500,
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=msg-input-draft-default-settings.const.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"msg-input-draft-default-settings.const.js","sourceRoot":"","sources":["../../../../src/_modules/messaging/input-draft/msg-input-draft-default-settings.const.ts"],"names":[],"mappings":";;;AAAA,sDAA4C;AAI5C;;GAEG;AACU,QAAA,mCAAmC,GAAsD;IACpG,KAAK,EAAE,cAAc;IACrB,YAAY,EAAE,EAAE;IAChB,QAAQ,EAAE,EAAE,GAAG,gBAAG;IAClB,gBAAgB,EAAE,MAAM;IACxB,iBAAiB,EAAE,GAAG;IACtB,YAAY,EAAE,GAAG;CAClB,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { DyNTS_RoutingModule } from '../../../_services/route/routing-module.service';
|
|
2
|
+
import { DyNTS_Msg_InputDraft_Settings_Interface } from './msg-input-draft-settings.interface';
|
|
3
|
+
/**
|
|
4
|
+
* BFR-CCAPREVISIONED-030 part 2 - the input-draft routing module (`/input-draft/save | get | list | clear`): the
|
|
5
|
+
* unsent text of an input field, per account and field key, so it comes back in another browser too.
|
|
6
|
+
*
|
|
7
|
+
* Needs the app's auth service on `DyNTS_GlobalService` (the owner is the authenticated issuer) and the
|
|
8
|
+
* `DyNTS_msgInputDraft_dataParams` collection among the app's db models.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* DyNTS_Msg_InputDraftRouting_Util.getRoutingModule({
|
|
13
|
+
* preProcesses: [ authService.authenticate_tokenSelf ],
|
|
14
|
+
* maxAgeMs: 14 * day,
|
|
15
|
+
* })
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export declare class DyNTS_Msg_InputDraftRouting_Util {
|
|
19
|
+
/** The routing module with the given settings (the defaults for the missing ones). */
|
|
20
|
+
static getRoutingModule(settings?: DyNTS_Msg_InputDraft_Settings_Interface): DyNTS_RoutingModule;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=msg-input-draft-routing.util.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"msg-input-draft-routing.util.d.ts","sourceRoot":"","sources":["../../../../src/_modules/messaging/input-draft/msg-input-draft-routing.util.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,iDAAiD,CAAC;AAEtF,OAAO,EAAE,uCAAuC,EAAE,MAAM,sCAAsC,CAAC;AAG/F;;;;;;;;;;;;;;GAcG;AACH,qBAAa,gCAAgC;IAC3C,sFAAsF;IACtF,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,EAAE,uCAAuC,GAAG,mBAAmB;CAUjG"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DyNTS_Msg_InputDraftRouting_Util = void 0;
|
|
4
|
+
const routing_module_service_1 = require("../../../_services/route/routing-module.service");
|
|
5
|
+
const msg_input_draft_controller_1 = require("./msg-input-draft.controller");
|
|
6
|
+
const msg_input_draft_util_1 = require("./msg-input-draft.util");
|
|
7
|
+
/**
|
|
8
|
+
* BFR-CCAPREVISIONED-030 part 2 - the input-draft routing module (`/input-draft/save | get | list | clear`): the
|
|
9
|
+
* unsent text of an input field, per account and field key, so it comes back in another browser too.
|
|
10
|
+
*
|
|
11
|
+
* Needs the app's auth service on `DyNTS_GlobalService` (the owner is the authenticated issuer) and the
|
|
12
|
+
* `DyNTS_msgInputDraft_dataParams` collection among the app's db models.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* DyNTS_Msg_InputDraftRouting_Util.getRoutingModule({
|
|
17
|
+
* preProcesses: [ authService.authenticate_tokenSelf ],
|
|
18
|
+
* maxAgeMs: 14 * day,
|
|
19
|
+
* })
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
class DyNTS_Msg_InputDraftRouting_Util {
|
|
23
|
+
/** The routing module with the given settings (the defaults for the missing ones). */
|
|
24
|
+
static getRoutingModule(settings) {
|
|
25
|
+
msg_input_draft_controller_1.DyNTS_Msg_InputDraft_Controller.configure(settings);
|
|
26
|
+
const set = {
|
|
27
|
+
route: msg_input_draft_util_1.DyNTS_Msg_InputDraft_Util.resolve(settings).route,
|
|
28
|
+
controllers: [msg_input_draft_controller_1.DyNTS_Msg_InputDraft_Controller.getInstance()],
|
|
29
|
+
};
|
|
30
|
+
return new routing_module_service_1.DyNTS_RoutingModule(set);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
exports.DyNTS_Msg_InputDraftRouting_Util = DyNTS_Msg_InputDraftRouting_Util;
|
|
34
|
+
//# sourceMappingURL=msg-input-draft-routing.util.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"msg-input-draft-routing.util.js","sourceRoot":"","sources":["../../../../src/_modules/messaging/input-draft/msg-input-draft-routing.util.ts"],"names":[],"mappings":";;;AACA,4FAAsF;AACtF,6EAA+E;AAE/E,iEAAmE;AAEnE;;;;;;;;;;;;;;GAcG;AACH,MAAa,gCAAgC;IAC3C,sFAAsF;IACtF,MAAM,CAAC,gBAAgB,CAAC,QAAkD;QACxE,4DAA+B,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAEpD,MAAM,GAAG,GAAiC;YACxC,KAAK,EAAE,gDAAyB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,KAAK;YACxD,WAAW,EAAE,CAAE,4DAA+B,CAAC,WAAW,EAAE,CAAE;SAC/D,CAAC;QAEF,OAAO,IAAI,4CAAmB,CAAC,GAAG,CAAC,CAAC;IACtC,CAAC;CACF;AAZD,4EAYC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BFR-CCAPREVISIONED-030 part 2 - the answer of a draft save. A failed STORE answers `saved: false` with 200 (the save
|
|
3
|
+
* is best-effort: it must never stop the typing or the sending), and says why in `error`.
|
|
4
|
+
*/
|
|
5
|
+
export interface DyNTS_Msg_InputDraft_SaveResult_Interface {
|
|
6
|
+
/** Whether the server copy was written. */
|
|
7
|
+
saved: boolean;
|
|
8
|
+
/** The stored revision (when saved). */
|
|
9
|
+
revision?: number;
|
|
10
|
+
/** The stored save time (when saved). */
|
|
11
|
+
savedAt?: Date;
|
|
12
|
+
/** Why it was not saved (the user-facing text, no technical detail). */
|
|
13
|
+
error?: string;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=msg-input-draft-save-result.interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"msg-input-draft-save-result.interface.d.ts","sourceRoot":"","sources":["../../../../src/_modules/messaging/input-draft/msg-input-draft-save-result.interface.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,yCAAyC;IACxD,2CAA2C;IAC3C,KAAK,EAAE,OAAO,CAAC;IACf,wCAAwC;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,OAAO,CAAC,EAAE,IAAI,CAAC;IACf,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"msg-input-draft-save-result.interface.js","sourceRoot":"","sources":["../../../../src/_modules/messaging/input-draft/msg-input-draft-save-result.interface.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Request, Response } from 'express';
|
|
2
|
+
/**
|
|
3
|
+
* BFR-CCAPREVISIONED-030 part 2 - the input-draft endpoints' settings (every field optional, the defaults are
|
|
4
|
+
* `DyNTS_msgInputDraft_defaultSettings`).
|
|
5
|
+
*/
|
|
6
|
+
export interface DyNTS_Msg_InputDraft_Settings_Interface {
|
|
7
|
+
/** The routing module's route (default `/input-draft`). */
|
|
8
|
+
route?: string;
|
|
9
|
+
/** Run before every endpoint (e.g. the app's token check); the owner is then the authenticated issuer. */
|
|
10
|
+
preProcesses?: ((req: Request, res: Response) => Promise<void>)[];
|
|
11
|
+
/** A draft older than this is not given back any more (default 30 days); the next save reuses its record. */
|
|
12
|
+
maxAgeMs?: number;
|
|
13
|
+
/** The longest accepted text (default 100 000 characters); a longer one is refused with 400, not cut. */
|
|
14
|
+
maxContentLength?: number;
|
|
15
|
+
/** The longest accepted field key (default 200 characters). */
|
|
16
|
+
maxFieldKeyLength?: number;
|
|
17
|
+
/** How many drafts the list gives back at most, newest first (default 500). */
|
|
18
|
+
maxListCount?: number;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=msg-input-draft-settings.interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"msg-input-draft-settings.interface.d.ts","sourceRoot":"","sources":["../../../../src/_modules/messaging/input-draft/msg-input-draft-settings.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAE5C;;;GAGG;AACH,MAAM,WAAW,uCAAuC;IACtD,2DAA2D;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0GAA0G;IAC1G,YAAY,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;IAClE,6GAA6G;IAC7G,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yGAAyG;IACzG,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,+DAA+D;IAC/D,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,+EAA+E;IAC/E,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"msg-input-draft-settings.interface.js","sourceRoot":"","sources":["../../../../src/_modules/messaging/input-draft/msg-input-draft-settings.interface.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { DyNTS_Controller } from '../../../_services/route/controller.service';
|
|
2
|
+
import { DyNTS_Msg_InputDraft_Settings_Interface } from './msg-input-draft-settings.interface';
|
|
3
|
+
/**
|
|
4
|
+
* BFR-CCAPREVISIONED-030 part 2 - the input-draft endpoints (mounted by `DyNTS_Msg_InputDraftRouting_Util`):
|
|
5
|
+
*
|
|
6
|
+
* | method | path | body / query | answer |
|
|
7
|
+
* |---|---|---|---|
|
|
8
|
+
* | PUT | `/save` | `{ fieldKey, content, savedByBrowserId? }` | `{ saved, revision?, savedAt?, error? }` |
|
|
9
|
+
* | GET | `/get` | `?fieldKey=` | `{ draft }` (`null` when none / expired) |
|
|
10
|
+
* | GET | `/list` | - | `{ drafts, count }` (newest first) |
|
|
11
|
+
* | DELETE | `/clear` | `?fieldKey=` | `{ cleared }` |
|
|
12
|
+
*
|
|
13
|
+
* - the owner is ALWAYS the authenticated issuer (`requireIssuerFromRequest`: none ⇒ 401), never a request field, so
|
|
14
|
+
* one account cannot read or overwrite another's drafts;
|
|
15
|
+
* - a failed store answers `saved: false` with 200 (best-effort, it must not stop the typing), a wrong request 400.
|
|
16
|
+
*/
|
|
17
|
+
export declare class DyNTS_Msg_InputDraft_Controller extends DyNTS_Controller {
|
|
18
|
+
/** The settings given to the routing module. */
|
|
19
|
+
private static settings;
|
|
20
|
+
/** Sets the endpoints' settings (before the routing module is built: it builds the endpoints). */
|
|
21
|
+
static configure(settings?: DyNTS_Msg_InputDraft_Settings_Interface): void;
|
|
22
|
+
/** The controller singleton. */
|
|
23
|
+
static getInstance(): DyNTS_Msg_InputDraft_Controller;
|
|
24
|
+
/** Builds the four endpoints. */
|
|
25
|
+
setupEndpoints(): void;
|
|
26
|
+
/** One endpoint behind the configured pre-processes, its task calling the handler on this controller. */
|
|
27
|
+
private endpoint;
|
|
28
|
+
/** PUT /save - stores the draft; a store failure is answered (200, `saved: false`), not thrown. */
|
|
29
|
+
private save;
|
|
30
|
+
/** GET /get - the field's draft (`null` when none or expired). */
|
|
31
|
+
private load;
|
|
32
|
+
/** GET /list - the owner's drafts, newest first. */
|
|
33
|
+
private list;
|
|
34
|
+
/** DELETE /clear - removes the field's draft after a send. */
|
|
35
|
+
private clear;
|
|
36
|
+
/**
|
|
37
|
+
* The authenticated account (none ⇒ 401, thrown). ⚠️ No fallback to the shipped default auth service: that one trusts
|
|
38
|
+
* an `x-user-id` header, so any caller could read anyone's drafts. Without the app's auth service ⇒ 503.
|
|
39
|
+
*/
|
|
40
|
+
private owner;
|
|
41
|
+
/** A data service for this request. */
|
|
42
|
+
private dataService;
|
|
43
|
+
/** A body / query as a plain record (anything else ⇒ empty). */
|
|
44
|
+
private record;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=msg-input-draft.controller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"msg-input-draft.controller.d.ts","sourceRoot":"","sources":["../../../../src/_modules/messaging/input-draft/msg-input-draft.controller.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,gBAAgB,EAAE,MAAM,6CAA6C,CAAC;AAK/E,OAAO,EAAE,uCAAuC,EAAE,MAAM,sCAAsC,CAAC;AAG/F;;;;;;;;;;;;;GAaG;AACH,qBAAa,+BAAgC,SAAQ,gBAAgB;IACnE,gDAAgD;IAChD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA0F;IAEjH,kGAAkG;IAClG,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,uCAAuC,GAAG,IAAI;IAI1E,gCAAgC;IAChC,MAAM,CAAC,WAAW,IAAI,+BAA+B;IAIrD,iCAAiC;IACjC,cAAc,IAAI,IAAI;IAStB,yGAAyG;IACzG,OAAO,CAAC,QAAQ;IAkBhB,mGAAmG;YACrF,IAAI;IAwBlB,kEAAkE;YACpD,IAAI;IASlB,oDAAoD;YACtC,IAAI;IAOlB,8DAA8D;YAChD,KAAK;IASnB;;;OAGG;IACH,OAAO,CAAC,KAAK;IAyBb,uCAAuC;IACvC,OAAO,CAAC,WAAW;IAInB,gEAAgE;IAChE,OAAO,CAAC,MAAM;CAWf"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DyNTS_Msg_InputDraft_Controller = void 0;
|
|
4
|
+
const fsm_dynamo_1 = require("@futdevpro/fsm-dynamo");
|
|
5
|
+
const global_settings_const_1 = require("../../../_collections/global-settings.const");
|
|
6
|
+
const endpoint_params_control_model_1 = require("../../../_models/control-models/endpoint-params.control-model");
|
|
7
|
+
const global_service_1 = require("../../../_services/core/global.service");
|
|
8
|
+
const controller_service_1 = require("../../../_services/route/controller.service");
|
|
9
|
+
const msg_input_draft_data_service_1 = require("./msg-input-draft.data-service");
|
|
10
|
+
const msg_input_draft_util_1 = require("./msg-input-draft.util");
|
|
11
|
+
/**
|
|
12
|
+
* BFR-CCAPREVISIONED-030 part 2 - the input-draft endpoints (mounted by `DyNTS_Msg_InputDraftRouting_Util`):
|
|
13
|
+
*
|
|
14
|
+
* | method | path | body / query | answer |
|
|
15
|
+
* |---|---|---|---|
|
|
16
|
+
* | PUT | `/save` | `{ fieldKey, content, savedByBrowserId? }` | `{ saved, revision?, savedAt?, error? }` |
|
|
17
|
+
* | GET | `/get` | `?fieldKey=` | `{ draft }` (`null` when none / expired) |
|
|
18
|
+
* | GET | `/list` | - | `{ drafts, count }` (newest first) |
|
|
19
|
+
* | DELETE | `/clear` | `?fieldKey=` | `{ cleared }` |
|
|
20
|
+
*
|
|
21
|
+
* - the owner is ALWAYS the authenticated issuer (`requireIssuerFromRequest`: none ⇒ 401), never a request field, so
|
|
22
|
+
* one account cannot read or overwrite another's drafts;
|
|
23
|
+
* - a failed store answers `saved: false` with 200 (best-effort, it must not stop the typing), a wrong request 400.
|
|
24
|
+
*/
|
|
25
|
+
class DyNTS_Msg_InputDraft_Controller extends controller_service_1.DyNTS_Controller {
|
|
26
|
+
/** The settings given to the routing module. */
|
|
27
|
+
static settings = msg_input_draft_util_1.DyNTS_Msg_InputDraft_Util.resolve();
|
|
28
|
+
/** Sets the endpoints' settings (before the routing module is built: it builds the endpoints). */
|
|
29
|
+
static configure(settings) {
|
|
30
|
+
DyNTS_Msg_InputDraft_Controller.settings = msg_input_draft_util_1.DyNTS_Msg_InputDraft_Util.resolve(settings);
|
|
31
|
+
}
|
|
32
|
+
/** The controller singleton. */
|
|
33
|
+
static getInstance() {
|
|
34
|
+
return DyNTS_Msg_InputDraft_Controller.getSingletonInstance();
|
|
35
|
+
}
|
|
36
|
+
/** Builds the four endpoints. */
|
|
37
|
+
setupEndpoints() {
|
|
38
|
+
this.endpoints = [
|
|
39
|
+
this.endpoint({ name: 'saveInputDraft', type: fsm_dynamo_1.DyFM_HttpCallType.put, path: '/save', handler: this.save }),
|
|
40
|
+
this.endpoint({ name: 'getInputDraft', type: fsm_dynamo_1.DyFM_HttpCallType.get, path: '/get', handler: this.load }),
|
|
41
|
+
this.endpoint({ name: 'listInputDrafts', type: fsm_dynamo_1.DyFM_HttpCallType.get, path: '/list', handler: this.list }),
|
|
42
|
+
this.endpoint({ name: 'clearInputDraft', type: fsm_dynamo_1.DyFM_HttpCallType.delete, path: '/clear', handler: this.clear }),
|
|
43
|
+
];
|
|
44
|
+
}
|
|
45
|
+
/** One endpoint behind the configured pre-processes, its task calling the handler on this controller. */
|
|
46
|
+
endpoint(set) {
|
|
47
|
+
return new endpoint_params_control_model_1.DyNTS_Endpoint_Params({
|
|
48
|
+
name: set.name,
|
|
49
|
+
type: set.type,
|
|
50
|
+
endpoint: set.path,
|
|
51
|
+
preProcesses: DyNTS_Msg_InputDraft_Controller.settings.preProcesses,
|
|
52
|
+
tasks: [
|
|
53
|
+
(req, res, issuer) => set.handler.call(this, { req: req, res: res, issuer: issuer }),
|
|
54
|
+
],
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
/** PUT /save - stores the draft; a store failure is answered (200, `saved: false`), not thrown. */
|
|
58
|
+
async save(call) {
|
|
59
|
+
const settings = DyNTS_Msg_InputDraft_Controller.settings;
|
|
60
|
+
const ownerId = this.owner(call.req);
|
|
61
|
+
const body = this.record(call.req.body);
|
|
62
|
+
const fieldKey = msg_input_draft_util_1.DyNTS_Msg_InputDraft_Util.fieldKey(body.fieldKey, settings);
|
|
63
|
+
const content = msg_input_draft_util_1.DyNTS_Msg_InputDraft_Util.content(body.content, settings);
|
|
64
|
+
let result;
|
|
65
|
+
try {
|
|
66
|
+
const saved = await this.dataService(call.issuer).save({
|
|
67
|
+
ownerId: ownerId,
|
|
68
|
+
fieldKey: fieldKey,
|
|
69
|
+
content: content,
|
|
70
|
+
savedByBrowserId: msg_input_draft_util_1.DyNTS_Msg_InputDraft_Util.optionalId(body.savedByBrowserId),
|
|
71
|
+
});
|
|
72
|
+
result = { saved: true, revision: saved.revision, savedAt: saved.savedAt };
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
fsm_dynamo_1.DyFM_Log.warn(`[DyNTS_Msg_InputDraft] save failed (answered with saved: false): '${fieldKey}'`, error);
|
|
76
|
+
result = { saved: false, error: fsm_dynamo_1.DyFM_Error.getUserMessage(error) || 'The draft could not be saved.' };
|
|
77
|
+
}
|
|
78
|
+
call.res.send(result);
|
|
79
|
+
}
|
|
80
|
+
/** GET /get - the field's draft (`null` when none or expired). */
|
|
81
|
+
async load(call) {
|
|
82
|
+
const ownerId = this.owner(call.req);
|
|
83
|
+
const fieldKey = msg_input_draft_util_1.DyNTS_Msg_InputDraft_Util.fieldKey(this.record(call.req.query).fieldKey, DyNTS_Msg_InputDraft_Controller.settings);
|
|
84
|
+
call.res.send({ draft: await this.dataService(call.issuer).load({ ownerId: ownerId, fieldKey: fieldKey }) });
|
|
85
|
+
}
|
|
86
|
+
/** GET /list - the owner's drafts, newest first. */
|
|
87
|
+
async list(call) {
|
|
88
|
+
const drafts = await this.dataService(call.issuer).list({ ownerId: this.owner(call.req) });
|
|
89
|
+
call.res.send({ drafts: drafts, count: drafts.length });
|
|
90
|
+
}
|
|
91
|
+
/** DELETE /clear - removes the field's draft after a send. */
|
|
92
|
+
async clear(call) {
|
|
93
|
+
const ownerId = this.owner(call.req);
|
|
94
|
+
const fieldKey = msg_input_draft_util_1.DyNTS_Msg_InputDraft_Util.fieldKey(this.record(call.req.query).fieldKey, DyNTS_Msg_InputDraft_Controller.settings);
|
|
95
|
+
call.res.send({ cleared: await this.dataService(call.issuer).clear({ ownerId: ownerId, fieldKey: fieldKey }) });
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* The authenticated account (none ⇒ 401, thrown). ⚠️ No fallback to the shipped default auth service: that one trusts
|
|
99
|
+
* an `x-user-id` header, so any caller could read anyone's drafts. Without the app's auth service ⇒ 503.
|
|
100
|
+
*/
|
|
101
|
+
owner(req) {
|
|
102
|
+
let auth;
|
|
103
|
+
let cause;
|
|
104
|
+
try {
|
|
105
|
+
// an app marked auth-optional gets `undefined` here instead of a throw: both mean "no owner can be known"
|
|
106
|
+
auth = global_service_1.DyNTS_GlobalService.getAuthService();
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
cause = error;
|
|
110
|
+
}
|
|
111
|
+
if (!auth) {
|
|
112
|
+
throw new fsm_dynamo_1.DyFM_Error({
|
|
113
|
+
status: 503,
|
|
114
|
+
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-MSG-ID-AU0`,
|
|
115
|
+
message: 'The input drafts need an auth service on DyNTS_GlobalService; none is set.',
|
|
116
|
+
userMessage: 'The drafts are not available on this server.',
|
|
117
|
+
issuerService: 'DyNTS_Msg_InputDraft_Controller',
|
|
118
|
+
error: cause ?? new Error('no auth service'),
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
return auth.requireIssuerFromRequest(req);
|
|
122
|
+
}
|
|
123
|
+
/** A data service for this request. */
|
|
124
|
+
dataService(issuer) {
|
|
125
|
+
return new msg_input_draft_data_service_1.DyNTS_Msg_InputDraft_DataService({ issuer: issuer, settings: DyNTS_Msg_InputDraft_Controller.settings });
|
|
126
|
+
}
|
|
127
|
+
/** A body / query as a plain record (anything else ⇒ empty). */
|
|
128
|
+
record(value) {
|
|
129
|
+
const result = {};
|
|
130
|
+
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
131
|
+
Object.entries(value).forEach(([key, item]) => {
|
|
132
|
+
result[key] = item;
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
return result;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
exports.DyNTS_Msg_InputDraft_Controller = DyNTS_Msg_InputDraft_Controller;
|
|
139
|
+
//# sourceMappingURL=msg-input-draft.controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"msg-input-draft.controller.js","sourceRoot":"","sources":["../../../../src/_modules/messaging/input-draft/msg-input-draft.controller.ts"],"names":[],"mappings":";;;AAEA,sDAAgF;AAEhF,uFAAoF;AACpF,iHAAsG;AAEtG,2EAA6E;AAC7E,oFAA+E;AAG/E,iFAAkF;AAGlF,iEAAmE;AAEnE;;;;;;;;;;;;;GAaG;AACH,MAAa,+BAAgC,SAAQ,qCAAgB;IACnE,gDAAgD;IACxC,MAAM,CAAC,QAAQ,GAAsD,gDAAyB,CAAC,OAAO,EAAE,CAAC;IAEjH,kGAAkG;IAClG,MAAM,CAAC,SAAS,CAAC,QAAkD;QACjE,+BAA+B,CAAC,QAAQ,GAAG,gDAAyB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACzF,CAAC;IAED,gCAAgC;IAChC,MAAM,CAAC,WAAW;QAChB,OAAO,+BAA+B,CAAC,oBAAoB,EAAE,CAAC;IAChE,CAAC;IAED,iCAAiC;IACjC,cAAc;QACZ,IAAI,CAAC,SAAS,GAAG;YACf,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,8BAAiB,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;YACzG,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,8BAAiB,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;YACvG,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,8BAAiB,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;YAC1G,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,8BAAiB,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;SAChH,CAAC;IACJ,CAAC;IAED,yGAAyG;IACjG,QAAQ,CAAC,GAKhB;QACC,OAAO,IAAI,qDAAqB,CAAC;YAC/B,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,QAAQ,EAAE,GAAG,CAAC,IAAI;YAClB,YAAY,EAAE,+BAA+B,CAAC,QAAQ,CAAC,YAAY;YACnE,KAAK,EAAE;gBACL,CAAC,GAAY,EAAE,GAAa,EAAE,MAAc,EAAiB,EAAE,CAC7D,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;aACjE;SACF,CAAC,CAAC;IACL,CAAC;IAED,mGAAmG;IAC3F,KAAK,CAAC,IAAI,CAAC,IAAyC;QAC1D,MAAM,QAAQ,GAAsD,+BAA+B,CAAC,QAAQ,CAAC;QAC7G,MAAM,OAAO,GAAW,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7C,MAAM,IAAI,GAA4B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACjE,MAAM,QAAQ,GAAW,gDAAyB,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACrF,MAAM,OAAO,GAAW,gDAAyB,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAClF,IAAI,MAAiD,CAAC;QAEtD,IAAI,CAAC;YACH,MAAM,KAAK,GAAmC,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC;gBACrF,OAAO,EAAE,OAAO;gBAChB,QAAQ,EAAE,QAAQ;gBAClB,OAAO,EAAE,OAAO;gBAChB,gBAAgB,EAAE,gDAAyB,CAAC,UAAU,CAAC,IAAI,CAAC,gBAAgB,CAAC;aAC9E,CAAC,CAAC;YAEH,MAAM,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;QAC7E,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,qBAAQ,CAAC,IAAI,CAAC,qEAAqE,QAAQ,GAAG,EAAE,KAAK,CAAC,CAAC;YACvG,MAAM,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,uBAAU,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,+BAA+B,EAAE,CAAC;QACxG,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACxB,CAAC;IAED,kEAAkE;IAC1D,KAAK,CAAC,IAAI,CAAC,IAAyC;QAC1D,MAAM,OAAO,GAAW,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7C,MAAM,QAAQ,GAAW,gDAAyB,CAAC,QAAQ,CACzD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,+BAA+B,CAAC,QAAQ,CAC/E,CAAC;QAEF,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;IAC/G,CAAC;IAED,oDAAoD;IAC5C,KAAK,CAAC,IAAI,CAAC,IAAyC;QAC1D,MAAM,MAAM,GACV,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAE9E,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED,8DAA8D;IACtD,KAAK,CAAC,KAAK,CAAC,IAAyC;QAC3D,MAAM,OAAO,GAAW,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7C,MAAM,QAAQ,GAAW,gDAAyB,CAAC,QAAQ,CACzD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,+BAA+B,CAAC,QAAQ,CAC/E,CAAC;QAEF,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;IAClH,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,GAAY;QACxB,IAAI,IAAmC,CAAC;QACxC,IAAI,KAAc,CAAC;QAEnB,IAAI,CAAC;YACH,0GAA0G;YAC1G,IAAI,GAAG,oCAAmB,CAAC,cAAc,EAAE,CAAC;QAC9C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,KAAK,GAAG,KAAK,CAAC;QAChB,CAAC;QAED,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,uBAAU,CAAC;gBACnB,MAAM,EAAE,GAAG;gBACX,SAAS,EAAE,GAAG,6CAAqB,CAAC,mBAAmB,mBAAmB;gBAC1E,OAAO,EAAE,4EAA4E;gBACrF,WAAW,EAAE,8CAA8C;gBAC3D,aAAa,EAAE,iCAAiC;gBAChD,KAAK,EAAE,KAAK,IAAI,IAAI,KAAK,CAAC,iBAAiB,CAAC;aAC7C,CAAC,CAAC;QACL,CAAC;QAED,OAAO,IAAI,CAAC,wBAAwB,CAAC,GAAG,CAAC,CAAC;IAC5C,CAAC;IAED,uCAAuC;IAC/B,WAAW,CAAC,MAAc;QAChC,OAAO,IAAI,+DAAgC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,+BAA+B,CAAC,QAAQ,EAAE,CAAC,CAAC;IACtH,CAAC;IAED,gEAAgE;IACxD,MAAM,CAAC,KAAc;QAC3B,MAAM,MAAM,GAA4B,EAAE,CAAC;QAE3C,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAChE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAE,GAAG,EAAE,IAAI,CAAuB,EAAQ,EAAE;gBACzE,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;YACrB,CAAC,CAAC,CAAC;QACL,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;;AA7IH,0EA8IC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { DyFM_DataModel_Params, DyFM_Metadata } from '@futdevpro/fsm-dynamo';
|
|
2
|
+
/**
|
|
3
|
+
* BFR-CCAPREVISIONED-030 part 2 (the CCAP's `MSG_InputDraft_*`, generalized) - the SERVER copy of an unsent input text,
|
|
4
|
+
* so a half-written message comes back in another browser or on another device too.
|
|
5
|
+
*
|
|
6
|
+
* - ONE record per (owner, field key): an upsert overwrites it (the collection grows with the fields, not the typing);
|
|
7
|
+
* - the owner is the authenticated account (the issuer), never a request field;
|
|
8
|
+
* - the field key is the app's own (e.g. `chat:<conversationId>`, `reply:<ticketId>`);
|
|
9
|
+
* - `content` is the user's own raw text: it is stored as it came, never trimmed or reformatted;
|
|
10
|
+
* - an EMPTY save over a non-empty text keeps that text in `lastWipedContent` (a wiped draft is not lost for good).
|
|
11
|
+
*/
|
|
12
|
+
export declare class DyNTS_Msg_InputDraft_DataModel extends DyFM_Metadata {
|
|
13
|
+
/** The account the draft belongs to (the authenticated issuer). */
|
|
14
|
+
ownerId: string;
|
|
15
|
+
/** The app's key of the input field (one draft per owner and key). */
|
|
16
|
+
fieldKey: string;
|
|
17
|
+
/** The unsent text, exactly as the user typed it (an empty string is a valid value). */
|
|
18
|
+
content: string;
|
|
19
|
+
/** When this version was saved (server time); the expiry and the "newest" order use it. */
|
|
20
|
+
savedAt: Date;
|
|
21
|
+
/** The save count on this field (from 1, grows by one on every save). */
|
|
22
|
+
revision: number;
|
|
23
|
+
/** Which browser saved it (the client's own id): "is the server copy my own unflushed tail?". */
|
|
24
|
+
savedByBrowserId?: string;
|
|
25
|
+
/** The non-empty text the last EMPTY save overwrote. */
|
|
26
|
+
lastWipedContent?: string;
|
|
27
|
+
/** The `savedAt` of the overwritten version. */
|
|
28
|
+
lastWipedAt?: Date;
|
|
29
|
+
/** The revision of the overwritten version. */
|
|
30
|
+
lastWipedRevision?: number;
|
|
31
|
+
/** A draft from the given fields. */
|
|
32
|
+
constructor(set?: Partial<DyNTS_Msg_InputDraft_DataModel>);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The `dynts_msg_input_draft` collection: the lookup is always (ownerId, fieldKey), both indexed; the text is not.
|
|
36
|
+
*/
|
|
37
|
+
export declare const DyNTS_msgInputDraft_dataParams: DyFM_DataModel_Params<DyNTS_Msg_InputDraft_DataModel>;
|
|
38
|
+
//# sourceMappingURL=msg-input-draft.data-model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"msg-input-draft.data-model.d.ts","sourceRoot":"","sources":["../../../../src/_modules/messaging/input-draft/msg-input-draft.data-model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAe,MAAM,uBAAuB,CAAC;AAE1F;;;;;;;;;GASG;AACH,qBAAa,8BAA+B,SAAQ,aAAa;IAC/D,mEAAmE;IACnE,OAAO,EAAE,MAAM,CAAM;IACrB,sEAAsE;IACtE,QAAQ,EAAE,MAAM,CAAM;IACtB,wFAAwF;IACxF,OAAO,EAAE,MAAM,CAAM;IACrB,2FAA2F;IAC3F,OAAO,EAAE,IAAI,CAAe;IAC5B,yEAAyE;IACzE,QAAQ,EAAE,MAAM,CAAK;IACrB,iGAAiG;IACjG,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,wDAAwD;IACxD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gDAAgD;IAChD,WAAW,CAAC,EAAE,IAAI,CAAC;IACnB,+CAA+C;IAC/C,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B,qCAAqC;gBACzB,GAAG,CAAC,EAAE,OAAO,CAAC,8BAA8B,CAAC;CAO1D;AAED;;GAEG;AACH,eAAO,MAAM,8BAA8B,EAAE,qBAAqB,CAAC,8BAA8B,CAc7F,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DyNTS_msgInputDraft_dataParams = exports.DyNTS_Msg_InputDraft_DataModel = void 0;
|
|
4
|
+
const fsm_dynamo_1 = require("@futdevpro/fsm-dynamo");
|
|
5
|
+
/**
|
|
6
|
+
* BFR-CCAPREVISIONED-030 part 2 (the CCAP's `MSG_InputDraft_*`, generalized) - the SERVER copy of an unsent input text,
|
|
7
|
+
* so a half-written message comes back in another browser or on another device too.
|
|
8
|
+
*
|
|
9
|
+
* - ONE record per (owner, field key): an upsert overwrites it (the collection grows with the fields, not the typing);
|
|
10
|
+
* - the owner is the authenticated account (the issuer), never a request field;
|
|
11
|
+
* - the field key is the app's own (e.g. `chat:<conversationId>`, `reply:<ticketId>`);
|
|
12
|
+
* - `content` is the user's own raw text: it is stored as it came, never trimmed or reformatted;
|
|
13
|
+
* - an EMPTY save over a non-empty text keeps that text in `lastWipedContent` (a wiped draft is not lost for good).
|
|
14
|
+
*/
|
|
15
|
+
class DyNTS_Msg_InputDraft_DataModel extends fsm_dynamo_1.DyFM_Metadata {
|
|
16
|
+
/** The account the draft belongs to (the authenticated issuer). */
|
|
17
|
+
ownerId = '';
|
|
18
|
+
/** The app's key of the input field (one draft per owner and key). */
|
|
19
|
+
fieldKey = '';
|
|
20
|
+
/** The unsent text, exactly as the user typed it (an empty string is a valid value). */
|
|
21
|
+
content = '';
|
|
22
|
+
/** When this version was saved (server time); the expiry and the "newest" order use it. */
|
|
23
|
+
savedAt = new Date(0);
|
|
24
|
+
/** The save count on this field (from 1, grows by one on every save). */
|
|
25
|
+
revision = 0;
|
|
26
|
+
/** Which browser saved it (the client's own id): "is the server copy my own unflushed tail?". */
|
|
27
|
+
savedByBrowserId;
|
|
28
|
+
/** The non-empty text the last EMPTY save overwrote. */
|
|
29
|
+
lastWipedContent;
|
|
30
|
+
/** The `savedAt` of the overwritten version. */
|
|
31
|
+
lastWipedAt;
|
|
32
|
+
/** The revision of the overwritten version. */
|
|
33
|
+
lastWipedRevision;
|
|
34
|
+
/** A draft from the given fields. */
|
|
35
|
+
constructor(set) {
|
|
36
|
+
super(set);
|
|
37
|
+
if (set) {
|
|
38
|
+
fsm_dynamo_1.DyFM_Object.cleanAssign(this, set);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
exports.DyNTS_Msg_InputDraft_DataModel = DyNTS_Msg_InputDraft_DataModel;
|
|
43
|
+
/**
|
|
44
|
+
* The `dynts_msg_input_draft` collection: the lookup is always (ownerId, fieldKey), both indexed; the text is not.
|
|
45
|
+
*/
|
|
46
|
+
exports.DyNTS_msgInputDraft_dataParams = new fsm_dynamo_1.DyFM_DataModel_Params({
|
|
47
|
+
dataName: 'dynts_msg_input_draft',
|
|
48
|
+
properties: {
|
|
49
|
+
ownerId: { type: 'string', required: true, index: true },
|
|
50
|
+
fieldKey: { type: 'string', required: true, index: true },
|
|
51
|
+
content: { type: 'string' },
|
|
52
|
+
savedAt: { type: 'date', required: true },
|
|
53
|
+
revision: { type: 'number', required: true },
|
|
54
|
+
savedByBrowserId: { type: 'string' },
|
|
55
|
+
lastWipedContent: { type: 'string' },
|
|
56
|
+
lastWipedAt: { type: 'date' },
|
|
57
|
+
lastWipedRevision: { type: 'number' },
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
//# sourceMappingURL=msg-input-draft.data-model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"msg-input-draft.data-model.js","sourceRoot":"","sources":["../../../../src/_modules/messaging/input-draft/msg-input-draft.data-model.ts"],"names":[],"mappings":";;;AAAA,sDAA0F;AAE1F;;;;;;;;;GASG;AACH,MAAa,8BAA+B,SAAQ,0BAAa;IAC/D,mEAAmE;IACnE,OAAO,GAAW,EAAE,CAAC;IACrB,sEAAsE;IACtE,QAAQ,GAAW,EAAE,CAAC;IACtB,wFAAwF;IACxF,OAAO,GAAW,EAAE,CAAC;IACrB,2FAA2F;IAC3F,OAAO,GAAS,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;IAC5B,yEAAyE;IACzE,QAAQ,GAAW,CAAC,CAAC;IACrB,iGAAiG;IACjG,gBAAgB,CAAU;IAC1B,wDAAwD;IACxD,gBAAgB,CAAU;IAC1B,gDAAgD;IAChD,WAAW,CAAQ;IACnB,+CAA+C;IAC/C,iBAAiB,CAAU;IAE3B,qCAAqC;IACrC,YAAY,GAA6C;QACvD,KAAK,CAAC,GAAG,CAAC,CAAC;QAEX,IAAI,GAAG,EAAE,CAAC;YACR,wBAAW,CAAC,WAAW,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;CACF;AA5BD,wEA4BC;AAED;;GAEG;AACU,QAAA,8BAA8B,GACzC,IAAI,kCAAqB,CAAiC;IACxD,QAAQ,EAAE,uBAAuB;IACjC,UAAU,EAAE;QACV,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE;QACxD,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE;QACzD,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAC3B,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE;QACzC,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;QAC5C,gBAAgB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QACpC,gBAAgB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QACpC,WAAW,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE;QAC7B,iBAAiB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;KACtC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { DyNTS_DataService } from '../../../_services/base/data.service';
|
|
2
|
+
import { DyNTS_Msg_InputDraft_DataModel } from './msg-input-draft.data-model';
|
|
3
|
+
import { DyNTS_Msg_InputDraft_Settings_Interface } from './msg-input-draft-settings.interface';
|
|
4
|
+
/**
|
|
5
|
+
* BFR-CCAPREVISIONED-030 part 2 (the CCAP's `MSG_InputDraft_DataService`, generalized) - the server copy of the
|
|
6
|
+
* unsent input texts, per owner and field key.
|
|
7
|
+
*
|
|
8
|
+
* - `save`: an UPSERT (the revision grows by one); an empty save over a text keeps that text in `lastWipedContent`;
|
|
9
|
+
* - `load` / `list`: only the owner's live drafts, younger than `maxAgeMs`; these reads NEVER throw (a database error
|
|
10
|
+
* gives none: opening a page must not break on it, and it is logged);
|
|
11
|
+
* - `clear`: after a successful send (a soft delete: the text stays recoverable in the database).
|
|
12
|
+
*
|
|
13
|
+
* ⚠️ The save looks up the current record with a THROWING read: a swallowed read error would look like "no draft yet"
|
|
14
|
+
* and create a second record for the same field (revision 1 again).
|
|
15
|
+
*/
|
|
16
|
+
export declare class DyNTS_Msg_InputDraft_DataService extends DyNTS_DataService<DyNTS_Msg_InputDraft_DataModel> {
|
|
17
|
+
/** The resolved settings (expiry, list size). */
|
|
18
|
+
private readonly settings;
|
|
19
|
+
/** A service for one request (the issuer for the record metadata). */
|
|
20
|
+
constructor(set: {
|
|
21
|
+
issuer: string;
|
|
22
|
+
settings?: DyNTS_Msg_InputDraft_Settings_Interface;
|
|
23
|
+
});
|
|
24
|
+
/** Stores the field's draft (create or overwrite); a database error throws (the caller reports `saved: false`). */
|
|
25
|
+
save(set: {
|
|
26
|
+
ownerId: string;
|
|
27
|
+
fieldKey: string;
|
|
28
|
+
content: string;
|
|
29
|
+
savedByBrowserId?: string;
|
|
30
|
+
now?: Date;
|
|
31
|
+
}): Promise<DyNTS_Msg_InputDraft_DataModel>;
|
|
32
|
+
/** The field's live, not expired draft, or `null` (also on a database error, logged). */
|
|
33
|
+
load(set: {
|
|
34
|
+
ownerId: string;
|
|
35
|
+
fieldKey: string;
|
|
36
|
+
now?: Date;
|
|
37
|
+
}): Promise<DyNTS_Msg_InputDraft_DataModel | null>;
|
|
38
|
+
/** The owner's live, not expired drafts, newest first (at most `maxListCount`; `[]` on a database error, logged). */
|
|
39
|
+
list(set: {
|
|
40
|
+
ownerId: string;
|
|
41
|
+
now?: Date;
|
|
42
|
+
}): Promise<DyNTS_Msg_InputDraft_DataModel[]>;
|
|
43
|
+
/** Removes the field's draft after a send (soft delete); `false` when there was none (or on an error, logged). */
|
|
44
|
+
clear(set: {
|
|
45
|
+
ownerId: string;
|
|
46
|
+
fieldKey: string;
|
|
47
|
+
}): Promise<boolean>;
|
|
48
|
+
/** The field's live record, expired or not (THROWS on a database error). */
|
|
49
|
+
private findCurrent;
|
|
50
|
+
/** Whether the draft is older than `maxAgeMs`. */
|
|
51
|
+
private isExpired;
|
|
52
|
+
/** The oldest save time still given back. */
|
|
53
|
+
private cutoff;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=msg-input-draft.data-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"msg-input-draft.data-service.d.ts","sourceRoot":"","sources":["../../../../src/_modules/messaging/input-draft/msg-input-draft.data-service.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AACzE,OAAO,EAAE,8BAA8B,EAAkC,MAAM,8BAA8B,CAAC;AAC9G,OAAO,EAAE,uCAAuC,EAAE,MAAM,sCAAsC,CAAC;AAG/F;;;;;;;;;;;GAWG;AACH,qBAAa,gCAAiC,SAAQ,iBAAiB,CAAC,8BAA8B,CAAC;IACrG,iDAAiD;IACjD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoD;IAE7E,sEAAsE;gBAC1D,GAAG,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,uCAAuC,CAAA;KAAE;IAKvF,mHAAmH;IAC7G,IAAI,CAAC,GAAG,EAAE;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;QAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,GAAG,CAAC,EAAE,IAAI,CAAC;KACZ,GAAG,OAAO,CAAC,8BAA8B,CAAC;IAkC3C,yFAAyF;IACnF,IAAI,CAAC,GAAG,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,IAAI,CAAA;KAAE,GAAG,OAAO,CAAC,8BAA8B,GAAG,IAAI,CAAC;IAYlH,qHAAqH;IAC/G,IAAI,CAAC,GAAG,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,IAAI,CAAA;KAAE,GAAG,OAAO,CAAC,8BAA8B,EAAE,CAAC;IAmB3F,kHAAkH;IAC5G,KAAK,CAAC,GAAG,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAuBzE,4EAA4E;YAC9D,WAAW;IAUzB,kDAAkD;IAClD,OAAO,CAAC,SAAS;IAIjB,6CAA6C;IAC7C,OAAO,CAAC,MAAM;CAGf"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DyNTS_Msg_InputDraft_DataService = void 0;
|
|
4
|
+
const fsm_dynamo_1 = require("@futdevpro/fsm-dynamo");
|
|
5
|
+
const global_settings_const_1 = require("../../../_collections/global-settings.const");
|
|
6
|
+
const data_service_1 = require("../../../_services/base/data.service");
|
|
7
|
+
const msg_input_draft_data_model_1 = require("./msg-input-draft.data-model");
|
|
8
|
+
const msg_input_draft_util_1 = require("./msg-input-draft.util");
|
|
9
|
+
/**
|
|
10
|
+
* BFR-CCAPREVISIONED-030 part 2 (the CCAP's `MSG_InputDraft_DataService`, generalized) - the server copy of the
|
|
11
|
+
* unsent input texts, per owner and field key.
|
|
12
|
+
*
|
|
13
|
+
* - `save`: an UPSERT (the revision grows by one); an empty save over a text keeps that text in `lastWipedContent`;
|
|
14
|
+
* - `load` / `list`: only the owner's live drafts, younger than `maxAgeMs`; these reads NEVER throw (a database error
|
|
15
|
+
* gives none: opening a page must not break on it, and it is logged);
|
|
16
|
+
* - `clear`: after a successful send (a soft delete: the text stays recoverable in the database).
|
|
17
|
+
*
|
|
18
|
+
* ⚠️ The save looks up the current record with a THROWING read: a swallowed read error would look like "no draft yet"
|
|
19
|
+
* and create a second record for the same field (revision 1 again).
|
|
20
|
+
*/
|
|
21
|
+
class DyNTS_Msg_InputDraft_DataService extends data_service_1.DyNTS_DataService {
|
|
22
|
+
/** The resolved settings (expiry, list size). */
|
|
23
|
+
settings;
|
|
24
|
+
/** A service for one request (the issuer for the record metadata). */
|
|
25
|
+
constructor(set) {
|
|
26
|
+
super(new msg_input_draft_data_model_1.DyNTS_Msg_InputDraft_DataModel(), msg_input_draft_data_model_1.DyNTS_msgInputDraft_dataParams, set.issuer);
|
|
27
|
+
this.settings = msg_input_draft_util_1.DyNTS_Msg_InputDraft_Util.resolve(set.settings);
|
|
28
|
+
}
|
|
29
|
+
/** Stores the field's draft (create or overwrite); a database error throws (the caller reports `saved: false`). */
|
|
30
|
+
async save(set) {
|
|
31
|
+
try {
|
|
32
|
+
const existing = await this.findCurrent(set);
|
|
33
|
+
const draft = new msg_input_draft_data_model_1.DyNTS_Msg_InputDraft_DataModel(existing ?? {
|
|
34
|
+
ownerId: set.ownerId, fieldKey: set.fieldKey,
|
|
35
|
+
});
|
|
36
|
+
// an empty save over a text: the text is kept (the user's raw input is never lost by one wipe)
|
|
37
|
+
if (!set.content && existing?.content) {
|
|
38
|
+
draft.lastWipedContent = existing.content;
|
|
39
|
+
draft.lastWipedAt = existing.savedAt;
|
|
40
|
+
draft.lastWipedRevision = existing.revision;
|
|
41
|
+
}
|
|
42
|
+
draft.content = set.content;
|
|
43
|
+
draft.savedAt = set.now ?? new Date();
|
|
44
|
+
draft.revision = (existing?.revision ?? 0) + 1;
|
|
45
|
+
draft.savedByBrowserId = set.savedByBrowserId;
|
|
46
|
+
this.data = existing
|
|
47
|
+
? await this.dataDBService.modifyData(draft, this.issuer)
|
|
48
|
+
: await this.dataDBService.createData(draft, this.issuer);
|
|
49
|
+
return new msg_input_draft_data_model_1.DyNTS_Msg_InputDraft_DataModel(this.data);
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
throw new fsm_dynamo_1.DyFM_Error({
|
|
53
|
+
...this.getDefaultErrorSettings('save', error),
|
|
54
|
+
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-MSG-ID-S0`,
|
|
55
|
+
message: 'The input draft could not be stored.',
|
|
56
|
+
userMessage: 'The draft could not be saved on the server.',
|
|
57
|
+
additionalContent: { fieldKey: set.fieldKey, contentLength: set.content.length },
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/** The field's live, not expired draft, or `null` (also on a database error, logged). */
|
|
62
|
+
async load(set) {
|
|
63
|
+
try {
|
|
64
|
+
const current = await this.findCurrent(set);
|
|
65
|
+
return current && !this.isExpired({ draft: current, now: set.now }) ? current : null;
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
fsm_dynamo_1.DyFM_Log.warn(`[DyNTS_Msg_InputDraft] load failed (no draft given): '${set.fieldKey}'`, error);
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/** The owner's live, not expired drafts, newest first (at most `maxListCount`; `[]` on a database error, logged). */
|
|
73
|
+
async list(set) {
|
|
74
|
+
try {
|
|
75
|
+
const filter = {
|
|
76
|
+
ownerId: set.ownerId,
|
|
77
|
+
savedAt: { $gte: this.cutoff(set.now) },
|
|
78
|
+
};
|
|
79
|
+
const found = await this.dataDBService.find(filter, false, {
|
|
80
|
+
sort: { savedAt: -1 }, limit: this.settings.maxListCount,
|
|
81
|
+
});
|
|
82
|
+
return found.map((draft) => new msg_input_draft_data_model_1.DyNTS_Msg_InputDraft_DataModel(draft));
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
fsm_dynamo_1.DyFM_Log.warn(`[DyNTS_Msg_InputDraft] list failed (an empty list given)`, error);
|
|
86
|
+
return [];
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/** Removes the field's draft after a send (soft delete); `false` when there was none (or on an error, logged). */
|
|
90
|
+
async clear(set) {
|
|
91
|
+
try {
|
|
92
|
+
// EVERY live record of the field: two first saves racing can create two, and clearing only the newest would
|
|
93
|
+
// bring the older (already sent) text back
|
|
94
|
+
const live = await this.dataDBService.find({ ownerId: set.ownerId, fieldKey: set.fieldKey }, false, { limit: 20 });
|
|
95
|
+
const ids = live
|
|
96
|
+
.map((draft) => draft._id)
|
|
97
|
+
.filter((id) => !!id);
|
|
98
|
+
for (const id of ids) {
|
|
99
|
+
await this.dataDBService.markDeletedById(id, this.issuer);
|
|
100
|
+
}
|
|
101
|
+
return ids.length > 0;
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
fsm_dynamo_1.DyFM_Log.warn(`[DyNTS_Msg_InputDraft] clear failed: '${set.fieldKey}'`, error);
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/** The field's live record, expired or not (THROWS on a database error). */
|
|
109
|
+
async findCurrent(set) {
|
|
110
|
+
const found = await this.dataDBService.find({ ownerId: set.ownerId, fieldKey: set.fieldKey }, false, { sort: { savedAt: -1 }, limit: 1 });
|
|
111
|
+
return found[0] ? new msg_input_draft_data_model_1.DyNTS_Msg_InputDraft_DataModel(found[0]) : null;
|
|
112
|
+
}
|
|
113
|
+
/** Whether the draft is older than `maxAgeMs`. */
|
|
114
|
+
isExpired(set) {
|
|
115
|
+
return new Date(set.draft.savedAt).getTime() < this.cutoff(set.now).getTime();
|
|
116
|
+
}
|
|
117
|
+
/** The oldest save time still given back. */
|
|
118
|
+
cutoff(now) {
|
|
119
|
+
return new Date((now ?? new Date()).getTime() - this.settings.maxAgeMs);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
exports.DyNTS_Msg_InputDraft_DataService = DyNTS_Msg_InputDraft_DataService;
|
|
123
|
+
//# sourceMappingURL=msg-input-draft.data-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"msg-input-draft.data-service.js","sourceRoot":"","sources":["../../../../src/_modules/messaging/input-draft/msg-input-draft.data-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { DyNTS_Msg_InputDraft_Settings_Interface } from './msg-input-draft-settings.interface';
|
|
2
|
+
/**
|
|
3
|
+
* BFR-CCAPREVISIONED-030 part 2 - the input-draft request checks (a wrong request is the caller's bug: 400, with a
|
|
4
|
+
* code; the stored text itself is never changed).
|
|
5
|
+
*/
|
|
6
|
+
export declare class DyNTS_Msg_InputDraft_Util {
|
|
7
|
+
/** The settings with every missing field taken from the defaults. */
|
|
8
|
+
static resolve(settings?: DyNTS_Msg_InputDraft_Settings_Interface): Required<DyNTS_Msg_InputDraft_Settings_Interface>;
|
|
9
|
+
/** The field key from a body / query value: a non-empty string, at most `maxFieldKeyLength` long (trimmed). */
|
|
10
|
+
static fieldKey(raw: unknown, settings: Required<DyNTS_Msg_InputDraft_Settings_Interface>): string;
|
|
11
|
+
/** The text from a body value, UNCHANGED: missing ⇒ empty; not a string or too long ⇒ 400 (never cut). */
|
|
12
|
+
static content(raw: unknown, settings: Required<DyNTS_Msg_InputDraft_Settings_Interface>): string;
|
|
13
|
+
/** An optional short id (the browser id): a non-empty string up to 200 characters, otherwise none. */
|
|
14
|
+
static optionalId(raw: unknown): string | undefined;
|
|
15
|
+
/** A 400 with the module's code. */
|
|
16
|
+
private static badRequest;
|
|
17
|
+
/** The given settings without their `undefined` fields (so they do not hide a default). */
|
|
18
|
+
private static defined;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=msg-input-draft.util.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"msg-input-draft.util.d.ts","sourceRoot":"","sources":["../../../../src/_modules/messaging/input-draft/msg-input-draft.util.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,uCAAuC,EAAE,MAAM,sCAAsC,CAAC;AAE/F;;;GAGG;AACH,qBAAa,yBAAyB;IACpC,qEAAqE;IACrE,MAAM,CAAC,OAAO,CACZ,QAAQ,CAAC,EAAE,uCAAuC,GACjD,QAAQ,CAAC,uCAAuC,CAAC;IAIpD,+GAA+G;IAC/G,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,uCAAuC,CAAC,GAAG,MAAM;IAgBlG,0GAA0G;IAC1G,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,uCAAuC,CAAC,GAAG,MAAM;IAkBjG,sGAAsG;IACtG,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS;IAMnD,oCAAoC;IACpC,OAAO,CAAC,MAAM,CAAC,UAAU;IAUzB,2FAA2F;IAC3F,OAAO,CAAC,MAAM,CAAC,OAAO;CAavB"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DyNTS_Msg_InputDraft_Util = void 0;
|
|
4
|
+
const fsm_dynamo_1 = require("@futdevpro/fsm-dynamo");
|
|
5
|
+
const global_settings_const_1 = require("../../../_collections/global-settings.const");
|
|
6
|
+
const msg_input_draft_default_settings_const_1 = require("./msg-input-draft-default-settings.const");
|
|
7
|
+
/**
|
|
8
|
+
* BFR-CCAPREVISIONED-030 part 2 - the input-draft request checks (a wrong request is the caller's bug: 400, with a
|
|
9
|
+
* code; the stored text itself is never changed).
|
|
10
|
+
*/
|
|
11
|
+
class DyNTS_Msg_InputDraft_Util {
|
|
12
|
+
/** The settings with every missing field taken from the defaults. */
|
|
13
|
+
static resolve(settings) {
|
|
14
|
+
return { ...msg_input_draft_default_settings_const_1.DyNTS_msgInputDraft_defaultSettings, ...DyNTS_Msg_InputDraft_Util.defined(settings) };
|
|
15
|
+
}
|
|
16
|
+
/** The field key from a body / query value: a non-empty string, at most `maxFieldKeyLength` long (trimmed). */
|
|
17
|
+
static fieldKey(raw, settings) {
|
|
18
|
+
const fieldKey = typeof raw === 'string' ? raw.trim() : '';
|
|
19
|
+
if (!fieldKey) {
|
|
20
|
+
throw DyNTS_Msg_InputDraft_Util.badRequest({ code: 'FK1', message: 'The fieldKey is missing.' });
|
|
21
|
+
}
|
|
22
|
+
if (fieldKey.length > settings.maxFieldKeyLength) {
|
|
23
|
+
throw DyNTS_Msg_InputDraft_Util.badRequest({
|
|
24
|
+
code: 'FK2', message: `The fieldKey is longer than ${settings.maxFieldKeyLength} characters.`,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
return fieldKey;
|
|
28
|
+
}
|
|
29
|
+
/** The text from a body value, UNCHANGED: missing ⇒ empty; not a string or too long ⇒ 400 (never cut). */
|
|
30
|
+
static content(raw, settings) {
|
|
31
|
+
if (raw === undefined || raw === null) {
|
|
32
|
+
return '';
|
|
33
|
+
}
|
|
34
|
+
if (typeof raw !== 'string') {
|
|
35
|
+
throw DyNTS_Msg_InputDraft_Util.badRequest({ code: 'CT1', message: 'The content must be a text.' });
|
|
36
|
+
}
|
|
37
|
+
if (raw.length > settings.maxContentLength) {
|
|
38
|
+
throw DyNTS_Msg_InputDraft_Util.badRequest({
|
|
39
|
+
code: 'CT2', message: `The draft is longer than ${settings.maxContentLength} characters.`,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
return raw;
|
|
43
|
+
}
|
|
44
|
+
/** An optional short id (the browser id): a non-empty string up to 200 characters, otherwise none. */
|
|
45
|
+
static optionalId(raw) {
|
|
46
|
+
const id = typeof raw === 'string' ? raw.trim() : '';
|
|
47
|
+
return id && id.length <= 200 ? id : undefined;
|
|
48
|
+
}
|
|
49
|
+
/** A 400 with the module's code. */
|
|
50
|
+
static badRequest(set) {
|
|
51
|
+
return new fsm_dynamo_1.DyFM_Error({
|
|
52
|
+
status: 400,
|
|
53
|
+
errorCode: `${global_settings_const_1.DyNTS_global_settings.systemShortCodeName}|DyNTS-MSG-ID-${set.code}`,
|
|
54
|
+
message: set.message,
|
|
55
|
+
userMessage: set.message,
|
|
56
|
+
issuerService: 'DyNTS_Msg_InputDraft_Util',
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
/** The given settings without their `undefined` fields (so they do not hide a default). */
|
|
60
|
+
static defined(settings) {
|
|
61
|
+
const result = {};
|
|
62
|
+
Object.entries(settings ?? {}).forEach(([key, value]) => {
|
|
63
|
+
if (value !== undefined) {
|
|
64
|
+
Reflect.set(result, key, value);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
return result;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
exports.DyNTS_Msg_InputDraft_Util = DyNTS_Msg_InputDraft_Util;
|
|
71
|
+
//# sourceMappingURL=msg-input-draft.util.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"msg-input-draft.util.js","sourceRoot":"","sources":["../../../../src/_modules/messaging/input-draft/msg-input-draft.util.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@futdevpro/nts-dynamo",
|
|
3
|
-
"version": "01.15.
|
|
3
|
+
"version": "01.15.466",
|
|
4
4
|
"description": "Dynamic NodeTS (NodeJS-Typescript), MongoDB Backend System Framework by Future Development Program Ltd.",
|
|
5
5
|
"DyBu_settings": {
|
|
6
6
|
"packageType": "server-package",
|