From c17d6dac3595ab0f50d5bdfa4badff4328274cc8 Mon Sep 17 00:00:00 2001 From: Juergen Kunz Date: Tue, 2 Dec 2025 20:26:34 +0000 Subject: [PATCH] feat: Refactor TypedServer to use SmartServe and introduce new request handlers - Removed legacy servertools and Express dependencies in favor of SmartServe. - Introduced DevToolsHandler and TypedRequestHandler for handling specific routes. - Added support for custom route registration with regex parsing. - Implemented sitemap and feed handling with dedicated helper classes. - Enhanced HTML response handling with reload script injection. - Updated UtilityServiceServer and UtilityWebsiteServer to utilize new TypedServer API. - Removed deprecated compression options and Express-based route handling. - Added comprehensive request handling for various endpoints including robots.txt, manifest.json, and sitemap. - Improved error handling and response formatting across the server. --- package.json | 3 +- pnpm-lock.yaml | 680 +++++++-------------- ts/classes.typedserver.ts | 585 ++++++++++++++---- ts/controllers/controller.devtools.ts | 53 ++ ts/controllers/controller.typedrequest.ts | 43 ++ ts/controllers/index.ts | 2 + ts/index.ts | 6 +- ts/plugins.ts | 13 +- ts/servertools/index.ts | 30 +- ts/servertools/tools.serviceworker.ts | 101 +-- ts/utilityservers/classes.serviceserver.ts | 12 +- ts/utilityservers/classes.websiteserver.ts | 77 +-- tsconfig.json | 2 - 13 files changed, 902 insertions(+), 705 deletions(-) create mode 100644 ts/controllers/controller.devtools.ts create mode 100644 ts/controllers/controller.typedrequest.ts create mode 100644 ts/controllers/index.ts diff --git a/package.json b/package.json index dbb95f3..348d98a 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "dependencies": { "@api.global/typedrequest": "^3.1.10", "@api.global/typedrequest-interfaces": "^3.0.19", - "@api.global/typedsocket": "^3.0.1", + "@api.global/typedsocket": "^3.1.1", "@cloudflare/workers-types": "^4.20251202.0", "@design.estate/dees-comms": "^1.0.27", "@push.rocks/lik": "^6.2.2", @@ -82,6 +82,7 @@ "@push.rocks/smartpromise": "^4.2.3", "@push.rocks/smartrequest": "^5.0.1", "@push.rocks/smartrx": "^3.0.10", + "@push.rocks/smartserve": "^1.1.0", "@push.rocks/smartsitemap": "^2.0.4", "@push.rocks/smartstream": "^3.2.5", "@push.rocks/smarttime": "^4.1.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b99a241..3ba2dff 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,8 +15,8 @@ importers: specifier: ^3.0.19 version: 3.0.19 '@api.global/typedsocket': - specifier: ^3.0.1 - version: 3.0.1 + specifier: ^3.1.1 + version: 3.1.1(@push.rocks/smartserve@1.1.0) '@cloudflare/workers-types': specifier: ^4.20251202.0 version: 4.20251202.0 @@ -80,6 +80,9 @@ importers: '@push.rocks/smartrx': specifier: ^3.0.10 version: 3.0.10 + '@push.rocks/smartserve': + specifier: ^1.1.0 + version: 1.1.0 '@push.rocks/smartsitemap': specifier: ^2.0.4 version: 2.0.4 @@ -134,7 +137,7 @@ importers: version: 2.0.0 '@git.zone/tstest': specifier: ^3.1.3 - version: 3.1.3(@aws-sdk/credential-providers@3.787.0)(socks@2.8.7)(typescript@5.9.3) + version: 3.1.3(@aws-sdk/credential-providers@3.787.0)(@push.rocks/smartserve@1.1.0)(socks@2.8.7)(typescript@5.9.3) '@types/node': specifier: ^24.10.1 version: 24.10.1 @@ -150,14 +153,16 @@ packages: '@api.global/typedrequest@3.1.10': resolution: {integrity: sha512-EiCp44XVcMjBvEs4oM1nMUaeY4ySU0Pzt3+mDwVG5DNP6EV87Nwancbr2jKScvaFNel9eeDgGtgEnFBKjOnApA==} - '@api.global/typedserver@3.0.36': - resolution: {integrity: sha512-j/Q7iGj19I3b+xZCNM5cx6+EHHf9cGP98n7JMd35qyQADACeYSkatqZEUOKV5+zV6cKxpLzt5e6bbq+/P2CU3g==} - '@api.global/typedserver@3.0.80': resolution: {integrity: sha512-dcp0oXsjBL+XdFg1wUUP08uJQid5bQ0Yv3V3Y3lnI2QCbat0FU+Tsb0TZRnZ4+P150Vj/ITBqJUgDzFsF34grA==} - '@api.global/typedsocket@3.0.1': - resolution: {integrity: sha512-xojiAVNXtHoxkpBo8U2HHJG8FrVXXuLvDNndSHXwx4C9VslUwDn5zSCI+PdBl8iAg+ZuBmKjqkpZZ9sL6DC5yQ==} + '@api.global/typedsocket@3.1.1': + resolution: {integrity: sha512-Wkz3NlhmfdZMKqXXI2c2dMtGGmSmhdOegZiziL+9b2mqPYdc7Gd8AZRdEOKvbSoIvc9G22/5BEadIWHrfq66TA==} + peerDependencies: + '@push.rocks/smartserve': '>=1.0.0' + peerDependenciesMeta: + '@push.rocks/smartserve': + optional: true '@aws-crypto/crc32@5.2.0': resolution: {integrity: sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==} @@ -1146,9 +1151,6 @@ packages: '@push.rocks/smartmatch@2.0.0': resolution: {integrity: sha512-MBzP++1yNIBeox71X6VxpIgZ8m4bXnJpZJ4nWVH6IWpmO38MXTu4X0QF8tQnyT4LFcwvc9iiWaD15cstHa7Mmw==} - '@push.rocks/smartmime@1.0.6': - resolution: {integrity: sha512-PHd+I4UcsnOATNg8wjDsSAmmJ4CwQFrQCNzd0HSJMs4ZpiK3Ya91almd6GLpDPU370U4HFh4FaPF4eEAI6vkJQ==} - '@push.rocks/smartmime@2.0.4': resolution: {integrity: sha512-mG6lRBLr5nF+GLZmgCcdjhdDsmTtJWBFZDCa1eJ8Au9TvUzbPW0fY5aqJBb3UwfyZzH6St8Th9cJSXjagOQkYA==} @@ -1209,14 +1211,17 @@ packages: '@push.rocks/smarts3@3.0.3': resolution: {integrity: sha512-Y9nXMwurthJ9Z7yi0RwjhPFUC58aY8Mhia8kFo6Xj1tBM4LE8Oxg/ydejF7otHqQGr3QyqV5C4YrDEG17rUuzg==} + '@push.rocks/smartserve@1.1.0': + resolution: {integrity: sha512-w9cSRw+ia5oWXcuK1QCBCEUUPsAJ2zDeOv1gHDytL+2e1oLlRAEp35uhWFHGPsTCZiwgVZhy3ZORWemJTODQlQ==} + '@push.rocks/smartshell@3.3.0': resolution: {integrity: sha512-m0w618H6YBs+vXGz1CgS4nPi5CUAnqRtckcS9/koGwfcIx1IpjqmiP47BoCTbdgcv0IPUxQVBG1IXTHPuZ8Z5g==} '@push.rocks/smartsitemap@2.0.4': resolution: {integrity: sha512-76dYWG/o/EjV4vYCK7ZKM35T9xgrI+oHEiiIE6E2MDaFIU6QnSfciTfbscH5nc0vxx8Ah+I0HPEJO94BM2S39w==} - '@push.rocks/smartsocket@2.0.27': - resolution: {integrity: sha512-planM3EkBvx/+guLLWHLBNnNp4mcWDwp1k9G0It0ul7IhdaBQsSWzKSQJxym3Bx2dypgA2UIeT3/hRvSa5Nqdw==} + '@push.rocks/smartsocket@2.1.0': + resolution: {integrity: sha512-etOGyfiDFQz/1WJnD3jFL2N7ykujTjiudAz6qZTz82xE5oabKuKX+Cn8SdM9dOwzyWmBUKbUdll8QhovAXjn+g==} '@push.rocks/smartspawn@3.0.3': resolution: {integrity: sha512-DyrGPV69wwOiJgKkyruk5hS3UEGZ99xFAqBE9O2nM8VXCRLbbty3xt1Ug5Z092ZZmJYaaGMSnMw3ijyZJFCT0Q==} @@ -1242,9 +1247,6 @@ packages: '@push.rocks/smartunique@3.0.9': resolution: {integrity: sha512-q6DYQgT7/dqdWi9HusvtWCjdsFzLFXY9LTtaZV6IYNJt6teZOonoygxTdNt9XLn6niBSbLYrHSKvJNTRH/uK+g==} - '@push.rocks/smarturl@3.0.7': - resolution: {integrity: sha512-nx4EWjQD9JeO7QVbOsxd1PFeDQYoSQOOOYCZ+r7QWXHLJG52iYzgvJDCQyX6p705HDkYMJWozW2ZzhR22qLKbw==} - '@push.rocks/smarturl@3.1.0': resolution: {integrity: sha512-ij73Q4GERojdPSHxAvYKvspimcpAJC6GGQCWsC4b+1sAiOSByjfmkUHK8yiEEOPRU9AeGuyaIVqK6ZzKLEZ3vA==} @@ -1491,6 +1493,10 @@ packages: resolution: {integrity: sha512-6gnIz3h+PEPQGDj8MnRSjDvKBah042jEoPgjFGJ4iJLBE78L4lY/n98x14XyPF4u3lN179Ub/ZKFY5za9GeLQw==} engines: {node: '>=18.0.0'} + '@smithy/core@3.18.6': + resolution: {integrity: sha512-8Q/ugWqfDUEU1Exw71+DoOzlONJ2Cn9QA8VeeDzLLjzO/qruh9UKFzbszy4jXcIYgGofxYiT0t1TT6+CT/GupQ==} + engines: {node: '>=18.0.0'} + '@smithy/credential-provider-imds@4.2.5': resolution: {integrity: sha512-BZwotjoZWn9+36nimwm/OLIcVe+KYRwzMjfhd4QT7QxPm9WY0HiOV8t/Wlh+HVUif0SBVV7ksq8//hPaBC/okQ==} engines: {node: '>=18.0.0'} @@ -1555,10 +1561,18 @@ packages: resolution: {integrity: sha512-9pAX/H+VQPzNbouhDhkW723igBMLgrI8OtX+++M7iKJgg/zY/Ig3i1e6seCcx22FWhE6Q/S61BRdi2wXBORT+A==} engines: {node: '>=18.0.0'} + '@smithy/middleware-endpoint@4.3.13': + resolution: {integrity: sha512-X4za1qCdyx1hEVVXuAWlZuK6wzLDv1uw1OY9VtaYy1lULl661+frY7FeuHdYdl7qAARUxH2yvNExU2/SmRFfcg==} + engines: {node: '>=18.0.0'} + '@smithy/middleware-retry@4.4.12': resolution: {integrity: sha512-S4kWNKFowYd0lID7/DBqWHOQxmxlsf0jBaos9chQZUWTVOjSW1Ogyh8/ib5tM+agFDJ/TCxuCTvrnlc+9cIBcQ==} engines: {node: '>=18.0.0'} + '@smithy/middleware-retry@4.4.13': + resolution: {integrity: sha512-RzIDF9OrSviXX7MQeKOm8r/372KTyY8Jmp6HNKOOYlrguHADuM3ED/f4aCyNhZZFLG55lv5beBin7nL0Nzy1Dw==} + engines: {node: '>=18.0.0'} + '@smithy/middleware-serde@4.2.6': resolution: {integrity: sha512-VkLoE/z7e2g8pirwisLz8XJWedUSY8my/qrp81VmAdyrhi94T+riBfwP+AOEEFR9rFTSonC/5D2eWNmFabHyGQ==} engines: {node: '>=18.0.0'} @@ -1607,6 +1621,10 @@ packages: resolution: {integrity: sha512-8xgq3LgKDEFoIrLWBho/oYKyWByw9/corz7vuh1upv7ZBm0ZMjGYBhbn6v643WoIqA9UTcx5A5htEp/YatUwMA==} engines: {node: '>=18.0.0'} + '@smithy/smithy-client@4.9.9': + resolution: {integrity: sha512-SUnZJMMo5yCmgjopJbiNeo1vlr8KvdnEfIHV9rlD77QuOGdRotIVBcOrBuMr+sI9zrnhtDtLP054bZVbpZpiQA==} + engines: {node: '>=18.0.0'} + '@smithy/types@4.9.0': resolution: {integrity: sha512-MvUbdnXDTwykR8cB1WZvNNwqoWVaTRA0RLlLmf/cIFNMM2cKWz01X4Ly6SMC4Kks30r8tT3Cty0jmeWfiuyHTA==} engines: {node: '>=18.0.0'} @@ -1643,10 +1661,18 @@ packages: resolution: {integrity: sha512-yHv+r6wSQXEXTPVCIQTNmXVWs7ekBTpMVErjqZoWkYN75HIFN5y9+/+sYOejfAuvxWGvgzgxbTHa/oz61YTbKw==} engines: {node: '>=18.0.0'} + '@smithy/util-defaults-mode-browser@4.3.12': + resolution: {integrity: sha512-TKc6FnOxFULKxLgTNHYjcFqdOYzXVPFFVm5JhI30F3RdhT7nYOtOsjgaOwfDRmA/3U66O9KaBQ3UHoXwayRhAg==} + engines: {node: '>=18.0.0'} + '@smithy/util-defaults-mode-node@4.2.14': resolution: {integrity: sha512-ljZN3iRvaJUgulfvobIuG97q1iUuCMrvXAlkZ4msY+ZuVHQHDIqn7FKZCEj+bx8omz6kF5yQXms/xhzjIO5XiA==} engines: {node: '>=18.0.0'} + '@smithy/util-defaults-mode-node@4.2.15': + resolution: {integrity: sha512-94NqfQVo+vGc5gsQ9SROZqOvBkGNMQu6pjXbnn8aQvBUhc31kx49gxlkBEqgmaZQHUUfdRUin5gK/HlHKmbAwg==} + engines: {node: '>=18.0.0'} + '@smithy/util-endpoints@3.2.5': resolution: {integrity: sha512-3O63AAWu2cSNQZp+ayl9I3NapW1p1rR5mlVHcF6hAB1dPZUQFfRPYtplWX/3xrzWthPGj5FqB12taJJCfH6s8A==} engines: {node: '>=18.0.0'} @@ -1731,11 +1757,8 @@ packages: '@types/connect@3.4.38': resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} - '@types/cookie@0.4.1': - resolution: {integrity: sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==} - - '@types/cors@2.8.17': - resolution: {integrity: sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==} + '@types/cors@2.8.19': + resolution: {integrity: sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==} '@types/debug@4.1.12': resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} @@ -1746,15 +1769,9 @@ packages: '@types/elliptic@6.4.18': resolution: {integrity: sha512-UseG6H5vjRiNpQvrhy4VF/JXdA3V/Fp5amvveaL+fs28BZ6xIKJBPnUPRlEaZpysD9MbpfaLi8lbl7PGUAkpWw==} - '@types/express-serve-static-core@4.19.7': - resolution: {integrity: sha512-FvPtiIf1LfhzsaIXhv/PHan/2FeQBbtBDtfX2QfvPxdUelMDEckK08SM6nqo1MIZY3RUlfA+HV8+hFUSio78qg==} - '@types/express-serve-static-core@5.1.0': resolution: {integrity: sha512-jnHMsrd0Mwa9Cf4IdOzbz543y4XJepXrbia2T4b6+spXC2We3t1y6K44D3mR8XMFSXMCf3/l7rCgddfx7UNVBA==} - '@types/express@4.17.25': - resolution: {integrity: sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==} - '@types/express@5.0.6': resolution: {integrity: sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA==} @@ -1788,9 +1805,6 @@ packages: '@types/mime-types@2.1.4': resolution: {integrity: sha512-lfU4b34HOri+kAY5UheuFMWPDOI+OPceBSHZKp69gEyTL/mmJ4cnU6Y/rlme3UL3GyOn6Y42hyIEw0/q8sWx5w==} - '@types/mime@1.3.5': - resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} - '@types/minimatch@5.1.2': resolution: {integrity: sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==} @@ -1809,9 +1823,6 @@ packages: '@types/qs@6.14.0': resolution: {integrity: sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==} - '@types/qs@6.9.15': - resolution: {integrity: sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==} - '@types/randomatic@3.1.5': resolution: {integrity: sha512-VCwCTw6qh1pRRw+5rNTAwqPmf6A+hdrkdM7dBpZVmhl7g+em3ONXlYK/bWPVKqVGMWgP0d1bog8Vc/X6zRwRRQ==} @@ -1824,15 +1835,9 @@ packages: '@types/semver@7.7.1': resolution: {integrity: sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==} - '@types/send@0.17.6': - resolution: {integrity: sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==} - '@types/send@1.2.1': resolution: {integrity: sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==} - '@types/serve-static@1.15.10': - resolution: {integrity: sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==} - '@types/serve-static@2.2.0': resolution: {integrity: sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ==} @@ -1924,9 +1929,6 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - array-flatten@1.1.1: - resolution: {integrity: sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=} - asn1js@3.0.6: resolution: {integrity: sha512-UOCGPYbl0tv8+006qks/dTgV9ajs97X2p0FAbyS2iyCRrmLSRolDaHdp+v/CLgnzHc3fVB+CwYiUmei7ndFcgA==} engines: {node: '>=12.0.0'} @@ -2010,10 +2012,6 @@ packages: bn.js@4.12.2: resolution: {integrity: sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==} - body-parser@1.20.3: - resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - body-parser@2.2.1: resolution: {integrity: sha512-nfDwkulwiZYQIGwxdy0RUmowMhKcFVcYXUU7m4QlKYim1rUtg83xm2yjZ40QjDuc291AJjjeSc9b++AWHSgSHw==} engines: {node: '>=18'} @@ -2021,6 +2019,9 @@ packages: bowser@2.12.1: resolution: {integrity: sha512-z4rE2Gxh7tvshQ4hluIT7XcFrgLIQaw9X3A+kTTRdovCz5PMukm/0QC/BKSYPj3omF5Qfypn9O/c5kgpmvYUCw==} + bowser@2.13.1: + resolution: {integrity: sha512-OHawaAbjwx6rqICCKgSG0SAnT05bzd7ppyKLVUITZpANBaaMFBAsaNkto3LoQ31tyFP5kNujE8Cdx85G9VzOkw==} + brace-expansion@1.1.12: resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} @@ -2144,10 +2145,6 @@ packages: config-chain@1.1.13: resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} - content-disposition@0.5.4: - resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} - engines: {node: '>= 0.6'} - content-disposition@1.0.0: resolution: {integrity: sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==} engines: {node: '>= 0.6'} @@ -2156,21 +2153,10 @@ packages: resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} engines: {node: '>= 0.6'} - cookie-signature@1.0.6: - resolution: {integrity: sha1-4wOogrNCzD7oylE6eZmXNNqzriw=} - cookie-signature@1.2.2: resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} engines: {node: '>=6.6.0'} - cookie@0.4.2: - resolution: {integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==} - engines: {node: '>= 0.6'} - - cookie@0.7.1: - resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} - engines: {node: '>= 0.6'} - cookie@0.7.2: resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} engines: {node: '>= 0.6'} @@ -2210,16 +2196,8 @@ packages: dayjs@1.11.13: resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} - debug@2.6.9: - resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - debug@4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' @@ -2279,10 +2257,6 @@ packages: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} - destroy@1.2.0: - resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - devlop@1.1.0: resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} @@ -2312,10 +2286,6 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - encodeurl@1.0.2: - resolution: {integrity: sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=} - engines: {node: '>= 0.8'} - encodeurl@2.0.0: resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} engines: {node: '>= 0.8'} @@ -2323,15 +2293,15 @@ packages: end-of-stream@1.4.5: resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} - engine.io-client@6.5.3: - resolution: {integrity: sha512-9Z0qLB0NIisTRt1DZ/8U2k12RJn8yls/nXMZLn+/N8hANT3TcYjKFKcwbw5zFQiN4NTde3TSY9zb79e1ij6j9Q==} + engine.io-client@6.6.3: + resolution: {integrity: sha512-T0iLjnyNWahNyv/lcjS2y4oE358tVS/SYQNxYXGAJ9/GLgH4VCvOQ/mhTjqU88mLZCQgiG8RIegFHYCdVC+j5w==} - engine.io-parser@5.2.2: - resolution: {integrity: sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw==} + engine.io-parser@5.2.3: + resolution: {integrity: sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==} engines: {node: '>=10.0.0'} - engine.io@6.5.4: - resolution: {integrity: sha512-KdVSDKhVKyOi+r5uEabrDLZw2qXStVvCsEB/LN3mw4WFi6Gx50jTyuxYVCwAAC0U46FdnzP/ScKRBTXb/NiEOg==} + engine.io@6.6.4: + resolution: {integrity: sha512-ZCkIjSYNDyGn0R6ewHDtXgns/Zre/NT6Agvq1/WobF7JXgFff4SeDroKiCO3fNJreU9YG429Sc81o4w5ok/W5g==} engines: {node: '>=10.2.0'} entities@4.5.0: @@ -2422,10 +2392,6 @@ packages: resolution: {integrity: sha1-AbK0mK5v0uQRUrIrV6Phc3c69n4=} engines: {node: '>=0.2.2'} - express@4.21.2: - resolution: {integrity: sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==} - engines: {node: '>= 0.10.0'} - express@5.2.1: resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==} engines: {node: '>= 18'} @@ -2492,10 +2458,6 @@ packages: resolution: {integrity: sha512-ifJXo8zUqbQ/bLbl9sFoqHNTNWbnPY1COImFfM6CCy7z+E+jC1eY9YfOKkx0fckIg+VljAy2/87T61fp0+eEkg==} engines: {node: '>=20'} - finalhandler@1.3.1: - resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==} - engines: {node: '>= 0.8'} - finalhandler@2.1.0: resolution: {integrity: sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==} engines: {node: '>= 0.8'} @@ -2545,10 +2507,6 @@ packages: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} - fresh@0.5.2: - resolution: {integrity: sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=} - engines: {node: '>= 0.6'} - fresh@2.0.0: resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} engines: {node: '>= 0.8'} @@ -2697,10 +2655,6 @@ packages: humanize-ms@1.2.1: resolution: {integrity: sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=} - iconv-lite@0.4.24: - resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} - engines: {node: '>=0.10.0'} - iconv-lite@0.7.0: resolution: {integrity: sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==} engines: {node: '>=0.10.0'} @@ -2967,10 +2921,6 @@ packages: mdast-util-to-string@4.0.0: resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} - media-typer@0.3.0: - resolution: {integrity: sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=} - engines: {node: '>= 0.6'} - media-typer@1.1.0: resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} engines: {node: '>= 0.8'} @@ -2978,17 +2928,10 @@ packages: memory-pager@1.5.0: resolution: {integrity: sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==} - merge-descriptors@1.0.3: - resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} - merge-descriptors@2.0.0: resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} engines: {node: '>=18'} - methods@1.1.2: - resolution: {integrity: sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=} - engines: {node: '>= 0.6'} - micromark-core-commonmark@2.0.2: resolution: {integrity: sha512-FKjQKbxd1cibWMM1P9N+H8TwlgGgSkWZMmfuVucLCHaYqeSvJ0hFeHsIa65pA2nYbes0f8LDHPMrd9X7Ujxg9w==} @@ -3092,11 +3035,6 @@ packages: resolution: {integrity: sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==} engines: {node: '>= 0.6'} - mime@1.6.0: - resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} - engines: {node: '>=4'} - hasBin: true - mime@4.0.6: resolution: {integrity: sha512-4rGt7rvQHBbaSOF9POGkk1ocRP16Md1x36Xma8sz8h8/vfCUI2OtEIeCqe4Ofes853x4xDoPiFLIT47J5fI/7A==} engines: {node: '>=16'} @@ -3179,12 +3117,6 @@ packages: socks: optional: true - ms@2.0.0: - resolution: {integrity: sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=} - - ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -3335,9 +3267,6 @@ packages: resolution: {integrity: sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==} engines: {node: 20 || >=22} - path-to-regexp@0.1.12: - resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==} - path-to-regexp@8.2.0: resolution: {integrity: sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==} engines: {node: '>=16'} @@ -3427,10 +3356,6 @@ packages: resolution: {integrity: sha512-KTqnxsgGiQ6ZAzZCVlJH5eOjSnvlyEgx1m8bkRJfOhmGRqfo5KLvmAlACQkrjEtOQ4B7wF9TdSLIs9O90MX9xA==} engines: {node: '>=16.0.0'} - qs@6.13.0: - resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} - engines: {node: '>=0.6'} - qs@6.14.0: resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} engines: {node: '>=0.6'} @@ -3447,10 +3372,6 @@ packages: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} - raw-body@2.5.2: - resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} - engines: {node: '>= 0.8'} - raw-body@3.0.2: resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} engines: {node: '>= 0.10'} @@ -3553,18 +3474,10 @@ packages: engines: {node: '>=10'} hasBin: true - send@0.19.0: - resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==} - engines: {node: '>= 0.8.0'} - send@1.2.0: resolution: {integrity: sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==} engines: {node: '>= 18'} - serve-static@1.16.2: - resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==} - engines: {node: '>= 0.8.0'} - serve-static@2.2.0: resolution: {integrity: sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==} engines: {node: '>= 18'} @@ -3611,19 +3524,19 @@ packages: resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} - socket.io-adapter@2.5.4: - resolution: {integrity: sha512-wDNHGXGewWAjQPt3pyeYBtpWSq9cLE5UW1ZUPL/2eGK9jtse/FpXib7epSTsz0Q0m+6sg6Y4KtcFTlah1bdOVg==} + socket.io-adapter@2.5.5: + resolution: {integrity: sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==} - socket.io-client@4.7.5: - resolution: {integrity: sha512-sJ/tqHOCe7Z50JCBCXrsY3I2k03iOiUe+tj1OmKeD2lXPiGH/RUCdTZFoqVyN7l1MnpIzPrGtLcijffmeouNlQ==} + socket.io-client@4.8.1: + resolution: {integrity: sha512-hJVXfu3E28NmzGk8o1sHhN3om52tRvwYeidbj7xKy2eIIse5IoKX3USlS6Tqt3BHAtflLIkCQBkzVrEEfWUyYQ==} engines: {node: '>=10.0.0'} socket.io-parser@4.2.4: resolution: {integrity: sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==} engines: {node: '>=10.0.0'} - socket.io@4.7.5: - resolution: {integrity: sha512-DmeAkF6cwM9jSfmp6Dr/5/mfMwb5Z5qRrSXLpo3Fq5SqyU8CMF15jIN4ZhfSwu35ksM1qmHZDQ/DK5XTccSTvA==} + socket.io@4.8.1: + resolution: {integrity: sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg==} engines: {node: '>=10.2.0'} socks-proxy-agent@8.0.5: @@ -3798,10 +3711,6 @@ packages: resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} engines: {node: '>=16'} - type-is@1.6.18: - resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} - engines: {node: '>= 0.6'} - type-is@2.0.1: resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} engines: {node: '>= 0.6'} @@ -3868,10 +3777,6 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=} - utils-merge@1.0.1: - resolution: {integrity: sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=} - engines: {node: '>= 0.4.0'} - uuid@9.0.1: resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} hasBin: true @@ -3922,12 +3827,12 @@ packages: wrappy@1.0.2: resolution: {integrity: sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=} - ws@8.11.0: - resolution: {integrity: sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==} + ws@8.17.1: + resolution: {integrity: sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 - utf-8-validate: ^5.0.2 + utf-8-validate: '>=5.0.2' peerDependenciesMeta: bufferutil: optional: true @@ -3946,8 +3851,8 @@ packages: utf-8-validate: optional: true - xmlhttprequest-ssl@2.0.0: - resolution: {integrity: sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==} + xmlhttprequest-ssl@2.1.2: + resolution: {integrity: sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==} engines: {node: '>=0.4.0'} y18n@5.0.8: @@ -4002,58 +3907,11 @@ snapshots: '@push.rocks/webrequest': 3.0.37 '@push.rocks/webstream': 1.0.10 - '@api.global/typedserver@3.0.36': + '@api.global/typedserver@3.0.80(@push.rocks/smartserve@1.1.0)': dependencies: '@api.global/typedrequest': 3.1.10 '@api.global/typedrequest-interfaces': 3.0.19 - '@api.global/typedsocket': 3.0.1 - '@cloudflare/workers-types': 4.20251202.0 - '@design.estate/dees-comms': 1.0.27 - '@push.rocks/lik': 6.2.2 - '@push.rocks/smartchok': 1.1.1 - '@push.rocks/smartdelay': 3.0.5 - '@push.rocks/smartenv': 5.0.13 - '@push.rocks/smartfeed': 1.4.0 - '@push.rocks/smartfile': 11.2.7 - '@push.rocks/smartjson': 5.2.0 - '@push.rocks/smartlog': 3.1.10 - '@push.rocks/smartlog-destination-devtools': 1.0.12 - '@push.rocks/smartlog-interfaces': 3.0.2 - '@push.rocks/smartmanifest': 2.0.2 - '@push.rocks/smartmatch': 2.0.0 - '@push.rocks/smartmime': 1.0.6 - '@push.rocks/smartntml': 2.0.8 - '@push.rocks/smartopen': 2.0.0 - '@push.rocks/smartpath': 5.1.0 - '@push.rocks/smartpromise': 4.2.3 - '@push.rocks/smartrequest': 2.1.0 - '@push.rocks/smartrx': 3.0.10 - '@push.rocks/smartsitemap': 2.0.4 - '@push.rocks/smartstream': 3.2.5 - '@push.rocks/smarttime': 4.1.1 - '@push.rocks/taskbuffer': 3.4.0 - '@push.rocks/webrequest': 3.0.37 - '@push.rocks/webstore': 2.0.20 - '@tsclass/tsclass': 4.4.4 - '@types/express': 4.17.25 - body-parser: 1.20.3 - cors: 2.8.5 - express: 4.21.2 - express-force-ssl: 0.3.2 - lit: 3.3.1 - transitivePeerDependencies: - - '@nuxt/kit' - - bufferutil - - react - - supports-color - - utf-8-validate - - vue - - '@api.global/typedserver@3.0.80': - dependencies: - '@api.global/typedrequest': 3.1.10 - '@api.global/typedrequest-interfaces': 3.0.19 - '@api.global/typedsocket': 3.0.1 + '@api.global/typedsocket': 3.1.1(@push.rocks/smartserve@1.1.0) '@cloudflare/workers-types': 4.20251202.0 '@design.estate/dees-comms': 1.0.27 '@push.rocks/lik': 6.2.2 @@ -4090,22 +3948,23 @@ snapshots: lit: 3.3.1 transitivePeerDependencies: - '@nuxt/kit' - - bufferutil + - '@push.rocks/smartserve' - react - supports-color - - utf-8-validate - vue - '@api.global/typedsocket@3.0.1': + '@api.global/typedsocket@3.1.1(@push.rocks/smartserve@1.1.0)': dependencies: '@api.global/typedrequest': 3.1.10 '@api.global/typedrequest-interfaces': 3.0.19 '@push.rocks/isohash': 2.0.1 '@push.rocks/smartjson': 5.2.0 '@push.rocks/smartrx': 3.0.10 - '@push.rocks/smartsocket': 2.0.27 - '@push.rocks/smartstring': 4.0.15 - '@push.rocks/smarturl': 3.0.7 + '@push.rocks/smartsocket': 2.1.0(@push.rocks/smartserve@1.1.0) + '@push.rocks/smartstring': 4.1.0 + '@push.rocks/smarturl': 3.1.0 + optionalDependencies: + '@push.rocks/smartserve': 1.1.0 transitivePeerDependencies: - '@nuxt/kit' - bufferutil @@ -4177,26 +4036,26 @@ snapshots: '@aws-sdk/util-user-agent-browser': 3.775.0 '@aws-sdk/util-user-agent-node': 3.787.0 '@smithy/config-resolver': 4.4.3 - '@smithy/core': 3.18.5 + '@smithy/core': 3.18.6 '@smithy/fetch-http-handler': 5.3.6 '@smithy/hash-node': 4.2.5 '@smithy/invalid-dependency': 4.2.5 '@smithy/middleware-content-length': 4.2.5 - '@smithy/middleware-endpoint': 4.3.12 - '@smithy/middleware-retry': 4.4.12 + '@smithy/middleware-endpoint': 4.3.13 + '@smithy/middleware-retry': 4.4.13 '@smithy/middleware-serde': 4.2.6 '@smithy/middleware-stack': 4.2.5 '@smithy/node-config-provider': 4.3.5 '@smithy/node-http-handler': 4.4.5 '@smithy/protocol-http': 5.3.5 - '@smithy/smithy-client': 4.9.8 + '@smithy/smithy-client': 4.9.9 '@smithy/types': 4.9.0 '@smithy/url-parser': 4.2.5 '@smithy/util-base64': 4.3.0 '@smithy/util-body-length-browser': 4.2.0 '@smithy/util-body-length-node': 4.2.1 - '@smithy/util-defaults-mode-browser': 4.3.11 - '@smithy/util-defaults-mode-node': 4.2.14 + '@smithy/util-defaults-mode-browser': 4.3.12 + '@smithy/util-defaults-mode-node': 4.2.15 '@smithy/util-endpoints': 3.2.5 '@smithy/util-middleware': 4.2.5 '@smithy/util-retry': 4.2.5 @@ -4341,26 +4200,26 @@ snapshots: '@aws-sdk/util-user-agent-browser': 3.775.0 '@aws-sdk/util-user-agent-node': 3.787.0 '@smithy/config-resolver': 4.4.3 - '@smithy/core': 3.18.5 + '@smithy/core': 3.18.6 '@smithy/fetch-http-handler': 5.3.6 '@smithy/hash-node': 4.2.5 '@smithy/invalid-dependency': 4.2.5 '@smithy/middleware-content-length': 4.2.5 - '@smithy/middleware-endpoint': 4.3.12 - '@smithy/middleware-retry': 4.4.12 + '@smithy/middleware-endpoint': 4.3.13 + '@smithy/middleware-retry': 4.4.13 '@smithy/middleware-serde': 4.2.6 '@smithy/middleware-stack': 4.2.5 '@smithy/node-config-provider': 4.3.5 '@smithy/node-http-handler': 4.4.5 '@smithy/protocol-http': 5.3.5 - '@smithy/smithy-client': 4.9.8 + '@smithy/smithy-client': 4.9.9 '@smithy/types': 4.9.0 '@smithy/url-parser': 4.2.5 '@smithy/util-base64': 4.3.0 '@smithy/util-body-length-browser': 4.2.0 '@smithy/util-body-length-node': 4.2.1 - '@smithy/util-defaults-mode-browser': 4.3.11 - '@smithy/util-defaults-mode-node': 4.2.14 + '@smithy/util-defaults-mode-browser': 4.3.12 + '@smithy/util-defaults-mode-node': 4.2.15 '@smithy/util-endpoints': 3.2.5 '@smithy/util-middleware': 4.2.5 '@smithy/util-retry': 4.2.5 @@ -4459,12 +4318,12 @@ snapshots: '@aws-sdk/core@3.775.0': dependencies: '@aws-sdk/types': 3.775.0 - '@smithy/core': 3.18.5 + '@smithy/core': 3.18.6 '@smithy/node-config-provider': 4.3.5 '@smithy/property-provider': 4.2.5 '@smithy/protocol-http': 5.3.5 '@smithy/signature-v4': 5.3.5 - '@smithy/smithy-client': 4.9.8 + '@smithy/smithy-client': 4.9.9 '@smithy/types': 4.9.0 '@smithy/util-middleware': 4.2.5 fast-xml-parser: 4.4.1 @@ -4547,7 +4406,7 @@ snapshots: '@smithy/node-http-handler': 4.4.5 '@smithy/property-provider': 4.2.5 '@smithy/protocol-http': 5.3.5 - '@smithy/smithy-client': 4.9.8 + '@smithy/smithy-client': 4.9.9 '@smithy/types': 4.9.0 '@smithy/util-stream': 4.5.6 tslib: 2.8.1 @@ -4819,7 +4678,7 @@ snapshots: '@aws-sdk/nested-clients': 3.787.0 '@aws-sdk/types': 3.775.0 '@smithy/config-resolver': 4.4.3 - '@smithy/core': 3.18.5 + '@smithy/core': 3.18.6 '@smithy/credential-provider-imds': 4.2.5 '@smithy/node-config-provider': 4.3.5 '@smithy/property-provider': 4.2.5 @@ -5023,7 +4882,7 @@ snapshots: '@aws-sdk/core': 3.775.0 '@aws-sdk/types': 3.775.0 '@aws-sdk/util-endpoints': 3.787.0 - '@smithy/core': 3.18.5 + '@smithy/core': 3.18.6 '@smithy/protocol-http': 5.3.5 '@smithy/types': 4.9.0 tslib: 2.8.1 @@ -5064,26 +4923,26 @@ snapshots: '@aws-sdk/util-user-agent-browser': 3.775.0 '@aws-sdk/util-user-agent-node': 3.787.0 '@smithy/config-resolver': 4.4.3 - '@smithy/core': 3.18.5 + '@smithy/core': 3.18.6 '@smithy/fetch-http-handler': 5.3.6 '@smithy/hash-node': 4.2.5 '@smithy/invalid-dependency': 4.2.5 '@smithy/middleware-content-length': 4.2.5 - '@smithy/middleware-endpoint': 4.3.12 - '@smithy/middleware-retry': 4.4.12 + '@smithy/middleware-endpoint': 4.3.13 + '@smithy/middleware-retry': 4.4.13 '@smithy/middleware-serde': 4.2.6 '@smithy/middleware-stack': 4.2.5 '@smithy/node-config-provider': 4.3.5 '@smithy/node-http-handler': 4.4.5 '@smithy/protocol-http': 5.3.5 - '@smithy/smithy-client': 4.9.8 + '@smithy/smithy-client': 4.9.9 '@smithy/types': 4.9.0 '@smithy/url-parser': 4.2.5 '@smithy/util-base64': 4.3.0 '@smithy/util-body-length-browser': 4.2.0 '@smithy/util-body-length-node': 4.2.1 - '@smithy/util-defaults-mode-browser': 4.3.11 - '@smithy/util-defaults-mode-node': 4.2.14 + '@smithy/util-defaults-mode-browser': 4.3.12 + '@smithy/util-defaults-mode-node': 4.2.15 '@smithy/util-endpoints': 3.2.5 '@smithy/util-middleware': 4.2.5 '@smithy/util-retry': 4.2.5 @@ -5311,7 +5170,7 @@ snapshots: dependencies: '@aws-sdk/types': 3.775.0 '@smithy/types': 4.9.0 - bowser: 2.12.1 + bowser: 2.13.1 tslib: 2.8.1 optional: true @@ -5697,9 +5556,9 @@ snapshots: '@push.rocks/smartshell': 3.3.0 tsx: 4.20.6 - '@git.zone/tstest@3.1.3(@aws-sdk/credential-providers@3.787.0)(socks@2.8.7)(typescript@5.9.3)': + '@git.zone/tstest@3.1.3(@aws-sdk/credential-providers@3.787.0)(@push.rocks/smartserve@1.1.0)(socks@2.8.7)(typescript@5.9.3)': dependencies: - '@api.global/typedserver': 3.0.80 + '@api.global/typedserver': 3.0.80(@push.rocks/smartserve@1.1.0) '@git.zone/tsbundle': 2.6.2 '@git.zone/tsrun': 2.0.0 '@push.rocks/consolecolor': 2.0.3 @@ -5728,6 +5587,7 @@ snapshots: - '@aws-sdk/credential-providers' - '@mongodb-js/zstd' - '@nuxt/kit' + - '@push.rocks/smartserve' - '@swc/helpers' - aws-crt - bare-abort-controller @@ -6315,11 +6175,6 @@ snapshots: dependencies: matcher: 5.0.0 - '@push.rocks/smartmime@1.0.6': - dependencies: - '@types/mime-types': 2.1.4 - mime-types: 2.1.35 - '@push.rocks/smartmime@2.0.4': dependencies: '@types/mime-types': 2.1.4 @@ -6500,6 +6355,14 @@ snapshots: transitivePeerDependencies: - aws-crt + '@push.rocks/smartserve@1.1.0': + dependencies: + '@api.global/typedrequest': 3.1.10 + '@push.rocks/lik': 6.2.2 + '@push.rocks/smartenv': 6.0.0 + '@push.rocks/smartlog': 3.1.10 + '@push.rocks/smartpath': 6.0.0 + '@push.rocks/smartshell@3.3.0': dependencies: '@push.rocks/smartdelay': 3.0.5 @@ -6518,10 +6381,10 @@ snapshots: '@push.rocks/webrequest': 4.0.1 '@tsclass/tsclass': 9.3.0 - '@push.rocks/smartsocket@2.0.27': + '@push.rocks/smartsocket@2.1.0(@push.rocks/smartserve@1.1.0)': dependencies: '@api.global/typedrequest-interfaces': 3.0.19 - '@api.global/typedserver': 3.0.36 + '@api.global/typedserver': 3.0.80(@push.rocks/smartserve@1.1.0) '@push.rocks/isohash': 2.0.1 '@push.rocks/isounique': 1.0.5 '@push.rocks/lik': 6.2.2 @@ -6532,11 +6395,12 @@ snapshots: '@push.rocks/smartpromise': 4.2.3 '@push.rocks/smartrx': 3.0.10 '@push.rocks/smarttime': 4.1.1 - engine.io: 6.5.4 - socket.io: 4.7.5 - socket.io-client: 4.7.5 + engine.io: 6.6.4 + socket.io: 4.8.1 + socket.io-client: 4.8.1 transitivePeerDependencies: - '@nuxt/kit' + - '@push.rocks/smartserve' - bufferutil - react - supports-color @@ -6609,8 +6473,6 @@ snapshots: nanoid: 4.0.2 uuid: 9.0.1 - '@push.rocks/smarturl@3.0.7': {} - '@push.rocks/smarturl@3.1.0': {} '@push.rocks/smartversion@3.0.5': @@ -6873,6 +6735,20 @@ snapshots: '@smithy/uuid': 1.1.0 tslib: 2.8.1 + '@smithy/core@3.18.6': + dependencies: + '@smithy/middleware-serde': 4.2.6 + '@smithy/protocol-http': 5.3.5 + '@smithy/types': 4.9.0 + '@smithy/util-base64': 4.3.0 + '@smithy/util-body-length-browser': 4.2.0 + '@smithy/util-middleware': 4.2.5 + '@smithy/util-stream': 4.5.6 + '@smithy/util-utf8': 4.2.0 + '@smithy/uuid': 1.1.0 + tslib: 2.8.1 + optional: true + '@smithy/credential-provider-imds@4.2.5': dependencies: '@smithy/node-config-provider': 4.3.5 @@ -6975,6 +6851,18 @@ snapshots: '@smithy/util-middleware': 4.2.5 tslib: 2.8.1 + '@smithy/middleware-endpoint@4.3.13': + dependencies: + '@smithy/core': 3.18.6 + '@smithy/middleware-serde': 4.2.6 + '@smithy/node-config-provider': 4.3.5 + '@smithy/shared-ini-file-loader': 4.4.0 + '@smithy/types': 4.9.0 + '@smithy/url-parser': 4.2.5 + '@smithy/util-middleware': 4.2.5 + tslib: 2.8.1 + optional: true + '@smithy/middleware-retry@4.4.12': dependencies: '@smithy/node-config-provider': 4.3.5 @@ -6987,6 +6875,19 @@ snapshots: '@smithy/uuid': 1.1.0 tslib: 2.8.1 + '@smithy/middleware-retry@4.4.13': + dependencies: + '@smithy/node-config-provider': 4.3.5 + '@smithy/protocol-http': 5.3.5 + '@smithy/service-error-classification': 4.2.5 + '@smithy/smithy-client': 4.9.9 + '@smithy/types': 4.9.0 + '@smithy/util-middleware': 4.2.5 + '@smithy/util-retry': 4.2.5 + '@smithy/uuid': 1.1.0 + tslib: 2.8.1 + optional: true + '@smithy/middleware-serde@4.2.6': dependencies: '@smithy/protocol-http': 5.3.5 @@ -7064,6 +6965,17 @@ snapshots: '@smithy/util-stream': 4.5.6 tslib: 2.8.1 + '@smithy/smithy-client@4.9.9': + dependencies: + '@smithy/core': 3.18.6 + '@smithy/middleware-endpoint': 4.3.13 + '@smithy/middleware-stack': 4.2.5 + '@smithy/protocol-http': 5.3.5 + '@smithy/types': 4.9.0 + '@smithy/util-stream': 4.5.6 + tslib: 2.8.1 + optional: true + '@smithy/types@4.9.0': dependencies: tslib: 2.8.1 @@ -7109,6 +7021,14 @@ snapshots: '@smithy/types': 4.9.0 tslib: 2.8.1 + '@smithy/util-defaults-mode-browser@4.3.12': + dependencies: + '@smithy/property-provider': 4.2.5 + '@smithy/smithy-client': 4.9.9 + '@smithy/types': 4.9.0 + tslib: 2.8.1 + optional: true + '@smithy/util-defaults-mode-node@4.2.14': dependencies: '@smithy/config-resolver': 4.4.3 @@ -7119,6 +7039,17 @@ snapshots: '@smithy/types': 4.9.0 tslib: 2.8.1 + '@smithy/util-defaults-mode-node@4.2.15': + dependencies: + '@smithy/config-resolver': 4.4.3 + '@smithy/credential-provider-imds': 4.2.5 + '@smithy/node-config-provider': 4.3.5 + '@smithy/property-provider': 4.2.5 + '@smithy/smithy-client': 4.9.9 + '@smithy/types': 4.9.0 + tslib: 2.8.1 + optional: true + '@smithy/util-endpoints@3.2.5': dependencies: '@smithy/node-config-provider': 4.3.5 @@ -7227,9 +7158,7 @@ snapshots: dependencies: '@types/node': 24.10.1 - '@types/cookie@0.4.1': {} - - '@types/cors@2.8.17': + '@types/cors@2.8.19': dependencies: '@types/node': 24.10.1 @@ -7245,13 +7174,6 @@ snapshots: dependencies: '@types/bn.js': 5.2.0 - '@types/express-serve-static-core@4.19.7': - dependencies: - '@types/node': 24.10.1 - '@types/qs': 6.9.15 - '@types/range-parser': 1.2.7 - '@types/send': 1.2.1 - '@types/express-serve-static-core@5.1.0': dependencies: '@types/node': 24.10.1 @@ -7259,13 +7181,6 @@ snapshots: '@types/range-parser': 1.2.7 '@types/send': 1.2.1 - '@types/express@4.17.25': - dependencies: - '@types/body-parser': 1.19.6 - '@types/express-serve-static-core': 4.19.7 - '@types/qs': 6.9.15 - '@types/serve-static': 1.15.10 - '@types/express@5.0.6': dependencies: '@types/body-parser': 1.19.6 @@ -7305,8 +7220,6 @@ snapshots: '@types/mime-types@2.1.4': {} - '@types/mime@1.3.5': {} - '@types/minimatch@5.1.2': {} '@types/ms@0.7.34': {} @@ -7323,8 +7236,6 @@ snapshots: '@types/qs@6.14.0': {} - '@types/qs@6.9.15': {} - '@types/randomatic@3.1.5': {} '@types/range-parser@1.2.7': {} @@ -7333,21 +7244,10 @@ snapshots: '@types/semver@7.7.1': {} - '@types/send@0.17.6': - dependencies: - '@types/mime': 1.3.5 - '@types/node': 24.10.1 - '@types/send@1.2.1': dependencies: '@types/node': 24.10.1 - '@types/serve-static@1.15.10': - dependencies: - '@types/http-errors': 2.0.5 - '@types/node': 24.10.1 - '@types/send': 0.17.6 - '@types/serve-static@2.2.0': dependencies: '@types/http-errors': 2.0.5 @@ -7438,8 +7338,6 @@ snapshots: argparse@2.0.1: {} - array-flatten@1.1.1: {} - asn1js@3.0.6: dependencies: pvtsutils: 1.3.6 @@ -7515,23 +7413,6 @@ snapshots: bn.js@4.12.2: {} - body-parser@1.20.3: - dependencies: - bytes: 3.1.2 - content-type: 1.0.5 - debug: 2.6.9 - depd: 2.0.0 - destroy: 1.2.0 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - on-finished: 2.4.1 - qs: 6.13.0 - raw-body: 2.5.2 - type-is: 1.6.18 - unpipe: 1.0.0 - transitivePeerDependencies: - - supports-color - body-parser@2.2.1: dependencies: bytes: 3.1.2 @@ -7548,6 +7429,9 @@ snapshots: bowser@2.12.1: {} + bowser@2.13.1: + optional: true + brace-expansion@1.1.12: dependencies: balanced-match: 1.0.2 @@ -7675,24 +7559,14 @@ snapshots: ini: 1.3.8 proto-list: 1.2.4 - content-disposition@0.5.4: - dependencies: - safe-buffer: 5.2.1 - content-disposition@1.0.0: dependencies: safe-buffer: 5.2.1 content-type@1.0.5: {} - cookie-signature@1.0.6: {} - cookie-signature@1.2.2: {} - cookie@0.4.2: {} - - cookie@0.7.1: {} - cookie@0.7.2: {} cors@2.8.5: @@ -7727,13 +7601,9 @@ snapshots: dayjs@1.11.13: {} - debug@2.6.9: + debug@4.3.7: dependencies: - ms: 2.0.0 - - debug@4.3.4: - dependencies: - ms: 2.1.2 + ms: 2.1.3 debug@4.4.3: dependencies: @@ -7777,8 +7647,6 @@ snapshots: dequal@2.0.3: {} - destroy@1.2.0: {} - devlop@1.1.0: dependencies: dequal: 2.0.3 @@ -7813,40 +7681,37 @@ snapshots: emoji-regex@9.2.2: {} - encodeurl@1.0.2: {} - encodeurl@2.0.0: {} end-of-stream@1.4.5: dependencies: once: 1.4.0 - engine.io-client@6.5.3: + engine.io-client@6.6.3: dependencies: '@socket.io/component-emitter': 3.1.2 - debug: 4.3.4 - engine.io-parser: 5.2.2 - ws: 8.11.0 - xmlhttprequest-ssl: 2.0.0 + debug: 4.3.7 + engine.io-parser: 5.2.3 + ws: 8.17.1 + xmlhttprequest-ssl: 2.1.2 transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - engine.io-parser@5.2.2: {} + engine.io-parser@5.2.3: {} - engine.io@6.5.4: + engine.io@6.6.4: dependencies: - '@types/cookie': 0.4.1 - '@types/cors': 2.8.17 + '@types/cors': 2.8.19 '@types/node': 24.10.1 accepts: 1.3.8 base64id: 2.0.0 - cookie: 0.4.2 + cookie: 0.7.2 cors: 2.8.5 - debug: 4.3.4 - engine.io-parser: 5.2.2 - ws: 8.11.0 + debug: 4.3.7 + engine.io-parser: 5.2.3 + ws: 8.17.1 transitivePeerDependencies: - bufferutil - supports-color @@ -7973,42 +7838,6 @@ snapshots: dependencies: lodash.assign: 3.2.0 - express@4.21.2: - dependencies: - accepts: 1.3.8 - array-flatten: 1.1.1 - body-parser: 1.20.3 - content-disposition: 0.5.4 - content-type: 1.0.5 - cookie: 0.7.1 - cookie-signature: 1.0.6 - debug: 2.6.9 - depd: 2.0.0 - encodeurl: 2.0.0 - escape-html: 1.0.3 - etag: 1.8.1 - finalhandler: 1.3.1 - fresh: 0.5.2 - http-errors: 2.0.0 - merge-descriptors: 1.0.3 - methods: 1.1.2 - on-finished: 2.4.1 - parseurl: 1.3.3 - path-to-regexp: 0.1.12 - proxy-addr: 2.0.7 - qs: 6.13.0 - range-parser: 1.2.1 - safe-buffer: 5.2.1 - send: 0.19.0 - serve-static: 1.16.2 - setprototypeof: 1.2.0 - statuses: 2.0.1 - type-is: 1.6.18 - utils-merge: 1.0.1 - vary: 1.1.2 - transitivePeerDependencies: - - supports-color - express@5.2.1: dependencies: accepts: 2.0.0 @@ -8111,18 +7940,6 @@ snapshots: transitivePeerDependencies: - supports-color - finalhandler@1.3.1: - dependencies: - debug: 2.6.9 - encodeurl: 2.0.0 - escape-html: 1.0.3 - on-finished: 2.4.1 - parseurl: 1.3.3 - statuses: 2.0.1 - unpipe: 1.0.0 - transitivePeerDependencies: - - supports-color - finalhandler@2.1.0: dependencies: debug: 4.4.3 @@ -8180,8 +7997,6 @@ snapshots: forwarded@0.2.0: {} - fresh@0.5.2: {} - fresh@2.0.0: {} fs-extra@11.3.2: @@ -8401,10 +8216,6 @@ snapshots: dependencies: ms: 2.1.3 - iconv-lite@0.4.24: - dependencies: - safer-buffer: 2.1.2 - iconv-lite@0.7.0: dependencies: safer-buffer: 2.1.2 @@ -8715,18 +8526,12 @@ snapshots: dependencies: '@types/mdast': 4.0.4 - media-typer@0.3.0: {} - media-typer@1.1.0: {} memory-pager@1.5.0: {} - merge-descriptors@1.0.3: {} - merge-descriptors@2.0.0: {} - methods@1.1.2: {} - micromark-core-commonmark@2.0.2: dependencies: decode-named-character-reference: 1.0.2 @@ -8937,8 +8742,6 @@ snapshots: dependencies: mime-db: 1.54.0 - mime@1.6.0: {} - mime@4.0.6: {} mimic-response@3.1.0: {} @@ -9025,10 +8828,6 @@ snapshots: '@aws-sdk/credential-providers': 3.787.0 socks: 2.8.7 - ms@2.0.0: {} - - ms@2.1.2: {} - ms@2.1.3: {} nanoid@4.0.2: {} @@ -9163,8 +8962,6 @@ snapshots: lru-cache: 11.2.2 minipass: 7.1.2 - path-to-regexp@0.1.12: {} - path-to-regexp@8.2.0: {} path-to-regexp@8.3.0: {} @@ -9271,10 +9068,6 @@ snapshots: pvutils@1.1.5: {} - qs@6.13.0: - dependencies: - side-channel: 1.1.0 - qs@6.14.0: dependencies: side-channel: 1.1.0 @@ -9289,13 +9082,6 @@ snapshots: range-parser@1.2.1: {} - raw-body@2.5.2: - dependencies: - bytes: 3.1.2 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - unpipe: 1.0.0 - raw-body@3.0.2: dependencies: bytes: 3.1.2 @@ -9435,24 +9221,6 @@ snapshots: semver@7.7.3: {} - send@0.19.0: - dependencies: - debug: 2.6.9 - depd: 2.0.0 - destroy: 1.2.0 - encodeurl: 1.0.2 - escape-html: 1.0.3 - etag: 1.8.1 - fresh: 0.5.2 - http-errors: 2.0.0 - mime: 1.6.0 - ms: 2.1.3 - on-finished: 2.4.1 - range-parser: 1.2.1 - statuses: 2.0.1 - transitivePeerDependencies: - - supports-color - send@1.2.0: dependencies: debug: 4.4.3 @@ -9469,15 +9237,6 @@ snapshots: transitivePeerDependencies: - supports-color - serve-static@1.16.2: - dependencies: - encodeurl: 2.0.0 - escape-html: 1.0.3 - parseurl: 1.3.3 - send: 0.19.0 - transitivePeerDependencies: - - supports-color - serve-static@2.2.0: dependencies: encodeurl: 2.0.0 @@ -9538,20 +9297,20 @@ snapshots: smart-buffer@4.2.0: {} - socket.io-adapter@2.5.4: + socket.io-adapter@2.5.5: dependencies: - debug: 4.3.4 - ws: 8.11.0 + debug: 4.3.7 + ws: 8.17.1 transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - socket.io-client@4.7.5: + socket.io-client@4.8.1: dependencies: '@socket.io/component-emitter': 3.1.2 - debug: 4.3.4 - engine.io-client: 6.5.3 + debug: 4.3.7 + engine.io-client: 6.6.3 socket.io-parser: 4.2.4 transitivePeerDependencies: - bufferutil @@ -9561,18 +9320,18 @@ snapshots: socket.io-parser@4.2.4: dependencies: '@socket.io/component-emitter': 3.1.2 - debug: 4.3.4 + debug: 4.3.7 transitivePeerDependencies: - supports-color - socket.io@4.7.5: + socket.io@4.8.1: dependencies: accepts: 1.3.8 base64id: 2.0.0 cors: 2.8.5 - debug: 4.3.4 - engine.io: 6.5.4 - socket.io-adapter: 2.5.4 + debug: 4.3.7 + engine.io: 6.6.4 + socket.io-adapter: 2.5.5 socket.io-parser: 4.2.4 transitivePeerDependencies: - bufferutil @@ -9776,11 +9535,6 @@ snapshots: type-fest@4.41.0: {} - type-is@1.6.18: - dependencies: - media-typer: 0.3.0 - mime-types: 2.1.35 - type-is@2.0.1: dependencies: content-type: 1.0.5 @@ -9847,8 +9601,6 @@ snapshots: util-deprecate@1.0.2: {} - utils-merge@1.0.1: {} - uuid@9.0.1: {} vary@1.1.2: {} @@ -9896,11 +9648,11 @@ snapshots: wrappy@1.0.2: {} - ws@8.11.0: {} + ws@8.17.1: {} ws@8.18.3: {} - xmlhttprequest-ssl@2.0.0: {} + xmlhttprequest-ssl@2.1.2: {} y18n@5.0.8: {} diff --git a/ts/classes.typedserver.ts b/ts/classes.typedserver.ts index 5318531..327af91 100644 --- a/ts/classes.typedserver.ts +++ b/ts/classes.typedserver.ts @@ -1,8 +1,8 @@ import * as plugins from './plugins.js'; import * as paths from './paths.js'; import * as interfaces from '../dist_ts_interfaces/index.js'; -import * as servertools from './servertools/index.js'; -import { type TCompressionMethod } from './servertools/classes.compressor.js'; +import { DevToolsHandler } from './controllers/controller.devtools.js'; +import { TypedRequestHandler } from './controllers/controller.typedrequest.js'; export interface IServerOptions { /** @@ -15,16 +15,6 @@ export interface IServerOptions { */ injectReload?: boolean; - /** - * enable compression - */ - enableCompression?: boolean; - - /** - * choose a preferred compression method - */ - preferredCompressionMethod?: TCompressionMethod; - /** * watch the serve directory? */ @@ -34,7 +24,6 @@ export interface IServerOptions { /** * a default answer given in case there is no other handler. - * @returns */ defaultAnswer?: () => Promise; @@ -42,13 +31,14 @@ export interface IServerOptions { * will try to reroute traffic to an ssl connection using headers */ forceSsl?: boolean; + /** * allows serving manifests */ manifest?: plugins.smartmanifest.ISmartManifestConstructorOptions; + /** * the port to listen on - * can be overwritten when actually starting the server */ port?: number | string; publicKey?: string; @@ -57,6 +47,7 @@ export interface IServerOptions { feed?: boolean; robots?: boolean; domain?: string; + /** * convey information about the app being served */ @@ -66,22 +57,45 @@ export interface IServerOptions { blockWaybackMachine?: boolean; } -export class TypedServer { - // static - // nothing here yet +export type THttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'ALL'; +export interface IRouteHandler { + (request: Request): Promise; +} + +export interface IRegisteredRoute { + pattern: string; + regex: RegExp; + paramNames: string[]; + method: THttpMethod; + handler: IRouteHandler; +} + +export class TypedServer { // instance public options: IServerOptions; - public server: servertools.Server; + public smartServe: plugins.smartserve.SmartServe; public smartwatchInstance: plugins.smartwatch.Smartwatch; public serveDirHashSubject = new plugins.smartrx.rxjs.ReplaySubject(1); public serveHash: string = '000000'; public typedsocket: plugins.typedsocket.TypedSocket; public typedrouter = new plugins.typedrequest.TypedRouter(); + // Sitemap and Feed helpers + private sitemapHelper: SitemapHelper; + private feedHelper: FeedHelper; + private smartmanifestInstance: plugins.smartmanifest.SmartManifest; + + // Request handlers + private devToolsHandler: DevToolsHandler; + private typedRequestHandler: TypedRequestHandler; + + // Custom route handlers (for addRoute API) + private customRoutes: IRegisteredRoute[] = []; + public lastReload: number = Date.now(); public ended = false; - + constructor(optionsArg: IServerOptions) { const standardOptions: IServerOptions = { port: 3000, @@ -95,43 +109,74 @@ export class TypedServer { ...optionsArg, }; - this.server = new servertools.Server(this.options); - // add routes to the smartexpress instance - this.server.addRoute( - '/typedserver/:request', - new servertools.Handler('ALL', async (req, res) => { - switch (req.params.request) { - case 'devtools': - res.setHeader('Content-Type', 'text/javascript'); - res.status(200); - const devtoolsContent = await plugins.fsInstance.file(paths.injectBundlePath).encoding('utf8').read(); - res.write(devtoolsContent); - res.end(); - break; - case 'reloadcheck': - console.log('got request for reloadcheck'); - res.setHeader('Content-Type', 'text/plain'); - res.status(200); - if (this.ended) { - res.write('end'); - res.end(); - return; - } - res.write(this.lastReload.toString()); - res.end(); - break; - default: - res.status(404); - res.write('Unknown request type'); - res.end(); - break; - } + // Initialize handlers + this.devToolsHandler = new DevToolsHandler({ + getLastReload: () => this.lastReload, + getEnded: () => this.ended, + }); + this.typedRequestHandler = new TypedRequestHandler(this.typedrouter); + } + + /** + * Access sitemap URLs (for adding/replacing) + */ + public get sitemap() { + return this.sitemapHelper; + } + + /** + * Add a custom route handler + * Supports Express-style path patterns like '/path/:param' and '/path/*splat' + * @param path - The route path pattern + * @param method - HTTP method (GET, POST, PUT, DELETE, PATCH, ALL) + * @param handler - Async function that receives Request and returns Response or null + */ + public addRoute( + path: string, + method: THttpMethod, + handler: IRouteHandler + ): void { + // Convert Express-style path to regex + const paramNames: string[] = []; + let regexPattern = path + // Handle named parameters :param + .replace(/:([a-zA-Z_][a-zA-Z0-9_]*)/g, (_, paramName) => { + paramNames.push(paramName); + return '([^/]+)'; }) - ); - this.server.addRoute( - '/typedrequest', - new servertools.HandlerTypedRouter(this.typedrouter) - ); + // Handle wildcard *splat (matches everything including slashes) + .replace(/\*([a-zA-Z_][a-zA-Z0-9_]*)/g, (_, paramName) => { + paramNames.push(paramName); + return '(.*)'; + }); + + // Ensure exact match + regexPattern = `^${regexPattern}$`; + + this.customRoutes.push({ + pattern: path, + regex: new RegExp(regexPattern), + paramNames, + method, + handler, + }); + } + + /** + * Parse route parameters from a path using a registered route + */ + private parseRouteParams( + route: IRegisteredRoute, + pathname: string + ): Record | null { + const match = pathname.match(route.regex); + if (!match) return null; + + const params: Record = {}; + route.paramNames.forEach((name, index) => { + params[name] = match[index + 1]; + }); + return params; } /** @@ -145,52 +190,60 @@ export class TypedServer { ); } - if (this.options.serveDir) { - this.server.addRoute( - '/{*splat}', - new servertools.HandlerStatic(this.options.serveDir, { - responseModifier: async (responseArg) => { - if (plugins.path.parse(responseArg.path).ext === '.html') { - let fileString = responseArg.responseContent.toString(); - const fileStringArray = fileString.split(''); - if (this.options.injectReload && fileStringArray.length === 2) { - fileStringArray[0] = `${fileStringArray[0]} - - - - - `; - fileString = fileStringArray.join(''); - console.log('injected typedserver script.'); - responseArg.responseContent = Buffer.from(fileString); - } else if (this.options.injectReload) { - console.log('Could not insert typedserver script - no tag found'); - } - } - const headers = responseArg.headers; - headers.appHash = this.serveHash; - headers['Cache-Control'] = 'no-cache, no-store, must-revalidate'; - headers['Pragma'] = 'no-cache'; - headers['Expires'] = '0'; - return { - headers, - path: responseArg.path, - responseContent: responseArg.responseContent, - travelData: responseArg.travelData, - }; - }, - serveIndexHtmlDefault: true, - enableCompression: this.options.enableCompression, - preferredCompressionMethod: this.options.preferredCompressionMethod, - }) - ); + const port = + typeof this.options.port === 'string' + ? parseInt(this.options.port, 10) + : this.options.port || 3000; + + // Initialize optional helpers + if (this.options.sitemap) { + this.sitemapHelper = new SitemapHelper(this.options.domain); } - + if (this.options.feed) { + this.feedHelper = new FeedHelper(); + } + if (this.options.manifest) { + this.smartmanifestInstance = new plugins.smartmanifest.SmartManifest(this.options.manifest); + } + + // Build SmartServe options + const smartServeOptions: plugins.smartserve.ISmartServeOptions = { + port, + hostname: '0.0.0.0', + tls: + this.options.privateKey && this.options.publicKey + ? { + key: this.options.privateKey, + cert: this.options.publicKey, + } + : undefined, + websocket: { + typedRouter: this.typedrouter, + onConnectionOpen: (peer) => { + peer.tags.add('typedserver_frontend'); + console.log(`WebSocket connected: ${peer.id}`); + }, + onConnectionClose: (peer) => { + console.log(`WebSocket disconnected: ${peer.id}`); + }, + }, + static: this.options.serveDir + ? { + root: this.options.serveDir, + index: ['index.html'], + etag: true, + } + : undefined, + }; + + this.smartServe = new plugins.smartserve.SmartServe(smartServeOptions); + + // Set up custom request handler for all custom routes + this.smartServe.setHandler(async (request: Request): Promise => { + return this.handleRequest(request); + }); + + // Setup file watching if (this.options.watch && this.options.serveDir) { try { this.smartwatchInstance = new plugins.smartwatch.Smartwatch([this.options.serveDir]); @@ -202,20 +255,21 @@ export class TypedServer { await this.createServeDirHash(); } catch (error) { console.error('Failed to initialize file watching:', error); - // Continue without file watching rather than crashing } } - // lets start the server - await this.server.start(); + // Start the server + await this.smartServe.start(); + console.log(`TypedServer listening on port ${port}`); + // Setup TypedSocket using SmartServe integration try { - this.typedsocket = await plugins.typedsocket.TypedSocket.createServer( - this.typedrouter, - this.server + this.typedsocket = plugins.typedsocket.TypedSocket.fromSmartServe( + this.smartServe, + this.typedrouter ); - // lets setup typedrouter + // Setup typedrouter handlers this.typedrouter.addTypedHandler( new plugins.typedrequest.TypedHandler('getLatestServerChangeTime', async () => { return { @@ -225,10 +279,235 @@ export class TypedServer { ); } catch (error) { console.error('Failed to initialize TypedSocket:', error); - // Continue without WebSocket support rather than crashing } } + /** + * Main request handler - routes to appropriate sub-handlers + */ + private async handleRequest(request: Request): Promise { + const url = new URL(request.url); + const path = url.pathname; + const method = request.method; + + // DevTools handler + let response = await this.devToolsHandler.handle(request); + if (response) return response; + + // TypedRequest handler + response = await this.typedRequestHandler.handle(request); + if (response) return response; + + // Custom routes (registered via addRoute) + for (const route of this.customRoutes) { + if (route.method === 'ALL' || route.method === method) { + const params = this.parseRouteParams(route, path); + if (params !== null) { + // Attach params to request for handler to access + (request as any).params = params; + response = await route.handler(request); + if (response) return response; + } + } + } + + // Robots.txt + if (this.options.robots && this.options.domain && path === '/robots.txt' && method === 'GET') { + return this.handleRobots(); + } + + // Manifest.json + if (this.options.manifest && path === '/manifest.json' && method === 'GET') { + return this.handleManifest(); + } + + // Sitemap + if (this.options.sitemap && path === '/sitemap' && method === 'GET') { + return this.handleSitemap(); + } + + // Sitemap News + if (this.options.sitemap && path === '/sitemap-news' && method === 'GET') { + return this.handleSitemapNews(); + } + + // Feed + if (this.options.feed && path === '/feed' && method === 'GET') { + return this.handleFeed(); + } + + // App version + if (this.options.appVersion && path === '/appversion' && method === 'GET') { + return new Response(this.options.appVersion, { + status: 200, + headers: { 'Content-Type': 'text/plain' }, + }); + } + + // HTML injection for reload (if enabled) + if (this.options.injectReload && this.options.serveDir) { + response = await this.handleHtmlWithInjection(request); + if (response) return response; + } + + // Not handled - let SmartServe handle (static files, etc.) + return null; + } + + /** + * Handle robots.txt request + */ + private handleRobots(): Response { + const waybackBlock = this.options.blockWaybackMachine + ? ` +User-Agent: ia_archiver +Disallow: / +` + : ''; + + const content = ` +User-agent: Googlebot-News +Disallow: /account +Disallow: /login + +User-agent: * +Disallow: /account +Disallow: /login +${waybackBlock} +Sitemap: https://${this.options.domain}/sitemap +Sitemap: https://${this.options.domain}/sitemap-news +`; + + return new Response(content.trim(), { + status: 200, + headers: { 'Content-Type': 'text/plain' }, + }); + } + + /** + * Handle manifest.json request + */ + private handleManifest(): Response { + return new Response(this.smartmanifestInstance.jsonString(), { + status: 200, + headers: { 'Content-Type': 'application/json' }, + }); + } + + /** + * Handle sitemap request + */ + private async handleSitemap(): Promise { + const sitemapXmlString = await this.sitemapHelper.createSitemap(); + return new Response(sitemapXmlString, { + status: 200, + headers: { 'Content-Type': 'application/xml' }, + }); + } + + /** + * Handle sitemap-news request + */ + private async handleSitemapNews(): Promise { + if (!this.options.articleGetterFunction) { + return new Response('no article getter function defined.', { status: 500 }); + } + + const sitemapNewsXml = await this.sitemapHelper.createSitemapNews( + await this.options.articleGetterFunction() + ); + + return new Response(sitemapNewsXml, { + status: 200, + headers: { 'Content-Type': 'application/xml' }, + }); + } + + /** + * Handle feed request + */ + private async handleFeed(): Promise { + if (!this.options.feedMetadata) { + return new Response('feed metadata is missing', { status: 500 }); + } + + if (!this.options.articleGetterFunction) { + return new Response('no article getter function defined.', { status: 500 }); + } + + const xmlString = await this.feedHelper.createFeed( + this.options.feedMetadata, + await this.options.articleGetterFunction() + ); + + return new Response(xmlString, { + status: 200, + headers: { 'Content-Type': 'application/xml' }, + }); + } + + /** + * Handle HTML files with reload script injection + */ + private async handleHtmlWithInjection(request: Request): Promise { + const url = new URL(request.url); + const requestPath = url.pathname; + + // Check if this is a request for an HTML file or root + if (requestPath === '/' || requestPath.endsWith('.html') || !requestPath.includes('.')) { + try { + let filePath = requestPath === '/' ? 'index.html' : requestPath.slice(1); + if (!filePath.endsWith('.html') && !filePath.includes('.')) { + filePath = plugins.path.join(filePath, 'index.html'); + } + + const fullPath = plugins.path.join(this.options.serveDir, filePath); + + // Security check + if (!fullPath.startsWith(this.options.serveDir)) { + return new Response('Forbidden', { status: 403 }); + } + + let fileContent = (await plugins.fsInstance + .file(fullPath) + .encoding('utf8') + .read()) as string; + + // Inject reload script + if (fileContent.includes('')) { + const injection = ` + + + + + `; + fileContent = fileContent.replace('', injection); + console.log('injected typedserver script.'); + } + + return new Response(fileContent, { + status: 200, + headers: { + 'Content-Type': 'text/html; charset=utf-8', + 'Cache-Control': 'no-cache, no-store, must-revalidate', + Pragma: 'no-cache', + Expires: '0', + appHash: this.serveHash, + }, + }); + } catch (error) { + // Fall through to default handling + } + } + + return null; + } + /** * reloads the page */ @@ -238,14 +517,17 @@ export class TypedServer { console.warn('TypedSocket not initialized, skipping client notifications'); return; } - + try { - const connections = await this.typedsocket.findAllTargetConnectionsByTag('typedserver_frontend'); + const connections = await this.typedsocket.findAllTargetConnectionsByTag( + 'typedserver_frontend' + ); for (const connection of connections) { - const pushTime = this.typedsocket.createTypedRequest( - 'pushLatestServerChangeTime', - connection - ); + const pushTime = + this.typedsocket.createTypedRequest( + 'pushLatestServerChangeTime', + connection + ); pushTime.fire({ time: this.lastReload, }); @@ -260,7 +542,7 @@ export class TypedServer { */ public async stop(): Promise { this.ended = true; - + const stopWithErrorHandling = async ( stopFn: () => Promise, componentName: string @@ -271,24 +553,24 @@ export class TypedServer { console.error(`Error stopping ${componentName}:`, err); } }; - + const tasks: Promise[] = []; - - // Stop server - if (this.server) { - tasks.push(stopWithErrorHandling(() => this.server.stop(), 'server')); + + // Stop SmartServe + if (this.smartServe) { + tasks.push(stopWithErrorHandling(() => this.smartServe.stop(), 'SmartServe')); } - - // Stop TypedSocket + + // Stop TypedSocket (in SmartServe mode, this is a no-op but good for cleanup) if (this.typedsocket) { tasks.push(stopWithErrorHandling(() => this.typedsocket.stop(), 'TypedSocket')); } - + // Stop file watcher if (this.smartwatchInstance) { tasks.push(stopWithErrorHandling(() => this.smartwatchInstance.stop(), 'file watcher')); } - + await Promise.all(tasks); } @@ -306,11 +588,62 @@ export class TypedServer { this.serveDirHashSubject.next(this.serveHash); } catch (error) { console.error('Failed to create serve directory hash:', error); - // Use a timestamp-based hash as fallback const fallbackHash = Date.now().toString(16).slice(-6); this.serveHash = fallbackHash; console.log('Using fallback hash: ' + fallbackHash); this.serveDirHashSubject.next(fallbackHash); } } -} \ No newline at end of file +} + +// ============================================================================ +// Helper Classes +// ============================================================================ + +/** + * Sitemap helper class + */ +class SitemapHelper { + private smartSitemap = new plugins.smartsitemap.SmartSitemap(); + public urls: plugins.smartsitemap.IUrlInfo[] = []; + + constructor(domain?: string) { + if (domain) { + this.urls.push({ + url: `https://${domain}/`, + timestamp: Date.now(), + frequency: 'daily', + }); + } + } + + async createSitemap(): Promise { + return this.smartSitemap.createSitemapFromUrlInfoArray(this.urls); + } + + async createSitemapNews(articles: plugins.tsclass.content.IArticle[]): Promise { + return this.smartSitemap.createSitemapNewsFromArticleArray(articles); + } + + replaceUrls(urlsArg: plugins.smartsitemap.IUrlInfo[]) { + this.urls = urlsArg; + } + + addUrls(urlsArg: plugins.smartsitemap.IUrlInfo[]) { + this.urls = this.urls.concat(urlsArg); + } +} + +/** + * Feed helper class + */ +class FeedHelper { + private smartfeedInstance = new plugins.smartfeed.Smartfeed(); + + async createFeed( + feedMetadata: plugins.smartfeed.IFeedOptions, + articles: plugins.tsclass.content.IArticle[] + ): Promise { + return this.smartfeedInstance.createFeedFromArticleArray(feedMetadata, articles); + } +} diff --git a/ts/controllers/controller.devtools.ts b/ts/controllers/controller.devtools.ts new file mode 100644 index 0000000..a38a79c --- /dev/null +++ b/ts/controllers/controller.devtools.ts @@ -0,0 +1,53 @@ +import * as plugins from '../plugins.js'; +import * as paths from '../paths.js'; + +/** + * DevTools controller for TypedServer + * Handles /typedserver/devtools and /typedserver/reloadcheck endpoints + */ +@plugins.smartserve.Route('/typedserver') +export class DevToolsController { + private getLastReload: () => number; + private getEnded: () => boolean; + + constructor(options: { getLastReload: () => number; getEnded: () => boolean }) { + this.getLastReload = options.getLastReload; + this.getEnded = options.getEnded; + } + + @plugins.smartserve.Get('/devtools') + async getDevtools(ctx: plugins.smartserve.IRequestContext): Promise { + const devtoolsContent = (await plugins.fsInstance + .file(paths.injectBundlePath) + .encoding('utf8') + .read()) as string; + + return new Response(devtoolsContent, { + status: 200, + headers: { + 'Content-Type': 'text/javascript', + }, + }); + } + + @plugins.smartserve.Get('/reloadcheck') + async reloadCheck(ctx: plugins.smartserve.IRequestContext): Promise { + console.log('got request for reloadcheck'); + + if (this.getEnded()) { + return new Response('end', { + status: 200, + headers: { + 'Content-Type': 'text/plain', + }, + }); + } + + return new Response(this.getLastReload().toString(), { + status: 200, + headers: { + 'Content-Type': 'text/plain', + }, + }); + } +} diff --git a/ts/controllers/controller.typedrequest.ts b/ts/controllers/controller.typedrequest.ts new file mode 100644 index 0000000..a145096 --- /dev/null +++ b/ts/controllers/controller.typedrequest.ts @@ -0,0 +1,43 @@ +import * as plugins from '../plugins.js'; + +/** + * TypedRequest handler for type-safe RPC endpoint + */ +export class TypedRequestHandler { + private typedRouter: plugins.typedrequest.TypedRouter; + + constructor(typedRouter: plugins.typedrequest.TypedRouter) { + this.typedRouter = typedRouter; + } + + /** + * Handle a request - returns Response if handled, null otherwise + */ + public async handle(request: Request): Promise { + const url = new URL(request.url); + const path = url.pathname; + + if (path === '/typedrequest' && request.method === 'POST') { + try { + const body = await request.json(); + const response = await this.typedRouter.routeAndAddResponse(body); + + return new Response(plugins.smartjson.stringify(response), { + status: 200, + headers: { + 'Content-Type': 'application/json', + }, + }); + } catch (error) { + return new Response(JSON.stringify({ error: 'Invalid request' }), { + status: 400, + headers: { + 'Content-Type': 'application/json', + }, + }); + } + } + + return null; + } +} diff --git a/ts/controllers/index.ts b/ts/controllers/index.ts new file mode 100644 index 0000000..696a0a8 --- /dev/null +++ b/ts/controllers/index.ts @@ -0,0 +1,2 @@ +export * from './controller.devtools.js'; +export * from './controller.typedrequest.js'; diff --git a/ts/index.ts b/ts/index.ts index fd70ce1..39a1f7f 100644 --- a/ts/index.ts +++ b/ts/index.ts @@ -5,10 +5,10 @@ import * as servertools from './servertools/index.js'; export { servertools }; export * from './classes.typedserver.js'; -// Type helpers -export type Request = plugins.express.Request; -export type Response = plugins.express.Response; +// Type helpers - using native Web API Request/Response types +// Native Request and Response are available in Node.js 18+ and all modern browsers +// Legacy Express types are available via servertools for backward compatibility // lets export utilityservers import * as utilityservers from './utilityservers/index.js'; diff --git a/ts/plugins.ts b/ts/plugins.ts index e54ea48..f29eb18 100644 --- a/ts/plugins.ts +++ b/ts/plugins.ts @@ -61,11 +61,16 @@ export { // Create a ready-to-use smartfs instance with Node.js provider export const fsInstance = new smartfs.SmartFs(new smartfs.SmartFsProviderNode()); -// express +// @push.rocks/smartserve +import * as smartserve from '@push.rocks/smartserve'; + +export { smartserve }; + +// Legacy Express dependencies - kept for backward compatibility with deprecated servertools +// These will be removed in the next major version +import express from 'express'; import bodyParser from 'body-parser'; import cors from 'cors'; -import express from 'express'; -// @ts-ignore import expressForceSsl from 'express-force-ssl'; -export { bodyParser, cors, express, expressForceSsl }; +export { express, bodyParser, cors, expressForceSsl }; diff --git a/ts/servertools/index.ts b/ts/servertools/index.ts index 44fc377..f27230a 100644 --- a/ts/servertools/index.ts +++ b/ts/servertools/index.ts @@ -1,12 +1,22 @@ -export * from './classes.server.js'; -export * from './classes.route.js'; -export * from './classes.handler.js'; -export * from './classes.handlerstatic.js'; -export * from './classes.handlerproxy.js'; -export * from './classes.handlertypedrouter.js'; +// Core utilities that don't depend on Express export * from './classes.compressor.js'; -import * as serviceworker from './tools.serviceworker.js'; -export { - serviceworker, -} +// Legacy Express-based classes - deprecated, will be removed in next major version +// These are kept for backward compatibility but should not be used for new code +// Use SmartServe decorator-based controllers instead +/** @deprecated Use SmartServe directly */ +export * from './classes.server.js'; +/** @deprecated Use SmartServe @Route decorator */ +export * from './classes.route.js'; +/** @deprecated Use SmartServe @Get/@Post decorators */ +export * from './classes.handler.js'; +/** @deprecated Use SmartServe static file serving */ +export * from './classes.handlerstatic.js'; +/** @deprecated Use SmartServe custom handler */ +export * from './classes.handlerproxy.js'; +/** @deprecated Use SmartServe TypedRouter integration */ +export * from './classes.handlertypedrouter.js'; + +// Service worker utilities - uses legacy patterns, will be migrated +import * as serviceworker from './tools.serviceworker.js'; +export { serviceworker }; diff --git a/ts/servertools/tools.serviceworker.ts b/ts/servertools/tools.serviceworker.ts index cd36106..6788484 100644 --- a/ts/servertools/tools.serviceworker.ts +++ b/ts/servertools/tools.serviceworker.ts @@ -1,10 +1,8 @@ import * as plugins from '../plugins.js'; import * as paths from '../paths.js'; -import * as interfaces from '../../dist_ts_interfaces/index.js' -import { Handler } from './classes.handler.js'; +import * as interfaces from '../../dist_ts_interfaces/index.js'; import type { TypedServer } from '../classes.typedserver.js'; -import { HandlerTypedRouter } from './classes.handlertypedrouter.js'; // Lazy-loaded service worker bundle content let swBundleJs: string | null = null; @@ -12,64 +10,83 @@ let swBundleJsMap: string | null = null; const loadServiceWorkerBundle = async (): Promise => { if (swBundleJs === null) { - swBundleJs = await plugins.fsInstance + swBundleJs = (await plugins.fsInstance .file(plugins.path.join(paths.serviceworkerBundleDir, './serviceworker.bundle.js')) .encoding('utf8') - .read() as string; + .read()) as string; } if (swBundleJsMap === null) { - swBundleJsMap = await plugins.fsInstance + swBundleJsMap = (await plugins.fsInstance .file(plugins.path.join(paths.serviceworkerBundleDir, './serviceworker.bundle.js.map')) .encoding('utf8') - .read() as string; + .read()) as string; } }; let swVersionInfo: interfaces.serviceworker.IRequest_Serviceworker_Backend_VersionInfo['response'] = null; -const serviceworkerHandler = new Handler( - 'GET', - async (req, res) => { - await loadServiceWorkerBundle(); - if (req.path === '/serviceworker.bundle.js') { - res.status(200); - res.set('Content-Type', 'text/javascript'); - res.write(swBundleJs + '\n' + `/** appSemVer: ${swVersionInfo?.appSemVer || 'not set'} */`); - } else if (req.path === '/serviceworker.bundle.js.map') { - res.status(200); - res.set('Content-Type', 'application/json'); - res.write(swBundleJsMap); - } - res.end(); - } -); - export const addServiceWorkerRoute = ( typedserverInstance: TypedServer, swDataFunc: () => interfaces.serviceworker.IRequest_Serviceworker_Backend_VersionInfo['response'] ) => { - // lets the version info as unique string; + // Set the version info swVersionInfo = swDataFunc(); - // the basic stuff - typedserverInstance.server.addRoute('/serviceworker/*splat', serviceworkerHandler); + // Service worker bundle handler + typedserverInstance.addRoute('/serviceworker/*splat', 'GET', async (request: Request) => { + await loadServiceWorkerBundle(); + const url = new URL(request.url); + const path = url.pathname; - // the typed stuff - const typedrouter = new plugins.typedrequest.TypedRouter(); + if (path === '/serviceworker/serviceworker.bundle.js' || path === '/serviceworker.bundle.js') { + return new Response( + swBundleJs + '\n' + `/** appSemVer: ${swVersionInfo?.appSemVer || 'not set'} */`, + { + status: 200, + headers: { 'Content-Type': 'text/javascript' }, + } + ); + } else if ( + path === '/serviceworker/serviceworker.bundle.js.map' || + path === '/serviceworker.bundle.js.map' + ) { + return new Response(swBundleJsMap, { + status: 200, + headers: { 'Content-Type': 'application/json' }, + }); + } - typedrouter.addTypedHandler( - new plugins.typedrequest.TypedHandler( - 'serviceworker_versionInfo', - async (req) => { - const versionInfoResponse = swDataFunc(); - return versionInfoResponse; - } - ) - ); + return null; + }); - typedserverInstance.server.addRoute( - '/sw-typedrequest', - new HandlerTypedRouter(typedrouter) - ); + // Typed request handler for service worker + typedserverInstance.addRoute('/sw-typedrequest', 'POST', async (request: Request) => { + try { + const body = await request.json(); + + // Create a local typed router for service worker requests + const typedrouter = new plugins.typedrequest.TypedRouter(); + + typedrouter.addTypedHandler( + new plugins.typedrequest.TypedHandler( + 'serviceworker_versionInfo', + async () => { + return swDataFunc(); + } + ) + ); + + const response = await typedrouter.routeAndAddResponse(body); + return new Response(plugins.smartjson.stringify(response), { + status: 200, + headers: { 'Content-Type': 'application/json' }, + }); + } catch (error) { + return new Response(JSON.stringify({ error: 'Invalid request' }), { + status: 400, + headers: { 'Content-Type': 'application/json' }, + }); + } + }); }; diff --git a/ts/utilityservers/classes.serviceserver.ts b/ts/utilityservers/classes.serviceserver.ts index 41ca98a..090ab72 100644 --- a/ts/utilityservers/classes.serviceserver.ts +++ b/ts/utilityservers/classes.serviceserver.ts @@ -1,9 +1,7 @@ import { TypedServer } from '../classes.typedserver.js'; -import * as servertools from '../servertools/index.js'; -import * as plugins from '../plugins.js'; export interface ILoleServiceServerConstructorOptions { - addCustomRoutes?: (serverArg: servertools.Server) => Promise; + addCustomRoutes?: (typedserver: TypedServer) => Promise; serviceName: string; serviceVersion: string; serviceDomain: string; @@ -20,12 +18,12 @@ export class UtilityServiceServer { } public async start() { - console.log('starting lole-serviceserver...') + console.log('starting lole-serviceserver...'); this.typedServer = new TypedServer({ cors: true, domain: this.options.serviceDomain, forceSsl: false, - port: this.options.port || 3000, + port: this.options.port || 3000, robots: true, defaultAnswer: async () => { const InfoHtml = (await import('../infohtml/index.js')).InfoHtml; @@ -37,9 +35,9 @@ export class UtilityServiceServer { }, }); - // lets add any custom routes + // Add any custom routes if (this.options.addCustomRoutes) { - await this.options.addCustomRoutes(this.typedServer.server); + await this.options.addCustomRoutes(this.typedServer); } await this.typedServer.start(); diff --git a/ts/utilityservers/classes.websiteserver.ts b/ts/utilityservers/classes.websiteserver.ts index af9c225..a803624 100644 --- a/ts/utilityservers/classes.websiteserver.ts +++ b/ts/utilityservers/classes.websiteserver.ts @@ -1,11 +1,10 @@ import * as interfaces from '../../dist_ts_interfaces/index.js'; import { type IServerOptions, TypedServer } from '../classes.typedserver.js'; -import type { Request, Response } from '../index.js'; import * as plugins from '../plugins.js'; import * as servertools from '../servertools/index.js'; export interface IUtilityWebsiteServerConstructorOptions { - addCustomRoutes?: (serverArg: servertools.Server) => Promise; + addCustomRoutes?: (typedserver: TypedServer) => Promise; appSemVer?: string; domain: string; serveDir: string; @@ -16,7 +15,6 @@ export interface IUtilityWebsiteServerConstructorOptions { * the utility website server implements a best practice server for websites * It supports: * * live reload - * * compression * * serviceworker * * pwa manifest */ @@ -30,7 +28,7 @@ export class UtilityWebsiteServer { } /** - * + * Start the website server */ public async start(portArg = 3000) { this.typedserver = new TypedServer({ @@ -38,8 +36,6 @@ export class UtilityWebsiteServer { injectReload: true, watch: true, serveDir: this.options.serveDir, - enableCompression: true, - preferredCompressionMethod: 'gzip', domain: this.options.domain, forceSsl: false, manifest: { @@ -58,33 +54,32 @@ export class UtilityWebsiteServer { sitemap: true, }); - let lswData: interfaces.serviceworker.IRequest_Serviceworker_Backend_VersionInfo['response'] = - { - appHash: 'xxxxxx', - appSemVer: this.options.appSemVer || 'x.x.x', - }; + let lswData: interfaces.serviceworker.IRequest_Serviceworker_Backend_VersionInfo['response'] = { + appHash: 'xxxxxx', + appSemVer: this.options.appSemVer || 'x.x.x', + }; // -> /lsw* - anything regarding serviceworker servertools.serviceworker.addServiceWorkerRoute(this.typedserver, () => { return lswData; }); - // lets add ads.txt - this.typedserver.server.addRoute( - '/ads.txt', - new servertools.Handler('GET', async (req, res) => { - res.type('txt/plain'); - const adsTxt = - ['google.com, pub-4104137977476459, DIRECT, f08c47fec0942fa0'].join('\n') + '\n'; - res.write(adsTxt); - res.end(); - }) - ); + // ads.txt handler + this.typedserver.addRoute('/ads.txt', 'GET', async () => { + const adsTxt = + ['google.com, pub-4104137977476459, DIRECT, f08c47fec0942fa0'].join('\n') + '\n'; + return new Response(adsTxt, { + status: 200, + headers: { 'Content-Type': 'text/plain' }, + }); + }); - this.typedserver.server.addRoute( + // Asset broker manifest handler + this.typedserver.addRoute( '/assetbroker/manifest/:manifestAsset', - new servertools.Handler('GET', async (req, res) => { - let manifestAssetName = req.params.manifestAsset; + 'GET', + async (request: Request) => { + let manifestAssetName = (request as any).params?.manifestAsset; if (manifestAssetName === 'favicon.png') { manifestAssetName = `favicon_${this.options.domain .replace('.', '') @@ -95,19 +90,19 @@ export class UtilityWebsiteServer { const smartRequest = plugins.smartrequest.SmartRequest.create(); const response = await smartRequest.url(fullOriginAssetUrl).get(); const arrayBuffer = await response.arrayBuffer(); - const dataBuffer: Buffer = Buffer.from(arrayBuffer); - res.type('.png'); - res.write(dataBuffer); - res.end(); - }) + return new Response(arrayBuffer, { + status: 200, + headers: { 'Content-Type': 'image/png' }, + }); + } ); - // lets add any custom routes + // Add any custom routes if (this.options.addCustomRoutes) { - await this.options.addCustomRoutes(this.typedserver.server); + await this.options.addCustomRoutes(this.typedserver); } - // -> /* - serve the files + // Subscribe to serve directory hash changes this.typedserver.serveDirHashSubject.subscribe((appHash: string) => { lswData = { appHash, @@ -115,11 +110,11 @@ export class UtilityWebsiteServer { }; }); - // lets setup the typedrouter chain + // Setup the typedrouter chain this.typedserver.typedrouter.addTypedRouter(this.typedrouter); - // lets start everything - console.log('routes are all set. Startin up now!'); + // Start everything + console.log('routes are all set. Starting up now!'); await this.typedserver.start(); console.log('typedserver started!'); } @@ -127,14 +122,4 @@ export class UtilityWebsiteServer { public async stop() { await this.typedserver.stop(); } - - /** - * allows you to hanlde requests from other server instances without the need to listen for yourself - * note smartexpress allows you start the instance wuith passing >>false<< as second parameter to .start(); - * @param req - * @param res - */ - public async handleRequest(req: Request, res: Response) { - await this.typedserver.server.handleReqRes(req, res); - } } diff --git a/tsconfig.json b/tsconfig.json index dfe5a55..70d3f34 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,5 @@ { "compilerOptions": { - "experimentalDecorators": true, - "useDefineForClassFields": false, "target": "ES2022", "module": "NodeNext", "moduleResolution": "NodeNext",