@ti-engine/web-framework 1.19.1 → 1.20.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,35 @@
2
2
 
3
3
  This document will contain the list of changes made to the framework. The format is based on the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) specification.
4
4
 
5
+ ## Version 1.20.1
6
+
7
+ * fix(types): emit `/// <reference types="node" />` into `web-server.d.ts`, which names `node:http`.
8
+ Without it a consumer who has not separately configured Node's types gets `TS2591` from inside the
9
+ published declarations. See `@ti-engine/core` 1.9.1 for why the 1.20.0 gate did not catch this
10
+ * build(release): bump package version from `1.20.0` to `1.20.1`
11
+
12
+ ## Version 1.20.0
13
+
14
+ TypeScript declarations now ship with the package, verified against a consumer type-checking with `skipLibCheck: false`
15
+ before they can be committed. See `@ti-engine/core` 1.9.0 for why the previous attempt was withdrawn.
16
+
17
+ * feat(types): generate and publish `.d.ts` declarations for every module, wired through `types` conditions in both
18
+ `exports` and `imports`
19
+ * feat(definitions): expose the shared type definitions as `@ti-engine/web-framework/definitions`
20
+ * fix(session-store)!: the store's `set`, `get` and `touch` are typed against `express-session`'s `SessionData`, which
21
+ is what the `Store` contract hands them — not `TiSession`, which additionally requires `id`, `save`, `regenerate` and
22
+ `destroy`. The implementation only ever reads `cookie.maxAge`, so the annotation was describing a stricter input than
23
+ the base class can supply and than the code needs. Documentation only; no behaviour changes
24
+ * fix(web-handlers): `ExpressResponse` referred to `import("express").res`, which express does not export. It is
25
+ `Response`
26
+ * refactor(exports): the extras hung off `module.exports` after a class assignment — `instance`, `authMethod`,
27
+ `applyAuthMethodVisibility`, the static route matchers — are assigned to the class itself. `module.exports` *is* the
28
+ class, so this is the same object with the same properties at runtime; as a declaration it is the difference between
29
+ a namespace merge and an export assignment colliding with named exports, which is not valid TypeScript
30
+ * fix(types): the same closure-style `{function(...)}` and `@private`-on-`#member` corrections as `core` 1.9.0
31
+ * build(deps): add `@types/express`, `@types/express-session` and `@types/node`. The published declarations name types
32
+ from all three
33
+
5
34
  ## Version 1.19.1
6
35
 
7
36
  Documentation and packaging only — no functional change.
@@ -15,6 +15,8 @@ const configRegistry = require( "#config-registry" );
15
15
  const configService = require( "#config-service" );
16
16
  const authorization = require( "#authorization" );
17
17
 
18
+ /** @import { TiSession } from "#definitions" */
19
+
18
20
  const RE_NONCE_ATTR = /\{ti-nonce-placeholder}/g;
19
21
  const RE_CSRF_ATTR = /\{ti-csrf-placeholder}/g;
20
22
  const RE_HTMX_CONFIG = /\{ti-htmx-config-placeholder}/g;
@@ -462,7 +464,6 @@ class TiWebAppManager {
462
464
  * @param {boolean} [options.isHome] Optional flag to indicate whether the requested route is the home page.
463
465
  * @param {string} [options.nonce] Optional CSP nonce to inject into inline scripts/styles.
464
466
  * @returns {Promise<string>}
465
- * @private
466
467
  */
467
468
  #getHtmlFragment( session, staticContentPaths, fragment, options = {} ) {
468
469
  return new Promise( ( resolve, reject ) => {
@@ -487,7 +488,6 @@ class TiWebAppManager {
487
488
  * @param {string[]} staticContentPaths A list of directories to search for static content. If sent as expected by the web server, the first item in the array should be the system default path.
488
489
  * @param {string} filePath Relative path to the static file to locate.
489
490
  * @returns {Promise<string>}
490
- * @private
491
491
  */
492
492
  #locateStaticFile( staticContentPaths, filePath ) {
493
493
  return new Promise( ( resolve, reject ) => {
@@ -530,7 +530,6 @@ class TiWebAppManager {
530
530
  * @param {string[]} staticContentPaths
531
531
  * @param {Array<string>} components
532
532
  * @returns {Promise<string>}
533
- * @private
534
533
  */
535
534
  #replaceComponentPlaceholders( html, staticContentPaths, components ) {
536
535
  return new Promise( ( resolve, reject ) => {
@@ -573,7 +572,6 @@ class TiWebAppManager {
573
572
  * @param {string} tagName
574
573
  * @param {string} replacement
575
574
  * @returns {string}
576
- * @private
577
575
  */
578
576
  #replacePlaceholderElement( html, tagName, replacement ) {
579
577
  const start = html.indexOf( `<${ tagName }` );
@@ -643,7 +641,6 @@ class TiWebAppManager {
643
641
  * @method
644
642
  * @param {string} openingTag The full opening tag text, e.g. `<ti-foo-placeholder bar="baz">`.
645
643
  * @returns {Object<string, string>}
646
- * @private
647
644
  */
648
645
  #parsePlaceholderAttributes( openingTag ) {
649
646
  const attributes = {};
@@ -660,4 +657,4 @@ class TiWebAppManager {
660
657
  }
661
658
 
662
659
  module.exports = TiWebAppManager;
663
- module.exports.applyAuthMethodVisibility = applyAuthMethodVisibility;
660
+ TiWebAppManager.applyAuthMethodVisibility = applyAuthMethodVisibility;
package/bin/web-server.js CHANGED
@@ -98,6 +98,12 @@ const applyWebConfigEnvOverrides = require( "#web-config-env" );
98
98
 
99
99
  const webServerConfig = require( "#web-server-config" );
100
100
 
101
+ /** @import { TiAuthMethod, TiTokenEndpointAuthMethod } from "#auth-manager" */
102
+ /** @import { TiSession } from "#definitions" */
103
+ /** @import User from "#user" */
104
+ /** @import TiWebAppManager from "#web-app-manager" */
105
+ /** @import { ServiceAddress, ServiceConfiguration } from "@ti-engine/core/definitions" */
106
+
101
107
  /**
102
108
  * Default unprotected static-asset route matchers. The path segments are matched with `(?:[^/]+\/)*` rather than
103
109
  * `(?:.+\/)*`: the inner `[^/]+` cannot also consume the "/" delimiter, so the pattern is unambiguous and matches
@@ -643,7 +649,6 @@ class TiWebServer extends ServiceConsumer {
643
649
  * middleware mounting is ever needed.
644
650
  *
645
651
  * @type {Set<string>}
646
- * @private
647
652
  */
648
653
  static #REGISTRABLE_METHODS = new Set( [ "get", "post", "put", "patch", "delete", "options", "head", "all" ] );
649
654
 
@@ -666,7 +671,6 @@ class TiWebServer extends ServiceConsumer {
666
671
  * clear a default entry. Absent from the config file, an explicitly empty array means exactly that.
667
672
  *
668
673
  * @type {Object}
669
- * @private
670
674
  */
671
675
  static #STATIC_CACHE_DEFAULTS = Object.freeze( {
672
676
  maxAge: 0,
@@ -682,7 +686,6 @@ class TiWebServer extends ServiceConsumer {
682
686
  * value any cache treats as meaningful, and the conventional pairing for `immutable`).
683
687
  *
684
688
  * @type {number}
685
- * @private
686
689
  */
687
690
  static #IMMUTABLE_MAX_AGE = 31536000;
688
691
 
@@ -694,7 +697,6 @@ class TiWebServer extends ServiceConsumer {
694
697
  * @static
695
698
  * @param {string} entry
696
699
  * @returns {string|null}
697
- * @private
698
700
  */
699
701
  static #normalizeImmutablePath( entry ) {
700
702
  if ( typeof entry !== "string" || entry.trim() === "" ) {
@@ -715,7 +717,6 @@ class TiWebServer extends ServiceConsumer {
715
717
  * @param {string} rootPath
716
718
  * @param {string} filePath
717
719
  * @returns {string}
718
- * @private
719
720
  */
720
721
  static #toServedPath( rootPath, filePath ) {
721
722
  // Split on the platform separator only: on POSIX a backslash is a legal filename character, not a delimiter.
@@ -881,7 +882,6 @@ class TiWebServer extends ServiceConsumer {
881
882
  * @param {number} port The port to listen on.
882
883
  * @param {string} host The host to listen on.
883
884
  * @returns {Promise<NodeServer>}
884
- * @private
885
885
  */
886
886
  #beginListening( server, port, host ) {
887
887
  return new Promise( ( resolve, reject ) => {
@@ -901,7 +901,6 @@ class TiWebServer extends ServiceConsumer {
901
901
  * @method
902
902
  * @param {NodeServer} server The server instance to stop listening on.
903
903
  * @returns {Promise}
904
- * @private
905
904
  */
906
905
  #endListening( server ) {
907
906
  return new Promise( ( resolve, reject ) => {
@@ -933,5 +932,5 @@ class TiWebServer extends ServiceConsumer {
933
932
 
934
933
  module.exports = TiWebServer;
935
934
  // Exported for unit testing of the ReDoS-hardened matchers; not part of the customization surface.
936
- module.exports.RE_STATIC_UNPROTECTED = RE_STATIC_UNPROTECTED;
937
- module.exports.RE_WELL_KNOWN_UNPROTECTED = RE_WELL_KNOWN_UNPROTECTED;
935
+ TiWebServer.RE_STATIC_UNPROTECTED = RE_STATIC_UNPROTECTED;
936
+ TiWebServer.RE_WELL_KNOWN_UNPROTECTED = RE_WELL_KNOWN_UNPROTECTED;
@@ -19,6 +19,9 @@
19
19
 
20
20
  const exceptions = require( "@ti-engine/core/exceptions" );
21
21
 
22
+ /** @import ConfigService from "#config-service" */
23
+ /** @import { ExpressHandler } from "#web-handlers" */
24
+
22
25
  function sendData( response, data ) {
23
26
  response.set( "Cache-Control", "no-store" );
24
27
  response.set( "Content-Type", "application/json; charset=utf-8" );
@@ -13,6 +13,8 @@ const { randomBytes } = require( "node:crypto" );
13
13
  const openidClient = require( "openid-client" );
14
14
  const User = require( "#user" );
15
15
 
16
+ /** @import { SettingsAuth } from "#web-server" */
17
+
16
18
  /**
17
19
  * Enum for specifying the authentication method.
18
20
  *
@@ -281,7 +283,6 @@ class AuthManager {
281
283
  * unavailable so a sign-in attempt against it is rejected per-request instead of taking down startup.
282
284
  *
283
285
  * @method
284
- * @private
285
286
  */
286
287
  #dropUnconfiguredOpenIDProviders() {
287
288
  const providers = [
@@ -302,7 +303,6 @@ class AuthManager {
302
303
  * @method
303
304
  * @param {SettingsOAuth2Client} [oauth2] The provider's OAuth2 settings.
304
305
  * @returns {boolean}
305
- * @private
306
306
  */
307
307
  #isOpenIDConfigured( oauth2 ) {
308
308
  return !!( oauth2 && typeof oauth2.clientID === "string" && oauth2.clientID.trim() !== "" );
@@ -318,7 +318,6 @@ class AuthManager {
318
318
  * @method
319
319
  * @param {SettingsOAuth2Client} oauth2
320
320
  * @returns {Promise<openidClient.Configuration>}
321
- * @private
322
321
  */
323
322
  #initializeOpenIDClient( oauth2 ) {
324
323
  return new Promise( ( resolve, reject ) => {
@@ -362,7 +361,6 @@ class AuthManager {
362
361
  * @param {string} username
363
362
  * @param {string} password
364
363
  * @returns {Promise}
365
- * @private
366
364
  */
367
365
  #authenticateLocal( username, password ) {
368
366
  return new Promise( ( resolve, reject ) => {
@@ -383,7 +381,6 @@ class AuthManager {
383
381
  * @param {SettingsOAuth2Client} oauth2
384
382
  * @param {openidClient.Configuration} clientConfig
385
383
  * @returns {Promise<Object>}
386
- * @private
387
384
  */
388
385
  #authenticateOpenID( baseUrl, oauth2, clientConfig ) {
389
386
  return new Promise( ( resolve, reject ) => {
@@ -416,7 +413,6 @@ class AuthManager {
416
413
  * @param {Object} oidc
417
414
  * @param {openidClient.Configuration} clientConfig
418
415
  * @returns {Promise<User>}
419
- * @private
420
416
  */
421
417
  #authorizeOpenID( currentUrl, oidc, clientConfig ) {
422
418
  return new Promise( ( resolve, reject ) => {
@@ -439,4 +435,4 @@ class AuthManager {
439
435
  }
440
436
 
441
437
  module.exports = AuthManager;
442
- module.exports.authMethod = authMethodEnum;
438
+ AuthManager.authMethod = authMethodEnum;
@@ -108,7 +108,7 @@ function isAccessAllowed( requiredRoles, userRoles ) {
108
108
  * Responds `401` when unauthenticated (no session user) and `403` when authenticated but lacking the role.
109
109
  *
110
110
  * @param {...(string|number)} roles
111
- * @returns {function(Object, Object, Function): void}
111
+ * @returns {(request: Object, response: Object, next: Function) => void}
112
112
  */
113
113
  function requireRole( ...roles ) {
114
114
  return ( request, response, next ) => {
@@ -128,7 +128,7 @@ function requireRole( ...roles ) {
128
128
  /**
129
129
  * Express middleware that admits only `admin`-role users.
130
130
  *
131
- * @type {function(Object, Object, Function): void}
131
+ * @type {(request: Object, response: Object, next: Function) => void}
132
132
  */
133
133
  const requireAdmin = requireRole( ADMIN_ROLE );
134
134
 
@@ -70,8 +70,8 @@ class ConfigChangeNotifier {
70
70
  * Subscribes a listener to configuration-change events.
71
71
  *
72
72
  * @method
73
- * @param {function(ConfigChangeEvent): void} listener
74
- * @returns {function(): void} An unsubscribe function.
73
+ * @param {(event: ConfigChangeEvent) => void} listener
74
+ * @returns {() => void} An unsubscribe function.
75
75
  * @public
76
76
  */
77
77
  subscribe( listener ) {
@@ -94,5 +94,5 @@ class ConfigChangeNotifier {
94
94
 
95
95
  const instance = new ConfigChangeNotifier();
96
96
  module.exports = ConfigChangeNotifier;
97
- module.exports.instance = instance;
98
- module.exports.CONFIG_CHANGED = CONFIG_CHANGED;
97
+ ConfigChangeNotifier.instance = instance;
98
+ ConfigChangeNotifier.CONFIG_CHANGED = CONFIG_CHANGED;
@@ -45,11 +45,11 @@ const instancePathToDataPath = ( instancePath ) => {
45
45
  * {@link ConfigService#applyEdits} call.
46
46
  *
47
47
  * @typedef {Object} ValidatorContext
48
- * @property {function(string): Promise<*>} getConfig Resolves the *pending* value of `key` when it is part of the
48
+ * @property {(key: string) => Promise<*>} getConfig Resolves the *pending* value of `key` when it is part of the
49
49
  * current edit batch, otherwise its current committed value. Lets a validator check a sibling document's
50
50
  * post-edit state — but calling this for the document being validated itself just returns the same incoming
51
51
  * value already passed as the validator's first argument, not its prior state.
52
- * @property {function(string): Promise<*>} getStoredConfig Always resolves the current committed value of `key`,
52
+ * @property {(key: string) => Promise<*>} getStoredConfig Always resolves the current committed value of `key`,
53
53
  * even when `key` is the document currently under validation. Use this to compare a document against its own
54
54
  * previous state (e.g. detecting an edit that should have bumped a version marker).
55
55
  */
@@ -214,7 +214,6 @@ class ConfigRegistry {
214
214
  * @method
215
215
  * @param {Object} registration
216
216
  * @returns {Function} The compiled (and cached) ajv validate function for the document's schema.
217
- * @private
218
217
  */
219
218
  #schemaValidator( registration ) {
220
219
  if ( !registration.compiled ) {
@@ -229,7 +228,6 @@ class ConfigRegistry {
229
228
  * @method
230
229
  * @param {Object} schema
231
230
  * @returns {Object} A shallow copy without the ajv-6-incompatible Draft-2020-12 `$schema` annotation.
232
- * @private
233
231
  */
234
232
  #stripUnsupportedMeta( schema ) {
235
233
  if ( schema && schema.$schema && String( schema.$schema ).includes( "draft/2020-12" ) ) {
@@ -244,7 +242,6 @@ class ConfigRegistry {
244
242
  * @method
245
243
  * @param {ConfigValidationIssue|string} issue
246
244
  * @returns {ConfigValidationIssue}
247
- * @private
248
245
  */
249
246
  #normalizeIssue( issue ) {
250
247
  if ( typeof issue === "string" ) {
@@ -257,4 +254,4 @@ class ConfigRegistry {
257
254
 
258
255
  const instance = new ConfigRegistry();
259
256
  module.exports = ConfigRegistry;
260
- module.exports.instance = instance;
257
+ ConfigRegistry.instance = instance;
@@ -8,6 +8,10 @@
8
8
 
9
9
  const exceptions = require( "@ti-engine/core/exceptions" );
10
10
 
11
+ /** @import ConfigChangeNotifier from "#config-change-notifier" */
12
+ /** @import ConfigRegistry from "#config-registry" */
13
+ /** @import ConfigStore from "#config-store" */
14
+
11
15
  /**
12
16
  * Orchestrates validated, versioned configuration edits on top of {@link ConfigStore} and {@link ConfigRegistry}.
13
17
  *
@@ -115,8 +119,8 @@ class ConfigService {
115
119
  * @param {string} editorKey
116
120
  * @param {Object} definition
117
121
  * @param {string[]} definition.documents The configKeys this editor spans.
118
- * @param {function(Object): *} definition.compose Maps `{ [configKey]: value }` → a view for the UI.
119
- * @param {function(*, Object): Object<string, Object>} definition.decompose Maps `(editedView, currentDocs)` → the
122
+ * @param {(configs: Object) => *} definition.compose Maps `{ [configKey]: value }` → a view for the UI.
123
+ * @param {(editedView: *, currentDocs: Object) => Object.<string, Object>} definition.decompose Maps `(editedView, currentDocs)` → the
120
124
  * full new values for the documents that changed (`{ [configKey]: newValue }`).
121
125
  * @param {Object} [definition.metadata]
122
126
  * @returns {ConfigService} this (chainable)
@@ -321,8 +325,8 @@ class ConfigService {
321
325
  * Subscribes a listener to `config:changed` events (delegates to the change notifier). Returns an unsubscribe fn.
322
326
  *
323
327
  * @method
324
- * @param {function(Object): void} listener
325
- * @returns {function(): void}
328
+ * @param {(configs: Object) => void} listener
329
+ * @returns {() => void}
326
330
  * @public
327
331
  */
328
332
  onConfigChanged( listener ) {
@@ -335,7 +339,6 @@ class ConfigService {
335
339
  * @method
336
340
  * @param {string[]} keys
337
341
  * @returns {Promise<{docs: Object<string, Object>, versions: Object<string, number>}>}
338
- * @private
339
342
  */
340
343
  #loadDocuments( keys ) {
341
344
  return Promise.all( keys.map( ( key ) => this.#store.getCurrent( key ) ) ).then( ( currents ) => {
@@ -357,4 +360,4 @@ function clone( value ) {
357
360
 
358
361
  const instance = new ConfigService();
359
362
  module.exports = ConfigService;
360
- module.exports.instance = instance;
363
+ ConfigService.instance = instance;
@@ -222,7 +222,6 @@ class ConfigStore {
222
222
  * @method
223
223
  * @param {string} key
224
224
  * @returns {Promise<Object|null>}
225
- * @private
226
225
  */
227
226
  #readJSON( key ) {
228
227
  return cache.instance.getJSON( key ).then( ( result ) => ( Array.isArray( result ) ? ( result[ 0 ] ?? null ) : ( result ?? null ) ) );
@@ -233,7 +232,6 @@ class ConfigStore {
233
232
  * @param {string} key
234
233
  * @param {Object} value
235
234
  * @returns {Promise}
236
- * @private
237
235
  */
238
236
  #writeJSON( key, value ) {
239
237
  return cache.instance.setJSON( key, value );
@@ -243,4 +241,4 @@ class ConfigStore {
243
241
 
244
242
  const instance = new ConfigStore();
245
243
  module.exports = ConfigStore;
246
- module.exports.instance = Object.freeze( instance );
244
+ ConfigStore.instance = Object.freeze( instance );
@@ -6,6 +6,8 @@
6
6
  * You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
7
7
  */
8
8
 
9
+ /** @import { TiLocalizationLanguage } from "@ti-engine/core/localization" */
10
+
9
11
  /**
10
12
  * @callback TiSessionCallback
11
13
  * @param {Error|null} [error]
@@ -20,7 +22,7 @@
20
22
  * @property {Object} [cookie]
21
23
  * @property {Object} [oidc]
22
24
  * @property {string} [csrfToken]
23
- * @property {function(TiSessionCallback): TiSession} regenerate
24
- * @property {function(TiSessionCallback): TiSession} destroy
25
- * @property {function(TiSessionCallback=): TiSession} save
25
+ * @property {(callback: TiSessionCallback) => TiSession} regenerate
26
+ * @property {(callback: TiSessionCallback) => TiSession} destroy
27
+ * @property {(callback?: TiSessionCallback) => TiSession} save
26
28
  */
@@ -12,6 +12,9 @@ const exceptions = require( "@ti-engine/core/exceptions" );
12
12
  const _ = require( "lodash" );
13
13
  const session = require( "express-session" );
14
14
 
15
+ /** @import { SessionData } from "express-session" */
16
+ /** @import { TiException } from "@ti-engine/core/exceptions" */
17
+
15
18
  // The name of the session store in the cache:
16
19
  const sessionStoreName = "ti:web:sessions";
17
20
 
@@ -37,8 +40,8 @@ class SessionStore extends session.Store {
37
40
  *
38
41
  * @method
39
42
  * @param {string} sessionID
40
- * @param {TiSession} session
41
- * @param {function( (Error|TiException|null)= )} callback
43
+ * @param {SessionData} session
44
+ * @param {(error?: Error|TiException|null) => void} callback
42
45
  * @public
43
46
  */
44
47
  set( sessionID, session, callback ) {
@@ -58,7 +61,7 @@ class SessionStore extends session.Store {
58
61
  *
59
62
  * @method
60
63
  * @param {string} sessionID
61
- * @param {function( (Error|TiException|null)=, (TiSession)= )} callback
64
+ * @param {(error?: Error|TiException|null, session?: SessionData|null) => void} callback
62
65
  * @public
63
66
  */
64
67
  get( sessionID, callback ) {
@@ -75,7 +78,7 @@ class SessionStore extends session.Store {
75
78
  *
76
79
  * @method
77
80
  * @param {string} sessionID
78
- * @param {function( (Error|TiException|null)= )} callback
81
+ * @param {(error?: Error|TiException|null) => void} callback
79
82
  * @public
80
83
  */
81
84
  destroy( sessionID, callback ) {
@@ -92,8 +95,8 @@ class SessionStore extends session.Store {
92
95
  *
93
96
  * @method
94
97
  * @param {string} sessionID
95
- * @param {TiSession} session
96
- * @param {function( (Error|TiException|null)= )} callback
98
+ * @param {SessionData} session
99
+ * @param {(error?: Error|TiException|null) => void} callback
97
100
  * @public
98
101
  */
99
102
  touch( sessionID, session, callback ) {
@@ -6,6 +6,8 @@
6
6
  * You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
7
7
  */
8
8
 
9
+ /** @import { TiLocalizationLanguage } from "@ti-engine/core/localization" */
10
+
9
11
  /**
10
12
  * Represents a user in the system.
11
13
  *
@@ -17,8 +17,11 @@ const cache = require( "@ti-engine/core/cache" );
17
17
  const authMethod = require( "#auth-manager" ).authMethod;
18
18
  const authorization = require( "#authorization" );
19
19
 
20
+ /** @import { TiAuthMethod } from "#auth-manager" */
21
+ /** @import TiWebServer from "#web-server" */
22
+
20
23
  /** @typedef {import("express").Request} ExpressRequest */
21
- /** @typedef {import("express").res} ExpressResponse */
24
+ /** @typedef {import("express").Response} ExpressResponse */
22
25
 
23
26
  /**
24
27
  * Express middleware callback.
@@ -26,7 +29,7 @@ const authorization = require( "#authorization" );
26
29
  * @callback ExpressHandler
27
30
  * @param {ExpressRequest} request
28
31
  * @param {ExpressResponse} response
29
- * @param {function( Error | null )} next
32
+ * @param {(error: Error|null) => void} next
30
33
  * @returns {void}
31
34
  */
32
35
 
@@ -37,7 +40,7 @@ const authorization = require( "#authorization" );
37
40
  * @param {Error} error
38
41
  * @param {ExpressRequest} request
39
42
  * @param {ExpressResponse} response
40
- * @param {function( Error | null )} next
43
+ * @param {(error: Error|null) => void} next
41
44
  * @returns {void}
42
45
  */
43
46
 
@@ -154,7 +157,7 @@ let getRequestOrigin = ( request ) => {
154
157
  * @method
155
158
  * @param {ExpressRequest} request
156
159
  * @param {string} redirectTo
157
- * @param {function( TiSession ): TiSession} modifier
160
+ * @param {(session: TiSession) => TiSession} modifier
158
161
  * @returns {Promise<string>}
159
162
  * @private
160
163
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ti-engine/web-framework",
3
- "version": "1.19.1",
3
+ "version": "1.20.1",
4
4
  "description": "A web-framework based on the ti-engine. It provides a customizable ready-to-use web-server microservice and a set of tools for creating web applications. NOTICE: This is still a work in progress and the full architecture, design, and functionality are not available!",
5
5
  "keywords": [
6
6
  "ti-engine",
@@ -15,43 +15,105 @@
15
15
  "author": "Boris Kostadinov <kostadinov.boris@gmail.com>",
16
16
  "license": "GPL-3.0-or-later",
17
17
  "exports": {
18
- "./config-management": "./components/config-service.js",
19
- "./web-application": "./bin/web-app-manager.js",
20
- "./web-server": "./bin/web-server.js"
18
+ "./config-management": {
19
+ "types": "./types/components/config-service.d.ts",
20
+ "default": "./components/config-service.js"
21
+ },
22
+ "./web-application": {
23
+ "types": "./types/bin/web-app-manager.d.ts",
24
+ "default": "./bin/web-app-manager.js"
25
+ },
26
+ "./web-server": {
27
+ "types": "./types/bin/web-server.d.ts",
28
+ "default": "./bin/web-server.js"
29
+ },
30
+ "./definitions": {
31
+ "types": "./types/components/definitions.types.d.ts",
32
+ "default": "./components/definitions.types.js"
33
+ }
21
34
  },
22
35
  "imports": {
23
- "#admin-config-handlers": "./components/admin-config-handlers.js",
24
- "#auth-manager": "./components/auth-manager.js",
25
- "#authorization": "./components/authorization.js",
26
- "#config-change-notifier": "./components/config-change-notifier.js",
27
- "#config-registry": "./components/config-registry.js",
28
- "#config-service": "./components/config-service.js",
29
- "#config-store": "./components/config-store.js",
30
- "#session-store": "./components/session-store.js",
31
- "#user": "./components/user.js",
32
- "#web-app-manager": "./bin/web-app-manager.js",
33
- "#web-config-env": "./components/web-config-env.js",
34
- "#web-handlers": "./components/web-handlers.js",
35
- "#web-server": "./bin/web-server.js",
36
+ "#admin-config-handlers": {
37
+ "types": "./types/components/admin-config-handlers.d.ts",
38
+ "default": "./components/admin-config-handlers.js"
39
+ },
40
+ "#auth-manager": {
41
+ "types": "./types/components/auth-manager.d.ts",
42
+ "default": "./components/auth-manager.js"
43
+ },
44
+ "#authorization": {
45
+ "types": "./types/components/authorization.d.ts",
46
+ "default": "./components/authorization.js"
47
+ },
48
+ "#config-change-notifier": {
49
+ "types": "./types/components/config-change-notifier.d.ts",
50
+ "default": "./components/config-change-notifier.js"
51
+ },
52
+ "#config-registry": {
53
+ "types": "./types/components/config-registry.d.ts",
54
+ "default": "./components/config-registry.js"
55
+ },
56
+ "#config-service": {
57
+ "types": "./types/components/config-service.d.ts",
58
+ "default": "./components/config-service.js"
59
+ },
60
+ "#config-store": {
61
+ "types": "./types/components/config-store.d.ts",
62
+ "default": "./components/config-store.js"
63
+ },
64
+ "#definitions": {
65
+ "types": "./types/components/definitions.types.d.ts",
66
+ "default": "./components/definitions.types.js"
67
+ },
68
+ "#session-store": {
69
+ "types": "./types/components/session-store.d.ts",
70
+ "default": "./components/session-store.js"
71
+ },
72
+ "#user": {
73
+ "types": "./types/components/user.d.ts",
74
+ "default": "./components/user.js"
75
+ },
76
+ "#web-app-manager": {
77
+ "types": "./types/bin/web-app-manager.d.ts",
78
+ "default": "./bin/web-app-manager.js"
79
+ },
80
+ "#web-config-env": {
81
+ "types": "./types/components/web-config-env.d.ts",
82
+ "default": "./components/web-config-env.js"
83
+ },
84
+ "#web-handlers": {
85
+ "types": "./types/components/web-handlers.d.ts",
86
+ "default": "./components/web-handlers.js"
87
+ },
88
+ "#web-server": {
89
+ "types": "./types/bin/web-server.d.ts",
90
+ "default": "./bin/web-server.js"
91
+ },
36
92
  "#web-server-config": "./bin/web-server.json"
37
93
  },
38
94
  "dependencies": {
39
- "@ti-engine/core": "*",
40
95
  "@alpinejs/csp": "^3.15.12",
41
- "htmx.org": "^2.0.10",
96
+ "@ti-engine/core": "*",
97
+ "@types/express": "^5.0.6",
98
+ "@types/express-session": "^1.18.2",
99
+ "@types/node": "^24.10.1",
42
100
  "ajv": "^8.20.0",
43
101
  "cookie-parser": "^1.4.7",
44
102
  "express": "^5.2.1",
45
103
  "express-session": "^1.19.0",
46
104
  "helmet": "^8.3.0",
105
+ "htmx.org": "^2.0.10",
47
106
  "lodash": "^4.18.1",
48
107
  "openid-client": "^6.8.4"
49
108
  },
50
- "devDependencies": {},
109
+ "devDependencies": {
110
+ "typescript": "^7.0.2"
111
+ },
51
112
  "files": [
52
113
  "bin/",
53
114
  "!bin/tls/**/*",
54
115
  "components/",
116
+ "types/",
55
117
  ".env",
56
118
  "package.json",
57
119
  "README.md",
@@ -71,6 +133,7 @@
71
133
  },
72
134
  "scripts": {
73
135
  "postinstall": "node ./bin/build/post-install.js",
74
- "test": "node --test test/*.test.js"
136
+ "test": "node --test test/*.test.js",
137
+ "build:types": "tsc -p tsconfig.types.json"
75
138
  }
76
139
  }