@ti-engine/web-framework 1.19.0 → 1.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/.env +4 -4
  2. package/CHANGELOG.md +384 -353
  3. package/README.md +73 -73
  4. package/bin/build/post-install.js +18 -18
  5. package/bin/localization/web-server-labels.json +27 -27
  6. package/bin/static/.well-known/appspecific/com.chrome.devtools.json +5 -5
  7. package/bin/static/fragments/components/component-notification-bar.html +21 -21
  8. package/bin/static/fragments/components/component-sidebar.html +33 -33
  9. package/bin/static/fragments/components/component-tooltip.html +10 -10
  10. package/bin/static/fragments/components/component-topbar.html +5 -5
  11. package/bin/static/fragments/frame-administration.html +2 -2
  12. package/bin/static/fragments/frame-application.html +18 -18
  13. package/bin/static/fragments/frame-dashboard.html +2 -2
  14. package/bin/static/fragments/frame-login.html +119 -119
  15. package/bin/static/fragments/frame-not-found.html +2 -2
  16. package/bin/static/fragments/frame-profile.html +2 -2
  17. package/bin/static/index.html +22 -22
  18. package/bin/static/scripts/ti-charts.js +1591 -1591
  19. package/bin/static/scripts/ti-framework.css +3194 -3194
  20. package/bin/static/scripts/ti-framework.js +1427 -1427
  21. package/bin/static/scripts/ti-theme-black-glass.css +216 -216
  22. package/bin/static/scripts/ti-theme-daylight.css +87 -87
  23. package/bin/web-app-manager.js +660 -663
  24. package/bin/web-server.js +936 -937
  25. package/bin/web-server.json +48 -48
  26. package/components/admin-config-handlers.js +95 -92
  27. package/components/auth-manager.js +438 -442
  28. package/components/authorization.js +135 -135
  29. package/components/config-change-notifier.js +98 -98
  30. package/components/config-registry.js +257 -260
  31. package/components/config-service.js +363 -360
  32. package/components/config-store.js +244 -246
  33. package/components/definitions.types.js +28 -26
  34. package/components/session-store.js +113 -110
  35. package/components/user.js +134 -132
  36. package/components/web-config-env.js +85 -85
  37. package/components/web-handlers.js +803 -800
  38. package/package.json +139 -67
  39. package/types/bin/web-app-manager.d.ts +194 -0
  40. package/types/bin/web-server.d.ts +373 -0
  41. package/types/components/admin-config-handlers.d.ts +11 -0
  42. package/types/components/auth-manager.d.ts +125 -0
  43. package/types/components/authorization.d.ts +54 -0
  44. package/types/components/config-change-notifier.d.ts +73 -0
  45. package/types/components/config-registry.d.ts +149 -0
  46. package/types/components/config-service.d.ts +218 -0
  47. package/types/components/config-store.d.ts +128 -0
  48. package/types/components/definitions.types.d.ts +31 -0
  49. package/types/components/session-store.d.ts +56 -0
  50. package/types/components/user.d.ts +83 -0
  51. package/types/components/web-config-env.d.ts +17 -0
  52. package/types/components/web-handlers.d.ts +23 -0
@@ -0,0 +1,149 @@
1
+ export = ConfigRegistry;
2
+ export type ConfigValidationIssue = {
3
+ /**
4
+ * A JSON pointer / data path to the offending value (e.g. ".competencies.E1-1.name"), or "".
5
+ */
6
+ path: string;
7
+ /**
8
+ * Human-readable problem description.
9
+ */
10
+ message: string;
11
+ /**
12
+ * "schema" for JSON-Schema failures, or a validator-supplied code (default "semantic").
13
+ */
14
+ code: string;
15
+ /**
16
+ * Optional structured details (e.g. ajv params).
17
+ */
18
+ params?: Object;
19
+ };
20
+ export type ValidatorContext = {
21
+ /**
22
+ * Resolves the *pending* value of `key` when it is part of the
23
+ * current edit batch, otherwise its current committed value. Lets a validator check a sibling document's
24
+ * post-edit state — but calling this for the document being validated itself just returns the same incoming
25
+ * value already passed as the validator's first argument, not its prior state.
26
+ */
27
+ getConfig: (key: string) => Promise<any>;
28
+ /**
29
+ * Always resolves the current committed value of `key`,
30
+ * even when `key` is the document currently under validation. Use this to compare a document against its own
31
+ * previous state (e.g. detecting an edit that should have bumped a version marker).
32
+ */
33
+ getStoredConfig: (key: string) => Promise<any>;
34
+ };
35
+ export type SemanticValidator = (value: Object, context: ValidatorContext) => ConfigValidationIssue[] | Promise<ConfigValidationIssue[]>;
36
+ /**
37
+ * @typedef {Object} ConfigValidationIssue
38
+ * @property {string} path A JSON pointer / data path to the offending value (e.g. ".competencies.E1-1.name"), or "".
39
+ * @property {string} message Human-readable problem description.
40
+ * @property {string} code "schema" for JSON-Schema failures, or a validator-supplied code (default "semantic").
41
+ * @property {Object} [params] Optional structured details (e.g. ajv params).
42
+ */
43
+ /**
44
+ * The cross-document read context passed to every {@link SemanticValidator}, built fresh for each
45
+ * {@link ConfigService#applyEdits} call.
46
+ *
47
+ * @typedef {Object} ValidatorContext
48
+ * @property {(key: string) => Promise<*>} getConfig Resolves the *pending* value of `key` when it is part of the
49
+ * current edit batch, otherwise its current committed value. Lets a validator check a sibling document's
50
+ * post-edit state — but calling this for the document being validated itself just returns the same incoming
51
+ * value already passed as the validator's first argument, not its prior state.
52
+ * @property {(key: string) => Promise<*>} getStoredConfig Always resolves the current committed value of `key`,
53
+ * even when `key` is the document currently under validation. Use this to compare a document against its own
54
+ * previous state (e.g. detecting an edit that should have bumped a version marker).
55
+ */
56
+ /**
57
+ * @typedef {(value: Object, context: ValidatorContext) => ConfigValidationIssue[]|Promise<ConfigValidationIssue[]>} SemanticValidator
58
+ * A semantic validator receives the candidate value and a {@link ValidatorContext} and returns the issues it found
59
+ * (empty array = OK). May be async.
60
+ */
61
+ /**
62
+ * Registry of editable configuration *documents* and the gate that validates a candidate value against a
63
+ * document's JSON Schema (ajv) plus its semantic validators. The framework stays domain-agnostic: an application
64
+ * registers its config documents (schemas, validators, defaults, editor metadata) at startup; this component knows
65
+ * only "validated, versioned JSON documents". Validation must pass *before* {@link ConfigStore#saveChangeSet}.
66
+ *
67
+ * @class ConfigRegistry
68
+ * @public
69
+ */
70
+ declare class ConfigRegistry {
71
+ #private;
72
+ constructor();
73
+ /**
74
+ * Registers an editable configuration document.
75
+ *
76
+ * @method
77
+ * @param {string} configKey Stable identifier for the document (also the ConfigStore key).
78
+ * @param {Object} definition
79
+ * @param {Object} definition.schema A JSON Schema for the document.
80
+ * @param {SemanticValidator[]} [definition.validators] Cross-cutting/semantic checks beyond the schema.
81
+ * @param {Object} [definition.defaultValue] The bootstrap default (seeds an empty store).
82
+ * @param {Object} [definition.metadata] Editor metadata (label, editor type, group, risk class, …).
83
+ * @returns {ConfigRegistry} this (chainable)
84
+ * @throws {TiException.E_WEB_INVALID_REQUEST_PARAMETERS} On missing key/schema.
85
+ * @public
86
+ */
87
+ register(configKey: string, definition: {
88
+ schema: Object;
89
+ validators?: SemanticValidator[];
90
+ defaultValue?: Object;
91
+ metadata?: Object;
92
+ }): ConfigRegistry;
93
+ /**
94
+ * Adds a schema that is referenced (via `$ref`/`$id`) by document schemas but is not itself a document.
95
+ *
96
+ * @method
97
+ * @param {Object} schema
98
+ * @returns {ConfigRegistry} this (chainable)
99
+ * @public
100
+ */
101
+ addSchema(schema: Object): ConfigRegistry;
102
+ /**
103
+ * @method
104
+ * @param {string} configKey
105
+ * @returns {boolean}
106
+ * @public
107
+ */
108
+ has(configKey: string): boolean;
109
+ /**
110
+ * @method
111
+ * @returns {string[]} All registered configuration keys.
112
+ * @public
113
+ */
114
+ list(): string[];
115
+ /**
116
+ * @method
117
+ * @param {string} configKey
118
+ * @returns {Object|undefined} The editor metadata registered for the document.
119
+ * @public
120
+ */
121
+ metadataFor(configKey: string): Object | undefined;
122
+ /**
123
+ * @method
124
+ * @param {string} configKey
125
+ * @returns {Object|undefined} The bootstrap default value registered for the document.
126
+ * @public
127
+ */
128
+ getDefault(configKey: string): Object | undefined;
129
+ /**
130
+ * Validates a candidate value for a registered document: JSON Schema first, then the semantic validators.
131
+ * Resolves with `{ valid, errors }` (errors is an array of {@link ConfigValidationIssue}).
132
+ *
133
+ * @method
134
+ * @param {string} configKey
135
+ * @param {Object} value
136
+ * @param {ValidatorContext} [context] Passed to each semantic validator.
137
+ * @returns {Promise<{valid: boolean, errors: ConfigValidationIssue[]}>}
138
+ * @throws {TiException.E_WEB_INVALID_REQUEST_PARAMETERS} If the document is not registered.
139
+ * @public
140
+ */
141
+ validate(configKey: string, value: Object, context?: ValidatorContext): Promise<{
142
+ valid: boolean;
143
+ errors: ConfigValidationIssue[];
144
+ }>;
145
+ }
146
+ declare namespace ConfigRegistry {
147
+ export { instance };
148
+ }
149
+ declare const instance: ConfigRegistry;
@@ -0,0 +1,218 @@
1
+ export = ConfigService;
2
+ import type ConfigChangeNotifier from "#config-change-notifier";
3
+ import type ConfigRegistry from "#config-registry";
4
+ import type ConfigStore from "#config-store";
5
+ /** @import ConfigChangeNotifier from "#config-change-notifier" */
6
+ /** @import ConfigRegistry from "#config-registry" */
7
+ /** @import ConfigStore from "#config-store" */
8
+ /**
9
+ * Orchestrates validated, versioned configuration edits on top of {@link ConfigStore} and {@link ConfigRegistry}.
10
+ *
11
+ * Two layers:
12
+ * - **Document level** — {@link ConfigService#applyEdits}: validate every affected document (schema + semantic,
13
+ * with a cross-document {@link ValidatorContext} whose `getConfig` sees the *pending* values of the same edit —
14
+ * letting a validator check a sibling document's post-edit state — while `getStoredConfig` always returns the
15
+ * committed value, even for the document currently under validation) and, only if all pass, commit them as one
16
+ * change-set. Validation failures return `{ ok:false, errors }` and write nothing; a version conflict from the
17
+ * store surfaces as a rejection.
18
+ * - **Entity level** — composite editors registered with `compose(docs)→view` / `decompose(edited, docs)→{key:value}`,
19
+ * so the UI edits a domain entity (e.g. a "competency") that is projected from, and scattered back into, several
20
+ * documents. {@link ConfigService#saveEditorEdit} decomposes the edit and routes it through `applyEdits`.
21
+ *
22
+ * @class ConfigService
23
+ * @public
24
+ */
25
+ declare class ConfigService {
26
+ #private;
27
+ /**
28
+ * @constructor
29
+ * @param {Object} [options]
30
+ * @param {ConfigStore} [options.store] Defaults to the ConfigStore singleton.
31
+ * @param {ConfigRegistry} [options.registry] Defaults to the ConfigRegistry singleton.
32
+ * @param {ConfigChangeNotifier} [options.notifier] Defaults to the ConfigChangeNotifier singleton.
33
+ */
34
+ constructor(options?: {
35
+ store?: ConfigStore;
36
+ registry?: ConfigRegistry;
37
+ notifier?: ConfigChangeNotifier;
38
+ });
39
+ /**
40
+ * Validates and commits a set of document edits atomically. Each edit: `{ configKey, value, expectedVersion }`.
41
+ *
42
+ * @method
43
+ * @param {Array<{configKey: string, value: Object, expectedVersion: number}>} edits
44
+ * @param {Object} meta
45
+ * @param {string} meta.adminID
46
+ * @param {string} [meta.note]
47
+ * @returns {Promise<{ok: true, changeSetID: string, versions: Object<string, number>} | {ok: false, errors: Object<string, Array>}>}
48
+ * @public
49
+ */
50
+ applyEdits(edits: Array<{
51
+ configKey: string;
52
+ value: Object;
53
+ expectedVersion: number;
54
+ }>, meta: {
55
+ adminID: string;
56
+ note?: string;
57
+ }): Promise<{
58
+ ok: true;
59
+ changeSetID: string;
60
+ versions: Record<string, number>;
61
+ } | {
62
+ ok: false;
63
+ errors: Record<string, any[]>;
64
+ }>;
65
+ /**
66
+ * Registers a composite editor over one or more documents.
67
+ *
68
+ * @method
69
+ * @param {string} editorKey
70
+ * @param {Object} definition
71
+ * @param {string[]} definition.documents The configKeys this editor spans.
72
+ * @param {(configs: Object) => *} definition.compose Maps `{ [configKey]: value }` → a view for the UI.
73
+ * @param {(editedView: *, currentDocs: Object) => Object.<string, Object>} definition.decompose Maps `(editedView, currentDocs)` → the
74
+ * full new values for the documents that changed (`{ [configKey]: newValue }`).
75
+ * @param {Object} [definition.metadata]
76
+ * @returns {ConfigService} this (chainable)
77
+ * @throws {TiException.E_WEB_INVALID_REQUEST_PARAMETERS}
78
+ * @public
79
+ */
80
+ registerEditor(editorKey: string, definition: {
81
+ documents: string[];
82
+ compose: (configs: Object) => any;
83
+ decompose: (editedView: any, currentDocs: Object) => Record<string, Object>;
84
+ metadata?: Object;
85
+ }): ConfigService;
86
+ /**
87
+ * @method
88
+ * @param {string} editorKey
89
+ * @returns {boolean}
90
+ * @public
91
+ */
92
+ hasEditor(editorKey: string): boolean;
93
+ /**
94
+ * @method
95
+ * @returns {string[]}
96
+ * @public
97
+ */
98
+ listEditors(): string[];
99
+ /**
100
+ * Loads the editor's documents and composes them into a view. Returns the view plus the current per-document
101
+ * versions, which the client must echo back on save for optimistic locking.
102
+ *
103
+ * @method
104
+ * @param {string} editorKey
105
+ * @returns {Promise<{rows: *, versions: Object<string, number>}>}
106
+ * @public
107
+ */
108
+ composeView(editorKey: string): Promise<{
109
+ rows: any;
110
+ versions: Record<string, number>;
111
+ }>;
112
+ /**
113
+ * Applies an edit made against a composite editor: decompose the edited view into per-document new values, then
114
+ * route through {@link ConfigService#applyEdits} (validate-all → atomic change-set). `expectedVersions` should be
115
+ * the versions returned by {@link ConfigService#composeView} when the edit started.
116
+ *
117
+ * @method
118
+ * @param {string} editorKey
119
+ * @param {*} editedView
120
+ * @param {Object} meta
121
+ * @param {Object<string, number>} [expectedVersions]
122
+ * @returns {Promise<Object>} The {@link ConfigService#applyEdits} result (or `{ ok:true, changeSetID:null }` if nothing changed).
123
+ * @public
124
+ */
125
+ saveEditorEdit(editorKey: string, editedView: any, meta: Object, expectedVersions?: Record<string, number>): Promise<Object>;
126
+ /**
127
+ * Restores a prior change-set through the validated path: rebuild edits from the change-set's historic snapshots
128
+ * and route them through {@link ConfigService#applyEdits} — so the restore is **re-validated against the current
129
+ * schemas/validators** (a snapshot valid when written may be invalid now) and emits `config:changed`. Returns the
130
+ * `applyEdits` result (`{ ok:false, errors }` if a snapshot no longer validates; nothing is written then).
131
+ *
132
+ * @method
133
+ * @param {string} changeSetID
134
+ * @param {Object} meta
135
+ * @param {string} meta.adminID
136
+ * @param {string} [meta.note]
137
+ * @returns {Promise<Object>}
138
+ * @public
139
+ */
140
+ restoreChangeSet(changeSetID: string, meta: {
141
+ adminID: string;
142
+ note?: string;
143
+ }): Promise<Object>;
144
+ /**
145
+ * @method
146
+ * @param {string} configKey
147
+ * @returns {Promise<Object|null>} The current envelope for a configuration document.
148
+ * @public
149
+ */
150
+ getCurrent(configKey: string): Promise<Object | null>;
151
+ /**
152
+ * @method
153
+ * @param {string} configKey
154
+ * @returns {Promise<Array<Object>>} The document's version history (ascending), each a full snapshot entry.
155
+ * @public
156
+ */
157
+ getHistory(configKey: string): Promise<Array<Object>>;
158
+ /**
159
+ * @method
160
+ * @param {string} changeSetID
161
+ * @returns {Promise<Object|null>} A single change-set record.
162
+ * @public
163
+ */
164
+ getChange(changeSetID: string): Promise<Object | null>;
165
+ /**
166
+ * @method
167
+ * @returns {Promise<Array<Object>>} The cross-document audit feed (change-sets, most-recent first).
168
+ * @public
169
+ */
170
+ listChanges(): Promise<Array<Object>>;
171
+ /**
172
+ * Builds a downloadable snapshot of the current live configuration — for every registered document, its repo file
173
+ * `path` (from registration metadata, if provided), current `version`, and `value`. This is the one-way export
174
+ * *out* of the store; an admin downloads it and commits the files to git. The store remains the live truth.
175
+ *
176
+ * @method
177
+ * @param {Object} [meta]
178
+ * @param {string} [meta.adminID]
179
+ * @returns {Promise<{exportedAt: string, exportedBy: (string|null), documents: Array<{configKey: string, path: (string|null), version: number, value: Object}>}>}
180
+ * @public
181
+ */
182
+ exportBundle(meta?: {
183
+ adminID?: string;
184
+ }): Promise<{
185
+ exportedAt: string;
186
+ exportedBy: (string | null);
187
+ documents: Array<{
188
+ configKey: string;
189
+ path: (string | null);
190
+ version: number;
191
+ value: Object;
192
+ }>;
193
+ }>;
194
+ /**
195
+ * Seeds a document's default value into the store only if it has never been written (idempotent bootstrap).
196
+ * Used by an application to bring its file defaults into the store at startup before serving live config.
197
+ *
198
+ * @method
199
+ * @param {string} configKey
200
+ * @param {Object} defaultValue
201
+ * @returns {Promise<Object>} The current envelope.
202
+ * @public
203
+ */
204
+ seedDefault(configKey: string, defaultValue: Object): Promise<Object>;
205
+ /**
206
+ * Subscribes a listener to `config:changed` events (delegates to the change notifier). Returns an unsubscribe fn.
207
+ *
208
+ * @method
209
+ * @param {(configs: Object) => void} listener
210
+ * @returns {() => void}
211
+ * @public
212
+ */
213
+ onConfigChanged(listener: (configs: Object) => void): () => void;
214
+ }
215
+ declare namespace ConfigService {
216
+ export { instance };
217
+ }
218
+ declare const instance: ConfigService;
@@ -0,0 +1,128 @@
1
+ export = ConfigStore;
2
+ /**
3
+ * A versioned, change-set-aware configuration store backed by the common memory cache (RedisJSON).
4
+ * <br/>
5
+ * Each editable configuration is a *document* identified by a `configKey`. Every committed edit:
6
+ * - bumps the document's monotonic `version`,
7
+ * - writes a full **snapshot** to history (enabling restore),
8
+ * - and is correlated with the other documents written in the same logical edit via a shared **change-set** id,
9
+ * so a multi-document edit (and its restore) is treated as one unit even though storage is per-document.
10
+ * <br/>
11
+ * Optimistic locking: callers pass the `expectedVersion` they edited from; the save is rejected if any document
12
+ * moved on in the meantime. This component is storage-only — schema/semantic validation is a separate pipeline
13
+ * that must run *before* {@link ConfigStore#saveChangeSet}.
14
+ * <br/>
15
+ * NOTE: true cross-document atomicity is not provided (the cache exposes per-key commands only). All locks are
16
+ * checked *before* any write, so the common conflict case is safe; a mid-write process failure can leave a
17
+ * partially-applied change-set, detectable via the change-set record. Hardening (a Lua/MULTI write) is deferred.
18
+ *
19
+ * @class ConfigStore
20
+ * @public
21
+ */
22
+ declare class ConfigStore {
23
+ #private;
24
+ /**
25
+ * Returns the current envelope `{ value, version, updatedAt, updatedBy, changeSetID }` for a configuration
26
+ * document, or `null` if it has never been written.
27
+ *
28
+ * @method
29
+ * @param {string} configKey
30
+ * @returns {Promise<Object|null>}
31
+ * @public
32
+ */
33
+ getCurrent(configKey: string): Promise<Object | null>;
34
+ /**
35
+ * Writes the default value as version 1 only if the document does not yet exist (idempotent bootstrap).
36
+ * Resolves with the current envelope either way.
37
+ *
38
+ * @method
39
+ * @param {string} configKey
40
+ * @param {Object} defaultValue
41
+ * @returns {Promise<Object>}
42
+ * @public
43
+ */
44
+ seedIfEmpty(configKey: string, defaultValue: Object): Promise<Object>;
45
+ /**
46
+ * Commits an edit spanning one or more documents as a single change-set. All optimistic-lock checks run before
47
+ * any write. Each edit: `{ configKey, value, expectedVersion }`.
48
+ *
49
+ * @method
50
+ * @param {Array<{configKey: string, value: Object, expectedVersion: number}>} edits
51
+ * @param {Object} meta
52
+ * @param {string} meta.adminID
53
+ * @param {string} [meta.note]
54
+ * @returns {Promise<{changeSetID: string, versions: Object<string, number>}>}
55
+ * @throws {TiException.E_WEB_INVALID_REQUEST_PARAMETERS} On bad input or a version conflict (see `details`).
56
+ * @public
57
+ */
58
+ saveChangeSet(edits: Array<{
59
+ configKey: string;
60
+ value: Object;
61
+ expectedVersion: number;
62
+ }>, meta: {
63
+ adminID: string;
64
+ note?: string;
65
+ }): Promise<{
66
+ changeSetID: string;
67
+ versions: Record<string, number>;
68
+ }>;
69
+ /**
70
+ * Returns all history entries for a document, ascending by version.
71
+ *
72
+ * @method
73
+ * @param {string} configKey
74
+ * @returns {Promise<Array<Object>>}
75
+ * @public
76
+ */
77
+ listHistory(configKey: string): Promise<Array<Object>>;
78
+ /**
79
+ * Returns a single history snapshot entry for a document version, or `null`.
80
+ *
81
+ * @method
82
+ * @param {string} configKey
83
+ * @param {number} version
84
+ * @returns {Promise<Object|null>}
85
+ * @public
86
+ */
87
+ getVersion(configKey: string, version: number): Promise<Object | null>;
88
+ /**
89
+ * Returns a change-set record by id, or `null`.
90
+ *
91
+ * @method
92
+ * @param {string} changeSetID
93
+ * @returns {Promise<Object|null>}
94
+ * @public
95
+ */
96
+ getChangeSet(changeSetID: string): Promise<Object | null>;
97
+ /**
98
+ * Returns every change-set record, most-recent first (the cross-document audit feed).
99
+ *
100
+ * @method
101
+ * @returns {Promise<Array<Object>>}
102
+ * @public
103
+ */
104
+ listChangeSets(): Promise<Array<Object>>;
105
+ /**
106
+ * Restores every document in a prior change-set to that change-set's snapshot, committing it as a *new*
107
+ * change-set (restore is never destructive — it moves forward to a past state).
108
+ *
109
+ * @method
110
+ * @param {string} changeSetID
111
+ * @param {Object} meta
112
+ * @param {string} meta.adminID
113
+ * @param {string} [meta.note]
114
+ * @returns {Promise<{changeSetID: string, versions: Object<string, number>}>}
115
+ * @public
116
+ */
117
+ restoreChangeSet(changeSetID: string, meta: {
118
+ adminID: string;
119
+ note?: string;
120
+ }): Promise<{
121
+ changeSetID: string;
122
+ versions: Record<string, number>;
123
+ }>;
124
+ }
125
+ declare namespace ConfigStore {
126
+ var _a: Readonly<ConfigStore>;
127
+ export { _a as instance };
128
+ }
@@ -0,0 +1,31 @@
1
+ import type { TiLocalizationLanguage } from "@ti-engine/core/localization";
2
+ export type TiSessionCallback = (error?: Error | null) => void;
3
+ export type TiSession = {
4
+ id: string;
5
+ user?: Object;
6
+ language?: TiLocalizationLanguage;
7
+ cookie?: Object;
8
+ oidc?: Object;
9
+ csrfToken?: string;
10
+ regenerate: (callback: TiSessionCallback) => TiSession;
11
+ destroy: (callback: TiSessionCallback) => TiSession;
12
+ save: (callback?: TiSessionCallback) => TiSession;
13
+ };
14
+ /** @import { TiLocalizationLanguage } from "@ti-engine/core/localization" */
15
+ /**
16
+ * @callback TiSessionCallback
17
+ * @param {Error|null} [error]
18
+ * @returns {void}
19
+ */
20
+ /**
21
+ * @typedef {Object} TiSession
22
+ * @property {string} id
23
+ * @property {Object} [user]
24
+ * @property {TiLocalizationLanguage} [language]
25
+ * @property {Object} [cookie]
26
+ * @property {Object} [oidc]
27
+ * @property {string} [csrfToken]
28
+ * @property {(callback: TiSessionCallback) => TiSession} regenerate
29
+ * @property {(callback: TiSessionCallback) => TiSession} destroy
30
+ * @property {(callback?: TiSessionCallback) => TiSession} save
31
+ */
@@ -0,0 +1,56 @@
1
+ export = SessionStore;
2
+ import session = require("express-session");
3
+ import type { SessionData } from "express-session";
4
+ import type { TiException } from "@ti-engine/core/exceptions";
5
+ /**
6
+ * A session store for the web server using the standard 'cache' module of the ti-engine.
7
+ * <br/>
8
+ * NOTE: This implementation is compatible with the 'express-session' module.
9
+ *
10
+ * @class SessionStore
11
+ * @public
12
+ */
13
+ declare class SessionStore extends session.Store {
14
+ /**
15
+ * @constructor
16
+ */
17
+ constructor();
18
+ /**
19
+ * Used to store a user session in the cache.
20
+ *
21
+ * @method
22
+ * @param {string} sessionID
23
+ * @param {SessionData} session
24
+ * @param {(error?: Error|TiException|null) => void} callback
25
+ * @public
26
+ */
27
+ set(sessionID: string, session: SessionData, callback: (error?: Error | TiException | null) => void): void;
28
+ /**
29
+ * Used to retrieve a user session from the cache.
30
+ *
31
+ * @method
32
+ * @param {string} sessionID
33
+ * @param {(error?: Error|TiException|null, session?: SessionData|null) => void} callback
34
+ * @public
35
+ */
36
+ get(sessionID: string, callback: (error?: Error | TiException | null, session?: SessionData | null) => void): void;
37
+ /**
38
+ * Used to remove a user session from the cache.
39
+ *
40
+ * @method
41
+ * @param {string} sessionID
42
+ * @param {(error?: Error|TiException|null) => void} callback
43
+ * @public
44
+ */
45
+ destroy(sessionID: string, callback: (error?: Error | TiException | null) => void): void;
46
+ /**
47
+ * Used to update the expiration time of a user session in the cache.
48
+ *
49
+ * @method
50
+ * @param {string} sessionID
51
+ * @param {SessionData} session
52
+ * @param {(error?: Error|TiException|null) => void} callback
53
+ * @public
54
+ */
55
+ touch(sessionID: string, session: SessionData, callback: (error?: Error | TiException | null) => void): void;
56
+ }
@@ -0,0 +1,83 @@
1
+ export = User;
2
+ import type { TiLocalizationLanguage } from "@ti-engine/core/localization";
3
+ /** @import { TiLocalizationLanguage } from "@ti-engine/core/localization" */
4
+ /**
5
+ * Represents a user in the system.
6
+ *
7
+ * @class User
8
+ * @public
9
+ */
10
+ declare class User {
11
+ #private;
12
+ /**
13
+ * @constructor
14
+ * @param {Object} userData
15
+ * @param {string} userData.userID
16
+ * @param {string} [userData.username]
17
+ * @param {string} [userData.email]
18
+ * @param {string} [userData.name]
19
+ * @param {TiLocalizationLanguage} [userData.language]
20
+ * @param {string[]} [userData.roles]
21
+ * @param {string[]} [userData.permissions]
22
+ * @param {Object} [userData.details]
23
+ */
24
+ constructor(userData?: {
25
+ userID: string;
26
+ username?: string;
27
+ email?: string;
28
+ name?: string;
29
+ language?: TiLocalizationLanguage;
30
+ roles?: string[];
31
+ permissions?: string[];
32
+ details?: Object;
33
+ });
34
+ /**
35
+ * @property
36
+ * @returns {string}
37
+ * @public
38
+ */
39
+ get userID(): string;
40
+ /**
41
+ * @property
42
+ * @returns {string}
43
+ * @public
44
+ */
45
+ get username(): string;
46
+ /**
47
+ * @property
48
+ * @returns {string}
49
+ * @public
50
+ */
51
+ get email(): string;
52
+ /**
53
+ * @property
54
+ * @returns {string}
55
+ * @public
56
+ */
57
+ get name(): string;
58
+ /**
59
+ * @property
60
+ * @returns {TiLocalizationLanguage}
61
+ * @public
62
+ */
63
+ get language(): TiLocalizationLanguage;
64
+ /**
65
+ * @method
66
+ * @returns {*}
67
+ * @public
68
+ */
69
+ getDetail(key: any): any;
70
+ /**
71
+ * @method
72
+ * @param {string} key
73
+ * @param {*} value
74
+ * @public
75
+ */
76
+ setDetail(key: string, value: any): void;
77
+ /**
78
+ * @method
79
+ * @returns {Object}
80
+ * @public
81
+ */
82
+ asJSON(): Object;
83
+ }
@@ -0,0 +1,17 @@
1
+ export = applyWebConfigEnvOverrides;
2
+ /**
3
+ * Applies TI_WEB_* environment-variable overrides onto an (already-merged) web server configuration object.
4
+ * Each override is applied ONLY when its environment variable is defined, so an absent variable leaves the
5
+ * configured/default value untouched (fully backward compatible). This gives ti-engine web servers 12-factor,
6
+ * container-friendly control over network binding, TLS, the session cookie secret, the enabled authentication
7
+ * methods, the admin allowlist, the trusted request origins, and the `/static` cache policy without editing config files. Note `TI_WEB_AUTH_METHODS`,
8
+ * `TI_WEB_AUTH_ADMINS`, `TI_WEB_TRUSTED_ORIGINS`, and `TI_WEB_STATIC_IMMUTABLE_PATHS` fully REPLACE their config arrays (`auth.enabledMethods` / `auth.admins` / `trustedOrigins` / `staticCache.immutablePaths`) rather than
9
+ * merging — the config-file merge is by-index and cannot cleanly override an array.
10
+ *
11
+ * @method
12
+ * @param {Object} config The web server configuration to augment (mutated in place and returned).
13
+ * @param {Object} [env=process.env] The environment source (injectable for testing).
14
+ * @returns {Object} The same config object, with any present overrides applied.
15
+ * @public
16
+ */
17
+ declare function applyWebConfigEnvOverrides(config: Object, env?: Object): Object;