diff --git a/.serena/.gitignore b/.serena/.gitignore new file mode 100644 index 0000000..14d86ad --- /dev/null +++ b/.serena/.gitignore @@ -0,0 +1 @@ +/cache diff --git a/.serena/project.yml b/.serena/project.yml new file mode 100644 index 0000000..69be979 --- /dev/null +++ b/.serena/project.yml @@ -0,0 +1,67 @@ +# language of the project (csharp, python, rust, java, typescript, go, cpp, or ruby) +# * For C, use cpp +# * For JavaScript, use typescript +# Special requirements: +# * csharp: Requires the presence of a .sln file in the project folder. +language: typescript + +# whether to use the project's gitignore file to ignore files +# Added on 2025-04-07 +ignore_all_files_in_gitignore: true +# list of additional paths to ignore +# same syntax as gitignore, so you can use * and ** +# Was previously called `ignored_dirs`, please update your config if you are using that. +# Added (renamed) on 2025-04-07 +ignored_paths: [] + +# whether the project is in read-only mode +# If set to true, all editing tools will be disabled and attempts to use them will result in an error +# Added on 2025-04-18 +read_only: false + +# list of tool names to exclude. We recommend not excluding any tools, see the readme for more details. +# Below is the complete list of tools for convenience. +# To make sure you have the latest list of tools, and to view their descriptions, +# execute `uv run scripts/print_tool_overview.py`. +# +# * `activate_project`: Activates a project by name. +# * `check_onboarding_performed`: Checks whether project onboarding was already performed. +# * `create_text_file`: Creates/overwrites a file in the project directory. +# * `delete_lines`: Deletes a range of lines within a file. +# * `delete_memory`: Deletes a memory from Serena's project-specific memory store. +# * `execute_shell_command`: Executes a shell command. +# * `find_referencing_code_snippets`: Finds code snippets in which the symbol at the given location is referenced. +# * `find_referencing_symbols`: Finds symbols that reference the symbol at the given location (optionally filtered by type). +# * `find_symbol`: Performs a global (or local) search for symbols with/containing a given name/substring (optionally filtered by type). +# * `get_current_config`: Prints the current configuration of the agent, including the active and available projects, tools, contexts, and modes. +# * `get_symbols_overview`: Gets an overview of the top-level symbols defined in a given file. +# * `initial_instructions`: Gets the initial instructions for the current project. +# Should only be used in settings where the system prompt cannot be set, +# e.g. in clients you have no control over, like Claude Desktop. +# * `insert_after_symbol`: Inserts content after the end of the definition of a given symbol. +# * `insert_at_line`: Inserts content at a given line in a file. +# * `insert_before_symbol`: Inserts content before the beginning of the definition of a given symbol. +# * `list_dir`: Lists files and directories in the given directory (optionally with recursion). +# * `list_memories`: Lists memories in Serena's project-specific memory store. +# * `onboarding`: Performs onboarding (identifying the project structure and essential tasks, e.g. for testing or building). +# * `prepare_for_new_conversation`: Provides instructions for preparing for a new conversation (in order to continue with the necessary context). +# * `read_file`: Reads a file within the project directory. +# * `read_memory`: Reads the memory with the given name from Serena's project-specific memory store. +# * `remove_project`: Removes a project from the Serena configuration. +# * `replace_lines`: Replaces a range of lines within a file with new content. +# * `replace_symbol_body`: Replaces the full definition of a symbol. +# * `restart_language_server`: Restarts the language server, may be necessary when edits not through Serena happen. +# * `search_for_pattern`: Performs a search for a pattern in the project. +# * `summarize_changes`: Provides instructions for summarizing the changes made to the codebase. +# * `switch_modes`: Activates modes by providing a list of their names +# * `think_about_collected_information`: Thinking tool for pondering the completeness of collected information. +# * `think_about_task_adherence`: Thinking tool for determining whether the agent is still on track with the current task. +# * `think_about_whether_you_are_done`: Thinking tool for determining whether the task is truly completed. +# * `write_memory`: Writes a named memory (for future reference) to Serena's project-specific memory store. +excluded_tools: [] + +# initial prompt for the project. It will always be given to the LLM upon activating the project +# (contrary to the memories, which are loaded on demand). +initial_prompt: "" + +project_name: "opendata" diff --git a/changelog.md b/changelog.md index 9ff8317..1cc44ee 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,15 @@ # Changelog +## 2025-10-11 - 1.7.0 - feat(stocks) +Add Marketstack provider (EOD) with tests, exports and documentation updates + +- Add MarketstackProvider implementation (ts/stocks/providers/provider.marketstack.ts) providing EOD single and batch fetching, availability checks and mapping to IStockPrice. +- Export MarketstackProvider from ts/stocks/index.ts so it is available via the public API. +- Add comprehensive Marketstack tests (test/test.marketstack.node.ts) covering registration, health checks, single/batch fetches, caching, ticker/market validation, provider stats and sample output. +- Update README with Marketstack usage examples, configuration, API key instructions and provider/health documentation. +- Bump dev dependency @git.zone/tstest to ^2.4.2 in package.json. +- Add project helper/config files (.claude/settings.local.json, .serena/project.yml and .serena/.gitignore) to support CI/tooling. + ## 2025-09-24 - 1.6.1 - fix(stocks) Fix Yahoo provider request handling and bump dependency versions diff --git a/package.json b/package.json index 6d07345..2b8b188 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "@git.zone/tsbuild": "^2.6.8", "@git.zone/tsbundle": "^2.5.1", "@git.zone/tsrun": "^1.3.3", - "@git.zone/tstest": "^2.3.8", + "@git.zone/tstest": "^2.4.2", "@types/node": "^22.14.0" }, "dependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2ccb764..3ed4213 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -67,8 +67,8 @@ importers: specifier: ^1.3.3 version: 1.3.3 '@git.zone/tstest': - specifier: ^2.3.8 - version: 2.3.8(@aws-sdk/credential-providers@3.840.0)(socks@2.8.5) + specifier: ^2.4.2 + version: 2.4.2(@aws-sdk/credential-providers@3.840.0)(socks@2.8.5) '@types/node': specifier: ^22.14.0 version: 22.14.0 @@ -352,8 +352,8 @@ packages: '@borewit/text-codec@0.1.1': resolution: {integrity: sha512-5L/uBxmjaCIX5h8Z+uu+kA9BQLkc/Wl06UGR5ajNRxu+/XjonB5i8JpgFMrPj3LXTCPA0pv8yxUvbUi+QthGGA==} - '@cloudflare/workers-types@4.20250923.0': - resolution: {integrity: sha512-EMs5wF70f9Dt9QtxX/lSyaZIcMdcDP0VhXOW0u5HrDaIHeXDjPJw76W1lkoGF1x8XAVclhiD5zGJZTdZnoXJiQ==} + '@cloudflare/workers-types@4.20251011.0': + resolution: {integrity: sha512-gQpih+pbq3sP4uXltUeCSbPgZxTNp2gQd8639SaIbQMwgA6oJNHLhIART1fWy6DQACngiRzDVULA2x0ohmkGTQ==} '@colors/colors@1.6.0': resolution: {integrity: sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==} @@ -362,8 +362,8 @@ packages: '@configvault.io/interfaces@1.0.17': resolution: {integrity: sha512-bEcCUR2VBDJsTin8HQh8Uw/mlYl2v8A3jMIaQ+MTB9Hrqd6CZL2dL7iJdWyFl/3EIX+LDxWFR+Oq7liIq7w+1Q==} - '@dabh/diagnostics@2.0.3': - resolution: {integrity: sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==} + '@dabh/diagnostics@2.0.8': + resolution: {integrity: sha512-R4MSXTVnuMzGD7bzHdW2ZhhdPC/igELENcq5IjEverBvq5hn1SXCWcsi6eSsdWP0/Ur+SItRRjAktmdoX/8R/Q==} '@design.estate/dees-comms@1.0.27': resolution: {integrity: sha512-GvzTUwkV442LD60T08iqSoqvhA02Mou5lFvvqBPc4yBUiU7cZISqBx+76xvMgMIEI9Dx9JfTl4/2nW8MoVAanw==} @@ -699,8 +699,8 @@ packages: resolution: {integrity: sha512-DDzWunkxXLtXJTxBf4EioXLwhuqdA2VzdTmOzWrw4Z4Qnms/YM67q36yajwNohAajPYyRz5DayU0ikrceFXyVw==} hasBin: true - '@git.zone/tstest@2.3.8': - resolution: {integrity: sha512-rt7rpR2UwzHXjpqquEvWG4LfzGOGeI6lcR2YyO8pc7lqjhH+xsuaWPUQ5IwFl4Vw4VnR9ZoHBCqkjvxF8ow1wQ==} + '@git.zone/tstest@2.4.2': + resolution: {integrity: sha512-Lcxuruk/ii1xFKNbf2b1lVYtl9d8ppTpqfF7qtWlcEMdLYW4/42wZ3dcG+jQlCPikQngEYfqSVaJSLyAWzkEGQ==} hasBin: true '@happy-dom/global-registrator@15.11.7': @@ -1280,6 +1280,10 @@ packages: resolution: {integrity: sha512-vkzula+IwRvPR6oKQhMYioM3A/oX/lFCZiwuxkQbRhqJS2S4YRY2k7k/SyR2jMf3607HLtbEwlRxi0ndXHMjRg==} engines: {node: '>=18.0.0'} + '@smithy/abort-controller@4.2.0': + resolution: {integrity: sha512-PLUYa+SUKOEZtXFURBu/CNxlsxfaFGxSBPcStL13KpVeVWIfdezWyDqkz7iDLmwnxojXD0s5KzuB5HGHvt4Aeg==} + engines: {node: '>=18.0.0'} + '@smithy/chunked-blob-reader-native@4.1.0': resolution: {integrity: sha512-Bnv0B3nSlfB2mPO0WgM49I/prl7+kamF042rrf3ezJ3Z4C7csPYvyYgZfXTGXwXfj1mAwDWjE/ybIf49PzFzvA==} engines: {node: '>=18.0.0'} @@ -1292,14 +1296,26 @@ packages: resolution: {integrity: sha512-IT6MatgBWagLybZl1xQcURXRICvqz1z3APSCAI9IqdvfCkrA7RaQIEfgC6G/KvfxnDfQUDqFV+ZlixcuFznGBQ==} engines: {node: '>=18.0.0'} + '@smithy/config-resolver@4.3.0': + resolution: {integrity: sha512-9oH+n8AVNiLPK/iK/agOsoWfrKZ3FGP3502tkksd6SRsKMYiu7AFX0YXo6YBADdsAj7C+G/aLKdsafIJHxuCkQ==} + engines: {node: '>=18.0.0'} + '@smithy/core@3.12.0': resolution: {integrity: sha512-zJeAgogZfbwlPGL93y4Z/XNeIN37YCreRUd6YMIRvaq+6RnBK8PPYYIQ85Is/GglPh3kNImD5riDCXbVSDpCiQ==} engines: {node: '>=18.0.0'} + '@smithy/core@3.15.0': + resolution: {integrity: sha512-VJWncXgt+ExNn0U2+Y7UywuATtRYaodGQKFo9mDyh70q+fJGedfrqi2XuKU1BhiLeXgg6RZrW7VEKfeqFhHAJA==} + engines: {node: '>=18.0.0'} + '@smithy/credential-provider-imds@4.1.2': resolution: {integrity: sha512-JlYNq8TShnqCLg0h+afqe2wLAwZpuoSgOyzhYvTgbiKBWRov+uUve+vrZEQO6lkdLOWPh7gK5dtb9dS+KGendg==} engines: {node: '>=18.0.0'} + '@smithy/credential-provider-imds@4.2.0': + resolution: {integrity: sha512-SOhFVvFH4D5HJZytb0bLKxCrSnwcqPiNlrw+S4ZXjMnsC+o9JcUQzbZOEQcA8yv9wJFNhfsUiIUKiEnYL68Big==} + engines: {node: '>=18.0.0'} + '@smithy/eventstream-codec@4.1.1': resolution: {integrity: sha512-PwkQw1hZwHTQB6X5hSUWz2OSeuj5Z6enWuAqke7DgWoP3t6vg3ktPpqPz3Erkn6w+tmsl8Oss6nrgyezoea2Iw==} engines: {node: '>=18.0.0'} @@ -1324,6 +1340,10 @@ packages: resolution: {integrity: sha512-5/3wxKNtV3wO/hk1is+CZUhL8a1yy/U+9u9LKQ9kZTkMsHaQjJhc3stFfiujtMnkITjzWfndGA2f7g9Uh9vKng==} engines: {node: '>=18.0.0'} + '@smithy/fetch-http-handler@5.3.1': + resolution: {integrity: sha512-3AvYYbB+Dv5EPLqnJIAgYw/9+WzeBiUYS8B+rU0pHq5NMQMvrZmevUROS4V2GAt0jEOn9viBzPLrZE+riTNd5Q==} + engines: {node: '>=18.0.0'} + '@smithy/hash-blob-browser@4.1.1': resolution: {integrity: sha512-avAtk++s1e/1VODf+rg7c9R2pB5G9y8yaJaGY4lPZI2+UIqVyuSDMikWjeWfBVmFZ3O7NpDxBbUCyGhThVUKWQ==} engines: {node: '>=18.0.0'} @@ -1332,6 +1352,10 @@ packages: resolution: {integrity: sha512-H9DIU9WBLhYrvPs9v4sYvnZ1PiAI0oc8CgNQUJ1rpN3pP7QADbTOUjchI2FB764Ub0DstH5xbTqcMJu1pnVqxA==} engines: {node: '>=18.0.0'} + '@smithy/hash-node@4.2.0': + resolution: {integrity: sha512-ugv93gOhZGysTctZh9qdgng8B+xO0cj+zN0qAZ+Sgh7qTQGPOJbMdIuyP89KNfUyfAqFSNh5tMvC+h2uCpmTtA==} + engines: {node: '>=18.0.0'} + '@smithy/hash-stream-node@4.1.1': resolution: {integrity: sha512-3ztT4pV0Moazs3JAYFdfKk11kYFDo4b/3R3+xVjIm6wY9YpJf+xfz+ocEnNKcWAdcmSMqi168i2EMaKmJHbJMA==} engines: {node: '>=18.0.0'} @@ -1340,6 +1364,10 @@ packages: resolution: {integrity: sha512-1AqLyFlfrrDkyES8uhINRlJXmHA2FkG+3DY8X+rmLSqmFwk3DJnvhyGzyByPyewh2jbmV+TYQBEfngQax8IFGg==} engines: {node: '>=18.0.0'} + '@smithy/invalid-dependency@4.2.0': + resolution: {integrity: sha512-ZmK5X5fUPAbtvRcUPtk28aqIClVhbfcmfoS4M7UQBTnDdrNxhsrxYVv0ZEl5NaPSyExsPWqL4GsPlRvtlwg+2A==} + engines: {node: '>=18.0.0'} + '@smithy/is-array-buffer@2.2.0': resolution: {integrity: sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==} engines: {node: '>=14.0.0'} @@ -1348,6 +1376,10 @@ packages: resolution: {integrity: sha512-ePTYUOV54wMogio+he4pBybe8fwg4sDvEVDBU8ZlHOZXbXK3/C0XfJgUCu6qAZcawv05ZhZzODGUerFBPsPUDQ==} engines: {node: '>=18.0.0'} + '@smithy/is-array-buffer@4.2.0': + resolution: {integrity: sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ==} + engines: {node: '>=18.0.0'} + '@smithy/md5-js@4.1.1': resolution: {integrity: sha512-MvWXKK743BuHjr/hnWuT6uStdKEaoqxHAQUvbKJPPZM5ZojTNFI5D+47BoQfBE5RgGlRRty05EbWA+NXDv+hIA==} engines: {node: '>=18.0.0'} @@ -1356,82 +1388,162 @@ packages: resolution: {integrity: sha512-9wlfBBgTsRvC2JxLJxv4xDGNBrZuio3AgSl0lSFX7fneW2cGskXTYpFxCdRYD2+5yzmsiTuaAJD1Wp7gWt9y9w==} engines: {node: '>=18.0.0'} + '@smithy/middleware-content-length@4.2.0': + resolution: {integrity: sha512-6ZAnwrXFecrA4kIDOcz6aLBhU5ih2is2NdcZtobBDSdSHtE9a+MThB5uqyK4XXesdOCvOcbCm2IGB95birTSOQ==} + engines: {node: '>=18.0.0'} + '@smithy/middleware-endpoint@4.2.4': resolution: {integrity: sha512-FZ4hzupOmthm8Q8ujYrd0I+/MHwVMuSTdkDtIQE0xVuvJt9pLT6Q+b0p4/t+slDyrpcf+Wj7SN+ZqT5OryaaZg==} engines: {node: '>=18.0.0'} + '@smithy/middleware-endpoint@4.3.1': + resolution: {integrity: sha512-JtM4SjEgImLEJVXdsbvWHYiJ9dtuKE8bqLlvkvGi96LbejDL6qnVpVxEFUximFodoQbg0Gnkyff9EKUhFhVJFw==} + engines: {node: '>=18.0.0'} + '@smithy/middleware-retry@4.3.0': resolution: {integrity: sha512-qhEX9745fAxZvtLM4bQJAVC98elWjiMO2OiHl1s6p7hUzS4QfZO1gXUYNwEK8m0J6NoCD5W52ggWxbIDHI0XSg==} engines: {node: '>=18.0.0'} + '@smithy/middleware-retry@4.4.1': + resolution: {integrity: sha512-wXxS4ex8cJJteL0PPQmWYkNi9QKDWZIpsndr0wZI2EL+pSSvA/qqxXU60gBOJoIc2YgtZSWY/PE86qhKCCKP1w==} + engines: {node: '>=18.0.0'} + '@smithy/middleware-serde@4.1.1': resolution: {integrity: sha512-lh48uQdbCoj619kRouev5XbWhCwRKLmphAif16c4J6JgJ4uXjub1PI6RL38d3BLliUvSso6klyB/LTNpWSNIyg==} engines: {node: '>=18.0.0'} + '@smithy/middleware-serde@4.2.0': + resolution: {integrity: sha512-rpTQ7D65/EAbC6VydXlxjvbifTf4IH+sADKg6JmAvhkflJO2NvDeyU9qsWUNBelJiQFcXKejUHWRSdmpJmEmiw==} + engines: {node: '>=18.0.0'} + '@smithy/middleware-stack@4.1.1': resolution: {integrity: sha512-ygRnniqNcDhHzs6QAPIdia26M7e7z9gpkIMUe/pK0RsrQ7i5MblwxY8078/QCnGq6AmlUUWgljK2HlelsKIb/A==} engines: {node: '>=18.0.0'} + '@smithy/middleware-stack@4.2.0': + resolution: {integrity: sha512-G5CJ//eqRd9OARrQu9MK1H8fNm2sMtqFh6j8/rPozhEL+Dokpvi1Og+aCixTuwDAGZUkJPk6hJT5jchbk/WCyg==} + engines: {node: '>=18.0.0'} + '@smithy/node-config-provider@4.2.2': resolution: {integrity: sha512-SYGTKyPvyCfEzIN5rD8q/bYaOPZprYUPD2f5g9M7OjaYupWOoQFYJ5ho+0wvxIRf471i2SR4GoiZ2r94Jq9h6A==} engines: {node: '>=18.0.0'} + '@smithy/node-config-provider@4.3.0': + resolution: {integrity: sha512-5QgHNuWdT9j9GwMPPJCKxy2KDxZ3E5l4M3/5TatSZrqYVoEiqQrDfAq8I6KWZw7RZOHtVtCzEPdYz7rHZixwcA==} + engines: {node: '>=18.0.0'} + '@smithy/node-http-handler@4.2.1': resolution: {integrity: sha512-REyybygHlxo3TJICPF89N2pMQSf+p+tBJqpVe1+77Cfi9HBPReNjTgtZ1Vg73exq24vkqJskKDpfF74reXjxfw==} engines: {node: '>=18.0.0'} + '@smithy/node-http-handler@4.3.0': + resolution: {integrity: sha512-RHZ/uWCmSNZ8cneoWEVsVwMZBKy/8123hEpm57vgGXA3Irf/Ja4v9TVshHK2ML5/IqzAZn0WhINHOP9xl+Qy6Q==} + engines: {node: '>=18.0.0'} + '@smithy/property-provider@4.1.1': resolution: {integrity: sha512-gm3ZS7DHxUbzC2wr8MUCsAabyiXY0gaj3ROWnhSx/9sPMc6eYLMM4rX81w1zsMaObj2Lq3PZtNCC1J6lpEY7zg==} engines: {node: '>=18.0.0'} + '@smithy/property-provider@4.2.0': + resolution: {integrity: sha512-rV6wFre0BU6n/tx2Ztn5LdvEdNZ2FasQbPQmDOPfV9QQyDmsCkOAB0osQjotRCQg+nSKFmINhyda0D3AnjSBJw==} + engines: {node: '>=18.0.0'} + '@smithy/protocol-http@5.2.1': resolution: {integrity: sha512-T8SlkLYCwfT/6m33SIU/JOVGNwoelkrvGjFKDSDtVvAXj/9gOT78JVJEas5a+ETjOu4SVvpCstKgd0PxSu/aHw==} engines: {node: '>=18.0.0'} + '@smithy/protocol-http@5.3.0': + resolution: {integrity: sha512-6POSYlmDnsLKb7r1D3SVm7RaYW6H1vcNcTWGWrF7s9+2noNYvUsm7E4tz5ZQ9HXPmKn6Hb67pBDRIjrT4w/d7Q==} + engines: {node: '>=18.0.0'} + '@smithy/querystring-builder@4.1.1': resolution: {integrity: sha512-J9b55bfimP4z/Jg1gNo+AT84hr90p716/nvxDkPGCD4W70MPms0h8KF50RDRgBGZeL83/u59DWNqJv6tEP/DHA==} engines: {node: '>=18.0.0'} + '@smithy/querystring-builder@4.2.0': + resolution: {integrity: sha512-Q4oFD0ZmI8yJkiPPeGUITZj++4HHYCW3pYBYfIobUCkYpI6mbkzmG1MAQQ3lJYYWj3iNqfzOenUZu+jqdPQ16A==} + engines: {node: '>=18.0.0'} + '@smithy/querystring-parser@4.1.1': resolution: {integrity: sha512-63TEp92YFz0oQ7Pj9IuI3IgnprP92LrZtRAkE3c6wLWJxfy/yOPRt39IOKerVr0JS770olzl0kGafXlAXZ1vng==} engines: {node: '>=18.0.0'} + '@smithy/querystring-parser@4.2.0': + resolution: {integrity: sha512-BjATSNNyvVbQxOOlKse0b0pSezTWGMvA87SvoFoFlkRsKXVsN3bEtjCxvsNXJXfnAzlWFPaT9DmhWy1vn0sNEA==} + engines: {node: '>=18.0.0'} + '@smithy/service-error-classification@4.1.2': resolution: {integrity: sha512-Kqd8wyfmBWHZNppZSMfrQFpc3M9Y/kjyN8n8P4DqJJtuwgK1H914R471HTw7+RL+T7+kI1f1gOnL7Vb5z9+NgQ==} engines: {node: '>=18.0.0'} + '@smithy/service-error-classification@4.2.0': + resolution: {integrity: sha512-Ylv1ttUeKatpR0wEOMnHf1hXMktPUMObDClSWl2TpCVT4DwtJhCeighLzSLbgH3jr5pBNM0LDXT5yYxUvZ9WpA==} + engines: {node: '>=18.0.0'} + '@smithy/shared-ini-file-loader@4.2.0': resolution: {integrity: sha512-OQTfmIEp2LLuWdxa8nEEPhZmiOREO6bcB6pjs0AySf4yiZhl6kMOfqmcwcY8BaBPX+0Tb+tG7/Ia/6mwpoZ7Pw==} engines: {node: '>=18.0.0'} + '@smithy/shared-ini-file-loader@4.3.0': + resolution: {integrity: sha512-VCUPPtNs+rKWlqqntX0CbVvWyjhmX30JCtzO+s5dlzzxrvSfRh5SY0yxnkirvc1c80vdKQttahL71a9EsdolSQ==} + engines: {node: '>=18.0.0'} + '@smithy/signature-v4@5.2.1': resolution: {integrity: sha512-M9rZhWQLjlQVCCR37cSjHfhriGRN+FQ8UfgrYNufv66TJgk+acaggShl3KS5U/ssxivvZLlnj7QH2CUOKlxPyA==} engines: {node: '>=18.0.0'} + '@smithy/signature-v4@5.3.0': + resolution: {integrity: sha512-MKNyhXEs99xAZaFhm88h+3/V+tCRDQ+PrDzRqL0xdDpq4gjxcMmf5rBA3YXgqZqMZ/XwemZEurCBQMfxZOWq/g==} + engines: {node: '>=18.0.0'} + '@smithy/smithy-client@4.6.4': resolution: {integrity: sha512-qL7O3VDyfzCSN9r+sdbQXGhaHtrfSJL30En6Jboj0I3bobf2g1/T0eP2L4qxqrEW26gWhJ4THI4ElVVLjYyBHg==} engines: {node: '>=18.0.0'} + '@smithy/smithy-client@4.7.1': + resolution: {integrity: sha512-WXVbiyNf/WOS/RHUoFMkJ6leEVpln5ojCjNBnzoZeMsnCg3A0BRhLK3WYc4V7PmYcYPZh9IYzzAg9XcNSzYxYQ==} + engines: {node: '>=18.0.0'} + '@smithy/types@4.5.0': resolution: {integrity: sha512-RkUpIOsVlAwUIZXO1dsz8Zm+N72LClFfsNqf173catVlvRZiwPy0x2u0JLEA4byreOPKDZPGjmPDylMoP8ZJRg==} engines: {node: '>=18.0.0'} + '@smithy/types@4.6.0': + resolution: {integrity: sha512-4lI9C8NzRPOv66FaY1LL1O/0v0aLVrq/mXP/keUa9mJOApEeae43LsLd2kZRUJw91gxOQfLIrV3OvqPgWz1YsA==} + engines: {node: '>=18.0.0'} + '@smithy/url-parser@4.1.1': resolution: {integrity: sha512-bx32FUpkhcaKlEoOMbScvc93isaSiRM75pQ5IgIBaMkT7qMlIibpPRONyx/0CvrXHzJLpOn/u6YiDX2hcvs7Dg==} engines: {node: '>=18.0.0'} + '@smithy/url-parser@4.2.0': + resolution: {integrity: sha512-AlBmD6Idav2ugmoAL6UtR6ItS7jU5h5RNqLMZC7QrLCoITA9NzIN3nx9GWi8g4z1pfWh2r9r96SX/jHiNwPJ9A==} + engines: {node: '>=18.0.0'} + '@smithy/util-base64@4.1.0': resolution: {integrity: sha512-RUGd4wNb8GeW7xk+AY5ghGnIwM96V0l2uzvs/uVHf+tIuVX2WSvynk5CxNoBCsM2rQRSZElAo9rt3G5mJ/gktQ==} engines: {node: '>=18.0.0'} + '@smithy/util-base64@4.3.0': + resolution: {integrity: sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ==} + engines: {node: '>=18.0.0'} + '@smithy/util-body-length-browser@4.1.0': resolution: {integrity: sha512-V2E2Iez+bo6bUMOTENPr6eEmepdY8Hbs+Uc1vkDKgKNA/brTJqOW/ai3JO1BGj9GbCeLqw90pbbH7HFQyFotGQ==} engines: {node: '>=18.0.0'} + '@smithy/util-body-length-browser@4.2.0': + resolution: {integrity: sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg==} + engines: {node: '>=18.0.0'} + '@smithy/util-body-length-node@4.1.0': resolution: {integrity: sha512-BOI5dYjheZdgR9XiEM3HJcEMCXSoqbzu7CzIgYrx0UtmvtC3tC2iDGpJLsSRFffUpy8ymsg2ARMP5fR8mtuUQQ==} engines: {node: '>=18.0.0'} + '@smithy/util-body-length-node@4.2.1': + resolution: {integrity: sha512-h53dz/pISVrVrfxV1iqXlx5pRg3V2YWFcSQyPyXZRrZoZj4R4DeWRDo1a7dd3CPTcFi3kE+98tuNyD2axyZReA==} + engines: {node: '>=18.0.0'} + '@smithy/util-buffer-from@2.2.0': resolution: {integrity: sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==} engines: {node: '>=14.0.0'} @@ -1440,42 +1552,82 @@ packages: resolution: {integrity: sha512-N6yXcjfe/E+xKEccWEKzK6M+crMrlwaCepKja0pNnlSkm6SjAeLKKA++er5Ba0I17gvKfN/ThV+ZOx/CntKTVw==} engines: {node: '>=18.0.0'} + '@smithy/util-buffer-from@4.2.0': + resolution: {integrity: sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew==} + engines: {node: '>=18.0.0'} + '@smithy/util-config-provider@4.1.0': resolution: {integrity: sha512-swXz2vMjrP1ZusZWVTB/ai5gK+J8U0BWvP10v9fpcFvg+Xi/87LHvHfst2IgCs1i0v4qFZfGwCmeD/KNCdJZbQ==} engines: {node: '>=18.0.0'} + '@smithy/util-config-provider@4.2.0': + resolution: {integrity: sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q==} + engines: {node: '>=18.0.0'} + '@smithy/util-defaults-mode-browser@4.1.4': resolution: {integrity: sha512-mLDJ1s4eA3vwOGaQOEPlg5LB4LdZUUMpB5UMOMofeGhWqiS7WR7dTpLiNi9zVn+YziKUd3Af5NLfxDs7NJqmIw==} engines: {node: '>=18.0.0'} + '@smithy/util-defaults-mode-browser@4.3.0': + resolution: {integrity: sha512-H4MAj8j8Yp19Mr7vVtGgi7noJjvjJbsKQJkvNnLlrIFduRFT5jq5Eri1k838YW7rN2g5FTnXpz5ktKVr1KVgPQ==} + engines: {node: '>=18.0.0'} + '@smithy/util-defaults-mode-node@4.1.4': resolution: {integrity: sha512-pjX2iMTcOASaSanAd7bu6i3fcMMezr3NTr8Rh64etB0uHRZi+Aw86DoCxPESjY4UTIuA06hhqtTtw95o//imYA==} engines: {node: '>=18.0.0'} + '@smithy/util-defaults-mode-node@4.2.1': + resolution: {integrity: sha512-PuDcgx7/qKEMzV1QFHJ7E4/MMeEjaA7+zS5UNcHCLPvvn59AeZQ0DSDGMpqC2xecfa/1cNGm4l8Ec/VxCuY7Ug==} + engines: {node: '>=18.0.0'} + '@smithy/util-endpoints@3.1.2': resolution: {integrity: sha512-+AJsaaEGb5ySvf1SKMRrPZdYHRYSzMkCoK16jWnIMpREAnflVspMIDeCVSZJuj+5muZfgGpNpijE3mUNtjv01Q==} engines: {node: '>=18.0.0'} + '@smithy/util-endpoints@3.2.0': + resolution: {integrity: sha512-TXeCn22D56vvWr/5xPqALc9oO+LN+QpFjrSM7peG/ckqEPoI3zaKZFp+bFwfmiHhn5MGWPaLCqDOJPPIixk9Wg==} + engines: {node: '>=18.0.0'} + '@smithy/util-hex-encoding@4.1.0': resolution: {integrity: sha512-1LcueNN5GYC4tr8mo14yVYbh/Ur8jHhWOxniZXii+1+ePiIbsLZ5fEI0QQGtbRRP5mOhmooos+rLmVASGGoq5w==} engines: {node: '>=18.0.0'} + '@smithy/util-hex-encoding@4.2.0': + resolution: {integrity: sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw==} + engines: {node: '>=18.0.0'} + '@smithy/util-middleware@4.1.1': resolution: {integrity: sha512-CGmZ72mL29VMfESz7S6dekqzCh8ZISj3B+w0g1hZFXaOjGTVaSqfAEFAq8EGp8fUL+Q2l8aqNmt8U1tglTikeg==} engines: {node: '>=18.0.0'} + '@smithy/util-middleware@4.2.0': + resolution: {integrity: sha512-u9OOfDa43MjagtJZ8AapJcmimP+K2Z7szXn8xbty4aza+7P1wjFmy2ewjSbhEiYQoW1unTlOAIV165weYAaowA==} + engines: {node: '>=18.0.0'} + '@smithy/util-retry@4.1.2': resolution: {integrity: sha512-NCgr1d0/EdeP6U5PSZ9Uv5SMR5XRRYoVr1kRVtKZxWL3tixEL3UatrPIMFZSKwHlCcp2zPLDvMubVDULRqeunA==} engines: {node: '>=18.0.0'} + '@smithy/util-retry@4.2.0': + resolution: {integrity: sha512-BWSiuGbwRnEE2SFfaAZEX0TqaxtvtSYPM/J73PFVm+A29Fg1HTPiYFb8TmX1DXp4hgcdyJcNQmprfd5foeORsg==} + engines: {node: '>=18.0.0'} + '@smithy/util-stream@4.3.2': resolution: {integrity: sha512-Ka+FA2UCC/Q1dEqUanCdpqwxOFdf5Dg2VXtPtB1qxLcSGh5C1HdzklIt18xL504Wiy9nNUKwDMRTVCbKGoK69g==} engines: {node: '>=18.0.0'} + '@smithy/util-stream@4.5.0': + resolution: {integrity: sha512-0TD5M5HCGu5diEvZ/O/WquSjhJPasqv7trjoqHyWjNh/FBeBl7a0ztl9uFMOsauYtRfd8jvpzIAQhDHbx+nvZw==} + engines: {node: '>=18.0.0'} + '@smithy/util-uri-escape@4.1.0': resolution: {integrity: sha512-b0EFQkq35K5NHUYxU72JuoheM6+pytEVUGlTwiFxWFpmddA+Bpz3LgsPRIpBk8lnPE47yT7AF2Egc3jVnKLuPg==} engines: {node: '>=18.0.0'} + '@smithy/util-uri-escape@4.2.0': + resolution: {integrity: sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA==} + engines: {node: '>=18.0.0'} + '@smithy/util-utf8@2.3.0': resolution: {integrity: sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==} engines: {node: '>=14.0.0'} @@ -1484,6 +1636,10 @@ packages: resolution: {integrity: sha512-mEu1/UIXAdNYuBcyEPbjScKi/+MQVXNIuY/7Cm5XLIWe319kDrT5SizBE95jqtmEXoDbGoZxKLCMttdZdqTZKQ==} engines: {node: '>=18.0.0'} + '@smithy/util-utf8@4.2.0': + resolution: {integrity: sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw==} + engines: {node: '>=18.0.0'} + '@smithy/util-waiter@4.1.1': resolution: {integrity: sha512-PJBmyayrlfxM7nbqjomF4YcT1sApQwZio0NHSsT0EzhJqljRmvhzqZua43TyEs80nJk2Cn2FGPg/N8phH6KeCQ==} engines: {node: '>=18.0.0'} @@ -1492,6 +1648,13 @@ packages: resolution: {integrity: sha512-OlA/yZHh0ekYFnbUkmYBDQPE6fGfdrvgz39ktp8Xf+FA6BfxLejPTMDOG0Nfk5/rDySAz1dRbFf24zaAFYVXlQ==} engines: {node: '>=18.0.0'} + '@smithy/uuid@1.1.0': + resolution: {integrity: sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw==} + engines: {node: '>=18.0.0'} + + '@so-ric/colorspace@1.1.6': + resolution: {integrity: sha512-/KiKkpHNOBgkFJwu9sh48LkHSMYGyuTcSFK/qMBdnOAlrRJzRSXAOFB5qwzaVQuDl8wAvHVMkaASQDReTahxuw==} + '@socket.io/component-emitter@3.1.2': resolution: {integrity: sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==} @@ -1557,8 +1720,8 @@ packages: '@types/express-serve-static-core@5.0.3': resolution: {integrity: sha512-JEhMNwUJt7bw728CydvYzntD0XJeTmDnvwLlbfbAhE7Tbslm/ax6bdIiUwTgeVlZTsJQPwZwKpAkyDtIjsvx3g==} - '@types/express-serve-static-core@5.0.7': - resolution: {integrity: sha512-R+33OsgWw7rOhD1emjU7dzCDHucJrgJXMA5PYCzJxVil0dsyx5iBEPHqpPfiKNJQb7lZ1vxwoLR4Z87bBUpeGQ==} + '@types/express-serve-static-core@5.1.0': + resolution: {integrity: sha512-jnHMsrd0Mwa9Cf4IdOzbz543y4XJepXrbia2T4b6+spXC2We3t1y6K44D3mR8XMFSXMCf3/l7rCgddfx7UNVBA==} '@types/express@5.0.0': resolution: {integrity: sha512-DvZriSMehGHL1ZNLzi6MidnsDhUZM/x2pRdDIKdwbUNqqwHxMlRdkxtn6/EPKyqKpHqTl/4nRZsRNLpZxZRpPQ==} @@ -1647,11 +1810,14 @@ packages: '@types/send@0.17.5': resolution: {integrity: sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==} + '@types/send@1.2.0': + resolution: {integrity: sha512-zBF6vZJn1IaMpg3xUF25VK3gd3l8zwE0ZLRX7dsQyQi+jp4E8mMDJNGDYnYse+bQhYwWERTxVwHpi3dMOq7RKQ==} + '@types/serve-static@1.15.7': resolution: {integrity: sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==} - '@types/serve-static@1.15.8': - resolution: {integrity: sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==} + '@types/serve-static@1.15.9': + resolution: {integrity: sha512-dOTIuqpWLyl3BBXU3maNQsS4A3zuuoYRNIvYSxxhebPfXg2mzWQEPne/nlJ37yOse6uGgR386uTpdsx4D0QZWA==} '@types/symbol-tree@3.2.5': resolution: {integrity: sha512-zXnnyENt1TYQcS21MkPaJCVjfcPq7p7yc5mo5JACuumXp6sly5jnlS0IokHd+xmmuCbx6V7JqkMBpswR+nZAcw==} @@ -1954,20 +2120,27 @@ packages: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} + color-convert@3.1.2: + resolution: {integrity: sha512-UNqkvCDXstVck3kdowtOTWROIJQwafjOfXSmddoDrXo4cewMKmusCeF22Q24zvjR8nwWib/3S/dfyzPItPEiJg==} + engines: {node: '>=14.6'} + color-name@1.1.3: resolution: {integrity: sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=} color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - color-string@1.9.1: - resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + color-name@2.0.2: + resolution: {integrity: sha512-9vEt7gE16EW7Eu7pvZnR0abW9z6ufzhXxGXZEVU9IqPdlsUiMwJeJfRtq0zePUmnbHGT9zajca7mX8zgoayo4A==} + engines: {node: '>=12.20'} - color@3.2.1: - resolution: {integrity: sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==} + color-string@2.1.2: + resolution: {integrity: sha512-RxmjYxbWemV9gKu4zPgiZagUxbH3RQpEIO77XoSSX0ivgABDZ+h8Zuash/EMFLTI4N9QgFPOJ6JQpPZKFxa+dA==} + engines: {node: '>=18'} - colorspace@1.1.4: - resolution: {integrity: sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==} + color@5.0.2: + resolution: {integrity: sha512-e2hz5BzbUPcYlIRHo8ieAhYgoajrJr+hWoceg6E345TPsATMUKqDgzt8fSXZJJbxfpiPzkWyphz8yn8At7q3fA==} + engines: {node: '>=18'} combined-stream@1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} @@ -2316,8 +2489,8 @@ packages: resolution: {integrity: sha512-cB507r5T3D55DfclY01GLkninZLfU7HXV/mhVRTnTRm5k2u+fY7Fof2dBkr80p5t7G7dlA/G5dI87QiMdPpMCQ==} engines: {node: '>=18'} - fake-indexeddb@6.2.2: - resolution: {integrity: sha512-SGbf7fzjeHz3+12NO1dYigcYn4ivviaeULV5yY5rdGihBvvgwMds4r4UBbNIUMwkze57KTDm32rq3j1Az8mzEw==} + fake-indexeddb@6.2.3: + resolution: {integrity: sha512-idzJXFtDIHNShFZ9ssS8IdsRgAP0t9zwWvSdCKsWK2dgh2xcXA6/2Oteaxar5GJqmwzZXCrKRO6F5IEiR4yJzw==} engines: {node: '>=18'} fast-deep-equal@3.1.3: @@ -2455,6 +2628,10 @@ packages: function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + generator-function@2.0.1: + resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==} + engines: {node: '>= 0.4'} + get-intrinsic@1.2.6: resolution: {integrity: sha512-qxsEs+9A+u85HhllWJJFicJfPDhRmjzoYdl64aMWW9yRIJmSyxdn8IEkuIM530/7T+lv0TIHd8L6Q/ra0tEoeA==} engines: {node: '>= 0.4'} @@ -2631,9 +2808,6 @@ packages: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} - is-arrayish@0.3.4: - resolution: {integrity: sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==} - is-docker@2.2.1: resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} engines: {node: '>=8'} @@ -2643,8 +2817,8 @@ packages: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} - is-generator-function@1.1.0: - resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==} + is-generator-function@1.1.2: + resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==} engines: {node: '>= 0.4'} is-ip@4.0.0: @@ -3576,9 +3750,6 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} - simple-swizzle@0.2.4: - resolution: {integrity: sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==} - smart-buffer@4.2.0: resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} @@ -3707,8 +3878,8 @@ packages: os: [darwin, linux, win32, freebsd, openbsd, netbsd, sunos, android] hasBin: true - systeminformation@5.27.10: - resolution: {integrity: sha512-jkeOerLSwLZqJrPHCYltlKHu0PisdepIuS4GwjFFtgQUG/5AQPVZekkECuULqdP0cgrrIHW8Nl8J7WQXo5ypEg==} + systeminformation@5.27.11: + resolution: {integrity: sha512-K3Lto/2m3K2twmKHdgx5B+0in9qhXK4YnoT9rIlgwN/4v7OV5c8IjbeAUkuky/6VzCQC7iKCAqi8rZathCdjHg==} engines: {node: '>=8.0.0'} os: [darwin, linux, win32, freebsd, openbsd, netbsd, sunos, android] hasBin: true @@ -3941,8 +4112,8 @@ packages: resolution: {integrity: sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==} engines: {node: '>= 12.0.0'} - winston@3.17.0: - resolution: {integrity: sha512-DLiFIXYC5fMPxaRg832S6F5mJYvePtmO5G9v9IgUFPhXm9/GkXarH/TUrBAVzhTCzAj9anE/+GjrgXp/54nOgw==} + winston@3.18.3: + resolution: {integrity: sha512-NoBZauFNNWENgsnC9YpgyYwOVrl2m58PpQ8lNHjV3kosGs7KJ7Npk9pCUE+WJlawVSe8mykWDKWFSVfs3QO9ww==} engines: {node: '>= 12.0.0'} wrap-ansi@7.0.0: @@ -4056,7 +4227,7 @@ snapshots: '@api.global/typedrequest': 3.1.10 '@api.global/typedrequest-interfaces': 3.0.19 '@api.global/typedsocket': 3.0.1 - '@cloudflare/workers-types': 4.20250923.0 + '@cloudflare/workers-types': 4.20251011.0 '@design.estate/dees-comms': 1.0.27 '@push.rocks/lik': 6.2.2 '@push.rocks/smartchok': 1.1.1 @@ -4178,31 +4349,31 @@ snapshots: '@aws-sdk/util-endpoints': 3.840.0 '@aws-sdk/util-user-agent-browser': 3.840.0 '@aws-sdk/util-user-agent-node': 3.840.0 - '@smithy/config-resolver': 4.2.2 - '@smithy/core': 3.12.0 - '@smithy/fetch-http-handler': 5.2.1 - '@smithy/hash-node': 4.1.1 - '@smithy/invalid-dependency': 4.1.1 - '@smithy/middleware-content-length': 4.1.1 - '@smithy/middleware-endpoint': 4.2.4 - '@smithy/middleware-retry': 4.3.0 - '@smithy/middleware-serde': 4.1.1 - '@smithy/middleware-stack': 4.1.1 - '@smithy/node-config-provider': 4.2.2 - '@smithy/node-http-handler': 4.2.1 - '@smithy/protocol-http': 5.2.1 - '@smithy/smithy-client': 4.6.4 - '@smithy/types': 4.5.0 - '@smithy/url-parser': 4.1.1 - '@smithy/util-base64': 4.1.0 - '@smithy/util-body-length-browser': 4.1.0 - '@smithy/util-body-length-node': 4.1.0 - '@smithy/util-defaults-mode-browser': 4.1.4 - '@smithy/util-defaults-mode-node': 4.1.4 - '@smithy/util-endpoints': 3.1.2 - '@smithy/util-middleware': 4.1.1 - '@smithy/util-retry': 4.1.2 - '@smithy/util-utf8': 4.1.0 + '@smithy/config-resolver': 4.3.0 + '@smithy/core': 3.15.0 + '@smithy/fetch-http-handler': 5.3.1 + '@smithy/hash-node': 4.2.0 + '@smithy/invalid-dependency': 4.2.0 + '@smithy/middleware-content-length': 4.2.0 + '@smithy/middleware-endpoint': 4.3.1 + '@smithy/middleware-retry': 4.4.1 + '@smithy/middleware-serde': 4.2.0 + '@smithy/middleware-stack': 4.2.0 + '@smithy/node-config-provider': 4.3.0 + '@smithy/node-http-handler': 4.3.0 + '@smithy/protocol-http': 5.3.0 + '@smithy/smithy-client': 4.7.1 + '@smithy/types': 4.6.0 + '@smithy/url-parser': 4.2.0 + '@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.0 + '@smithy/util-defaults-mode-node': 4.2.1 + '@smithy/util-endpoints': 3.2.0 + '@smithy/util-middleware': 4.2.0 + '@smithy/util-retry': 4.2.0 + '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt @@ -4285,31 +4456,31 @@ snapshots: '@aws-sdk/util-endpoints': 3.840.0 '@aws-sdk/util-user-agent-browser': 3.840.0 '@aws-sdk/util-user-agent-node': 3.840.0 - '@smithy/config-resolver': 4.2.2 - '@smithy/core': 3.12.0 - '@smithy/fetch-http-handler': 5.2.1 - '@smithy/hash-node': 4.1.1 - '@smithy/invalid-dependency': 4.1.1 - '@smithy/middleware-content-length': 4.1.1 - '@smithy/middleware-endpoint': 4.2.4 - '@smithy/middleware-retry': 4.3.0 - '@smithy/middleware-serde': 4.1.1 - '@smithy/middleware-stack': 4.1.1 - '@smithy/node-config-provider': 4.2.2 - '@smithy/node-http-handler': 4.2.1 - '@smithy/protocol-http': 5.2.1 - '@smithy/smithy-client': 4.6.4 - '@smithy/types': 4.5.0 - '@smithy/url-parser': 4.1.1 - '@smithy/util-base64': 4.1.0 - '@smithy/util-body-length-browser': 4.1.0 - '@smithy/util-body-length-node': 4.1.0 - '@smithy/util-defaults-mode-browser': 4.1.4 - '@smithy/util-defaults-mode-node': 4.1.4 - '@smithy/util-endpoints': 3.1.2 - '@smithy/util-middleware': 4.1.1 - '@smithy/util-retry': 4.1.2 - '@smithy/util-utf8': 4.1.0 + '@smithy/config-resolver': 4.3.0 + '@smithy/core': 3.15.0 + '@smithy/fetch-http-handler': 5.3.1 + '@smithy/hash-node': 4.2.0 + '@smithy/invalid-dependency': 4.2.0 + '@smithy/middleware-content-length': 4.2.0 + '@smithy/middleware-endpoint': 4.3.1 + '@smithy/middleware-retry': 4.4.1 + '@smithy/middleware-serde': 4.2.0 + '@smithy/middleware-stack': 4.2.0 + '@smithy/node-config-provider': 4.3.0 + '@smithy/node-http-handler': 4.3.0 + '@smithy/protocol-http': 5.3.0 + '@smithy/smithy-client': 4.7.1 + '@smithy/types': 4.6.0 + '@smithy/url-parser': 4.2.0 + '@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.0 + '@smithy/util-defaults-mode-node': 4.2.1 + '@smithy/util-endpoints': 3.2.0 + '@smithy/util-middleware': 4.2.0 + '@smithy/util-retry': 4.2.0 + '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt @@ -4362,17 +4533,17 @@ snapshots: dependencies: '@aws-sdk/types': 3.840.0 '@aws-sdk/xml-builder': 3.821.0 - '@smithy/core': 3.12.0 - '@smithy/node-config-provider': 4.2.2 - '@smithy/property-provider': 4.1.1 - '@smithy/protocol-http': 5.2.1 - '@smithy/signature-v4': 5.2.1 - '@smithy/smithy-client': 4.6.4 - '@smithy/types': 4.5.0 - '@smithy/util-base64': 4.1.0 - '@smithy/util-body-length-browser': 4.1.0 - '@smithy/util-middleware': 4.1.1 - '@smithy/util-utf8': 4.1.0 + '@smithy/core': 3.15.0 + '@smithy/node-config-provider': 4.3.0 + '@smithy/property-provider': 4.2.0 + '@smithy/protocol-http': 5.3.0 + '@smithy/signature-v4': 5.3.0 + '@smithy/smithy-client': 4.7.1 + '@smithy/types': 4.6.0 + '@smithy/util-base64': 4.3.0 + '@smithy/util-body-length-browser': 4.2.0 + '@smithy/util-middleware': 4.2.0 + '@smithy/util-utf8': 4.2.0 fast-xml-parser: 4.4.1 tslib: 2.8.1 optional: true @@ -4398,8 +4569,8 @@ snapshots: dependencies: '@aws-sdk/client-cognito-identity': 3.840.0 '@aws-sdk/types': 3.840.0 - '@smithy/property-provider': 4.1.1 - '@smithy/types': 4.5.0 + '@smithy/property-provider': 4.2.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt @@ -4409,8 +4580,8 @@ snapshots: dependencies: '@aws-sdk/core': 3.840.0 '@aws-sdk/types': 3.840.0 - '@smithy/property-provider': 4.1.1 - '@smithy/types': 4.5.0 + '@smithy/property-provider': 4.2.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 optional: true @@ -4426,13 +4597,13 @@ snapshots: dependencies: '@aws-sdk/core': 3.840.0 '@aws-sdk/types': 3.840.0 - '@smithy/fetch-http-handler': 5.2.1 - '@smithy/node-http-handler': 4.2.1 - '@smithy/property-provider': 4.1.1 - '@smithy/protocol-http': 5.2.1 - '@smithy/smithy-client': 4.6.4 - '@smithy/types': 4.5.0 - '@smithy/util-stream': 4.3.2 + '@smithy/fetch-http-handler': 5.3.1 + '@smithy/node-http-handler': 4.3.0 + '@smithy/property-provider': 4.2.0 + '@smithy/protocol-http': 5.3.0 + '@smithy/smithy-client': 4.7.1 + '@smithy/types': 4.6.0 + '@smithy/util-stream': 4.5.0 tslib: 2.8.1 optional: true @@ -4459,10 +4630,10 @@ snapshots: '@aws-sdk/credential-provider-web-identity': 3.840.0 '@aws-sdk/nested-clients': 3.840.0 '@aws-sdk/types': 3.840.0 - '@smithy/credential-provider-imds': 4.1.2 - '@smithy/property-provider': 4.1.1 - '@smithy/shared-ini-file-loader': 4.2.0 - '@smithy/types': 4.5.0 + '@smithy/credential-provider-imds': 4.2.0 + '@smithy/property-provider': 4.2.0 + '@smithy/shared-ini-file-loader': 4.3.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt @@ -4495,10 +4666,10 @@ snapshots: '@aws-sdk/credential-provider-sso': 3.840.0 '@aws-sdk/credential-provider-web-identity': 3.840.0 '@aws-sdk/types': 3.840.0 - '@smithy/credential-provider-imds': 4.1.2 - '@smithy/property-provider': 4.1.1 - '@smithy/shared-ini-file-loader': 4.2.0 - '@smithy/types': 4.5.0 + '@smithy/credential-provider-imds': 4.2.0 + '@smithy/property-provider': 4.2.0 + '@smithy/shared-ini-file-loader': 4.3.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt @@ -4525,9 +4696,9 @@ snapshots: dependencies: '@aws-sdk/core': 3.840.0 '@aws-sdk/types': 3.840.0 - '@smithy/property-provider': 4.1.1 - '@smithy/shared-ini-file-loader': 4.2.0 - '@smithy/types': 4.5.0 + '@smithy/property-provider': 4.2.0 + '@smithy/shared-ini-file-loader': 4.3.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 optional: true @@ -4546,9 +4717,9 @@ snapshots: '@aws-sdk/core': 3.840.0 '@aws-sdk/token-providers': 3.840.0 '@aws-sdk/types': 3.840.0 - '@smithy/property-provider': 4.1.1 - '@smithy/shared-ini-file-loader': 4.2.0 - '@smithy/types': 4.5.0 + '@smithy/property-provider': 4.2.0 + '@smithy/shared-ini-file-loader': 4.3.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt @@ -4572,8 +4743,8 @@ snapshots: '@aws-sdk/core': 3.840.0 '@aws-sdk/nested-clients': 3.840.0 '@aws-sdk/types': 3.840.0 - '@smithy/property-provider': 4.1.1 - '@smithy/types': 4.5.0 + '@smithy/property-provider': 4.2.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt @@ -4605,12 +4776,12 @@ snapshots: '@aws-sdk/credential-provider-web-identity': 3.840.0 '@aws-sdk/nested-clients': 3.840.0 '@aws-sdk/types': 3.840.0 - '@smithy/config-resolver': 4.2.2 - '@smithy/core': 3.12.0 - '@smithy/credential-provider-imds': 4.1.2 - '@smithy/node-config-provider': 4.2.2 - '@smithy/property-provider': 4.1.1 - '@smithy/types': 4.5.0 + '@smithy/config-resolver': 4.3.0 + '@smithy/core': 3.15.0 + '@smithy/credential-provider-imds': 4.2.0 + '@smithy/node-config-provider': 4.3.0 + '@smithy/property-provider': 4.2.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt @@ -4652,8 +4823,8 @@ snapshots: '@aws-sdk/middleware-host-header@3.840.0': dependencies: '@aws-sdk/types': 3.840.0 - '@smithy/protocol-http': 5.2.1 - '@smithy/types': 4.5.0 + '@smithy/protocol-http': 5.3.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 optional: true @@ -4673,7 +4844,7 @@ snapshots: '@aws-sdk/middleware-logger@3.840.0': dependencies: '@aws-sdk/types': 3.840.0 - '@smithy/types': 4.5.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 optional: true @@ -4686,8 +4857,8 @@ snapshots: '@aws-sdk/middleware-recursion-detection@3.840.0': dependencies: '@aws-sdk/types': 3.840.0 - '@smithy/protocol-http': 5.2.1 - '@smithy/types': 4.5.0 + '@smithy/protocol-http': 5.3.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 optional: true @@ -4727,9 +4898,9 @@ snapshots: '@aws-sdk/core': 3.840.0 '@aws-sdk/types': 3.840.0 '@aws-sdk/util-endpoints': 3.840.0 - '@smithy/core': 3.12.0 - '@smithy/protocol-http': 5.2.1 - '@smithy/types': 4.5.0 + '@smithy/core': 3.15.0 + '@smithy/protocol-http': 5.3.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 optional: true @@ -4757,31 +4928,31 @@ snapshots: '@aws-sdk/util-endpoints': 3.840.0 '@aws-sdk/util-user-agent-browser': 3.840.0 '@aws-sdk/util-user-agent-node': 3.840.0 - '@smithy/config-resolver': 4.2.2 - '@smithy/core': 3.12.0 - '@smithy/fetch-http-handler': 5.2.1 - '@smithy/hash-node': 4.1.1 - '@smithy/invalid-dependency': 4.1.1 - '@smithy/middleware-content-length': 4.1.1 - '@smithy/middleware-endpoint': 4.2.4 - '@smithy/middleware-retry': 4.3.0 - '@smithy/middleware-serde': 4.1.1 - '@smithy/middleware-stack': 4.1.1 - '@smithy/node-config-provider': 4.2.2 - '@smithy/node-http-handler': 4.2.1 - '@smithy/protocol-http': 5.2.1 - '@smithy/smithy-client': 4.6.4 - '@smithy/types': 4.5.0 - '@smithy/url-parser': 4.1.1 - '@smithy/util-base64': 4.1.0 - '@smithy/util-body-length-browser': 4.1.0 - '@smithy/util-body-length-node': 4.1.0 - '@smithy/util-defaults-mode-browser': 4.1.4 - '@smithy/util-defaults-mode-node': 4.1.4 - '@smithy/util-endpoints': 3.1.2 - '@smithy/util-middleware': 4.1.1 - '@smithy/util-retry': 4.1.2 - '@smithy/util-utf8': 4.1.0 + '@smithy/config-resolver': 4.3.0 + '@smithy/core': 3.15.0 + '@smithy/fetch-http-handler': 5.3.1 + '@smithy/hash-node': 4.2.0 + '@smithy/invalid-dependency': 4.2.0 + '@smithy/middleware-content-length': 4.2.0 + '@smithy/middleware-endpoint': 4.3.1 + '@smithy/middleware-retry': 4.4.1 + '@smithy/middleware-serde': 4.2.0 + '@smithy/middleware-stack': 4.2.0 + '@smithy/node-config-provider': 4.3.0 + '@smithy/node-http-handler': 4.3.0 + '@smithy/protocol-http': 5.3.0 + '@smithy/smithy-client': 4.7.1 + '@smithy/types': 4.6.0 + '@smithy/url-parser': 4.2.0 + '@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.0 + '@smithy/util-defaults-mode-node': 4.2.1 + '@smithy/util-endpoints': 3.2.0 + '@smithy/util-middleware': 4.2.0 + '@smithy/util-retry': 4.2.0 + '@smithy/util-utf8': 4.2.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt @@ -4833,10 +5004,10 @@ snapshots: '@aws-sdk/region-config-resolver@3.840.0': dependencies: '@aws-sdk/types': 3.840.0 - '@smithy/node-config-provider': 4.2.2 - '@smithy/types': 4.5.0 - '@smithy/util-config-provider': 4.1.0 - '@smithy/util-middleware': 4.1.1 + '@smithy/node-config-provider': 4.3.0 + '@smithy/types': 4.6.0 + '@smithy/util-config-provider': 4.2.0 + '@smithy/util-middleware': 4.2.0 tslib: 2.8.1 optional: true @@ -4863,9 +5034,9 @@ snapshots: '@aws-sdk/core': 3.840.0 '@aws-sdk/nested-clients': 3.840.0 '@aws-sdk/types': 3.840.0 - '@smithy/property-provider': 4.1.1 - '@smithy/shared-ini-file-loader': 4.2.0 - '@smithy/types': 4.5.0 + '@smithy/property-provider': 4.2.0 + '@smithy/shared-ini-file-loader': 4.3.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 transitivePeerDependencies: - aws-crt @@ -4885,7 +5056,7 @@ snapshots: '@aws-sdk/types@3.840.0': dependencies: - '@smithy/types': 4.5.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 optional: true @@ -4901,8 +5072,8 @@ snapshots: '@aws-sdk/util-endpoints@3.840.0': dependencies: '@aws-sdk/types': 3.840.0 - '@smithy/types': 4.5.0 - '@smithy/util-endpoints': 3.1.2 + '@smithy/types': 4.6.0 + '@smithy/util-endpoints': 3.2.0 tslib: 2.8.1 optional: true @@ -4921,7 +5092,7 @@ snapshots: '@aws-sdk/util-user-agent-browser@3.840.0': dependencies: '@aws-sdk/types': 3.840.0 - '@smithy/types': 4.5.0 + '@smithy/types': 4.6.0 bowser: 2.12.1 tslib: 2.8.1 optional: true @@ -4937,8 +5108,8 @@ snapshots: dependencies: '@aws-sdk/middleware-user-agent': 3.840.0 '@aws-sdk/types': 3.840.0 - '@smithy/node-config-provider': 4.2.2 - '@smithy/types': 4.5.0 + '@smithy/node-config-provider': 4.3.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 optional: true @@ -4952,7 +5123,7 @@ snapshots: '@aws-sdk/xml-builder@3.821.0': dependencies: - '@smithy/types': 4.5.0 + '@smithy/types': 4.6.0 tslib: 2.8.1 optional: true @@ -4970,7 +5141,7 @@ snapshots: '@borewit/text-codec@0.1.1': {} - '@cloudflare/workers-types@4.20250923.0': {} + '@cloudflare/workers-types@4.20251011.0': {} '@colors/colors@1.6.0': {} @@ -4978,9 +5149,9 @@ snapshots: dependencies: '@api.global/typedrequest-interfaces': 3.0.19 - '@dabh/diagnostics@2.0.3': + '@dabh/diagnostics@2.0.8': dependencies: - colorspace: 1.1.4 + '@so-ric/colorspace': 1.1.6 enabled: 2.0.0 kuler: 2.0.0 @@ -5260,7 +5431,7 @@ snapshots: '@push.rocks/smartshell': 3.2.2 tsx: 4.19.2 - '@git.zone/tstest@2.3.8(@aws-sdk/credential-providers@3.840.0)(socks@2.8.5)': + '@git.zone/tstest@2.4.2(@aws-sdk/credential-providers@3.840.0)(socks@2.8.5)': dependencies: '@api.global/typedserver': 3.0.79 '@git.zone/tsbundle': 2.5.1 @@ -5900,7 +6071,7 @@ snapshots: '@push.rocks/smartpromise': 4.2.3 '@push.rocks/smartstring': 4.1.0 isopen: 1.3.0 - systeminformation: 5.27.10 + systeminformation: 5.27.11 transitivePeerDependencies: - supports-color @@ -5929,7 +6100,7 @@ snapshots: '@design.estate/dees-element': 2.1.2 '@happy-dom/global-registrator': 15.11.7 '@push.rocks/smartpromise': 4.2.3 - fake-indexeddb: 6.2.2 + fake-indexeddb: 6.2.3 transitivePeerDependencies: - '@nuxt/kit' - react @@ -6400,6 +6571,12 @@ snapshots: '@smithy/types': 4.5.0 tslib: 2.8.1 + '@smithy/abort-controller@4.2.0': + dependencies: + '@smithy/types': 4.6.0 + tslib: 2.8.1 + optional: true + '@smithy/chunked-blob-reader-native@4.1.0': dependencies: '@smithy/util-base64': 4.1.0 @@ -6417,6 +6594,15 @@ snapshots: '@smithy/util-middleware': 4.1.1 tslib: 2.8.1 + '@smithy/config-resolver@4.3.0': + dependencies: + '@smithy/node-config-provider': 4.3.0 + '@smithy/types': 4.6.0 + '@smithy/util-config-provider': 4.2.0 + '@smithy/util-middleware': 4.2.0 + tslib: 2.8.1 + optional: true + '@smithy/core@3.12.0': dependencies: '@smithy/middleware-serde': 4.1.1 @@ -6430,6 +6616,20 @@ snapshots: '@smithy/uuid': 1.0.0 tslib: 2.8.1 + '@smithy/core@3.15.0': + dependencies: + '@smithy/middleware-serde': 4.2.0 + '@smithy/protocol-http': 5.3.0 + '@smithy/types': 4.6.0 + '@smithy/util-base64': 4.3.0 + '@smithy/util-body-length-browser': 4.2.0 + '@smithy/util-middleware': 4.2.0 + '@smithy/util-stream': 4.5.0 + '@smithy/util-utf8': 4.2.0 + '@smithy/uuid': 1.1.0 + tslib: 2.8.1 + optional: true + '@smithy/credential-provider-imds@4.1.2': dependencies: '@smithy/node-config-provider': 4.2.2 @@ -6438,6 +6638,15 @@ snapshots: '@smithy/url-parser': 4.1.1 tslib: 2.8.1 + '@smithy/credential-provider-imds@4.2.0': + dependencies: + '@smithy/node-config-provider': 4.3.0 + '@smithy/property-provider': 4.2.0 + '@smithy/types': 4.6.0 + '@smithy/url-parser': 4.2.0 + tslib: 2.8.1 + optional: true + '@smithy/eventstream-codec@4.1.1': dependencies: '@aws-crypto/crc32': 5.2.0 @@ -6476,6 +6685,15 @@ snapshots: '@smithy/util-base64': 4.1.0 tslib: 2.8.1 + '@smithy/fetch-http-handler@5.3.1': + dependencies: + '@smithy/protocol-http': 5.3.0 + '@smithy/querystring-builder': 4.2.0 + '@smithy/types': 4.6.0 + '@smithy/util-base64': 4.3.0 + tslib: 2.8.1 + optional: true + '@smithy/hash-blob-browser@4.1.1': dependencies: '@smithy/chunked-blob-reader': 5.1.0 @@ -6490,6 +6708,14 @@ snapshots: '@smithy/util-utf8': 4.1.0 tslib: 2.8.1 + '@smithy/hash-node@4.2.0': + dependencies: + '@smithy/types': 4.6.0 + '@smithy/util-buffer-from': 4.2.0 + '@smithy/util-utf8': 4.2.0 + tslib: 2.8.1 + optional: true + '@smithy/hash-stream-node@4.1.1': dependencies: '@smithy/types': 4.5.0 @@ -6501,6 +6727,12 @@ snapshots: '@smithy/types': 4.5.0 tslib: 2.8.1 + '@smithy/invalid-dependency@4.2.0': + dependencies: + '@smithy/types': 4.6.0 + tslib: 2.8.1 + optional: true + '@smithy/is-array-buffer@2.2.0': dependencies: tslib: 2.8.1 @@ -6509,6 +6741,11 @@ snapshots: dependencies: tslib: 2.8.1 + '@smithy/is-array-buffer@4.2.0': + dependencies: + tslib: 2.8.1 + optional: true + '@smithy/md5-js@4.1.1': dependencies: '@smithy/types': 4.5.0 @@ -6521,6 +6758,13 @@ snapshots: '@smithy/types': 4.5.0 tslib: 2.8.1 + '@smithy/middleware-content-length@4.2.0': + dependencies: + '@smithy/protocol-http': 5.3.0 + '@smithy/types': 4.6.0 + tslib: 2.8.1 + optional: true + '@smithy/middleware-endpoint@4.2.4': dependencies: '@smithy/core': 3.12.0 @@ -6532,6 +6776,18 @@ snapshots: '@smithy/util-middleware': 4.1.1 tslib: 2.8.1 + '@smithy/middleware-endpoint@4.3.1': + dependencies: + '@smithy/core': 3.15.0 + '@smithy/middleware-serde': 4.2.0 + '@smithy/node-config-provider': 4.3.0 + '@smithy/shared-ini-file-loader': 4.3.0 + '@smithy/types': 4.6.0 + '@smithy/url-parser': 4.2.0 + '@smithy/util-middleware': 4.2.0 + tslib: 2.8.1 + optional: true + '@smithy/middleware-retry@4.3.0': dependencies: '@smithy/node-config-provider': 4.2.2 @@ -6544,17 +6800,43 @@ snapshots: '@smithy/uuid': 1.0.0 tslib: 2.8.1 + '@smithy/middleware-retry@4.4.1': + dependencies: + '@smithy/node-config-provider': 4.3.0 + '@smithy/protocol-http': 5.3.0 + '@smithy/service-error-classification': 4.2.0 + '@smithy/smithy-client': 4.7.1 + '@smithy/types': 4.6.0 + '@smithy/util-middleware': 4.2.0 + '@smithy/util-retry': 4.2.0 + '@smithy/uuid': 1.1.0 + tslib: 2.8.1 + optional: true + '@smithy/middleware-serde@4.1.1': dependencies: '@smithy/protocol-http': 5.2.1 '@smithy/types': 4.5.0 tslib: 2.8.1 + '@smithy/middleware-serde@4.2.0': + dependencies: + '@smithy/protocol-http': 5.3.0 + '@smithy/types': 4.6.0 + tslib: 2.8.1 + optional: true + '@smithy/middleware-stack@4.1.1': dependencies: '@smithy/types': 4.5.0 tslib: 2.8.1 + '@smithy/middleware-stack@4.2.0': + dependencies: + '@smithy/types': 4.6.0 + tslib: 2.8.1 + optional: true + '@smithy/node-config-provider@4.2.2': dependencies: '@smithy/property-provider': 4.1.1 @@ -6562,6 +6844,14 @@ snapshots: '@smithy/types': 4.5.0 tslib: 2.8.1 + '@smithy/node-config-provider@4.3.0': + dependencies: + '@smithy/property-provider': 4.2.0 + '@smithy/shared-ini-file-loader': 4.3.0 + '@smithy/types': 4.6.0 + tslib: 2.8.1 + optional: true + '@smithy/node-http-handler@4.2.1': dependencies: '@smithy/abort-controller': 4.1.1 @@ -6570,36 +6860,81 @@ snapshots: '@smithy/types': 4.5.0 tslib: 2.8.1 + '@smithy/node-http-handler@4.3.0': + dependencies: + '@smithy/abort-controller': 4.2.0 + '@smithy/protocol-http': 5.3.0 + '@smithy/querystring-builder': 4.2.0 + '@smithy/types': 4.6.0 + tslib: 2.8.1 + optional: true + '@smithy/property-provider@4.1.1': dependencies: '@smithy/types': 4.5.0 tslib: 2.8.1 + '@smithy/property-provider@4.2.0': + dependencies: + '@smithy/types': 4.6.0 + tslib: 2.8.1 + optional: true + '@smithy/protocol-http@5.2.1': dependencies: '@smithy/types': 4.5.0 tslib: 2.8.1 + '@smithy/protocol-http@5.3.0': + dependencies: + '@smithy/types': 4.6.0 + tslib: 2.8.1 + optional: true + '@smithy/querystring-builder@4.1.1': dependencies: '@smithy/types': 4.5.0 '@smithy/util-uri-escape': 4.1.0 tslib: 2.8.1 + '@smithy/querystring-builder@4.2.0': + dependencies: + '@smithy/types': 4.6.0 + '@smithy/util-uri-escape': 4.2.0 + tslib: 2.8.1 + optional: true + '@smithy/querystring-parser@4.1.1': dependencies: '@smithy/types': 4.5.0 tslib: 2.8.1 + '@smithy/querystring-parser@4.2.0': + dependencies: + '@smithy/types': 4.6.0 + tslib: 2.8.1 + optional: true + '@smithy/service-error-classification@4.1.2': dependencies: '@smithy/types': 4.5.0 + '@smithy/service-error-classification@4.2.0': + dependencies: + '@smithy/types': 4.6.0 + optional: true + '@smithy/shared-ini-file-loader@4.2.0': dependencies: '@smithy/types': 4.5.0 tslib: 2.8.1 + '@smithy/shared-ini-file-loader@4.3.0': + dependencies: + '@smithy/types': 4.6.0 + tslib: 2.8.1 + optional: true + '@smithy/signature-v4@5.2.1': dependencies: '@smithy/is-array-buffer': 4.1.0 @@ -6611,6 +6946,18 @@ snapshots: '@smithy/util-utf8': 4.1.0 tslib: 2.8.1 + '@smithy/signature-v4@5.3.0': + dependencies: + '@smithy/is-array-buffer': 4.2.0 + '@smithy/protocol-http': 5.3.0 + '@smithy/types': 4.6.0 + '@smithy/util-hex-encoding': 4.2.0 + '@smithy/util-middleware': 4.2.0 + '@smithy/util-uri-escape': 4.2.0 + '@smithy/util-utf8': 4.2.0 + tslib: 2.8.1 + optional: true + '@smithy/smithy-client@4.6.4': dependencies: '@smithy/core': 3.12.0 @@ -6621,30 +6968,70 @@ snapshots: '@smithy/util-stream': 4.3.2 tslib: 2.8.1 + '@smithy/smithy-client@4.7.1': + dependencies: + '@smithy/core': 3.15.0 + '@smithy/middleware-endpoint': 4.3.1 + '@smithy/middleware-stack': 4.2.0 + '@smithy/protocol-http': 5.3.0 + '@smithy/types': 4.6.0 + '@smithy/util-stream': 4.5.0 + tslib: 2.8.1 + optional: true + '@smithy/types@4.5.0': dependencies: tslib: 2.8.1 + '@smithy/types@4.6.0': + dependencies: + tslib: 2.8.1 + optional: true + '@smithy/url-parser@4.1.1': dependencies: '@smithy/querystring-parser': 4.1.1 '@smithy/types': 4.5.0 tslib: 2.8.1 + '@smithy/url-parser@4.2.0': + dependencies: + '@smithy/querystring-parser': 4.2.0 + '@smithy/types': 4.6.0 + tslib: 2.8.1 + optional: true + '@smithy/util-base64@4.1.0': dependencies: '@smithy/util-buffer-from': 4.1.0 '@smithy/util-utf8': 4.1.0 tslib: 2.8.1 + '@smithy/util-base64@4.3.0': + dependencies: + '@smithy/util-buffer-from': 4.2.0 + '@smithy/util-utf8': 4.2.0 + tslib: 2.8.1 + optional: true + '@smithy/util-body-length-browser@4.1.0': dependencies: tslib: 2.8.1 + '@smithy/util-body-length-browser@4.2.0': + dependencies: + tslib: 2.8.1 + optional: true + '@smithy/util-body-length-node@4.1.0': dependencies: tslib: 2.8.1 + '@smithy/util-body-length-node@4.2.1': + dependencies: + tslib: 2.8.1 + optional: true + '@smithy/util-buffer-from@2.2.0': dependencies: '@smithy/is-array-buffer': 2.2.0 @@ -6655,10 +7042,21 @@ snapshots: '@smithy/is-array-buffer': 4.1.0 tslib: 2.8.1 + '@smithy/util-buffer-from@4.2.0': + dependencies: + '@smithy/is-array-buffer': 4.2.0 + tslib: 2.8.1 + optional: true + '@smithy/util-config-provider@4.1.0': dependencies: tslib: 2.8.1 + '@smithy/util-config-provider@4.2.0': + dependencies: + tslib: 2.8.1 + optional: true + '@smithy/util-defaults-mode-browser@4.1.4': dependencies: '@smithy/property-provider': 4.1.1 @@ -6667,6 +7065,14 @@ snapshots: bowser: 2.12.1 tslib: 2.8.1 + '@smithy/util-defaults-mode-browser@4.3.0': + dependencies: + '@smithy/property-provider': 4.2.0 + '@smithy/smithy-client': 4.7.1 + '@smithy/types': 4.6.0 + tslib: 2.8.1 + optional: true + '@smithy/util-defaults-mode-node@4.1.4': dependencies: '@smithy/config-resolver': 4.2.2 @@ -6677,27 +7083,63 @@ snapshots: '@smithy/types': 4.5.0 tslib: 2.8.1 + '@smithy/util-defaults-mode-node@4.2.1': + dependencies: + '@smithy/config-resolver': 4.3.0 + '@smithy/credential-provider-imds': 4.2.0 + '@smithy/node-config-provider': 4.3.0 + '@smithy/property-provider': 4.2.0 + '@smithy/smithy-client': 4.7.1 + '@smithy/types': 4.6.0 + tslib: 2.8.1 + optional: true + '@smithy/util-endpoints@3.1.2': dependencies: '@smithy/node-config-provider': 4.2.2 '@smithy/types': 4.5.0 tslib: 2.8.1 + '@smithy/util-endpoints@3.2.0': + dependencies: + '@smithy/node-config-provider': 4.3.0 + '@smithy/types': 4.6.0 + tslib: 2.8.1 + optional: true + '@smithy/util-hex-encoding@4.1.0': dependencies: tslib: 2.8.1 + '@smithy/util-hex-encoding@4.2.0': + dependencies: + tslib: 2.8.1 + optional: true + '@smithy/util-middleware@4.1.1': dependencies: '@smithy/types': 4.5.0 tslib: 2.8.1 + '@smithy/util-middleware@4.2.0': + dependencies: + '@smithy/types': 4.6.0 + tslib: 2.8.1 + optional: true + '@smithy/util-retry@4.1.2': dependencies: '@smithy/service-error-classification': 4.1.2 '@smithy/types': 4.5.0 tslib: 2.8.1 + '@smithy/util-retry@4.2.0': + dependencies: + '@smithy/service-error-classification': 4.2.0 + '@smithy/types': 4.6.0 + tslib: 2.8.1 + optional: true + '@smithy/util-stream@4.3.2': dependencies: '@smithy/fetch-http-handler': 5.2.1 @@ -6709,10 +7151,27 @@ snapshots: '@smithy/util-utf8': 4.1.0 tslib: 2.8.1 + '@smithy/util-stream@4.5.0': + dependencies: + '@smithy/fetch-http-handler': 5.3.1 + '@smithy/node-http-handler': 4.3.0 + '@smithy/types': 4.6.0 + '@smithy/util-base64': 4.3.0 + '@smithy/util-buffer-from': 4.2.0 + '@smithy/util-hex-encoding': 4.2.0 + '@smithy/util-utf8': 4.2.0 + tslib: 2.8.1 + optional: true + '@smithy/util-uri-escape@4.1.0': dependencies: tslib: 2.8.1 + '@smithy/util-uri-escape@4.2.0': + dependencies: + tslib: 2.8.1 + optional: true + '@smithy/util-utf8@2.3.0': dependencies: '@smithy/util-buffer-from': 2.2.0 @@ -6723,6 +7182,12 @@ snapshots: '@smithy/util-buffer-from': 4.1.0 tslib: 2.8.1 + '@smithy/util-utf8@4.2.0': + dependencies: + '@smithy/util-buffer-from': 4.2.0 + tslib: 2.8.1 + optional: true + '@smithy/util-waiter@4.1.1': dependencies: '@smithy/abort-controller': 4.1.1 @@ -6733,6 +7198,16 @@ snapshots: dependencies: tslib: 2.8.1 + '@smithy/uuid@1.1.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@so-ric/colorspace@1.1.6': + dependencies: + color: 5.0.2 + text-hex: 1.0.0 + '@socket.io/component-emitter@3.1.2': {} '@szmarczak/http-timer@5.0.1': @@ -6818,12 +7293,12 @@ snapshots: '@types/range-parser': 1.2.7 '@types/send': 0.17.4 - '@types/express-serve-static-core@5.0.7': + '@types/express-serve-static-core@5.1.0': dependencies: '@types/node': 22.14.0 '@types/qs': 6.14.0 '@types/range-parser': 1.2.7 - '@types/send': 0.17.5 + '@types/send': 1.2.0 '@types/express@5.0.0': dependencies: @@ -6835,8 +7310,8 @@ snapshots: '@types/express@5.0.3': dependencies: '@types/body-parser': 1.19.6 - '@types/express-serve-static-core': 5.0.7 - '@types/serve-static': 1.15.8 + '@types/express-serve-static-core': 5.1.0 + '@types/serve-static': 1.15.9 '@types/fs-extra@11.0.4': dependencies: @@ -6917,13 +7392,17 @@ snapshots: '@types/mime': 1.3.5 '@types/node': 22.14.0 + '@types/send@1.2.0': + dependencies: + '@types/node': 22.14.0 + '@types/serve-static@1.15.7': dependencies: '@types/http-errors': 2.0.4 '@types/node': 22.14.0 '@types/send': 0.17.4 - '@types/serve-static@1.15.8': + '@types/serve-static@1.15.9': dependencies: '@types/http-errors': 2.0.5 '@types/node': 22.14.0 @@ -7249,24 +7728,24 @@ snapshots: dependencies: color-name: 1.1.4 + color-convert@3.1.2: + dependencies: + color-name: 2.0.2 + color-name@1.1.3: {} color-name@1.1.4: {} - color-string@1.9.1: - dependencies: - color-name: 1.1.4 - simple-swizzle: 0.2.4 + color-name@2.0.2: {} - color@3.2.1: + color-string@2.1.2: dependencies: - color-convert: 1.9.3 - color-string: 1.9.1 + color-name: 2.0.2 - colorspace@1.1.4: + color@5.0.2: dependencies: - color: 3.2.1 - text-hex: 1.0.0 + color-convert: 3.1.2 + color-string: 2.1.2 combined-stream@1.0.8: dependencies: @@ -7675,7 +8154,7 @@ snapshots: fake-indexeddb@5.0.2: {} - fake-indexeddb@6.2.2: {} + fake-indexeddb@6.2.3: {} fast-deep-equal@3.1.3: {} @@ -7825,6 +8304,8 @@ snapshots: function-bind@1.1.2: {} + generator-function@2.0.1: {} + get-intrinsic@1.2.6: dependencies: call-bind-apply-helpers: 1.0.1 @@ -8072,15 +8553,14 @@ snapshots: ipaddr.js@1.9.1: {} - is-arrayish@0.3.4: {} - is-docker@2.2.1: {} is-fullwidth-code-point@3.0.0: {} - is-generator-function@1.1.0: + is-generator-function@1.1.2: dependencies: call-bound: 1.0.4 + generator-function: 2.0.1 get-proto: 1.0.1 has-tostringtag: 1.0.2 safe-regex-test: 1.1.0 @@ -8197,7 +8677,7 @@ snapshots: fresh: 0.5.2 http-assert: 1.5.0 http-errors: 1.8.1 - is-generator-function: 1.1.0 + is-generator-function: 1.1.2 koa-compose: 4.1.0 koa-convert: 2.0.0 on-finished: 2.4.1 @@ -9149,7 +9629,7 @@ snapshots: koa-logger: 3.2.1 lodash: 4.17.21 statuses: 2.0.2 - winston: 3.17.0 + winston: 3.18.3 transitivePeerDependencies: - supports-color @@ -9272,10 +9752,6 @@ snapshots: signal-exit@4.1.0: {} - simple-swizzle@0.2.4: - dependencies: - is-arrayish: 0.3.4 - smart-buffer@4.2.0: optional: true @@ -9426,7 +9902,7 @@ snapshots: systeminformation@5.24.6: {} - systeminformation@5.27.10: {} + systeminformation@5.27.11: {} tar-fs@2.1.1: dependencies: @@ -9659,10 +10135,10 @@ snapshots: readable-stream: 3.6.2 triple-beam: 1.4.1 - winston@3.17.0: + winston@3.18.3: dependencies: '@colors/colors': 1.6.0 - '@dabh/diagnostics': 2.0.3 + '@dabh/diagnostics': 2.0.8 async: 3.2.6 is-stream: 2.0.1 logform: 2.7.0 diff --git a/readme.md b/readme.md index e02f035..f11309e 100644 --- a/readme.md +++ b/readme.md @@ -1,4 +1,5 @@ # @fin.cx/opendata + šŸš€ **Real-time financial data and German business intelligence in one powerful TypeScript library** Access live stock prices, cryptocurrencies, forex, commodities AND comprehensive German company data - all through a single, unified API. @@ -8,34 +9,42 @@ Access live stock prices, cryptocurrencies, forex, commodities AND comprehensive ```bash npm install @fin.cx/opendata # or -yarn add @fin.cx/opendata +pnpm add @fin.cx/opendata ``` ## Quick Start -### šŸ“ˆ Real-Time Stock Data +### šŸ“ˆ Stock Market Data -Get live market data in seconds: +Get market data with EOD (End-of-Day) pricing: ```typescript -import { StockPriceService, YahooFinanceProvider } from '@fin.cx/opendata'; +import { StockPriceService, MarketstackProvider } from '@fin.cx/opendata'; -// Initialize the service -const stockService = new StockPriceService(); -stockService.register(new YahooFinanceProvider()); +// Initialize the service with caching +const stockService = new StockPriceService({ + ttl: 60000, // Cache for 1 minute + maxEntries: 1000 // Max cached symbols +}); + +// Register Marketstack provider with API key +stockService.register(new MarketstackProvider('YOUR_API_KEY'), { + priority: 100, + retryAttempts: 3 +}); // Get single stock price const apple = await stockService.getPrice({ ticker: 'AAPL' }); console.log(`Apple: $${apple.price} (${apple.changePercent.toFixed(2)}%)`); -// Get multiple prices at once -const prices = await stockService.getPrices({ - tickers: ['AAPL', 'MSFT', 'GOOGL', 'BTC-USD', 'ETH-USD'] +// Get multiple prices at once (batch fetching) +const prices = await stockService.getPrices({ + tickers: ['AAPL', 'MSFT', 'GOOGL', 'AMZN', 'TSLA'] }); -// Market indices, crypto, forex, commodities - all supported! -const marketData = await stockService.getPrices({ - tickers: ['^GSPC', '^DJI', 'BTC-USD', 'EURUSD=X', 'GC=F'] +// 125,000+ tickers across 72+ exchanges worldwide +const internationalStocks = await stockService.getPrices({ + tickers: ['AAPL', 'VOD.LON', 'SAP.DEX', 'TM', 'BABA'] }); ``` @@ -73,11 +82,12 @@ await openData.buildInitialDb(); ### šŸŽÆ Stock Market Module -- **Real-time prices** for stocks, ETFs, indices, crypto, forex, and commodities +- **Marketstack API** - End-of-Day (EOD) data for 125,000+ tickers across 72+ exchanges +- **Stock prices** for stocks, ETFs, indices, and more - **Batch operations** - fetch 100+ symbols in one request - **Smart caching** - configurable TTL, automatic invalidation -- **Provider system** - easily extensible for new data sources -- **Automatic retries** and fallback mechanisms +- **Extensible provider system** - easily add new data sources +- **Retry logic** - configurable retry attempts and delays - **Type-safe** - full TypeScript support with detailed interfaces ### šŸ‡©šŸ‡Ŗ German Business Intelligence @@ -92,29 +102,24 @@ await openData.buildInitialDb(); ### Market Dashboard -Create a real-time market overview: +Create an EOD market overview: ```typescript const indicators = [ // Indices { ticker: '^GSPC', name: 'S&P 500' }, - { ticker: '^IXIC', name: 'NASDAQ' }, - + { ticker: '^DJI', name: 'DOW Jones' }, + // Tech Giants { ticker: 'AAPL', name: 'Apple' }, { ticker: 'MSFT', name: 'Microsoft' }, - - // Crypto - { ticker: 'BTC-USD', name: 'Bitcoin' }, - { ticker: 'ETH-USD', name: 'Ethereum' }, - - // Commodities - { ticker: 'GC=F', name: 'Gold' }, - { ticker: 'CL=F', name: 'Oil' } + { ticker: 'GOOGL', name: 'Alphabet' }, + { ticker: 'AMZN', name: 'Amazon' }, + { ticker: 'TSLA', name: 'Tesla' } ]; -const prices = await stockService.getPrices({ - tickers: indicators.map(i => i.ticker) +const prices = await stockService.getPrices({ + tickers: indicators.map(i => i.ticker) }); // Display with color-coded changes @@ -122,7 +127,7 @@ prices.forEach(price => { const indicator = indicators.find(i => i.ticker === price.ticker); const arrow = price.change >= 0 ? '↑' : '↓'; const color = price.change >= 0 ? '\x1b[32m' : '\x1b[31m'; - + console.log( `${indicator.name.padEnd(15)} ${price.price.toFixed(2).padStart(10)} ` + `${color}${arrow} ${price.changePercent.toFixed(2)}%\x1b[0m` @@ -130,6 +135,25 @@ prices.forEach(price => { }); ``` +### Provider Health and Statistics + +Monitor your provider health and track usage: + +```typescript +// Check provider health +const health = await stockService.checkProvidersHealth(); +console.log(`Marketstack: ${health.get('Marketstack') ? 'āœ…' : 'āŒ'}`); + +// Get provider statistics +const stats = stockService.getProviderStats(); +const marketstackStats = stats.get('Marketstack'); +console.log('Marketstack Stats:', { + successCount: marketstackStats.successCount, + errorCount: marketstackStats.errorCount, + lastError: marketstackStats.lastError +}); +``` + ### Handelsregister Integration Automate German company data retrieval: @@ -169,15 +193,15 @@ for (const company of publicCompanies) { try { // Map company to ticker (custom logic needed) const ticker = mapCompanyToTicker(company.data.name); - + if (ticker) { const stock = await stockService.getPrice({ ticker }); - + // Add financial metrics company.data.stockPrice = stock.price; company.data.marketCap = stock.price * getSharesOutstanding(ticker); company.data.priceChange = stock.changePercent; - + await company.save(); } } catch (error) { @@ -196,8 +220,8 @@ const stockService = new StockPriceService({ maxEntries: 1000 // Max cached symbols }); -// Provider configuration -stockService.register(new YahooFinanceProvider(), { +// Marketstack - EOD data, requires API key +stockService.register(new MarketstackProvider('YOUR_API_KEY'), { enabled: true, priority: 100, timeout: 10000, @@ -208,7 +232,7 @@ stockService.register(new YahooFinanceProvider(), { ### MongoDB Setup -Set environment variables: +Set environment variables for German business data: ```env MONGODB_URL=mongodb://localhost:27017 @@ -217,6 +241,14 @@ MONGODB_USER=myuser MONGODB_PASS=mypass ``` +### Marketstack API Key + +Get your free API key at [marketstack.com](https://marketstack.com) and set it in your environment: + +```env +MARKETSTACK_COM_TOKEN=your_api_key_here +``` + ## API Reference ### Stock Types @@ -240,10 +272,21 @@ interface IStockPrice { ### Key Methods **StockPriceService** -- `getPrice(request)` - Single stock price -- `getPrices(request)` - Batch prices -- `register(provider)` - Add data provider +- `getPrice(request)` - Single stock price with automatic provider selection +- `getPrices(request)` - Batch prices (100+ symbols in one request) +- `register(provider, config)` - Add data provider with priority and retry config +- `checkProvidersHealth()` - Test all providers and return health status +- `getProviderStats()` - Get success/error statistics for each provider - `clearCache()` - Clear price cache +- `setCacheTTL(ttl)` - Update cache TTL dynamically + +**MarketstackProvider** +- āœ… End-of-Day (EOD) data +- āœ… 125,000+ tickers across 72+ exchanges worldwide +- āœ… Batch fetching support (multiple symbols in one request) +- āœ… Comprehensive data: open, high, low, close, volume, splits, dividends +- āš ļø Requires API key (free tier: 100 requests/month) +- āš ļø EOD data only (not real-time) **OpenData** - `start()` - Initialize MongoDB connection @@ -251,31 +294,48 @@ interface IStockPrice { - `CBusinessRecord` - Business record class - `handelsregister` - Registry automation -## Performance +## Provider Architecture -- **Batch fetching**: Get 100+ prices in <500ms -- **Caching**: Instant repeated queries -- **Concurrent processing**: Handle 1000+ records/second -- **Streaming**: Process GB-sized datasets without memory issues - -## Extensibility - -The provider architecture makes it easy to add new data sources: +The library uses a flexible provider system that makes it easy to add new data sources: ```typescript class MyCustomProvider implements IStockProvider { name = 'My Provider'; - + priority = 50; + requiresAuth = true; + async fetchPrice(request: IStockQuoteRequest): Promise { // Your implementation } - - // ... other required methods + + async fetchPrices(request: IStockBatchQuoteRequest): Promise { + // Batch implementation + } + + async isAvailable(): Promise { + // Health check + } + + supportsMarket(market: string): boolean { + // Market validation + } + + supportsTicker(ticker: string): boolean { + // Ticker validation + } } stockService.register(new MyCustomProvider()); ``` +## Performance + +- **Batch fetching**: Get 100+ EOD prices in one API request +- **Smart caching**: Instant repeated queries with configurable TTL +- **Rate limit aware**: Automatic retry logic for API limits +- **Concurrent processing**: Handle 1000+ business records/second +- **Streaming**: Process GB-sized datasets without memory issues + ## Testing Run the comprehensive test suite: @@ -284,19 +344,21 @@ Run the comprehensive test suite: npm test ``` -View live market data: +Test stock provider: ```bash -npm test -- --grep "market indicators" +npx tstest test/test.marketstack.node.ts --verbose ``` -## Contributing +Test German business data: -We welcome contributions! Please see our contributing guidelines for details. +```bash +npx tstest test/test.handelsregister.ts --verbose +``` ## License and Legal Information -This repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository. +This repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository. **Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file. @@ -306,9 +368,9 @@ This project is owned and maintained by Task Venture Capital GmbH. The names and ### Company Information -Task Venture Capital GmbH +Task Venture Capital GmbH Registered at District court Bremen HRB 35230 HB, Germany For any legal inquiries or if you require further information, please contact us via email at hello@task.vc. -By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works. \ No newline at end of file +By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works. diff --git a/test/test.marketstack.node.ts b/test/test.marketstack.node.ts new file mode 100644 index 0000000..dc7b6ca --- /dev/null +++ b/test/test.marketstack.node.ts @@ -0,0 +1,302 @@ +import { expect, tap } from '@git.zone/tstest/tapbundle'; +import * as opendata from '../ts/index.js'; +import * as paths from '../ts/paths.js'; +import * as plugins from '../ts/plugins.js'; + +// Test data +const testTickers = ['AAPL', 'MSFT', 'GOOGL']; +const invalidTicker = 'INVALID_TICKER_XYZ'; + +let stockService: opendata.StockPriceService; +let marketstackProvider: opendata.MarketstackProvider; +let testQenv: plugins.qenv.Qenv; + +tap.test('should create StockPriceService instance', async () => { + stockService = new opendata.StockPriceService({ + ttl: 30000, // 30 seconds cache + maxEntries: 100 + }); + expect(stockService).toBeInstanceOf(opendata.StockPriceService); +}); + +tap.test('should create MarketstackProvider instance', async () => { + try { + // Create qenv and get API key + testQenv = new plugins.qenv.Qenv(paths.packageDir, paths.nogitDir); + const apiKey = await testQenv.getEnvVarOnDemand('MARKETSTACK_COM_TOKEN'); + + marketstackProvider = new opendata.MarketstackProvider(apiKey, { + enabled: true, + timeout: 10000, + retryAttempts: 2, + retryDelay: 500 + }); + expect(marketstackProvider).toBeInstanceOf(opendata.MarketstackProvider); + expect(marketstackProvider.name).toEqual('Marketstack'); + expect(marketstackProvider.requiresAuth).toEqual(true); + expect(marketstackProvider.priority).toEqual(80); + } catch (error) { + if (error.message.includes('MARKETSTACK_COM_TOKEN')) { + console.log('āš ļø MARKETSTACK_COM_TOKEN not set - skipping Marketstack tests'); + tap.test('Marketstack token not available', async () => { + expect(true).toEqual(true); // Skip gracefully + }); + return; + } + throw error; + } +}); + +tap.test('should register Marketstack provider with the service', async () => { + if (!marketstackProvider) { + console.log('āš ļø Skipping - Marketstack provider not initialized'); + return; + } + + stockService.register(marketstackProvider); + const providers = stockService.getAllProviders(); + expect(providers).toContainEqual(marketstackProvider); + expect(stockService.getProvider('Marketstack')).toEqual(marketstackProvider); +}); + +tap.test('should check provider health', async () => { + if (!marketstackProvider) { + console.log('āš ļø Skipping - Marketstack provider not initialized'); + return; + } + + const health = await stockService.checkProvidersHealth(); + expect(health.get('Marketstack')).toEqual(true); +}); + +tap.test('should fetch single stock price', async () => { + if (!marketstackProvider) { + console.log('āš ļø Skipping - Marketstack provider not initialized'); + return; + } + + const price = await stockService.getPrice({ ticker: 'AAPL' }); + + expect(price).toHaveProperty('ticker'); + expect(price).toHaveProperty('price'); + expect(price).toHaveProperty('currency'); + expect(price).toHaveProperty('change'); + expect(price).toHaveProperty('changePercent'); + expect(price).toHaveProperty('previousClose'); + expect(price).toHaveProperty('timestamp'); + expect(price).toHaveProperty('provider'); + expect(price).toHaveProperty('marketState'); + + expect(price.ticker).toEqual('AAPL'); + expect(price.price).toBeGreaterThan(0); + expect(price.provider).toEqual('Marketstack'); + expect(price.timestamp).toBeInstanceOf(Date); + expect(price.marketState).toEqual('CLOSED'); // EOD data + + console.log(`āœ“ Fetched AAPL: $${price.price} (${price.changePercent >= 0 ? '+' : ''}${price.changePercent.toFixed(2)}%)`); +}); + +tap.test('should fetch multiple stock prices', async () => { + if (!marketstackProvider) { + console.log('āš ļø Skipping - Marketstack provider not initialized'); + return; + } + + const prices = await stockService.getPrices({ + tickers: testTickers + }); + + expect(prices).toBeArray(); + expect(prices.length).toBeGreaterThan(0); + expect(prices.length).toBeLessThanOrEqual(testTickers.length); + + for (const price of prices) { + expect(testTickers).toContain(price.ticker); + expect(price.price).toBeGreaterThan(0); + expect(price.provider).toEqual('Marketstack'); + expect(price.marketState).toEqual('CLOSED'); + console.log(` ${price.ticker}: $${price.price}`); + } +}); + +tap.test('should serve cached prices on subsequent requests', async () => { + if (!marketstackProvider) { + console.log('āš ļø Skipping - Marketstack provider not initialized'); + return; + } + + // First request - should hit the API + const firstRequest = await stockService.getPrice({ ticker: 'AAPL' }); + + // Second request - should be served from cache + const secondRequest = await stockService.getPrice({ ticker: 'AAPL' }); + + expect(secondRequest.ticker).toEqual(firstRequest.ticker); + expect(secondRequest.price).toEqual(firstRequest.price); + expect(secondRequest.timestamp).toEqual(firstRequest.timestamp); + + console.log('āœ“ Cache working correctly'); +}); + +tap.test('should handle invalid ticker gracefully', async () => { + if (!marketstackProvider) { + console.log('āš ļø Skipping - Marketstack provider not initialized'); + return; + } + + try { + await stockService.getPrice({ ticker: invalidTicker }); + throw new Error('Should have thrown an error for invalid ticker'); + } catch (error) { + expect(error.message).toInclude('Failed to fetch price'); + console.log('āœ“ Invalid ticker handled correctly'); + } +}); + +tap.test('should support market checking', async () => { + if (!marketstackProvider) { + console.log('āš ļø Skipping - Marketstack provider not initialized'); + return; + } + + expect(marketstackProvider.supportsMarket('US')).toEqual(true); + expect(marketstackProvider.supportsMarket('UK')).toEqual(true); + expect(marketstackProvider.supportsMarket('DE')).toEqual(true); + expect(marketstackProvider.supportsMarket('JP')).toEqual(true); + expect(marketstackProvider.supportsMarket('INVALID')).toEqual(false); + + console.log('āœ“ Market support check working'); +}); + +tap.test('should validate ticker format', async () => { + if (!marketstackProvider) { + console.log('āš ļø Skipping - Marketstack provider not initialized'); + return; + } + + expect(marketstackProvider.supportsTicker('AAPL')).toEqual(true); + expect(marketstackProvider.supportsTicker('MSFT')).toEqual(true); + expect(marketstackProvider.supportsTicker('BRK.B')).toEqual(true); + expect(marketstackProvider.supportsTicker('123456789012')).toEqual(false); + expect(marketstackProvider.supportsTicker('invalid@ticker')).toEqual(false); + + console.log('āœ“ Ticker validation working'); +}); + +tap.test('should get provider statistics', async () => { + if (!marketstackProvider) { + console.log('āš ļø Skipping - Marketstack provider not initialized'); + return; + } + + const stats = stockService.getProviderStats(); + const marketstackStats = stats.get('Marketstack'); + + expect(marketstackStats).not.toEqual(undefined); + expect(marketstackStats.successCount).toBeGreaterThan(0); + expect(marketstackStats.errorCount).toBeGreaterThanOrEqual(0); + + console.log(`āœ“ Provider stats: ${marketstackStats.successCount} successes, ${marketstackStats.errorCount} errors`); +}); + +tap.test('should test direct provider methods', async () => { + if (!marketstackProvider) { + console.log('āš ļø Skipping - Marketstack provider not initialized'); + return; + } + + console.log('\nšŸ” Testing direct provider methods:'); + + // Test isAvailable + const available = await marketstackProvider.isAvailable(); + expect(available).toEqual(true); + console.log(' āœ“ isAvailable() returned true'); + + // Test fetchPrice directly + const price = await marketstackProvider.fetchPrice({ ticker: 'MSFT' }); + expect(price.ticker).toEqual('MSFT'); + expect(price.provider).toEqual('Marketstack'); + expect(price.price).toBeGreaterThan(0); + console.log(` āœ“ fetchPrice() for MSFT: $${price.price}`); + + // Test fetchPrices directly + const prices = await marketstackProvider.fetchPrices({ + tickers: ['AAPL', 'GOOGL'] + }); + expect(prices.length).toBeGreaterThan(0); + console.log(` āœ“ fetchPrices() returned ${prices.length} prices`); + + for (const p of prices) { + console.log(` ${p.ticker}: $${p.price}`); + } +}); + +tap.test('should fetch sample EOD data', async () => { + if (!marketstackProvider) { + console.log('āš ļø Skipping - Marketstack provider not initialized'); + return; + } + + console.log('\nšŸ“Š Sample EOD Stock Data from Marketstack:'); + console.log('═'.repeat(65)); + + const sampleTickers = [ + { ticker: 'AAPL', name: 'Apple Inc.' }, + { ticker: 'MSFT', name: 'Microsoft Corp.' }, + { ticker: 'GOOGL', name: 'Alphabet Inc.' }, + { ticker: 'AMZN', name: 'Amazon.com Inc.' }, + { ticker: 'TSLA', name: 'Tesla Inc.' } + ]; + + try { + const prices = await marketstackProvider.fetchPrices({ + tickers: sampleTickers.map(t => t.ticker) + }); + + const priceMap = new Map(prices.map(p => [p.ticker, p])); + + for (const stock of sampleTickers) { + const price = priceMap.get(stock.ticker); + if (price) { + const changeSymbol = price.change >= 0 ? '↑' : '↓'; + const changeColor = price.change >= 0 ? '\x1b[32m' : '\x1b[31m'; + const resetColor = '\x1b[0m'; + + console.log( + `${stock.name.padEnd(20)} ${price.price.toLocaleString('en-US', { + minimumFractionDigits: 2, + maximumFractionDigits: 2 + }).padStart(10)} ${changeColor}${changeSymbol} ${price.change >= 0 ? '+' : ''}${price.change.toFixed(2)} (${price.changePercent >= 0 ? '+' : ''}${price.changePercent.toFixed(2)}%)${resetColor}` + ); + } + } + + console.log('═'.repeat(65)); + console.log(`Provider: Marketstack (EOD Data)`); + console.log(`Last updated: ${new Date().toLocaleString()}\n`); + } catch (error) { + console.log('Error fetching sample data:', error.message); + } + + expect(true).toEqual(true); +}); + +tap.test('should clear cache', async () => { + if (!marketstackProvider) { + console.log('āš ļø Skipping - Marketstack provider not initialized'); + return; + } + + // Ensure we have something in cache + await stockService.getPrice({ ticker: 'AAPL' }); + + // Clear cache + stockService.clearCache(); + console.log('āœ“ Cache cleared'); + + // Next request should hit the API again + const price = await stockService.getPrice({ ticker: 'AAPL' }); + expect(price).not.toEqual(undefined); +}); + +export default tap.start(); diff --git a/ts/00_commitinfo_data.ts b/ts/00_commitinfo_data.ts index abcc831..4ef3af8 100644 --- a/ts/00_commitinfo_data.ts +++ b/ts/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@fin.cx/opendata', - version: '1.6.1', + version: '1.7.0', description: 'A comprehensive TypeScript library for accessing business data and real-time financial information. Features include German company data management with MongoDB integration, JSONL bulk processing, automated Handelsregister interactions, and real-time stock market data from multiple providers.' } diff --git a/ts/stocks/index.ts b/ts/stocks/index.ts index 434656f..94da2fc 100644 --- a/ts/stocks/index.ts +++ b/ts/stocks/index.ts @@ -6,4 +6,5 @@ export * from './interfaces/provider.js'; export * from './classes.stockservice.js'; // Export providers -export * from './providers/provider.yahoo.js'; \ No newline at end of file +export * from './providers/provider.yahoo.js'; +export * from './providers/provider.marketstack.js'; \ No newline at end of file diff --git a/ts/stocks/providers/provider.marketstack.ts b/ts/stocks/providers/provider.marketstack.ts new file mode 100644 index 0000000..2eac3dc --- /dev/null +++ b/ts/stocks/providers/provider.marketstack.ts @@ -0,0 +1,200 @@ +import * as plugins from '../../plugins.js'; +import type { IStockProvider, IProviderConfig } from '../interfaces/provider.js'; +import type { IStockPrice, IStockQuoteRequest, IStockBatchQuoteRequest } from '../interfaces/stockprice.js'; + +/** + * Marketstack API v2 Provider + * Documentation: https://marketstack.com/documentation_v2 + * + * Features: + * - End-of-Day (EOD) stock prices + * - Supports 125,000+ tickers across 72+ exchanges worldwide + * - Requires API key authentication + * + * Rate Limits: + * - Free Plan: 100 requests/month (EOD only) + * - Basic Plan: 10,000 requests/month + * - Professional Plan: 100,000 requests/month + * + * Note: This provider returns EOD data, not real-time prices + */ +export class MarketstackProvider implements IStockProvider { + public name = 'Marketstack'; + public priority = 80; // Lower than Yahoo (100) due to rate limits and EOD-only data + public readonly requiresAuth = true; + public readonly rateLimit = { + requestsPerMinute: undefined, // No per-minute limit specified + requestsPerDay: undefined // Varies by plan + }; + + private logger = console; + private baseUrl = 'https://api.marketstack.com/v2'; + private apiKey: string; + + constructor(apiKey: string, private config?: IProviderConfig) { + if (!apiKey) { + throw new Error('API key is required for Marketstack provider'); + } + + this.apiKey = apiKey; + } + + /** + * Fetch latest EOD price for a single ticker + */ + public async fetchPrice(request: IStockQuoteRequest): Promise { + try { + const url = `${this.baseUrl}/tickers/${request.ticker}/eod/latest?access_key=${this.apiKey}`; + + const response = await plugins.smartrequest.SmartRequest.create() + .url(url) + .timeout(this.config?.timeout || 10000) + .get(); + + const responseData = await response.json() as any; + + // Check for API errors + if (responseData.error) { + throw new Error(`Marketstack API error: ${responseData.error.message || JSON.stringify(responseData.error)}`); + } + + // For single ticker endpoint, response is direct object (not wrapped in data field) + if (!responseData || !responseData.close) { + throw new Error(`No data found for ticker ${request.ticker}`); + } + + return this.mapToStockPrice(responseData); + } catch (error) { + this.logger.error(`Failed to fetch price for ${request.ticker}:`, error); + throw new Error(`Marketstack: Failed to fetch price for ${request.ticker}: ${error.message}`); + } + } + + /** + * Fetch latest EOD prices for multiple tickers + */ + public async fetchPrices(request: IStockBatchQuoteRequest): Promise { + try { + const symbols = request.tickers.join(','); + const url = `${this.baseUrl}/eod/latest?access_key=${this.apiKey}&symbols=${symbols}`; + + const response = await plugins.smartrequest.SmartRequest.create() + .url(url) + .timeout(this.config?.timeout || 15000) + .get(); + + const responseData = await response.json() as any; + + // Check for API errors + if (responseData.error) { + throw new Error(`Marketstack API error: ${responseData.error.message || JSON.stringify(responseData.error)}`); + } + + if (!responseData?.data || !Array.isArray(responseData.data)) { + throw new Error('Invalid response format from Marketstack API'); + } + + const prices: IStockPrice[] = []; + + for (const data of responseData.data) { + try { + prices.push(this.mapToStockPrice(data)); + } catch (error) { + this.logger.warn(`Failed to parse data for ${data.symbol}:`, error); + // Continue processing other tickers + } + } + + if (prices.length === 0) { + throw new Error('No valid price data received from batch request'); + } + + return prices; + } catch (error) { + this.logger.error(`Failed to fetch batch prices:`, error); + throw new Error(`Marketstack: Failed to fetch batch prices: ${error.message}`); + } + } + + /** + * Check if the Marketstack API is available and accessible + */ + public async isAvailable(): Promise { + try { + // Test with a well-known ticker + const url = `${this.baseUrl}/tickers/AAPL/eod/latest?access_key=${this.apiKey}`; + + const response = await plugins.smartrequest.SmartRequest.create() + .url(url) + .timeout(5000) + .get(); + + const responseData = await response.json() as any; + + // Check if we got valid data (not an error) + // Single ticker endpoint returns direct object, not wrapped in data field + return !responseData.error && responseData.close !== undefined; + } catch (error) { + this.logger.warn('Marketstack provider is not available:', error); + return false; + } + } + + /** + * Check if a market is supported + * Marketstack supports 72+ exchanges worldwide + */ + public supportsMarket(market: string): boolean { + // Marketstack has broad international coverage including: + // US, UK, DE, FR, JP, CN, HK, AU, CA, IN, etc. + const supportedMarkets = [ + 'US', 'UK', 'GB', 'DE', 'FR', 'JP', 'CN', 'HK', 'AU', 'CA', + 'IN', 'BR', 'MX', 'IT', 'ES', 'NL', 'SE', 'CH', 'NO', 'DK' + ]; + return supportedMarkets.includes(market.toUpperCase()); + } + + /** + * Check if a ticker format is supported + */ + public supportsTicker(ticker: string): boolean { + // Basic validation - Marketstack supports most standard ticker formats + return /^[A-Z0-9\.\-]{1,10}$/.test(ticker.toUpperCase()); + } + + /** + * Map Marketstack API response to IStockPrice interface + */ + private mapToStockPrice(data: any): IStockPrice { + if (!data.close) { + throw new Error('Missing required price data'); + } + + // Calculate change and change percent + // EOD data: previous close is typically open price of the same day + // For better accuracy, we'd need previous day's close, but that requires another API call + const currentPrice = data.close; + const previousClose = data.open; + const change = currentPrice - previousClose; + const changePercent = previousClose !== 0 ? (change / previousClose) * 100 : 0; + + // Parse timestamp + const timestamp = data.date ? new Date(data.date) : new Date(); + + const stockPrice: IStockPrice = { + ticker: data.symbol.toUpperCase(), + price: currentPrice, + currency: data.price_currency || 'USD', + change: change, + changePercent: changePercent, + previousClose: previousClose, + timestamp: timestamp, + provider: this.name, + marketState: 'CLOSED', // EOD data is always for closed markets + exchange: data.exchange, + exchangeName: data.exchange_code || data.name + }; + + return stockPrice; + } +}