107 Commits

Author SHA1 Message Date
Torsten Schulz (local)
cf3bd3cd6d Enhance member training participation tracking and UI feedback
This commit adds functionality to track training participations for members in the backend, updating the MemberService to include a count of training participations. The frontend components, DiaryView and MembersView, have been updated to display warning icons based on the number of training participations, providing visual feedback for members with significant participation. CSS styles for warning icons have also been refined to improve visibility and user experience.
2025-11-13 12:12:49 +01:00
Torsten Schulz (local)
4c1a919d17 Add club settings link for admin users and remove test PIN references in MatchReportApiDialog
This commit introduces a new link to the club settings in the App.vue component, visible only to admin users. Additionally, it removes references to a test PIN ('1234') in the MatchReportApiDialog.vue, enhancing security and streamlining the user experience by eliminating unnecessary hints and validation logic.
2025-11-13 09:27:08 +01:00
Torsten Schulz (local)
eb9748dd89 Enhance group assignment functionality in DiaryView with improved reactivity
This commit updates the DiaryView component to enhance the group assignment feature for participants. It adds an @input event listener to the group selection dropdown for immediate UI updates and refines the logic for updating the memberGroupsMap to ensure reactivity in Vue 3. Additionally, it includes error handling improvements to reload participant data upon failure, ensuring data consistency and a better user experience.
2025-11-12 16:21:08 +01:00
Torsten Schulz (local)
e295657621 Add validation endpoint for meeting reports and enhance frontend functionality
This commit introduces a new API endpoint in the backend for validating meeting reports, allowing for improved error handling and cookie management. The frontend has been updated to include a validation function that checks the report data before submission, providing users with feedback on validation warnings and errors. These changes enhance the overall user experience by ensuring data integrity and improving interaction with the meeting report feature.
2025-11-12 16:13:04 +01:00
Torsten Schulz (local)
da351b40b2 Add node-fetch dependency and implement meeting report submission endpoint
This commit introduces the node-fetch package to facilitate HTTP requests in the backend. Additionally, a new API endpoint for submitting meeting reports has been implemented in the nuscoreApiRoutes. The endpoint handles report data submission, cookie management, and error handling, enhancing the functionality of the meeting report feature. Frontend components have been updated to support this new functionality, improving the overall user experience.
2025-11-12 15:29:04 +01:00
Torsten Schulz (local)
3c64e2e92d Remove Playwright dependency and related proxy service files from the backend. This commit deletes the node-fetch package and its associated files, as well as the nuscoreProxyRoutes and nuscoreProxyService, streamlining the backend by eliminating unused components. 2025-11-12 13:41:09 +01:00
Torsten Schulz (local)
45381707ea Erweitert den MatchReportApiDialog um neue Funktionen zur Verwaltung von Spielberichten. Implementiert eine verbesserte Logik zur Berechnung der Gesamtpunkte und Sätze sowie zur Validierung von Eingaben. Fügt visuelle Hinweise für den Abschlussstatus und Warnungen bei fehlerhaften Eingaben hinzu. Optimiert die Benutzeroberfläche mit neuen CSS-Stilen für eine bessere Benutzererfahrung. 2025-11-12 13:40:55 +01:00
Torsten Schulz (local)
b166f7c7d5 Refactor member gallery dialog in DiaryView for improved functionality and user experience
This commit replaces the existing BaseDialog for the member gallery with a new MemberGalleryDialog component, streamlining the dialog's functionality. The new component integrates props for current club, date, and participant status, enhancing interactivity. Additionally, redundant gallery loading logic and state management have been removed, simplifying the codebase and improving maintainability.
2025-11-12 12:53:29 +01:00
Torsten Schulz (local)
1f20737721 Enhance member gallery functionality with latest image retrieval and JSON format support
This commit improves the member gallery feature by allowing users to request the latest member images and receive member information in JSON format. The backend has been updated to handle "latest" as a valid imageId, ensuring the most recent image is fetched. Additionally, the frontend has been modified to support displaying member details in an interactive gallery format, enhancing user experience and providing more flexibility in how member information is presented.
2025-11-12 11:58:37 +01:00
Torsten Schulz (local)
8ef4e1dc9d Enhance member gallery generation with customizable image size selection
This commit updates the member gallery generation feature by allowing users to specify the image size through the frontend. The DiaryView component now includes a dropdown for selecting image dimensions (100x100, 150x150, 200x200), which is passed to the backend for processing. The memberService has been modified to validate the size parameter, ensuring only allowed dimensions are used. These changes improve user experience by providing flexibility in gallery display options.
2025-11-12 10:05:08 +01:00
Torsten Schulz (local)
98c50bc03a Refactor gallery layout in memberService and update DiaryView styles for improved responsiveness
This commit refines the gallery layout logic in memberService by adjusting the calculations for canvas dimensions and positions, ensuring a more accurate representation of images. Additionally, the DiaryView component's styles have been updated to enhance the alignment and responsiveness of the gallery images, contributing to a better user experience across devices.
2025-11-12 08:46:58 +01:00
Torsten Schulz (local)
7b28eb04ac Refactor memberService and update DiaryView styles for improved functionality and layout
This commit includes minor refactoring in the memberService to enhance error logging and improve image handling logic. Additionally, the DiaryView component has been updated to adjust the gallery dialog layout, ensuring better alignment and responsiveness of images. These changes contribute to a more robust backend and a better user experience in the frontend.
2025-11-12 07:57:55 +01:00
Torsten Schulz (local)
ed15137003 Add member gallery generation feature in backend and frontend
This commit introduces a new API endpoint for generating a member gallery, allowing users to retrieve a composite image of active members' latest images. The backend has been updated with a new method in MemberService to handle gallery creation, while the frontend has been enhanced with a dialog for displaying the generated gallery. This feature improves the user experience by providing a visual representation of club members.
2025-11-11 16:22:47 +01:00
Torsten Schulz (local)
2bf5c0137b Adjust image height settings in ImageViewerDialog component for improved responsiveness. Updated max-height for desktop and mobile views to enhance user experience when viewing images. 2025-11-11 15:56:21 +01:00
Torsten Schulz (local)
22e6913005 Implement member image management features in backend and frontend
This commit introduces new functionalities for managing member images, including uploading, deleting, and setting primary images. The memberController and memberService have been updated to handle these operations, while new routes have been added to facilitate image management. The frontend has been enhanced with an ImageViewerDialog component that supports image rotation, deletion, and setting primary images. Additionally, improvements to the member view allow for better image handling and display. These changes enhance the overall user experience and functionality of the member management system.
2025-11-11 15:53:21 +01:00
Torsten Schulz (local)
f7eff0bcb7 Enhance error handling and logging in backend controllers and services
This commit improves error handling in various controllers, including diaryNoteController, memberNoteController, and permissionController, by adding console error logging for better debugging. Additionally, it updates the diaryService and teamDocumentService to enhance functionality and maintainability. The config.js file is also updated to ensure proper configuration for the development environment. These changes contribute to a more robust and user-friendly application.
2025-11-11 11:36:47 +01:00
Torsten Schulz (local)
45c90280f8 Update package dependencies and types for improved compatibility and functionality
This commit updates the package-lock.json and package.json files to reflect the latest versions of dependencies, including @types/node and validator. Additionally, it removes unused type definitions and enhances the overall structure of the project, ensuring better compatibility and performance across the application.
2025-11-11 09:33:24 +01:00
Torsten Schulz (local)
a4890f241b Add new API routes for season, session, team, and tournament management
Integrated additional routes into the Express application for managing seasons, sessions, teams, team documents, and tournaments. This enhancement improves the API's structure and expands its capabilities, allowing for better organization and access to related resources.
2025-11-11 09:30:40 +01:00
Torsten Schulz (local)
684409491f Add permission management tests for role and custom permissions updates
Implemented new tests in permissionRoutes.test.js to validate role changes and custom permissions for users within clubs. Added checks for successful updates and error handling for invalid club IDs. This enhancement improves test coverage for permission management features in the application.
2025-11-11 09:00:18 +01:00
Torsten Schulz (local)
15b88f8177 Add member transfer validation and contact management tests
Implemented a new test for validating transfer configuration via the API in memberRoutes.test.js, ensuring proper error handling for invalid transfer requests. Additionally, enhanced memberService.test.js with tests for creating and updating members along with their contacts, including filtering inactive members. These additions improve the test coverage and reliability of member management features in the application.
2025-11-11 08:35:55 +01:00
Torsten Schulz (local)
20f204e70b Enhance diary note and tag management in backend controllers
Updated the diaryNoteController to require diaryDateId in note creation and improved error handling for missing fields. Enhanced the createTag function in diaryTagController to validate tag names and return appropriate responses. Additionally, refined the deleteTag function to ensure proper error handling when a tag is not found. These changes improve the robustness and usability of the diary management features.
2025-11-11 08:29:18 +01:00
Torsten Schulz (local)
b8191e41ee Add club team and diary routes to the Express application
Integrated new routes for club team management and diary functionality into the backend. This enhancement improves the API's structure and accessibility, allowing for better organization of related resources and expanding the application's capabilities.
2025-11-10 18:29:55 +01:00
Torsten Schulz (local)
b906a218a5 Add API logging and club routes to the Express application
Integrated new routes for API logging and club management into the backend, enhancing the API's functionality and organization. This addition allows for better access to logging and club-related resources, improving overall application structure.
2025-11-10 17:09:57 +01:00
Torsten Schulz (local)
6c3b46c037 Add accident and activity routes to the Express application
Enhanced the backend by integrating new routes for accident and activity management. This addition improves the API's functionality, allowing for better organization and access to related resources.
2025-11-10 17:01:43 +01:00
Torsten Schulz (local)
3f1018ef93 Refactor database configuration and enhance error handling in authentication services
Updated the database configuration to centralize settings and improve maintainability. Enhanced error handling in the authentication service to provide clearer and more specific error messages for various failure scenarios, including registration, activation, and login processes. Additionally, added new dependencies for testing and SQLite support in the package.json file.
2025-11-10 16:54:49 +01:00
Torsten Schulz (local)
620b065ac8 Refactor dialog handling to utilize utility functions for improved consistency
Updated various components to replace direct dialog configurations with utility functions for building dialog configurations. This change enhances the maintainability and readability of the code by centralizing dialog setup logic, ensuring a consistent approach across the application. Additionally, improved error handling and user feedback mechanisms were implemented to provide clearer messages during interactions.
2025-11-10 16:07:24 +01:00
Torsten Schulz (local)
4cfa03834e Refactor alert handling to use dialog components for improved user feedback
Updated various components to replace alert calls with showInfo and showConfirm dialog methods, enhancing user experience by providing more informative and styled feedback. This change standardizes the way messages are displayed across the application, improving consistency and clarity in user interactions.
2025-11-10 14:20:34 +01:00
Torsten Schulz (local)
d94238f6df Refactor logging in cleanup scripts to use report array for improved output management
Updated various cleanup scripts to replace console.log statements with a report array, enhancing the output handling and allowing for better formatting of messages. This change improves the readability of logs and ensures consistent reporting across different cleanup operations, including database connection status, index management, and summary reports.
2025-11-10 13:25:11 +01:00
Torsten Schulz (local)
eb37532de2 Refactor group ID handling in DiaryView and related services for consistency
Updated the handling of group IDs in DiaryView.vue to ensure they are consistently treated as strings. Enhanced the DiaryDateActivityService to filter out duplicate group activities and ensure proper handling of group IDs during updates. This improves data integrity and consistency across the application.
2025-11-08 22:31:38 +01:00
Torsten Schulz (local)
d79e71d6d7 Update PDF parsing and document upload handling in team management
Enhanced the PDFParserService to support layout-based text extraction from PDFs using pdfjs-dist, improving parsing accuracy. Updated the team management view to streamline document uploads and parsing processes, removing unnecessary UI elements and consolidating upload logic. Improved error handling and user feedback during document processing, ensuring better user experience and clarity in case of issues.
2025-11-08 10:15:25 +01:00
Torsten Schulz (local)
f0e3c6a717 Enhance MyTischtennisService and MyTischtennisAccount.vue for improved login handling and account status display
Updated MyTischtennisService to include federation nickname in account data and refined login logic to utilize stored passwords or valid sessions more effectively. Enhanced error handling for login failures. In MyTischtennisAccount.vue, added account status management to display password storage status and improved account loading logic to fetch both account and status data concurrently.
2025-11-07 14:54:15 +01:00
Torsten Schulz (local)
b2d47c7a37 Update error message in MyTischtennisUrlController for clarity
Modified the error handling in MyTischtennisUrlController to specify that only the URL is required, enhancing the clarity of the error response. This change aligns with recent efforts to standardize error handling across the application.
2025-11-07 13:50:18 +01:00
Torsten Schulz (local)
498742e6ae Refactor error handling in controllers and services to standardize HttpError instantiation
Updated multiple controllers and services to ensure consistent error handling by modifying the HttpError instantiation format. This change enhances clarity and maintains uniformity across error responses, improving overall code quality and maintainability.
2025-11-07 13:45:58 +01:00
Torsten Schulz (local)
94aab93f7d Add global error handling middleware for API routes and enhance rating update logic
Implemented a global error handling middleware in the server to standardize error responses for API routes. Additionally, updated the AutoUpdateRatingsService to retrieve the approved user club before updating ratings, ensuring proper access control. Modified the error handling in MyTischtennisAccount.vue to provide more informative login failure messages.
2025-11-07 13:22:22 +01:00
Torsten Schulz (local)
eba8ba30aa Add notes placeholder in member transfer templates for improved data handling
Updated the MemberTransferService to include a new '{{notes}}' placeholder in the member transfer templates. This addition ensures that notes are accounted for during member data transfers, enhancing the completeness of the information being processed.
2025-11-07 10:05:03 +01:00
Torsten Schulz (local)
9d24c6ae7b Filter active members in phone list generation to exclude test memberships for improved accuracy 2025-11-06 17:15:19 +01:00
Torsten Schulz (local)
02b8ba3d0a Enhance PDF generation for member phone lists by improving formatting and fallback handling
Updated the PDFGenerator component to ensure consistent font sizes for phone list entries and added fallback logic for handling cases where no phone contacts are available. Improved the display of parent contact names with appropriate font sizes, enhancing the readability and organization of member information in generated PDFs.
2025-11-06 17:12:58 +01:00
Torsten Schulz (local)
fc7b70b307 Standardize phone number formatting in member service and MembersView
Integrated phone number standardization in the member service to ensure consistent formatting during member updates and contact creation. Added a new utility function in MembersView for phone number standardization, enhancing data integrity and user experience when adding or updating member information.
2025-11-06 16:45:44 +01:00
Torsten Schulz (local)
9cdbd60a23 Enhance member management by adding postal code and contact handling
Introduced a postal code field to the member model and implemented a new MemberContact model to manage multiple phone numbers and email addresses. Updated the member service and controller to handle contact data during member creation and updates. Enhanced the MembersView component to support input for multiple contacts, ensuring better organization and accessibility of member information.
2025-11-06 16:12:34 +01:00
Torsten Schulz (local)
5a4553a8a0 Add member_contact table and postal_code column to member table
Created a new SQL migration to add a postal_code column to the member table and introduced a member_contact table to store multiple phone numbers and email addresses. Implemented data migration for existing phone numbers and email addresses from the member table to the new member_contact table, ensuring data integrity and improved contact management.
2025-11-06 16:03:42 +01:00
Torsten Schulz (local)
98637eec00 Update MembersView styling for action icons to improve layout consistency
Modified the action-icons-row CSS to prevent wrapping and ensure icons remain in a single line, enhancing the visual layout and usability of the MembersView component.
2025-11-06 15:01:40 +01:00
Torsten Schulz (local)
106c63890e Enhance training participation loading in MembersView with improved ID handling and logging
Updated the loadTrainingParticipations method to store participation totals using both string and number keys in the participation map, addressing potential type issues. Enhanced logging to provide detailed insights into the loading process, including responses and member counts, improving debugging capabilities and user experience.
2025-11-06 14:58:19 +01:00
Torsten Schulz (local)
f6b8388819 Add quick deactivate member functionality and update routes and UI
Implemented a new quickDeactivateMember function in MemberService to handle member deactivation. Updated member routes to include a new endpoint for quick deactivation. Enhanced the MembersView component to support quick deactivation actions with updated UI elements, improving user experience for managing member statuses.
2025-11-06 14:46:16 +01:00
Torsten Schulz (local)
f1a29e4111 Add last scheduler executions endpoint and member quick update functions
Implemented a new endpoint in ApiLogController to retrieve the last execution information for scheduler jobs. Added quick update functions in MemberService and corresponding routes for updating test membership status and marking member forms as handed over. Enhanced the MembersView to support quick actions for managing test memberships and form statuses, improving user experience and operational efficiency.
2025-11-06 14:25:15 +01:00
Torsten Schulz (local)
c9d82827ff Enhance member validation and error reporting in MemberTransferService and MemberTransferDialog
Updated the MemberTransferService to include validation for required member fields, categorizing members into valid and invalid lists. Improved error handling to provide detailed feedback on invalid members during transfers. Enhanced the MemberTransferDialog to display information about excluded members and their errors, ensuring users are informed of any issues during the transfer process.
2025-11-06 08:28:27 +01:00
Torsten Schulz (local)
75242f63fc Enhance error handling and logging in MemberTransferService and MemberTransferDialog
Updated the MemberTransferService to provide detailed error messages during bulk transfers, including identification of problematic members. Improved logging for error responses to facilitate debugging. In the MemberTransferDialog, implemented $nextTick to ensure login credentials are cleared properly upon loading and closing, enhancing user experience and preventing autofill issues.
2025-11-06 08:24:39 +01:00
Torsten Schulz (local)
2f161d1eb5 Refactor logging in MemberTransferService to use info and error logs
Updated the MemberTransferService to replace debug logging with info and error logging for better visibility in production. This change enhances the logging of login credentials, transfer details, and error handling, ensuring critical information is captured appropriately during member transfers.
2025-11-06 08:16:14 +01:00
Torsten Schulz (local)
cad76edaad Enhance MemberTransferService and MemberTransferDialog with detailed debug logging
Added extensive debug logging to the MemberTransferService to track member transfer details, including logging the first few members and bulk data structure. Updated the MemberTransferDialog to clear login credentials upon loading and closing, improving user experience and ensuring a clean state for configuration loading. These enhancements aim to facilitate troubleshooting and provide better visibility into the member transfer process.
2025-11-06 08:13:43 +01:00
Torsten Schulz (local)
d0a8ef5ff2 Enhance MemberTransferService with detailed debug logging for login credentials
Added comprehensive debug logging to the MemberTransferService to track login credentials and endpoint details during member transfers. Implemented checks for the presence of login credentials, including mapping username to email when necessary, and improved error handling for missing credentials. This enhancement aims to facilitate troubleshooting and improve the overall robustness of the login process.
2025-11-06 07:29:49 +01:00
Torsten Schulz (local)
a0d12a895e Enhance permission validation and error handling in permissionController
Updated the getUserPermissions function to include validation for clubId, ensuring it is a valid positive integer. Added error handling to return a 400 status with a descriptive message for invalid club IDs, improving the robustness of the API response.
2025-11-05 16:33:52 +01:00
Torsten Schulz (local)
ad99787f75 Enhance member transfer service and dialog for improved credential handling
Updated the MemberTransferService to better manage login credentials, ensuring that saved credentials are utilized when none are provided. Improved error handling during login attempts by extracting detailed error messages and adjusting status codes to prevent user logout. Refined the MemberTransferDialog to clear login credentials when no club is selected and to only include non-empty values in the login credentials object, enhancing user experience and validation logic.
2025-11-05 16:22:40 +01:00
Torsten Schulz (local)
c05cfbbe38 Refactor MemberTransferDialog to improve configuration handling and UI
Updated the MemberTransferDialog component to enhance user experience by displaying configuration summaries and handling missing configurations more effectively. Removed redundant form sections and added conditional rendering for login credentials. Improved validation logic for transfer settings and introduced new styles for better visual clarity.
2025-11-05 15:39:34 +01:00
Torsten Schulz (local)
1f47a11091 Add member transfer configuration and UI enhancements
Introduced MemberTransferConfig model and integrated it into the backend, allowing for the storage and retrieval of member transfer settings. Updated server routes to include member transfer configuration endpoints. Enhanced the frontend with a new MemberTransferDialog component for user interaction, added a dedicated route for member transfer settings, and updated the App.vue to include a link for accessing these settings. Improved the loading state and configuration handling in the dialog for better user experience.
2025-11-05 15:30:12 +01:00
Torsten Schulz (local)
5bba9522b3 Add member transfer functionality to memberController and update routes and UI
Implemented a new transferMembers function in memberController to handle member transfers, including validation for transfer endpoint and template. Updated memberRoutes to include a new route for member transfers. Enhanced MembersView with a button to open a transfer dialog and integrated a MemberTransferDialog component for user interaction during the transfer process.
2025-11-05 14:33:09 +01:00
Torsten Schulz (local)
5bdcd946cf Update diagonal cell styling in TournamentsView for improved visibility
Modified the CSS for diagonal cells in TournamentsView to change the background and text color from black to a lighter gray. This enhancement improves the visual clarity of the tournament display, making it easier for users to identify active matches.
2025-11-05 08:55:29 +01:00
Torsten Schulz (local)
6500493314 Enhance TournamentsView with diagonal cell styling for match rankings
Updated the TournamentsView to include a new CSS class for diagonal cells, improving the visual representation of match rankings. The diagonal cells now have distinct styling to indicate active matches, enhancing user interaction and clarity in tournament displays.
2025-11-05 08:49:27 +01:00
Torsten Schulz (local)
d0e3ae3610 Implement ranking logic for players with identical scores in TournamentsView
Updated the ranking assignment logic in TournamentsView to ensure players with identical points, set differences, and sets won receive the same position. This change enhances the accuracy of player rankings and improves the user experience by reflecting true standings in tournament scenarios. Additionally, adjusted the position retrieval for players in live stats to accommodate the new ranking logic.
2025-11-05 08:45:23 +01:00
Torsten Schulz (local)
8db827adeb Refactor participant list in DiaryView for improved layout and interaction
Updated the participant list in DiaryView to enhance the layout and user interaction. Introduced new CSS classes for better styling of participant rows, including flexbox for alignment and spacing. Improved the checkbox label structure and added a dedicated actions section for each participant, streamlining the user experience when managing participants. Additionally, modified the selectMember method to automatically open the notes modal for the selected participant.
2025-11-04 16:37:09 +01:00
Torsten Schulz (local)
d40eea5e46 Enhance DiaryView with member form handover functionality and styling improvements
Added a new feature to mark the member form as handed over, updating the member's status accordingly. Enhanced the participant list with conditional styling based on member activity and membership status. Introduced new CSS classes for better visual representation of inactive members and those with test memberships. Improved user interaction by adding an icon for marking the form handover.
2025-11-04 16:22:21 +01:00
Torsten Schulz (local)
a3ed130211 Add animation controls and enhance arrow drawing in CourtDrawingRender component
Implemented animation controls for arrow rendering in the CourtDrawingRender component, allowing users to start and stop animations. Enhanced the drawArrow method to support progressive rendering based on animation state. Added computed properties to determine the presence of arrows and updated the component's lifecycle methods for proper animation management. Improved styling for animation buttons to enhance user experience.
2025-11-04 15:54:18 +01:00
Torsten Schulz (local)
e8766b919a --- 2025-11-03 14:15:00 +01:00
Torsten Schulz (local)
76ee9ee742 Refactor memberController and memberService to include memberFormHandedOver field and improve parameter handling
Updated memberController to handle the showAll parameter more effectively and added memberFormHandedOver to the setClubMember method in memberService. Enhanced Member model to include memberFormHandedOver field with appropriate defaults. Updated MembersView to reflect changes in the UI, allowing for better member data management and visibility.
2025-11-03 12:36:13 +01:00
Torsten Schulz (local)
84ff4e126e Enhance MyTischtennisUrlController with ratings update and improve apiLogService truncation limits
Added functionality in MyTischtennisUrlController to update (Q)TTR ratings for clubs based on user authentication. Enhanced error handling for ratings updates to provide clearer feedback. Updated apiLogService to increase truncation limits for request and response bodies, accommodating larger API JSON payloads, ensuring better logging accuracy.
2025-11-03 12:03:34 +01:00
Torsten Schulz (local)
23708b99b5 Refactor error handling in MyTischtennisUrlController and improve memberService indexing
Refactored error handling in MyTischtennisUrlController to standardize error messages and ensure consistent status codes. Enhanced memberService by implementing a more efficient indexing system for member data retrieval, improving performance and accuracy in TTR and QTTR updates. Updated TeamManagementView to handle timeout errors and provide detailed user feedback, enhancing overall user experience.
2025-11-03 10:45:04 +01:00
Torsten Schulz (local)
acf2cf00bd Refactor MyTischtennisUrlController and enhance error handling in TeamManagementView
Refactored MyTischtennisUrlController to define variables outside of try/catch for better error handling. Improved error messaging in TeamManagementView by providing more detailed debug information and ensuring fallback messages are available. This enhances the robustness of data retrieval and user feedback.
2025-11-03 10:07:24 +01:00
Torsten Schulz (local)
bb3f0f3a03 Enhance error handling in MyTischtennisUrlController and update TrainingStatsView with TTR and QTTR columns
Improved error handling in MyTischtennisUrlController by adding detailed debug information in the response, including status codes and relevant data. Updated TrainingStatsView to display TTR and QTTR values for members, enhancing data visibility and user experience.
2025-11-03 09:46:26 +01:00
Torsten Schulz (local)
f4411a4ee5 Enhance club rankings retrieval and member TTR updates
Updated the getClubRankings method in myTischtennisClient to include an optional parameter for current rankings. Modified memberService to fetch both current and quarterly TTR values, improving member data accuracy. Enhanced the TeamManagementView to display (Q)TTR values for better user visibility. Added error handling for QTTR retrieval, ensuring robustness in member updates.
2025-11-03 09:35:04 +01:00
Torsten Schulz (local)
e32871a005 Implement deleteGroupActivity endpoint and enhance addGroupActivity functionality
Added a new endpoint to delete group activities in the diaryDateActivityController and corresponding route in diaryDateActivityRoutes. Enhanced the addGroupActivity function to accept an optional timeblockId parameter, allowing for more precise activity management. Updated the DiaryView component to support the removal of group activities, improving user experience and functionality in activity management.
2025-11-03 08:43:24 +01:00
Torsten Schulz (local)
a8318c74cf Implement last participations endpoint and enhance member activity retrieval
Added a new endpoint to fetch the last participations of a member, including group assignment checks for activities. Updated the member activity controller to include logic for filtering activities based on participant group IDs. Enhanced the DiaryView component to display activity statistics and last participations in a modal, improving user experience and data accessibility.
2025-10-31 16:33:20 +01:00
Torsten Schulz (local)
7e85926aa1 Refactor CourtDrawing components by removing overlay text and debug logs
Removed overlay text rendering and debug logging from CourtDrawingRender.vue and CourtDrawingTool.vue to streamline the drawing process. Updated DiaryView.vue to suppress debug messages and handle parsing errors more gracefully, enhancing overall code clarity and user experience.
2025-10-31 15:14:11 +01:00
Torsten Schulz (local)
91fc3e9d13 Implement Court Drawing Dialog and enhance activity management in DiaryView and PredefinedActivities
Added a Court Drawing Dialog component to facilitate the creation and editing of drawing data for activities. Updated DiaryView.vue to include a button for opening the drawing dialog and handling the resulting data. Enhanced PredefinedActivities.vue to allow users to create or edit drawing data directly from the activity form, improving the overall user experience. Refactored related styles and logic for better integration and usability.
2025-10-31 15:05:40 +01:00
Torsten Schulz (local)
6a333f198d Enhance CourtDrawing components with new rendering logic and overlay features
Updated CourtDrawingRender.vue to include an overlay displaying the rendered code string and raw values for debugging. Refactored position resolution logic to streamline the determination of start positions. Added methods for building and applying render codes, improving the overall functionality of the drawing tool. Enhanced CourtDrawingTool.vue with updated button styles and layout adjustments for better user experience. Updated DiaryView.vue to ensure proper handling of drawing data and start positions from render codes.
2025-10-30 15:24:57 +01:00
Torsten Schulz (local)
7ea719c178 Enhance CourtDrawing components with additional target selection and arrow drawing features
Added new target selection buttons for main and additional strokes in CourtDrawingTool.vue, allowing users to explicitly choose target positions. Updated CourtDrawingRender.vue to support drawing up to three additional arrows, alternating between left and right sides, with distinct colors for each stroke. Improved the logic for determining the next stroke side and updated related methods for better clarity and functionality.
2025-10-30 11:09:55 +01:00
Torsten Schulz (local)
e23d9fbc44 Update testMembership flag in DiaryView to enable testing mode 2025-10-30 08:32:04 +01:00
Torsten Schulz (local)
3f2b92d886 Refactor backend configuration and enhance logging in services
Updated config.js to ensure .env is loaded correctly from the backend directory. Enhanced MyTischtennisUrlController by removing unnecessary console logs and improving error handling. Updated autoFetchMatchResultsService and autoUpdateRatingsService to return detailed summaries, including counts of fetched or updated items. Improved logging in schedulerService to capture execution details, enhancing monitoring capabilities across scheduled tasks.
2025-10-30 08:14:17 +01:00
Torsten Schulz (local)
89329607dc Enhance myTischtennis URL controller with improved error handling and logging
Updated MyTischtennisUrlController to include detailed error messages for missing user IDs and team configurations. Added logging for session details and automatic login attempts, improving debugging capabilities. Enhanced request logging for API calls to myTischtennis, ensuring all requests are logged, even in case of errors. Updated requestLoggingMiddleware to only log myTischtennis-related requests, streamlining log management. Improved validation checks in autoFetchMatchResultsService for team and league data integrity.
2025-10-29 18:07:43 +01:00
Torsten Schulz (local)
c2b8656783 Refactor request logging middleware to simplify endpoint exclusion logic
Updated the requestLoggingMiddleware to streamline the logic for excluding specific endpoints from logging. The new implementation checks for 'status' in the path and handles root paths more efficiently, improving code readability and maintainability.
2025-10-29 13:41:31 +01:00
Torsten Schulz (local)
0b1e745f03 Add API logging functionality and enhance scheduler service
Introduced ApiLog model and integrated logging for scheduled tasks in the SchedulerService. Updated server.js to include request logging middleware and new API log routes. Enhanced frontend navigation by adding a link to system logs for admin users. Adjusted session check interval in App.vue for improved performance. This update improves monitoring and debugging capabilities across the application.
2025-10-29 13:35:25 +01:00
Torsten Schulz (local)
7a35a0a1d3 Update server port and enhance participant management features
Changed the server port from 3000 to 3005 for local development. Enhanced the participant management functionality by adding a new endpoint to update participant group assignments, including error handling for non-existent participants. Updated the participant model to include a groupId reference, and modified the participant retrieval logic to include group information. Additionally, improved the frontend API client to accommodate the new backend structure and added filtering options in the MembersView for better user experience.
2025-10-29 11:48:24 +01:00
Torsten Schulz (local)
bb2164f666 Add league configuration endpoint and frontend integration for myTischtennis
Implemented a new POST endpoint in MyTischtennisUrlController to configure leagues from table URLs, including season creation logic. Updated myTischtennisRoutes to include the new route for league configuration. Enhanced the myTischtennisUrlParserService to support parsing of table URLs and added a method for decoding group names. Updated TeamManagementView.vue to prompt users for league configuration when a table URL is detected, providing feedback upon successful configuration and reloading relevant data.
2025-10-24 17:06:10 +02:00
Torsten Schulz (local)
d16f250f80 Refactor match and predefined activity services for improved functionality and user experience
Removed unnecessary logging from the MatchService to streamline performance. Enhanced the PredefinedActivityService by implementing a more intelligent search feature that splits queries into individual terms, allowing for more precise filtering of activities. Updated the frontend PredefinedActivities.vue to include a search input with real-time results and a clear search button, improving user interaction and accessibility.
2025-10-24 16:35:03 +02:00
Torsten Schulz (local)
c18b70c6f6 Update styles and enhance clipboard functionality in ScheduleView
Modified main.scss to adjust table header styles, changing font weight to 600 and text transformation to uppercase for improved readability. In ScheduleView.vue, updated clipboard copy functionality to provide user feedback with a visual confirmation when copying codes and PINs, enhancing user experience. The feedback mechanism now includes style changes for better visibility and a reset after a brief display period.
2025-10-24 15:56:59 +02:00
Torsten Schulz (local)
67f4f728fe Refactor PDF table generation to support manual column exclusion
Updated the addTable method in PDFGenerator.js to enhance the functionality for excluding specified columns when generating PDF tables. This change allows for more flexible table rendering by manually parsing the HTML table if columns are to be excluded, improving the overall usability of the PDF generation feature.
2025-10-20 23:43:14 +02:00
Torsten Schulz (local)
b69684ad03 Enhance PDF generation by adding column exclusion functionality in PDFGenerator
Updated PDFGenerator.js to allow exclusion of specified columns when generating tables in PDFs. Modified ScheduleView.vue to determine which columns to exclude based on the selected league, improving the flexibility and usability of the PDF generation feature.
2025-10-20 23:40:05 +02:00
Torsten Schulz (local)
4ff021a85c Refactor schedule view to improve PDF generation and enhance element referencing
Updated ScheduleView.vue to replace direct DOM querying with Vue's ref system for better maintainability. The 'flex-item' div now uses a reference for PDF generation, improving code clarity and performance. This change aligns with best practices in Vue component design.
2025-10-20 23:36:31 +02:00
Torsten Schulz (local)
f1b37d131f Refactor predefined activity routes to simplify permission checks and enhance manual navigation in the frontend
Updated backend predefined activity routes to remove explicit permission checks, allowing for streamlined authentication. Modified frontend App.vue to eliminate automatic redirection to the training-stats page, enabling users to navigate manually. This change improves user experience by providing more control over navigation.
2025-10-17 12:48:58 +02:00
Torsten Schulz (local)
48bbc8015b Enhance permission management by adding caching control and improving permission parsing
Implement middleware to disable caching for permission routes, ensuring up-to-date responses. Update permission parsing logic in the backend to handle JSON strings more robustly, preventing errors during permission retrieval. Enhance the frontend PermissionsView with improved UI elements for managing permissions, including reset functionality and better state representation for actions. Ensure that only explicitly set permissions are saved, optimizing data handling.
2025-10-17 11:55:43 +02:00
Torsten Schulz (local)
56f0ce2f27 Implement permission management and enhance user interface for permissions in the application
Add new permission routes and integrate permission checks across various existing routes to ensure proper access control. Update the UserClub model to include role and permissions fields, allowing for more granular user access management. Enhance the frontend by introducing a user dropdown menu for managing permissions and displaying relevant options based on user roles. Improve the overall user experience by implementing permission-based visibility for navigation links and actions throughout the application.
2025-10-17 09:44:10 +02:00
Torsten Schulz (local)
2dd5e28cbc Add manual trigger endpoints for scheduler service in sessionRoutes
Introduce new POST endpoints for triggering rating updates and fetching match results, along with a GET endpoint for retrieving scheduler status. Enhance error handling and response formatting for better API usability.
2025-10-17 08:10:26 +02:00
Torsten Schulz (local)
c74217f6d8 Add member activity routes and UI enhancements in MembersView
Integrate member activity management by adding new routes in the backend for member activities. Update MembersView.vue to include a button for opening the activities modal and implement the MemberActivitiesDialog component for displaying member activities. Enhance the UI with new button styles for better user interaction.
2025-10-16 22:36:49 +02:00
Torsten Schulz (local)
01bbb85485 Enhance diary member activity management by adding validation and logging in addMembersToActivity function. Implement checks for participantIds to ensure they are an array, and log relevant information for better debugging. Update DiaryDateActivityService to improve error handling and logging for group activity associations. Modify frontend DiaryView to support group activity member assignment, including new methods for toggling and assigning members to group activities, enhancing user experience and functionality. 2025-10-16 22:20:51 +02:00
Torsten Schulz (local)
24aaa9c150 Update favicon links and Open Graph/Twitter image metadata in index.html for improved branding and social sharing. Replace existing favicon with multiple formats and update image references for better compatibility across platforms. 2025-10-16 21:36:59 +02:00
Torsten Schulz (local)
ea3cca563b Enhance match management functionality by adding player selection capabilities. Introduce new endpoints for updating match players and retrieving player match statistics in matchController and matchService. Update Match model to include fields for players ready, planned, and played. Modify frontend components to support player selection dialog, allowing users to manage player statuses effectively. Improve UI for better user experience and data visibility. 2025-10-16 21:09:13 +02:00
Torsten Schulz (local)
e0d56ddadd Enhance MyTischtennis fetch logging in AutoFetchMatchResultsService and AutoUpdateRatingsService. Integrate logging for match results and league table fetch attempts, including success status and execution details. Update updateRatings method to utilize memberService for fetching ratings, improving error handling and logging consistency. Update .gitignore to exclude backend log files. 2025-10-16 18:53:28 +02:00
Torsten Schulz (local)
32f06d7399 Refactor MyTischtennis URL controller to streamline match results and league table fetching. Remove redundant logging and execution time tracking for match results, while ensuring successful fetch counts are accurately reported in the response. Simplify error handling for league table updates without failing the entire request. 2025-10-14 23:31:12 +02:00
Torsten Schulz (local)
e823af064e Erweitert den MatchReportApiDialog um neue Funktionen zur Anzeige und Verwaltung von Start- und Endzeiten. Fügt Buttons zum Setzen der aktuellen Zeit für beide Zeitpunkte hinzu und implementiert eine Formatierungsfunktion für die Zeitdarstellung. Optimiert die Benutzeroberfläche mit neuen CSS-Stilen für die Zeitanzeigen und die Auto-Fill-Funktion. 2025-10-04 01:30:10 +02:00
Torsten Schulz (local)
3bc6a465a2 Erweitert den MatchReportApiDialog um eine neue Funktion zur Verwaltung des Abschlussstatus der Begrüßung. Fügt einen Toggle-Button hinzu, um den Status als abgeschlossen oder nicht abgeschlossen zu kennzeichnen, und aktualisiert die Benutzeroberfläche mit entsprechenden visuellen Hinweisen. Implementiert Logik zum automatischen Wechsel zur Ergebniserfassung nach Abschluss der Begrüßung. 2025-10-04 01:06:10 +02:00
Torsten Schulz (local)
e8b6578bd4 Erweitert den MatchReportApiDialog um eine neue Validierungslogik zur Überprüfung, ob beide Mannschaften genügend Spieler für den ALLGAMES-Modus haben. Implementiert die Methode canBothTeamsPlayAllGames, die die Spieleranzahl basierend auf verschiedenen Spielsystemen überprüft. Aktualisiert die Benutzeroberfläche mit neuen Warnungen und Rückmeldungen für unvollständige Mannschaften und ermöglicht das Absenden des Berichts trotz unvollständiger Spieleranzahl. 2025-10-04 00:54:41 +02:00
Torsten Schulz (local)
280c1432b7 Fügt eine Auto-Fill-Funktion für leere Matches im MatchReportApiDialog hinzu. Implementiert einen neuen Header mit einem Button zum automatischen Ausfüllen, der die Spielergebnisse für unvollständige Matches basierend auf vorhandenen Spielern automatisch ausfüllt. Verbessert die Benutzeroberfläche mit neuen CSS-Stilen für den Header und den Button. 2025-10-04 00:51:25 +02:00
Torsten Schulz (local)
fd82efdcee Optimiert die Spieleranzahl-Berechnung im MatchReportApiDialog, um die Braunschweiger Regel zu berücksichtigen. Implementiert die Methode getEffectivePlayerCount, die die Spieleranzahl für 2er-Mannschaften als 3 zählt. Aktualisiert die Logik zur Überprüfung der verfügbaren Spieler für Positionen und verbessert die Benutzeroberfläche durch präzisere Rückmeldungen. 2025-10-04 00:45:45 +02:00
Torsten Schulz (local)
e354d82969 Erweitert den MatchReportApiDialog um umfassende Validierungslogik für die Eingabe von Spielberichten. Implementiert neue Warnungen für unvollständige oder fehlerhafte Match-Ergebnisse sowie für ungültige Start- und Endzeiten. Aktualisiert die Logik zur Aktivierung und Deaktivierung des Absende-Buttons basierend auf den Validierungsbedingungen. Verbessert die Benutzeroberfläche mit neuen CSS-Stilen für Validierungsbenachrichtigungen und optimiert die Benutzererfahrung durch dynamische Rückmeldungen. 2025-10-03 23:42:52 +02:00
Torsten Schulz (local)
049ee56571 Erweitert den MatchReportApiDialog um neue Validierungsfunktionen zur Überprüfung von Satz-Inputs und zur Handhabung von Lücken in der Eingabe. Implementiert Methoden zur Berechnung gewonnener Sätze und zur Deaktivierung von Eingabefeldern, wenn ein Spieler bereits 3 Sätze gewonnen hat. Fügt visuelle Warnungen für problematische Eingaben hinzu und verbessert die Benutzeroberfläche mit neuen CSS-Stilen für Eingabefelder. 2025-10-03 23:11:18 +02:00
Torsten Schulz (local)
c6bb534a0d Erweitert den MatchReportApiDialog um Validierungslogik für Mindestspielerzahlen und Doppel. Fügt Methoden zur Überprüfung der Spieleranzahl und Doppelformationen basierend auf dem Spielmodus hinzu. Implementiert Fehlermeldungen zur Anzeige von Validierungsfehlern für Heim- und Gastteams. Verbessert die Benutzeroberfläche mit neuen CSS-Stilen für Fehlermeldungen. 2025-10-03 23:01:13 +02:00
Torsten Schulz (local)
a0fdf256e7 Fügt neue Funktionen zur Bearbeitung von Spielberichten im MatchReportApiDialog hinzu. Implementiert eine Anzeige für den Abschlussstatus des Spiels, einschließlich Warnungen und Deaktivierungen von Eingabefeldern, wenn das Match bereits abgeschlossen ist. Aktualisiert die Logik zur Berechnung der Gesamtpunkte und Sätze sowie zur Validierung von PINs. Verbessert die Benutzeroberfläche mit neuen CSS-Stilen für abgeschlossene Matches und Dialoge zur Anzeige von Match-Daten. 2025-10-03 22:49:05 +02:00
Torsten Schulz (local)
d23a9f086c Erweitert den MatchReportApiDialog mit neuen Funktionen zur Abschlussbearbeitung. Fügt die Anzeige von Aufstellungen, Endergebnis, Zeitangaben, Protest-Eingabe und PIN-Eingaben hinzu. Implementiert Methoden zur Extraktion von Einzel- und Doppelspielern sowie zur Berechnung des Gesamtergebnisses. Optimiert die Benutzeroberfläche mit neuen CSS-Stilen für eine verbesserte Darstellung. 2025-10-03 20:13:49 +02:00
Torsten Schulz (local)
ac727c6c5b Fügt die Funktionalität zur Aktualisierung der Vereinseinstellungen hinzu. Implementiert die Methode updateClubSettings im clubsController, um Begrüßungstexte und Mitgliedsnummern zu aktualisieren. Aktualisiert das Club-Modell, um neue Felder für greetingText und associationMemberNumber zu unterstützen. Ergänzt die Routen in clubRoutes, um die neuen Einstellungen zu verarbeiten. Fügt eine neue Ansicht für die Vereins-Einstellungen im Frontend hinzu und aktualisiert die Navigation entsprechend. 2025-10-03 19:49:19 +02:00
Torsten Schulz (local)
4b1a046149 Fügt Unterstützung für die neue nuscore API hinzu. Aktualisiert die Backend-Routen zur Verarbeitung von Anfragen an die nuscore API und integriert die neuen Dialogkomponenten im Frontend. Ermöglicht das Erstellen lokaler Kopien von nuscore-Daten und verbessert die Benutzeroberfläche durch neue Schaltflächen und Dialoge. Entfernt veraltete Konsolenausgaben und optimiert die Logik zur PIN-Verwaltung. 2025-10-03 15:57:57 +02:00
484 changed files with 48323 additions and 23072 deletions

2
.gitignore vendored
View File

@@ -6,3 +6,5 @@ frontend/.env
backend/.env
backend/images/*
backend/backend-debug.log
backend/*.log

210
PERMISSIONS_GUIDE.md Normal file
View File

@@ -0,0 +1,210 @@
# Berechtigungssystem - Dokumentation
## Übersicht
Das Trainingstagebuch verfügt nun über ein vollständiges rollenbasiertes Berechtigungssystem (RBAC - Role-Based Access Control). Der Club-Ersteller hat automatisch Admin-Rechte und kann anderen Mitgliedern Rollen und spezifische Berechtigungen zuweisen.
## Rollen
### 1. Administrator (admin)
- **Vollzugriff** auf alle Funktionen
- Kann Berechtigungen anderer Benutzer verwalten
- Der Club-Ersteller ist automatisch Administrator und kann nicht degradiert werden
### 2. Trainer (trainer)
- Kann Trainingseinheiten planen und verwalten
- Kann Mitglieder anlegen und bearbeiten
- Kann Spielpläne einsehen und bearbeiten
- Kann Turniere organisieren
- **Kann nicht**: Einstellungen ändern, Berechtigungen verwalten
### 3. Mannschaftsführer (team_manager)
- Kann Teams und Spielpläne verwalten
- Kann Spieler für Matches einteilen
- Kann Spielergebnisse eintragen
- **Kann nicht**: Trainingseinheiten planen, Mitglieder verwalten
### 4. Mitglied (member)
- Nur Lesezugriff auf alle Bereiche
- Kann eigene Daten einsehen
- **Kann nicht**: Daten ändern oder löschen
## Berechtigungsbereiche
- **diary**: Trainingstagebuch
- **members**: Mitgliederverwaltung
- **teams**: Team-Management
- **schedule**: Spielpläne
- **tournaments**: Turniere
- **statistics**: Statistiken
- **settings**: Einstellungen
- **permissions**: Berechtigungsverwaltung
- **mytischtennis**: MyTischtennis-Integration (für alle zugänglich)
## Backend-Integration
### Migration ausführen
```sql
mysql -u username -p database_name < backend/migrations/add_permissions_to_user_club.sql
```
### Authorization Middleware verwenden
```javascript
import { authorize, requireAdmin, requireOwner } from '../middleware/authorizationMiddleware.js';
// Beispiel: Nur Lesezugriff erforderlich
router.get('/diary/:clubId', authenticate, authorize('diary', 'read'), getDiary);
// Beispiel: Schreibzugriff erforderlich
router.post('/diary/:clubId', authenticate, authorize('diary', 'write'), createDiary);
// Beispiel: Admin-Rechte erforderlich
router.put('/settings/:clubId', authenticate, requireAdmin(), updateSettings);
// Beispiel: Nur Owner
router.delete('/club/:clubId', authenticate, requireOwner(), deleteClub);
```
### Permission Service verwenden
```javascript
import permissionService from '../services/permissionService.js';
// Berechtigungen prüfen
const hasPermission = await permissionService.hasPermission(userId, clubId, 'diary', 'write');
// Rolle setzen
await permissionService.setUserRole(userId, clubId, 'trainer', adminUserId);
// Custom Permissions setzen
await permissionService.setCustomPermissions(
userId,
clubId,
{ diary: { write: false }, members: { write: true } },
adminUserId
);
```
## Frontend-Integration
### Composable verwenden
```vue
<script setup>
import { usePermissions } from '@/composables/usePermissions.js';
const { can, canWrite, canDelete, isAdmin, isOwner, userRole } = usePermissions();
// Beispiel
if (can('diary', 'write')) {
// Zeige Bearbeitungsbutton
}
</script>
```
### Direktiven verwenden
```vue
<template>
<!-- Nur anzeigen, wenn Schreibrechte für diary vorhanden -->
<button v-can:diary.write>Bearbeiten</button>
<!-- Nur anzeigen, wenn Löschrechte für members vorhanden -->
<button v-can:members.delete>Löschen</button>
<!-- Alternative Syntax -->
<div v-can="'diary.write'">Inhalt nur für Berechtigte</div>
<!-- Nur für Admins -->
<div v-admin>Admin-Bereich</div>
<!-- Nur für Owner -->
<div v-owner>Owner-Bereich</div>
</template>
```
### Store verwenden
```javascript
import { useStore } from 'vuex';
const store = useStore();
// Berechtigungen abrufen
const permissions = store.getters.currentPermissions;
const hasPermission = store.getters.hasPermission('diary', 'write');
const isOwner = store.getters.isClubOwner;
const userRole = store.getters.userRole;
// Berechtigungen laden (wird automatisch beim Club-Wechsel gemacht)
await store.dispatch('loadPermissions', clubId);
```
## Admin-UI
Die Berechtigungsverwaltung ist unter `/permissions` verfügbar und nur für Administratoren sichtbar.
**Funktionen:**
- Übersicht aller Clubmitglieder mit ihren Rollen
- Rollen zuweisen/ändern
- Custom Permissions für einzelne Benutzer definieren
- Erklärung der verfügbaren Rollen
## MyTischtennis-Integration
Die MyTischtennis-Einstellungen und -Funktionen sind für **alle Club-Mitglieder** zugänglich, unabhängig von ihrer Rolle. Dies ermöglicht es jedem, die Anbindung einzurichten und Daten abzurufen.
## Sicherheitshinweise
1. **Der Club-Ersteller** (Owner) kann nicht degradiert oder gelöscht werden
2. **Owner-Rechte** können nicht übertragen werden
3. **Backend-Validierung** wird immer durchgeführt, auch wenn das Frontend Elemente ausblendet
4. **Alle API-Routen** sind durch Middleware geschützt
5. **Permissions werden gecacht** im localStorage für bessere Performance
## Beispiel-Szenarien
### Szenario 1: Trainer hinzufügen
1. Admin öffnet `/permissions`
2. Wählt Benutzer aus
3. Ändert Rolle zu "Trainer"
4. Benutzer kann jetzt Trainingseinheiten planen
### Szenario 2: Custom Permissions
1. Admin öffnet `/permissions`
2. Wählt Benutzer aus
3. Klickt auf "Anpassen"
4. Setzt individuelle Berechtigungen (z.B. nur Diary-Schreibrecht)
5. Speichert
### Szenario 3: Neues Mitglied
1. Mitglied registriert sich und fordert Zugang an
2. Admin genehmigt Anfrage (Standardrolle: "member")
3. Mitglied hat Lesezugriff
4. Bei Bedarf kann Admin die Rolle später ändern
## Troubleshooting
**Problem**: Berechtigungen werden nicht aktualisiert
- **Lösung**: Seite neu laden oder Club neu auswählen
**Problem**: "Keine Berechtigung" trotz korrekter Rolle
- **Lösung**: Prüfen, ob Custom Permissions die Rolle überschreiben
**Problem**: Owner kann keine Änderungen vornehmen
- **Lösung**: Owner sollte automatisch alle Rechte haben. Prüfen Sie die `isOwner`-Flag in der Datenbank
## API-Endpunkte
```
GET /api/permissions/:clubId - Eigene Berechtigungen abrufen
GET /api/permissions/:clubId/members - Alle Mitglieder mit Berechtigungen (Admin)
PUT /api/permissions/:clubId/user/:userId/role - Rolle ändern (Admin)
PUT /api/permissions/:clubId/user/:userId/permissions - Custom Permissions setzen (Admin)
GET /api/permissions/roles/available - Verfügbare Rollen abrufen
GET /api/permissions/structure/all - Berechtigungsstruktur abrufen
```

235
PERMISSIONS_MIGRATION.md Normal file
View File

@@ -0,0 +1,235 @@
# Berechtigungssystem - Migrations-Anleitung
## Übersicht
Diese Anleitung hilft Ihnen, das neue Berechtigungssystem für bestehende Clubs einzurichten.
## Schritt 1: Datenbank-Schema erweitern
Führen Sie zuerst die SQL-Migration aus, um die neuen Spalten hinzuzufügen:
```bash
mysql -u username -p database_name < backend/migrations/add_permissions_to_user_club.sql
```
Dies fügt folgende Spalten zur `user_club` Tabelle hinzu:
- `role` (VARCHAR) - Benutzerrolle (admin, trainer, team_manager, member)
- `permissions` (JSON) - Custom Permissions
- `is_owner` (BOOLEAN) - Markiert den Club-Ersteller
## Schritt 2: Bestehende Daten migrieren
Sie haben zwei Optionen:
### Option A: Node.js Script (Empfohlen)
Das Script identifiziert automatisch den ersten Benutzer jedes Clubs (nach `createdAt`) und setzt ihn als Owner.
```bash
cd /home/torsten/Programs/trainingstagebuch/backend
node scripts/migratePermissions.js
```
**Ausgabe:**
```
Starting permissions migration...
Found 3 club(s)
--- Club: TTC Beispiel (ID: 1) ---
Members found: 5
First member (will be owner): admin@example.com
✓ Updated admin@example.com: role=admin, isOwner=true
✓ Updated user1@example.com: role=member, isOwner=false
✓ Updated user2@example.com: role=member, isOwner=false
...
✅ Migration completed successfully!
Summary:
Club Owners (3):
- TTC Beispiel: admin@example.com
- SV Teststadt: owner@test.de
- TSC Demo: demo@example.com
Role Distribution:
- Admins: 3
- Members: 12
```
### Option B: SQL Script
Wenn Sie lieber SQL verwenden möchten:
```bash
mysql -u username -p database_name < backend/migrations/update_existing_user_club_permissions.sql
```
Dieses Script:
1. Setzt `role = 'member'` für alle genehmigten Benutzer ohne Rolle
2. Markiert den Benutzer mit der niedrigsten `user_id` pro Club als Owner
## Schritt 3: Manuelle Anpassungen (Optional)
### Falscher Owner?
Falls das Script den falschen Benutzer als Owner markiert hat, können Sie dies manuell korrigieren:
```sql
-- Alten Owner zurücksetzen
UPDATE user_club
SET is_owner = 0, role = 'member'
WHERE club_id = 1 AND user_id = 123;
-- Neuen Owner setzen
UPDATE user_club
SET is_owner = 1, role = 'admin'
WHERE club_id = 1 AND user_id = 456;
```
### Weitere Admins ernennen
```sql
UPDATE user_club
SET role = 'admin'
WHERE club_id = 1 AND user_id = 789;
```
### Trainer ernennen
```sql
UPDATE user_club
SET role = 'trainer'
WHERE club_id = 1 AND user_id = 101;
```
## Schritt 4: Verifizierung
### Backend neu starten
```bash
# Server neu starten (wenn er läuft)
sudo systemctl restart tt-tagebuch
```
### Im Browser testen
1. Loggen Sie sich ein
2. Wählen Sie einen Club aus
3. Navigieren Sie zu "Berechtigungen" (nur für Admins sichtbar)
4. Überprüfen Sie, dass alle Mitglieder korrekt angezeigt werden
### SQL Verifizierung
```sql
-- Alle Club-Mitglieder mit ihren Berechtigungen anzeigen
SELECT
c.name as club_name,
u.email as user_email,
uc.role,
uc.is_owner,
uc.approved
FROM user_club uc
JOIN club c ON c.id = uc.club_id
JOIN user u ON u.id = uc.user_id
WHERE uc.approved = 1
ORDER BY c.name, uc.is_owner DESC, uc.role, u.email;
```
## Troubleshooting
### Problem: "Keine Berechtigung" trotz Owner-Status
**Lösung:** Überprüfen Sie in der Datenbank:
```sql
SELECT role, is_owner, approved
FROM user_club
WHERE user_id = YOUR_USER_ID AND club_id = YOUR_CLUB_ID;
```
Sollte sein: `role='admin'`, `is_owner=1`, `approved=1`
### Problem: Owner kann nicht geändert werden
Das ist korrekt! Der Owner (Club-Ersteller) kann seine eigenen Rechte nicht verlieren. Dies ist eine Sicherheitsmaßnahme.
### Problem: Berechtigungen werden nicht geladen
**Lösung:**
1. Browser-Cache leeren
2. LocalStorage leeren: `localStorage.clear()` in der Browser-Console
3. Neu einloggen
### Problem: "Lade Mitglieder..." bleibt hängen
**Mögliche Ursachen:**
1. Migration noch nicht ausgeführt
2. Backend nicht neu gestartet
3. Frontend nicht neu gebaut
**Lösung:**
```bash
# Backend
cd /home/torsten/Programs/trainingstagebuch/backend
node scripts/migratePermissions.js
# Frontend
cd /home/torsten/Programs/trainingstagebuch/frontend
npm run build
# Server neu starten
sudo systemctl restart tt-tagebuch
```
## Nach der Migration
### Neue Clubs
Bei neuen Clubs wird der Ersteller automatisch als Owner mit Admin-Rechten eingerichtet. Keine manuelle Aktion erforderlich.
### Neue Mitglieder
Neue Mitglieder erhalten automatisch die Rolle "member" (Lesezugriff). Admins können die Rolle später ändern.
### Berechtigungen verwalten
Admins können über die Web-UI unter `/permissions` Berechtigungen verwalten:
1. Rollen zuweisen (Admin, Trainer, Mannschaftsführer, Mitglied)
2. Custom Permissions definieren (für spezielle Anwendungsfälle)
## Wichtige Hinweise
⚠️ **Sicherung erstellen:**
```bash
mysqldump -u username -p database_name > backup_before_permissions_$(date +%Y%m%d).sql
```
⚠️ **Owner-Rechte:**
- Der Owner (is_owner=1) kann nicht degradiert oder gelöscht werden
- Jeder Club hat genau einen Owner
- Owner-Rechte können nicht übertragen werden (nur durch direkte DB-Änderung)
⚠️ **MyTischtennis:**
- MyTischtennis-Funktionen sind für ALLE Mitglieder zugänglich
- Keine Berechtigungsprüfung für MyTischtennis-Endpunkte
## Rollback (falls nötig)
Falls Sie das Berechtigungssystem zurücknehmen müssen:
```sql
-- Spalten entfernen (Achtung: Datenverlust!)
ALTER TABLE user_club
DROP COLUMN role,
DROP COLUMN permissions,
DROP COLUMN is_owner;
-- Indizes entfernen
DROP INDEX idx_user_club_role ON user_club;
DROP INDEX idx_user_club_owner ON user_club;
```
Dann Backend-Code auf vorherige Version zurücksetzen.

View File

@@ -203,7 +203,8 @@ export default {
this.parsedData = result.data;
} catch (error) {
console.error('Fehler beim Parsen:', error);
alert('URL konnte nicht geparst werden');
// Hinweis: Im Frontend stattdessen InfoDialog/ConfirmDialog verwenden
// alert('URL konnte nicht geparst werden');
}
},
@@ -227,11 +228,14 @@ export default {
const result = await response.json();
if (result.success) {
alert('Team erfolgreich konfiguriert!');
// In der Anwendung bitte InfoDialog nutzen
// alert('Team erfolgreich konfiguriert!');
} else {
// alert('Team konnte nicht konfiguriert werden');
}
} catch (error) {
console.error('Fehler bei Konfiguration:', error);
alert('Team konnte nicht konfiguriert werden');
// alert('Team konnte nicht konfiguriert werden');
}
}
}

View File

@@ -9,15 +9,18 @@ const dbConfig = {
database: process.env.DB_NAME || 'trainingsdiary'
};
const report = [];
async function cleanupKeys() {
let connection;
try {
console.log('🔌 Verbinde mit der Datenbank...');
report.push('🔌 Verbinde mit der Datenbank...');
connection = await mysql.createConnection(dbConfig);
// 1. Status vor dem Cleanup
console.log('\n📊 STATUS VOR DEM CLEANUP:');
report.push('');
report.push('📊 STATUS VOR DEM CLEANUP:');
const [tablesBefore] = await connection.execute(`
SELECT
TABLE_NAME,
@@ -29,57 +32,60 @@ async function cleanupKeys() {
`, [dbConfig.database]);
tablesBefore.forEach(table => {
console.log(` ${table.TABLE_NAME}: ${table.key_count} Keys`);
report.push(` ${table.TABLE_NAME}: ${table.key_count} Keys`);
});
// 2. Alle INDEX der Problem-Tabellen anzeigen
const problemTables = ['member', 'diary_tags', 'season'];
for (const tableName of problemTables) {
console.log(`\n🔍 INDEX für Tabelle '${tableName}':`);
report.push('');
report.push(`🔍 INDEX für Tabelle '${tableName}':`);
try {
const [indexes] = await connection.execute(`SHOW INDEX FROM \`${tableName}\``);
if (indexes.length === 0) {
console.log(` Keine INDEX gefunden für Tabelle '${tableName}'`);
report.push(` Keine INDEX gefunden für Tabelle '${tableName}'`);
continue;
}
indexes.forEach(index => {
console.log(` - ${index.Key_name} (${index.Column_name}) - ${index.Non_unique === 0 ? 'UNIQUE' : 'NON-UNIQUE'}`);
report.push(` - ${index.Key_name} (${index.Column_name}) - ${index.Non_unique === 0 ? 'UNIQUE' : 'NON-UNIQUE'}`);
});
// 3. Überflüssige INDEX entfernen (alle außer PRIMARY und UNIQUE)
console.log(`\n🗑️ Entferne überflüssige INDEX aus '${tableName}':`);
report.push('');
report.push(`🗑️ Entferne überflüssige INDEX aus '${tableName}':`);
for (const index of indexes) {
// Behalte PRIMARY KEY und UNIQUE constraints
if (index.Key_name === 'PRIMARY' || index.Non_unique === 0) {
console.log(` ✅ Behalte: ${index.Key_name} (${index.Column_name})`);
report.push(` ✅ Behalte: ${index.Key_name} (${index.Column_name})`);
continue;
}
// Entferne alle anderen INDEX
try {
await connection.execute(`DROP INDEX \`${index.Key_name}\` ON \`${tableName}\``);
console.log(` ❌ Entfernt: ${index.Key_name} (${index.Column_name})`);
report.push(` ❌ Entfernt: ${index.Key_name} (${index.Column_name})`);
} catch (error) {
if (error.code === 'ER_CANT_DROP_FIELD_OR_KEY') {
console.log(` ⚠️ Kann nicht entfernen: ${index.Key_name} (${index.Column_name}) - ${error.message}`);
report.push(` ⚠️ Kann nicht entfernen: ${index.Key_name} (${index.Column_name}) - ${error.message}`);
} else {
console.log(` ❌ Fehler beim Entfernen von ${index.Key_name}: ${error.message}`);
report.push(` ❌ Fehler beim Entfernen von ${index.Key_name}: ${error.message}`);
}
}
}
} catch (error) {
console.log(` ⚠️ Fehler beim Zugriff auf Tabelle '${tableName}': ${error.message}`);
report.push(` ⚠️ Fehler beim Zugriff auf Tabelle '${tableName}': ${error.message}`);
}
}
// 4. Status nach dem Cleanup
console.log('\n📊 STATUS NACH DEM CLEANUP:');
report.push('');
report.push('📊 STATUS NACH DEM CLEANUP:');
const [tablesAfter] = await connection.execute(`
SELECT
TABLE_NAME,
@@ -96,7 +102,7 @@ async function cleanupKeys() {
const diff = beforeCount - table.key_count;
const status = table.key_count <= 5 ? '✅' : table.key_count <= 10 ? '⚠️' : '❌';
console.log(` ${status} ${table.TABLE_NAME}: ${table.key_count} Keys (${diff > 0 ? `-${diff}` : `+${Math.abs(diff)}`})`);
report.push(` ${status} ${table.TABLE_NAME}: ${table.key_count} Keys (${diff > 0 ? `-${diff}` : `+${Math.abs(diff)}`})`);
});
// 5. Gesamtanzahl der Keys
@@ -106,18 +112,20 @@ async function cleanupKeys() {
WHERE TABLE_SCHEMA = ?
`, [dbConfig.database]);
console.log(`\n📈 GESAMTANZAHL KEYS: ${totalKeys[0].total_keys}`);
report.push('');
report.push(`📈 GESAMTANZAHL KEYS: ${totalKeys[0].total_keys}`);
// 6. Zusammenfassung
console.log('\n🎯 ZUSAMMENFASSUNG:');
report.push('');
report.push('🎯 ZUSAMMENFASSUNG:');
const problemTablesAfter = tablesAfter.filter(t => t.key_count > 10);
if (problemTablesAfter.length === 0) {
console.log(' ✅ Alle Tabellen haben jetzt weniger als 10 Keys!');
report.push(' ✅ Alle Tabellen haben jetzt weniger als 10 Keys!');
} else {
console.log(' ⚠️ Folgende Tabellen haben immer noch zu viele Keys:');
report.push(' ⚠️ Folgende Tabellen haben immer noch zu viele Keys:');
problemTablesAfter.forEach(table => {
console.log(` - ${table.TABLE_NAME}: ${table.key_count} Keys`);
report.push(` - ${table.TABLE_NAME}: ${table.key_count} Keys`);
});
}
@@ -126,15 +134,18 @@ async function cleanupKeys() {
} finally {
if (connection) {
await connection.end();
console.log('\n🔌 Datenbankverbindung geschlossen.');
report.push('');
report.push('🔌 Datenbankverbindung geschlossen.');
}
}
}
// Script ausführen
console.log('🚀 Starte intelligentes INDEX-Cleanup...\n');
report.push('🚀 Starte intelligentes INDEX-Cleanup...');
cleanupKeys().then(() => {
console.log('\n✨ Cleanup abgeschlossen!');
report.push('');
report.push('✨ Cleanup abgeschlossen!');
process.stdout.write(`${report.join('\n')}\n`);
process.exit(0);
}).catch(error => {
console.error('\n💥 Fehler beim Cleanup:', error);

View File

@@ -7,41 +7,23 @@ import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const report = [];
// Umgebungsvariablen aus dem Root-Verzeichnis laden
//const envPath = path.join(__dirname, '..', '.env');
//console.log('🔍 Lade .env-Datei von:', envPath);
const envPath = path.join(__dirname, '..', '.env');
dotenv.config();
// Debug: Zeige geladene Umgebungsvariablen
console.log('🔍 Geladene Umgebungsvariablen:');
console.log(' DB_HOST:', process.env.DB_HOST);
console.log(' DB_USER:', process.env.DB_USER);
console.log(' DB_NAME:', process.env.DB_NAME);
console.log(' DB_PASSWORD:', process.env.DB_PASSWORD ? '***gesetzt***' : 'nicht gesetzt');
// Datenbankverbindung
const dbConfig = {
host: process.env.DB_HOST || 'localhost',
user: process.env.DB_USER || 'root',
password: process.env.DB_PASSWORD || '',
database: process.env.DB_NAME || 'trainingsdiary'
};
console.log('🔍 Datenbankverbindung:');
console.log(' Host:', dbConfig.host);
console.log(' User:', dbConfig.user);
console.log(' Database:', dbConfig.database);
console.log(' Password:', dbConfig.password ? '***gesetzt***' : 'nicht gesetzt');
report.push('Environment variables loaded');
async function cleanupKeys() {
let connection;
try {
console.log('🔌 Verbinde mit der Datenbank...');
report.push('🔌 Verbinde mit der Datenbank...');
connection = await mysql.createConnection(dbConfig);
// 1. Status vor dem Cleanup
console.log('\n📊 STATUS VOR DEM CLEANUP:');
report.push('');
report.push('📊 STATUS VOR DEM CLEANUP:');
const [tablesBefore] = await connection.execute(`
SELECT
TABLE_NAME,
@@ -53,57 +35,60 @@ async function cleanupKeys() {
`, [dbConfig.database]);
tablesBefore.forEach(table => {
console.log(` ${table.TABLE_NAME}: ${table.key_count} Keys`);
report.push(` ${table.TABLE_NAME}: ${table.key_count} Keys`);
});
// 2. Alle INDEX der Problem-Tabellen anzeigen
const problemTables = ['member', 'diary_tags', 'season'];
for (const tableName of problemTables) {
console.log(`\n🔍 INDEX für Tabelle '${tableName}':`);
report.push('');
report.push(`🔍 INDEX für Tabelle '${tableName}':`);
try {
const [indexes] = await connection.execute(`SHOW INDEX FROM \`${tableName}\``);
if (indexes.length === 0) {
console.log(` Keine INDEX gefunden für Tabelle '${tableName}'`);
report.push(` Keine INDEX gefunden für Tabelle '${tableName}'`);
continue;
}
indexes.forEach(index => {
console.log(` - ${index.Key_name} (${index.Column_name}) - ${index.Non_unique === 0 ? 'UNIQUE' : 'NON-UNIQUE'}`);
report.push(` - ${index.Key_name} (${index.Column_name}) - ${index.Non_unique === 0 ? 'UNIQUE' : 'NON-UNIQUE'}`);
});
// 3. Überflüssige INDEX entfernen (alle außer PRIMARY und UNIQUE)
console.log(`\n🗑️ Entferne überflüssige INDEX aus '${tableName}':`);
report.push('');
report.push(`🗑️ Entferne überflüssige INDEX aus '${tableName}':`);
for (const index of indexes) {
// Behalte PRIMARY KEY und UNIQUE constraints
if (index.Key_name === 'PRIMARY' || index.Non_unique === 0) {
console.log(` ✅ Behalte: ${index.Key_name} (${index.Column_name})`);
report.push(` ✅ Behalte: ${index.Key_name} (${index.Column_name})`);
continue;
}
// Entferne alle anderen INDEX
try {
await connection.execute(`DROP INDEX \`${index.Key_name}\` ON \`${tableName}\``);
console.log(` ❌ Entfernt: ${index.Key_name} (${index.Column_name})`);
report.push(` ❌ Entfernt: ${index.Key_name} (${index.Column_name})`);
} catch (error) {
if (error.code === 'ER_CANT_DROP_FIELD_OR_KEY') {
console.log(` ⚠️ Kann nicht entfernen: ${index.Key_name} (${index.Column_name}) - ${error.message}`);
report.push(` ⚠️ Kann nicht entfernen: ${index.Key_name} (${index.Column_name}) - ${error.message}`);
} else {
console.log(` ❌ Fehler beim Entfernen von ${index.Key_name}: ${error.message}`);
report.push(` ❌ Fehler beim Entfernen von ${index.Key_name}: ${error.message}`);
}
}
}
} catch (error) {
console.log(` ⚠️ Fehler beim Zugriff auf Tabelle '${tableName}': ${error.message}`);
report.push(` ⚠️ Fehler beim Zugriff auf Tabelle '${tableName}': ${error.message}`);
}
}
// 4. Status nach dem Cleanup
console.log('\n📊 STATUS NACH DEM CLEANUP:');
report.push('');
report.push('📊 STATUS NACH DEM CLEANUP:');
const [tablesAfter] = await connection.execute(`
SELECT
TABLE_NAME,
@@ -120,7 +105,7 @@ async function cleanupKeys() {
const diff = beforeCount - table.key_count;
const status = table.key_count <= 5 ? '✅' : table.key_count <= 10 ? '⚠️' : '❌';
console.log(` ${status} ${table.TABLE_NAME}: ${table.key_count} Keys (${diff > 0 ? `-${diff}` : `+${Math.abs(diff)}`})`);
report.push(` ${status} ${table.TABLE_NAME}: ${table.key_count} Keys (${diff > 0 ? `-${diff}` : `+${Math.abs(diff)}`})`);
});
// 5. Gesamtanzahl der Keys
@@ -130,18 +115,20 @@ async function cleanupKeys() {
WHERE TABLE_SCHEMA = ?
`, [dbConfig.database]);
console.log(`\n📈 GESAMTANZAHL KEYS: ${totalKeys[0].total_keys}`);
report.push('');
report.push(`📈 GESAMTANZAHL KEYS: ${totalKeys[0].total_keys}`);
// 6. Zusammenfassung
console.log('\n🎯 ZUSAMMENFASSUNG:');
report.push('');
report.push('🎯 ZUSAMMENFASSUNG:');
const problemTablesAfter = tablesAfter.filter(t => t.key_count > 10);
if (problemTablesAfter.length === 0) {
console.log(' ✅ Alle Tabellen haben jetzt weniger als 10 Keys!');
report.push(' ✅ Alle Tabellen haben jetzt weniger als 10 Keys!');
} else {
console.log(' ⚠️ Folgende Tabellen haben immer noch zu viele Keys:');
report.push(' ⚠️ Folgende Tabellen haben immer noch zu viele Keys:');
problemTablesAfter.forEach(table => {
console.log(` - ${table.TABLE_NAME}: ${table.key_count} Keys`);
report.push(` - ${table.TABLE_NAME}: ${table.key_count} Keys`);
});
}
@@ -150,15 +137,18 @@ async function cleanupKeys() {
} finally {
if (connection) {
await connection.end();
console.log('\n🔌 Datenbankverbindung geschlossen.');
report.push('');
report.push('🔌 Datenbankverbindung geschlossen.');
}
}
}
// Script ausführen
console.log('🚀 Starte intelligentes INDEX-Cleanup...\n');
report.push('🚀 Starte intelligentes INDEX-Cleanup...');
cleanupKeys().then(() => {
console.log('\n✨ Cleanup abgeschlossen!');
report.push('');
report.push('✨ Cleanup abgeschlossen!');
process.stdout.write(`${report.join('\n')}\n`);
process.exit(0);
}).catch(error => {
console.error('\n💥 Fehler beim Cleanup:', error);

View File

@@ -156,17 +156,6 @@ class MyTischtennisClient {
if (result.success) {
console.log('[getUserProfile] - Response structure:', {
hasUserProfile: !!result.data?.userProfile,
hasClub: !!result.data?.userProfile?.club,
hasOrganization: !!result.data?.userProfile?.organization,
clubnr: result.data?.userProfile?.club?.clubnr,
clubName: result.data?.userProfile?.club?.name,
orgShort: result.data?.userProfile?.organization?.short,
ttr: result.data?.userProfile?.ttr,
qttr: result.data?.userProfile?.qttr
});
return {
success: true,
@@ -190,14 +179,14 @@ class MyTischtennisClient {
* @param {string} fedNickname - Federation nickname (e.g., "HeTTV")
* @returns {Promise<Object>} Rankings with player entries (all pages)
*/
async getClubRankings(cookie, clubId, fedNickname) {
async getClubRankings(cookie, clubId, fedNickname, currentRanking = 'yes') {
const allEntries = [];
let currentPage = 0;
let hasMorePages = true;
while (hasMorePages) {
const endpoint = `/rankings/andro-rangliste?all-players=on&clubnr=${clubId}&fednickname=${fedNickname}&results-per-page=100&page=${currentPage}&_data=routes%2F%24`;
const endpoint = `/rankings/andro-rangliste?all-players=on&clubnr=${clubId}&fednickname=${fedNickname}&current-ranking=${currentRanking}&results-per-page=100&page=${currentPage}&_data=routes%2F%24`;
const result = await this.authenticatedRequest(endpoint, cookie, {

View File

@@ -1,17 +1,41 @@
import dotenv from 'dotenv';
import path from 'path';
import { fileURLToPath } from 'url';
dotenv.config();
// Ensure .env is loaded from the backend folder (not dependent on process.cwd())
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
dotenv.config({ path: path.resolve(__dirname, '.env') });
export const development = {
const isTestEnv = process.env.NODE_ENV === 'test';
const baseConfig = {
username: process.env.DB_USER || 'root',
password: process.env.DB_PASSWORD || 'hitomisan',
database: process.env.DB_NAME || 'trainingdiary',
host: process.env.DB_HOST,
dialect: process.env.DB_DIALECT,
host: process.env.DB_HOST || 'localhost',
dialect: process.env.DB_DIALECT || 'mysql',
define: {
freezeTableName: true,
underscored: true,
underscoredAll: true,
},
logging: false,
storage: process.env.DB_STORAGE,
};
if (isTestEnv) {
baseConfig.username = 'sqlite';
baseConfig.password = '';
baseConfig.database = 'sqlite';
baseConfig.host = 'localhost';
baseConfig.dialect = 'sqlite';
baseConfig.storage = process.env.DB_STORAGE || ':memory:';
}
if (baseConfig.dialect === 'sqlite' && !baseConfig.storage) {
baseConfig.storage = ':memory:';
}
export const development = baseConfig;

View File

@@ -0,0 +1,85 @@
import apiLogService from '../services/apiLogService.js';
import HttpError from '../exceptions/HttpError.js';
class ApiLogController {
/**
* GET /api/logs
* Get API logs with optional filters
*/
async getLogs(req, res, next) {
try {
const {
userId,
logType,
method,
path,
statusCode,
startDate,
endDate,
limit = 100,
offset = 0
} = req.query;
const result = await apiLogService.getLogs({
userId: userId ? parseInt(userId) : null,
logType,
method,
path,
statusCode: statusCode ? parseInt(statusCode) : null,
startDate,
endDate,
limit: parseInt(limit),
offset: parseInt(offset)
});
res.json({
success: true,
data: result
});
} catch (error) {
next(error);
}
}
/**
* GET /api/logs/:id
* Get a single log entry by ID
*/
async getLogById(req, res, next) {
try {
const { id } = req.params;
const log = await apiLogService.getLogById(parseInt(id));
if (!log) {
throw new HttpError('Log entry not found', 404);
}
res.json({
success: true,
data: log
});
} catch (error) {
next(error);
}
}
/**
* GET /api/logs/scheduler/last-executions
* Get last execution info for scheduler jobs
*/
async getLastSchedulerExecutions(req, res, next) {
try {
const { clubId } = req.query;
const results = await apiLogService.getLastSchedulerExecutions(clubId ? parseInt(clubId) : null);
res.json({
success: true,
data: results
});
} catch (error) {
next(error);
}
}
}
export default new ApiLogController();

View File

@@ -25,7 +25,7 @@ export const addClub = async (req, res) => {
}
const newClub = await ClubService.createClub(clubName);
await ClubService.addUserToClub(user.id, newClub.id);
await ClubService.addUserToClub(user.id, newClub.id, true); // true = isOwner
res.status(200).json(newClub);
} catch (error) {
console.error('[addClub] - error:', error);
@@ -56,6 +56,25 @@ export const getClub = async (req, res) => {
}
};
export const updateClubSettings = async (req, res) => {
try {
const { authcode: token } = req.headers;
const { clubid } = req.params;
const { greetingText, associationMemberNumber } = req.body;
const updated = await ClubService.updateClubSettings(token, clubid, { greetingText, associationMemberNumber });
res.status(200).json(updated);
} catch (error) {
if (error.message === 'noaccess') {
res.status(403).json({ error: 'noaccess' });
} else if (error.message === 'clubnotfound') {
res.status(404).json({ error: 'clubnotfound' });
} else {
console.error('[updateClubSettings] - error:', error);
res.status(500).json({ error: 'internalerror' });
}
}
};
export const requestClubAccess = async (req, res) => {
const { authcode: token } = req.headers;
const { clubid: clubId } = req.params;

View File

@@ -79,11 +79,23 @@ export const getDiaryDateActivities = async (req, res) => {
export const addGroupActivity = async(req, res) => {
try {
const { authcode: userToken } = req.headers;
const { clubId, diaryDateId, groupId, activity } = req.body;
const activityItem = await diaryDateActivityService.addGroupActivity(userToken, clubId, diaryDateId, groupId, activity);
const { clubId, diaryDateId, groupId, activity, timeblockId } = req.body;
const activityItem = await diaryDateActivityService.addGroupActivity(userToken, clubId, diaryDateId, groupId, activity, timeblockId);
res.status(201).json(activityItem);
} catch (error) {
devLog(error);
res.status(500).json({ error: 'Error adding group activity' });
}
}
export const deleteGroupActivity = async(req, res) => {
try {
const { authcode: userToken } = req.headers;
const { clubId, groupActivityId } = req.params;
await diaryDateActivityService.deleteGroupActivity(userToken, clubId, groupActivityId);
res.status(200).json({ message: 'Group activity deleted' });
} catch (error) {
devLog(error);
res.status(500).json({ error: 'Error deleting group activity' });
}
}

View File

@@ -19,20 +19,32 @@ export const addMembersToActivity = async (req, res) => {
const { authcode: userToken } = req.headers;
const { clubId, diaryDateActivityId } = req.params;
const { participantIds } = req.body; // array of participant ids
await checkAccess(userToken, clubId);
if (!participantIds || !Array.isArray(participantIds)) {
console.error('[addMembersToActivity] Invalid participantIds:', participantIds);
return res.status(400).json({ error: 'participantIds must be an array' });
}
const validParticipants = await Participant.findAll({ where: { id: participantIds } });
const validIds = new Set(validParticipants.map(p => p.id));
const created = [];
for (const pid of participantIds) {
if (!validIds.has(pid)) continue;
if (!validIds.has(pid)) {
continue;
}
const existing = await DiaryMemberActivity.findOne({ where: { diaryDateActivityId, participantId: pid } });
if (!existing) {
const rec = await DiaryMemberActivity.create({ diaryDateActivityId, participantId: pid });
created.push(rec);
} else {
}
}
res.status(201).json(created);
} catch (e) {
console.error('[addMembersToActivity] Error:', e);
res.status(500).json({ error: 'Error adding members to activity' });
}
};

View File

@@ -18,17 +18,28 @@ export const getNotes = async (req, res) => {
export const createNote = async (req, res) => {
try {
const { memberId, content, tags } = req.body;
const newNote = await DiaryNote.create({ memberId, content });
if (tags && tags.length > 0) {
const { memberId, diaryDateId, content, tags } = req.body;
if (!memberId || !diaryDateId || !content) {
return res.status(400).json({ error: 'memberId, diaryDateId und content sind erforderlich.' });
}
const newNote = await DiaryNote.create({ memberId, diaryDateId, content });
if (Array.isArray(tags) && tags.length > 0 && typeof newNote.addTags === 'function') {
const tagInstances = await DiaryTag.findAll({ where: { id: tags } });
await newNote.addTags(tagInstances);
const noteWithTags = await DiaryNote.findByPk(newNote.id, {
include: [{ model: DiaryTag, as: 'tags', required: false }],
});
return res.status(201).json(noteWithTags ?? newNote);
}
const noteWithTags = await DiaryNote.findByPk(newNote.id, {
include: [{ model: DiaryTag, as: 'tags' }],
});
res.status(201).json(noteWithTags);
res.status(201).json(newNote);
} catch (error) {
console.error('[createNote] - Error:', error);
res.status(500).json({ error: 'Error creating note' });
}
};

View File

@@ -1,6 +1,5 @@
import { DiaryTag, DiaryDateTag } from '../models/index.js';
import { devLog } from '../utils/logger.js';
export const getTags = async (req, res) => {
try {
const tags = await DiaryTag.findAll();
@@ -13,9 +12,12 @@ export const getTags = async (req, res) => {
export const createTag = async (req, res) => {
try {
const { name } = req.body;
devLog(name);
const newTag = await DiaryTag.findOrCreate({ where: { name }, defaults: { name } });
res.status(201).json(newTag);
if (!name) {
return res.status(400).json({ error: 'Der Name des Tags ist erforderlich.' });
}
const [tag, created] = await DiaryTag.findOrCreate({ where: { name }, defaults: { name } });
res.status(created ? 201 : 200).json(tag);
} catch (error) {
res.status(500).json({ error: 'Error creating tag' });
}
@@ -24,9 +26,14 @@ export const createTag = async (req, res) => {
export const deleteTag = async (req, res) => {
try {
const { tagId } = req.params;
const { authcode: userToken } = req.headers;
const { clubId } = req.params;
await diaryService.removeTagFromDiaryDate(userToken, clubId, tagId);
await DiaryDateTag.destroy({ where: { tagId } });
const deleted = await DiaryTag.destroy({ where: { id: tagId } });
if (!deleted) {
return res.status(404).json({ error: 'Tag nicht gefunden' });
}
res.status(200).json({ message: 'Tag deleted' });
} catch (error) {
console.error('[deleteTag] - Error:', error);

View File

@@ -102,3 +102,46 @@ export const fetchLeagueTableFromMyTischtennis = async (req, res) => {
return res.status(500).json({ error: 'Failed to fetch league table from MyTischtennis' });
}
};
export const updateMatchPlayers = async (req, res) => {
try {
const { authcode: userToken } = req.headers;
const { matchId } = req.params;
const { playersReady, playersPlanned, playersPlayed } = req.body;
const result = await MatchService.updateMatchPlayers(
userToken,
matchId,
playersReady,
playersPlanned,
playersPlayed
);
return res.status(200).json({
message: 'Match players updated successfully',
data: result
});
} catch (error) {
console.error('Error updating match players:', error);
return res.status(error.statusCode || 500).json({
error: error.message || 'Failed to update match players'
});
}
};
export const getPlayerMatchStats = async (req, res) => {
try {
const { authcode: userToken } = req.headers;
const { clubId, leagueId } = req.params;
const { seasonid: seasonId } = req.query;
const stats = await MatchService.getPlayerMatchStats(userToken, clubId, leagueId, seasonId);
return res.status(200).json(stats);
} catch (error) {
console.error('Error retrieving player match stats:', error);
return res.status(error.statusCode || 500).json({
error: error.message || 'Failed to retrieve player match stats'
});
}
};

View File

@@ -0,0 +1,232 @@
import { checkAccess } from '../utils/userUtils.js';
import DiaryMemberActivity from '../models/DiaryMemberActivity.js';
import DiaryDateActivity from '../models/DiaryDateActivity.js';
import DiaryDates from '../models/DiaryDates.js';
import Participant from '../models/Participant.js';
import PredefinedActivity from '../models/PredefinedActivity.js';
import GroupActivity from '../models/GroupActivity.js';
import { Op } from 'sequelize';
export const getMemberActivities = async (req, res) => {
try {
const { authcode: userToken } = req.headers;
const { clubId, memberId } = req.params;
const { period } = req.query; // 'month', '3months', '6months', 'year', 'all'
await checkAccess(userToken, clubId);
// Calculate date range based on period
const now = new Date();
let startDate = null;
switch (period) {
case 'month':
startDate = new Date(now.getFullYear(), now.getMonth() - 1, now.getDate());
break;
case '3months':
startDate = new Date(now.getFullYear(), now.getMonth() - 3, now.getDate());
break;
case '6months':
startDate = new Date(now.getFullYear(), now.getMonth() - 6, now.getDate());
break;
case 'year':
startDate = new Date(now.getFullYear() - 1, now.getMonth(), now.getDate());
break;
case 'all':
default:
startDate = null;
break;
}
// Get participant ID for this member
const participants = await Participant.findAll({
where: { memberId: memberId }
});
if (participants.length === 0) {
return res.status(200).json([]);
}
const participantIds = participants.map(p => p.id);
// Get all diary member activities for this member
const whereClause = {
participantId: participantIds
};
const memberActivities = await DiaryMemberActivity.findAll({
where: whereClause,
include: [
{
model: Participant,
as: 'participant',
attributes: ['id', 'groupId', 'diaryDateId']
},
{
model: DiaryDateActivity,
as: 'activity',
include: [
{
model: DiaryDates,
as: 'diaryDate',
where: startDate ? {
date: {
[Op.gte]: startDate
}
} : {}
},
{
model: PredefinedActivity,
as: 'predefinedActivity'
},
{
model: GroupActivity,
as: 'groupActivities',
required: false
}
]
}
],
order: [[{ model: DiaryDateActivity, as: 'activity' }, { model: DiaryDates, as: 'diaryDate' }, 'date', 'DESC']]
});
// Group activities by name and count occurrences, considering group assignment
const activityMap = new Map();
for (const ma of memberActivities) {
if (!ma.activity || !ma.activity.predefinedActivity || !ma.participant) {
continue;
}
// Check group assignment
const participantGroupId = ma.participant.groupId;
const activityGroupIds = ma.activity.groupActivities?.map(ga => ga.groupId) || [];
// Filter: Only count if:
// 1. Activity has no group assignment (empty activityGroupIds) - activity is for all groups OR
// 2. Participant's group matches one of the activity's groups
const shouldCount = activityGroupIds.length === 0 ||
(participantGroupId !== null && activityGroupIds.includes(participantGroupId));
if (!shouldCount) {
continue;
}
const activity = ma.activity.predefinedActivity;
const activityName = activity.name;
const date = ma.activity.diaryDate?.date;
if (!activityMap.has(activityName)) {
activityMap.set(activityName, {
name: activityName,
count: 0,
dates: []
});
}
const activityData = activityMap.get(activityName);
activityData.count++;
if (date) {
activityData.dates.push(date);
}
}
// Convert map to array and sort by count
const activities = Array.from(activityMap.values())
.sort((a, b) => b.count - a.count);
return res.status(200).json(activities);
} catch (error) {
console.error('Error fetching member activities:', error);
return res.status(500).json({ error: 'Failed to fetch member activities' });
}
};
export const getMemberLastParticipations = async (req, res) => {
try {
const { authcode: userToken } = req.headers;
const { clubId, memberId } = req.params;
const { limit = 3 } = req.query;
await checkAccess(userToken, clubId);
// Get participant ID for this member
const participants = await Participant.findAll({
where: { memberId: memberId }
});
if (participants.length === 0) {
return res.status(200).json([]);
}
const participantIds = participants.map(p => p.id);
// Get last participations for this member
const memberActivities = await DiaryMemberActivity.findAll({
where: {
participantId: participantIds
},
include: [
{
model: Participant,
as: 'participant',
attributes: ['id', 'groupId', 'diaryDateId']
},
{
model: DiaryDateActivity,
as: 'activity',
include: [
{
model: DiaryDates,
as: 'diaryDate'
},
{
model: PredefinedActivity,
as: 'predefinedActivity'
},
{
model: GroupActivity,
as: 'groupActivities',
required: false
}
]
}
],
order: [[{ model: DiaryDateActivity, as: 'activity' }, { model: DiaryDates, as: 'diaryDate' }, 'date', 'DESC']],
limit: parseInt(limit) * 10 // Get more to filter by group
});
// Format the results, considering group assignment
const participations = memberActivities
.filter(ma => {
if (!ma.activity || !ma.activity.predefinedActivity || !ma.activity.diaryDate || !ma.participant) {
return false;
}
// Check group assignment
const participantGroupId = ma.participant.groupId;
const activityGroupIds = ma.activity.groupActivities?.map(ga => ga.groupId) || [];
// Filter: Only count if:
// 1. Activity has no group assignment (empty activityGroupIds) - activity is for all groups OR
// 2. Participant's group matches one of the activity's groups
return activityGroupIds.length === 0 ||
(participantGroupId !== null && activityGroupIds.includes(participantGroupId));
})
.slice(0, parseInt(limit)) // Limit after filtering
.map(ma => ({
id: ma.id,
activityName: ma.activity.predefinedActivity.name,
date: ma.activity.diaryDate.date,
diaryDateId: ma.activity.diaryDate.id
}));
return res.status(200).json(participations);
} catch (error) {
console.error('Error fetching member last participations:', error);
return res.status(500).json({ error: 'Failed to fetch member last participations' });
}
};

View File

@@ -1,13 +1,12 @@
import MemberService from "../services/memberService.js";
import MemberTransferService from "../services/memberTransferService.js";
import { devLog } from '../utils/logger.js';
const getClubMembers = async(req, res) => {
try {
const { authcode: userToken } = req.headers;
const { id: clubId, showAll } = req.params;
if (showAll === null) {
showAll = false;
}
const { id: clubId } = req.params;
const showAll = req.params.showAll ?? 'false';
res.status(200).json(await MemberService.getClubMembers(userToken, clubId, showAll));
} catch(error) {
res.status(500).json({ error: 'systemerror' });
@@ -27,16 +26,16 @@ const getWaitingApprovals = async(req, res) => {
const setClubMembers = async (req, res) => {
try {
const { id: memberId, firstname: firstName, lastname: lastName, street, city, birthdate, phone, email, active,
testMembership, picsInInternetAllowed, gender, ttr, qttr } = req.body;
const { id: memberId, firstname: firstName, lastname: lastName, street, city, postalCode, birthdate, phone, email, active,
testMembership, picsInInternetAllowed, gender, ttr, qttr, memberFormHandedOver, contacts } = req.body;
const { id: clubId } = req.params;
const { authcode: userToken } = req.headers;
const addResult = await MemberService.setClubMember(userToken, clubId, memberId, firstName, lastName, street, city, birthdate,
phone, email, active, testMembership, picsInInternetAllowed, gender, ttr, qttr);
const addResult = await MemberService.setClubMember(userToken, clubId, memberId, firstName, lastName, street, city, postalCode, birthdate,
phone, email, active, testMembership, picsInInternetAllowed, gender, ttr, qttr, memberFormHandedOver, contacts);
res.status(addResult.status || 500).json(addResult.response);
} catch (error) {
console.error('[setClubMembers] - Error:', error);
res.status(500).json({ error: 'Failed to upload image' });
res.status(500).json({ error: 'Failed to save member' });
}
}
@@ -44,8 +43,12 @@ const uploadMemberImage = async (req, res) => {
try {
const { clubId, memberId } = req.params;
const { authcode: userToken } = req.headers;
const result = await MemberService.uploadMemberImage(userToken, clubId, memberId, req.file.buffer);
res.status(result.status).json(result.message ? { message: result.message } : { error: result.error });
const makePrimary =
req.body?.makePrimary === true ||
req.body?.makePrimary === 'true' ||
req.query?.makePrimary === 'true';
const result = await MemberService.uploadMemberImage(userToken, clubId, memberId, req.file.buffer, { makePrimary });
res.status(result.status).json(result.response ?? { success: false, error: 'Unknown upload result' });
} catch (error) {
console.error('[uploadMemberImage] - Error:', error);
res.status(500).json({ error: 'Failed to upload image' });
@@ -54,9 +57,11 @@ const uploadMemberImage = async (req, res) => {
const getMemberImage = async (req, res) => {
try {
const { clubId, memberId } = req.params;
const { clubId, memberId, imageId } = req.params;
const { authcode: userToken } = req.headers;
const result = await MemberService.getMemberImage(userToken, clubId, memberId);
// Support "latest" as imageId to get the latest image
const actualImageId = imageId === 'latest' ? null : (imageId || null);
const result = await MemberService.getMemberImage(userToken, clubId, memberId, actualImageId);
if (result.status === 200) {
res.sendFile(result.imagePath);
} else {
@@ -82,7 +87,7 @@ const updateRatingsFromMyTischtennis = async (req, res) => {
const rotateMemberImage = async (req, res) => {
try {
const { clubId, memberId } = req.params;
const { clubId, memberId, imageId } = req.params;
const { direction } = req.body;
const { authcode: userToken } = req.headers;
@@ -93,7 +98,7 @@ const rotateMemberImage = async (req, res) => {
});
}
const result = await MemberService.rotateMemberImage(userToken, clubId, memberId, direction);
const result = await MemberService.rotateMemberImage(userToken, clubId, memberId, imageId, direction);
res.status(result.status).json(result.response);
} catch (error) {
console.error('[rotateMemberImage] - Error:', error);
@@ -101,4 +106,141 @@ const rotateMemberImage = async (req, res) => {
}
};
export { getClubMembers, getWaitingApprovals, setClubMembers, uploadMemberImage, getMemberImage, updateRatingsFromMyTischtennis, rotateMemberImage };
const deleteMemberImage = async (req, res) => {
try {
const { clubId, memberId, imageId } = req.params;
const { authcode: userToken } = req.headers;
const result = await MemberService.deleteMemberImage(userToken, clubId, memberId, imageId);
res.status(result.status).json(result.response);
} catch (error) {
console.error('[deleteMemberImage] - Error:', error);
res.status(500).json({ success: false, error: 'Failed to delete image' });
}
};
const generateMemberGallery = async (req, res) => {
try {
const { clubId } = req.params;
const { authcode: userToken } = req.headers;
const size = parseInt(req.query.size) || 200; // Default: 200x200
const format = req.query.format || 'image'; // 'image' or 'json'
const result = await MemberService.generateMemberGallery(userToken, clubId, size);
if (result.status === 200) {
if (format === 'json') {
// Return member information for interactive gallery
return res.status(200).json({
members: result.galleryEntries.map(entry => ({
memberId: entry.memberId,
firstName: entry.firstName,
lastName: entry.lastName,
fullName: entry.fullName
}))
});
}
res.setHeader('Content-Type', 'image/png');
res.setHeader('Cache-Control', 'no-store');
return res.status(200).send(result.buffer);
}
return res.status(result.status).json({ error: result.error || 'Galerie konnte nicht erstellt werden' });
} catch (error) {
console.error('[generateMemberGallery] - Error:', error);
res.status(500).json({ error: 'Failed to generate member gallery' });
}
};
const setPrimaryMemberImage = async (req, res) => {
try {
const { clubId, memberId, imageId } = req.params;
const { authcode: userToken } = req.headers;
const result = await MemberService.setPrimaryMemberImage(userToken, clubId, memberId, imageId);
res.status(result.status).json(result.response);
} catch (error) {
console.error('[setPrimaryMemberImage] - Error:', error);
res.status(500).json({ success: false, error: 'Failed to update primary image' });
}
};
const quickUpdateTestMembership = async (req, res) => {
try {
const { clubId, memberId } = req.params;
const { authcode: userToken } = req.headers;
const result = await MemberService.quickUpdateTestMembership(userToken, clubId, memberId);
res.status(result.status).json(result.response);
} catch (error) {
console.error('[quickUpdateTestMembership] - Error:', error);
res.status(500).json({ error: 'Failed to update test membership' });
}
};
const quickUpdateMemberFormHandedOver = async (req, res) => {
try {
const { clubId, memberId } = req.params;
const { authcode: userToken } = req.headers;
const result = await MemberService.quickUpdateMemberFormHandedOver(userToken, clubId, memberId);
res.status(result.status).json(result.response);
} catch (error) {
console.error('[quickUpdateMemberFormHandedOver] - Error:', error);
res.status(500).json({ error: 'Failed to update member form status' });
}
};
const quickDeactivateMember = async (req, res) => {
try {
const { clubId, memberId } = req.params;
const { authcode: userToken } = req.headers;
const result = await MemberService.quickDeactivateMember(userToken, clubId, memberId);
res.status(result.status).json(result.response);
} catch (error) {
console.error('[quickDeactivateMember] - Error:', error);
res.status(500).json({ error: 'Failed to deactivate member' });
}
};
const transferMembers = async (req, res) => {
try {
const { id: clubId } = req.params;
const { authcode: userToken } = req.headers;
const config = req.body;
// Validierung
if (!config.transferEndpoint) {
return res.status(400).json({
success: false,
error: 'Übertragungs-Endpoint ist erforderlich'
});
}
if (!config.transferTemplate) {
return res.status(400).json({
success: false,
error: 'Übertragungs-Template ist erforderlich'
});
}
const result = await MemberTransferService.transferMembers(userToken, clubId, config);
res.status(result.status).json(result.response);
} catch (error) {
console.error('[transferMembers] - Error:', error);
res.status(500).json({
success: false,
error: 'Fehler bei der Übertragung: ' + error.message
});
}
};
export {
getClubMembers,
getWaitingApprovals,
setClubMembers,
uploadMemberImage,
getMemberImage,
updateRatingsFromMyTischtennis,
rotateMemberImage,
transferMembers,
quickUpdateTestMembership,
quickUpdateMemberFormHandedOver,
quickDeactivateMember,
deleteMemberImage,
setPrimaryMemberImage,
generateMemberGallery
};

View File

@@ -1,4 +1,5 @@
import MemberNoteService from "../services/memberNoteService.js";
import MemberNote from '../models/MemberNote.js';
import { devLog } from '../utils/logger.js';
const getMemberNotes = async (req, res) => {
@@ -21,6 +22,7 @@ const addMemberNote = async (req, res) => {
const notes = await MemberNoteService.getNotesForMember(userToken, clubId, memberId);
res.status(201).json(notes);
} catch (error) {
console.error('[addMemberNote] - Error:', error);
res.status(500).json({ error: 'systemerror' });
}
};
@@ -30,11 +32,16 @@ const deleteMemberNote = async (req, res) => {
const { authcode: userToken } = req.headers;
const { noteId } = req.params;
const { clubId } = req.body;
const memberId = await MemberNoteService.getMemberIdForNote(noteId); // Member ID ermitteln
const note = await MemberNote.findByPk(noteId);
if (!note) {
return res.status(404).json({ error: 'notfound' });
}
const memberId = note.memberId;
await MemberNoteService.deleteNoteForMember(userToken, clubId, noteId);
const notes = await MemberNoteService.getNotesForMember(userToken, clubId, memberId);
res.status(200).json(notes);
} catch (error) {
console.error('[deleteMemberNote] - Error:', error);
res.status(500).json({ error: 'systemerror' });
}
};

View File

@@ -0,0 +1,51 @@
import MemberTransferConfigService from '../services/memberTransferConfigService.js';
export const getConfig = async (req, res) => {
try {
const { id: clubId } = req.params;
const { authcode: userToken } = req.headers;
const result = await MemberTransferConfigService.getConfig(userToken, clubId);
res.status(result.status).json(result.response);
} catch (error) {
console.error('[getConfig] Error:', error);
res.status(500).json({
success: false,
error: 'Fehler beim Laden der Konfiguration'
});
}
};
export const saveConfig = async (req, res) => {
try {
const { id: clubId } = req.params;
const { authcode: userToken } = req.headers;
const configData = req.body;
const result = await MemberTransferConfigService.saveConfig(userToken, clubId, configData);
res.status(result.status).json(result.response);
} catch (error) {
console.error('[saveConfig] Error:', error);
res.status(500).json({
success: false,
error: 'Fehler beim Speichern der Konfiguration'
});
}
};
export const deleteConfig = async (req, res) => {
try {
const { id: clubId } = req.params;
const { authcode: userToken } = req.headers;
const result = await MemberTransferConfigService.deleteConfig(userToken, clubId);
res.status(result.status).json(result.response);
} catch (error) {
console.error('[deleteConfig] Error:', error);
res.status(500).json({
success: false,
error: 'Fehler beim Löschen der Konfiguration'
});
}
};

View File

@@ -45,12 +45,12 @@ class MyTischtennisController {
const { email, password, savePassword, autoUpdateRatings, userPassword } = req.body;
if (!email) {
throw new HttpError(400, 'E-Mail-Adresse erforderlich');
throw new HttpError('E-Mail-Adresse erforderlich', 400);
}
// Wenn ein Passwort gesetzt wird, muss das App-Passwort angegeben werden
if (password && !userPassword) {
throw new HttpError(400, 'App-Passwort erforderlich zum Setzen des myTischtennis-Passworts');
throw new HttpError('App-Passwort erforderlich zum Setzen des myTischtennis-Passworts', 400);
}
const account = await myTischtennisService.upsertAccount(
@@ -81,7 +81,7 @@ class MyTischtennisController {
const deleted = await myTischtennisService.deleteAccount(userId);
if (!deleted) {
throw new HttpError(404, 'Kein myTischtennis-Account gefunden');
throw new HttpError('Kein myTischtennis-Account gefunden', 404);
}
res.status(200).json({ message: 'myTischtennis-Account gelöscht' });

View File

@@ -1,6 +1,8 @@
import myTischtennisUrlParserService from '../services/myTischtennisUrlParserService.js';
import myTischtennisService from '../services/myTischtennisService.js';
import MemberService from '../services/memberService.js';
import autoFetchMatchResultsService from '../services/autoFetchMatchResultsService.js';
import apiLogService from '../services/apiLogService.js';
import ClubTeam from '../models/ClubTeam.js';
import League from '../models/League.js';
import Season from '../models/Season.js';
@@ -19,12 +21,12 @@ class MyTischtennisUrlController {
const { url } = req.body;
if (!url) {
throw new HttpError(400, 'URL is required');
throw new HttpError('URL is required', 400);
}
// Validate URL
if (!myTischtennisUrlParserService.isValidTeamUrl(url)) {
throw new HttpError(400, 'Invalid myTischtennis URL format');
throw new HttpError('Invalid myTischtennis URL format', 400);
}
// Parse URL
@@ -53,7 +55,6 @@ class MyTischtennisUrlController {
);
}
} catch (error) {
console.error('Error fetching additional team data:', error);
// Continue with parsed data only
}
}
@@ -78,7 +79,7 @@ class MyTischtennisUrlController {
const userIdOrEmail = req.headers.userid;
if (!url || !clubTeamId) {
throw new HttpError(400, 'URL and clubTeamId are required');
throw new HttpError('URL and clubTeamId are required', 400);
}
// Get actual user ID
@@ -86,7 +87,7 @@ class MyTischtennisUrlController {
if (isNaN(userIdOrEmail)) {
const user = await User.findOne({ where: { email: userIdOrEmail } });
if (!user) {
throw new HttpError(404, 'User not found');
throw new HttpError('User not found', 404);
}
userId = user.id;
}
@@ -106,7 +107,6 @@ class MyTischtennisUrlController {
account.accessToken
);
} catch (error) {
console.error('Error fetching team data:', error);
}
}
@@ -122,13 +122,13 @@ class MyTischtennisUrlController {
}
if (!season) {
throw new HttpError(404, `Season ${completeData.season} not found. Set createSeason=true to create it.`);
throw new HttpError(`Season ${completeData.season} not found. Set createSeason=true to create it.`, 404);
}
// Find or create league
const team = await ClubTeam.findByPk(clubTeamId);
if (!team) {
throw new HttpError(404, 'Club team not found');
throw new HttpError('Club team not found', 404);
}
let league;
@@ -176,7 +176,7 @@ class MyTischtennisUrlController {
groupname: completeData.groupname
});
} else {
throw new HttpError(400, 'League not found and team has no league assigned. Set createLeague=true to create one.');
throw new HttpError('League not found and team has no league assigned. Set createLeague=true to create one.', 400);
}
// Update team
@@ -220,12 +220,21 @@ class MyTischtennisUrlController {
* Body: { clubTeamId: number }
*/
async fetchTeamData(req, res, next) {
// Define outside of try/catch so catch has access
let account = null;
let team = null;
let myTischtennisUrl = null;
let requestStartTime = null;
try {
const { clubTeamId } = req.body;
const userIdOrEmail = req.headers.userid;
if (!clubTeamId) {
throw new HttpError(400, 'clubTeamId is required');
throw new HttpError('clubTeamId is required', 400);
}
if (!userIdOrEmail) {
throw new HttpError('User-ID fehlt. Bitte melden Sie sich an.', 401);
}
// Get actual user ID (userid header might be email address)
@@ -234,48 +243,47 @@ class MyTischtennisUrlController {
// It's an email, find the user
const user = await User.findOne({ where: { email: userIdOrEmail } });
if (!user) {
throw new HttpError(404, 'User not found');
throw new HttpError('User not found', 404);
}
userId = user.id;
}
// Get myTischtennis session (similar to memberService.updateRatingsFromMyTischtennis)
console.log('Fetching session for userId:', userId, '(from header:', userIdOrEmail, ')');
let session;
try {
session = await myTischtennisService.getSession(userId);
console.log('Session found:', !!session);
} catch (sessionError) {
console.log('Session invalid, attempting login...', sessionError.message);
// Versuche automatischen Login mit gespeicherten Credentials
try {
// Check if account exists and has password
const accountCheck = await myTischtennisService.getAccount(userId);
if (!accountCheck) {
throw new Error('MyTischtennis-Account nicht gefunden');
}
if (!accountCheck.encryptedPassword) {
throw new Error('Kein Passwort gespeichert. Bitte melden Sie sich in den MyTischtennis-Einstellungen an und speichern Sie Ihr Passwort.');
}
await myTischtennisService.verifyLogin(userId);
session = await myTischtennisService.getSession(userId);
console.log('Automatic login successful');
} catch (loginError) {
console.error('Automatic login failed:', loginError.message);
throw new HttpError(401, 'MyTischtennis-Session abgelaufen und automatischer Login fehlgeschlagen. Bitte melden Sie sich in den MyTischtennis-Einstellungen an.');
const errorMessage = loginError.message || 'Automatischer Login fehlgeschlagen';
throw new HttpError(`MyTischtennis-Session abgelaufen und automatischer Login fehlgeschlagen: ${errorMessage}. Bitte melden Sie sich in den MyTischtennis-Einstellungen an.`, 401);
}
}
// Get account data (for clubId, etc.)
const account = await myTischtennisService.getAccount(userId);
account = await myTischtennisService.getAccount(userId);
if (!account) {
throw new HttpError(404, 'MyTischtennis-Account nicht verknüpft. Bitte verknüpfen Sie Ihren Account in den MyTischtennis-Einstellungen.');
throw new HttpError('MyTischtennis-Account nicht verknüpft. Bitte verknüpfen Sie Ihren Account in den MyTischtennis-Einstellungen.', 404);
}
console.log('Using session:', {
email: account.email,
hasCookie: !!session.cookie,
hasAccessToken: !!session.accessToken,
expiresAt: new Date(session.expiresAt * 1000)
});
// Get team with league and season
const team = await ClubTeam.findByPk(clubTeamId, {
team = await ClubTeam.findByPk(clubTeamId, {
include: [
{
model: League,
@@ -291,137 +299,170 @@ class MyTischtennisUrlController {
});
if (!team) {
throw new HttpError(404, 'Team not found');
throw new HttpError(`Team mit ID ${clubTeamId} nicht gefunden`, 404);
}
console.log('Team data:', {
id: team.id,
name: team.name,
myTischtennisTeamId: team.myTischtennisTeamId,
hasLeague: !!team.league,
leagueData: team.league ? {
id: team.league.id,
name: team.league.name,
myTischtennisGroupId: team.league.myTischtennisGroupId,
association: team.league.association,
groupname: team.league.groupname,
hasSeason: !!team.league.season
} : null
});
// Verbesserte Validierung mit detaillierten Fehlermeldungen
if (!team.myTischtennisTeamId) {
throw new HttpError(`Team "${team.name}" (interne ID: ${team.id}) ist nicht für myTischtennis konfiguriert: myTischtennisTeamId fehlt. Bitte konfigurieren Sie das Team zuerst über die MyTischtennis-URL.`, 400);
}
if (!team.league) {
throw new HttpError('Team ist keiner Liga zugeordnet. Bitte ordnen Sie das Team einer Liga zu.', 400);
}
if (!team.league.myTischtennisGroupId) {
throw new HttpError('Liga ist nicht für myTischtennis konfiguriert: myTischtennisGroupId fehlt. Bitte konfigurieren Sie die Liga zuerst über die MyTischtennis-URL.', 400);
}
if (!team.myTischtennisTeamId || !team.league || !team.league.myTischtennisGroupId) {
throw new HttpError(400, 'Team is not configured for myTischtennis');
// Validate season before proceeding
if (!team.league.season || !team.league.season.season) {
throw new HttpError('Liga ist keiner Saison zugeordnet. Bitte ordnen Sie die Liga einer Saison zu.', 400);
}
// Build the URL that will be used - do this early so we can log it even if errors occur
const seasonFull = team.league.season.season;
const seasonParts = seasonFull.split('/');
const seasonShort = seasonParts.length === 2
? `${seasonParts[0].slice(-2)}/${seasonParts[1].slice(-2)}`
: seasonFull;
const seasonStr = seasonShort.replace('/', '--');
const teamnameEncoded = encodeURIComponent(team.name.replace(/\s/g, '_'));
myTischtennisUrl = `https://www.mytischtennis.de/click-tt/${team.league.association}/${seasonStr}/ligen/${team.league.groupname}/gruppe/${team.league.myTischtennisGroupId}/mannschaft/${team.myTischtennisTeamId}/${teamnameEncoded}/spielerbilanzen/gesamt`;
// Log the request to myTischtennis BEFORE making the call
// This ensures we always see what WILL BE sent, even if the call fails
requestStartTime = Date.now();
try {
await apiLogService.logRequest({
userId: account.userId,
method: 'GET',
path: myTischtennisUrl.replace('https://www.mytischtennis.de', ''),
statusCode: null,
requestBody: JSON.stringify({
url: myTischtennisUrl,
myTischtennisTeamId: team.myTischtennisTeamId,
clubTeamId: team.id,
teamName: team.name,
leagueName: team.league.name,
association: team.league.association,
groupId: team.league.myTischtennisGroupId,
groupname: team.league.groupname,
season: seasonFull
}),
responseBody: null,
executionTime: null,
errorMessage: 'Request wird ausgeführt...',
logType: 'api_request',
schedulerJobType: 'mytischtennis_fetch'
});
} catch (logError) {
// Silent fail - logging errors shouldn't break the request
}
// Fetch data for this specific team
const startTime = Date.now();
let matchResultsSuccess = false;
let tableUpdateSuccess = false;
let matchResultsCount = 0;
let tableUpdateCount = 0;
try {
const result = await autoFetchMatchResultsService.fetchTeamResults(
{
userId: account.userId,
email: account.email,
cookie: session.cookie,
accessToken: session.accessToken,
expiresAt: session.expiresAt,
getPassword: () => null // Not needed for manual fetch
},
team
);
matchResultsSuccess = true;
matchResultsCount = result.fetchedCount || 0;
// Log match results fetch
const fetchLogService = (await import('../services/myTischtennisFetchLogService.js')).default;
await fetchLogService.logFetch(
account.userId,
'match_results',
true,
`${matchResultsCount} Spielergebnisse erfolgreich abgerufen`,
{
recordsProcessed: matchResultsCount,
executionTime: Date.now() - startTime,
isAutomatic: false
}
);
} catch (error) {
console.error('Error fetching match results:', error);
const fetchLogService = (await import('../services/myTischtennisFetchLogService.js')).default;
await fetchLogService.logFetch(
account.userId,
'match_results',
false,
'Fehler beim Abrufen der Spielergebnisse',
{
errorDetails: error.message,
executionTime: Date.now() - startTime,
isAutomatic: false
}
);
}
// Note: fetchTeamResults will also log and update with actual response
const result = await autoFetchMatchResultsService.fetchTeamResults(
{
userId: account.userId,
email: account.email,
cookie: session.cookie,
accessToken: session.accessToken,
expiresAt: session.expiresAt,
getPassword: () => null // Not needed for manual fetch
},
team
);
// Also fetch and update league table data
let tableUpdateResult = null;
const tableStartTime = Date.now();
// Also fetch and update league table data
let tableUpdateResult = null;
try {
await autoFetchMatchResultsService.fetchAndUpdateLeagueTable(account.userId, team.league.id);
tableUpdateResult = 'League table updated successfully';
tableUpdateSuccess = true;
tableUpdateCount = 1; // One table updated
console.log('✓ League table updated for league:', team.league.id);
// Log league table fetch
const fetchLogService = (await import('../services/myTischtennisFetchLogService.js')).default;
await fetchLogService.logFetch(
account.userId,
'league_table',
true,
'Ligatabelle erfolgreich aktualisiert',
{
recordsProcessed: tableUpdateCount,
executionTime: Date.now() - tableStartTime,
isAutomatic: false
}
);
} catch (error) {
console.error('Error fetching league table data:', error);
tableUpdateResult = 'League table update failed: ' + error.message;
// Log league table fetch failure
const fetchLogService = (await import('../services/myTischtennisFetchLogService.js')).default;
await fetchLogService.logFetch(
account.userId,
'league_table',
false,
'Fehler beim Aktualisieren der Ligatabelle',
{
errorDetails: error.message,
executionTime: Date.now() - tableStartTime,
isAutomatic: false
}
);
// Don't fail the entire request if table update fails
}
res.json({
success: true,
message: `${matchResultsCount} Datensätze abgerufen und verarbeitet`,
data: {
fetchedCount: matchResultsCount,
teamName: team.name,
tableUpdate: tableUpdateResult
tableUpdateResult = 'League table updated successfully';
} catch (error) {
tableUpdateResult = 'League table update failed: ' + error.message;
// Don't fail the entire request if table update fails
}
});
} catch (error) {
console.error('Error in fetchTeamData:', error);
console.error('Error stack:', error.stack);
next(error);
}
// Additionally update (Q)TTR ratings for the club
let ratingsUpdate = null;
try {
// Use already resolved userId instead of authcode to avoid header dependency
const ratingsResult = await MemberService.updateRatingsFromMyTischtennisByUserId(userId, team.clubId);
ratingsUpdate = ratingsResult?.response?.message || `Ratings update status: ${ratingsResult?.status}`;
} catch (ratingsErr) {
ratingsUpdate = 'Ratings update failed: ' + (ratingsErr.message || String(ratingsErr));
}
res.json({
success: true,
message: `${result.fetchedCount} Datensätze abgerufen und verarbeitet`,
data: {
fetchedCount: result.fetchedCount,
teamName: team.name,
tableUpdate: tableUpdateResult,
ratingsUpdate
}
});
} catch (error) {
// Update log with error information if we got far enough to build the URL
if (myTischtennisUrl && account && team) {
const requestExecutionTime = requestStartTime ? (Date.now() - requestStartTime) : null;
try {
await apiLogService.logRequest({
userId: account.userId,
method: 'GET',
path: myTischtennisUrl.replace('https://www.mytischtennis.de', ''),
statusCode: 0,
requestBody: JSON.stringify({
url: myTischtennisUrl,
myTischtennisTeamId: team.myTischtennisTeamId,
clubTeamId: team.id,
teamName: team.name,
leagueName: team.league?.name,
association: team.league?.association,
groupname: team.league?.groupname,
groupId: team.league?.myTischtennisGroupId
}),
responseBody: null,
executionTime: requestExecutionTime,
errorMessage: error.message || String(error),
logType: 'api_request',
schedulerJobType: 'mytischtennis_fetch'
});
} catch (logError) {
// Silent fail - logging errors shouldn't break the request
}
}
// Normalize HTTP status code (guard against strings)
const rawCode = error && (error.statusCode != null ? error.statusCode : error.status);
const parsed = Number(rawCode);
const status = Number.isInteger(parsed) && parsed >= 100 && parsed <= 599 ? parsed : 500;
const debug = {
message: error.message || String(error),
name: error.name,
stack: (process.env.NODE_ENV === 'dev' || process.env.NODE_ENV === 'development') ? (error.stack || null) : undefined,
team: team ? { id: team.id, name: team.name } : null,
league: team && team.league ? { id: team.league.id, name: team.league.name, association: team.league.association, groupId: team.league.myTischtennisGroupId, groupname: team.league.groupname } : null,
url: typeof myTischtennisUrl !== 'undefined' ? myTischtennisUrl : null
};
try {
if (!res.headersSent) {
// Spezieller Fall: myTischtennis-Reauth nötig → nicht 401 an FE senden, um App-Logout zu vermeiden
const isMyTischtennisAuthIssue = status === 401 && /MyTischtennis-Session abgelaufen|Automatischer Login fehlgeschlagen|Passwort gespeichert/i.test(debug.message || '');
if (isMyTischtennisAuthIssue) {
return res.status(200).json({ success: false, error: debug.message, debug, needsMyTischtennisReauth: true });
}
res.status(status).json({ success: false, error: debug.message, debug });
}
} catch (writeErr) {
// Fallback, falls Headers schon gesendet wurden
// eslint-disable-next-line no-console
console.error('[fetchTeamData] Response write failed:', writeErr);
}
}
}
/**
@@ -448,16 +489,16 @@ class MyTischtennisUrlController {
});
if (!team) {
throw new HttpError(404, 'Team not found');
throw new HttpError('Team not found', 404);
}
if (!team.myTischtennisTeamId || !team.league || !team.league.myTischtennisGroupId) {
throw new HttpError(400, 'Team is not configured for myTischtennis');
throw new HttpError('Team is not configured for myTischtennis', 400);
}
const url = myTischtennisUrlParserService.buildUrl({
association: team.league.association,
season: team.league.season.name,
season: team.league.season?.season,
groupname: team.league.groupname,
groupId: team.league.myTischtennisGroupId,
teamId: team.myTischtennisTeamId,
@@ -472,6 +513,89 @@ class MyTischtennisUrlController {
next(error);
}
}
/**
* Configure league from myTischtennis table URL
* POST /api/mytischtennis/configure-league
* Body: { url: string, createSeason?: boolean }
*/
async configureLeague(req, res, next) {
try {
const { url, createSeason } = req.body;
const userIdOrEmail = req.headers.userid;
if (!url) {
throw new HttpError('URL is required', 400);
}
// Parse URL
const parsedData = myTischtennisUrlParserService.parseUrl(url);
if (parsedData.urlType !== 'table') {
throw new HttpError('URL must be a table URL (not a team URL)', 400);
}
// Find or create season
let season = await Season.findOne({
where: { season: parsedData.season }
});
if (!season && createSeason) {
season = await Season.create({
season: parsedData.season,
startDate: new Date(),
endDate: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000) // 1 Jahr später
});
}
// Find or create league
let league = await League.findOne({
where: {
myTischtennisGroupId: parsedData.groupId,
association: parsedData.association
}
});
if (!league) {
league = await League.create({
name: parsedData.groupnameOriginal, // Verwende die originale URL-kodierte Version
myTischtennisGroupId: parsedData.groupId,
association: parsedData.association,
groupname: parsedData.groupnameOriginal, // Verwende die originale URL-kodierte Version
seasonId: season?.id || null
});
} else {
// Update existing league - aber nur wenn es sich wirklich geändert hat
if (league.name !== parsedData.groupnameOriginal) {
league.name = parsedData.groupnameOriginal;
league.groupname = parsedData.groupnameOriginal;
}
league.seasonId = season?.id || league.seasonId;
await league.save();
}
res.json({
success: true,
message: 'League configured successfully',
data: {
league: {
id: league.id,
name: league.name,
myTischtennisGroupId: league.myTischtennisGroupId,
association: league.association,
groupname: league.groupname
},
season: season ? {
id: season.id,
name: season.season
} : null,
parsedData
}
});
} catch (error) {
next(error);
}
}
}
export default new MyTischtennisUrlController();

View File

@@ -4,7 +4,10 @@ import { devLog } from '../utils/logger.js';
export const getParticipants = async (req, res) => {
try {
const { dateId } = req.params;
const participants = await Participant.findAll({ where: { diaryDateId: dateId } });
const participants = await Participant.findAll({
where: { diaryDateId: dateId },
attributes: ['id', 'diaryDateId', 'memberId', 'groupId', 'notes', 'createdAt', 'updatedAt']
});
res.status(200).json(participants);
} catch (error) {
devLog(error);
@@ -12,6 +15,32 @@ export const getParticipants = async (req, res) => {
}
};
export const updateParticipantGroup = async (req, res) => {
try {
const { dateId, memberId } = req.params;
const { groupId } = req.body;
const participant = await Participant.findOne({
where: {
diaryDateId: dateId,
memberId: memberId
}
});
if (!participant) {
return res.status(404).json({ error: 'Teilnehmer nicht gefunden' });
}
participant.groupId = groupId || null;
await participant.save();
res.status(200).json(participant);
} catch (error) {
devLog(error);
res.status(500).json({ error: 'Fehler beim Aktualisieren der Teilnehmer-Gruppenzuordnung' });
}
};
export const addParticipant = async (req, res) => {
try {
const { diaryDateId, memberId } = req.body;

View File

@@ -0,0 +1,167 @@
import permissionService from '../services/permissionService.js';
/**
* Get user's permissions for a club
*/
export const getUserPermissions = async (req, res) => {
try {
const { clubId } = req.params;
const userId = req.user.id;
// Validierung: clubId muss eine gültige Zahl sein
const parsedClubId = parseInt(clubId, 10);
if (isNaN(parsedClubId) || parsedClubId <= 0) {
return res.status(400).json({ error: 'Ungültige Club-ID' });
}
const permissions = await permissionService.getUserClubPermissions(userId, parsedClubId);
if (!permissions) {
return res.status(404).json({ error: 'Keine Berechtigungen gefunden' });
}
res.json(permissions);
} catch (error) {
console.error('Error getting user permissions:', error);
res.status(500).json({ error: 'Fehler beim Abrufen der Berechtigungen' });
}
};
/**
* Get all club members with their permissions
*/
export const getClubMembersWithPermissions = async (req, res) => {
try {
const { clubId } = req.params;
const userId = req.user.id;
const members = await permissionService.getClubMembersWithPermissions(
parseInt(clubId),
userId
);
res.json(members);
} catch (error) {
console.error('Error getting club members with permissions:', error);
if (error.message === 'Keine Berechtigung zum Anzeigen von Berechtigungen') {
return res.status(403).json({ error: error.message });
}
res.status(500).json({ error: 'Fehler beim Abrufen der Mitglieder' });
}
};
/**
* Update user role
*/
export const updateUserRole = async (req, res) => {
try {
const { clubId, userId: targetUserId } = req.params;
const { role } = req.body;
const updatingUserId = req.user.id;
const result = await permissionService.setUserRole(
parseInt(targetUserId),
parseInt(clubId),
role,
updatingUserId
);
res.json(result);
} catch (error) {
console.error('Error updating user role:', error);
if (error.message && error.message.toLowerCase().includes('keine berechtigung')) {
return res.status(403).json({ error: error.message });
}
res.status(400).json({ error: error.message });
}
};
/**
* Update user custom permissions
*/
export const updateUserPermissions = async (req, res) => {
try {
const { clubId, userId: targetUserId } = req.params;
const { permissions } = req.body;
const updatingUserId = req.user.id;
const result = await permissionService.setCustomPermissions(
parseInt(targetUserId),
parseInt(clubId),
permissions,
updatingUserId
);
res.json(result);
} catch (error) {
console.error('Error updating user permissions:', error);
if (error.message && error.message.toLowerCase().includes('keine berechtigung')) {
return res.status(403).json({ error: error.message });
}
res.status(400).json({ error: error.message });
}
};
/**
* Get available roles
*/
export const getAvailableRoles = async (req, res) => {
try {
const roles = permissionService.getAvailableRoles();
res.json(roles);
} catch (error) {
console.error('Error getting available roles:', error);
res.status(500).json({ error: 'Fehler beim Abrufen der Rollen' });
}
};
/**
* Get permission structure
*/
export const getPermissionStructure = async (req, res) => {
try {
const structure = permissionService.getPermissionStructure();
res.json(structure);
} catch (error) {
console.error('Error getting permission structure:', error);
res.status(500).json({ error: 'Fehler beim Abrufen der Berechtigungsstruktur' });
}
};
/**
* Update user status (activate/deactivate)
*/
export const updateUserStatus = async (req, res) => {
try {
const { clubId, userId: targetUserId } = req.params;
const { approved } = req.body;
const updatingUserId = req.user.id;
const result = await permissionService.setUserStatus(
parseInt(targetUserId),
parseInt(clubId),
approved,
updatingUserId
);
res.json(result);
} catch (error) {
console.error('Error updating user status:', error);
if (error.message && error.message.toLowerCase().includes('keine berechtigung')) {
return res.status(403).json({ error: error.message });
}
res.status(400).json({ error: error.message });
}
};
export default {
getUserPermissions,
getClubMembersWithPermissions,
updateUserRole,
updateUserPermissions,
updateUserStatus,
getAvailableRoles,
getPermissionStructure
};

View File

@@ -1,5 +1,6 @@
import multer from 'multer';
import path from 'path';
import fs from 'fs';
import TeamDocumentService from '../services/teamDocumentService.js';
import PDFParserService from '../services/pdfParserService.js';
import { getUserByToken } from '../utils/userUtils.js';
@@ -8,6 +9,11 @@ import { devLog } from '../utils/logger.js';
// Multer-Konfiguration für Datei-Uploads
const storage = multer.diskStorage({
destination: (req, file, cb) => {
try {
fs.mkdirSync('uploads/temp', { recursive: true });
} catch (mkdirError) {
console.error('[multer] - Failed to ensure temp upload directory exists:', mkdirError);
}
cb(null, 'uploads/temp/');
},
filename: (req, file, cb) => {
@@ -23,15 +29,17 @@ const upload = multer({
},
fileFilter: (req, file, cb) => {
// Erlaube nur PDF, DOC, DOCX, TXT, CSV Dateien
const allowedTypes = /pdf|doc|docx|txt|csv/;
const extname = allowedTypes.test(path.extname(file.originalname).toLowerCase());
const mimetype = allowedTypes.test(file.mimetype);
const allowedExtensions = ['.pdf', '.doc', '.docx', '.txt', '.csv'];
const allowedMimePatterns = ['pdf', 'msword', 'wordprocessingml.document', 'text/plain', 'csv', 'excel'];
if (mimetype && extname) {
const extensionValid = allowedExtensions.includes(path.extname(file.originalname).toLowerCase());
const mimetypeValid = allowedMimePatterns.some((pattern) => file.mimetype && file.mimetype.toLowerCase().includes(pattern));
if (extensionValid && mimetypeValid) {
return cb(null, true);
} else {
cb(new Error('Nur PDF, DOC, DOCX, TXT und CSV Dateien sind erlaubt!'));
}
cb(new Error('Nur PDF, DOC, DOCX, TXT und CSV Dateien sind erlaubt!'));
}
});

View File

@@ -10,7 +10,8 @@ const sequelize = new Sequelize(
host: development.host,
dialect: development.dialect,
define: development.define,
logging: false, // SQL-Logging deaktivieren
logging: development.logging ?? false,
storage: development.storage,
}
);

View File

@@ -6,6 +6,9 @@ export const authenticate = async (req, res, next) => {
if (!token) {
token = req.headers['authcode'];
}
if (!token) {
token = req.query?.authcode || req.query?.token || null;
}
if (!token) {
return res.status(401).json({ error: 'Unauthorized: Token fehlt' });
}

View File

@@ -0,0 +1,215 @@
import permissionService from '../services/permissionService.js';
/**
* Authorization Middleware
* Checks if user has permission to access a resource
*/
/**
* Check if user has permission for a specific resource and action
* @param {string} resource - Resource name (diary, members, teams, etc.)
* @param {string} action - Action type (read, write, delete)
* @returns {Function} Express middleware function
*/
export const authorize = (resource, action = 'read') => {
return async (req, res, next) => {
try {
const userId = req.user?.id;
if (!userId) {
return res.status(401).json({ error: 'Nicht authentifiziert' });
}
// Get clubId from various possible sources
const clubId =
req.params.clubId ??
req.params.clubid ??
req.params.id ??
req.body.clubId ??
req.body.clubid ??
req.query.clubId ??
req.query.clubid;
if (!clubId) {
return res.status(400).json({ error: 'Club-ID fehlt' });
}
// Check permission
const hasPermission = await permissionService.hasPermission(
userId,
parseInt(clubId),
resource,
action
);
if (!hasPermission) {
return res.status(403).json({
error: 'Keine Berechtigung',
details: `Fehlende Berechtigung: ${resource}.${action}`
});
}
// Store permissions in request for later use
const userPermissions = await permissionService.getUserClubPermissions(
userId,
parseInt(clubId)
);
req.userPermissions = userPermissions;
next();
} catch (error) {
console.error('Authorization error:', error);
res.status(500).json({ error: 'Fehler bei der Berechtigungsprüfung' });
}
};
};
/**
* Check if user is club owner
* @returns {Function} Express middleware function
*/
export const requireOwner = () => {
return async (req, res, next) => {
try {
const userId = req.user?.id;
if (!userId) {
return res.status(401).json({ error: 'Nicht authentifiziert' });
}
const clubId =
req.params.clubId ??
req.params.clubid ??
req.params.id ??
req.body.clubId ??
req.body.clubid ??
req.query.clubId ??
req.query.clubid;
if (!clubId) {
return res.status(400).json({ error: 'Club-ID fehlt' });
}
const userPermissions = await permissionService.getUserClubPermissions(
userId,
parseInt(clubId)
);
if (!userPermissions || !userPermissions.isOwner) {
return res.status(403).json({
error: 'Keine Berechtigung',
details: 'Nur der Club-Ersteller hat Zugriff'
});
}
req.userPermissions = userPermissions;
next();
} catch (error) {
console.error('Owner check error:', error);
res.status(500).json({ error: 'Fehler bei der Berechtigungsprüfung' });
}
};
};
/**
* Check if user is admin (owner or admin role)
* @returns {Function} Express middleware function
*/
export const requireAdmin = () => {
return async (req, res, next) => {
try {
const userId = req.user?.id;
if (!userId) {
return res.status(401).json({ error: 'Nicht authentifiziert' });
}
const clubId =
req.params.clubId ??
req.params.clubid ??
req.params.id ??
req.body.clubId ??
req.body.clubid ??
req.query.clubId ??
req.query.clubid;
if (!clubId) {
return res.status(400).json({ error: 'Club-ID fehlt' });
}
const userPermissions = await permissionService.getUserClubPermissions(
userId,
parseInt(clubId)
);
if (!userPermissions || (userPermissions.role !== 'admin' && !userPermissions.isOwner)) {
return res.status(403).json({
error: 'Keine Berechtigung',
details: 'Administrator-Rechte erforderlich'
});
}
req.userPermissions = userPermissions;
next();
} catch (error) {
console.error('Admin check error:', error);
res.status(500).json({ error: 'Fehler bei der Berechtigungsprüfung' });
}
};
};
/**
* Check if user has any of the specified roles
* @param {string[]} roles - Array of allowed roles
* @returns {Function} Express middleware function
*/
export const requireRole = (roles) => {
return async (req, res, next) => {
try {
const userId = req.user?.id;
if (!userId) {
return res.status(401).json({ error: 'Nicht authentifiziert' });
}
const clubId =
req.params.clubId ??
req.params.clubid ??
req.params.id ??
req.body.clubId ??
req.body.clubid ??
req.query.clubId ??
req.query.clubid;
if (!clubId) {
return res.status(400).json({ error: 'Club-ID fehlt' });
}
const userPermissions = await permissionService.getUserClubPermissions(
userId,
parseInt(clubId)
);
if (!userPermissions || !roles.includes(userPermissions.role)) {
return res.status(403).json({
error: 'Keine Berechtigung',
details: `Erforderliche Rolle: ${roles.join(', ')}`
});
}
req.userPermissions = userPermissions;
next();
} catch (error) {
console.error('Role check error:', error);
res.status(500).json({ error: 'Fehler bei der Berechtigungsprüfung' });
}
};
};
export default {
authorize,
requireOwner,
requireAdmin,
requireRole
};

View File

@@ -0,0 +1,87 @@
import ApiLog from '../models/ApiLog.js';
/**
* Middleware to log all API requests and responses
* Should be added early in the middleware chain, but after authentication
*/
export const requestLoggingMiddleware = async (req, res, next) => {
const startTime = Date.now();
const originalSend = res.send;
// Get request body (but limit size for sensitive data)
let requestBody = null;
if (req.body && Object.keys(req.body).length > 0) {
const bodyStr = JSON.stringify(req.body);
// Truncate very long bodies
requestBody = bodyStr.length > 10000 ? bodyStr.substring(0, 10000) + '... (truncated)' : bodyStr;
}
// Capture response
let responseBody = null;
res.send = function(data) {
// Try to parse response as JSON
try {
const parsed = JSON.parse(data);
const responseStr = JSON.stringify(parsed);
// Truncate very long responses
responseBody = responseStr.length > 10000 ? responseStr.substring(0, 10000) + '... (truncated)' : responseStr;
} catch (e) {
// Not JSON, just use raw data (truncated)
responseBody = typeof data === 'string' ? data.substring(0, 1000) : String(data).substring(0, 1000);
}
// Restore original send
res.send = originalSend;
return res.send.apply(res, arguments);
};
// Log after response is sent
res.on('finish', async () => {
const executionTime = Date.now() - startTime;
const ipAddress = req.ip || req.connection.remoteAddress || req.headers['x-forwarded-for'];
const path = req.path || req.url;
// Nur myTischtennis-Requests loggen
// Skip logging for non-data endpoints (Status-Checks, Health-Checks, etc.)
// Exclude any endpoint containing 'status' or root paths
if (
path.includes('/status') ||
path === '/' ||
path === '/health' ||
path.endsWith('/status') ||
path.includes('/scheduler-status')
) {
return;
}
// Nur myTischtennis-Endpunkte loggen (z.B. /api/mytischtennis/*)
if (!path.includes('/mytischtennis')) {
return;
}
// Get user ID if available (wird von authMiddleware gesetzt)
const userId = req.user?.id || null;
try {
await ApiLog.create({
userId,
method: req.method,
path: path,
statusCode: res.statusCode,
requestBody,
responseBody,
executionTime,
errorMessage: res.statusCode >= 400 ? `HTTP ${res.statusCode}` : null,
ipAddress,
userAgent: req.headers['user-agent'],
logType: 'api_request'
});
} catch (error) {
// Don't let logging errors break the request
console.error('Error logging API request:', error);
}
});
next();
};

View File

@@ -0,0 +1,17 @@
-- Create table for storing multiple images per member
CREATE TABLE IF NOT EXISTS `member_image` (
`id` INT NOT NULL AUTO_INCREMENT,
`member_id` INT NOT NULL,
`file_name` VARCHAR(255) NOT NULL,
`sort_order` INT NOT NULL DEFAULT 0,
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
INDEX `idx_member_image_member_id` (`member_id`),
CONSTRAINT `fk_member_image_member`
FOREIGN KEY (`member_id`)
REFERENCES `member` (`id`)
ON DELETE CASCADE
ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

View File

@@ -0,0 +1,5 @@
ALTER TABLE clubs
ADD COLUMN IF NOT EXISTS greeting_text TEXT NULL,
ADD COLUMN IF NOT EXISTS association_member_number VARCHAR(255) NULL;

View File

@@ -0,0 +1,9 @@
-- Migration: Add group_id to participants table
-- This allows assigning participants to groups for training organization
ALTER TABLE participants
ADD COLUMN group_id INTEGER NULL REFERENCES "group"(id) ON DELETE SET NULL ON UPDATE CASCADE;
-- Add index for better query performance
CREATE INDEX IF NOT EXISTS idx_participants_group_id ON participants(group_id);

View File

@@ -0,0 +1,57 @@
-- Add postal_code column to member table
ALTER TABLE `member`
ADD COLUMN `postal_code` TEXT NULL COMMENT 'Postal code (PLZ)' AFTER `city`;
-- Create member_contact table for multiple phone numbers and email addresses
CREATE TABLE IF NOT EXISTS `member_contact` (
`id` INT NOT NULL AUTO_INCREMENT,
`member_id` INT NOT NULL,
`type` ENUM('phone', 'email') NOT NULL COMMENT 'Type of contact: phone or email',
`value` TEXT NOT NULL,
`is_parent` BOOLEAN NOT NULL DEFAULT FALSE COMMENT 'Whether this contact belongs to a parent',
`parent_name` TEXT NULL COMMENT 'Name of the parent (e.g. "Mutter", "Vater", "Elternteil 1")',
`is_primary` BOOLEAN NOT NULL DEFAULT FALSE COMMENT 'Whether this is the primary contact of this type',
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
INDEX `idx_member_id` (`member_id`),
INDEX `idx_type` (`type`),
CONSTRAINT `fk_member_contact_member`
FOREIGN KEY (`member_id`)
REFERENCES `member` (`id`)
ON DELETE CASCADE
ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- Migrate existing phone numbers from member.phone to member_contact
INSERT INTO `member_contact` (`member_id`, `type`, `value`, `is_parent`, `parent_name`, `is_primary`, `created_at`, `updated_at`)
SELECT
`id` AS `member_id`,
'phone' AS `type`,
`phone` AS `value`,
FALSE AS `is_parent`,
NULL AS `parent_name`,
TRUE AS `is_primary`,
NOW() AS `created_at`,
NOW() AS `updated_at`
FROM `member`
WHERE `phone` IS NOT NULL
AND `phone` != ''
AND TRIM(`phone`) != '';
-- Migrate existing email addresses from member.email to member_contact
INSERT INTO `member_contact` (`member_id`, `type`, `value`, `is_parent`, `parent_name`, `is_primary`, `created_at`, `updated_at`)
SELECT
`id` AS `member_id`,
'email' AS `type`,
`email` AS `value`,
FALSE AS `is_parent`,
NULL AS `parent_name`,
TRUE AS `is_primary`,
NOW() AS `created_at`,
NOW() AS `updated_at`
FROM `member`
WHERE `email` IS NOT NULL
AND `email` != ''
AND TRIM(`email`) != '';

View File

@@ -0,0 +1,17 @@
-- Add role and permissions columns to user_club table
ALTER TABLE `user_club`
ADD COLUMN `role` VARCHAR(50) DEFAULT 'member' COMMENT 'User role: admin, trainer, team_manager, member' AFTER `approved`,
ADD COLUMN `permissions` JSON NULL COMMENT 'Specific permissions: {diary: {read: true, write: true}, members: {...}, ...}' AFTER `role`,
ADD COLUMN `is_owner` BOOLEAN DEFAULT FALSE COMMENT 'True if user created the club' AFTER `permissions`;
-- Create index for faster role lookups
CREATE INDEX `idx_user_club_role` ON `user_club` (`role`);
CREATE INDEX `idx_user_club_owner` ON `user_club` (`is_owner`);
-- Set existing approved users as members
UPDATE `user_club` SET `role` = 'member' WHERE `approved` = 1 AND `role` IS NULL;
-- If there's a user who created the club (we need to identify them somehow)
-- For now, we'll need to manually set the owner after migration

View File

@@ -0,0 +1,8 @@
-- Add player tracking fields to match table
-- These fields store arrays of member IDs for different participation states
ALTER TABLE `match`
ADD COLUMN `players_ready` JSON NULL COMMENT 'Array of member IDs who are ready to play' AFTER `pdf_url`,
ADD COLUMN `players_planned` JSON NULL COMMENT 'Array of member IDs who are planned to play' AFTER `players_ready`,
ADD COLUMN `players_played` JSON NULL COMMENT 'Array of member IDs who actually played' AFTER `players_planned`;

View File

@@ -0,0 +1,26 @@
-- Migration: Create api_log table for comprehensive request/response and execution logging
CREATE TABLE IF NOT EXISTS api_log (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NULL,
method VARCHAR(10) NOT NULL COMMENT 'HTTP method (GET, POST, PUT, DELETE, etc.)',
path VARCHAR(500) NOT NULL COMMENT 'Request path',
status_code INT NULL COMMENT 'HTTP status code',
request_body TEXT NULL COMMENT 'Request body (truncated if too long)',
response_body TEXT NULL COMMENT 'Response body (truncated if too long)',
execution_time INT NULL COMMENT 'Execution time in milliseconds',
error_message TEXT NULL COMMENT 'Error message if request failed',
ip_address VARCHAR(45) NULL COMMENT 'Client IP address',
user_agent VARCHAR(500) NULL COMMENT 'User agent string',
log_type ENUM('api_request', 'scheduler', 'cron_job', 'manual') NOT NULL DEFAULT 'api_request' COMMENT 'Type of log entry',
scheduler_job_type VARCHAR(50) NULL COMMENT 'Type of scheduler job (rating_updates, match_results, etc.)',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES user(id) ON DELETE SET NULL ON UPDATE CASCADE,
INDEX idx_api_log_user_id (user_id, created_at),
INDEX idx_api_log_path (path, created_at),
INDEX idx_api_log_log_type (log_type, created_at),
INDEX idx_api_log_created_at (created_at),
INDEX idx_api_log_status_code (status_code)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

View File

@@ -0,0 +1,38 @@
-- Update existing user_club entries with default permissions
-- This migration sets default values for role and is_owner for existing club memberships
-- Set default role to 'member' for all approved users who don't have a role yet
UPDATE `user_club`
SET `role` = 'member'
WHERE `approved` = 1
AND (`role` IS NULL OR `role` = '');
-- Optionally: Set the first approved user of each club as owner
-- This finds the user with the lowest user_id per club (oldest member) and marks them as owner
UPDATE `user_club` AS uc1
INNER JOIN (
SELECT `club_id`, MIN(`user_id`) as `first_user_id`
FROM `user_club`
WHERE `approved` = 1
GROUP BY `club_id`
) AS uc2 ON uc1.`club_id` = uc2.`club_id` AND uc1.`user_id` = uc2.`first_user_id`
SET
uc1.`is_owner` = 1,
uc1.`role` = 'admin';
-- Verify the changes
SELECT
uc.`club_id`,
c.`name` as club_name,
uc.`user_id`,
u.`email` as user_email,
uc.`role`,
uc.`is_owner`,
uc.`approved`
FROM `user_club` uc
LEFT JOIN `club` c ON c.`id` = uc.`club_id`
LEFT JOIN `user` u ON u.`id` = uc.`user_id`
WHERE uc.`approved` = 1
ORDER BY uc.`club_id`, uc.`is_owner` DESC, uc.`user_id`;

102
backend/models/ApiLog.js Normal file
View File

@@ -0,0 +1,102 @@
import { DataTypes } from 'sequelize';
import sequelize from '../database.js';
import User from './User.js';
const ApiLog = sequelize.define('ApiLog', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
},
userId: {
type: DataTypes.INTEGER,
allowNull: true,
references: {
model: User,
key: 'id',
},
onDelete: 'SET NULL',
onUpdate: 'CASCADE',
},
method: {
type: DataTypes.STRING(10),
allowNull: false,
comment: 'HTTP method (GET, POST, PUT, DELETE, etc.)'
},
path: {
type: DataTypes.STRING(500),
allowNull: false,
comment: 'Request path'
},
statusCode: {
type: DataTypes.INTEGER,
allowNull: true,
comment: 'HTTP status code'
},
requestBody: {
type: DataTypes.TEXT,
allowNull: true,
comment: 'Request body (truncated if too long)'
},
responseBody: {
type: DataTypes.TEXT,
allowNull: true,
comment: 'Response body (truncated if too long)'
},
executionTime: {
type: DataTypes.INTEGER,
allowNull: true,
comment: 'Execution time in milliseconds'
},
errorMessage: {
type: DataTypes.TEXT,
allowNull: true,
comment: 'Error message if completes failed'
},
ipAddress: {
type: DataTypes.STRING(45),
allowNull: true,
comment: 'Client IP address'
},
userAgent: {
type: DataTypes.STRING(500),
allowNull: true,
comment: 'User agent string'
},
logType: {
type: DataTypes.ENUM('api_request', 'scheduler', 'cron_job', 'manual'),
allowNull: false,
defaultValue: 'api_request',
comment: 'Type of log entry'
},
schedulerJobType: {
type: DataTypes.STRING(50),
allowNull: true,
comment: 'Type of scheduler job (rating_updates, match_results, etc.)'
},
}, {
underscored: true,
tableName: 'api_log',
timestamps: true,
indexes: [
{
fields: ['user_id', 'created_at']
},
{
fields: ['path', 'created_at']
},
{
fields: ['log_type', 'created_at']
},
{
fields: ['created_at']
},
{
fields: ['status_code']
}
]
});
export default ApiLog;

View File

@@ -7,6 +7,16 @@ const Club = sequelize.define('Club', {
allowNull: false,
unique: true,
},
greetingText: {
type: DataTypes.TEXT,
allowNull: true,
field: 'greeting_text'
},
associationMemberNumber: {
type: DataTypes.STRING,
allowNull: true,
field: 'association_member_number'
},
}, {
tableName: 'clubs',
underscored: true,

View File

@@ -109,6 +109,24 @@ const Match = sequelize.define('Match', {
comment: 'PDF URL from myTischtennis',
field: 'pdf_url'
},
playersReady: {
type: DataTypes.JSON,
allowNull: true,
comment: 'Array of member IDs who are ready to play',
field: 'players_ready'
},
playersPlanned: {
type: DataTypes.JSON,
allowNull: true,
comment: 'Array of member IDs who are planned to play',
field: 'players_planned'
},
playersPlayed: {
type: DataTypes.JSON,
allowNull: true,
comment: 'Array of member IDs who actually played',
field: 'players_played'
},
}, {
underscored: true,
tableName: 'match',

View File

@@ -52,6 +52,7 @@ const Member = sequelize.define('Member', {
},
get() {
const encryptedValue = this.getDataValue('birthDate');
if (!encryptedValue) return null;
return decryptData(encryptedValue);
}
},
@@ -91,6 +92,21 @@ const Member = sequelize.define('Member', {
return decryptData(encryptedValue);
}
},
postalCode: {
type: DataTypes.STRING,
allowNull: true,
set(value) {
const encryptedValue = encryptData(value || '');
this.setDataValue('postalCode', encryptedValue);
},
get() {
const encryptedValue = this.getDataValue('postalCode');
if (!encryptedValue) return null;
return decryptData(encryptedValue);
},
field: 'postal_code',
comment: 'Postal code (PLZ)'
},
email: {
type: DataTypes.STRING,
allowNull: false,
@@ -138,6 +154,13 @@ const Member = sequelize.define('Member', {
allowNull: true,
defaultValue: null
},
memberFormHandedOver: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: false,
field: 'member_form_handed_over',
comment: 'Mitgliedsformular ausgehändigt'
},
myTischtennisPlayerId: {
type: DataTypes.STRING,
allowNull: true,
@@ -157,13 +180,7 @@ const Member = sequelize.define('Member', {
member.save();
},
}
},
{
underscored: true,
tableName: 'log',
timestamps: true
}
);
});
Member.belongsTo(Club, { as: 'club' });
Club.hasMany(Member, { as: 'members' });

View File

@@ -0,0 +1,89 @@
import { DataTypes } from 'sequelize';
import sequelize from '../database.js';
import Member from './Member.js';
import { encryptData, decryptData } from '../utils/encrypt.js';
const MemberContact = sequelize.define('MemberContact', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false
},
memberId: {
type: DataTypes.INTEGER,
allowNull: false,
references: {
model: 'member',
key: 'id'
},
onDelete: 'CASCADE',
field: 'member_id'
},
type: {
type: DataTypes.ENUM('phone', 'email'),
allowNull: false,
comment: 'Type of contact: phone or email'
},
value: {
type: DataTypes.STRING,
allowNull: false,
set(value) {
const encryptedValue = encryptData(value);
this.setDataValue('value', encryptedValue);
},
get() {
const encryptedValue = this.getDataValue('value');
if (!encryptedValue) return null;
try {
return decryptData(encryptedValue);
} catch (error) {
console.error('[MemberContact] Error decrypting value:', error);
return encryptedValue; // Fallback: return encrypted value if decryption fails
}
}
},
isParent: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: false,
field: 'is_parent',
comment: 'Whether this contact belongs to a parent'
},
parentName: {
type: DataTypes.STRING,
allowNull: true,
set(value) {
if (value) {
const encryptedValue = encryptData(value);
this.setDataValue('parentName', encryptedValue);
} else {
this.setDataValue('parentName', null);
}
},
get() {
const encryptedValue = this.getDataValue('parentName');
return encryptedValue ? decryptData(encryptedValue) : null;
},
field: 'parent_name',
comment: 'Name of the parent (e.g. "Mutter", "Vater", "Elternteil 1")'
},
isPrimary: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: false,
field: 'is_primary',
comment: 'Whether this is the primary contact of this type'
}
}, {
underscored: true,
sequelize,
modelName: 'MemberContact',
tableName: 'member_contact',
timestamps: true
});
// Associations are defined in models/index.js to avoid duplicate alias errors
export default MemberContact;

View File

@@ -0,0 +1,40 @@
import { DataTypes } from 'sequelize';
import sequelize from '../database.js';
const MemberImage = sequelize.define('MemberImage', {
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true,
allowNull: false
},
memberId: {
type: DataTypes.INTEGER,
allowNull: false,
field: 'member_id',
references: {
model: 'member',
key: 'id'
},
onDelete: 'CASCADE',
onUpdate: 'CASCADE'
},
fileName: {
type: DataTypes.STRING(255),
allowNull: false,
field: 'file_name'
},
sortOrder: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: 0,
field: 'sort_order'
}
}, {
tableName: 'member_image',
underscored: true,
timestamps: true
});
export default MemberImage;

View File

@@ -0,0 +1,117 @@
import { DataTypes } from 'sequelize';
import sequelize from '../database.js';
import Club from './Club.js';
import { encryptData, decryptData } from '../utils/encrypt.js';
const MemberTransferConfig = sequelize.define('MemberTransferConfig', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false
},
clubId: {
type: DataTypes.INTEGER,
allowNull: false,
unique: true,
references: {
model: Club,
key: 'id'
},
onDelete: 'CASCADE'
},
server: {
type: DataTypes.STRING,
allowNull: true,
field: 'server',
comment: 'Base URL des Servers (z.B. https://example.com)'
},
loginEndpoint: {
type: DataTypes.STRING,
allowNull: true,
field: 'login_endpoint',
comment: 'Relativer Pfad zum Login-Endpoint (z.B. /api/auth/login)'
},
loginFormat: {
type: DataTypes.STRING,
allowNull: true,
defaultValue: 'json',
field: 'login_format'
},
encryptedLoginCredentials: {
type: DataTypes.TEXT,
allowNull: true,
field: 'encrypted_login_credentials',
comment: 'Verschlüsselte Login-Daten als JSON-String'
},
transferEndpoint: {
type: DataTypes.STRING,
allowNull: false,
field: 'transfer_endpoint',
comment: 'Relativer Pfad zum Übertragungs-Endpoint (z.B. /api/members/bulk)'
},
transferMethod: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: 'POST',
field: 'transfer_method'
},
transferFormat: {
type: DataTypes.STRING,
allowNull: false,
defaultValue: 'json',
field: 'transfer_format'
},
transferTemplate: {
type: DataTypes.TEXT,
allowNull: false,
field: 'transfer_template'
},
useBulkMode: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: false,
field: 'use_bulk_mode'
},
bulkWrapperTemplate: {
type: DataTypes.TEXT,
allowNull: true,
field: 'bulk_wrapper_template',
comment: 'Optionales Template für die äußere Struktur im Bulk-Modus (z.B. {"data": {"members": "{{members}}"}})'
}
}, {
underscored: true,
tableName: 'member_transfer_config',
timestamps: true
});
// Getter/Setter für verschlüsselte Login-Daten
MemberTransferConfig.prototype.getLoginCredentials = function() {
if (!this.encryptedLoginCredentials) {
return null;
}
try {
const decrypted = decryptData(this.encryptedLoginCredentials);
return JSON.parse(decrypted);
} catch (error) {
console.error('[MemberTransferConfig] Error decrypting login credentials:', error);
return null;
}
};
MemberTransferConfig.prototype.setLoginCredentials = function(credentials) {
if (!credentials || Object.keys(credentials).length === 0) {
this.encryptedLoginCredentials = null;
return;
}
try {
const jsonString = JSON.stringify(credentials);
this.encryptedLoginCredentials = encryptData(jsonString);
} catch (error) {
console.error('[MemberTransferConfig] Error encrypting login credentials:', error);
this.encryptedLoginCredentials = null;
}
};
export default MemberTransferConfig;

View File

@@ -2,6 +2,7 @@ import { DataTypes } from 'sequelize';
import sequelize from '../database.js';
import Member from './Member.js';
import DiaryDate from './DiaryDates.js';
import Group from './Group.js';
import { encryptData, decryptData } from '../utils/encrypt.js';
const Participant = sequelize.define('Participant', {
@@ -27,6 +28,16 @@ const Participant = sequelize.define('Participant', {
key: 'id'
}
},
groupId: {
type: DataTypes.INTEGER,
allowNull: true,
references: {
model: Group,
key: 'id'
},
onDelete: 'SET NULL',
onUpdate: 'CASCADE'
},
notes: {
type: DataTypes.STRING(4096),
allowNull: true,

View File

@@ -6,6 +6,7 @@ import Club from './Club.js';
const UserClub = sequelize.define('UserClub', {
userId: {
type: DataTypes.INTEGER,
primaryKey: true,
references: {
model: User,
key: 'id',
@@ -13,6 +14,7 @@ const UserClub = sequelize.define('UserClub', {
},
clubId: {
type: DataTypes.INTEGER,
primaryKey: true,
references: {
model: Club,
key: 'id',
@@ -22,6 +24,23 @@ const UserClub = sequelize.define('UserClub', {
type: DataTypes.BOOLEAN,
defaultValue: false,
},
role: {
type: DataTypes.STRING(50),
defaultValue: 'member',
allowNull: false,
comment: 'User role: admin, trainer, team_manager, member'
},
permissions: {
type: DataTypes.JSON,
allowNull: true,
comment: 'Specific permissions: {diary: {read: true, write: true}, members: {...}, ...}'
},
isOwner: {
type: DataTypes.BOOLEAN,
defaultValue: false,
allowNull: false,
comment: 'True if user created the club'
}
}, {
underscored: true,
tableName: 'user_club',

View File

@@ -38,6 +38,10 @@ import OfficialCompetitionMember from './OfficialCompetitionMember.js';
import MyTischtennis from './MyTischtennis.js';
import MyTischtennisUpdateHistory from './MyTischtennisUpdateHistory.js';
import MyTischtennisFetchLog from './MyTischtennisFetchLog.js';
import ApiLog from './ApiLog.js';
import MemberTransferConfig from './MemberTransferConfig.js';
import MemberContact from './MemberContact.js';
import MemberImage from './MemberImage.js';
// Official tournaments relations
OfficialTournament.hasMany(OfficialCompetition, { foreignKey: 'tournamentId', as: 'competitions' });
OfficialCompetition.belongsTo(OfficialTournament, { foreignKey: 'tournamentId', as: 'tournament' });
@@ -160,7 +164,7 @@ Club.hasMany(UserClub, { foreignKey: 'clubId' });
Group.belongsTo(DiaryDate, { foreignKey: 'diaryDateId', as: 'diaryDateGroup' });
DiaryDate.hasMany(Group, { foreignKey: 'diaryDateId', as: 'groupsDiaryDate' });
GroupActivity.belongsTo(DiaryDateActivity, { foreignKey: 'id', as: 'activityGroupActivity' });
GroupActivity.belongsTo(DiaryDateActivity, { foreignKey: 'diaryDateActivity', as: 'activityGroupActivity' });
DiaryDateActivity.hasMany(GroupActivity, { foreignKey: 'diaryDateActivity', as: 'groupActivities' });
Group.hasOne(GroupActivity, { foreignKey: 'groupId', as: 'groupGroupActivity' });
@@ -238,6 +242,18 @@ MyTischtennisUpdateHistory.belongsTo(User, { foreignKey: 'userId', as: 'user' })
User.hasMany(MyTischtennisFetchLog, { foreignKey: 'userId', as: 'fetchLogs' });
MyTischtennisFetchLog.belongsTo(User, { foreignKey: 'userId', as: 'user' });
User.hasMany(ApiLog, { foreignKey: 'userId', as: 'apiLogs' });
ApiLog.belongsTo(User, { foreignKey: 'userId', as: 'user' });
Club.hasOne(MemberTransferConfig, { foreignKey: 'clubId', as: 'memberTransferConfig' });
MemberTransferConfig.belongsTo(Club, { foreignKey: 'clubId', as: 'club' });
Member.hasMany(MemberContact, { foreignKey: 'memberId', as: 'contacts' });
MemberContact.belongsTo(Member, { foreignKey: 'memberId', as: 'member' });
Member.hasMany(MemberImage, { foreignKey: 'memberId', as: 'images' });
MemberImage.belongsTo(Member, { foreignKey: 'memberId', as: 'member' });
export {
User,
Log,
@@ -278,4 +294,8 @@ export {
MyTischtennis,
MyTischtennisUpdateHistory,
MyTischtennisFetchLog,
ApiLog,
MemberTransferConfig,
MemberContact,
MemberImage,
};

3278
backend/node_modules/.package-lock.json generated vendored

File diff suppressed because it is too large Load Diff

View File

@@ -8,8 +8,8 @@ This package contains type definitions for node (https://nodejs.org/).
Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node.
### Additional Details
* Last updated: Tue, 23 Jul 2024 18:09:25 GMT
* Last updated: Mon, 03 Nov 2025 01:29:59 GMT
* Dependencies: [undici-types](https://npmjs.com/package/undici-types)
# Credits
These definitions were written by [Microsoft TypeScript](https://github.com/Microsoft), [Alberto Schiabel](https://github.com/jkomyno), [Alvis HT Tang](https://github.com/alvis), [Andrew Makarov](https://github.com/r3nya), [Benjamin Toueg](https://github.com/btoueg), [Chigozirim C.](https://github.com/smac89), [David Junger](https://github.com/touffy), [Deividas Bakanas](https://github.com/DeividasBakanas), [Eugene Y. Q. Shen](https://github.com/eyqs), [Hannes Magnusson](https://github.com/Hannes-Magnusson-CK), [Huw](https://github.com/hoo29), [Kelvin Jin](https://github.com/kjin), [Klaus Meinhardt](https://github.com/ajafff), [Lishude](https://github.com/islishude), [Mariusz Wiktorczyk](https://github.com/mwiktorczyk), [Mohsen Azimi](https://github.com/mohsen1), [Nikita Galkin](https://github.com/galkin), [Parambir Singh](https://github.com/parambirs), [Sebastian Silbermann](https://github.com/eps1lon), [Thomas den Hollander](https://github.com/ThomasdenH), [Wilco Bakker](https://github.com/WilcoBakker), [wwwy3y3](https://github.com/wwwy3y3), [Samuel Ainsworth](https://github.com/samuela), [Kyle Uehlein](https://github.com/kuehlein), [Thanik Bhongbhibhat](https://github.com/bhongy), [Marcin Kopacz](https://github.com/chyzwar), [Trivikram Kamat](https://github.com/trivikr), [Junxiao Shi](https://github.com/yoursunny), [Ilia Baryshnikov](https://github.com/qwelias), [ExE Boss](https://github.com/ExE-Boss), [Piotr Błażejewicz](https://github.com/peterblazejewicz), [Anna Henningsen](https://github.com/addaleax), [Victor Perin](https://github.com/victorperin), [Yongsheng Zhang](https://github.com/ZYSzys), [NodeJS Contributors](https://github.com/NodeJS), [Linus Unnebäck](https://github.com/LinusU), [wafuwafu13](https://github.com/wafuwafu13), [Matteo Collina](https://github.com/mcollina), and [Dmitry Semigradsky](https://github.com/Semigradsky).
These definitions were written by [Microsoft TypeScript](https://github.com/Microsoft), [Alberto Schiabel](https://github.com/jkomyno), [Andrew Makarov](https://github.com/r3nya), [Benjamin Toueg](https://github.com/btoueg), [David Junger](https://github.com/touffy), [Mohsen Azimi](https://github.com/mohsen1), [Nikita Galkin](https://github.com/galkin), [Sebastian Silbermann](https://github.com/eps1lon), [Wilco Bakker](https://github.com/WilcoBakker), [Marcin Kopacz](https://github.com/chyzwar), [Trivikram Kamat](https://github.com/trivikr), [Junxiao Shi](https://github.com/yoursunny), [Ilia Baryshnikov](https://github.com/qwelias), [ExE Boss](https://github.com/ExE-Boss), [Piotr Błażejewicz](https://github.com/peterblazejewicz), [Anna Henningsen](https://github.com/addaleax), [Victor Perin](https://github.com/victorperin), [NodeJS Contributors](https://github.com/NodeJS), [Linus Unnebäck](https://github.com/LinusU), [wafuwafu13](https://github.com/wafuwafu13), [Matteo Collina](https://github.com/mcollina), [Dmitry Semigradsky](https://github.com/Semigradsky), [René](https://github.com/Renegade334), and [Yagiz Nizipli](https://github.com/anonrig).

View File

@@ -1,20 +1,166 @@
/**
* The `node:assert` module provides a set of assertion functions for verifying
* invariants.
* @see [source](https://github.com/nodejs/node/blob/v20.13.1/lib/assert.js)
* @see [source](https://github.com/nodejs/node/blob/v24.x/lib/assert.js)
*/
declare module "assert" {
import strict = require("assert/strict");
/**
* An alias of {@link ok}.
* An alias of {@link assert.ok}.
* @since v0.5.9
* @param value The input that is checked for being truthy.
*/
function assert(value: unknown, message?: string | Error): asserts value;
const kOptions: unique symbol;
namespace assert {
type AssertMethodNames =
| "deepEqual"
| "deepStrictEqual"
| "doesNotMatch"
| "doesNotReject"
| "doesNotThrow"
| "equal"
| "fail"
| "ifError"
| "match"
| "notDeepEqual"
| "notDeepStrictEqual"
| "notEqual"
| "notStrictEqual"
| "ok"
| "partialDeepStrictEqual"
| "rejects"
| "strictEqual"
| "throws";
interface AssertOptions {
/**
* If set to `'full'`, shows the full diff in assertion errors.
* @default 'simple'
*/
diff?: "simple" | "full" | undefined;
/**
* If set to `true`, non-strict methods behave like their
* corresponding strict methods.
* @default true
*/
strict?: boolean | undefined;
/**
* If set to `true`, skips prototype and constructor
* comparison in deep equality checks.
* @since v24.9.0
* @default false
*/
skipPrototype?: boolean | undefined;
}
interface Assert extends Pick<typeof assert, AssertMethodNames> {
readonly [kOptions]: AssertOptions & { strict: false };
}
interface AssertStrict extends Pick<typeof strict, AssertMethodNames> {
readonly [kOptions]: AssertOptions & { strict: true };
}
/**
* The `Assert` class allows creating independent assertion instances with custom options.
* @since v24.6.0
*/
var Assert: {
/**
* Creates a new assertion instance. The `diff` option controls the verbosity of diffs in assertion error messages.
*
* ```js
* const { Assert } = require('node:assert');
* const assertInstance = new Assert({ diff: 'full' });
* assertInstance.deepStrictEqual({ a: 1 }, { a: 2 });
* // Shows a full diff in the error message.
* ```
*
* **Important**: When destructuring assertion methods from an `Assert` instance,
* the methods lose their connection to the instance's configuration options (such
* as `diff`, `strict`, and `skipPrototype` settings).
* The destructured methods will fall back to default behavior instead.
*
* ```js
* const myAssert = new Assert({ diff: 'full' });
*
* // This works as expected - uses 'full' diff
* myAssert.strictEqual({ a: 1 }, { b: { c: 1 } });
*
* // This loses the 'full' diff setting - falls back to default 'simple' diff
* const { strictEqual } = myAssert;
* strictEqual({ a: 1 }, { b: { c: 1 } });
* ```
*
* The `skipPrototype` option affects all deep equality methods:
*
* ```js
* class Foo {
* constructor(a) {
* this.a = a;
* }
* }
*
* class Bar {
* constructor(a) {
* this.a = a;
* }
* }
*
* const foo = new Foo(1);
* const bar = new Bar(1);
*
* // Default behavior - fails due to different constructors
* const assert1 = new Assert();
* assert1.deepStrictEqual(foo, bar); // AssertionError
*
* // Skip prototype comparison - passes if properties are equal
* const assert2 = new Assert({ skipPrototype: true });
* assert2.deepStrictEqual(foo, bar); // OK
* ```
*
* When destructured, methods lose access to the instance's `this` context and revert to default assertion behavior
* (diff: 'simple', non-strict mode).
* To maintain custom options when using destructured methods, avoid
* destructuring and call methods directly on the instance.
* @since v24.6.0
*/
new(
options?: AssertOptions & { strict?: true | undefined },
): AssertStrict;
new(
options: AssertOptions,
): Assert;
};
interface AssertionErrorOptions {
/**
* If provided, the error message is set to this value.
*/
message?: string | undefined;
/**
* The `actual` property on the error instance.
*/
actual?: unknown;
/**
* The `expected` property on the error instance.
*/
expected?: unknown;
/**
* The `operator` property on the error instance.
*/
operator?: string | undefined;
/**
* If provided, the generated stack trace omits frames before this function.
*/
stackStartFn?: Function | undefined;
/**
* If set to `'full'`, shows the full diff in assertion errors.
* @default 'simple'
*/
diff?: "simple" | "full" | undefined;
}
/**
* Indicates the failure of an assertion. All errors thrown by the `node:assert` module will be instances of the `AssertionError` class.
*/
class AssertionError extends Error {
constructor(options: AssertionErrorOptions);
/**
* Set to the `actual` argument for methods such as {@link assert.strictEqual()}.
*/
@@ -23,10 +169,6 @@ declare module "assert" {
* Set to the `expected` argument for methods such as {@link assert.strictEqual()}.
*/
expected: unknown;
/**
* Set to the passed in operator value.
*/
operator: string;
/**
* Indicates if the message was auto-generated (`true`) or not.
*/
@@ -35,19 +177,10 @@ declare module "assert" {
* Value is always `ERR_ASSERTION` to show that the error is an assertion error.
*/
code: "ERR_ASSERTION";
constructor(options?: {
/** If provided, the error message is set to this value. */
message?: string | undefined;
/** The `actual` property on the error instance. */
actual?: unknown | undefined;
/** The `expected` property on the error instance. */
expected?: unknown | undefined;
/** The `operator` property on the error instance. */
operator?: string | undefined;
/** If provided, the generated stack trace omits frames before this function. */
// eslint-disable-next-line @typescript-eslint/ban-types
stackStartFn?: Function | undefined;
});
/**
* Set to the passed in operator value.
*/
operator: string;
}
/**
* This feature is deprecated and will be removed in a future version.
@@ -79,7 +212,9 @@ declare module "assert" {
* @return A function that wraps `fn`.
*/
calls(exact?: number): () => void;
calls<Func extends (...args: any[]) => any>(fn?: Func, exact?: number): Func;
calls(fn: undefined, exact?: number): () => void;
calls<Func extends (...args: any[]) => any>(fn: Func, exact?: number): Func;
calls<Func extends (...args: any[]) => any>(fn?: Func, exact?: number): Func | (() => void);
/**
* Example:
*
@@ -226,7 +361,7 @@ declare module "assert" {
expected: unknown,
message?: string | Error,
operator?: string,
// eslint-disable-next-line @typescript-eslint/ban-types
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
stackStartFn?: Function,
): never;
/**
@@ -796,7 +931,7 @@ declare module "assert" {
* check that the promise is rejected.
*
* If `asyncFn` is a function and it throws an error synchronously, `assert.rejects()` will return a rejected `Promise` with that error. If the
* function does not return a promise, `assert.rejects()` will return a rejected `Promise` with an [ERR_INVALID_RETURN_VALUE](https://nodejs.org/docs/latest-v20.x/api/errors.html#err_invalid_return_value)
* function does not return a promise, `assert.rejects()` will return a rejected `Promise` with an [ERR_INVALID_RETURN_VALUE](https://nodejs.org/docs/latest-v24.x/api/errors.html#err_invalid_return_value)
* error. In both cases the error handler is skipped.
*
* Besides the async nature to await the completion behaves identically to {@link throws}.
@@ -866,7 +1001,7 @@ declare module "assert" {
*
* If `asyncFn` is a function and it throws an error synchronously, `assert.doesNotReject()` will return a rejected `Promise` with that error. If
* the function does not return a promise, `assert.doesNotReject()` will return a
* rejected `Promise` with an [ERR_INVALID_RETURN_VALUE](https://nodejs.org/docs/latest-v20.x/api/errors.html#err_invalid_return_value) error. In both cases
* rejected `Promise` with an [ERR_INVALID_RETURN_VALUE](https://nodejs.org/docs/latest-v24.x/api/errors.html#err_invalid_return_value) error. In both cases
* the error handler is skipped.
*
* Using `assert.doesNotReject()` is actually not useful because there is little
@@ -929,7 +1064,7 @@ declare module "assert" {
* If the values do not match, or if the `string` argument is of another type than `string`, an `{@link AssertionError}` is thrown with a `message` property set equal
* to the value of the `message` parameter. If the `message` parameter is
* undefined, a default error message is assigned. If the `message` parameter is an
* instance of an [Error](https://nodejs.org/docs/latest-v20.x/api/errors.html#class-error) then it will be thrown instead of the `{@link AssertionError}`.
* instance of an [Error](https://nodejs.org/docs/latest-v24.x/api/errors.html#class-error) then it will be thrown instead of the `{@link AssertionError}`.
* @since v13.6.0, v12.16.0
*/
function match(value: string, regExp: RegExp, message?: string | Error): void;
@@ -952,85 +1087,25 @@ declare module "assert" {
* If the values do match, or if the `string` argument is of another type than `string`, an `{@link AssertionError}` is thrown with a `message` property set equal
* to the value of the `message` parameter. If the `message` parameter is
* undefined, a default error message is assigned. If the `message` parameter is an
* instance of an [Error](https://nodejs.org/docs/latest-v20.x/api/errors.html#class-error) then it will be thrown instead of the `{@link AssertionError}`.
* instance of an [Error](https://nodejs.org/docs/latest-v24.x/api/errors.html#class-error) then it will be thrown instead of the `{@link AssertionError}`.
* @since v13.6.0, v12.16.0
*/
function doesNotMatch(value: string, regExp: RegExp, message?: string | Error): void;
/**
* In strict assertion mode, non-strict methods behave like their corresponding strict methods. For example,
* {@link deepEqual} will behave like {@link deepStrictEqual}.
* Tests for partial deep equality between the `actual` and `expected` parameters.
* "Deep" equality means that the enumerable "own" properties of child objects
* are recursively evaluated also by the following rules. "Partial" equality means
* that only properties that exist on the `expected` parameter are going to be
* compared.
*
* In strict assertion mode, error messages for objects display a diff. In legacy assertion mode, error
* messages for objects display the objects, often truncated.
*
* To use strict assertion mode:
*
* ```js
* import { strict as assert } from 'node:assert';COPY
* import assert from 'node:assert/strict';
* ```
*
* Example error diff:
*
* ```js
* import { strict as assert } from 'node:assert';
*
* assert.deepEqual([[[1, 2, 3]], 4, 5], [[[1, 2, '3']], 4, 5]);
* // AssertionError: Expected inputs to be strictly deep-equal:
* // + actual - expected ... Lines skipped
* //
* // [
* // [
* // ...
* // 2,
* // + 3
* // - '3'
* // ],
* // ...
* // 5
* // ]
* ```
*
* To deactivate the colors, use the `NO_COLOR` or `NODE_DISABLE_COLORS` environment variables. This will also
* deactivate the colors in the REPL. For more on color support in terminal environments, read the tty
* `getColorDepth()` documentation.
*
* @since v15.0.0, v13.9.0, v12.16.2, v9.9.0
* This method always passes the same test cases as `assert.deepStrictEqual()`,
* behaving as a super set of it.
* @since v22.13.0
*/
namespace strict {
type AssertionError = assert.AssertionError;
type AssertPredicate = assert.AssertPredicate;
type CallTrackerCall = assert.CallTrackerCall;
type CallTrackerReportInformation = assert.CallTrackerReportInformation;
}
const strict:
& Omit<
typeof assert,
| "equal"
| "notEqual"
| "deepEqual"
| "notDeepEqual"
| "ok"
| "strictEqual"
| "deepStrictEqual"
| "ifError"
| "strict"
>
& {
(value: unknown, message?: string | Error): asserts value;
equal: typeof strictEqual;
notEqual: typeof notStrictEqual;
deepEqual: typeof deepStrictEqual;
notDeepEqual: typeof notDeepStrictEqual;
// Mapped types and assertion functions are incompatible?
// TS2775: Assertions require every name in the call target
// to be declared with an explicit type annotation.
ok: typeof ok;
strictEqual: typeof strictEqual;
deepStrictEqual: typeof deepStrictEqual;
ifError: typeof ifError;
strict: typeof strict;
};
function partialDeepStrictEqual(actual: unknown, expected: unknown, message?: string | Error): void;
}
namespace assert {
export { strict };
}
export = assert;
}

View File

@@ -1,8 +1,111 @@
/**
* In strict assertion mode, non-strict methods behave like their corresponding
* strict methods. For example, `assert.deepEqual()` will behave like
* `assert.deepStrictEqual()`.
*
* In strict assertion mode, error messages for objects display a diff. In legacy
* assertion mode, error messages for objects display the objects, often truncated.
*
* To use strict assertion mode:
*
* ```js
* import { strict as assert } from 'node:assert';
* ```
*
* ```js
* import assert from 'node:assert/strict';
* ```
*
* Example error diff:
*
* ```js
* import { strict as assert } from 'node:assert';
*
* assert.deepEqual([[[1, 2, 3]], 4, 5], [[[1, 2, '3']], 4, 5]);
* // AssertionError: Expected inputs to be strictly deep-equal:
* // + actual - expected ... Lines skipped
* //
* // [
* // [
* // ...
* // 2,
* // + 3
* // - '3'
* // ],
* // ...
* // 5
* // ]
* ```
*
* To deactivate the colors, use the `NO_COLOR` or `NODE_DISABLE_COLORS`
* environment variables. This will also deactivate the colors in the REPL. For
* more on color support in terminal environments, read the tty
* [`getColorDepth()`](https://nodejs.org/docs/latest-v24.x/api/tty.html#writestreamgetcolordepthenv) documentation.
* @since v15.0.0
* @see [source](https://github.com/nodejs/node/blob/v24.x/lib/assert/strict.js)
*/
declare module "assert/strict" {
import { strict } from "node:assert";
import {
Assert,
AssertionError,
AssertionErrorOptions,
AssertOptions,
AssertPredicate,
AssertStrict,
CallTracker,
CallTrackerCall,
CallTrackerReportInformation,
deepStrictEqual,
doesNotMatch,
doesNotReject,
doesNotThrow,
fail,
ifError,
match,
notDeepStrictEqual,
notStrictEqual,
ok,
partialDeepStrictEqual,
rejects,
strictEqual,
throws,
} from "node:assert";
function strict(value: unknown, message?: string | Error): asserts value;
namespace strict {
export {
Assert,
AssertionError,
AssertionErrorOptions,
AssertOptions,
AssertPredicate,
AssertStrict,
CallTracker,
CallTrackerCall,
CallTrackerReportInformation,
deepStrictEqual,
deepStrictEqual as deepEqual,
doesNotMatch,
doesNotReject,
doesNotThrow,
fail,
ifError,
match,
notDeepStrictEqual,
notDeepStrictEqual as notDeepEqual,
notStrictEqual,
notStrictEqual as notEqual,
ok,
partialDeepStrictEqual,
rejects,
strict,
strictEqual,
strictEqual as equal,
throws,
};
}
export = strict;
}
declare module "node:assert/strict" {
import { strict } from "node:assert";
import strict = require("assert/strict");
export = strict;
}

View File

@@ -2,8 +2,8 @@
* We strongly discourage the use of the `async_hooks` API.
* Other APIs that can cover most of its use cases include:
*
* * [`AsyncLocalStorage`](https://nodejs.org/docs/latest-v20.x/api/async_context.html#class-asynclocalstorage) tracks async context
* * [`process.getActiveResourcesInfo()`](https://nodejs.org/docs/latest-v20.x/api/process.html#processgetactiveresourcesinfo) tracks active resources
* * [`AsyncLocalStorage`](https://nodejs.org/docs/latest-v24.x/api/async_context.html#class-asynclocalstorage) tracks async context
* * [`process.getActiveResourcesInfo()`](https://nodejs.org/docs/latest-v24.x/api/process.html#processgetactiveresourcesinfo) tracks active resources
*
* The `node:async_hooks` module provides an API to track asynchronous resources.
* It can be accessed using:
@@ -12,7 +12,7 @@
* import async_hooks from 'node:async_hooks';
* ```
* @experimental
* @see [source](https://github.com/nodejs/node/blob/v20.13.1/lib/async_hooks.js)
* @see [source](https://github.com/nodejs/node/blob/v24.x/lib/async_hooks.js)
*/
declare module "async_hooks" {
/**
@@ -44,7 +44,7 @@ declare module "async_hooks" {
* ```
*
* Promise contexts may not get precise `executionAsyncIds` by default.
* See the section on [promise execution tracking](https://nodejs.org/docs/latest-v20.x/api/async_hooks.html#promise-execution-tracking).
* See the section on [promise execution tracking](https://nodejs.org/docs/latest-v24.x/api/async_hooks.html#promise-execution-tracking).
* @since v8.1.0
* @return The `asyncId` of the current execution context. Useful to track when something calls.
*/
@@ -77,7 +77,7 @@ declare module "async_hooks" {
* executionAsyncId,
* executionAsyncResource,
* createHook,
* } from 'async_hooks';
* } from 'node:async_hooks';
* const sym = Symbol('state'); // Private symbol to avoid pollution
*
* createHook({
@@ -117,7 +117,7 @@ declare module "async_hooks" {
* ```
*
* Promise contexts may not get valid `triggerAsyncId`s by default. See
* the section on [promise execution tracking](https://nodejs.org/docs/latest-v20.x/api/async_hooks.html#promise-execution-tracking).
* the section on [promise execution tracking](https://nodejs.org/docs/latest-v24.x/api/async_hooks.html#promise-execution-tracking).
* @return The ID of the resource responsible for calling the callback that is currently being executed.
*/
function triggerAsyncId(): number;
@@ -320,6 +320,16 @@ declare module "async_hooks" {
*/
triggerAsyncId(): number;
}
interface AsyncLocalStorageOptions {
/**
* The default value to be used when no store is provided.
*/
defaultValue?: any;
/**
* A name for the `AsyncLocalStorage` value.
*/
name?: string | undefined;
}
/**
* This class creates stores that stay coherent through asynchronous operations.
*
@@ -358,8 +368,8 @@ declare module "async_hooks" {
* http.get('http://localhost:8080');
* // Prints:
* // 0: start
* // 1: start
* // 0: finish
* // 1: start
* // 1: finish
* ```
*
@@ -369,10 +379,14 @@ declare module "async_hooks" {
* @since v13.10.0, v12.17.0
*/
class AsyncLocalStorage<T> {
/**
* Creates a new instance of `AsyncLocalStorage`. Store is only provided within a
* `run()` call or after an `enterWith()` call.
*/
constructor(options?: AsyncLocalStorageOptions);
/**
* Binds the given function to the current execution context.
* @since v19.8.0
* @experimental
* @param fn The function to bind to the current execution context.
* @return A new function that calls `fn` within the captured execution context.
*/
@@ -403,7 +417,6 @@ declare module "async_hooks" {
* console.log(asyncLocalStorage.run(321, () => foo.get())); // returns 123
* ```
* @since v19.8.0
* @experimental
* @return A new function with the signature `(fn: (...args) : R, ...args) : R`.
*/
static snapshot(): <R, TArgs extends any[]>(fn: (...args: TArgs) => R, ...args: TArgs) => R;
@@ -432,6 +445,11 @@ declare module "async_hooks" {
* @since v13.10.0, v12.17.0
*/
getStore(): T | undefined;
/**
* The name of the `AsyncLocalStorage` instance if provided.
* @since v24.0.0
*/
readonly name: string;
/**
* Runs a function synchronously within a context and returns its
* return value. The store is not accessible outside of the callback function.
@@ -535,6 +553,70 @@ declare module "async_hooks" {
*/
enterWith(store: T): void;
}
/**
* @since v17.2.0, v16.14.0
* @return A map of provider types to the corresponding numeric id.
* This map contains all the event types that might be emitted by the `async_hooks.init()` event.
*/
namespace asyncWrapProviders {
const NONE: number;
const DIRHANDLE: number;
const DNSCHANNEL: number;
const ELDHISTOGRAM: number;
const FILEHANDLE: number;
const FILEHANDLECLOSEREQ: number;
const FIXEDSIZEBLOBCOPY: number;
const FSEVENTWRAP: number;
const FSREQCALLBACK: number;
const FSREQPROMISE: number;
const GETADDRINFOREQWRAP: number;
const GETNAMEINFOREQWRAP: number;
const HEAPSNAPSHOT: number;
const HTTP2SESSION: number;
const HTTP2STREAM: number;
const HTTP2PING: number;
const HTTP2SETTINGS: number;
const HTTPINCOMINGMESSAGE: number;
const HTTPCLIENTREQUEST: number;
const JSSTREAM: number;
const JSUDPWRAP: number;
const MESSAGEPORT: number;
const PIPECONNECTWRAP: number;
const PIPESERVERWRAP: number;
const PIPEWRAP: number;
const PROCESSWRAP: number;
const PROMISE: number;
const QUERYWRAP: number;
const SHUTDOWNWRAP: number;
const SIGNALWRAP: number;
const STATWATCHER: number;
const STREAMPIPE: number;
const TCPCONNECTWRAP: number;
const TCPSERVERWRAP: number;
const TCPWRAP: number;
const TTYWRAP: number;
const UDPSENDWRAP: number;
const UDPWRAP: number;
const SIGINTWATCHDOG: number;
const WORKER: number;
const WORKERHEAPSNAPSHOT: number;
const WRITEWRAP: number;
const ZLIB: number;
const CHECKPRIMEREQUEST: number;
const PBKDF2REQUEST: number;
const KEYPAIRGENREQUEST: number;
const KEYGENREQUEST: number;
const KEYEXPORTREQUEST: number;
const CIPHERREQUEST: number;
const DERIVEBITSREQUEST: number;
const HASHREQUEST: number;
const RANDOMBYTESREQUEST: number;
const RANDOMPRIMEREQUEST: number;
const SCRYPTREQUEST: number;
const SIGNREQUEST: number;
const TLSWRAP: number;
const VERIFYREQUEST: number;
}
}
declare module "node:async_hooks" {
export * from "async_hooks";

View File

@@ -1,3 +1,8 @@
// If lib.dom.d.ts or lib.webworker.d.ts is loaded, then use the global types.
// Otherwise, use the types from node.
type _Blob = typeof globalThis extends { onmessage: any; Blob: any } ? {} : import("buffer").Blob;
type _File = typeof globalThis extends { onmessage: any; File: any } ? {} : import("buffer").File;
/**
* `Buffer` objects are used to represent a fixed-length sequence of bytes. Many
* Node.js APIs support `Buffer`s.
@@ -41,7 +46,7 @@
* // Creates a Buffer containing the Latin-1 bytes [0x74, 0xe9, 0x73, 0x74].
* const buf7 = Buffer.from('tést', 'latin1');
* ```
* @see [source](https://github.com/nodejs/node/blob/v20.13.1/lib/buffer.js)
* @see [source](https://github.com/nodejs/node/blob/v24.x/lib/buffer.js)
*/
declare module "buffer" {
import { BinaryLike } from "node:crypto";
@@ -54,7 +59,7 @@ declare module "buffer" {
* @since v19.4.0, v18.14.0
* @param input The input to validate.
*/
export function isUtf8(input: Buffer | ArrayBuffer | NodeJS.TypedArray): boolean;
export function isUtf8(input: ArrayBuffer | NodeJS.TypedArray): boolean;
/**
* This function returns `true` if `input` contains only valid ASCII-encoded data,
* including the case in which `input` is empty.
@@ -63,8 +68,8 @@ declare module "buffer" {
* @since v19.6.0, v18.15.0
* @param input The input to validate.
*/
export function isAscii(input: Buffer | ArrayBuffer | NodeJS.TypedArray): boolean;
export const INSPECT_MAX_BYTES: number;
export function isAscii(input: ArrayBuffer | NodeJS.TypedArray): boolean;
export let INSPECT_MAX_BYTES: number;
export const kMaxLength: number;
export const kStringMaxLength: number;
export const constants: {
@@ -108,28 +113,26 @@ declare module "buffer" {
* @param fromEnc The current encoding.
* @param toEnc To target encoding.
*/
export function transcode(source: Uint8Array, fromEnc: TranscodeEncoding, toEnc: TranscodeEncoding): Buffer;
export const SlowBuffer: {
/** @deprecated since v6.0.0, use `Buffer.allocUnsafeSlow()` */
new(size: number): Buffer;
prototype: Buffer;
};
export function transcode(
source: Uint8Array,
fromEnc: TranscodeEncoding,
toEnc: TranscodeEncoding,
): NonSharedBuffer;
/**
* Resolves a `'blob:nodedata:...'` an associated `Blob` object registered using
* a prior call to `URL.createObjectURL()`.
* @since v16.7.0
* @experimental
* @param id A `'blob:nodedata:...` URL string returned by a prior call to `URL.createObjectURL()`.
*/
export function resolveObjectURL(id: string): Blob | undefined;
export { Buffer };
export { type AllowSharedBuffer, Buffer, type NonSharedBuffer };
/**
* @experimental
*/
export interface BlobOptions {
/**
* One of either `'transparent'` or `'native'`. When set to `'native'`, line endings in string source parts
* will be converted to the platform native line-ending as specified by `require('node:os').EOL`.
* will be converted to the platform native line-ending as specified by `import { EOL } from 'node:os'`.
*/
endings?: "transparent" | "native";
/**
@@ -140,7 +143,7 @@ declare module "buffer" {
type?: string | undefined;
}
/**
* A [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) encapsulates immutable, raw data that can be safely shared across
* A `Blob` encapsulates immutable, raw data that can be safely shared across
* multiple worker threads.
* @since v15.7.0, v14.18.0
*/
@@ -170,6 +173,17 @@ declare module "buffer" {
* @since v15.7.0, v14.18.0
*/
arrayBuffer(): Promise<ArrayBuffer>;
/**
* The `blob.bytes()` method returns the byte of the `Blob` object as a `Promise<Uint8Array>`.
*
* ```js
* const blob = new Blob(['hello']);
* blob.bytes().then((bytes) => {
* console.log(bytes); // Outputs: Uint8Array(5) [ 104, 101, 108, 108, 111 ]
* });
* ```
*/
bytes(): Promise<Uint8Array>;
/**
* Creates and returns a new `Blob` containing a subset of this `Blob` objects
* data. The original `Blob` is not altered.
@@ -194,7 +208,7 @@ declare module "buffer" {
export interface FileOptions {
/**
* One of either `'transparent'` or `'native'`. When set to `'native'`, line endings in string source parts will be
* converted to the platform native line-ending as specified by `require('node:os').EOL`.
* converted to the platform native line-ending as specified by `import { EOL } from 'node:os'`.
*/
endings?: "native" | "transparent";
/** The File content-type. */
@@ -221,10 +235,10 @@ declare module "buffer" {
}
export import atob = globalThis.atob;
export import btoa = globalThis.btoa;
import { Blob as NodeBlob } from "buffer";
// This conditional type will be the existing global Blob in a browser, or
// the copy below in a Node environment.
type __Blob = typeof globalThis extends { onmessage: any; Blob: any } ? {} : NodeBlob;
export type WithImplicitCoercion<T> =
| T
| { valueOf(): T }
| (T extends string ? { [Symbol.toPrimitive](hint: "string"): T } : never);
global {
namespace NodeJS {
export { BufferEncoding };
@@ -243,111 +257,15 @@ declare module "buffer" {
| "latin1"
| "binary"
| "hex";
type WithImplicitCoercion<T> =
| T
| {
valueOf(): T;
};
/**
* Raw data is stored in instances of the Buffer class.
* A Buffer is similar to an array of integers but corresponds to a raw memory allocation outside the V8 heap. A Buffer cannot be resized.
* Valid string encodings: 'ascii'|'utf8'|'utf16le'|'ucs2'(alias of 'utf16le')|'base64'|'base64url'|'binary'(deprecated)|'hex'
*/
interface BufferConstructor {
/**
* Allocates a new buffer containing the given {str}.
*
* @param str String to store in buffer.
* @param encoding encoding to use, optional. Default is 'utf8'
* @deprecated since v10.0.0 - Use `Buffer.from(string[, encoding])` instead.
*/
new(str: string, encoding?: BufferEncoding): Buffer;
/**
* Allocates a new buffer of {size} octets.
*
* @param size count of octets to allocate.
* @deprecated since v10.0.0 - Use `Buffer.alloc()` instead (also see `Buffer.allocUnsafe()`).
*/
new(size: number): Buffer;
/**
* Allocates a new buffer containing the given {array} of octets.
*
* @param array The octets to store.
* @deprecated since v10.0.0 - Use `Buffer.from(array)` instead.
*/
new(array: Uint8Array): Buffer;
/**
* Produces a Buffer backed by the same allocated memory as
* the given {ArrayBuffer}/{SharedArrayBuffer}.
*
* @param arrayBuffer The ArrayBuffer with which to share memory.
* @deprecated since v10.0.0 - Use `Buffer.from(arrayBuffer[, byteOffset[, length]])` instead.
*/
new(arrayBuffer: ArrayBuffer | SharedArrayBuffer): Buffer;
/**
* Allocates a new buffer containing the given {array} of octets.
*
* @param array The octets to store.
* @deprecated since v10.0.0 - Use `Buffer.from(array)` instead.
*/
new(array: readonly any[]): Buffer;
/**
* Copies the passed {buffer} data onto a new {Buffer} instance.
*
* @param buffer The buffer to copy.
* @deprecated since v10.0.0 - Use `Buffer.from(buffer)` instead.
*/
new(buffer: Buffer): Buffer;
/**
* Allocates a new `Buffer` using an `array` of bytes in the range `0` `255`.
* Array entries outside that range will be truncated to fit into it.
*
* ```js
* import { Buffer } from 'node:buffer';
*
* // Creates a new Buffer containing the UTF-8 bytes of the string 'buffer'.
* const buf = Buffer.from([0x62, 0x75, 0x66, 0x66, 0x65, 0x72]);
* ```
*
* If `array` is an `Array`\-like object (that is, one with a `length` property of
* type `number`), it is treated as if it is an array, unless it is a `Buffer` or
* a `Uint8Array`. This means all other `TypedArray` variants get treated as an `Array`. To create a `Buffer` from the bytes backing a `TypedArray`, use `Buffer.copyBytesFrom()`.
*
* A `TypeError` will be thrown if `array` is not an `Array` or another type
* appropriate for `Buffer.from()` variants.
*
* `Buffer.from(array)` and `Buffer.from(string)` may also use the internal `Buffer` pool like `Buffer.allocUnsafe()` does.
* @since v5.10.0
*/
from(
arrayBuffer: WithImplicitCoercion<ArrayBuffer | SharedArrayBuffer>,
byteOffset?: number,
length?: number,
): Buffer;
/**
* Creates a new Buffer using the passed {data}
* @param data data to create a new Buffer
*/
from(data: Uint8Array | readonly number[]): Buffer;
from(data: WithImplicitCoercion<Uint8Array | readonly number[] | string>): Buffer;
/**
* Creates a new Buffer containing the given JavaScript string {str}.
* If provided, the {encoding} parameter identifies the character encoding.
* If not provided, {encoding} defaults to 'utf8'.
*/
from(
str:
| WithImplicitCoercion<string>
| {
[Symbol.toPrimitive](hint: "string"): string;
},
encoding?: BufferEncoding,
): Buffer;
/**
* Creates a new Buffer using the passed {data}
* @param values to create a new Buffer
*/
of(...items: number[]): Buffer;
// see buffer.buffer.d.ts for implementation specific to TypeScript 5.7 and later
// see ts5.6/buffer.buffer.d.ts for implementation specific to TypeScript 5.6 and earlier
/**
* Returns `true` if `obj` is a `Buffer`, `false` otherwise.
*
@@ -416,65 +334,9 @@ declare module "buffer" {
* @return The number of bytes contained within `string`.
*/
byteLength(
string: string | Buffer | NodeJS.ArrayBufferView | ArrayBuffer | SharedArrayBuffer,
string: string | NodeJS.ArrayBufferView | ArrayBufferLike,
encoding?: BufferEncoding,
): number;
/**
* Returns a new `Buffer` which is the result of concatenating all the `Buffer` instances in the `list` together.
*
* If the list has no items, or if the `totalLength` is 0, then a new zero-length `Buffer` is returned.
*
* If `totalLength` is not provided, it is calculated from the `Buffer` instances
* in `list` by adding their lengths.
*
* If `totalLength` is provided, it is coerced to an unsigned integer. If the
* combined length of the `Buffer`s in `list` exceeds `totalLength`, the result is
* truncated to `totalLength`.
*
* ```js
* import { Buffer } from 'node:buffer';
*
* // Create a single `Buffer` from a list of three `Buffer` instances.
*
* const buf1 = Buffer.alloc(10);
* const buf2 = Buffer.alloc(14);
* const buf3 = Buffer.alloc(18);
* const totalLength = buf1.length + buf2.length + buf3.length;
*
* console.log(totalLength);
* // Prints: 42
*
* const bufA = Buffer.concat([buf1, buf2, buf3], totalLength);
*
* console.log(bufA);
* // Prints: <Buffer 00 00 00 00 ...>
* console.log(bufA.length);
* // Prints: 42
* ```
*
* `Buffer.concat()` may also use the internal `Buffer` pool like `Buffer.allocUnsafe()` does.
* @since v0.7.11
* @param list List of `Buffer` or {@link Uint8Array} instances to concatenate.
* @param totalLength Total length of the `Buffer` instances in `list` when concatenated.
*/
concat(list: readonly Uint8Array[], totalLength?: number): Buffer;
/**
* Copies the underlying memory of `view` into a new `Buffer`.
*
* ```js
* const u16 = new Uint16Array([0, 0xffff]);
* const buf = Buffer.copyBytesFrom(u16, 1, 1);
* u16[1] = 0;
* console.log(buf.length); // 2
* console.log(buf[0]); // 255
* console.log(buf[1]); // 255
* ```
* @since v19.8.0
* @param view The {TypedArray} to copy.
* @param [offset=0] The starting offset within `view`.
* @param [length=view.length - offset] The number of elements from `view` to copy.
*/
copyBytesFrom(view: NodeJS.TypedArray, offset?: number, length?: number): Buffer;
/**
* Compares `buf1` to `buf2`, typically for the purpose of sorting arrays of `Buffer` instances. This is equivalent to calling `buf1.compare(buf2)`.
*
@@ -493,135 +355,6 @@ declare module "buffer" {
* @return Either `-1`, `0`, or `1`, depending on the result of the comparison. See `compare` for details.
*/
compare(buf1: Uint8Array, buf2: Uint8Array): -1 | 0 | 1;
/**
* Allocates a new `Buffer` of `size` bytes. If `fill` is `undefined`, the`Buffer` will be zero-filled.
*
* ```js
* import { Buffer } from 'node:buffer';
*
* const buf = Buffer.alloc(5);
*
* console.log(buf);
* // Prints: <Buffer 00 00 00 00 00>
* ```
*
* If `size` is larger than {@link constants.MAX_LENGTH} or smaller than 0, `ERR_OUT_OF_RANGE` is thrown.
*
* If `fill` is specified, the allocated `Buffer` will be initialized by calling `buf.fill(fill)`.
*
* ```js
* import { Buffer } from 'node:buffer';
*
* const buf = Buffer.alloc(5, 'a');
*
* console.log(buf);
* // Prints: <Buffer 61 61 61 61 61>
* ```
*
* If both `fill` and `encoding` are specified, the allocated `Buffer` will be
* initialized by calling `buf.fill(fill, encoding)`.
*
* ```js
* import { Buffer } from 'node:buffer';
*
* const buf = Buffer.alloc(11, 'aGVsbG8gd29ybGQ=', 'base64');
*
* console.log(buf);
* // Prints: <Buffer 68 65 6c 6c 6f 20 77 6f 72 6c 64>
* ```
*
* Calling `Buffer.alloc()` can be measurably slower than the alternative `Buffer.allocUnsafe()` but ensures that the newly created `Buffer` instance
* contents will never contain sensitive data from previous allocations, including
* data that might not have been allocated for `Buffer`s.
*
* A `TypeError` will be thrown if `size` is not a number.
* @since v5.10.0
* @param size The desired length of the new `Buffer`.
* @param [fill=0] A value to pre-fill the new `Buffer` with.
* @param [encoding='utf8'] If `fill` is a string, this is its encoding.
*/
alloc(size: number, fill?: string | Uint8Array | number, encoding?: BufferEncoding): Buffer;
/**
* Allocates a new `Buffer` of `size` bytes. If `size` is larger than {@link constants.MAX_LENGTH} or smaller than 0, `ERR_OUT_OF_RANGE` is thrown.
*
* The underlying memory for `Buffer` instances created in this way is _not_
* _initialized_. The contents of the newly created `Buffer` are unknown and _may contain sensitive data_. Use `Buffer.alloc()` instead to initialize`Buffer` instances with zeroes.
*
* ```js
* import { Buffer } from 'node:buffer';
*
* const buf = Buffer.allocUnsafe(10);
*
* console.log(buf);
* // Prints (contents may vary): <Buffer a0 8b 28 3f 01 00 00 00 50 32>
*
* buf.fill(0);
*
* console.log(buf);
* // Prints: <Buffer 00 00 00 00 00 00 00 00 00 00>
* ```
*
* A `TypeError` will be thrown if `size` is not a number.
*
* The `Buffer` module pre-allocates an internal `Buffer` instance of
* size `Buffer.poolSize` that is used as a pool for the fast allocation of new `Buffer` instances created using `Buffer.allocUnsafe()`, `Buffer.from(array)`,
* and `Buffer.concat()` only when `size` is less than `Buffer.poolSize >>> 1` (floor of `Buffer.poolSize` divided by two).
*
* Use of this pre-allocated internal memory pool is a key difference between
* calling `Buffer.alloc(size, fill)` vs. `Buffer.allocUnsafe(size).fill(fill)`.
* Specifically, `Buffer.alloc(size, fill)` will _never_ use the internal `Buffer`pool, while `Buffer.allocUnsafe(size).fill(fill)`_will_ use the internal`Buffer` pool if `size` is less
* than or equal to half `Buffer.poolSize`. The
* difference is subtle but can be important when an application requires the
* additional performance that `Buffer.allocUnsafe()` provides.
* @since v5.10.0
* @param size The desired length of the new `Buffer`.
*/
allocUnsafe(size: number): Buffer;
/**
* Allocates a new `Buffer` of `size` bytes. If `size` is larger than {@link constants.MAX_LENGTH} or smaller than 0, `ERR_OUT_OF_RANGE` is thrown. A zero-length `Buffer` is created if
* `size` is 0.
*
* The underlying memory for `Buffer` instances created in this way is _not_
* _initialized_. The contents of the newly created `Buffer` are unknown and _may contain sensitive data_. Use `buf.fill(0)` to initialize
* such `Buffer` instances with zeroes.
*
* When using `Buffer.allocUnsafe()` to allocate new `Buffer` instances,
* allocations under 4 KiB are sliced from a single pre-allocated `Buffer`. This
* allows applications to avoid the garbage collection overhead of creating many
* individually allocated `Buffer` instances. This approach improves both
* performance and memory usage by eliminating the need to track and clean up as
* many individual `ArrayBuffer` objects.
*
* However, in the case where a developer may need to retain a small chunk of
* memory from a pool for an indeterminate amount of time, it may be appropriate
* to create an un-pooled `Buffer` instance using `Buffer.allocUnsafeSlow()` and
* then copying out the relevant bits.
*
* ```js
* import { Buffer } from 'node:buffer';
*
* // Need to keep around a few small chunks of memory.
* const store = [];
*
* socket.on('readable', () => {
* let data;
* while (null !== (data = readable.read())) {
* // Allocate for retained data.
* const sb = Buffer.allocUnsafeSlow(10);
*
* // Copy the data into the new allocation.
* data.copy(sb, 0, 0, 10);
*
* store.push(sb);
* }
* });
* ```
*
* A `TypeError` will be thrown if `size` is not a number.
* @since v5.12.0
* @param size The desired length of the new `Buffer`.
*/
allocUnsafeSlow(size: number): Buffer;
/**
* This is the size (in bytes) of pre-allocated internal `Buffer` instances used
* for pooling. This value may be modified.
@@ -629,7 +362,10 @@ declare module "buffer" {
*/
poolSize: number;
}
interface Buffer extends Uint8Array {
interface Buffer {
// see buffer.buffer.d.ts for implementation specific to TypeScript 5.7 and later
// see ts5.6/buffer.buffer.d.ts for implementation specific to TypeScript 5.6 and earlier
/**
* Writes `string` to `buf` at `offset` according to the character encoding in`encoding`. The `length` parameter is the number of bytes to write. If `buf` did
* not contain enough space to fit the entire string, only part of `string` will be
@@ -866,100 +602,6 @@ declare module "buffer" {
* @return The number of bytes copied.
*/
copy(target: Uint8Array, targetStart?: number, sourceStart?: number, sourceEnd?: number): number;
/**
* Returns a new `Buffer` that references the same memory as the original, but
* offset and cropped by the `start` and `end` indices.
*
* This method is not compatible with the `Uint8Array.prototype.slice()`,
* which is a superclass of `Buffer`. To copy the slice, use`Uint8Array.prototype.slice()`.
*
* ```js
* import { Buffer } from 'node:buffer';
*
* const buf = Buffer.from('buffer');
*
* const copiedBuf = Uint8Array.prototype.slice.call(buf);
* copiedBuf[0]++;
* console.log(copiedBuf.toString());
* // Prints: cuffer
*
* console.log(buf.toString());
* // Prints: buffer
*
* // With buf.slice(), the original buffer is modified.
* const notReallyCopiedBuf = buf.slice();
* notReallyCopiedBuf[0]++;
* console.log(notReallyCopiedBuf.toString());
* // Prints: cuffer
* console.log(buf.toString());
* // Also prints: cuffer (!)
* ```
* @since v0.3.0
* @deprecated Use `subarray` instead.
* @param [start=0] Where the new `Buffer` will start.
* @param [end=buf.length] Where the new `Buffer` will end (not inclusive).
*/
slice(start?: number, end?: number): Buffer;
/**
* Returns a new `Buffer` that references the same memory as the original, but
* offset and cropped by the `start` and `end` indices.
*
* Specifying `end` greater than `buf.length` will return the same result as
* that of `end` equal to `buf.length`.
*
* This method is inherited from [`TypedArray.prototype.subarray()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/subarray).
*
* Modifying the new `Buffer` slice will modify the memory in the original `Buffer`because the allocated memory of the two objects overlap.
*
* ```js
* import { Buffer } from 'node:buffer';
*
* // Create a `Buffer` with the ASCII alphabet, take a slice, and modify one byte
* // from the original `Buffer`.
*
* const buf1 = Buffer.allocUnsafe(26);
*
* for (let i = 0; i < 26; i++) {
* // 97 is the decimal ASCII value for 'a'.
* buf1[i] = i + 97;
* }
*
* const buf2 = buf1.subarray(0, 3);
*
* console.log(buf2.toString('ascii', 0, buf2.length));
* // Prints: abc
*
* buf1[0] = 33;
*
* console.log(buf2.toString('ascii', 0, buf2.length));
* // Prints: !bc
* ```
*
* Specifying negative indexes causes the slice to be generated relative to the
* end of `buf` rather than the beginning.
*
* ```js
* import { Buffer } from 'node:buffer';
*
* const buf = Buffer.from('buffer');
*
* console.log(buf.subarray(-6, -1).toString());
* // Prints: buffe
* // (Equivalent to buf.subarray(0, 5).)
*
* console.log(buf.subarray(-6, -2).toString());
* // Prints: buff
* // (Equivalent to buf.subarray(0, 4).)
*
* console.log(buf.subarray(-5, -2).toString());
* // Prints: uff
* // (Equivalent to buf.subarray(1, 4).)
* ```
* @since v3.0.0
* @param [start=0] Where the new `Buffer` will start.
* @param [end=buf.length] Where the new `Buffer` will end (not inclusive).
*/
subarray(start?: number, end?: number): Buffer;
/**
* Writes `value` to `buf` at the specified `offset` as big-endian.
*
@@ -1617,7 +1259,7 @@ declare module "buffer" {
* @since v5.10.0
* @return A reference to `buf`.
*/
swap16(): Buffer;
swap16(): this;
/**
* Interprets `buf` as an array of unsigned 32-bit integers and swaps the
* byte order _in-place_. Throws `ERR_INVALID_BUFFER_SIZE` if `buf.length` is not a multiple of 4.
@@ -1643,7 +1285,7 @@ declare module "buffer" {
* @since v5.10.0
* @return A reference to `buf`.
*/
swap32(): Buffer;
swap32(): this;
/**
* Interprets `buf` as an array of 64-bit numbers and swaps byte order _in-place_.
* Throws `ERR_INVALID_BUFFER_SIZE` if `buf.length` is not a multiple of 8.
@@ -1669,7 +1311,7 @@ declare module "buffer" {
* @since v6.3.0
* @return A reference to `buf`.
*/
swap64(): Buffer;
swap64(): this;
/**
* Writes `value` to `buf` at the specified `offset`. `value` must be a
* valid unsigned 8-bit integer. Behavior is undefined when `value` is anything
@@ -2063,6 +1705,8 @@ declare module "buffer" {
* @return A reference to `buf`.
*/
fill(value: string | Uint8Array | number, offset?: number, end?: number, encoding?: BufferEncoding): this;
fill(value: string | Uint8Array | number, offset: number, encoding: BufferEncoding): this;
fill(value: string | Uint8Array | number, encoding: BufferEncoding): this;
/**
* If `value` is:
*
@@ -2132,6 +1776,7 @@ declare module "buffer" {
* @return The index of the first occurrence of `value` in `buf`, or `-1` if `buf` does not contain `value`.
*/
indexOf(value: string | number | Uint8Array, byteOffset?: number, encoding?: BufferEncoding): number;
indexOf(value: string | number | Uint8Array, encoding: BufferEncoding): number;
/**
* Identical to `buf.indexOf()`, except the last occurrence of `value` is found
* rather than the first occurrence.
@@ -2200,6 +1845,7 @@ declare module "buffer" {
* @return The index of the last occurrence of `value` in `buf`, or `-1` if `buf` does not contain `value`.
*/
lastIndexOf(value: string | number | Uint8Array, byteOffset?: number, encoding?: BufferEncoding): number;
lastIndexOf(value: string | number | Uint8Array, encoding: BufferEncoding): number;
/**
* Equivalent to `buf.indexOf() !== -1`.
*
@@ -2230,6 +1876,7 @@ declare module "buffer" {
* @return `true` if `value` was found in `buf`, `false` otherwise.
*/
includes(value: string | number | Buffer, byteOffset?: number, encoding?: BufferEncoding): boolean;
includes(value: string | number | Buffer, encoding: BufferEncoding): boolean;
}
var Buffer: BufferConstructor;
/**
@@ -2264,17 +1911,22 @@ declare module "buffer" {
* @param data An ASCII (Latin1) string.
*/
function btoa(data: string): string;
interface Blob extends __Blob {}
interface Blob extends _Blob {}
/**
* `Blob` class is a global reference for `require('node:buffer').Blob`
* `Blob` class is a global reference for `import { Blob } from 'node:buffer'`
* https://nodejs.org/api/buffer.html#class-blob
* @since v18.0.0
*/
var Blob: typeof globalThis extends {
onmessage: any;
Blob: infer T;
} ? T
: typeof NodeBlob;
var Blob: typeof globalThis extends { onmessage: any; Blob: infer T } ? T
: typeof import("buffer").Blob;
interface File extends _File {}
/**
* `File` class is a global reference for `import { File } from 'node:buffer'`
* https://nodejs.org/api/buffer.html#class-file
* @since v20.0.0
*/
var File: typeof globalThis extends { onmessage: any; File: infer T } ? T
: typeof import("buffer").File;
}
}
declare module "node:buffer" {

View File

@@ -4,7 +4,7 @@
* is primarily provided by the {@link spawn} function:
*
* ```js
* const { spawn } = require('node:child_process');
* import { spawn } from 'node:child_process';
* const ls = spawn('ls', ['-lh', '/usr']);
*
* ls.stdout.on('data', (data) => {
@@ -24,7 +24,7 @@
* the parent Node.js process and the spawned subprocess. These pipes have
* limited (and platform-specific) capacity. If the subprocess writes to
* stdout in excess of that limit without the output being captured, the
* subprocess blocks waiting for the pipe buffer to accept more data. This is
* subprocess blocks, waiting for the pipe buffer to accept more data. This is
* identical to the behavior of pipes in the shell. Use the `{ stdio: 'ignore' }` option if the output will not be consumed.
*
* The command lookup is performed using the `options.env.PATH` environment
@@ -63,14 +63,14 @@
* For certain use cases, such as automating shell scripts, the `synchronous counterparts` may be more convenient. In many cases, however,
* the synchronous methods can have significant impact on performance due to
* stalling the event loop while spawned processes complete.
* @see [source](https://github.com/nodejs/node/blob/v20.13.1/lib/child_process.js)
* @see [source](https://github.com/nodejs/node/blob/v24.x/lib/child_process.js)
*/
declare module "child_process" {
import { ObjectEncodingOptions } from "node:fs";
import { NonSharedBuffer } from "node:buffer";
import { Abortable, EventEmitter } from "node:events";
import * as dgram from "node:dgram";
import * as net from "node:net";
import { Pipe, Readable, Stream, Writable } from "node:stream";
import { Readable, Stream, Writable } from "node:stream";
import { URL } from "node:url";
type Serializable = string | object | number | boolean | bigint;
type SendHandle = net.Socket | net.Server | dgram.Socket | undefined;
@@ -109,7 +109,7 @@ declare module "child_process" {
* refer to the same value.
*
* ```js
* const { spawn } = require('node:child_process');
* import { spawn } from 'node:child_process';
*
* const subprocess = spawn('ls');
*
@@ -140,7 +140,7 @@ declare module "child_process" {
* no IPC channel exists, this property is `undefined`.
* @since v7.1.0
*/
readonly channel?: Pipe | null | undefined;
readonly channel?: Control | null;
/**
* A sparse array of pipes to the child process, corresponding with positions in
* the `stdio` option passed to {@link spawn} that have been set
@@ -152,9 +152,9 @@ declare module "child_process" {
* in the array are `null`.
*
* ```js
* const assert = require('node:assert');
* const fs = require('node:fs');
* const child_process = require('node:child_process');
* import assert from 'node:assert';
* import fs from 'node:fs';
* import child_process from 'node:child_process';
*
* const subprocess = child_process.spawn('ls', {
* stdio: [
@@ -202,7 +202,7 @@ declare module "child_process" {
* emitted.
*
* ```js
* const { spawn } = require('node:child_process');
* import { spawn } from 'node:child_process';
* const grep = spawn('grep', ['ssh']);
*
* console.log(`Spawned child pid: ${grep.pid}`);
@@ -249,7 +249,7 @@ declare module "child_process" {
* returns `true` if [`kill(2)`](http://man7.org/linux/man-pages/man2/kill.2.html) succeeds, and `false` otherwise.
*
* ```js
* const { spawn } = require('node:child_process');
* import { spawn } from 'node:child_process';
* const grep = spawn('grep', ['ssh']);
*
* grep.on('close', (code, signal) => {
@@ -282,7 +282,7 @@ declare module "child_process" {
*
* ```js
* 'use strict';
* const { spawn } = require('node:child_process');
* import { spawn } from 'node:child_process';
*
* const subprocess = spawn(
* 'sh',
@@ -320,7 +320,7 @@ declare module "child_process" {
* For example, in the parent script:
*
* ```js
* const cp = require('node:child_process');
* import cp from 'node:child_process';
* const n = cp.fork(`${__dirname}/sub.js`);
*
* n.on('message', (m) => {
@@ -374,10 +374,12 @@ declare module "child_process" {
* a TCP server object to the child process as illustrated in the example below:
*
* ```js
* const subprocess = require('node:child_process').fork('subprocess.js');
* import { createServer } from 'node:net';
* import { fork } from 'node:child_process';
* const subprocess = fork('subprocess.js');
*
* // Open up the server object and send the handle.
* const server = require('node:net').createServer();
* const server = createServer();
* server.on('connection', (socket) => {
* socket.end('handled by parent');
* });
@@ -412,13 +414,14 @@ declare module "child_process" {
* handle connections with "normal" or "special" priority:
*
* ```js
* const { fork } = require('node:child_process');
* import { createServer } from 'node:net';
* import { fork } from 'node:child_process';
* const normal = fork('subprocess.js', ['normal']);
* const special = fork('subprocess.js', ['special']);
*
* // Open up the server and send sockets to child. Use pauseOnConnect to prevent
* // the sockets from being read before they are sent to the child process.
* const server = require('node:net').createServer({ pauseOnConnect: true });
* const server = createServer({ pauseOnConnect: true });
* server.on('connection', (socket) => {
*
* // If this is special priority...
@@ -455,7 +458,7 @@ declare module "child_process" {
* as the connection may have been closed during the time it takes to send the
* connection to the child.
* @since v0.5.9
* @param sendHandle `undefined`, or a [`net.Socket`](https://nodejs.org/docs/latest-v20.x/api/net.html#class-netsocket), [`net.Server`](https://nodejs.org/docs/latest-v20.x/api/net.html#class-netserver), or [`dgram.Socket`](https://nodejs.org/docs/latest-v20.x/api/dgram.html#class-dgramsocket) object.
* @param sendHandle `undefined`, or a [`net.Socket`](https://nodejs.org/docs/latest-v24.x/api/net.html#class-netsocket), [`net.Server`](https://nodejs.org/docs/latest-v24.x/api/net.html#class-netserver), or [`dgram.Socket`](https://nodejs.org/docs/latest-v24.x/api/dgram.html#class-dgramsocket) object.
* @param options The `options` argument, if present, is an object used to parameterize the sending of certain types of handles. `options` supports the following properties:
*/
send(message: Serializable, callback?: (error: Error | null) => void): boolean;
@@ -490,7 +493,7 @@ declare module "child_process" {
* the child and the parent.
*
* ```js
* const { spawn } = require('node:child_process');
* import { spawn } from 'node:child_process';
*
* const subprocess = spawn(process.argv[0], ['child_program.js'], {
* detached: true,
@@ -508,7 +511,7 @@ declare module "child_process" {
* to wait for the child to exit before exiting itself.
*
* ```js
* const { spawn } = require('node:child_process');
* import { spawn } from 'node:child_process';
*
* const subprocess = spawn(process.argv[0], ['child_program.js'], {
* detached: true,
@@ -610,6 +613,10 @@ declare module "child_process" {
Readable | Writable | null | undefined, // extra, no modification
];
}
interface Control extends EventEmitter {
ref(): void;
unref(): void;
}
interface MessageOptions {
keepOpen?: boolean | undefined;
}
@@ -711,7 +718,7 @@ declare module "child_process" {
* exit code:
*
* ```js
* const { spawn } = require('node:child_process');
* import { spawn } from 'node:child_process';
* const ls = spawn('ls', ['-lh', '/usr']);
*
* ls.stdout.on('data', (data) => {
@@ -730,7 +737,7 @@ declare module "child_process" {
* Example: A very elaborate way to run `ps ax | grep ssh`
*
* ```js
* const { spawn } = require('node:child_process');
* import { spawn } from 'node:child_process';
* const ps = spawn('ps', ['ax']);
* const grep = spawn('grep', ['ssh']);
*
@@ -767,7 +774,7 @@ declare module "child_process" {
* Example of checking for failed `spawn`:
*
* ```js
* const { spawn } = require('node:child_process');
* import { spawn } from 'node:child_process';
* const subprocess = spawn('bad_command');
*
* subprocess.on('error', (err) => {
@@ -785,7 +792,7 @@ declare module "child_process" {
* the error passed to the callback will be an `AbortError`:
*
* ```js
* const { spawn } = require('node:child_process');
* import { spawn } from 'node:child_process';
* const controller = new AbortController();
* const { signal } = controller;
* const grep = spawn('grep', ['ssh'], { signal });
@@ -884,18 +891,20 @@ declare module "child_process" {
signal?: AbortSignal | undefined;
maxBuffer?: number | undefined;
killSignal?: NodeJS.Signals | number | undefined;
encoding?: string | null | undefined;
}
interface ExecOptionsWithStringEncoding extends ExecOptions {
encoding: BufferEncoding;
encoding?: BufferEncoding | undefined;
}
interface ExecOptionsWithBufferEncoding extends ExecOptions {
encoding: BufferEncoding | null; // specify `null`.
encoding: "buffer" | null; // specify `null`.
}
// TODO: Just Plain Wrong™ (see also nodejs/node#57392)
interface ExecException extends Error {
cmd?: string | undefined;
killed?: boolean | undefined;
code?: number | undefined;
signal?: NodeJS.Signals | undefined;
cmd?: string;
killed?: boolean;
code?: number;
signal?: NodeJS.Signals;
stdout?: string;
stderr?: string;
}
@@ -906,7 +915,7 @@ declare module "child_process" {
* need to be dealt with accordingly:
*
* ```js
* const { exec } = require('node:child_process');
* import { exec } from 'node:child_process';
*
* exec('"/path/to/test file/test.sh" arg1 arg2');
* // Double quotes are used so that the space in the path is not interpreted as
@@ -932,7 +941,7 @@ declare module "child_process" {
* encoding, `Buffer` objects will be passed to the callback instead.
*
* ```js
* const { exec } = require('node:child_process');
* import { exec } from 'node:child_process';
* exec('cat *.js missing_file | wc -l', (error, stdout, stderr) => {
* if (error) {
* console.error(`exec error: ${error}`);
@@ -957,8 +966,9 @@ declare module "child_process" {
* callback, but with two additional properties `stdout` and `stderr`.
*
* ```js
* const util = require('node:util');
* const exec = util.promisify(require('node:child_process').exec);
* import util from 'node:util';
* import child_process from 'node:child_process';
* const exec = util.promisify(child_process.exec);
*
* async function lsExample() {
* const { stdout, stderr } = await exec('ls');
@@ -972,7 +982,7 @@ declare module "child_process" {
* the error passed to the callback will be an `AbortError`:
*
* ```js
* const { exec } = require('node:child_process');
* import { exec } from 'node:child_process';
* const controller = new AbortController();
* const { signal } = controller;
* const child = exec('grep ssh', { signal }, (error) => {
@@ -991,39 +1001,24 @@ declare module "child_process" {
// `options` with `"buffer"` or `null` for `encoding` means stdout/stderr are definitely `Buffer`.
function exec(
command: string,
options: {
encoding: "buffer" | null;
} & ExecOptions,
callback?: (error: ExecException | null, stdout: Buffer, stderr: Buffer) => void,
options: ExecOptionsWithBufferEncoding,
callback?: (error: ExecException | null, stdout: NonSharedBuffer, stderr: NonSharedBuffer) => void,
): ChildProcess;
// `options` with well known `encoding` means stdout/stderr are definitely `string`.
// `options` with well-known or absent `encoding` means stdout/stderr are definitely `string`.
function exec(
command: string,
options: {
encoding: BufferEncoding;
} & ExecOptions,
callback?: (error: ExecException | null, stdout: string, stderr: string) => void,
): ChildProcess;
// `options` with an `encoding` whose type is `string` means stdout/stderr could either be `Buffer` or `string`.
// There is no guarantee the `encoding` is unknown as `string` is a superset of `BufferEncoding`.
function exec(
command: string,
options: {
encoding: BufferEncoding;
} & ExecOptions,
callback?: (error: ExecException | null, stdout: string | Buffer, stderr: string | Buffer) => void,
): ChildProcess;
// `options` without an `encoding` means stdout/stderr are definitely `string`.
function exec(
command: string,
options: ExecOptions,
options: ExecOptionsWithStringEncoding,
callback?: (error: ExecException | null, stdout: string, stderr: string) => void,
): ChildProcess;
// fallback if nothing else matches. Worst case is always `string | Buffer`.
function exec(
command: string,
options: (ObjectEncodingOptions & ExecOptions) | undefined | null,
callback?: (error: ExecException | null, stdout: string | Buffer, stderr: string | Buffer) => void,
options: ExecOptions | undefined | null,
callback?: (
error: ExecException | null,
stdout: string | NonSharedBuffer,
stderr: string | NonSharedBuffer,
) => void,
): ChildProcess;
interface PromiseWithChild<T> extends Promise<T> {
child: ChildProcess;
@@ -1035,35 +1030,24 @@ declare module "child_process" {
}>;
function __promisify__(
command: string,
options: {
encoding: "buffer" | null;
} & ExecOptions,
options: ExecOptionsWithBufferEncoding,
): PromiseWithChild<{
stdout: Buffer;
stderr: Buffer;
stdout: NonSharedBuffer;
stderr: NonSharedBuffer;
}>;
function __promisify__(
command: string,
options: {
encoding: BufferEncoding;
} & ExecOptions,
options: ExecOptionsWithStringEncoding,
): PromiseWithChild<{
stdout: string;
stderr: string;
}>;
function __promisify__(
command: string,
options: ExecOptions,
options: ExecOptions | undefined | null,
): PromiseWithChild<{
stdout: string;
stderr: string;
}>;
function __promisify__(
command: string,
options?: (ObjectEncodingOptions & ExecOptions) | null,
): PromiseWithChild<{
stdout: string | Buffer;
stderr: string | Buffer;
stdout: string | NonSharedBuffer;
stderr: string | NonSharedBuffer;
}>;
}
interface ExecFileOptions extends CommonOptions, Abortable {
@@ -1072,20 +1056,21 @@ declare module "child_process" {
windowsVerbatimArguments?: boolean | undefined;
shell?: boolean | string | undefined;
signal?: AbortSignal | undefined;
encoding?: string | null | undefined;
}
interface ExecFileOptionsWithStringEncoding extends ExecFileOptions {
encoding: BufferEncoding;
encoding?: BufferEncoding | undefined;
}
interface ExecFileOptionsWithBufferEncoding extends ExecFileOptions {
encoding: "buffer" | null;
}
interface ExecFileOptionsWithOtherEncoding extends ExecFileOptions {
encoding: BufferEncoding;
}
/** @deprecated Use `ExecFileOptions` instead. */
interface ExecFileOptionsWithOtherEncoding extends ExecFileOptions {}
// TODO: execFile exceptions can take many forms... this accurately describes none of them
type ExecFileException =
& Omit<ExecException, "code">
& Omit<NodeJS.ErrnoException, "code">
& { code?: string | number | undefined | null };
& { code?: string | number | null };
/**
* The `child_process.execFile()` function is similar to {@link exec} except that it does not spawn a shell by default. Rather, the specified
* executable `file` is spawned directly as a new process making it slightly more
@@ -1096,7 +1081,7 @@ declare module "child_process" {
* supported.
*
* ```js
* const { execFile } = require('node:child_process');
* import { execFile } from 'node:child_process';
* const child = execFile('node', ['--version'], (error, stdout, stderr) => {
* if (error) {
* throw error;
@@ -1119,8 +1104,9 @@ declare module "child_process" {
* callback, but with two additional properties `stdout` and `stderr`.
*
* ```js
* const util = require('node:util');
* const execFile = util.promisify(require('node:child_process').execFile);
* import util from 'node:util';
* import child_process from 'node:child_process';
* const execFile = util.promisify(child_process.execFile);
* async function getVersion() {
* const { stdout } = await execFile('node', ['--version']);
* console.log(stdout);
@@ -1136,7 +1122,7 @@ declare module "child_process" {
* the error passed to the callback will be an `AbortError`:
*
* ```js
* const { execFile } = require('node:child_process');
* import { execFile } from 'node:child_process';
* const controller = new AbortController();
* const { signal } = controller;
* const child = execFile('node', ['--version'], { signal }, (error) => {
@@ -1149,91 +1135,63 @@ declare module "child_process" {
* @param args List of string arguments.
* @param callback Called with the output when process terminates.
*/
function execFile(file: string): ChildProcess;
function execFile(
file: string,
options: (ObjectEncodingOptions & ExecFileOptions) | undefined | null,
): ChildProcess;
function execFile(file: string, args?: readonly string[] | null): ChildProcess;
function execFile(
file: string,
args: readonly string[] | undefined | null,
options: (ObjectEncodingOptions & ExecFileOptions) | undefined | null,
): ChildProcess;
// no `options` definitely means stdout/stderr are `string`.
function execFile(
file: string,
callback: (error: ExecFileException | null, stdout: string, stderr: string) => void,
callback?: (error: ExecFileException | null, stdout: string, stderr: string) => void,
): ChildProcess;
function execFile(
file: string,
args: readonly string[] | undefined | null,
callback: (error: ExecFileException | null, stdout: string, stderr: string) => void,
callback?: (error: ExecFileException | null, stdout: string, stderr: string) => void,
): ChildProcess;
// `options` with `"buffer"` or `null` for `encoding` means stdout/stderr are definitely `Buffer`.
function execFile(
file: string,
options: ExecFileOptionsWithBufferEncoding,
callback: (error: ExecFileException | null, stdout: Buffer, stderr: Buffer) => void,
callback?: (error: ExecFileException | null, stdout: NonSharedBuffer, stderr: NonSharedBuffer) => void,
): ChildProcess;
function execFile(
file: string,
args: readonly string[] | undefined | null,
options: ExecFileOptionsWithBufferEncoding,
callback: (error: ExecFileException | null, stdout: Buffer, stderr: Buffer) => void,
callback?: (error: ExecFileException | null, stdout: NonSharedBuffer, stderr: NonSharedBuffer) => void,
): ChildProcess;
// `options` with well known `encoding` means stdout/stderr are definitely `string`.
// `options` with well-known or absent `encoding` means stdout/stderr are definitely `string`.
function execFile(
file: string,
options: ExecFileOptionsWithStringEncoding,
callback: (error: ExecFileException | null, stdout: string, stderr: string) => void,
callback?: (error: ExecFileException | null, stdout: string, stderr: string) => void,
): ChildProcess;
function execFile(
file: string,
args: readonly string[] | undefined | null,
options: ExecFileOptionsWithStringEncoding,
callback: (error: ExecFileException | null, stdout: string, stderr: string) => void,
): ChildProcess;
// `options` with an `encoding` whose type is `string` means stdout/stderr could either be `Buffer` or `string`.
// There is no guarantee the `encoding` is unknown as `string` is a superset of `BufferEncoding`.
function execFile(
file: string,
options: ExecFileOptionsWithOtherEncoding,
callback: (error: ExecFileException | null, stdout: string | Buffer, stderr: string | Buffer) => void,
): ChildProcess;
function execFile(
file: string,
args: readonly string[] | undefined | null,
options: ExecFileOptionsWithOtherEncoding,
callback: (error: ExecFileException | null, stdout: string | Buffer, stderr: string | Buffer) => void,
): ChildProcess;
// `options` without an `encoding` means stdout/stderr are definitely `string`.
function execFile(
file: string,
options: ExecFileOptions,
callback: (error: ExecFileException | null, stdout: string, stderr: string) => void,
): ChildProcess;
function execFile(
file: string,
args: readonly string[] | undefined | null,
options: ExecFileOptions,
callback: (error: ExecFileException | null, stdout: string, stderr: string) => void,
callback?: (error: ExecFileException | null, stdout: string, stderr: string) => void,
): ChildProcess;
// fallback if nothing else matches. Worst case is always `string | Buffer`.
function execFile(
file: string,
options: (ObjectEncodingOptions & ExecFileOptions) | undefined | null,
options: ExecFileOptions | undefined | null,
callback:
| ((error: ExecFileException | null, stdout: string | Buffer, stderr: string | Buffer) => void)
| ((
error: ExecFileException | null,
stdout: string | NonSharedBuffer,
stderr: string | NonSharedBuffer,
) => void)
| undefined
| null,
): ChildProcess;
function execFile(
file: string,
args: readonly string[] | undefined | null,
options: (ObjectEncodingOptions & ExecFileOptions) | undefined | null,
options: ExecFileOptions | undefined | null,
callback:
| ((error: ExecFileException | null, stdout: string | Buffer, stderr: string | Buffer) => void)
| ((
error: ExecFileException | null,
stdout: string | NonSharedBuffer,
stderr: string | NonSharedBuffer,
) => void)
| undefined
| null,
): ChildProcess;
@@ -1253,16 +1211,16 @@ declare module "child_process" {
file: string,
options: ExecFileOptionsWithBufferEncoding,
): PromiseWithChild<{
stdout: Buffer;
stderr: Buffer;
stdout: NonSharedBuffer;
stderr: NonSharedBuffer;
}>;
function __promisify__(
file: string,
args: readonly string[] | undefined | null,
options: ExecFileOptionsWithBufferEncoding,
): PromiseWithChild<{
stdout: Buffer;
stderr: Buffer;
stdout: NonSharedBuffer;
stderr: NonSharedBuffer;
}>;
function __promisify__(
file: string,
@@ -1281,48 +1239,18 @@ declare module "child_process" {
}>;
function __promisify__(
file: string,
options: ExecFileOptionsWithOtherEncoding,
options: ExecFileOptions | undefined | null,
): PromiseWithChild<{
stdout: string | Buffer;
stderr: string | Buffer;
stdout: string | NonSharedBuffer;
stderr: string | NonSharedBuffer;
}>;
function __promisify__(
file: string,
args: readonly string[] | undefined | null,
options: ExecFileOptionsWithOtherEncoding,
options: ExecFileOptions | undefined | null,
): PromiseWithChild<{
stdout: string | Buffer;
stderr: string | Buffer;
}>;
function __promisify__(
file: string,
options: ExecFileOptions,
): PromiseWithChild<{
stdout: string;
stderr: string;
}>;
function __promisify__(
file: string,
args: readonly string[] | undefined | null,
options: ExecFileOptions,
): PromiseWithChild<{
stdout: string;
stderr: string;
}>;
function __promisify__(
file: string,
options: (ObjectEncodingOptions & ExecFileOptions) | undefined | null,
): PromiseWithChild<{
stdout: string | Buffer;
stderr: string | Buffer;
}>;
function __promisify__(
file: string,
args: readonly string[] | undefined | null,
options: (ObjectEncodingOptions & ExecFileOptions) | undefined | null,
): PromiseWithChild<{
stdout: string | Buffer;
stderr: string | Buffer;
stdout: string | NonSharedBuffer;
stderr: string | NonSharedBuffer;
}>;
}
interface ForkOptions extends ProcessEnvOptions, MessagingOptions, Abortable {
@@ -1377,7 +1305,7 @@ declare module "child_process" {
* console.log(`Hello from ${process.argv[2]}!`);
* }, 1_000);
* } else {
* const { fork } = require('node:child_process');
* import { fork } from 'node:child_process';
* const controller = new AbortController();
* const { signal } = controller;
* const child = fork(__filename, ['child'], { signal });
@@ -1411,7 +1339,7 @@ declare module "child_process" {
stderr: T;
status: number | null;
signal: NodeJS.Signals | null;
error?: Error | undefined;
error?: Error;
}
/**
* The `child_process.spawnSync()` method is generally identical to {@link spawn} with the exception that the function will not return
@@ -1428,11 +1356,11 @@ declare module "child_process" {
* @param command The command to run.
* @param args List of string arguments.
*/
function spawnSync(command: string): SpawnSyncReturns<Buffer>;
function spawnSync(command: string): SpawnSyncReturns<NonSharedBuffer>;
function spawnSync(command: string, options: SpawnSyncOptionsWithStringEncoding): SpawnSyncReturns<string>;
function spawnSync(command: string, options: SpawnSyncOptionsWithBufferEncoding): SpawnSyncReturns<Buffer>;
function spawnSync(command: string, options?: SpawnSyncOptions): SpawnSyncReturns<string | Buffer>;
function spawnSync(command: string, args: readonly string[]): SpawnSyncReturns<Buffer>;
function spawnSync(command: string, options: SpawnSyncOptionsWithBufferEncoding): SpawnSyncReturns<NonSharedBuffer>;
function spawnSync(command: string, options?: SpawnSyncOptions): SpawnSyncReturns<string | NonSharedBuffer>;
function spawnSync(command: string, args: readonly string[]): SpawnSyncReturns<NonSharedBuffer>;
function spawnSync(
command: string,
args: readonly string[],
@@ -1442,12 +1370,12 @@ declare module "child_process" {
command: string,
args: readonly string[],
options: SpawnSyncOptionsWithBufferEncoding,
): SpawnSyncReturns<Buffer>;
): SpawnSyncReturns<NonSharedBuffer>;
function spawnSync(
command: string,
args?: readonly string[],
options?: SpawnSyncOptions,
): SpawnSyncReturns<string | Buffer>;
): SpawnSyncReturns<string | NonSharedBuffer>;
interface CommonExecOptions extends CommonOptions {
input?: string | NodeJS.ArrayBufferView | undefined;
/**
@@ -1489,10 +1417,10 @@ declare module "child_process" {
* @param command The command to run.
* @return The stdout from the command.
*/
function execSync(command: string): Buffer;
function execSync(command: string): NonSharedBuffer;
function execSync(command: string, options: ExecSyncOptionsWithStringEncoding): string;
function execSync(command: string, options: ExecSyncOptionsWithBufferEncoding): Buffer;
function execSync(command: string, options?: ExecSyncOptions): string | Buffer;
function execSync(command: string, options: ExecSyncOptionsWithBufferEncoding): NonSharedBuffer;
function execSync(command: string, options?: ExecSyncOptions): string | NonSharedBuffer;
interface ExecFileSyncOptions extends CommonExecOptions {
shell?: boolean | string | undefined;
}
@@ -1500,7 +1428,7 @@ declare module "child_process" {
encoding: BufferEncoding;
}
interface ExecFileSyncOptionsWithBufferEncoding extends ExecFileSyncOptions {
encoding?: "buffer" | null; // specify `null`.
encoding?: "buffer" | null | undefined; // specify `null`.
}
/**
* The `child_process.execFileSync()` method is generally identical to {@link execFile} with the exception that the method will not
@@ -1522,11 +1450,11 @@ declare module "child_process" {
* @param args List of string arguments.
* @return The stdout from the command.
*/
function execFileSync(file: string): Buffer;
function execFileSync(file: string): NonSharedBuffer;
function execFileSync(file: string, options: ExecFileSyncOptionsWithStringEncoding): string;
function execFileSync(file: string, options: ExecFileSyncOptionsWithBufferEncoding): Buffer;
function execFileSync(file: string, options?: ExecFileSyncOptions): string | Buffer;
function execFileSync(file: string, args: readonly string[]): Buffer;
function execFileSync(file: string, options: ExecFileSyncOptionsWithBufferEncoding): NonSharedBuffer;
function execFileSync(file: string, options?: ExecFileSyncOptions): string | NonSharedBuffer;
function execFileSync(file: string, args: readonly string[]): NonSharedBuffer;
function execFileSync(
file: string,
args: readonly string[],
@@ -1536,8 +1464,12 @@ declare module "child_process" {
file: string,
args: readonly string[],
options: ExecFileSyncOptionsWithBufferEncoding,
): Buffer;
function execFileSync(file: string, args?: readonly string[], options?: ExecFileSyncOptions): string | Buffer;
): NonSharedBuffer;
function execFileSync(
file: string,
args?: readonly string[],
options?: ExecFileSyncOptions,
): string | NonSharedBuffer;
}
declare module "node:child_process" {
export * from "child_process";

View File

@@ -1,7 +1,7 @@
/**
* Clusters of Node.js processes can be used to run multiple instances of Node.js
* that can distribute workloads among their application threads. When process isolation
* is not needed, use the [`worker_threads`](https://nodejs.org/docs/latest-v20.x/api/worker_threads.html)
* is not needed, use the [`worker_threads`](https://nodejs.org/docs/latest-v24.x/api/worker_threads.html)
* module instead, which allows running multiple application threads within a single Node.js instance.
*
* The cluster module allows easy creation of child processes that all share
@@ -50,7 +50,7 @@
* ```
*
* On Windows, it is not yet possible to set up a named pipe server in a worker.
* @see [source](https://github.com/nodejs/node/blob/v20.13.1/lib/cluster.js)
* @see [source](https://github.com/nodejs/node/blob/v24.x/lib/cluster.js)
*/
declare module "cluster" {
import * as child from "node:child_process";
@@ -72,7 +72,7 @@ declare module "cluster" {
* String arguments passed to worker.
* @default process.argv.slice(2)
*/
args?: string[] | undefined;
args?: readonly string[] | undefined;
/**
* Whether or not to send output to parent's stdio.
* @default false
@@ -80,8 +80,8 @@ declare module "cluster" {
silent?: boolean | undefined;
/**
* Configures the stdio of forked processes. Because the cluster module relies on IPC to function, this configuration must
* contain an `'ipc'` entry. When this option is provided, it overrides `silent`. See [`child_prcess.spawn()`](https://nodejs.org/docs/latest-v20.x/api/child_process.html#child_processspawncommand-args-options)'s
* [`stdio`](https://nodejs.org/docs/latest-v20.x/api/child_process.html#optionsstdio).
* contain an `'ipc'` entry. When this option is provided, it overrides `silent`. See [`child_prcess.spawn()`](https://nodejs.org/docs/latest-v24.x/api/child_process.html#child_processspawncommand-args-options)'s
* [`stdio`](https://nodejs.org/docs/latest-v24.x/api/child_process.html#optionsstdio).
*/
stdio?: any[] | undefined;
/**
@@ -99,7 +99,7 @@ declare module "cluster" {
inspectPort?: number | (() => number) | undefined;
/**
* Specify the kind of serialization used for sending messages between processes. Possible values are `'json'` and `'advanced'`.
* See [Advanced serialization for `child_process`](https://nodejs.org/docs/latest-v20.x/api/child_process.html#advanced-serialization) for more details.
* See [Advanced serialization for `child_process`](https://nodejs.org/docs/latest-v24.x/api/child_process.html#advanced-serialization) for more details.
* @default false
*/
serialization?: SerializationType | undefined;
@@ -142,10 +142,10 @@ declare module "cluster" {
*/
id: number;
/**
* All workers are created using [`child_process.fork()`](https://nodejs.org/docs/latest-v20.x/api/child_process.html#child_processforkmodulepath-args-options), the returned object
* All workers are created using [`child_process.fork()`](https://nodejs.org/docs/latest-v24.x/api/child_process.html#child_processforkmodulepath-args-options), the returned object
* from this function is stored as `.process`. In a worker, the global `process` is stored.
*
* See: [Child Process module](https://nodejs.org/docs/latest-v20.x/api/child_process.html#child_processforkmodulepath-args-options).
* See: [Child Process module](https://nodejs.org/docs/latest-v24.x/api/child_process.html#child_processforkmodulepath-args-options).
*
* Workers will call `process.exit(0)` if the `'disconnect'` event occurs
* on `process` and `.exitedAfterDisconnect` is not `true`. This protects against
@@ -156,7 +156,7 @@ declare module "cluster" {
/**
* Send a message to a worker or primary, optionally with a handle.
*
* In the primary, this sends a message to a specific worker. It is identical to [`ChildProcess.send()`](https://nodejs.org/docs/latest-v20.x/api/child_process.html#subprocesssendmessage-sendhandle-options-callback).
* In the primary, this sends a message to a specific worker. It is identical to [`ChildProcess.send()`](https://nodejs.org/docs/latest-v24.x/api/child_process.html#subprocesssendmessage-sendhandle-options-callback).
*
* In a worker, this sends a message to the primary. It is identical to `process.send()`.
*
@@ -198,7 +198,7 @@ declare module "cluster" {
* This method is aliased as `worker.destroy()` for backwards compatibility.
*
* In a worker, `process.kill()` exists, but it is not this function;
* it is [`kill()`](https://nodejs.org/docs/latest-v20.x/api/process.html#processkillpid-signal).
* it is [`kill()`](https://nodejs.org/docs/latest-v24.x/api/process.html#processkillpid-signal).
* @since v0.9.12
* @param [signal='SIGTERM'] Name of the kill signal to send to the worker process.
*/
@@ -231,6 +231,8 @@ declare module "cluster" {
* the `'disconnect'` event has not been emitted after some time.
*
* ```js
* import net from 'node:net';
*
* if (cluster.isPrimary) {
* const worker = cluster.fork();
* let timeout;
@@ -248,7 +250,6 @@ declare module "cluster" {
* });
*
* } else if (cluster.isWorker) {
* const net = require('node:net');
* const server = net.createServer((socket) => {
* // Connections never end
* });
@@ -265,7 +266,7 @@ declare module "cluster" {
* @since v0.7.7
* @return A reference to `worker`.
*/
disconnect(): void;
disconnect(): this;
/**
* This function returns `true` if the worker is connected to its primary via its
* IPC channel, `false` otherwise. A worker is connected to its primary after it
@@ -411,7 +412,7 @@ declare module "cluster" {
readonly isWorker: boolean;
/**
* The scheduling policy, either `cluster.SCHED_RR` for round-robin or `cluster.SCHED_NONE` to leave it to the operating system. This is a
* global setting and effectively frozen once either the first worker is spawned, or [`.setupPrimary()`](https://nodejs.org/docs/latest-v20.x/api/cluster.html#clustersetupprimarysettings)
* global setting and effectively frozen once either the first worker is spawned, or [`.setupPrimary()`](https://nodejs.org/docs/latest-v24.x/api/cluster.html#clustersetupprimarysettings)
* is called, whichever comes first.
*
* `SCHED_RR` is the default on all operating systems except Windows. Windows will change to `SCHED_RR` once libuv is able to effectively distribute
@@ -422,24 +423,24 @@ declare module "cluster" {
*/
schedulingPolicy: number;
/**
* After calling [`.setupPrimary()`](https://nodejs.org/docs/latest-v20.x/api/cluster.html#clustersetupprimarysettings)
* (or [`.fork()`](https://nodejs.org/docs/latest-v20.x/api/cluster.html#clusterforkenv)) this settings object will contain
* After calling [`.setupPrimary()`](https://nodejs.org/docs/latest-v24.x/api/cluster.html#clustersetupprimarysettings)
* (or [`.fork()`](https://nodejs.org/docs/latest-v24.x/api/cluster.html#clusterforkenv)) this settings object will contain
* the settings, including the default values.
*
* This object is not intended to be changed or set manually.
* @since v0.7.1
*/
readonly settings: ClusterSettings;
/** @deprecated since v16.0.0 - use [`.setupPrimary()`](https://nodejs.org/docs/latest-v20.x/api/cluster.html#clustersetupprimarysettings) instead. */
/** @deprecated since v16.0.0 - use [`.setupPrimary()`](https://nodejs.org/docs/latest-v24.x/api/cluster.html#clustersetupprimarysettings) instead. */
setupMaster(settings?: ClusterSettings): void;
/**
* `setupPrimary` is used to change the default 'fork' behavior. Once called, the settings will be present in `cluster.settings`.
*
* Any settings changes only affect future calls to [`.fork()`](https://nodejs.org/docs/latest-v20.x/api/cluster.html#clusterforkenv)
* Any settings changes only affect future calls to [`.fork()`](https://nodejs.org/docs/latest-v24.x/api/cluster.html#clusterforkenv)
* and have no effect on workers that are already running.
*
* The only attribute of a worker that cannot be set via `.setupPrimary()` is the `env` passed to
* [`.fork()`](https://nodejs.org/docs/latest-v20.x/api/cluster.html#clusterforkenv).
* [`.fork()`](https://nodejs.org/docs/latest-v24.x/api/cluster.html#clusterforkenv).
*
* The defaults above apply to the first call only; the defaults for later calls are the current values at the time of
* `cluster.setupPrimary()` is called.
@@ -480,7 +481,7 @@ declare module "cluster" {
* ```
* @since v0.7.0
*/
readonly worker?: Worker | undefined;
readonly worker?: Worker;
/**
* A hash that stores the active worker objects, keyed by `id` field. This makes it easy to loop through all the workers. It is only available in the primary process.
*
@@ -496,7 +497,7 @@ declare module "cluster" {
* ```
* @since v0.7.0
*/
readonly workers?: NodeJS.Dict<Worker> | undefined;
readonly workers?: NodeJS.Dict<Worker>;
readonly SCHED_NONE: number;
readonly SCHED_RR: number;
/**
@@ -549,10 +550,9 @@ declare module "cluster" {
prependListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): this;
prependListener(event: "fork", listener: (worker: Worker) => void): this;
prependListener(event: "listening", listener: (worker: Worker, address: Address) => void): this;
// the handle is a net.Socket or net.Server object, or undefined.
prependListener(
event: "message",
listener: (worker: Worker, message: any, handle?: net.Socket | net.Server) => void,
listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void,
): this;
prependListener(event: "online", listener: (worker: Worker) => void): this;
prependListener(event: "setup", listener: (settings: ClusterSettings) => void): this;

View File

@@ -5,12 +5,12 @@
* The module exports two specific components:
*
* * A `Console` class with methods such as `console.log()`, `console.error()`, and `console.warn()` that can be used to write to any Node.js stream.
* * A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v20.x/api/process.html#processstdout) and
* [`process.stderr`](https://nodejs.org/docs/latest-v20.x/api/process.html#processstderr). The global `console` can be used without calling `require('node:console')`.
* * A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstdout) and
* [`process.stderr`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module.
*
* _**Warning**_: The global console object's methods are neither consistently
* synchronous like the browser APIs they resemble, nor are they consistently
* asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v20.x/api/process.html#a-note-on-process-io) for
* asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v24.x/api/process.html#a-note-on-process-io) for
* more information.
*
* Example using the global `console`:
@@ -54,7 +54,7 @@
* myConsole.warn(`Danger ${name}! Danger!`);
* // Prints: Danger Will Robinson! Danger!, to err
* ```
* @see [source](https://github.com/nodejs/node/blob/v20.13.1/lib/console.js)
* @see [source](https://github.com/nodejs/node/blob/v24.x/lib/console.js)
*/
declare module "console" {
import console = require("node:console");
@@ -70,7 +70,7 @@ declare module "node:console" {
* `console.assert()` writes a message if `value` is [falsy](https://developer.mozilla.org/en-US/docs/Glossary/Falsy) or omitted. It only
* writes a message and does not otherwise affect execution. The output always
* starts with `"Assertion failed"`. If provided, `message` is formatted using
* [`util.format()`](https://nodejs.org/docs/latest-v20.x/api/util.html#utilformatformat-args).
* [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args).
*
* If `value` is [truthy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy), nothing happens.
*
@@ -152,7 +152,7 @@ declare module "node:console" {
*/
debug(message?: any, ...optionalParams: any[]): void;
/**
* Uses [`util.inspect()`](https://nodejs.org/docs/latest-v20.x/api/util.html#utilinspectobject-options) on `obj` and prints the resulting string to `stdout`.
* Uses [`util.inspect()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilinspectobject-options) on `obj` and prints the resulting string to `stdout`.
* This function bypasses any custom `inspect()` function defined on `obj`.
* @since v0.1.101
*/
@@ -167,7 +167,7 @@ declare module "node:console" {
* Prints to `stderr` with newline. Multiple arguments can be passed, with the
* first used as the primary message and all additional used as substitution
* values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html)
* (the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v20.x/api/util.html#utilformatformat-args)).
* (the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args)).
*
* ```js
* const code = 5;
@@ -178,8 +178,8 @@ declare module "node:console" {
* ```
*
* If formatting elements (e.g. `%d`) are not found in the first string then
* [`util.inspect()`](https://nodejs.org/docs/latest-v20.x/api/util.html#utilinspectobject-options) is called on each argument and the
* resulting string values are concatenated. See [`util.format()`](https://nodejs.org/docs/latest-v20.x/api/util.html#utilformatformat-args)
* [`util.inspect()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilinspectobject-options) is called on each argument and the
* resulting string values are concatenated. See [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args)
* for more information.
* @since v0.1.100
*/
@@ -211,7 +211,7 @@ declare module "node:console" {
* Prints to `stdout` with newline. Multiple arguments can be passed, with the
* first used as the primary message and all additional used as substitution
* values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html)
* (the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v20.x/api/util.html#utilformatformat-args)).
* (the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args)).
*
* ```js
* const count = 5;
@@ -221,7 +221,7 @@ declare module "node:console" {
* // Prints: count: 5, to stdout
* ```
*
* See [`util.format()`](https://nodejs.org/docs/latest-v20.x/api/util.html#utilformatformat-args) for more information.
* See [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args) for more information.
* @since v0.1.100
*/
log(message?: any, ...optionalParams: any[]): void;
@@ -297,7 +297,7 @@ declare module "node:console" {
*/
timeLog(label?: string, ...data: any[]): void;
/**
* Prints to `stderr` the string `'Trace: '`, followed by the [`util.format()`](https://nodejs.org/docs/latest-v20.x/api/util.html#utilformatformat-args)
* Prints to `stderr` the string `'Trace: '`, followed by the [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args)
* formatted message and stack trace to the current position in the code.
*
* ```js
@@ -361,12 +361,12 @@ declare module "node:console" {
* The module exports two specific components:
*
* * A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream.
* * A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v20.x/api/process.html#processstdout) and
* [`process.stderr`](https://nodejs.org/docs/latest-v20.x/api/process.html#processstderr). The global `console` can be used without calling `require('console')`.
* * A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstdout) and
* [`process.stderr`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module.
*
* _**Warning**_: The global console object's methods are neither consistently
* synchronous like the browser APIs they resemble, nor are they consistently
* asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v20.x/api/process.html#a-note-on-process-io) for
* asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v24.x/api/process.html#a-note-on-process-io) for
* more information.
*
* Example using the global `console`:
@@ -410,7 +410,7 @@ declare module "node:console" {
* myConsole.warn(`Danger ${name}! Danger!`);
* // Prints: Danger Will Robinson! Danger!, to err
* ```
* @see [source](https://github.com/nodejs/node/blob/v20.11.1/lib/console.js)
* @see [source](https://github.com/nodejs/node/blob/v24.x/lib/console.js)
*/
namespace console {
interface ConsoleConstructorOptions {
@@ -431,9 +431,10 @@ declare module "node:console" {
colorMode?: boolean | "auto" | undefined;
/**
* Specifies options that are passed along to
* [`util.inspect()`](https://nodejs.org/docs/latest-v20.x/api/util.html#utilinspectobject-options).
* `util.inspect()`. Can be an options object or, if different options
* for stdout and stderr are desired, a `Map` from stream objects to options.
*/
inspectOptions?: InspectOptions | undefined;
inspectOptions?: InspectOptions | ReadonlyMap<NodeJS.WritableStream, InspectOptions> | undefined;
/**
* Set group indentation.
* @default 2

View File

@@ -1,16 +1,18 @@
/** @deprecated since v6.3.0 - use constants property exposed by the relevant module instead. */
/**
* @deprecated The `node:constants` module is deprecated. When requiring access to constants
* relevant to specific Node.js builtin modules, developers should instead refer
* to the `constants` property exposed by the relevant module. For instance,
* `require('node:fs').constants` and `require('node:os').constants`.
*/
declare module "constants" {
import { constants as osConstants, SignalConstants } from "node:os";
import { constants as cryptoConstants } from "node:crypto";
import { constants as fsConstants } from "node:fs";
const exp:
& typeof osConstants.errno
& typeof osConstants.priority
& SignalConstants
& typeof cryptoConstants
& typeof fsConstants;
export = exp;
const constants:
& typeof import("node:os").constants.dlopen
& typeof import("node:os").constants.errno
& typeof import("node:os").constants.priority
& typeof import("node:os").constants.signals
& typeof import("node:fs").constants
& typeof import("node:crypto").constants;
export = constants;
}
declare module "node:constants" {

File diff suppressed because it is too large Load Diff

View File

@@ -23,10 +23,11 @@
* server.bind(41234);
* // Prints: server listening 0.0.0.0:41234
* ```
* @see [source](https://github.com/nodejs/node/blob/v20.13.1/lib/dgram.js)
* @see [source](https://github.com/nodejs/node/blob/v24.x/lib/dgram.js)
*/
declare module "dgram" {
import { AddressInfo } from "node:net";
import { NonSharedBuffer } from "node:buffer";
import { AddressInfo, BlockList } from "node:net";
import * as dns from "node:dns";
import { Abortable, EventEmitter } from "node:events";
interface RemoteInfo {
@@ -45,6 +46,7 @@ declare module "dgram" {
interface SocketOptions extends Abortable {
type: SocketType;
reuseAddr?: boolean | undefined;
reusePort?: boolean | undefined;
/**
* @default false
*/
@@ -58,6 +60,8 @@ declare module "dgram" {
callback: (err: NodeJS.ErrnoException | null, address: string, family: number) => void,
) => void)
| undefined;
receiveBlockList?: BlockList | undefined;
sendBlockList?: BlockList | undefined;
}
/**
* Creates a `dgram.Socket` object. Once the socket is created, calling `socket.bind()` will instruct the socket to begin listening for datagram
@@ -82,8 +86,8 @@ declare module "dgram" {
* @param options Available options are:
* @param callback Attached as a listener for `'message'` events. Optional.
*/
function createSocket(type: SocketType, callback?: (msg: Buffer, rinfo: RemoteInfo) => void): Socket;
function createSocket(options: SocketOptions, callback?: (msg: Buffer, rinfo: RemoteInfo) => void): Socket;
function createSocket(type: SocketType, callback?: (msg: NonSharedBuffer, rinfo: RemoteInfo) => void): Socket;
function createSocket(options: SocketOptions, callback?: (msg: NonSharedBuffer, rinfo: RemoteInfo) => void): Socket;
/**
* Encapsulates the datagram functionality.
*
@@ -352,22 +356,22 @@ declare module "dgram" {
* @param callback Called when the message has been sent.
*/
send(
msg: string | Uint8Array | readonly any[],
msg: string | NodeJS.ArrayBufferView | readonly any[],
port?: number,
address?: string,
callback?: (error: Error | null, bytes: number) => void,
): void;
send(
msg: string | Uint8Array | readonly any[],
msg: string | NodeJS.ArrayBufferView | readonly any[],
port?: number,
callback?: (error: Error | null, bytes: number) => void,
): void;
send(
msg: string | Uint8Array | readonly any[],
msg: string | NodeJS.ArrayBufferView | readonly any[],
callback?: (error: Error | null, bytes: number) => void,
): void;
send(
msg: string | Uint8Array,
msg: string | NodeJS.ArrayBufferView,
offset: number,
length: number,
port?: number,
@@ -375,14 +379,14 @@ declare module "dgram" {
callback?: (error: Error | null, bytes: number) => void,
): void;
send(
msg: string | Uint8Array,
msg: string | NodeJS.ArrayBufferView,
offset: number,
length: number,
port?: number,
callback?: (error: Error | null, bytes: number) => void,
): void;
send(
msg: string | Uint8Array,
msg: string | NodeJS.ArrayBufferView,
offset: number,
length: number,
callback?: (error: Error | null, bytes: number) => void,
@@ -553,37 +557,37 @@ declare module "dgram" {
addListener(event: "connect", listener: () => void): this;
addListener(event: "error", listener: (err: Error) => void): this;
addListener(event: "listening", listener: () => void): this;
addListener(event: "message", listener: (msg: Buffer, rinfo: RemoteInfo) => void): this;
addListener(event: "message", listener: (msg: NonSharedBuffer, rinfo: RemoteInfo) => void): this;
emit(event: string | symbol, ...args: any[]): boolean;
emit(event: "close"): boolean;
emit(event: "connect"): boolean;
emit(event: "error", err: Error): boolean;
emit(event: "listening"): boolean;
emit(event: "message", msg: Buffer, rinfo: RemoteInfo): boolean;
emit(event: "message", msg: NonSharedBuffer, rinfo: RemoteInfo): boolean;
on(event: string, listener: (...args: any[]) => void): this;
on(event: "close", listener: () => void): this;
on(event: "connect", listener: () => void): this;
on(event: "error", listener: (err: Error) => void): this;
on(event: "listening", listener: () => void): this;
on(event: "message", listener: (msg: Buffer, rinfo: RemoteInfo) => void): this;
on(event: "message", listener: (msg: NonSharedBuffer, rinfo: RemoteInfo) => void): this;
once(event: string, listener: (...args: any[]) => void): this;
once(event: "close", listener: () => void): this;
once(event: "connect", listener: () => void): this;
once(event: "error", listener: (err: Error) => void): this;
once(event: "listening", listener: () => void): this;
once(event: "message", listener: (msg: Buffer, rinfo: RemoteInfo) => void): this;
once(event: "message", listener: (msg: NonSharedBuffer, rinfo: RemoteInfo) => void): this;
prependListener(event: string, listener: (...args: any[]) => void): this;
prependListener(event: "close", listener: () => void): this;
prependListener(event: "connect", listener: () => void): this;
prependListener(event: "error", listener: (err: Error) => void): this;
prependListener(event: "listening", listener: () => void): this;
prependListener(event: "message", listener: (msg: Buffer, rinfo: RemoteInfo) => void): this;
prependListener(event: "message", listener: (msg: NonSharedBuffer, rinfo: RemoteInfo) => void): this;
prependOnceListener(event: string, listener: (...args: any[]) => void): this;
prependOnceListener(event: "close", listener: () => void): this;
prependOnceListener(event: "connect", listener: () => void): this;
prependOnceListener(event: "error", listener: (err: Error) => void): this;
prependOnceListener(event: "listening", listener: () => void): this;
prependOnceListener(event: "message", listener: (msg: Buffer, rinfo: RemoteInfo) => void): this;
prependOnceListener(event: "message", listener: (msg: NonSharedBuffer, rinfo: RemoteInfo) => void): this;
/**
* Calls `socket.close()` and returns a promise that fulfills when the socket has closed.
* @since v20.5.0

View File

@@ -20,7 +20,7 @@
* should generally include the module name to avoid collisions with data from
* other modules.
* @since v15.1.0, v14.17.0
* @see [source](https://github.com/nodejs/node/blob/v20.13.1/lib/diagnostics_channel.js)
* @see [source](https://github.com/nodejs/node/blob/v24.x/lib/diagnostics_channel.js)
*/
declare module "diagnostics_channel" {
import { AsyncLocalStorage } from "node:async_hooks";
@@ -189,7 +189,6 @@ declare module "diagnostics_channel" {
* });
* ```
* @since v15.1.0, v14.17.0
* @deprecated Since v18.7.0,v16.17.0 - Use {@link subscribe(name, onMessage)}
* @param onMessage The handler to receive channel messages
*/
subscribe(onMessage: ChannelListener): void;
@@ -210,7 +209,6 @@ declare module "diagnostics_channel" {
* channel.unsubscribe(onMessage);
* ```
* @since v15.1.0, v14.17.0
* @deprecated Since v18.7.0,v16.17.0 - Use {@link unsubscribe(name, onMessage)}
* @param onMessage The previous subscribed handler to remove
* @return `true` if the handler was found, `false` otherwise.
*/
@@ -259,7 +257,7 @@ declare module "diagnostics_channel" {
* @param store The store to unbind from the channel.
* @return `true` if the store was found, `false` otherwise.
*/
unbindStore(store: any): void;
unbindStore(store: AsyncLocalStorage<StoreType>): boolean;
/**
* Applies the given data to any AsyncLocalStorage instances bound to the channel
* for the duration of the given function, then publishes to the channel within
@@ -297,7 +295,12 @@ declare module "diagnostics_channel" {
* @param thisArg The receiver to be used for the function call.
* @param args Optional arguments to pass to the function.
*/
runStores(): void;
runStores<ThisArg = any, Args extends any[] = any[], Result = any>(
context: ContextType,
fn: (this: ThisArg, ...args: Args) => Result,
thisArg?: ThisArg,
...args: Args
): Result;
}
interface TracingChannelSubscribers<ContextType extends object> {
start: (message: ContextType) => void;
@@ -441,12 +444,12 @@ declare module "diagnostics_channel" {
* @param args Optional arguments to pass to the function
* @return The return value of the given function
*/
traceSync<ThisArg = any, Args extends any[] = any[]>(
fn: (this: ThisArg, ...args: Args) => any,
traceSync<ThisArg = any, Args extends any[] = any[], Result = any>(
fn: (this: ThisArg, ...args: Args) => Result,
context?: ContextType,
thisArg?: ThisArg,
...args: Args
): void;
): Result;
/**
* Trace a promise-returning function call. This will always produce a `start event` and `end event` around the synchronous portion of the
* function execution, and will produce an `asyncStart event` and `asyncEnd event` when a promise continuation is reached. It may also
@@ -476,12 +479,12 @@ declare module "diagnostics_channel" {
* @param args Optional arguments to pass to the function
* @return Chained from promise returned by the given function
*/
tracePromise<ThisArg = any, Args extends any[] = any[]>(
fn: (this: ThisArg, ...args: Args) => Promise<any>,
tracePromise<ThisArg = any, Args extends any[] = any[], Result = any>(
fn: (this: ThisArg, ...args: Args) => Promise<Result>,
context?: ContextType,
thisArg?: ThisArg,
...args: Args
): void;
): Promise<Result>;
/**
* Trace a callback-receiving function call. This will always produce a `start event` and `end event` around the synchronous portion of the
* function execution, and will produce a `asyncStart event` and `asyncEnd event` around the callback execution. It may also produce an `error event` if the given function throws an error or
@@ -540,13 +543,32 @@ declare module "diagnostics_channel" {
* @param args Optional arguments to pass to the function
* @return The return value of the given function
*/
traceCallback<Fn extends (this: any, ...args: any) => any>(
fn: Fn,
position: number | undefined,
context: ContextType | undefined,
thisArg: any,
...args: Parameters<Fn>
): void;
traceCallback<ThisArg = any, Args extends any[] = any[], Result = any>(
fn: (this: ThisArg, ...args: Args) => Result,
position?: number,
context?: ContextType,
thisArg?: ThisArg,
...args: Args
): Result;
/**
* `true` if any of the individual channels has a subscriber, `false` if not.
*
* This is a helper method available on a {@link TracingChannel} instance to check
* if any of the [TracingChannel Channels](https://nodejs.org/api/diagnostics_channel.html#tracingchannel-channels) have subscribers.
* A `true` is returned if any of them have at least one subscriber, a `false` is returned otherwise.
*
* ```js
* const diagnostics_channel = require('node:diagnostics_channel');
*
* const channels = diagnostics_channel.tracingChannel('my-channel');
*
* if (channels.hasSubscribers) {
* // Do something
* }
* ```
* @since v22.0.0, v20.13.0
*/
readonly hasSubscribers: boolean;
}
}
declare module "node:diagnostics_channel" {

View File

@@ -9,7 +9,7 @@
* system do, use {@link lookup}.
*
* ```js
* const dns = require('node:dns');
* import dns from 'node:dns';
*
* dns.lookup('example.org', (err, address, family) => {
* console.log('address: %j family: IPv%s', address, family);
@@ -23,7 +23,7 @@
* DNS queries, bypassing other name-resolution facilities.
*
* ```js
* const dns = require('node:dns');
* import dns from 'node:dns';
*
* dns.resolve4('archive.org', (err, addresses) => {
* if (err) throw err;
@@ -41,8 +41,8 @@
* });
* ```
*
* See the [Implementation considerations section](https://nodejs.org/docs/latest-v20.x/api/dns.html#implementation-considerations) for more information.
* @see [source](https://github.com/nodejs/node/blob/v20.13.1/lib/dns.js)
* See the [Implementation considerations section](https://nodejs.org/docs/latest-v24.x/api/dns.html#implementation-considerations) for more information.
* @see [source](https://github.com/nodejs/node/blob/v24.x/lib/dns.js)
*/
declare module "dns" {
import * as dnsPromises from "node:dns/promises";
@@ -71,7 +71,7 @@ declare module "dns" {
*/
family?: number | "IPv4" | "IPv6" | undefined;
/**
* One or more [supported `getaddrinfo`](https://nodejs.org/docs/latest-v20.x/api/dns.html#supported-getaddrinfo-flags) flags. Multiple flags may be
* One or more [supported `getaddrinfo`](https://nodejs.org/docs/latest-v24.x/api/dns.html#supported-getaddrinfo-flags) flags. Multiple flags may be
* passed by bitwise `OR`ing their values.
*/
hints?: number | undefined;
@@ -84,16 +84,17 @@ declare module "dns" {
* When `verbatim`, the resolved addresses are return unsorted. When `ipv4first`, the resolved addresses are sorted
* by placing IPv4 addresses before IPv6 addresses. When `ipv6first`, the resolved addresses are sorted by placing IPv6
* addresses before IPv4 addresses. Default value is configurable using
* {@link setDefaultResultOrder} or [`--dns-result-order`](https://nodejs.org/docs/latest-v20.x/api/cli.html#--dns-result-orderorder).
* {@link setDefaultResultOrder} or [`--dns-result-order`](https://nodejs.org/docs/latest-v24.x/api/cli.html#--dns-result-orderorder).
* @default `verbatim` (addresses are not reordered)
* @since v22.1.0
*/
order?: "ipv4first" | "ipv6first" | "verbatim" | undefined;
/**
* When `true`, the callback receives IPv4 and IPv6 addresses in the order the DNS resolver returned them. When `false`, IPv4
* addresses are placed before IPv6 addresses. This option will be deprecated in favor of `order`. When both are specified,
* `order` has higher precedence. New code should only use `order`. Default value is configurable using {@link setDefaultResultOrder}
* or [`--dns-result-order`](https://nodejs.org/docs/latest-v20.x/api/cli.html#--dns-result-orderorder).
* @default true (addresses are not reordered)
* @deprecated Please use `order` option
*/
verbatim?: boolean | undefined;
}
@@ -132,13 +133,13 @@ declare module "dns" {
* The implementation uses an operating system facility that can associate names
* with addresses and vice versa. This implementation can have subtle but
* important consequences on the behavior of any Node.js program. Please take some
* time to consult the [Implementation considerations section](https://nodejs.org/docs/latest-v20.x/api/dns.html#implementation-considerations)
* time to consult the [Implementation considerations section](https://nodejs.org/docs/latest-v24.x/api/dns.html#implementation-considerations)
* before using `dns.lookup()`.
*
* Example usage:
*
* ```js
* const dns = require('node:dns');
* import dns from 'node:dns';
* const options = {
* family: 6,
* hints: dns.ADDRCONFIG | dns.V4MAPPED,
@@ -154,7 +155,7 @@ declare module "dns" {
* // addresses: [{"address":"2606:2800:220:1:248:1893:25c8:1946","family":6}]
* ```
*
* If this method is invoked as its [util.promisify()](https://nodejs.org/docs/latest-v20.x/api/util.html#utilpromisifyoriginal) ed
* If this method is invoked as its [util.promisify()](https://nodejs.org/docs/latest-v24.x/api/util.html#utilpromisifyoriginal) ed
* version, and `all` is not set to `true`, it returns a `Promise` for an `Object` with `address` and `family` properties.
* @since v0.1.90
*/
@@ -194,18 +195,18 @@ declare module "dns" {
* If `address` is not a valid IP address, a `TypeError` will be thrown.
* The `port` will be coerced to a number. If it is not a legal port, a `TypeError` will be thrown.
*
* On an error, `err` is an [`Error`](https://nodejs.org/docs/latest-v20.x/api/errors.html#class-error) object,
* On an error, `err` is an [`Error`](https://nodejs.org/docs/latest-v24.x/api/errors.html#class-error) object,
* where `err.code` is the error code.
*
* ```js
* const dns = require('node:dns');
* import dns from 'node:dns';
* dns.lookupService('127.0.0.1', 22, (err, hostname, service) => {
* console.log(hostname, service);
* // Prints: localhost ssh
* });
* ```
*
* If this method is invoked as its [util.promisify()](https://nodejs.org/docs/latest-v20.x/api/util.html#utilpromisifyoriginal) ed
* If this method is invoked as its [util.promisify()](https://nodejs.org/docs/latest-v24.x/api/util.html#utilpromisifyoriginal) ed
* version, it returns a `Promise` for an `Object` with `hostname` and `service` properties.
* @since v0.11.14
*/
@@ -249,6 +250,9 @@ declare module "dns" {
contactemail?: string | undefined;
contactphone?: string | undefined;
}
export interface AnyCaaRecord extends CaaRecord {
type: "CAA";
}
export interface MxRecord {
priority: number;
exchange: string;
@@ -288,6 +292,15 @@ declare module "dns" {
export interface AnySrvRecord extends SrvRecord {
type: "SRV";
}
export interface TlsaRecord {
certUsage: number;
selector: number;
match: number;
data: ArrayBuffer;
}
export interface AnyTlsaRecord extends TlsaRecord {
type: "TLSA";
}
export interface AnyTxtRecord {
type: "TXT";
entries: string[];
@@ -307,6 +320,7 @@ declare module "dns" {
export type AnyRecord =
| AnyARecord
| AnyAaaaRecord
| AnyCaaRecord
| AnyCnameRecord
| AnyMxRecord
| AnyNaptrRecord
@@ -314,6 +328,7 @@ declare module "dns" {
| AnyPtrRecord
| AnySoaRecord
| AnySrvRecord
| AnyTlsaRecord
| AnyTxtRecord;
/**
* Uses the DNS protocol to resolve a host name (e.g. `'nodejs.org'`) into an array
@@ -322,7 +337,7 @@ declare module "dns" {
*
* <omitted>
*
* On error, `err` is an [`Error`](https://nodejs.org/docs/latest-v20.x/api/errors.html#class-error) object,
* On error, `err` is an [`Error`](https://nodejs.org/docs/latest-v24.x/api/errors.html#class-error) object,
* where `err.code` is one of the `DNS error codes`.
* @since v0.1.27
* @param hostname Host name to resolve.
@@ -334,12 +349,7 @@ declare module "dns" {
): void;
export function resolve(
hostname: string,
rrtype: "A",
callback: (err: NodeJS.ErrnoException | null, addresses: string[]) => void,
): void;
export function resolve(
hostname: string,
rrtype: "AAAA",
rrtype: "A" | "AAAA" | "CNAME" | "NS" | "PTR",
callback: (err: NodeJS.ErrnoException | null, addresses: string[]) => void,
): void;
export function resolve(
@@ -349,8 +359,8 @@ declare module "dns" {
): void;
export function resolve(
hostname: string,
rrtype: "CNAME",
callback: (err: NodeJS.ErrnoException | null, addresses: string[]) => void,
rrtype: "CAA",
callback: (err: NodeJS.ErrnoException | null, address: CaaRecord[]) => void,
): void;
export function resolve(
hostname: string,
@@ -362,16 +372,6 @@ declare module "dns" {
rrtype: "NAPTR",
callback: (err: NodeJS.ErrnoException | null, addresses: NaptrRecord[]) => void,
): void;
export function resolve(
hostname: string,
rrtype: "NS",
callback: (err: NodeJS.ErrnoException | null, addresses: string[]) => void,
): void;
export function resolve(
hostname: string,
rrtype: "PTR",
callback: (err: NodeJS.ErrnoException | null, addresses: string[]) => void,
): void;
export function resolve(
hostname: string,
rrtype: "SOA",
@@ -382,6 +382,11 @@ declare module "dns" {
rrtype: "SRV",
callback: (err: NodeJS.ErrnoException | null, addresses: SrvRecord[]) => void,
): void;
export function resolve(
hostname: string,
rrtype: "TLSA",
callback: (err: NodeJS.ErrnoException | null, addresses: TlsaRecord[]) => void,
): void;
export function resolve(
hostname: string,
rrtype: "TXT",
@@ -392,21 +397,42 @@ declare module "dns" {
rrtype: string,
callback: (
err: NodeJS.ErrnoException | null,
addresses: string[] | MxRecord[] | NaptrRecord[] | SoaRecord | SrvRecord[] | string[][] | AnyRecord[],
addresses:
| string[]
| CaaRecord[]
| MxRecord[]
| NaptrRecord[]
| SoaRecord
| SrvRecord[]
| TlsaRecord[]
| string[][]
| AnyRecord[],
) => void,
): void;
export namespace resolve {
function __promisify__(hostname: string, rrtype?: "A" | "AAAA" | "CNAME" | "NS" | "PTR"): Promise<string[]>;
function __promisify__(hostname: string, rrtype: "ANY"): Promise<AnyRecord[]>;
function __promisify__(hostname: string, rrtype: "CAA"): Promise<CaaRecord[]>;
function __promisify__(hostname: string, rrtype: "MX"): Promise<MxRecord[]>;
function __promisify__(hostname: string, rrtype: "NAPTR"): Promise<NaptrRecord[]>;
function __promisify__(hostname: string, rrtype: "SOA"): Promise<SoaRecord>;
function __promisify__(hostname: string, rrtype: "SRV"): Promise<SrvRecord[]>;
function __promisify__(hostname: string, rrtype: "TLSA"): Promise<TlsaRecord[]>;
function __promisify__(hostname: string, rrtype: "TXT"): Promise<string[][]>;
function __promisify__(
hostname: string,
rrtype: string,
): Promise<string[] | MxRecord[] | NaptrRecord[] | SoaRecord | SrvRecord[] | string[][] | AnyRecord[]>;
): Promise<
| string[]
| CaaRecord[]
| MxRecord[]
| NaptrRecord[]
| SoaRecord
| SrvRecord[]
| TlsaRecord[]
| string[][]
| AnyRecord[]
>;
}
/**
* Uses the DNS protocol to resolve a IPv4 addresses (`A` records) for the `hostname`. The `addresses` argument passed to the `callback` function
@@ -608,6 +634,33 @@ declare module "dns" {
export namespace resolveSrv {
function __promisify__(hostname: string): Promise<SrvRecord[]>;
}
/**
* Uses the DNS protocol to resolve certificate associations (`TLSA` records) for
* the `hostname`. The `records` argument passed to the `callback` function is an
* array of objects with these properties:
*
* * `certUsage`
* * `selector`
* * `match`
* * `data`
*
* ```js
* {
* certUsage: 3,
* selector: 1,
* match: 1,
* data: [ArrayBuffer]
* }
* ```
* @since v23.9.0, v22.15.0
*/
export function resolveTlsa(
hostname: string,
callback: (err: NodeJS.ErrnoException | null, addresses: TlsaRecord[]) => void,
): void;
export namespace resolveTlsa {
function __promisify__(hostname: string): Promise<TlsaRecord[]>;
}
/**
* Uses the DNS protocol to resolve text queries (`TXT` records) for the `hostname`. The `records` argument passed to the `callback` function is a
* two-dimensional array of the text records available for `hostname` (e.g.`[ ['v=spf1 ip4:0.0.0.0 ', '~all' ] ]`). Each sub-array contains TXT chunks of
@@ -663,8 +716,8 @@ declare module "dns" {
* Performs a reverse DNS query that resolves an IPv4 or IPv6 address to an
* array of host names.
*
* On error, `err` is an [`Error`](https://nodejs.org/docs/latest-v20.x/api/errors.html#class-error) object, where `err.code` is
* one of the [DNS error codes](https://nodejs.org/docs/latest-v20.x/api/dns.html#error-codes).
* On error, `err` is an [`Error`](https://nodejs.org/docs/latest-v24.x/api/errors.html#class-error) object, where `err.code` is
* one of the [DNS error codes](https://nodejs.org/docs/latest-v24.x/api/dns.html#error-codes).
* @since v0.1.16
*/
export function reverse(
@@ -672,7 +725,7 @@ declare module "dns" {
callback: (err: NodeJS.ErrnoException | null, hostnames: string[]) => void,
): void;
/**
* Get the default value for `order` in {@link lookup} and [`dnsPromises.lookup()`](https://nodejs.org/docs/latest-v20.x/api/dns.html#dnspromiseslookuphostname-options).
* Get the default value for `order` in {@link lookup} and [`dnsPromises.lookup()`](https://nodejs.org/docs/latest-v24.x/api/dns.html#dnspromiseslookuphostname-options).
* The value could be:
*
* * `ipv4first`: for `order` defaulting to `ipv4first`.
@@ -727,7 +780,7 @@ declare module "dns" {
*/
export function getServers(): string[];
/**
* Set the default value of `order` in {@link lookup} and [`dnsPromises.lookup()`](https://nodejs.org/docs/latest-v20.x/api/dns.html#dnspromiseslookuphostname-options).
* Set the default value of `order` in {@link lookup} and [`dnsPromises.lookup()`](https://nodejs.org/docs/latest-v24.x/api/dns.html#dnspromiseslookuphostname-options).
* The value could be:
*
* * `ipv4first`: sets default `order` to `ipv4first`.
@@ -735,8 +788,8 @@ declare module "dns" {
* * `verbatim`: sets default `order` to `verbatim`.
*
* The default is `verbatim` and {@link setDefaultResultOrder} have higher
* priority than [`--dns-result-order`](https://nodejs.org/docs/latest-v20.x/api/cli.html#--dns-result-orderorder). When using
* [worker threads](https://nodejs.org/docs/latest-v20.x/api/worker_threads.html), {@link setDefaultResultOrder} from the main
* priority than [`--dns-result-order`](https://nodejs.org/docs/latest-v24.x/api/cli.html#--dns-result-orderorder). When using
* [worker threads](https://nodejs.org/docs/latest-v24.x/api/worker_threads.html), {@link setDefaultResultOrder} from the main
* thread won't affect the default dns orders in workers.
* @since v16.4.0, v14.18.0
* @param order must be `'ipv4first'`, `'ipv6first'` or `'verbatim'`.
@@ -776,17 +829,22 @@ declare module "dns" {
* The number of tries the resolver will try contacting each name server before giving up.
* @default 4
*/
tries?: number;
tries?: number | undefined;
/**
* The max retry timeout, in milliseconds.
* @default 0
*/
maxTimeout?: number | undefined;
}
/**
* An independent resolver for DNS requests.
*
* Creating a new resolver uses the default server settings. Setting
* the servers used for a resolver using [`resolver.setServers()`](https://nodejs.org/docs/latest-v20.x/api/dns.html#dnssetserversservers) does not affect
* the servers used for a resolver using [`resolver.setServers()`](https://nodejs.org/docs/latest-v24.x/api/dns.html#dnssetserversservers) does not affect
* other resolvers:
*
* ```js
* const { Resolver } = require('node:dns');
* import { Resolver } from 'node:dns';
* const resolver = new Resolver();
* resolver.setServers(['4.4.4.4']);
*
@@ -837,6 +895,7 @@ declare module "dns" {
resolvePtr: typeof resolvePtr;
resolveSoa: typeof resolveSoa;
resolveSrv: typeof resolveSrv;
resolveTlsa: typeof resolveTlsa;
resolveTxt: typeof resolveTxt;
reverse: typeof reverse;
/**

View File

@@ -1,7 +1,7 @@
/**
* The `dns.promises` API provides an alternative set of asynchronous DNS methods
* that return `Promise` objects rather than using callbacks. The API is accessible
* via `require('node:dns').promises` or `require('node:dns/promises')`.
* via `import { promises as dnsPromises } from 'node:dns'` or `import dnsPromises from 'node:dns/promises'`.
* @since v10.6.0
*/
declare module "dns/promises" {
@@ -20,6 +20,7 @@ declare module "dns/promises" {
ResolveWithTtlOptions,
SoaRecord,
SrvRecord,
TlsaRecord,
} from "node:dns";
/**
* Returns an array of IP address strings, formatted according to [RFC 5952](https://tools.ietf.org/html/rfc5952#section-6),
@@ -60,7 +61,7 @@ declare module "dns/promises" {
* Example usage:
*
* ```js
* const dns = require('node:dns');
* import dns from 'node:dns';
* const dnsPromises = dns.promises;
* const options = {
* family: 6,
@@ -96,7 +97,7 @@ declare module "dns/promises" {
* On error, the `Promise` is rejected with an [`Error`](https://nodejs.org/docs/latest-v20.x/api/errors.html#class-error) object, where `err.code` is the error code.
*
* ```js
* const dnsPromises = require('node:dns').promises;
* import dnsPromises from 'node:dns';
* dnsPromises.lookupService('127.0.0.1', 22).then((result) => {
* console.log(result.hostname, result.service);
* // Prints: localhost ssh
@@ -126,22 +127,26 @@ declare module "dns/promises" {
* @param [rrtype='A'] Resource record type.
*/
function resolve(hostname: string): Promise<string[]>;
function resolve(hostname: string, rrtype: "A"): Promise<string[]>;
function resolve(hostname: string, rrtype: "AAAA"): Promise<string[]>;
function resolve(hostname: string, rrtype: "A" | "AAAA" | "CNAME" | "NS" | "PTR"): Promise<string[]>;
function resolve(hostname: string, rrtype: "ANY"): Promise<AnyRecord[]>;
function resolve(hostname: string, rrtype: "CAA"): Promise<CaaRecord[]>;
function resolve(hostname: string, rrtype: "CNAME"): Promise<string[]>;
function resolve(hostname: string, rrtype: "MX"): Promise<MxRecord[]>;
function resolve(hostname: string, rrtype: "NAPTR"): Promise<NaptrRecord[]>;
function resolve(hostname: string, rrtype: "NS"): Promise<string[]>;
function resolve(hostname: string, rrtype: "PTR"): Promise<string[]>;
function resolve(hostname: string, rrtype: "SOA"): Promise<SoaRecord>;
function resolve(hostname: string, rrtype: "SRV"): Promise<SrvRecord[]>;
function resolve(hostname: string, rrtype: "TLSA"): Promise<TlsaRecord[]>;
function resolve(hostname: string, rrtype: "TXT"): Promise<string[][]>;
function resolve(
hostname: string,
rrtype: string,
): Promise<string[] | MxRecord[] | NaptrRecord[] | SoaRecord | SrvRecord[] | string[][] | AnyRecord[]>;
function resolve(hostname: string, rrtype: string): Promise<
| string[]
| CaaRecord[]
| MxRecord[]
| NaptrRecord[]
| SoaRecord
| SrvRecord[]
| TlsaRecord[]
| string[][]
| AnyRecord[]
>;
/**
* Uses the DNS protocol to resolve IPv4 addresses (`A` records) for the `hostname`. On success, the `Promise` is resolved with an array of IPv4
* addresses (e.g. `['74.125.79.104', '74.125.79.105', '74.125.79.106']`).
@@ -292,6 +297,27 @@ declare module "dns/promises" {
* @since v10.6.0
*/
function resolveSrv(hostname: string): Promise<SrvRecord[]>;
/**
* Uses the DNS protocol to resolve certificate associations (`TLSA` records) for
* the `hostname`. On success, the `Promise` is resolved with an array of objectsAdd commentMore actions
* with these properties:
*
* * `certUsage`
* * `selector`
* * `match`
* * `data`
*
* ```js
* {
* certUsage: 3,
* selector: 1,
* match: 1,
* data: [ArrayBuffer]
* }
* ```
* @since v23.9.0, v22.15.0
*/
function resolveTlsa(hostname: string): Promise<TlsaRecord[]>;
/**
* Uses the DNS protocol to resolve text queries (`TXT` records) for the `hostname`. On success, the `Promise` is resolved with a two-dimensional array
* of the text records available for `hostname` (e.g.`[ ['v=spf1 ip4:0.0.0.0 ', '~all' ] ]`). Each sub-array contains TXT chunks of
@@ -394,8 +420,8 @@ declare module "dns/promises" {
* other resolvers:
*
* ```js
* const { Resolver } = require('node:dns').promises;
* const resolver = new Resolver();
* import { promises } from 'node:dns';
* const resolver = new promises.Resolver();
* resolver.setServers(['4.4.4.4']);
*
* // This request will use the server at 4.4.4.4, independent of global settings.
@@ -450,6 +476,7 @@ declare module "dns/promises" {
resolvePtr: typeof resolvePtr;
resolveSoa: typeof resolveSoa;
resolveSrv: typeof resolveSrv;
resolveTlsa: typeof resolveTlsa;
resolveTxt: typeof resolveTxt;
reverse: typeof reverse;
/**

View File

@@ -1,124 +0,0 @@
export {}; // Don't export anything!
//// DOM-like Events
// NB: The Event / EventTarget / EventListener implementations below were copied
// from lib.dom.d.ts, then edited to reflect Node's documentation at
// https://nodejs.org/api/events.html#class-eventtarget.
// Please read that link to understand important implementation differences.
// This conditional type will be the existing global Event in a browser, or
// the copy below in a Node environment.
type __Event = typeof globalThis extends { onmessage: any; Event: any } ? {}
: {
/** This is not used in Node.js and is provided purely for completeness. */
readonly bubbles: boolean;
/** Alias for event.stopPropagation(). This is not used in Node.js and is provided purely for completeness. */
cancelBubble: () => void;
/** True if the event was created with the cancelable option */
readonly cancelable: boolean;
/** This is not used in Node.js and is provided purely for completeness. */
readonly composed: boolean;
/** Returns an array containing the current EventTarget as the only entry or empty if the event is not being dispatched. This is not used in Node.js and is provided purely for completeness. */
composedPath(): [EventTarget?];
/** Alias for event.target. */
readonly currentTarget: EventTarget | null;
/** Is true if cancelable is true and event.preventDefault() has been called. */
readonly defaultPrevented: boolean;
/** This is not used in Node.js and is provided purely for completeness. */
readonly eventPhase: 0 | 2;
/** The `AbortSignal` "abort" event is emitted with `isTrusted` set to `true`. The value is `false` in all other cases. */
readonly isTrusted: boolean;
/** Sets the `defaultPrevented` property to `true` if `cancelable` is `true`. */
preventDefault(): void;
/** This is not used in Node.js and is provided purely for completeness. */
returnValue: boolean;
/** Alias for event.target. */
readonly srcElement: EventTarget | null;
/** Stops the invocation of event listeners after the current one completes. */
stopImmediatePropagation(): void;
/** This is not used in Node.js and is provided purely for completeness. */
stopPropagation(): void;
/** The `EventTarget` dispatching the event */
readonly target: EventTarget | null;
/** The millisecond timestamp when the Event object was created. */
readonly timeStamp: number;
/** Returns the type of event, e.g. "click", "hashchange", or "submit". */
readonly type: string;
};
// See comment above explaining conditional type
type __EventTarget = typeof globalThis extends { onmessage: any; EventTarget: any } ? {}
: {
/**
* Adds a new handler for the `type` event. Any given `listener` is added only once per `type` and per `capture` option value.
*
* If the `once` option is true, the `listener` is removed after the next time a `type` event is dispatched.
*
* The `capture` option is not used by Node.js in any functional way other than tracking registered event listeners per the `EventTarget` specification.
* Specifically, the `capture` option is used as part of the key when registering a `listener`.
* Any individual `listener` may be added once with `capture = false`, and once with `capture = true`.
*/
addEventListener(
type: string,
listener: EventListener | EventListenerObject,
options?: AddEventListenerOptions | boolean,
): void;
/** Dispatches a synthetic event event to target and returns true if either event's cancelable attribute value is false or its preventDefault() method was not invoked, and false otherwise. */
dispatchEvent(event: Event): boolean;
/** Removes the event listener in target's event listener list with the same type, callback, and options. */
removeEventListener(
type: string,
listener: EventListener | EventListenerObject,
options?: EventListenerOptions | boolean,
): void;
};
interface EventInit {
bubbles?: boolean;
cancelable?: boolean;
composed?: boolean;
}
interface EventListenerOptions {
/** Not directly used by Node.js. Added for API completeness. Default: `false`. */
capture?: boolean;
}
interface AddEventListenerOptions extends EventListenerOptions {
/** When `true`, the listener is automatically removed when it is first invoked. Default: `false`. */
once?: boolean;
/** When `true`, serves as a hint that the listener will not call the `Event` object's `preventDefault()` method. Default: false. */
passive?: boolean;
/** The listener will be removed when the given AbortSignal object's `abort()` method is called. */
signal?: AbortSignal;
}
interface EventListener {
(evt: Event): void;
}
interface EventListenerObject {
handleEvent(object: Event): void;
}
import {} from "events"; // Make this an ambient declaration
declare global {
/** An event which takes place in the DOM. */
interface Event extends __Event {}
var Event: typeof globalThis extends { onmessage: any; Event: infer T } ? T
: {
prototype: __Event;
new(type: string, eventInitDict?: EventInit): __Event;
};
/**
* EventTarget is a DOM interface implemented by objects that can
* receive events and may have listeners for them.
*/
interface EventTarget extends __EventTarget {}
var EventTarget: typeof globalThis extends { onmessage: any; EventTarget: infer T } ? T
: {
prototype: __EventTarget;
new(): __EventTarget;
};
}

View File

@@ -12,7 +12,7 @@
* will be notified, rather than losing the context of the error in the `process.on('uncaughtException')` handler, or causing the program to
* exit immediately with an error code.
* @deprecated Since v1.4.2 - Deprecated
* @see [source](https://github.com/nodejs/node/blob/v20.13.1/lib/domain.js)
* @see [source](https://github.com/nodejs/node/blob/v24.x/lib/domain.js)
*/
declare module "domain" {
import EventEmitter = require("node:events");
@@ -63,8 +63,8 @@ declare module "domain" {
* This is the most basic way to use a domain.
*
* ```js
* const domain = require('node:domain');
* const fs = require('node:fs');
* import domain from 'node:domain';
* import fs from 'node:fs';
* const d = domain.create();
* d.on('error', (er) => {
* console.error('Caught error!', er);

View File

@@ -32,43 +32,10 @@
* });
* myEmitter.emit('event');
* ```
* @see [source](https://github.com/nodejs/node/blob/v20.13.1/lib/events.js)
* @see [source](https://github.com/nodejs/node/blob/v24.x/lib/events.js)
*/
declare module "events" {
import { AsyncResource, AsyncResourceOptions } from "node:async_hooks";
// NOTE: This class is in the docs but is **not actually exported** by Node.
// If https://github.com/nodejs/node/issues/39903 gets resolved and Node
// actually starts exporting the class, uncomment below.
// import { EventListener, EventListenerObject } from '__dom-events';
// /** The NodeEventTarget is a Node.js-specific extension to EventTarget that emulates a subset of the EventEmitter API. */
// interface NodeEventTarget extends EventTarget {
// /**
// * Node.js-specific extension to the `EventTarget` class that emulates the equivalent `EventEmitter` API.
// * The only difference between `addListener()` and `addEventListener()` is that addListener() will return a reference to the EventTarget.
// */
// addListener(type: string, listener: EventListener | EventListenerObject, options?: { once: boolean }): this;
// /** Node.js-specific extension to the `EventTarget` class that returns an array of event `type` names for which event listeners are registered. */
// eventNames(): string[];
// /** Node.js-specific extension to the `EventTarget` class that returns the number of event listeners registered for the `type`. */
// listenerCount(type: string): number;
// /** Node.js-specific alias for `eventTarget.removeListener()`. */
// off(type: string, listener: EventListener | EventListenerObject): this;
// /** Node.js-specific alias for `eventTarget.addListener()`. */
// on(type: string, listener: EventListener | EventListenerObject, options?: { once: boolean }): this;
// /** Node.js-specific extension to the `EventTarget` class that adds a `once` listener for the given event `type`. This is equivalent to calling `on` with the `once` option set to `true`. */
// once(type: string, listener: EventListener | EventListenerObject): this;
// /**
// * Node.js-specific extension to the `EventTarget` class.
// * If `type` is specified, removes all registered listeners for `type`,
// * otherwise removes all registered listeners.
// */
// removeAllListeners(type: string): this;
// /**
// * Node.js-specific extension to the `EventTarget` class that removes the listener for the given `type`.
// * The only difference between `removeListener()` and `removeEventListener()` is that `removeListener()` will return a reference to the `EventTarget`.
// */
// removeListener(type: string, listener: EventListener | EventListenerObject): this;
// }
interface EventEmitterOptions {
/**
* Enables automatic capturing of promise rejection.
@@ -304,12 +271,12 @@ declare module "events" {
emitter: NodeJS.EventEmitter,
eventName: string | symbol,
options?: StaticEventEmitterIteratorOptions,
): AsyncIterableIterator<any[]>;
): NodeJS.AsyncIterator<any[]>;
static on(
emitter: EventTarget,
eventName: string,
options?: StaticEventEmitterIteratorOptions,
): AsyncIterableIterator<any[]>;
): NodeJS.AsyncIterator<any[]>;
/**
* A class method that returns the number of listeners for the given `eventName` registered on the given `emitter`.
*
@@ -396,7 +363,7 @@ declare module "events" {
* ```
* @since v15.4.0
* @param n A non-negative number. The maximum number of listeners per `EventTarget` event.
* @param eventsTargets Zero or more {EventTarget} or {EventEmitter} instances. If none are specified, `n` is set as the default max for all newly created {EventTarget} and {EventEmitter}
* @param eventTargets Zero or more {EventTarget} or {EventEmitter} instances. If none are specified, `n` is set as the default max for all newly created {EventTarget} and {EventEmitter}
* objects.
*/
static setMaxListeners(n?: number, ...eventTargets: Array<EventTarget | NodeJS.EventEmitter>): void;
@@ -431,7 +398,6 @@ declare module "events" {
* }
* ```
* @since v20.5.0
* @experimental
* @return Disposable that removes the `abort` listener.
*/
static addAbortListener(signal: AbortSignal, resource: (event: Event) => void): Disposable;
@@ -518,7 +484,7 @@ declare module "events" {
* directly rather than as a child class.
* @default new.target.name if instantiated as a child class.
*/
name?: string;
name?: string | undefined;
}
/**
@@ -585,6 +551,85 @@ declare module "events" {
*/
readonly asyncResource: EventEmitterReferencingAsyncResource;
}
/**
* The `NodeEventTarget` is a Node.js-specific extension to `EventTarget`
* that emulates a subset of the `EventEmitter` API.
* @since v14.5.0
*/
export interface NodeEventTarget extends EventTarget {
/**
* Node.js-specific extension to the `EventTarget` class that emulates the
* equivalent `EventEmitter` API. The only difference between `addListener()` and
* `addEventListener()` is that `addListener()` will return a reference to the
* `EventTarget`.
* @since v14.5.0
*/
addListener(type: string, listener: (arg: any) => void): this;
/**
* Node.js-specific extension to the `EventTarget` class that dispatches the
* `arg` to the list of handlers for `type`.
* @since v15.2.0
* @returns `true` if event listeners registered for the `type` exist,
* otherwise `false`.
*/
emit(type: string, arg: any): boolean;
/**
* Node.js-specific extension to the `EventTarget` class that returns an array
* of event `type` names for which event listeners are registered.
* @since 14.5.0
*/
eventNames(): string[];
/**
* Node.js-specific extension to the `EventTarget` class that returns the number
* of event listeners registered for the `type`.
* @since v14.5.0
*/
listenerCount(type: string): number;
/**
* Node.js-specific extension to the `EventTarget` class that sets the number
* of max event listeners as `n`.
* @since v14.5.0
*/
setMaxListeners(n: number): void;
/**
* Node.js-specific extension to the `EventTarget` class that returns the number
* of max event listeners.
* @since v14.5.0
*/
getMaxListeners(): number;
/**
* Node.js-specific alias for `eventTarget.removeEventListener()`.
* @since v14.5.0
*/
off(type: string, listener: (arg: any) => void, options?: EventListenerOptions): this;
/**
* Node.js-specific alias for `eventTarget.addEventListener()`.
* @since v14.5.0
*/
on(type: string, listener: (arg: any) => void): this;
/**
* Node.js-specific extension to the `EventTarget` class that adds a `once`
* listener for the given event `type`. This is equivalent to calling `on`
* with the `once` option set to `true`.
* @since v14.5.0
*/
once(type: string, listener: (arg: any) => void): this;
/**
* Node.js-specific extension to the `EventTarget` class. If `type` is specified,
* removes all registered listeners for `type`, otherwise removes all registered
* listeners.
* @since v14.5.0
*/
removeAllListeners(type?: string): this;
/**
* Node.js-specific extension to the `EventTarget` class that removes the
* `listener` for the given `type`. The only difference between `removeListener()`
* and `removeEventListener()` is that `removeListener()` will return a reference
* to the `EventTarget`.
* @since v14.5.0
*/
removeListener(type: string, listener: (arg: any) => void, options?: EventListenerOptions): this;
}
}
global {
namespace NodeJS {
@@ -768,7 +813,7 @@ declare module "events" {
setMaxListeners(n: number): this;
/**
* Returns the current max listener value for the `EventEmitter` which is either
* set by `emitter.setMaxListeners(n)` or defaults to {@link defaultMaxListeners}.
* set by `emitter.setMaxListeners(n)` or defaults to {@link EventEmitter.defaultMaxListeners}.
* @since v1.0.0
*/
getMaxListeners(): number;

File diff suppressed because it is too large Load Diff

View File

@@ -9,6 +9,7 @@
* @since v10.0.0
*/
declare module "fs/promises" {
import { NonSharedBuffer } from "node:buffer";
import { Abortable } from "node:events";
import { Stream } from "node:stream";
import { ReadableStream } from "node:stream/web";
@@ -20,12 +21,20 @@ declare module "fs/promises" {
CopyOptions,
Dir,
Dirent,
DisposableTempDir,
EncodingOption,
GlobOptions,
GlobOptionsWithFileTypes,
GlobOptionsWithoutFileTypes,
MakeDirectoryOptions,
Mode,
ObjectEncodingOptions,
OpenDirOptions,
OpenMode,
PathLike,
ReadOptions,
ReadOptionsWithBuffer,
ReadPosition,
ReadStream,
ReadVResult,
RmDirOptions,
@@ -36,7 +45,7 @@ declare module "fs/promises" {
StatsFs,
TimeLike,
WatchEventType,
WatchOptions,
WatchOptions as _WatchOptions,
WriteStream,
WriteVResult,
} from "node:fs";
@@ -53,6 +62,7 @@ declare module "fs/promises" {
bytesRead: number;
buffer: T;
}
/** @deprecated This interface will be removed in a future version. Use `import { ReadOptionsWithBuffer } from "node:fs"` instead. */
interface FileReadOptions<T extends NodeJS.ArrayBufferView = Buffer> {
/**
* @default `Buffer.alloc(0xffff)`
@@ -66,9 +76,9 @@ declare module "fs/promises" {
* @default `buffer.byteLength`
*/
length?: number | null;
position?: number | null;
position?: ReadPosition | null;
}
interface CreateReadStreamOptions {
interface CreateReadStreamOptions extends Abortable {
encoding?: BufferEncoding | null | undefined;
autoClose?: boolean | undefined;
emitClose?: boolean | undefined;
@@ -85,11 +95,7 @@ declare module "fs/promises" {
flush?: boolean | undefined;
}
interface ReadableWebStreamOptions {
/**
* Whether to open a normal or a `'bytes'` stream.
* @since v20.0.0
*/
type?: "bytes" | undefined;
autoClose?: boolean | undefined;
}
// TODO: Add `EventEmitter` close
interface FileHandle {
@@ -109,7 +115,7 @@ declare module "fs/promises" {
appendFile(
data: string | Uint8Array,
options?:
| (ObjectEncodingOptions & FlagAndOpenMode & { flush?: boolean | undefined })
| (ObjectEncodingOptions & Abortable)
| BufferEncoding
| null,
): Promise<void>;
@@ -233,11 +239,18 @@ declare module "fs/promises" {
buffer: T,
offset?: number | null,
length?: number | null,
position?: number | null,
position?: ReadPosition | null,
): Promise<FileReadResult<T>>;
read<T extends NodeJS.ArrayBufferView>(
buffer: T,
options?: ReadOptions,
): Promise<FileReadResult<T>>;
read<T extends NodeJS.ArrayBufferView = NonSharedBuffer>(
options?: ReadOptionsWithBuffer<T>,
): Promise<FileReadResult<T>>;
read<T extends NodeJS.ArrayBufferView = Buffer>(options?: FileReadOptions<T>): Promise<FileReadResult<T>>;
/**
* Returns a `ReadableStream` that may be used to read the files data.
* Returns a byte-oriented `ReadableStream` that may be used to read the file's
* contents.
*
* An error will be thrown if this method is called more than once or is called
* after the `FileHandle` is closed or closing.
@@ -258,7 +271,6 @@ declare module "fs/promises" {
* While the `ReadableStream` will read the file to completion, it will not
* close the `FileHandle` automatically. User code must still call the`fileHandle.close()` method.
* @since v17.0.0
* @experimental
*/
readableWebStream(options?: ReadableWebStreamOptions): ReadableStream;
/**
@@ -276,39 +288,29 @@ declare module "fs/promises" {
* data will be a string.
*/
readFile(
options?: {
encoding?: null | undefined;
flag?: OpenMode | undefined;
} | null,
): Promise<Buffer>;
options?:
| ({ encoding?: null | undefined } & Abortable)
| null,
): Promise<NonSharedBuffer>;
/**
* Asynchronously reads the entire contents of a file. The underlying file will _not_ be closed automatically.
* The `FileHandle` must have been opened for reading.
* @param options An object that may contain an optional flag.
* If a flag is not provided, it defaults to `'r'`.
*/
readFile(
options:
| {
encoding: BufferEncoding;
flag?: OpenMode | undefined;
}
| ({ encoding: BufferEncoding } & Abortable)
| BufferEncoding,
): Promise<string>;
/**
* Asynchronously reads the entire contents of a file. The underlying file will _not_ be closed automatically.
* The `FileHandle` must have been opened for reading.
* @param options An object that may contain an optional flag.
* If a flag is not provided, it defaults to `'r'`.
*/
readFile(
options?:
| (ObjectEncodingOptions & {
flag?: OpenMode | undefined;
})
| (ObjectEncodingOptions & Abortable)
| BufferEncoding
| null,
): Promise<string | Buffer>;
): Promise<string | NonSharedBuffer>;
/**
* Convenience method to create a `readline` interface and stream over the file.
* See `filehandle.createReadStream()` for the options.
@@ -395,7 +397,7 @@ declare module "fs/promises" {
writeFile(
data: string | Uint8Array,
options?:
| (ObjectEncodingOptions & FlagAndOpenMode & Abortable & { flush?: boolean | undefined })
| (ObjectEncodingOptions & Abortable)
| BufferEncoding
| null,
): Promise<void>;
@@ -417,7 +419,7 @@ declare module "fs/promises" {
* @param [position='null'] The offset from the beginning of the file where the data from `buffer` should be written. If `position` is not a `number`, the data will be written at the current
* position. See the POSIX pwrite(2) documentation for more detail.
*/
write<TBuffer extends Uint8Array>(
write<TBuffer extends NodeJS.ArrayBufferView>(
buffer: TBuffer,
offset?: number | null,
length?: number | null,
@@ -426,6 +428,13 @@ declare module "fs/promises" {
bytesWritten: number;
buffer: TBuffer;
}>;
write<TBuffer extends Uint8Array>(
buffer: TBuffer,
options?: { offset?: number; length?: number; position?: number },
): Promise<{
bytesWritten: number;
buffer: TBuffer;
}>;
write(
data: string,
position?: number | null,
@@ -449,14 +458,20 @@ declare module "fs/promises" {
* @param [position='null'] The offset from the beginning of the file where the data from `buffers` should be written. If `position` is not a `number`, the data will be written at the current
* position.
*/
writev(buffers: readonly NodeJS.ArrayBufferView[], position?: number): Promise<WriteVResult>;
writev<TBuffers extends readonly NodeJS.ArrayBufferView[]>(
buffers: TBuffers,
position?: number,
): Promise<WriteVResult<TBuffers>>;
/**
* Read from a file and write to an array of [ArrayBufferView](https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView) s
* @since v13.13.0, v12.17.0
* @param [position='null'] The offset from the beginning of the file where the data should be read from. If `position` is not a `number`, the data will be read from the current position.
* @return Fulfills upon success an object containing two properties:
*/
readv(buffers: readonly NodeJS.ArrayBufferView[], position?: number): Promise<ReadVResult>;
readv<TBuffers extends readonly NodeJS.ArrayBufferView[]>(
buffers: TBuffers,
position?: number,
): Promise<ReadVResult<TBuffers>>;
/**
* Closes the file handle after waiting for any pending operation on the handle to
* complete.
@@ -476,8 +491,9 @@ declare module "fs/promises" {
*/
close(): Promise<void>;
/**
* An alias for {@link FileHandle.close()}.
* @since v20.4.0
* Calls `filehandle.close()` and returns a promise that fulfills when the
* filehandle is closed.
* @since v20.4.0, v18.8.0
*/
[Symbol.asyncDispose](): Promise<void>;
}
@@ -692,7 +708,7 @@ declare module "fs/promises" {
recursive?: boolean | undefined;
}
| "buffer",
): Promise<Buffer[]>;
): Promise<NonSharedBuffer[]>;
/**
* Asynchronous readdir(3) - read a directory.
* @param path A path to a file. If a URL is provided, it must use the `file:` protocol.
@@ -707,7 +723,7 @@ declare module "fs/promises" {
})
| BufferEncoding
| null,
): Promise<string[] | Buffer[]>;
): Promise<string[] | NonSharedBuffer[]>;
/**
* Asynchronous readdir(3) - read a directory.
* @param path A path to a file. If a URL is provided, it must use the `file:` protocol.
@@ -720,6 +736,19 @@ declare module "fs/promises" {
recursive?: boolean | undefined;
},
): Promise<Dirent[]>;
/**
* Asynchronous readdir(3) - read a directory.
* @param path A path to a directory. If a URL is provided, it must use the `file:` protocol.
* @param options Must include `withFileTypes: true` and `encoding: 'buffer'`.
*/
function readdir(
path: PathLike,
options: {
encoding: "buffer";
withFileTypes: true;
recursive?: boolean | undefined;
},
): Promise<Dirent<NonSharedBuffer>[]>;
/**
* Reads the contents of the symbolic link referred to by `path`. See the POSIX [`readlink(2)`](http://man7.org/linux/man-pages/man2/readlink.2.html) documentation for more detail. The promise is
* fulfilled with the`linkString` upon success.
@@ -737,13 +766,16 @@ declare module "fs/promises" {
* @param path A path to a file. If a URL is provided, it must use the `file:` protocol.
* @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used.
*/
function readlink(path: PathLike, options: BufferEncodingOption): Promise<Buffer>;
function readlink(path: PathLike, options: BufferEncodingOption): Promise<NonSharedBuffer>;
/**
* Asynchronous readlink(2) - read value of a symbolic link.
* @param path A path to a file. If a URL is provided, it must use the `file:` protocol.
* @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used.
*/
function readlink(path: PathLike, options?: ObjectEncodingOptions | string | null): Promise<string | Buffer>;
function readlink(
path: PathLike,
options?: ObjectEncodingOptions | string | null,
): Promise<string | NonSharedBuffer>;
/**
* Creates a symbolic link.
*
@@ -894,7 +926,7 @@ declare module "fs/promises" {
* @param path A path to a file. If a URL is provided, it must use the `file:` protocol.
* @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used.
*/
function realpath(path: PathLike, options: BufferEncodingOption): Promise<Buffer>;
function realpath(path: PathLike, options: BufferEncodingOption): Promise<NonSharedBuffer>;
/**
* Asynchronous realpath(3) - return the canonicalized absolute pathname.
* @param path A path to a file. If a URL is provided, it must use the `file:` protocol.
@@ -903,7 +935,7 @@ declare module "fs/promises" {
function realpath(
path: PathLike,
options?: ObjectEncodingOptions | BufferEncoding | null,
): Promise<string | Buffer>;
): Promise<string | NonSharedBuffer>;
/**
* Creates a unique temporary directory. A unique directory name is generated by
* appending six random characters to the end of the provided `prefix`. Due to
@@ -929,7 +961,7 @@ declare module "fs/promises" {
* The `fsPromises.mkdtemp()` method will append the six randomly selected
* characters directly to the `prefix` string. For instance, given a directory `/tmp`, if the intention is to create a temporary directory _within_ `/tmp`, the `prefix` must end with a trailing
* platform-specific path separator
* (`require('node:path').sep`).
* (`import { sep } from 'node:path'`).
* @since v10.0.0
* @return Fulfills with a string containing the file system path of the newly created temporary directory.
*/
@@ -939,13 +971,36 @@ declare module "fs/promises" {
* Generates six random characters to be appended behind a required `prefix` to create a unique temporary directory.
* @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used.
*/
function mkdtemp(prefix: string, options: BufferEncodingOption): Promise<Buffer>;
function mkdtemp(prefix: string, options: BufferEncodingOption): Promise<NonSharedBuffer>;
/**
* Asynchronously creates a unique temporary directory.
* Generates six random characters to be appended behind a required `prefix` to create a unique temporary directory.
* @param options The encoding (or an object specifying the encoding), used as the encoding of the result. If not provided, `'utf8'` is used.
*/
function mkdtemp(prefix: string, options?: ObjectEncodingOptions | BufferEncoding | null): Promise<string | Buffer>;
function mkdtemp(
prefix: string,
options?: ObjectEncodingOptions | BufferEncoding | null,
): Promise<string | NonSharedBuffer>;
/**
* The resulting Promise holds an async-disposable object whose `path` property
* holds the created directory path. When the object is disposed, the directory
* and its contents will be removed asynchronously if it still exists. If the
* directory cannot be deleted, disposal will throw an error. The object has an
* async `remove()` method which will perform the same task.
*
* Both this function and the disposal function on the resulting object are
* async, so it should be used with `await` + `await using` as in
* `await using dir = await fsPromises.mkdtempDisposable('prefix')`.
*
* <!-- TODO: link MDN docs for disposables once https://github.com/mdn/content/pull/38027 lands -->
*
* For detailed information, see the documentation of `fsPromises.mkdtemp()`.
*
* The optional `options` argument can be a string specifying an encoding, or an
* object with an `encoding` property specifying the character encoding to use.
* @since v24.4.0
*/
function mkdtempDisposable(prefix: PathLike, options?: EncodingOption): Promise<DisposableTempDir>;
/**
* Asynchronously writes data to a file, replacing the file if it already exists. `data` can be a string, a buffer, an
* [AsyncIterable](https://tc39.github.io/ecma262/#sec-asynciterable-interface), or an
@@ -1101,7 +1156,7 @@ declare module "fs/promises" {
flag?: OpenMode | undefined;
} & Abortable)
| null,
): Promise<Buffer>;
): Promise<NonSharedBuffer>;
/**
* Asynchronously reads the entire contents of a file.
* @param path A path to a file. If a URL is provided, it must use the `file:` protocol.
@@ -1137,7 +1192,7 @@ declare module "fs/promises" {
)
| BufferEncoding
| null,
): Promise<string | Buffer>;
): Promise<string | NonSharedBuffer>;
/**
* Asynchronously open a directory for iterative scanning. See the POSIX [`opendir(3)`](http://man7.org/linux/man-pages/man3/opendir.3.html) documentation for more detail.
*
@@ -1167,11 +1222,21 @@ declare module "fs/promises" {
* @return Fulfills with an {fs.Dir}.
*/
function opendir(path: PathLike, options?: OpenDirOptions): Promise<Dir>;
interface WatchOptions extends _WatchOptions {
maxQueue?: number | undefined;
overflow?: "ignore" | "throw" | undefined;
}
interface WatchOptionsWithBufferEncoding extends WatchOptions {
encoding: "buffer";
}
interface WatchOptionsWithStringEncoding extends WatchOptions {
encoding?: BufferEncoding | undefined;
}
/**
* Returns an async iterator that watches for changes on `filename`, where `filename`is either a file or a directory.
*
* ```js
* const { watch } = require('node:fs/promises');
* import { watch } from 'node:fs/promises';
*
* const ac = new AbortController();
* const { signal } = ac;
@@ -1199,33 +1264,16 @@ declare module "fs/promises" {
*/
function watch(
filename: PathLike,
options:
| (WatchOptions & {
encoding: "buffer";
})
| "buffer",
): AsyncIterable<FileChangeInfo<Buffer>>;
/**
* Watch for changes on `filename`, where `filename` is either a file or a directory, returning an `FSWatcher`.
* @param filename A path to a file or directory. If a URL is provided, it must use the `file:` protocol.
* @param options Either the encoding for the filename provided to the listener, or an object optionally specifying encoding, persistent, and recursive options.
* If `encoding` is not supplied, the default of `'utf8'` is used.
* If `persistent` is not supplied, the default of `true` is used.
* If `recursive` is not supplied, the default of `false` is used.
*/
function watch(filename: PathLike, options?: WatchOptions | BufferEncoding): AsyncIterable<FileChangeInfo<string>>;
/**
* Watch for changes on `filename`, where `filename` is either a file or a directory, returning an `FSWatcher`.
* @param filename A path to a file or directory. If a URL is provided, it must use the `file:` protocol.
* @param options Either the encoding for the filename provided to the listener, or an object optionally specifying encoding, persistent, and recursive options.
* If `encoding` is not supplied, the default of `'utf8'` is used.
* If `persistent` is not supplied, the default of `true` is used.
* If `recursive` is not supplied, the default of `false` is used.
*/
options?: WatchOptionsWithStringEncoding | BufferEncoding,
): NodeJS.AsyncIterator<FileChangeInfo<string>>;
function watch(
filename: PathLike,
options: WatchOptions | string,
): AsyncIterable<FileChangeInfo<string>> | AsyncIterable<FileChangeInfo<Buffer>>;
options: WatchOptionsWithBufferEncoding | "buffer",
): NodeJS.AsyncIterator<FileChangeInfo<NonSharedBuffer>>;
function watch(
filename: PathLike,
options: WatchOptions | BufferEncoding | "buffer",
): NodeJS.AsyncIterator<FileChangeInfo<string | NonSharedBuffer>>;
/**
* Asynchronously copies the entire directory structure from `src` to `dest`,
* including subdirectories and files.
@@ -1239,6 +1287,30 @@ declare module "fs/promises" {
* @return Fulfills with `undefined` upon success.
*/
function cp(source: string | URL, destination: string | URL, opts?: CopyOptions): Promise<void>;
/**
* ```js
* import { glob } from 'node:fs/promises';
*
* for await (const entry of glob('*.js'))
* console.log(entry);
* ```
* @since v22.0.0
* @returns An AsyncIterator that yields the paths of files
* that match the pattern.
*/
function glob(pattern: string | readonly string[]): NodeJS.AsyncIterator<string>;
function glob(
pattern: string | readonly string[],
options: GlobOptionsWithFileTypes,
): NodeJS.AsyncIterator<Dirent>;
function glob(
pattern: string | readonly string[],
options: GlobOptionsWithoutFileTypes,
): NodeJS.AsyncIterator<string>;
function glob(
pattern: string | readonly string[],
options: GlobOptions,
): NodeJS.AsyncIterator<Dirent | string>;
}
declare module "node:fs/promises" {
export * from "fs/promises";

View File

@@ -1,412 +1,170 @@
export {}; // Make this a module
declare var global: typeof globalThis;
// #region Fetch and friends
// Conditional type aliases, used at the end of this file.
// Will either be empty if lib-dom is included, or the undici version otherwise.
type _Request = typeof globalThis extends { onmessage: any } ? {} : import("undici-types").Request;
type _Response = typeof globalThis extends { onmessage: any } ? {} : import("undici-types").Response;
type _FormData = typeof globalThis extends { onmessage: any } ? {} : import("undici-types").FormData;
type _Headers = typeof globalThis extends { onmessage: any } ? {} : import("undici-types").Headers;
type _RequestInit = typeof globalThis extends { onmessage: any } ? {}
: import("undici-types").RequestInit;
type _ResponseInit = typeof globalThis extends { onmessage: any } ? {}
: import("undici-types").ResponseInit;
type _File = typeof globalThis extends { onmessage: any } ? {} : import("node:buffer").File;
// #endregion Fetch and friends
declare global {
// Declare "static" methods in Error
interface ErrorConstructor {
/** Create .stack property on a target object */
captureStackTrace(targetObject: object, constructorOpt?: Function): void;
/**
* Optional override for formatting stack traces
*
* @see https://v8.dev/docs/stack-trace-api#customizing-stack-traces
*/
prepareStackTrace?: ((err: Error, stackTraces: NodeJS.CallSite[]) => any) | undefined;
stackTraceLimit: number;
}
/*-----------------------------------------------*
* *
* GLOBAL *
* *
------------------------------------------------*/
// For backwards compability
interface NodeRequire extends NodeJS.Require {}
interface RequireResolve extends NodeJS.RequireResolve {}
interface NodeModule extends NodeJS.Module {}
var process: NodeJS.Process;
var console: Console;
var __filename: string;
var __dirname: string;
var require: NodeRequire;
var module: NodeModule;
// Same as module.exports
var exports: any;
declare var process: NodeJS.Process;
declare var console: Console;
interface ErrorConstructor {
/**
* Only available if `--expose-gc` is passed to the process.
*/
var gc: undefined | (() => void);
// #region borrowed
// from https://github.com/microsoft/TypeScript/blob/38da7c600c83e7b31193a62495239a0fe478cb67/lib/lib.webworker.d.ts#L633 until moved to separate lib
/** A controller object that allows you to abort one or more DOM requests as and when desired. */
interface AbortController {
/**
* Returns the AbortSignal object associated with this object.
*/
readonly signal: AbortSignal;
/**
* Invoking this method will set this object's AbortSignal's aborted flag and signal to any observers that the associated activity is to be aborted.
*/
abort(reason?: any): void;
}
/** A signal object that allows you to communicate with a DOM request (such as a Fetch) and abort it if required via an AbortController object. */
interface AbortSignal extends EventTarget {
/**
* Returns true if this AbortSignal's AbortController has signaled to abort, and false otherwise.
*/
readonly aborted: boolean;
readonly reason: any;
onabort: null | ((this: AbortSignal, event: Event) => any);
throwIfAborted(): void;
}
var AbortController: typeof globalThis extends { onmessage: any; AbortController: infer T } ? T
: {
prototype: AbortController;
new(): AbortController;
};
var AbortSignal: typeof globalThis extends { onmessage: any; AbortSignal: infer T } ? T
: {
prototype: AbortSignal;
new(): AbortSignal;
abort(reason?: any): AbortSignal;
timeout(milliseconds: number): AbortSignal;
any(signals: AbortSignal[]): AbortSignal;
};
// #endregion borrowed
// #region Disposable
interface SymbolConstructor {
/**
* A method that is used to release resources held by an object. Called by the semantics of the `using` statement.
*/
readonly dispose: unique symbol;
/**
* A method that is used to asynchronously release resources held by an object. Called by the semantics of the `await using` statement.
*/
readonly asyncDispose: unique symbol;
}
interface Disposable {
[Symbol.dispose](): void;
}
interface AsyncDisposable {
[Symbol.asyncDispose](): PromiseLike<void>;
}
// #endregion Disposable
// #region ArrayLike.at()
interface RelativeIndexable<T> {
/**
* Takes an integer value and returns the item at that index,
* allowing for positive and negative integers.
* Negative integers count back from the last item in the array.
*/
at(index: number): T | undefined;
}
interface String extends RelativeIndexable<string> {}
interface Array<T> extends RelativeIndexable<T> {}
interface ReadonlyArray<T> extends RelativeIndexable<T> {}
interface Int8Array extends RelativeIndexable<number> {}
interface Uint8Array extends RelativeIndexable<number> {}
interface Uint8ClampedArray extends RelativeIndexable<number> {}
interface Int16Array extends RelativeIndexable<number> {}
interface Uint16Array extends RelativeIndexable<number> {}
interface Int32Array extends RelativeIndexable<number> {}
interface Uint32Array extends RelativeIndexable<number> {}
interface Float32Array extends RelativeIndexable<number> {}
interface Float64Array extends RelativeIndexable<number> {}
interface BigInt64Array extends RelativeIndexable<bigint> {}
interface BigUint64Array extends RelativeIndexable<bigint> {}
// #endregion ArrayLike.at() end
/**
* @since v17.0.0
* Creates a `.stack` property on `targetObject`, which when accessed returns
* a string representing the location in the code at which
* `Error.captureStackTrace()` was called.
*
* Creates a deep clone of an object.
* ```js
* const myObject = {};
* Error.captureStackTrace(myObject);
* myObject.stack; // Similar to `new Error().stack`
* ```
*
* The first line of the trace will be prefixed with
* `${myObject.name}: ${myObject.message}`.
*
* The optional `constructorOpt` argument accepts a function. If given, all frames
* above `constructorOpt`, including `constructorOpt`, will be omitted from the
* generated stack trace.
*
* The `constructorOpt` argument is useful for hiding implementation
* details of error generation from the user. For instance:
*
* ```js
* function a() {
* b();
* }
*
* function b() {
* c();
* }
*
* function c() {
* // Create an error without stack trace to avoid calculating the stack trace twice.
* const { stackTraceLimit } = Error;
* Error.stackTraceLimit = 0;
* const error = new Error();
* Error.stackTraceLimit = stackTraceLimit;
*
* // Capture the stack trace above function b
* Error.captureStackTrace(error, b); // Neither function c, nor b is included in the stack trace
* throw error;
* }
*
* a();
* ```
*/
function structuredClone<T>(
value: T,
transfer?: { transfer: ReadonlyArray<import("worker_threads").TransferListItem> },
): T;
captureStackTrace(targetObject: object, constructorOpt?: Function): void;
/**
* @see https://v8.dev/docs/stack-trace-api#customizing-stack-traces
*/
prepareStackTrace(err: Error, stackTraces: NodeJS.CallSite[]): any;
/**
* The `Error.stackTraceLimit` property specifies the number of stack frames
* collected by a stack trace (whether generated by `new Error().stack` or
* `Error.captureStackTrace(obj)`).
*
* The default value is `10` but may be set to any valid JavaScript number. Changes
* will affect any stack trace captured _after_ the value has been changed.
*
* If set to a non-number value, or set to a negative number, stack traces will
* not capture any frames.
*/
stackTraceLimit: number;
}
/*----------------------------------------------*
* *
* GLOBAL INTERFACES *
* *
*-----------------------------------------------*/
namespace NodeJS {
interface CallSite {
/**
* Value of "this"
*/
getThis(): unknown;
/**
* Enable this API with the `--expose-gc` CLI flag.
*/
declare var gc: NodeJS.GCFunction | undefined;
/**
* Type of "this" as a string.
* This is the name of the function stored in the constructor field of
* "this", if available. Otherwise the object's [[Class]] internal
* property.
*/
getTypeName(): string | null;
/**
* Current function
*/
getFunction(): Function | undefined;
/**
* Name of the current function, typically its name property.
* If a name property is not available an attempt will be made to try
* to infer a name from the function's context.
*/
getFunctionName(): string | null;
/**
* Name of the property [of "this" or one of its prototypes] that holds
* the current function
*/
getMethodName(): string | null;
/**
* Name of the script [if this function was defined in a script]
*/
getFileName(): string | undefined;
/**
* Current line number [if this function was defined in a script]
*/
getLineNumber(): number | null;
/**
* Current column number [if this function was defined in a script]
*/
getColumnNumber(): number | null;
/**
* A call site object representing the location where eval was called
* [if this function was created using a call to eval]
*/
getEvalOrigin(): string | undefined;
/**
* Is this a toplevel invocation, that is, is "this" the global object?
*/
isToplevel(): boolean;
/**
* Does this call take place in code defined by a call to eval?
*/
isEval(): boolean;
/**
* Is this call in native V8 code?
*/
isNative(): boolean;
/**
* Is this a constructor call?
*/
isConstructor(): boolean;
/**
* is this an async call (i.e. await, Promise.all(), or Promise.any())?
*/
isAsync(): boolean;
/**
* is this an async call to Promise.all()?
*/
isPromiseAll(): boolean;
/**
* returns the index of the promise element that was followed in
* Promise.all() or Promise.any() for async stack traces, or null
* if the CallSite is not an async
*/
getPromiseIndex(): number | null;
getScriptNameOrSourceURL(): string;
getScriptHash(): string;
getEnclosingColumnNumber(): number;
getEnclosingLineNumber(): number;
getPosition(): number;
toString(): string;
}
interface ErrnoException extends Error {
errno?: number | undefined;
code?: string | undefined;
path?: string | undefined;
syscall?: string | undefined;
}
interface ReadableStream extends EventEmitter {
readable: boolean;
read(size?: number): string | Buffer;
setEncoding(encoding: BufferEncoding): this;
pause(): this;
resume(): this;
isPaused(): boolean;
pipe<T extends WritableStream>(destination: T, options?: { end?: boolean | undefined }): T;
unpipe(destination?: WritableStream): this;
unshift(chunk: string | Uint8Array, encoding?: BufferEncoding): void;
wrap(oldStream: ReadableStream): this;
[Symbol.asyncIterator](): AsyncIterableIterator<string | Buffer>;
}
interface WritableStream extends EventEmitter {
writable: boolean;
write(buffer: Uint8Array | string, cb?: (err?: Error | null) => void): boolean;
write(str: string, encoding?: BufferEncoding, cb?: (err?: Error | null) => void): boolean;
end(cb?: () => void): this;
end(data: string | Uint8Array, cb?: () => void): this;
end(str: string, encoding?: BufferEncoding, cb?: () => void): this;
}
interface ReadWriteStream extends ReadableStream, WritableStream {}
interface RefCounted {
ref(): this;
unref(): this;
}
type TypedArray =
| Uint8Array
| Uint8ClampedArray
| Uint16Array
| Uint32Array
| Int8Array
| Int16Array
| Int32Array
| BigUint64Array
| BigInt64Array
| Float32Array
| Float64Array;
type ArrayBufferView = TypedArray | DataView;
interface Require {
(id: string): any;
resolve: RequireResolve;
cache: Dict<NodeModule>;
/**
* @deprecated
*/
extensions: RequireExtensions;
main: Module | undefined;
}
interface RequireResolve {
(id: string, options?: { paths?: string[] | undefined }): string;
paths(request: string): string[] | null;
}
interface RequireExtensions extends Dict<(m: Module, filename: string) => any> {
".js": (m: Module, filename: string) => any;
".json": (m: Module, filename: string) => any;
".node": (m: Module, filename: string) => any;
}
interface Module {
/**
* `true` if the module is running during the Node.js preload
*/
isPreloading: boolean;
exports: any;
require: Require;
id: string;
filename: string;
loaded: boolean;
/** @deprecated since v14.6.0 Please use `require.main` and `module.children` instead. */
parent: Module | null | undefined;
children: Module[];
/**
* @since v11.14.0
*
* The directory name of the module. This is usually the same as the path.dirname() of the module.id.
*/
path: string;
paths: string[];
}
interface Dict<T> {
[key: string]: T | undefined;
}
interface ReadOnlyDict<T> {
readonly [key: string]: T | undefined;
}
declare namespace NodeJS {
interface CallSite {
getColumnNumber(): number | null;
getEnclosingColumnNumber(): number | null;
getEnclosingLineNumber(): number | null;
getEvalOrigin(): string | undefined;
getFileName(): string | null;
getFunction(): Function | undefined;
getFunctionName(): string | null;
getLineNumber(): number | null;
getMethodName(): string | null;
getPosition(): number;
getPromiseIndex(): number | null;
getScriptHash(): string;
getScriptNameOrSourceURL(): string | null;
getThis(): unknown;
getTypeName(): string | null;
isAsync(): boolean;
isConstructor(): boolean;
isEval(): boolean;
isNative(): boolean;
isPromiseAll(): boolean;
isToplevel(): boolean;
}
interface RequestInit extends _RequestInit {}
interface ErrnoException extends Error {
errno?: number | undefined;
code?: string | undefined;
path?: string | undefined;
syscall?: string | undefined;
}
function fetch(
input: string | URL | globalThis.Request,
init?: RequestInit,
): Promise<Response>;
interface ReadableStream extends EventEmitter {
readable: boolean;
read(size?: number): string | Buffer;
setEncoding(encoding: BufferEncoding): this;
pause(): this;
resume(): this;
isPaused(): boolean;
pipe<T extends WritableStream>(destination: T, options?: { end?: boolean | undefined }): T;
unpipe(destination?: WritableStream): this;
unshift(chunk: string | Uint8Array, encoding?: BufferEncoding): void;
wrap(oldStream: ReadableStream): this;
[Symbol.asyncIterator](): AsyncIterableIterator<string | Buffer>;
}
interface Request extends _Request {}
var Request: typeof globalThis extends {
onmessage: any;
Request: infer T;
} ? T
: typeof import("undici-types").Request;
interface WritableStream extends EventEmitter {
writable: boolean;
write(buffer: Uint8Array | string, cb?: (err?: Error | null) => void): boolean;
write(str: string, encoding?: BufferEncoding, cb?: (err?: Error | null) => void): boolean;
end(cb?: () => void): this;
end(data: string | Uint8Array, cb?: () => void): this;
end(str: string, encoding?: BufferEncoding, cb?: () => void): this;
}
interface ResponseInit extends _ResponseInit {}
interface ReadWriteStream extends ReadableStream, WritableStream {}
interface Response extends _Response {}
var Response: typeof globalThis extends {
onmessage: any;
Response: infer T;
} ? T
: typeof import("undici-types").Response;
interface RefCounted {
ref(): this;
unref(): this;
}
interface FormData extends _FormData {}
var FormData: typeof globalThis extends {
onmessage: any;
FormData: infer T;
} ? T
: typeof import("undici-types").FormData;
interface Dict<T> {
[key: string]: T | undefined;
}
interface Headers extends _Headers {}
var Headers: typeof globalThis extends {
onmessage: any;
Headers: infer T;
} ? T
: typeof import("undici-types").Headers;
interface ReadOnlyDict<T> {
readonly [key: string]: T | undefined;
}
interface File extends _File {}
var File: typeof globalThis extends {
onmessage: any;
File: infer T;
} ? T
: typeof import("node:buffer").File;
type PartialOptions<T> = { [K in keyof T]?: T[K] | undefined };
interface GCFunction {
(minor?: boolean): void;
(options: NodeJS.GCOptions & { execution: "async" }): Promise<void>;
(options: NodeJS.GCOptions): void;
}
interface GCOptions {
execution?: "sync" | "async" | undefined;
flavor?: "regular" | "last-resort" | undefined;
type?: "major-snapshot" | "major" | "minor" | undefined;
filename?: string | undefined;
}
/** An iterable iterator returned by the Node.js API. */
interface Iterator<T, TReturn = undefined, TNext = any> extends IteratorObject<T, TReturn, TNext> {
[Symbol.iterator](): NodeJS.Iterator<T, TReturn, TNext>;
}
/** An async iterable iterator returned by the Node.js API. */
interface AsyncIterator<T, TReturn = undefined, TNext = any> extends AsyncIteratorObject<T, TReturn, TNext> {
[Symbol.asyncIterator](): NodeJS.AsyncIterator<T, TReturn, TNext>;
}
}

View File

@@ -1 +0,0 @@
declare var global: typeof globalThis;

View File

@@ -1,5 +1,5 @@
/**
* To use the HTTP server and client one must `require('node:http')`.
* To use the HTTP server and client one must import the `node:http` module.
*
* The HTTP interfaces in Node.js are designed to support many features
* of the protocol which have been traditionally difficult to use.
@@ -37,9 +37,10 @@
* 'Host', 'example.com',
* 'accepT', '*' ]
* ```
* @see [source](https://github.com/nodejs/node/blob/v20.13.1/lib/http.js)
* @see [source](https://github.com/nodejs/node/blob/v24.x/lib/http.js)
*/
declare module "http" {
import { NonSharedBuffer } from "node:buffer";
import * as stream from "node:stream";
import { URL } from "node:url";
import { LookupOptions } from "node:dns";
@@ -48,6 +49,7 @@ declare module "http" {
// incoming headers will never contain number
interface IncomingHttpHeaders extends NodeJS.Dict<string | string[]> {
accept?: string | undefined;
"accept-encoding"?: string | undefined;
"accept-language"?: string | undefined;
"accept-patch"?: string | undefined;
"accept-ranges"?: string | undefined;
@@ -94,6 +96,10 @@ declare module "http" {
range?: string | undefined;
referer?: string | undefined;
"retry-after"?: string | undefined;
"sec-fetch-site"?: string | undefined;
"sec-fetch-mode"?: string | undefined;
"sec-fetch-user"?: string | undefined;
"sec-fetch-dest"?: string | undefined;
"sec-websocket-accept"?: string | undefined;
"sec-websocket-extensions"?: string | undefined;
"sec-websocket-key"?: string | undefined;
@@ -141,6 +147,7 @@ declare module "http" {
"content-range"?: string | undefined;
"content-security-policy"?: string | undefined;
"content-security-policy-report-only"?: string | undefined;
"content-type"?: string | undefined;
cookie?: string | string[] | undefined;
dav?: string | string[] | undefined;
dnt?: string | undefined;
@@ -161,7 +168,7 @@ declare module "http" {
location?: string | undefined;
"max-forwards"?: string | undefined;
origin?: string | undefined;
prgama?: string | string[] | undefined;
pragma?: string | string[] | undefined;
"proxy-authenticate"?: string | string[] | undefined;
"proxy-authorization"?: string | undefined;
"public-key-pins"?: string | undefined;
@@ -194,7 +201,7 @@ declare module "http" {
"x-frame-options"?: string | undefined;
"x-xss-protection"?: string | undefined;
}
interface ClientRequestArgs {
interface ClientRequestArgs extends Pick<LookupOptions, "hints"> {
_defaultAgent?: Agent | undefined;
agent?: Agent | boolean | undefined;
auth?: string | null | undefined;
@@ -206,8 +213,7 @@ declare module "http" {
| undefined;
defaultPort?: number | string | undefined;
family?: number | undefined;
headers?: OutgoingHttpHeaders | undefined;
hints?: LookupOptions["hints"];
headers?: OutgoingHttpHeaders | readonly string[] | undefined;
host?: string | null | undefined;
hostname?: string | null | undefined;
insecureHTTPParser?: boolean | undefined;
@@ -222,16 +228,17 @@ declare module "http" {
path?: string | null | undefined;
port?: number | string | null | undefined;
protocol?: string | null | undefined;
setDefaultHeaders?: boolean | undefined;
setHost?: boolean | undefined;
signal?: AbortSignal | undefined;
socketPath?: string | undefined;
timeout?: number | undefined;
uniqueHeaders?: Array<string | string[]> | undefined;
joinDuplicateHeaders?: boolean;
joinDuplicateHeaders?: boolean | undefined;
}
interface ServerOptions<
Request extends typeof IncomingMessage = typeof IncomingMessage,
Response extends typeof ServerResponse = typeof ServerResponse,
Response extends typeof ServerResponse<InstanceType<Request>> = typeof ServerResponse,
> {
/**
* Specifies the `IncomingMessage` class to be used. Useful for extending the original `IncomingMessage`.
@@ -253,7 +260,7 @@ declare module "http" {
* @default false
* @since v18.14.0
*/
joinDuplicateHeaders?: boolean;
joinDuplicateHeaders?: boolean | undefined;
/**
* The number of milliseconds of inactivity a server needs to wait for additional incoming data,
* after it has finished writing the last response, before a socket will be destroyed.
@@ -262,11 +269,25 @@ declare module "http" {
* @since v18.0.0
*/
keepAliveTimeout?: number | undefined;
/**
* An additional buffer time added to the
* `server.keepAliveTimeout` to extend the internal socket timeout.
* @since 24.6.0
* @default 1000
*/
keepAliveTimeoutBuffer?: number | undefined;
/**
* Sets the interval value in milliseconds to check for request and headers timeout in incomplete requests.
* @default 30000
*/
connectionsCheckingInterval?: number | undefined;
/**
* Sets the timeout value in milliseconds for receiving the complete HTTP headers from the client.
* See {@link Server.headersTimeout} for more information.
* @default 60000
* @since 18.0.0
*/
headersTimeout?: number | undefined;
/**
* Optionally overrides all `socket`s' `readableHighWaterMark` and `writableHighWaterMark`.
* This affects `highWaterMark` property of both `IncomingMessage` and `ServerResponse`.
@@ -294,6 +315,13 @@ declare module "http" {
* @since v16.5.0
*/
noDelay?: boolean | undefined;
/**
* If set to `true`, it forces the server to respond with a 400 (Bad Request) status code
* to any HTTP/1.1 request message that lacks a Host header (as mandated by the specification).
* @default true
* @since 20.0.0
*/
requireHostHeader?: boolean | undefined;
/**
* If set to `true`, it enables keep-alive functionality on the socket immediately after a new incoming connection is received,
* similarly on what is done in `socket.setKeepAlive([enable][, initialDelay])`.
@@ -312,17 +340,34 @@ declare module "http" {
* If the header's value is an array, the items will be joined using `; `.
*/
uniqueHeaders?: Array<string | string[]> | undefined;
/**
* A callback which receives an
* incoming request and returns a boolean, to control which upgrade attempts
* should be accepted. Accepted upgrades will fire an `'upgrade'` event (or
* their sockets will be destroyed, if no listener is registered) while
* rejected upgrades will fire a `'request'` event like any non-upgrade
* request.
* @since v24.9.0
* @default () => server.listenerCount('upgrade') > 0
*/
shouldUpgradeCallback?: ((request: InstanceType<Request>) => boolean) | undefined;
/**
* If set to `true`, an error is thrown when writing to an HTTP response which does not have a body.
* @default false
* @since v18.17.0, v20.2.0
*/
rejectNonStandardBodyWrites?: boolean | undefined;
}
type RequestListener<
Request extends typeof IncomingMessage = typeof IncomingMessage,
Response extends typeof ServerResponse = typeof ServerResponse,
Response extends typeof ServerResponse<InstanceType<Request>> = typeof ServerResponse,
> = (req: InstanceType<Request>, res: InstanceType<Response> & { req: InstanceType<Request> }) => void;
/**
* @since v0.1.17
*/
class Server<
Request extends typeof IncomingMessage = typeof IncomingMessage,
Response extends typeof ServerResponse = typeof ServerResponse,
Response extends typeof ServerResponse<InstanceType<Request>> = typeof ServerResponse,
> extends NetServer {
constructor(requestListener?: RequestListener<Request, Response>);
constructor(options: ServerOptions<Request, Response>, requestListener?: RequestListener<Request, Response>);
@@ -340,8 +385,8 @@ declare module "http" {
* @since v0.9.12
* @param [msecs=0 (no timeout)]
*/
setTimeout(msecs?: number, callback?: () => void): this;
setTimeout(callback: () => void): this;
setTimeout(msecs?: number, callback?: (socket: Socket) => void): this;
setTimeout(callback: (socket: Socket) => void): this;
/**
* Limits maximum incoming headers count. If set to 0, no limit will be applied.
* @since v0.7.0
@@ -386,12 +431,18 @@ declare module "http" {
/**
* The number of milliseconds of inactivity a server needs to wait for additional
* incoming data, after it has finished writing the last response, before a socket
* will be destroyed. If the server receives new data before the keep-alive
* timeout has fired, it will reset the regular inactivity timeout, i.e., `server.timeout`.
* will be destroyed.
*
* This timeout value is combined with the
* `server.keepAliveTimeoutBuffer` option to determine the actual socket
* timeout, calculated as:
* socketTimeout = keepAliveTimeout + keepAliveTimeoutBuffer
* If the server receives new data before the keep-alive timeout has fired, it
* will reset the regular inactivity timeout, i.e., `server.timeout`.
*
* A value of `0` will disable the keep-alive timeout behavior on incoming
* connections.
* A value of `0` makes the http server behave similarly to Node.js versions prior
* A value of `0` makes the HTTP server behave similarly to Node.js versions prior
* to 8.0.0, which did not have a keep-alive timeout.
*
* The socket timeout logic is set up on connection, so changing this value only
@@ -399,6 +450,18 @@ declare module "http" {
* @since v8.0.0
*/
keepAliveTimeout: number;
/**
* An additional buffer time added to the
* `server.keepAliveTimeout` to extend the internal socket timeout.
*
* This buffer helps reduce connection reset (`ECONNRESET`) errors by increasing
* the socket timeout slightly beyond the advertised keep-alive timeout.
*
* This option applies only to new incoming connections.
* @since v24.6.0
* @default 1000
*/
keepAliveTimeoutBuffer: number;
/**
* Sets the timeout value in milliseconds for receiving the entire request from
* the client.
@@ -433,13 +496,13 @@ declare module "http" {
addListener(event: "clientError", listener: (err: Error, socket: stream.Duplex) => void): this;
addListener(
event: "connect",
listener: (req: InstanceType<Request>, socket: stream.Duplex, head: Buffer) => void,
listener: (req: InstanceType<Request>, socket: stream.Duplex, head: NonSharedBuffer) => void,
): this;
addListener(event: "dropRequest", listener: (req: InstanceType<Request>, socket: stream.Duplex) => void): this;
addListener(event: "request", listener: RequestListener<Request, Response>): this;
addListener(
event: "upgrade",
listener: (req: InstanceType<Request>, socket: stream.Duplex, head: Buffer) => void,
listener: (req: InstanceType<Request>, socket: stream.Duplex, head: NonSharedBuffer) => void,
): this;
emit(event: string, ...args: any[]): boolean;
emit(event: "close"): boolean;
@@ -457,14 +520,14 @@ declare module "http" {
res: InstanceType<Response> & { req: InstanceType<Request> },
): boolean;
emit(event: "clientError", err: Error, socket: stream.Duplex): boolean;
emit(event: "connect", req: InstanceType<Request>, socket: stream.Duplex, head: Buffer): boolean;
emit(event: "connect", req: InstanceType<Request>, socket: stream.Duplex, head: NonSharedBuffer): boolean;
emit(event: "dropRequest", req: InstanceType<Request>, socket: stream.Duplex): boolean;
emit(
event: "request",
req: InstanceType<Request>,
res: InstanceType<Response> & { req: InstanceType<Request> },
): boolean;
emit(event: "upgrade", req: InstanceType<Request>, socket: stream.Duplex, head: Buffer): boolean;
emit(event: "upgrade", req: InstanceType<Request>, socket: stream.Duplex, head: NonSharedBuffer): boolean;
on(event: string, listener: (...args: any[]) => void): this;
on(event: "close", listener: () => void): this;
on(event: "connection", listener: (socket: Socket) => void): this;
@@ -473,10 +536,16 @@ declare module "http" {
on(event: "checkContinue", listener: RequestListener<Request, Response>): this;
on(event: "checkExpectation", listener: RequestListener<Request, Response>): this;
on(event: "clientError", listener: (err: Error, socket: stream.Duplex) => void): this;
on(event: "connect", listener: (req: InstanceType<Request>, socket: stream.Duplex, head: Buffer) => void): this;
on(
event: "connect",
listener: (req: InstanceType<Request>, socket: stream.Duplex, head: NonSharedBuffer) => void,
): this;
on(event: "dropRequest", listener: (req: InstanceType<Request>, socket: stream.Duplex) => void): this;
on(event: "request", listener: RequestListener<Request, Response>): this;
on(event: "upgrade", listener: (req: InstanceType<Request>, socket: stream.Duplex, head: Buffer) => void): this;
on(
event: "upgrade",
listener: (req: InstanceType<Request>, socket: stream.Duplex, head: NonSharedBuffer) => void,
): this;
once(event: string, listener: (...args: any[]) => void): this;
once(event: "close", listener: () => void): this;
once(event: "connection", listener: (socket: Socket) => void): this;
@@ -487,13 +556,13 @@ declare module "http" {
once(event: "clientError", listener: (err: Error, socket: stream.Duplex) => void): this;
once(
event: "connect",
listener: (req: InstanceType<Request>, socket: stream.Duplex, head: Buffer) => void,
listener: (req: InstanceType<Request>, socket: stream.Duplex, head: NonSharedBuffer) => void,
): this;
once(event: "dropRequest", listener: (req: InstanceType<Request>, socket: stream.Duplex) => void): this;
once(event: "request", listener: RequestListener<Request, Response>): this;
once(
event: "upgrade",
listener: (req: InstanceType<Request>, socket: stream.Duplex, head: Buffer) => void,
listener: (req: InstanceType<Request>, socket: stream.Duplex, head: NonSharedBuffer) => void,
): this;
prependListener(event: string, listener: (...args: any[]) => void): this;
prependListener(event: "close", listener: () => void): this;
@@ -505,7 +574,7 @@ declare module "http" {
prependListener(event: "clientError", listener: (err: Error, socket: stream.Duplex) => void): this;
prependListener(
event: "connect",
listener: (req: InstanceType<Request>, socket: stream.Duplex, head: Buffer) => void,
listener: (req: InstanceType<Request>, socket: stream.Duplex, head: NonSharedBuffer) => void,
): this;
prependListener(
event: "dropRequest",
@@ -514,7 +583,7 @@ declare module "http" {
prependListener(event: "request", listener: RequestListener<Request, Response>): this;
prependListener(
event: "upgrade",
listener: (req: InstanceType<Request>, socket: stream.Duplex, head: Buffer) => void,
listener: (req: InstanceType<Request>, socket: stream.Duplex, head: NonSharedBuffer) => void,
): this;
prependOnceListener(event: string, listener: (...args: any[]) => void): this;
prependOnceListener(event: "close", listener: () => void): this;
@@ -526,7 +595,7 @@ declare module "http" {
prependOnceListener(event: "clientError", listener: (err: Error, socket: stream.Duplex) => void): this;
prependOnceListener(
event: "connect",
listener: (req: InstanceType<Request>, socket: stream.Duplex, head: Buffer) => void,
listener: (req: InstanceType<Request>, socket: stream.Duplex, head: NonSharedBuffer) => void,
): this;
prependOnceListener(
event: "dropRequest",
@@ -535,7 +604,7 @@ declare module "http" {
prependOnceListener(event: "request", listener: RequestListener<Request, Response>): this;
prependOnceListener(
event: "upgrade",
listener: (req: InstanceType<Request>, socket: stream.Duplex, head: Buffer) => void,
listener: (req: InstanceType<Request>, socket: stream.Duplex, head: NonSharedBuffer) => void,
): this;
}
/**
@@ -588,6 +657,42 @@ declare module "http" {
* @param value Header value
*/
setHeader(name: string, value: number | string | readonly string[]): this;
/**
* Sets multiple header values for implicit headers. headers must be an instance of
* `Headers` or `Map`, if a header already exists in the to-be-sent headers, its
* value will be replaced.
*
* ```js
* const headers = new Headers({ foo: 'bar' });
* outgoingMessage.setHeaders(headers);
* ```
*
* or
*
* ```js
* const headers = new Map([['foo', 'bar']]);
* outgoingMessage.setHeaders(headers);
* ```
*
* When headers have been set with `outgoingMessage.setHeaders()`, they will be
* merged with any headers passed to `response.writeHead()`, with the headers passed
* to `response.writeHead()` given precedence.
*
* ```js
* // Returns content-type = text/plain
* const server = http.createServer((req, res) => {
* const headers = new Headers({ 'Content-Type': 'text/html' });
* res.setHeaders(headers);
* res.writeHead(200, { 'Content-Type': 'text/plain' });
* res.end('ok');
* });
* ```
*
* @since v19.6.0, v18.15.0
* @param name Header name
* @param value Header value
*/
setHeaders(headers: Headers | Map<string, number | string | readonly string[]>): this;
/**
* Append a single header value to the header object.
*
@@ -848,7 +953,7 @@ declare module "http" {
* the request body should be sent.
* @since v10.0.0
*/
writeProcessing(): void;
writeProcessing(callback?: () => void): void;
}
interface InformationEvent {
statusCode: number;
@@ -1019,7 +1124,7 @@ declare module "http" {
addListener(event: "abort", listener: () => void): this;
addListener(
event: "connect",
listener: (response: IncomingMessage, socket: Socket, head: Buffer) => void,
listener: (response: IncomingMessage, socket: Socket, head: NonSharedBuffer) => void,
): this;
addListener(event: "continue", listener: () => void): this;
addListener(event: "information", listener: (info: InformationEvent) => void): this;
@@ -1028,7 +1133,7 @@ declare module "http" {
addListener(event: "timeout", listener: () => void): this;
addListener(
event: "upgrade",
listener: (response: IncomingMessage, socket: Socket, head: Buffer) => void,
listener: (response: IncomingMessage, socket: Socket, head: NonSharedBuffer) => void,
): this;
addListener(event: "close", listener: () => void): this;
addListener(event: "drain", listener: () => void): this;
@@ -1041,13 +1146,19 @@ declare module "http" {
* @deprecated
*/
on(event: "abort", listener: () => void): this;
on(event: "connect", listener: (response: IncomingMessage, socket: Socket, head: Buffer) => void): this;
on(
event: "connect",
listener: (response: IncomingMessage, socket: Socket, head: NonSharedBuffer) => void,
): this;
on(event: "continue", listener: () => void): this;
on(event: "information", listener: (info: InformationEvent) => void): this;
on(event: "response", listener: (response: IncomingMessage) => void): this;
on(event: "socket", listener: (socket: Socket) => void): this;
on(event: "timeout", listener: () => void): this;
on(event: "upgrade", listener: (response: IncomingMessage, socket: Socket, head: Buffer) => void): this;
on(
event: "upgrade",
listener: (response: IncomingMessage, socket: Socket, head: NonSharedBuffer) => void,
): this;
on(event: "close", listener: () => void): this;
on(event: "drain", listener: () => void): this;
on(event: "error", listener: (err: Error) => void): this;
@@ -1059,13 +1170,19 @@ declare module "http" {
* @deprecated
*/
once(event: "abort", listener: () => void): this;
once(event: "connect", listener: (response: IncomingMessage, socket: Socket, head: Buffer) => void): this;
once(
event: "connect",
listener: (response: IncomingMessage, socket: Socket, head: NonSharedBuffer) => void,
): this;
once(event: "continue", listener: () => void): this;
once(event: "information", listener: (info: InformationEvent) => void): this;
once(event: "response", listener: (response: IncomingMessage) => void): this;
once(event: "socket", listener: (socket: Socket) => void): this;
once(event: "timeout", listener: () => void): this;
once(event: "upgrade", listener: (response: IncomingMessage, socket: Socket, head: Buffer) => void): this;
once(
event: "upgrade",
listener: (response: IncomingMessage, socket: Socket, head: NonSharedBuffer) => void,
): this;
once(event: "close", listener: () => void): this;
once(event: "drain", listener: () => void): this;
once(event: "error", listener: (err: Error) => void): this;
@@ -1079,7 +1196,7 @@ declare module "http" {
prependListener(event: "abort", listener: () => void): this;
prependListener(
event: "connect",
listener: (response: IncomingMessage, socket: Socket, head: Buffer) => void,
listener: (response: IncomingMessage, socket: Socket, head: NonSharedBuffer) => void,
): this;
prependListener(event: "continue", listener: () => void): this;
prependListener(event: "information", listener: (info: InformationEvent) => void): this;
@@ -1088,7 +1205,7 @@ declare module "http" {
prependListener(event: "timeout", listener: () => void): this;
prependListener(
event: "upgrade",
listener: (response: IncomingMessage, socket: Socket, head: Buffer) => void,
listener: (response: IncomingMessage, socket: Socket, head: NonSharedBuffer) => void,
): this;
prependListener(event: "close", listener: () => void): this;
prependListener(event: "drain", listener: () => void): this;
@@ -1103,7 +1220,7 @@ declare module "http" {
prependOnceListener(event: "abort", listener: () => void): this;
prependOnceListener(
event: "connect",
listener: (response: IncomingMessage, socket: Socket, head: Buffer) => void,
listener: (response: IncomingMessage, socket: Socket, head: NonSharedBuffer) => void,
): this;
prependOnceListener(event: "continue", listener: () => void): this;
prependOnceListener(event: "information", listener: (info: InformationEvent) => void): this;
@@ -1112,7 +1229,7 @@ declare module "http" {
prependOnceListener(event: "timeout", listener: () => void): this;
prependOnceListener(
event: "upgrade",
listener: (response: IncomingMessage, socket: Socket, head: Buffer) => void,
listener: (response: IncomingMessage, socket: Socket, head: NonSharedBuffer) => void,
): this;
prependOnceListener(event: "close", listener: () => void): this;
prependOnceListener(event: "drain", listener: () => void): this;
@@ -1356,7 +1473,15 @@ declare module "http" {
*/
destroy(error?: Error): this;
}
interface AgentOptions extends Partial<TcpSocketConnectOpts> {
interface ProxyEnv extends NodeJS.ProcessEnv {
HTTP_PROXY?: string | undefined;
HTTPS_PROXY?: string | undefined;
NO_PROXY?: string | undefined;
http_proxy?: string | undefined;
https_proxy?: string | undefined;
no_proxy?: string | undefined;
}
interface AgentOptions extends NodeJS.PartialOptions<TcpSocketConnectOpts> {
/**
* Keep sockets around in a pool to be used by other requests in the future. Default = false
*/
@@ -1366,6 +1491,16 @@ declare module "http" {
* Only relevant if keepAlive is set to true.
*/
keepAliveMsecs?: number | undefined;
/**
* Milliseconds to subtract from
* the server-provided `keep-alive: timeout=...` hint when determining socket
* expiration time. This buffer helps ensure the agent closes the socket
* slightly before the server does, reducing the chance of sending a request
* on a socket thats about to be closed by the server.
* @since v24.7.0
* @default 1000
*/
agentKeepAliveTimeoutBuffer?: number | undefined;
/**
* Maximum number of sockets to allow per host. Default for Node 0.10 is 5, default for Node 0.12 is Infinity
*/
@@ -1387,6 +1522,22 @@ declare module "http" {
* @default `lifo`
*/
scheduling?: "fifo" | "lifo" | undefined;
/**
* Environment variables for proxy configuration. See
* [Built-in Proxy Support](https://nodejs.org/docs/latest-v24.x/api/http.html#built-in-proxy-support) for details.
* @since v24.5.0
*/
proxyEnv?: ProxyEnv | undefined;
/**
* Default port to use when the port is not specified in requests.
* @since v24.5.0
*/
defaultPort?: number | undefined;
/**
* The protocol to use for the agent.
* @since v24.5.0
*/
protocol?: string | undefined;
}
/**
* An `Agent` is responsible for managing connection persistence
@@ -1442,12 +1593,12 @@ declare module "http" {
* });
* ```
*
* `options` in [`socket.connect()`](https://nodejs.org/docs/latest-v20.x/api/net.html#socketconnectoptions-connectlistener) are also supported.
* `options` in [`socket.connect()`](https://nodejs.org/docs/latest-v24.x/api/net.html#socketconnectoptions-connectlistener) are also supported.
*
* To configure any of them, a custom {@link Agent} instance must be created.
*
* ```js
* const http = require('node:http');
* import http from 'node:http';
* const keepAliveAgent = new http.Agent({ keepAlive: true });
* options.agent = keepAliveAgent;
* http.request(options, onResponseCallback)
@@ -1507,6 +1658,68 @@ declare module "http" {
* @since v0.11.4
*/
destroy(): void;
/**
* Produces a socket/stream to be used for HTTP requests.
*
* By default, this function is the same as `net.createConnection()`. However,
* custom agents may override this method in case greater flexibility is desired.
*
* A socket/stream can be supplied in one of two ways: by returning the
* socket/stream from this function, or by passing the socket/stream to `callback`.
*
* This method is guaranteed to return an instance of the `net.Socket` class,
* a subclass of `stream.Duplex`, unless the user specifies a socket
* type other than `net.Socket`.
*
* `callback` has a signature of `(err, stream)`.
* @since v0.11.4
* @param options Options containing connection details. Check `createConnection` for the format of the options
* @param callback Callback function that receives the created socket
*/
createConnection(
options: ClientRequestArgs,
callback?: (err: Error | null, stream: stream.Duplex) => void,
): stream.Duplex | null | undefined;
/**
* Called when `socket` is detached from a request and could be persisted by the`Agent`. Default behavior is to:
*
* ```js
* socket.setKeepAlive(true, this.keepAliveMsecs);
* socket.unref();
* return true;
* ```
*
* This method can be overridden by a particular `Agent` subclass. If this
* method returns a falsy value, the socket will be destroyed instead of persisting
* it for use with the next request.
*
* The `socket` argument can be an instance of `net.Socket`, a subclass of `stream.Duplex`.
* @since v8.1.0
*/
keepSocketAlive(socket: stream.Duplex): void;
/**
* Called when `socket` is attached to `request` after being persisted because of
* the keep-alive options. Default behavior is to:
*
* ```js
* socket.ref();
* ```
*
* This method can be overridden by a particular `Agent` subclass.
*
* The `socket` argument can be an instance of `net.Socket`, a subclass of `stream.Duplex`.
* @since v8.1.0
*/
reuseSocket(socket: stream.Duplex, request: ClientRequest): void;
/**
* Get a unique name for a set of request options, to determine whether a
* connection can be reused. For an HTTP agent, this returns`host:port:localAddress` or `host:port:localAddress:family`. For an HTTPS agent,
* the name includes the CA, cert, ciphers, and other HTTPS/TLS-specific options
* that determine socket reusability.
* @since v0.11.4
* @param options A set of options providing information for name generation
*/
getName(options?: ClientRequestArgs): string;
}
const METHODS: string[];
const STATUS_CODES: {
@@ -1553,11 +1766,11 @@ declare module "http" {
*/
function createServer<
Request extends typeof IncomingMessage = typeof IncomingMessage,
Response extends typeof ServerResponse = typeof ServerResponse,
Response extends typeof ServerResponse<InstanceType<Request>> = typeof ServerResponse,
>(requestListener?: RequestListener<Request, Response>): Server<Request, Response>;
function createServer<
Request extends typeof IncomingMessage = typeof IncomingMessage,
Response extends typeof ServerResponse = typeof ServerResponse,
Response extends typeof ServerResponse<InstanceType<Request>> = typeof ServerResponse,
>(
options: ServerOptions<Request, Response>,
requestListener?: RequestListener<Request, Response>,
@@ -1902,6 +2115,19 @@ declare module "http" {
* Defaults to 16KB. Configurable using the `--max-http-header-size` CLI option.
*/
const maxHeaderSize: number;
/**
* A browser-compatible implementation of `WebSocket`.
* @since v22.5.0
*/
const WebSocket: typeof import("undici-types").WebSocket;
/**
* @since v22.5.0
*/
const CloseEvent: typeof import("undici-types").CloseEvent;
/**
* @since v22.5.0
*/
const MessageEvent: typeof import("undici-types").MessageEvent;
}
declare module "node:http" {
export * from "http";

File diff suppressed because it is too large Load Diff

View File

@@ -1,27 +1,26 @@
/**
* HTTPS is the HTTP protocol over TLS/SSL. In Node.js this is implemented as a
* separate module.
* @see [source](https://github.com/nodejs/node/blob/v20.13.1/lib/https.js)
* @see [source](https://github.com/nodejs/node/blob/v24.x/lib/https.js)
*/
declare module "https" {
import { NonSharedBuffer } from "node:buffer";
import { Duplex } from "node:stream";
import * as tls from "node:tls";
import * as http from "node:http";
import { URL } from "node:url";
type ServerOptions<
interface ServerOptions<
Request extends typeof http.IncomingMessage = typeof http.IncomingMessage,
Response extends typeof http.ServerResponse = typeof http.ServerResponse,
> = tls.SecureContextOptions & tls.TlsOptions & http.ServerOptions<Request, Response>;
type RequestOptions =
& http.RequestOptions
& tls.SecureContextOptions
& {
checkServerIdentity?: typeof tls.checkServerIdentity | undefined;
rejectUnauthorized?: boolean | undefined; // Defaults to true
servername?: string | undefined; // SNI TLS Extension
};
Response extends typeof http.ServerResponse<InstanceType<Request>> = typeof http.ServerResponse,
> extends http.ServerOptions<Request, Response>, tls.TlsOptions {}
interface RequestOptions extends http.RequestOptions, tls.SecureContextOptions {
checkServerIdentity?:
| ((hostname: string, cert: tls.DetailedPeerCertificate) => Error | undefined)
| undefined;
rejectUnauthorized?: boolean | undefined; // Defaults to true
servername?: string | undefined; // SNI TLS Extension
}
interface AgentOptions extends http.AgentOptions, tls.ConnectionOptions {
rejectUnauthorized?: boolean | undefined;
maxCachedSessions?: number | undefined;
}
/**
@@ -31,10 +30,15 @@ declare module "https" {
class Agent extends http.Agent {
constructor(options?: AgentOptions);
options: AgentOptions;
createConnection(
options: RequestOptions,
callback?: (err: Error | null, stream: Duplex) => void,
): Duplex | null | undefined;
getName(options?: RequestOptions): string;
}
interface Server<
Request extends typeof http.IncomingMessage = typeof http.IncomingMessage,
Response extends typeof http.ServerResponse = typeof http.ServerResponse,
Response extends typeof http.ServerResponse<InstanceType<Request>> = typeof http.ServerResponse,
> extends http.Server<Request, Response> {}
/**
* See `http.Server` for more information.
@@ -42,7 +46,7 @@ declare module "https" {
*/
class Server<
Request extends typeof http.IncomingMessage = typeof http.IncomingMessage,
Response extends typeof http.ServerResponse = typeof http.ServerResponse,
Response extends typeof http.ServerResponse<InstanceType<Request>> = typeof http.ServerResponse,
> extends tls.Server {
constructor(requestListener?: http.RequestListener<Request, Response>);
constructor(
@@ -60,22 +64,25 @@ declare module "https" {
*/
closeIdleConnections(): void;
addListener(event: string, listener: (...args: any[]) => void): this;
addListener(event: "keylog", listener: (line: Buffer, tlsSocket: tls.TLSSocket) => void): this;
addListener(event: "keylog", listener: (line: NonSharedBuffer, tlsSocket: tls.TLSSocket) => void): this;
addListener(
event: "newSession",
listener: (sessionId: Buffer, sessionData: Buffer, callback: (err: Error, resp: Buffer) => void) => void,
listener: (sessionId: NonSharedBuffer, sessionData: NonSharedBuffer, callback: () => void) => void,
): this;
addListener(
event: "OCSPRequest",
listener: (
certificate: Buffer,
issuer: Buffer,
callback: (err: Error | null, resp: Buffer) => void,
certificate: NonSharedBuffer,
issuer: NonSharedBuffer,
callback: (err: Error | null, resp: Buffer | null) => void,
) => void,
): this;
addListener(
event: "resumeSession",
listener: (sessionId: Buffer, callback: (err: Error, sessionData: Buffer) => void) => void,
listener: (
sessionId: NonSharedBuffer,
callback: (err: Error | null, sessionData: Buffer | null) => void,
) => void,
): this;
addListener(event: "secureConnection", listener: (tlsSocket: tls.TLSSocket) => void): this;
addListener(event: "tlsClientError", listener: (err: Error, tlsSocket: tls.TLSSocket) => void): this;
@@ -88,28 +95,32 @@ declare module "https" {
addListener(event: "clientError", listener: (err: Error, socket: Duplex) => void): this;
addListener(
event: "connect",
listener: (req: InstanceType<Request>, socket: Duplex, head: Buffer) => void,
listener: (req: InstanceType<Request>, socket: Duplex, head: NonSharedBuffer) => void,
): this;
addListener(event: "request", listener: http.RequestListener<Request, Response>): this;
addListener(
event: "upgrade",
listener: (req: InstanceType<Request>, socket: Duplex, head: Buffer) => void,
listener: (req: InstanceType<Request>, socket: Duplex, head: NonSharedBuffer) => void,
): this;
emit(event: string, ...args: any[]): boolean;
emit(event: "keylog", line: Buffer, tlsSocket: tls.TLSSocket): boolean;
emit(event: "keylog", line: NonSharedBuffer, tlsSocket: tls.TLSSocket): boolean;
emit(
event: "newSession",
sessionId: Buffer,
sessionData: Buffer,
callback: (err: Error, resp: Buffer) => void,
sessionId: NonSharedBuffer,
sessionData: NonSharedBuffer,
callback: () => void,
): boolean;
emit(
event: "OCSPRequest",
certificate: Buffer,
issuer: Buffer,
callback: (err: Error | null, resp: Buffer) => void,
certificate: NonSharedBuffer,
issuer: NonSharedBuffer,
callback: (err: Error | null, resp: Buffer | null) => void,
): boolean;
emit(
event: "resumeSession",
sessionId: NonSharedBuffer,
callback: (err: Error | null, sessionData: Buffer | null) => void,
): boolean;
emit(event: "resumeSession", sessionId: Buffer, callback: (err: Error, sessionData: Buffer) => void): boolean;
emit(event: "secureConnection", tlsSocket: tls.TLSSocket): boolean;
emit(event: "tlsClientError", err: Error, tlsSocket: tls.TLSSocket): boolean;
emit(event: "close"): boolean;
@@ -119,44 +130,41 @@ declare module "https" {
emit(
event: "checkContinue",
req: InstanceType<Request>,
res: InstanceType<Response> & {
req: InstanceType<Request>;
},
res: InstanceType<Response>,
): boolean;
emit(
event: "checkExpectation",
req: InstanceType<Request>,
res: InstanceType<Response> & {
req: InstanceType<Request>;
},
res: InstanceType<Response>,
): boolean;
emit(event: "clientError", err: Error, socket: Duplex): boolean;
emit(event: "connect", req: InstanceType<Request>, socket: Duplex, head: Buffer): boolean;
emit(event: "connect", req: InstanceType<Request>, socket: Duplex, head: NonSharedBuffer): boolean;
emit(
event: "request",
req: InstanceType<Request>,
res: InstanceType<Response> & {
req: InstanceType<Request>;
},
res: InstanceType<Response>,
): boolean;
emit(event: "upgrade", req: InstanceType<Request>, socket: Duplex, head: Buffer): boolean;
emit(event: "upgrade", req: InstanceType<Request>, socket: Duplex, head: NonSharedBuffer): boolean;
on(event: string, listener: (...args: any[]) => void): this;
on(event: "keylog", listener: (line: Buffer, tlsSocket: tls.TLSSocket) => void): this;
on(event: "keylog", listener: (line: NonSharedBuffer, tlsSocket: tls.TLSSocket) => void): this;
on(
event: "newSession",
listener: (sessionId: Buffer, sessionData: Buffer, callback: (err: Error, resp: Buffer) => void) => void,
listener: (sessionId: NonSharedBuffer, sessionData: NonSharedBuffer, callback: () => void) => void,
): this;
on(
event: "OCSPRequest",
listener: (
certificate: Buffer,
issuer: Buffer,
callback: (err: Error | null, resp: Buffer) => void,
certificate: NonSharedBuffer,
issuer: NonSharedBuffer,
callback: (err: Error | null, resp: Buffer | null) => void,
) => void,
): this;
on(
event: "resumeSession",
listener: (sessionId: Buffer, callback: (err: Error, sessionData: Buffer) => void) => void,
listener: (
sessionId: NonSharedBuffer,
callback: (err: Error | null, sessionData: Buffer | null) => void,
) => void,
): this;
on(event: "secureConnection", listener: (tlsSocket: tls.TLSSocket) => void): this;
on(event: "tlsClientError", listener: (err: Error, tlsSocket: tls.TLSSocket) => void): this;
@@ -167,26 +175,35 @@ declare module "https" {
on(event: "checkContinue", listener: http.RequestListener<Request, Response>): this;
on(event: "checkExpectation", listener: http.RequestListener<Request, Response>): this;
on(event: "clientError", listener: (err: Error, socket: Duplex) => void): this;
on(event: "connect", listener: (req: InstanceType<Request>, socket: Duplex, head: Buffer) => void): this;
on(
event: "connect",
listener: (req: InstanceType<Request>, socket: Duplex, head: NonSharedBuffer) => void,
): this;
on(event: "request", listener: http.RequestListener<Request, Response>): this;
on(event: "upgrade", listener: (req: InstanceType<Request>, socket: Duplex, head: Buffer) => void): this;
on(
event: "upgrade",
listener: (req: InstanceType<Request>, socket: Duplex, head: NonSharedBuffer) => void,
): this;
once(event: string, listener: (...args: any[]) => void): this;
once(event: "keylog", listener: (line: Buffer, tlsSocket: tls.TLSSocket) => void): this;
once(event: "keylog", listener: (line: NonSharedBuffer, tlsSocket: tls.TLSSocket) => void): this;
once(
event: "newSession",
listener: (sessionId: Buffer, sessionData: Buffer, callback: (err: Error, resp: Buffer) => void) => void,
listener: (sessionId: NonSharedBuffer, sessionData: NonSharedBuffer, callback: () => void) => void,
): this;
once(
event: "OCSPRequest",
listener: (
certificate: Buffer,
issuer: Buffer,
callback: (err: Error | null, resp: Buffer) => void,
certificate: NonSharedBuffer,
issuer: NonSharedBuffer,
callback: (err: Error | null, resp: Buffer | null) => void,
) => void,
): this;
once(
event: "resumeSession",
listener: (sessionId: Buffer, callback: (err: Error, sessionData: Buffer) => void) => void,
listener: (
sessionId: NonSharedBuffer,
callback: (err: Error | null, sessionData: Buffer | null) => void,
) => void,
): this;
once(event: "secureConnection", listener: (tlsSocket: tls.TLSSocket) => void): this;
once(event: "tlsClientError", listener: (err: Error, tlsSocket: tls.TLSSocket) => void): this;
@@ -197,26 +214,35 @@ declare module "https" {
once(event: "checkContinue", listener: http.RequestListener<Request, Response>): this;
once(event: "checkExpectation", listener: http.RequestListener<Request, Response>): this;
once(event: "clientError", listener: (err: Error, socket: Duplex) => void): this;
once(event: "connect", listener: (req: InstanceType<Request>, socket: Duplex, head: Buffer) => void): this;
once(
event: "connect",
listener: (req: InstanceType<Request>, socket: Duplex, head: NonSharedBuffer) => void,
): this;
once(event: "request", listener: http.RequestListener<Request, Response>): this;
once(event: "upgrade", listener: (req: InstanceType<Request>, socket: Duplex, head: Buffer) => void): this;
once(
event: "upgrade",
listener: (req: InstanceType<Request>, socket: Duplex, head: NonSharedBuffer) => void,
): this;
prependListener(event: string, listener: (...args: any[]) => void): this;
prependListener(event: "keylog", listener: (line: Buffer, tlsSocket: tls.TLSSocket) => void): this;
prependListener(event: "keylog", listener: (line: NonSharedBuffer, tlsSocket: tls.TLSSocket) => void): this;
prependListener(
event: "newSession",
listener: (sessionId: Buffer, sessionData: Buffer, callback: (err: Error, resp: Buffer) => void) => void,
listener: (sessionId: NonSharedBuffer, sessionData: NonSharedBuffer, callback: () => void) => void,
): this;
prependListener(
event: "OCSPRequest",
listener: (
certificate: Buffer,
issuer: Buffer,
callback: (err: Error | null, resp: Buffer) => void,
certificate: NonSharedBuffer,
issuer: NonSharedBuffer,
callback: (err: Error | null, resp: Buffer | null) => void,
) => void,
): this;
prependListener(
event: "resumeSession",
listener: (sessionId: Buffer, callback: (err: Error, sessionData: Buffer) => void) => void,
listener: (
sessionId: NonSharedBuffer,
callback: (err: Error | null, sessionData: Buffer | null) => void,
) => void,
): this;
prependListener(event: "secureConnection", listener: (tlsSocket: tls.TLSSocket) => void): this;
prependListener(event: "tlsClientError", listener: (err: Error, tlsSocket: tls.TLSSocket) => void): this;
@@ -229,30 +255,33 @@ declare module "https" {
prependListener(event: "clientError", listener: (err: Error, socket: Duplex) => void): this;
prependListener(
event: "connect",
listener: (req: InstanceType<Request>, socket: Duplex, head: Buffer) => void,
listener: (req: InstanceType<Request>, socket: Duplex, head: NonSharedBuffer) => void,
): this;
prependListener(event: "request", listener: http.RequestListener<Request, Response>): this;
prependListener(
event: "upgrade",
listener: (req: InstanceType<Request>, socket: Duplex, head: Buffer) => void,
listener: (req: InstanceType<Request>, socket: Duplex, head: NonSharedBuffer) => void,
): this;
prependOnceListener(event: string, listener: (...args: any[]) => void): this;
prependOnceListener(event: "keylog", listener: (line: Buffer, tlsSocket: tls.TLSSocket) => void): this;
prependOnceListener(event: "keylog", listener: (line: NonSharedBuffer, tlsSocket: tls.TLSSocket) => void): this;
prependOnceListener(
event: "newSession",
listener: (sessionId: Buffer, sessionData: Buffer, callback: (err: Error, resp: Buffer) => void) => void,
listener: (sessionId: NonSharedBuffer, sessionData: NonSharedBuffer, callback: () => void) => void,
): this;
prependOnceListener(
event: "OCSPRequest",
listener: (
certificate: Buffer,
issuer: Buffer,
callback: (err: Error | null, resp: Buffer) => void,
certificate: NonSharedBuffer,
issuer: NonSharedBuffer,
callback: (err: Error | null, resp: Buffer | null) => void,
) => void,
): this;
prependOnceListener(
event: "resumeSession",
listener: (sessionId: Buffer, callback: (err: Error, sessionData: Buffer) => void) => void,
listener: (
sessionId: NonSharedBuffer,
callback: (err: Error | null, sessionData: Buffer | null) => void,
) => void,
): this;
prependOnceListener(event: "secureConnection", listener: (tlsSocket: tls.TLSSocket) => void): this;
prependOnceListener(event: "tlsClientError", listener: (err: Error, tlsSocket: tls.TLSSocket) => void): this;
@@ -265,19 +294,19 @@ declare module "https" {
prependOnceListener(event: "clientError", listener: (err: Error, socket: Duplex) => void): this;
prependOnceListener(
event: "connect",
listener: (req: InstanceType<Request>, socket: Duplex, head: Buffer) => void,
listener: (req: InstanceType<Request>, socket: Duplex, head: NonSharedBuffer) => void,
): this;
prependOnceListener(event: "request", listener: http.RequestListener<Request, Response>): this;
prependOnceListener(
event: "upgrade",
listener: (req: InstanceType<Request>, socket: Duplex, head: Buffer) => void,
listener: (req: InstanceType<Request>, socket: Duplex, head: NonSharedBuffer) => void,
): this;
}
/**
* ```js
* // curl -k https://localhost:8000/
* const https = require('node:https');
* const fs = require('node:fs');
* import https from 'node:https';
* import fs from 'node:fs';
*
* const options = {
* key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
@@ -293,8 +322,8 @@ declare module "https" {
* Or
*
* ```js
* const https = require('node:https');
* const fs = require('node:fs');
* import https from 'node:https';
* import fs from 'node:fs';
*
* const options = {
* pfx: fs.readFileSync('test/fixtures/test_cert.pfx'),
@@ -312,11 +341,11 @@ declare module "https" {
*/
function createServer<
Request extends typeof http.IncomingMessage = typeof http.IncomingMessage,
Response extends typeof http.ServerResponse = typeof http.ServerResponse,
Response extends typeof http.ServerResponse<InstanceType<Request>> = typeof http.ServerResponse,
>(requestListener?: http.RequestListener<Request, Response>): Server<Request, Response>;
function createServer<
Request extends typeof http.IncomingMessage = typeof http.IncomingMessage,
Response extends typeof http.ServerResponse = typeof http.ServerResponse,
Response extends typeof http.ServerResponse<InstanceType<Request>> = typeof http.ServerResponse,
>(
options: ServerOptions<Request, Response>,
requestListener?: http.RequestListener<Request, Response>,
@@ -334,7 +363,7 @@ declare module "https" {
* upload a file with a POST request, then write to the `ClientRequest` object.
*
* ```js
* const https = require('node:https');
* import https from 'node:https';
*
* const options = {
* hostname: 'encrypted.google.com',
@@ -407,9 +436,9 @@ declare module "https" {
* Example pinning on certificate fingerprint, or the public key (similar to`pin-sha256`):
*
* ```js
* const tls = require('node:tls');
* const https = require('node:https');
* const crypto = require('node:crypto');
* import tls from 'node:tls';
* import https from 'node:https';
* import crypto from 'node:crypto';
*
* function sha256(s) {
* return crypto.createHash('sha256').update(s).digest('base64');
@@ -517,7 +546,7 @@ declare module "https" {
* string, it is automatically parsed with `new URL()`. If it is a `URL` object, it will be automatically converted to an ordinary `options` object.
*
* ```js
* const https = require('node:https');
* import https from 'node:https';
*
* https.get('https://encrypted.google.com/', (res) => {
* console.log('statusCode:', res.statusCode);

View File

@@ -22,18 +22,32 @@
* IN THE SOFTWARE.
*/
// NOTE: These definitions support NodeJS and TypeScript 4.9+.
// NOTE: These definitions support Node.js and TypeScript 5.8+.
// Reference required types from the default lib:
// Reference required TypeScript libraries:
/// <reference lib="es2020" />
/// <reference lib="esnext.asynciterable" />
/// <reference lib="esnext.intl" />
/// <reference lib="esnext.bigint" />
/// <reference lib="esnext.disposable" />
/// <reference lib="esnext.float16" />
// Base definitions for all NodeJS modules that are not specific to any version of TypeScript:
// Iterator definitions required for compatibility with TypeScript <5.6:
/// <reference path="compatibility/iterators.d.ts" />
// Definitions for Node.js modules specific to TypeScript 5.7+:
/// <reference path="globals.typedarray.d.ts" />
/// <reference path="buffer.buffer.d.ts" />
// Definitions for Node.js modules that are not specific to any version of TypeScript:
/// <reference path="globals.d.ts" />
/// <reference path="web-globals/abortcontroller.d.ts" />
/// <reference path="web-globals/crypto.d.ts" />
/// <reference path="web-globals/domexception.d.ts" />
/// <reference path="web-globals/events.d.ts" />
/// <reference path="web-globals/fetch.d.ts" />
/// <reference path="web-globals/navigator.d.ts" />
/// <reference path="web-globals/storage.d.ts" />
/// <reference path="web-globals/streams.d.ts" />
/// <reference path="assert.d.ts" />
/// <reference path="assert/strict.d.ts" />
/// <reference path="globals.d.ts" />
/// <reference path="async_hooks.d.ts" />
/// <reference path="buffer.d.ts" />
/// <reference path="child_process.d.ts" />
@@ -45,9 +59,7 @@
/// <reference path="diagnostics_channel.d.ts" />
/// <reference path="dns.d.ts" />
/// <reference path="dns/promises.d.ts" />
/// <reference path="dns/promises.d.ts" />
/// <reference path="domain.d.ts" />
/// <reference path="dom-events.d.ts" />
/// <reference path="events.d.ts" />
/// <reference path="fs.d.ts" />
/// <reference path="fs/promises.d.ts" />
@@ -55,6 +67,7 @@
/// <reference path="http2.d.ts" />
/// <reference path="https.d.ts" />
/// <reference path="inspector.d.ts" />
/// <reference path="inspector.generated.d.ts" />
/// <reference path="module.d.ts" />
/// <reference path="net.d.ts" />
/// <reference path="os.d.ts" />
@@ -67,6 +80,7 @@
/// <reference path="readline/promises.d.ts" />
/// <reference path="repl.d.ts" />
/// <reference path="sea.d.ts" />
/// <reference path="sqlite.d.ts" />
/// <reference path="stream.d.ts" />
/// <reference path="stream/promises.d.ts" />
/// <reference path="stream/consumers.d.ts" />
@@ -85,5 +99,3 @@
/// <reference path="wasi.d.ts" />
/// <reference path="worker_threads.d.ts" />
/// <reference path="zlib.d.ts" />
/// <reference path="globals.global.d.ts" />

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -8,11 +8,12 @@
* It can be accessed using:
*
* ```js
* const net = require('node:net');
* import net from 'node:net';
* ```
* @see [source](https://github.com/nodejs/node/blob/v20.13.1/lib/net.js)
* @see [source](https://github.com/nodejs/node/blob/v24.x/lib/net.js)
*/
declare module "net" {
import { NonSharedBuffer } from "node:buffer";
import * as stream from "node:stream";
import { Abortable, EventEmitter } from "node:events";
import * as dns from "node:dns";
@@ -29,28 +30,21 @@ declare module "net" {
interface SocketConstructorOpts {
fd?: number | undefined;
allowHalfOpen?: boolean | undefined;
onread?: OnReadOpts | undefined;
readable?: boolean | undefined;
writable?: boolean | undefined;
signal?: AbortSignal;
signal?: AbortSignal | undefined;
}
interface OnReadOpts {
buffer: Uint8Array | (() => Uint8Array);
/**
* This function is called for every chunk of incoming data.
* Two arguments are passed to it: the number of bytes written to buffer and a reference to buffer.
* Return false from this function to implicitly pause() the socket.
* Two arguments are passed to it: the number of bytes written to `buffer` and a reference to `buffer`.
* Return `false` from this function to implicitly `pause()` the socket.
*/
callback(bytesWritten: number, buf: Uint8Array): boolean;
callback(bytesWritten: number, buffer: Uint8Array): boolean;
}
interface ConnectOpts {
/**
* If specified, incoming data is stored in a single buffer and passed to the supplied callback when data arrives on the socket.
* Note: this will cause the streaming functionality to not provide any data, however events like 'error', 'end', and 'close' will
* still be emitted as normal and methods like pause() and resume() will also behave as expected.
*/
onread?: OnReadOpts | undefined;
}
interface TcpSocketConnectOpts extends ConnectOpts {
interface TcpSocketConnectOpts {
port: number;
host?: string | undefined;
localAddress?: string | undefined;
@@ -69,8 +63,9 @@ declare module "net" {
* @since v18.13.0
*/
autoSelectFamilyAttemptTimeout?: number | undefined;
blockList?: BlockList | undefined;
}
interface IpcSocketConnectOpts extends ConnectOpts {
interface IpcSocketConnectOpts {
path: string;
}
type SocketConnectOpts = TcpSocketConnectOpts | IpcSocketConnectOpts;
@@ -112,8 +107,8 @@ declare module "net" {
* @since v0.1.90
* @param [encoding='utf8'] Only used when data is `string`.
*/
write(buffer: Uint8Array | string, cb?: (err?: Error) => void): boolean;
write(str: Uint8Array | string, encoding?: BufferEncoding, cb?: (err?: Error) => void): boolean;
write(buffer: Uint8Array | string, cb?: (err?: Error | null) => void): boolean;
write(str: Uint8Array | string, encoding?: BufferEncoding, cb?: (err?: Error | null) => void): boolean;
/**
* Initiate a connection on a given socket.
*
@@ -327,25 +322,25 @@ declare module "net" {
* the socket is destroyed (for example, if the client disconnected).
* @since v0.5.10
*/
readonly remoteAddress?: string | undefined;
readonly remoteAddress: string | undefined;
/**
* The string representation of the remote IP family. `'IPv4'` or `'IPv6'`. Value may be `undefined` if
* the socket is destroyed (for example, if the client disconnected).
* @since v0.11.14
*/
readonly remoteFamily?: string | undefined;
readonly remoteFamily: string | undefined;
/**
* The numeric representation of the remote port. For example, `80` or `21`. Value may be `undefined` if
* the socket is destroyed (for example, if the client disconnected).
* @since v0.5.10
*/
readonly remotePort?: number | undefined;
readonly remotePort: number | undefined;
/**
* The socket timeout in milliseconds as set by `socket.setTimeout()`.
* It is `undefined` if a timeout has not been set.
* @since v10.7.0
*/
readonly timeout?: number | undefined;
readonly timeout?: number;
/**
* Half-closes the socket. i.e., it sends a FIN packet. It is possible the
* server will still send some data.
@@ -380,13 +375,13 @@ declare module "net" {
addListener(event: "connectionAttempt", listener: (ip: string, port: number, family: number) => void): this;
addListener(
event: "connectionAttemptFailed",
listener: (ip: string, port: number, family: number) => void,
listener: (ip: string, port: number, family: number, error: Error) => void,
): this;
addListener(
event: "connectionAttemptTimeout",
listener: (ip: string, port: number, family: number) => void,
): this;
addListener(event: "data", listener: (data: Buffer) => void): this;
addListener(event: "data", listener: (data: NonSharedBuffer) => void): this;
addListener(event: "drain", listener: () => void): this;
addListener(event: "end", listener: () => void): this;
addListener(event: "error", listener: (err: Error) => void): this;
@@ -400,9 +395,9 @@ declare module "net" {
emit(event: "close", hadError: boolean): boolean;
emit(event: "connect"): boolean;
emit(event: "connectionAttempt", ip: string, port: number, family: number): boolean;
emit(event: "connectionAttemptFailed", ip: string, port: number, family: number): boolean;
emit(event: "connectionAttemptFailed", ip: string, port: number, family: number, error: Error): boolean;
emit(event: "connectionAttemptTimeout", ip: string, port: number, family: number): boolean;
emit(event: "data", data: Buffer): boolean;
emit(event: "data", data: NonSharedBuffer): boolean;
emit(event: "drain"): boolean;
emit(event: "end"): boolean;
emit(event: "error", err: Error): boolean;
@@ -413,9 +408,12 @@ declare module "net" {
on(event: "close", listener: (hadError: boolean) => void): this;
on(event: "connect", listener: () => void): this;
on(event: "connectionAttempt", listener: (ip: string, port: number, family: number) => void): this;
on(event: "connectionAttemptFailed", listener: (ip: string, port: number, family: number) => void): this;
on(
event: "connectionAttemptFailed",
listener: (ip: string, port: number, family: number, error: Error) => void,
): this;
on(event: "connectionAttemptTimeout", listener: (ip: string, port: number, family: number) => void): this;
on(event: "data", listener: (data: Buffer) => void): this;
on(event: "data", listener: (data: NonSharedBuffer) => void): this;
on(event: "drain", listener: () => void): this;
on(event: "end", listener: () => void): this;
on(event: "error", listener: (err: Error) => void): this;
@@ -428,10 +426,13 @@ declare module "net" {
once(event: string, listener: (...args: any[]) => void): this;
once(event: "close", listener: (hadError: boolean) => void): this;
once(event: "connectionAttempt", listener: (ip: string, port: number, family: number) => void): this;
once(event: "connectionAttemptFailed", listener: (ip: string, port: number, family: number) => void): this;
once(
event: "connectionAttemptFailed",
listener: (ip: string, port: number, family: number, error: Error) => void,
): this;
once(event: "connectionAttemptTimeout", listener: (ip: string, port: number, family: number) => void): this;
once(event: "connect", listener: () => void): this;
once(event: "data", listener: (data: Buffer) => void): this;
once(event: "data", listener: (data: NonSharedBuffer) => void): this;
once(event: "drain", listener: () => void): this;
once(event: "end", listener: () => void): this;
once(event: "error", listener: (err: Error) => void): this;
@@ -447,13 +448,13 @@ declare module "net" {
prependListener(event: "connectionAttempt", listener: (ip: string, port: number, family: number) => void): this;
prependListener(
event: "connectionAttemptFailed",
listener: (ip: string, port: number, family: number) => void,
listener: (ip: string, port: number, family: number, error: Error) => void,
): this;
prependListener(
event: "connectionAttemptTimeout",
listener: (ip: string, port: number, family: number) => void,
): this;
prependListener(event: "data", listener: (data: Buffer) => void): this;
prependListener(event: "data", listener: (data: NonSharedBuffer) => void): this;
prependListener(event: "drain", listener: () => void): this;
prependListener(event: "end", listener: () => void): this;
prependListener(event: "error", listener: (err: Error) => void): this;
@@ -472,13 +473,13 @@ declare module "net" {
): this;
prependOnceListener(
event: "connectionAttemptFailed",
listener: (ip: string, port: number, family: number) => void,
listener: (ip: string, port: number, family: number, error: Error) => void,
): this;
prependOnceListener(
event: "connectionAttemptTimeout",
listener: (ip: string, port: number, family: number) => void,
): this;
prependOnceListener(event: "data", listener: (data: Buffer) => void): this;
prependOnceListener(event: "data", listener: (data: NonSharedBuffer) => void): this;
prependOnceListener(event: "drain", listener: () => void): this;
prependOnceListener(event: "end", listener: () => void): this;
prependOnceListener(event: "error", listener: (err: Error) => void): this;
@@ -490,17 +491,18 @@ declare module "net" {
prependOnceListener(event: "timeout", listener: () => void): this;
}
interface ListenOptions extends Abortable {
port?: number | undefined;
host?: string | undefined;
backlog?: number | undefined;
path?: string | undefined;
exclusive?: boolean | undefined;
readableAll?: boolean | undefined;
writableAll?: boolean | undefined;
host?: string | undefined;
/**
* @default false
*/
ipv6Only?: boolean | undefined;
reusePort?: boolean | undefined;
path?: string | undefined;
port?: number | undefined;
readableAll?: boolean | undefined;
writableAll?: boolean | undefined;
}
interface ServerOpts {
/**
@@ -532,6 +534,21 @@ declare module "net" {
* @since v16.5.0
*/
keepAliveInitialDelay?: number | undefined;
/**
* Optionally overrides all `net.Socket`s' `readableHighWaterMark` and `writableHighWaterMark`.
* @default See [stream.getDefaultHighWaterMark()](https://nodejs.org/docs/latest-v24.x/api/stream.html#streamgetdefaulthighwatermarkobjectmode).
* @since v18.17.0, v20.1.0
*/
highWaterMark?: number | undefined;
/**
* `blockList` can be used for disabling inbound
* access to specific IP addresses, IP ranges, or IP subnets. This does not
* work if the server is behind a reverse proxy, NAT, etc. because the address
* checked against the block list is the address of the proxy, or the one
* specified by the NAT.
* @since v22.13.0
*/
blockList?: BlockList | undefined;
}
interface DropArgument {
localAddress?: string;
@@ -643,7 +660,7 @@ declare module "net" {
* Callback should take two arguments `err` and `count`.
* @since v0.9.7
*/
getConnections(cb: (error: Error | null, count: number) => void): void;
getConnections(cb: (error: Error | null, count: number) => void): this;
/**
* Opposite of `unref()`, calling `ref()` on a previously `unref`ed server will _not_ let the program exit if it's the only server left (the default behavior).
* If the server is `ref`ed calling `ref()` again will have no effect.
@@ -783,6 +800,33 @@ declare module "net" {
* @since v15.0.0, v14.18.0
*/
rules: readonly string[];
/**
* Returns `true` if the `value` is a `net.BlockList`.
* @since v22.13.0
* @param value Any JS value
*/
static isBlockList(value: unknown): value is BlockList;
/**
* ```js
* const blockList = new net.BlockList();
* const data = [
* 'Subnet: IPv4 192.168.1.0/24',
* 'Address: IPv4 10.0.0.5',
* 'Range: IPv4 192.168.2.1-192.168.2.10',
* 'Range: IPv4 10.0.0.1-10.0.0.10',
* ];
* blockList.fromJSON(data);
* blockList.fromJSON(JSON.stringify(data));
* ```
* @since v24.5.0
* @experimental
*/
fromJSON(data: string | readonly string[]): void;
/**
* @since v24.5.0
* @experimental
*/
toJSON(): readonly string[];
}
interface TcpNetConnectOpts extends TcpSocketConnectOpts, SocketConstructorOpts {
timeout?: number | undefined;
@@ -812,7 +856,7 @@ declare module "net" {
* on port 8124:
*
* ```js
* const net = require('node:net');
* import net from 'node:net';
* const server = net.createServer((c) => {
* // 'connection' listener.
* console.log('client connected');
@@ -894,6 +938,9 @@ declare module "net" {
function getDefaultAutoSelectFamily(): boolean;
/**
* Sets the default value of the `autoSelectFamily` option of `socket.connect(options)`.
* @param value The new default value.
* The initial default value is `true`, unless the command line option
* `--no-network-family-autoselection` is provided.
* @since v19.4.0
*/
function setDefaultAutoSelectFamily(value: boolean): void;
@@ -992,6 +1039,14 @@ declare module "net" {
* @since v15.14.0, v14.18.0
*/
readonly flowlabel: number;
/**
* @since v22.13.0
* @param input An input string containing an IP address and optional port,
* e.g. `123.1.2.3:1234` or `[1::1]:1234`.
* @returns Returns a `SocketAddress` if parsing was successful.
* Otherwise returns `undefined`.
*/
static parse(input: string): SocketAddress | undefined;
}
}
declare module "node:net" {

View File

@@ -3,11 +3,12 @@
* properties. It can be accessed using:
*
* ```js
* const os = require('node:os');
* import os from 'node:os';
* ```
* @see [source](https://github.com/nodejs/node/blob/v20.13.1/lib/os.js)
* @see [source](https://github.com/nodejs/node/blob/v24.x/lib/os.js)
*/
declare module "os" {
import { NonSharedBuffer } from "buffer";
interface CpuInfo {
model: string;
speed: number;
@@ -30,10 +31,10 @@ declare module "os" {
mac: string;
internal: boolean;
cidr: string | null;
scopeid?: number;
}
interface NetworkInterfaceInfoIPv4 extends NetworkInterfaceBase {
family: "IPv4";
scopeid?: undefined;
}
interface NetworkInterfaceInfoIPv6 extends NetworkInterfaceBase {
family: "IPv6";
@@ -231,6 +232,15 @@ declare module "os" {
* @since v2.3.0
*/
function homedir(): string;
interface UserInfoOptions {
encoding?: BufferEncoding | "buffer" | undefined;
}
interface UserInfoOptionsWithBufferEncoding extends UserInfoOptions {
encoding: "buffer";
}
interface UserInfoOptionsWithStringEncoding extends UserInfoOptions {
encoding?: BufferEncoding | undefined;
}
/**
* Returns information about the currently effective user. On POSIX platforms,
* this is typically a subset of the password file. The returned object includes
@@ -241,11 +251,12 @@ declare module "os" {
* environment variables for the home directory before falling back to the
* operating system response.
*
* Throws a [`SystemError`](https://nodejs.org/docs/latest-v20.x/api/errors.html#class-systemerror) if a user has no `username` or `homedir`.
* Throws a [`SystemError`](https://nodejs.org/docs/latest-v24.x/api/errors.html#class-systemerror) if a user has no `username` or `homedir`.
* @since v6.0.0
*/
function userInfo(options: { encoding: "buffer" }): UserInfo<Buffer>;
function userInfo(options?: { encoding: BufferEncoding }): UserInfo<string>;
function userInfo(options?: UserInfoOptionsWithStringEncoding): UserInfo<string>;
function userInfo(options: UserInfoOptionsWithBufferEncoding): UserInfo<NonSharedBuffer>;
function userInfo(options: UserInfoOptions): UserInfo<string | NonSharedBuffer>;
type SignalConstants = {
[key in NodeJS.Signals]: number;
};
@@ -417,13 +428,13 @@ declare module "os" {
const EOL: string;
/**
* Returns the operating system CPU architecture for which the Node.js binary was
* compiled. Possible values are `'arm'`, `'arm64'`, `'ia32'`, `'loong64'`, `'mips'`, `'mipsel'`, `'ppc'`, `'ppc64'`, `'riscv64'`, `'s390'`, `'s390x'`,
* and `'x64'`.
* compiled. Possible values are `'arm'`, `'arm64'`, `'ia32'`, `'loong64'`,
* `'mips'`, `'mipsel'`, `'ppc64'`, `'riscv64'`, `'s390x'`, and `'x64'`.
*
* The return value is equivalent to [process.arch](https://nodejs.org/docs/latest-v20.x/api/process.html#processarch).
* The return value is equivalent to [process.arch](https://nodejs.org/docs/latest-v24.x/api/process.html#processarch).
* @since v0.5.0
*/
function arch(): string;
function arch(): NodeJS.Architecture;
/**
* Returns a string identifying the kernel version.
*
@@ -445,7 +456,8 @@ declare module "os" {
*/
function platform(): NodeJS.Platform;
/**
* Returns the machine type as a string, such as `arm`, `arm64`, `aarch64`, `mips`, `mips64`, `ppc64`, `ppc64le`, `s390`, `s390x`, `i386`, `i686`, `x86_64`.
* Returns the machine type as a string, such as `arm`, `arm64`, `aarch64`,
* `mips`, `mips64`, `ppc64`, `ppc64le`, `s390x`, `i386`, `i686`, `x86_64`.
*
* On POSIX systems, the machine type is determined by calling [`uname(3)`](https://linux.die.net/man/3/uname). On Windows, `RtlGetVersion()` is used, and if it is not
* available, `GetVersionExW()` will be used. See [https://en.wikipedia.org/wiki/Uname#Examples](https://en.wikipedia.org/wiki/Uname#Examples) for more information.

View File

@@ -1,6 +1,6 @@
{
"name": "@types/node",
"version": "20.14.12",
"version": "24.10.0",
"description": "TypeScript definitions for node",
"homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node",
"license": "MIT",
@@ -15,11 +15,6 @@
"githubUsername": "jkomyno",
"url": "https://github.com/jkomyno"
},
{
"name": "Alvis HT Tang",
"githubUsername": "alvis",
"url": "https://github.com/alvis"
},
{
"name": "Andrew Makarov",
"githubUsername": "r3nya",
@@ -30,56 +25,11 @@
"githubUsername": "btoueg",
"url": "https://github.com/btoueg"
},
{
"name": "Chigozirim C.",
"githubUsername": "smac89",
"url": "https://github.com/smac89"
},
{
"name": "David Junger",
"githubUsername": "touffy",
"url": "https://github.com/touffy"
},
{
"name": "Deividas Bakanas",
"githubUsername": "DeividasBakanas",
"url": "https://github.com/DeividasBakanas"
},
{
"name": "Eugene Y. Q. Shen",
"githubUsername": "eyqs",
"url": "https://github.com/eyqs"
},
{
"name": "Hannes Magnusson",
"githubUsername": "Hannes-Magnusson-CK",
"url": "https://github.com/Hannes-Magnusson-CK"
},
{
"name": "Huw",
"githubUsername": "hoo29",
"url": "https://github.com/hoo29"
},
{
"name": "Kelvin Jin",
"githubUsername": "kjin",
"url": "https://github.com/kjin"
},
{
"name": "Klaus Meinhardt",
"githubUsername": "ajafff",
"url": "https://github.com/ajafff"
},
{
"name": "Lishude",
"githubUsername": "islishude",
"url": "https://github.com/islishude"
},
{
"name": "Mariusz Wiktorczyk",
"githubUsername": "mwiktorczyk",
"url": "https://github.com/mwiktorczyk"
},
{
"name": "Mohsen Azimi",
"githubUsername": "mohsen1",
@@ -90,46 +40,16 @@
"githubUsername": "galkin",
"url": "https://github.com/galkin"
},
{
"name": "Parambir Singh",
"githubUsername": "parambirs",
"url": "https://github.com/parambirs"
},
{
"name": "Sebastian Silbermann",
"githubUsername": "eps1lon",
"url": "https://github.com/eps1lon"
},
{
"name": "Thomas den Hollander",
"githubUsername": "ThomasdenH",
"url": "https://github.com/ThomasdenH"
},
{
"name": "Wilco Bakker",
"githubUsername": "WilcoBakker",
"url": "https://github.com/WilcoBakker"
},
{
"name": "wwwy3y3",
"githubUsername": "wwwy3y3",
"url": "https://github.com/wwwy3y3"
},
{
"name": "Samuel Ainsworth",
"githubUsername": "samuela",
"url": "https://github.com/samuela"
},
{
"name": "Kyle Uehlein",
"githubUsername": "kuehlein",
"url": "https://github.com/kuehlein"
},
{
"name": "Thanik Bhongbhibhat",
"githubUsername": "bhongy",
"url": "https://github.com/bhongy"
},
{
"name": "Marcin Kopacz",
"githubUsername": "chyzwar",
@@ -170,11 +90,6 @@
"githubUsername": "victorperin",
"url": "https://github.com/victorperin"
},
{
"name": "Yongsheng Zhang",
"githubUsername": "ZYSzys",
"url": "https://github.com/ZYSzys"
},
{
"name": "NodeJS Contributors",
"githubUsername": "NodeJS",
@@ -199,10 +114,32 @@
"name": "Dmitry Semigradsky",
"githubUsername": "Semigradsky",
"url": "https://github.com/Semigradsky"
},
{
"name": "René",
"githubUsername": "Renegade334",
"url": "https://github.com/Renegade334"
},
{
"name": "Yagiz Nizipli",
"githubUsername": "anonrig",
"url": "https://github.com/anonrig"
}
],
"main": "",
"types": "index.d.ts",
"typesVersions": {
"<=5.6": {
"*": [
"ts5.6/*"
]
},
"<=5.7": {
"*": [
"ts5.7/*"
]
}
},
"repository": {
"type": "git",
"url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git",
@@ -210,8 +147,9 @@
},
"scripts": {},
"dependencies": {
"undici-types": "~5.26.4"
"undici-types": "~7.16.0"
},
"typesPublisherContentHash": "9e6a411f225bdb4e807bf8a25271d2fc7c8aa163691598117f118732284e76e0",
"typeScriptVersion": "4.8"
"peerDependencies": {},
"typesPublisherContentHash": "520eb7d36290a7656940213fbf34026408b9af9ff538455bf669b4ea7a21d5bf",
"typeScriptVersion": "5.2"
}

View File

@@ -11,9 +11,9 @@ declare module "path/win32" {
* paths. It can be accessed using:
*
* ```js
* const path = require('node:path');
* import path from 'node:path';
* ```
* @see [source](https://github.com/nodejs/node/blob/v20.13.1/lib/path.js)
* @see [source](https://github.com/nodejs/node/blob/v24.x/lib/path.js)
*/
declare module "path" {
namespace path {
@@ -94,6 +94,15 @@ declare module "path" {
* @throws {TypeError} if any of the arguments is not a string.
*/
resolve(...paths: string[]): string;
/**
* The `path.matchesGlob()` method determines if `path` matches the `pattern`.
* @param path The path to glob-match against.
* @param pattern The glob to check the path against.
* @returns Whether or not the `path` matched the `pattern`.
* @throws {TypeError} if `path` or `pattern` are not strings.
* @since v22.5.0
*/
matchesGlob(path: string, pattern: string): boolean;
/**
* Determines whether {path} is an absolute path. An absolute path will always resolve to the same location, regardless of the working directory.
*

View File

@@ -10,7 +10,7 @@
* * [Resource Timing](https://www.w3.org/TR/resource-timing-2/)
*
* ```js
* const { PerformanceObserver, performance } = require('node:perf_hooks');
* import { PerformanceObserver, performance } from 'node:perf_hooks';
*
* const obs = new PerformanceObserver((items) => {
* console.log(items.getEntries()[0].duration);
@@ -27,24 +27,34 @@
* performance.measure('A to B', 'A', 'B');
* });
* ```
* @see [source](https://github.com/nodejs/node/blob/v20.13.1/lib/perf_hooks.js)
* @see [source](https://github.com/nodejs/node/blob/v24.x/lib/perf_hooks.js)
*/
declare module "perf_hooks" {
import { AsyncResource } from "node:async_hooks";
type EntryType = "node" | "mark" | "measure" | "gc" | "function" | "http2" | "http" | "dns" | "net";
type EntryType =
| "dns" // Node.js only
| "function" // Node.js only
| "gc" // Node.js only
| "http2" // Node.js only
| "http" // Node.js only
| "mark" // available on the Web
| "measure" // available on the Web
| "net" // Node.js only
| "node" // Node.js only
| "resource"; // available on the Web
interface NodeGCPerformanceDetail {
/**
* When `performanceEntry.entryType` is equal to 'gc', the `performance.kind` property identifies
* the type of garbage collection operation that occurred.
* See perf_hooks.constants for valid values.
*/
readonly kind?: number | undefined;
readonly kind: number;
/**
* When `performanceEntry.entryType` is equal to 'gc', the `performance.flags`
* property contains additional information about garbage collection operation.
* See perf_hooks.constants for valid values.
*/
readonly flags?: number | undefined;
readonly flags: number;
}
/**
* The constructor of this class is not exposed to users directly.
@@ -82,11 +92,6 @@ declare module "perf_hooks" {
* @since v8.5.0
*/
readonly entryType: EntryType;
/**
* Additional detail specific to the `entryType`.
* @since v16.0.0
*/
readonly detail?: NodeGCPerformanceDetail | unknown | undefined; // TODO: Narrow this based on entry type.
toJSON(): any;
}
/**
@@ -94,6 +99,7 @@ declare module "perf_hooks" {
* @since v18.2.0, v16.17.0
*/
class PerformanceMark extends PerformanceEntry {
readonly detail: any;
readonly duration: 0;
readonly entryType: "mark";
}
@@ -104,8 +110,24 @@ declare module "perf_hooks" {
* @since v18.2.0, v16.17.0
*/
class PerformanceMeasure extends PerformanceEntry {
readonly detail: any;
readonly entryType: "measure";
}
interface UVMetrics {
/**
* Number of event loop iterations.
*/
readonly loopCount: number;
/**
* Number of events that have been processed by the event handler.
*/
readonly events: number;
/**
* Number of events that were waiting to be processed when the event provider was called.
*/
readonly eventsWaiting: number;
}
// TODO: PerformanceNodeEntry is missing
/**
* _This property is an extension by Node.js. It is not available in Web browsers._
*
@@ -114,6 +136,7 @@ declare module "perf_hooks" {
* @since v8.5.0
*/
class PerformanceNodeTiming extends PerformanceEntry {
readonly entryType: "node";
/**
* The high resolution millisecond timestamp at which the Node.js process
* completed bootstrapping. If bootstrapping has not yet finished, the property
@@ -155,6 +178,16 @@ declare module "perf_hooks" {
* @since v8.5.0
*/
readonly nodeStart: number;
/**
* This is a wrapper to the `uv_metrics_info` function.
* It returns the current set of event loop metrics.
*
* It is recommended to use this property inside a function whose execution was
* scheduled using `setImmediate` to avoid collecting metrics before finishing all
* operations scheduled during the current loop iteration.
* @since v22.8.0, v20.18.0
*/
readonly uvMetricsInfo: UVMetrics;
/**
* The high resolution millisecond timestamp at which the V8 platform was
* initialized.
@@ -190,7 +223,7 @@ declare module "perf_hooks" {
/**
* Additional optional detail to include with the mark.
*/
detail?: unknown | undefined;
detail?: unknown;
/**
* Duration between start and end times.
*/
@@ -270,6 +303,30 @@ declare module "perf_hooks" {
* @param name
*/
mark(name: string, options?: MarkOptions): PerformanceMark;
/**
* Creates a new `PerformanceResourceTiming` entry in the Resource Timeline.
* A `PerformanceResourceTiming` is a subclass of `PerformanceEntry` whose `performanceEntry.entryType` is always `'resource'`.
* Performance resources are used to mark moments in the Resource Timeline.
* @param timingInfo [Fetch Timing Info](https://fetch.spec.whatwg.org/#fetch-timing-info)
* @param requestedUrl The resource url
* @param initiatorType The initiator name, e.g: 'fetch'
* @param global
* @param cacheMode The cache mode must be an empty string ('') or 'local'
* @param bodyInfo [Fetch Response Body Info](https://fetch.spec.whatwg.org/#response-body-info)
* @param responseStatus The response's status code
* @param deliveryType The delivery type. Default: ''.
* @since v18.2.0, v16.17.0
*/
markResourceTiming(
timingInfo: object,
requestedUrl: string,
initiatorType: string,
global: object,
cacheMode: "" | "local",
bodyInfo: object,
responseStatus: number,
deliveryType?: string,
): PerformanceResourceTiming;
/**
* Creates a new PerformanceMeasure entry in the Performance Timeline.
* A PerformanceMeasure is a subclass of PerformanceEntry whose performanceEntry.entryType is always 'measure',
@@ -320,10 +377,10 @@ declare module "perf_hooks" {
* A `PerformanceObserver` must be subscribed to the `'function'` event type in order for the timing details to be accessed.
*
* ```js
* const {
* import {
* performance,
* PerformanceObserver,
* } = require('node:perf_hooks');
* } from 'node:perf_hooks';
*
* function someFunction() {
* console.log('hello world');
@@ -362,10 +419,10 @@ declare module "perf_hooks" {
* with respect to `performanceEntry.startTime`.
*
* ```js
* const {
* import {
* performance,
* PerformanceObserver,
* } = require('node:perf_hooks');
* } from 'node:perf_hooks';
*
* const obs = new PerformanceObserver((perfObserverList, observer) => {
* console.log(perfObserverList.getEntries());
@@ -405,10 +462,10 @@ declare module "perf_hooks" {
* equal to `name`, and optionally, whose `performanceEntry.entryType` is equal to`type`.
*
* ```js
* const {
* import {
* performance,
* PerformanceObserver,
* } = require('node:perf_hooks');
* } from 'node:perf_hooks';
*
* const obs = new PerformanceObserver((perfObserverList, observer) => {
* console.log(perfObserverList.getEntriesByName('meow'));
@@ -456,10 +513,10 @@ declare module "perf_hooks" {
* with respect to `performanceEntry.startTime` whose `performanceEntry.entryType` is equal to `type`.
*
* ```js
* const {
* import {
* performance,
* PerformanceObserver,
* } = require('node:perf_hooks');
* } from 'node:perf_hooks';
*
* const obs = new PerformanceObserver((perfObserverList, observer) => {
* console.log(perfObserverList.getEntriesByType('mark'));
@@ -509,10 +566,10 @@ declare module "perf_hooks" {
* Subscribes the `PerformanceObserver` instance to notifications of new `PerformanceEntry` instances identified either by `options.entryTypes` or `options.type`:
*
* ```js
* const {
* import {
* performance,
* PerformanceObserver,
* } = require('node:perf_hooks');
* } from 'node:perf_hooks';
*
* const obs = new PerformanceObserver((list, observer) => {
* // Called once asynchronously. `list` contains three items.
@@ -535,6 +592,11 @@ declare module "perf_hooks" {
buffered?: boolean | undefined;
},
): void;
/**
* @since v16.0.0
* @returns Current list of entries stored in the performance observer, emptying it out.
*/
takeRecords(): PerformanceEntry[];
}
/**
* Provides detailed network timing data regarding the loading of an application's resources.
@@ -543,6 +605,7 @@ declare module "perf_hooks" {
* @since v18.2.0, v16.17.0
*/
class PerformanceResourceTiming extends PerformanceEntry {
readonly entryType: "resource";
protected constructor();
/**
* The high resolution millisecond timestamp at immediately before dispatching the `fetch`
@@ -748,6 +811,20 @@ declare module "perf_hooks" {
* @since v11.10.0
*/
disable(): boolean;
/**
* Disables the update interval timer when the histogram is disposed.
*
* ```js
* const { monitorEventLoopDelay } = require('node:perf_hooks');
* {
* using hist = monitorEventLoopDelay({ resolution: 20 });
* hist.enable();
* // The histogram will be disabled when the block is exited.
* }
* ```
* @since v24.2.0
*/
[Symbol.dispose](): void;
}
interface RecordableHistogram extends Histogram {
/**
@@ -780,7 +857,7 @@ declare module "perf_hooks" {
* detect.
*
* ```js
* const { monitorEventLoopDelay } = require('node:perf_hooks');
* import { monitorEventLoopDelay } from 'node:perf_hooks';
* const h = monitorEventLoopDelay({ resolution: 20 });
* h.enable();
* // Do something.
@@ -801,12 +878,12 @@ declare module "perf_hooks" {
* The minimum recordable value. Must be an integer value greater than 0.
* @default 1
*/
min?: number | bigint | undefined;
lowest?: number | bigint | undefined;
/**
* The maximum recordable value. Must be an integer value greater than min.
* @default Number.MAX_SAFE_INTEGER
*/
max?: number | bigint | undefined;
highest?: number | bigint | undefined;
/**
* The number of accuracy digits. Must be a number between 1 and 5.
* @default 3
@@ -829,8 +906,8 @@ declare module "perf_hooks" {
} from "perf_hooks";
global {
/**
* `PerformanceEntry` is a global reference for `require('node:perf_hooks').PerformanceEntry`
* @see https://nodejs.org/docs/latest-v20.x/api/globals.html#performanceentry
* `PerformanceEntry` is a global reference for `import { PerformanceEntry } from 'node:perf_hooks'`
* @see https://nodejs.org/docs/latest-v24.x/api/globals.html#performanceentry
* @since v19.0.0
*/
var PerformanceEntry: typeof globalThis extends {
@@ -839,8 +916,8 @@ declare module "perf_hooks" {
} ? T
: typeof _PerformanceEntry;
/**
* `PerformanceMark` is a global reference for `require('node:perf_hooks').PerformanceMark`
* @see https://nodejs.org/docs/latest-v20.x/api/globals.html#performancemark
* `PerformanceMark` is a global reference for `import { PerformanceMark } from 'node:perf_hooks'`
* @see https://nodejs.org/docs/latest-v24.x/api/globals.html#performancemark
* @since v19.0.0
*/
var PerformanceMark: typeof globalThis extends {
@@ -849,8 +926,8 @@ declare module "perf_hooks" {
} ? T
: typeof _PerformanceMark;
/**
* `PerformanceMeasure` is a global reference for `require('node:perf_hooks').PerformanceMeasure`
* @see https://nodejs.org/docs/latest-v20.x/api/globals.html#performancemeasure
* `PerformanceMeasure` is a global reference for `import { PerformanceMeasure } from 'node:perf_hooks'`
* @see https://nodejs.org/docs/latest-v24.x/api/globals.html#performancemeasure
* @since v19.0.0
*/
var PerformanceMeasure: typeof globalThis extends {
@@ -859,8 +936,8 @@ declare module "perf_hooks" {
} ? T
: typeof _PerformanceMeasure;
/**
* `PerformanceObserver` is a global reference for `require('node:perf_hooks').PerformanceObserver`
* @see https://nodejs.org/docs/latest-v20.x/api/globals.html#performanceobserver
* `PerformanceObserver` is a global reference for `import { PerformanceObserver } from 'node:perf_hooks'`
* @see https://nodejs.org/docs/latest-v24.x/api/globals.html#performanceobserver
* @since v19.0.0
*/
var PerformanceObserver: typeof globalThis extends {
@@ -869,8 +946,8 @@ declare module "perf_hooks" {
} ? T
: typeof _PerformanceObserver;
/**
* `PerformanceObserverEntryList` is a global reference for `require('node:perf_hooks').PerformanceObserverEntryList`
* @see https://nodejs.org/docs/latest-v20.x/api/globals.html#performanceobserverentrylist
* `PerformanceObserverEntryList` is a global reference for `import { PerformanceObserverEntryList } from 'node:perf_hooks'`
* @see https://nodejs.org/docs/latest-v24.x/api/globals.html#performanceobserverentrylist
* @since v19.0.0
*/
var PerformanceObserverEntryList: typeof globalThis extends {
@@ -879,8 +956,8 @@ declare module "perf_hooks" {
} ? T
: typeof _PerformanceObserverEntryList;
/**
* `PerformanceResourceTiming` is a global reference for `require('node:perf_hooks').PerformanceResourceTiming`
* @see https://nodejs.org/docs/latest-v20.x/api/globals.html#performanceresourcetiming
* `PerformanceResourceTiming` is a global reference for `import { PerformanceResourceTiming } from 'node:perf_hooks'`
* @see https://nodejs.org/docs/latest-v24.x/api/globals.html#performanceresourcetiming
* @since v19.0.0
*/
var PerformanceResourceTiming: typeof globalThis extends {
@@ -889,8 +966,8 @@ declare module "perf_hooks" {
} ? T
: typeof _PerformanceResourceTiming;
/**
* `performance` is a global reference for `require('node:perf_hooks').performance`
* @see https://nodejs.org/docs/latest-v20.x/api/globals.html#performance
* `performance` is a global reference for `import { performance } from 'node:perf_hooks'`
* @see https://nodejs.org/docs/latest-v24.x/api/globals.html#performance
* @since v16.0.0
*/
var performance: typeof globalThis extends {

View File

@@ -1,8 +1,123 @@
declare module "process" {
import * as net from "node:net";
import * as os from "node:os";
import { Control, MessageOptions, SendHandle } from "node:child_process";
import { PathLike } from "node:fs";
import * as tty from "node:tty";
import { Worker } from "node:worker_threads";
interface BuiltInModule {
"assert": typeof import("assert");
"node:assert": typeof import("node:assert");
"assert/strict": typeof import("assert/strict");
"node:assert/strict": typeof import("node:assert/strict");
"async_hooks": typeof import("async_hooks");
"node:async_hooks": typeof import("node:async_hooks");
"buffer": typeof import("buffer");
"node:buffer": typeof import("node:buffer");
"child_process": typeof import("child_process");
"node:child_process": typeof import("node:child_process");
"cluster": typeof import("cluster");
"node:cluster": typeof import("node:cluster");
"console": typeof import("console");
"node:console": typeof import("node:console");
"constants": typeof import("constants");
"node:constants": typeof import("node:constants");
"crypto": typeof import("crypto");
"node:crypto": typeof import("node:crypto");
"dgram": typeof import("dgram");
"node:dgram": typeof import("node:dgram");
"diagnostics_channel": typeof import("diagnostics_channel");
"node:diagnostics_channel": typeof import("node:diagnostics_channel");
"dns": typeof import("dns");
"node:dns": typeof import("node:dns");
"dns/promises": typeof import("dns/promises");
"node:dns/promises": typeof import("node:dns/promises");
"domain": typeof import("domain");
"node:domain": typeof import("node:domain");
"events": typeof import("events");
"node:events": typeof import("node:events");
"fs": typeof import("fs");
"node:fs": typeof import("node:fs");
"fs/promises": typeof import("fs/promises");
"node:fs/promises": typeof import("node:fs/promises");
"http": typeof import("http");
"node:http": typeof import("node:http");
"http2": typeof import("http2");
"node:http2": typeof import("node:http2");
"https": typeof import("https");
"node:https": typeof import("node:https");
"inspector": typeof import("inspector");
"node:inspector": typeof import("node:inspector");
"inspector/promises": typeof import("inspector/promises");
"node:inspector/promises": typeof import("node:inspector/promises");
"module": typeof import("module");
"node:module": typeof import("node:module");
"net": typeof import("net");
"node:net": typeof import("node:net");
"os": typeof import("os");
"node:os": typeof import("node:os");
"path": typeof import("path");
"node:path": typeof import("node:path");
"path/posix": typeof import("path/posix");
"node:path/posix": typeof import("node:path/posix");
"path/win32": typeof import("path/win32");
"node:path/win32": typeof import("node:path/win32");
"perf_hooks": typeof import("perf_hooks");
"node:perf_hooks": typeof import("node:perf_hooks");
"process": typeof import("process");
"node:process": typeof import("node:process");
"punycode": typeof import("punycode");
"node:punycode": typeof import("node:punycode");
"querystring": typeof import("querystring");
"node:querystring": typeof import("node:querystring");
"readline": typeof import("readline");
"node:readline": typeof import("node:readline");
"readline/promises": typeof import("readline/promises");
"node:readline/promises": typeof import("node:readline/promises");
"repl": typeof import("repl");
"node:repl": typeof import("node:repl");
"node:sea": typeof import("node:sea");
"node:sqlite": typeof import("node:sqlite");
"stream": typeof import("stream");
"node:stream": typeof import("node:stream");
"stream/consumers": typeof import("stream/consumers");
"node:stream/consumers": typeof import("node:stream/consumers");
"stream/promises": typeof import("stream/promises");
"node:stream/promises": typeof import("node:stream/promises");
"stream/web": typeof import("stream/web");
"node:stream/web": typeof import("node:stream/web");
"string_decoder": typeof import("string_decoder");
"node:string_decoder": typeof import("node:string_decoder");
"node:test": typeof import("node:test");
"node:test/reporters": typeof import("node:test/reporters");
"timers": typeof import("timers");
"node:timers": typeof import("node:timers");
"timers/promises": typeof import("timers/promises");
"node:timers/promises": typeof import("node:timers/promises");
"tls": typeof import("tls");
"node:tls": typeof import("node:tls");
"trace_events": typeof import("trace_events");
"node:trace_events": typeof import("node:trace_events");
"tty": typeof import("tty");
"node:tty": typeof import("node:tty");
"url": typeof import("url");
"node:url": typeof import("node:url");
"util": typeof import("util");
"node:util": typeof import("node:util");
"sys": typeof import("util");
"node:sys": typeof import("node:util");
"util/types": typeof import("util/types");
"node:util/types": typeof import("node:util/types");
"v8": typeof import("v8");
"node:v8": typeof import("node:v8");
"vm": typeof import("vm");
"node:vm": typeof import("node:vm");
"wasi": typeof import("wasi");
"node:wasi": typeof import("node:wasi");
"worker_threads": typeof import("worker_threads");
"node:worker_threads": typeof import("node:worker_threads");
"zlib": typeof import("zlib");
"node:zlib": typeof import("node:zlib");
}
global {
var process: NodeJS.Process;
namespace NodeJS {
@@ -55,6 +170,84 @@ declare module "process" {
libUrl?: string | undefined;
lts?: string | undefined;
}
interface ProcessFeatures {
/**
* A boolean value that is `true` if the current Node.js build is caching builtin modules.
* @since v12.0.0
*/
readonly cached_builtins: boolean;
/**
* A boolean value that is `true` if the current Node.js build is a debug build.
* @since v0.5.5
*/
readonly debug: boolean;
/**
* A boolean value that is `true` if the current Node.js build includes the inspector.
* @since v11.10.0
*/
readonly inspector: boolean;
/**
* A boolean value that is `true` if the current Node.js build includes support for IPv6.
*
* Since all Node.js builds have IPv6 support, this value is always `true`.
* @since v0.5.3
* @deprecated This property is always true, and any checks based on it are redundant.
*/
readonly ipv6: boolean;
/**
* A boolean value that is `true` if the current Node.js build supports
* [loading ECMAScript modules using `require()`](https://nodejs.org/docs/latest-v24.x/api/modules.md#loading-ecmascript-modules-using-require).
* @since v22.10.0
*/
readonly require_module: boolean;
/**
* A boolean value that is `true` if the current Node.js build includes support for TLS.
* @since v0.5.3
*/
readonly tls: boolean;
/**
* A boolean value that is `true` if the current Node.js build includes support for ALPN in TLS.
*
* In Node.js 11.0.0 and later versions, the OpenSSL dependencies feature unconditional ALPN support.
* This value is therefore identical to that of `process.features.tls`.
* @since v4.8.0
* @deprecated Use `process.features.tls` instead.
*/
readonly tls_alpn: boolean;
/**
* A boolean value that is `true` if the current Node.js build includes support for OCSP in TLS.
*
* In Node.js 11.0.0 and later versions, the OpenSSL dependencies feature unconditional OCSP support.
* This value is therefore identical to that of `process.features.tls`.
* @since v0.11.13
* @deprecated Use `process.features.tls` instead.
*/
readonly tls_ocsp: boolean;
/**
* A boolean value that is `true` if the current Node.js build includes support for SNI in TLS.
*
* In Node.js 11.0.0 and later versions, the OpenSSL dependencies feature unconditional SNI support.
* This value is therefore identical to that of `process.features.tls`.
* @since v0.5.3
* @deprecated Use `process.features.tls` instead.
*/
readonly tls_sni: boolean;
/**
* A value that is `"strip"` by default,
* `"transform"` if Node.js is run with `--experimental-transform-types`, and `false` if
* Node.js is run with `--no-experimental-strip-types`.
* @since v22.10.0
*/
readonly typescript: "strip" | "transform" | false;
/**
* A boolean value that is `true` if the current Node.js build includes support for libuv.
*
* Since it's not possible to build Node.js without libuv, this value is always `true`.
* @since v0.5.3
* @deprecated This property is always true, and any checks based on it are redundant.
*/
readonly uv: boolean;
}
interface ProcessVersions extends Dict<string> {
http_parser: string;
node: string;
@@ -84,10 +277,8 @@ declare module "process" {
| "loong64"
| "mips"
| "mipsel"
| "ppc"
| "ppc64"
| "riscv64"
| "s390"
| "s390x"
| "x64";
type Signals =
@@ -141,7 +332,7 @@ declare module "process" {
*/
type UnhandledRejectionListener = (reason: unknown, promise: Promise<unknown>) => void;
type WarningListener = (warning: Error) => void;
type MessageListener = (message: unknown, sendHandle: unknown) => void;
type MessageListener = (message: unknown, sendHandle: SendHandle) => void;
type SignalsListener = (signal: Signals) => void;
type MultipleResolveListener = (
type: MultipleResolveType,
@@ -157,14 +348,46 @@ declare module "process" {
/**
* Can be used to change the default timezone at runtime
*/
TZ?: string;
TZ?: string | undefined;
}
interface HRTime {
/**
* This is the legacy version of {@link process.hrtime.bigint()}
* before bigint was introduced in JavaScript.
*
* The `process.hrtime()` method returns the current high-resolution real time in a `[seconds, nanoseconds]` tuple `Array`,
* where `nanoseconds` is the remaining part of the real time that can't be represented in second precision.
*
* `time` is an optional parameter that must be the result of a previous `process.hrtime()` call to diff with the current time.
* If the parameter passed in is not a tuple `Array`, a TypeError will be thrown.
* Passing in a user-defined array instead of the result of a previous call to `process.hrtime()` will lead to undefined behavior.
*
* These times are relative to an arbitrary time in the past,
* and not related to the time of day and therefore not subject to clock drift.
* The primary use is for measuring performance between intervals:
* ```js
* const { hrtime } = require('node:process');
* const NS_PER_SEC = 1e9;
* const time = hrtime();
* // [ 1800216, 25 ]
*
* setTimeout(() => {
* const diff = hrtime(time);
* // [ 1, 552 ]
*
* console.log(`Benchmark took ${diff[0] * NS_PER_SEC + diff[1]} nanoseconds`);
* // Benchmark took 1000000552 nanoseconds
* }, 1000);
* ```
* @since 0.7.6
* @legacy Use {@link process.hrtime.bigint()} instead.
* @param time The result of a previous call to `process.hrtime()`
*/
(time?: [number, number]): [number, number];
/**
* The `bigint` version of the `{@link hrtime()}` method returning the current high-resolution real time in nanoseconds as a `bigint`.
* The `bigint` version of the {@link process.hrtime()} method returning the current high-resolution real time in nanoseconds as a `bigint`.
*
* Unlike `{@link hrtime()}`, it does not support an additional time argument since the difference can just be computed directly by subtraction of the two `bigint`s.
* Unlike {@link process.hrtime()}, it does not support an additional time argument since the difference can just be computed directly by subtraction of the two `bigint`s.
* ```js
* import { hrtime } from 'node:process';
*
@@ -179,6 +402,7 @@ declare module "process" {
* // Benchmark took 1154389282 nanoseconds
* }, 1000);
* ```
* @since v10.7.0
*/
bigint(): bigint;
}
@@ -209,24 +433,28 @@ declare module "process" {
has(scope: string, reference?: string): boolean;
}
interface ProcessReport {
/**
* Write reports in a compact format, single-line JSON, more easily consumable by log processing systems
* than the default multi-line format designed for human consumption.
* @since v13.12.0, v12.17.0
*/
compact: boolean;
/**
* Directory where the report is written.
* The default value is the empty string, indicating that reports are written to the current
* working directory of the Node.js process.
* @default '' indicating that reports are written to the current
*/
directory: string;
/**
* Filename where the report is written.
* The default value is the empty string.
* @default '' the output filename will be comprised of a timestamp,
* PID, and sequence number.
* Filename where the report is written. If set to the empty string, the output filename will be comprised
* of a timestamp, PID, and sequence number. The default value is the empty string.
*/
filename: string;
/**
* Returns a JSON-formatted diagnostic report for the running process.
* The report's JavaScript stack trace is taken from err, if present.
* Returns a JavaScript Object representation of a diagnostic report for the running process.
* The report's JavaScript stack trace is taken from `err`, if present.
*/
getReport(err?: Error): string;
getReport(err?: Error): object;
/**
* If true, a diagnostic report is generated on fatal errors,
* such as out of memory errors or failed C++ assertions.
@@ -252,18 +480,19 @@ declare module "process" {
/**
* Writes a diagnostic report to a file. If filename is not provided, the default filename
* includes the date, time, PID, and a sequence number.
* The report's JavaScript stack trace is taken from err, if present.
* The report's JavaScript stack trace is taken from `err`, if present.
*
* If the value of filename is set to `'stdout'` or `'stderr'`, the report is written
* to the stdout or stderr of the process respectively.
* @param fileName Name of the file where the report is written.
* This should be a relative path, that will be appended to the directory specified in
* `process.report.directory`, or the current working directory of the Node.js process,
* if unspecified.
* @param error A custom error used for reporting the JavaScript stack.
* @param err A custom error used for reporting the JavaScript stack.
* @return Filename of the generated report.
*/
writeReport(fileName?: string): string;
writeReport(error?: Error): string;
writeReport(fileName?: string, err?: Error): string;
writeReport(err?: Error): string;
}
interface ResourceUsage {
fsRead: number;
@@ -520,7 +749,7 @@ declare module "process" {
* should not be used directly, except in special cases. In other words, `require()` should be preferred over `process.dlopen()`
* unless there are specific reasons such as custom dlopen flags or loading from ES modules.
*
* The `flags` argument is an integer that allows to specify dlopen behavior. See the `[os.constants.dlopen](https://nodejs.org/docs/latest-v20.x/api/os.html#dlopen-constants)`
* The `flags` argument is an integer that allows to specify dlopen behavior. See the `[os.constants.dlopen](https://nodejs.org/docs/latest-v24.x/api/os.html#dlopen-constants)`
* documentation for details.
*
* An important requirement when calling `process.dlopen()` is that the `module` instance must be passed. Functions exported by the C++ Addon
@@ -763,7 +992,7 @@ declare module "process" {
* @since v0.1.13
* @param [code=0] The exit code. For string type, only integer strings (e.g.,'1') are allowed.
*/
exit(code?: number | string | null | undefined): never;
exit(code?: number | string | null): never;
/**
* A number which will be the process exit code, when the process either
* exits gracefully, or is exited via {@link exit} without specifying
@@ -774,7 +1003,41 @@ declare module "process" {
* @default undefined
* @since v0.11.8
*/
exitCode?: number | string | number | undefined;
exitCode: number | string | null | undefined;
finalization: {
/**
* This function registers a callback to be called when the process emits the `exit` event if the `ref` object was not garbage collected.
* If the object `ref` was garbage collected before the `exit` event is emitted, the callback will be removed from the finalization registry, and it will not be called on process exit.
*
* Inside the callback you can release the resources allocated by the `ref` object.
* Be aware that all limitations applied to the `beforeExit` event are also applied to the callback function,
* this means that there is a possibility that the callback will not be called under special circumstances.
*
* The idea of this function is to help you free up resources when the starts process exiting, but also let the object be garbage collected if it is no longer being used.
* @param ref The reference to the resource that is being tracked.
* @param callback The callback function to be called when the resource is finalized.
* @since v22.5.0
* @experimental
*/
register<T extends object>(ref: T, callback: (ref: T, event: "exit") => void): void;
/**
* This function behaves exactly like the `register`, except that the callback will be called when the process emits the `beforeExit` event if `ref` object was not garbage collected.
*
* Be aware that all limitations applied to the `beforeExit` event are also applied to the callback function, this means that there is a possibility that the callback will not be called under special circumstances.
* @param ref The reference to the resource that is being tracked.
* @param callback The callback function to be called when the resource is finalized.
* @since v22.5.0
* @experimental
*/
registerBeforeExit<T extends object>(ref: T, callback: (ref: T, event: "beforeExit") => void): void;
/**
* This function remove the register of the object from the finalization registry, so the callback will not be called anymore.
* @param ref The reference to the resource that was registered previously.
* @since v22.5.0
* @experimental
*/
unregister(ref: object): void;
};
/**
* The `process.getActiveResourcesInfo()` method returns an array of strings containing
* the types of the active resources that are currently keeping the event loop alive.
@@ -793,6 +1056,12 @@ declare module "process" {
* @since v17.3.0, v16.14.0
*/
getActiveResourcesInfo(): string[];
/**
* Provides a way to load built-in modules in a globally available function.
* @param id ID of the built-in module being requested.
*/
getBuiltinModule<ID extends keyof BuiltInModule>(id: ID): BuiltInModule[ID];
getBuiltinModule(id: string): object | undefined;
/**
* The `process.getgid()` method returns the numerical group identity of the
* process. (See [`getgid(2)`](http://man7.org/linux/man-pages/man2/getgid.2.html).)
@@ -1198,7 +1467,7 @@ declare module "process" {
* @since v20.12.0
* @param path The path to the .env file
*/
loadEnvFile(path?: string | URL | Buffer): void;
loadEnvFile(path?: PathLike): void;
/**
* The `process.pid` property returns the PID of the process.
*
@@ -1222,6 +1491,18 @@ declare module "process" {
* @since v9.2.0, v8.10.0, v6.13.0
*/
readonly ppid: number;
/**
* The `process.threadCpuUsage()` method returns the user and system CPU time usage of
* the current worker thread, in an object with properties `user` and `system`, whose
* values are microsecond values (millionth of a second).
*
* The result of a previous call to `process.threadCpuUsage()` can be passed as the
* argument to the function, to get a diff reading.
* @since v23.9.0
* @param previousValue A previous return value from calling
* `process.threadCpuUsage()`
*/
threadCpuUsage(previousValue?: CpuUsage): CpuUsage;
/**
* The `process.title` property returns the current process title (i.e. returns
* the current value of `ps`). Assigning a new value to `process.title` modifies
@@ -1242,7 +1523,8 @@ declare module "process" {
title: string;
/**
* The operating system CPU architecture for which the Node.js binary was compiled.
* Possible values are: `'arm'`, `'arm64'`, `'ia32'`, `'loong64'`, `'mips'`, `'mipsel'`, `'ppc'`, `'ppc64'`, `'riscv64'`, `'s390'`, `'s390x'`, and `'x64'`.
* Possible values are: `'arm'`, `'arm64'`, `'ia32'`, `'loong64'`, `'mips'`,
* `'mipsel'`, `'ppc64'`, `'riscv64'`, `'s390x'`, and `'x64'`.
*
* ```js
* import { arch } from 'node:process';
@@ -1288,7 +1570,7 @@ declare module "process" {
* @since v0.1.17
* @deprecated Since v14.0.0 - Use `main` instead.
*/
mainModule?: Module | undefined;
mainModule?: Module;
memoryUsage: MemoryUsageFn;
/**
* Gets the amount of memory available to the process (in bytes) based on
@@ -1298,13 +1580,11 @@ declare module "process" {
* See [`uv_get_constrained_memory`](https://docs.libuv.org/en/v1.x/misc.html#c.uv_get_constrained_memory) for more
* information.
* @since v19.6.0, v18.15.0
* @experimental
*/
constrainedMemory(): number;
/**
* Gets the amount of free memory that is still available to the process (in bytes).
* See [`uv_get_available_memory`](https://nodejs.org/docs/latest-v20.x/api/process.html#processavailablememory) for more information.
* @experimental
* See [`uv_get_available_memory`](https://nodejs.org/docs/latest-v24.x/api/process.html#processavailablememory) for more information.
* @since v20.13.0
*/
availableMemory(): number;
@@ -1425,7 +1705,7 @@ declare module "process" {
*/
nextTick(callback: Function, ...args: any[]): void;
/**
* This API is available through the [--experimental-permission](https://nodejs.org/api/cli.html#--experimental-permission) flag.
* This API is available through the [--permission](https://nodejs.org/api/cli.html#--permission) flag.
*
* `process.permission` is an object whose methods are used to manage permissions for the current process.
* Additional documentation is available in the [Permission Model](https://nodejs.org/api/permissions.html#permission-model).
@@ -1454,16 +1734,7 @@ declare module "process" {
* @since v3.0.0
*/
readonly release: ProcessRelease;
features: {
inspector: boolean;
debug: boolean;
uv: boolean;
ipv6: boolean;
tls_alpn: boolean;
tls_sni: boolean;
tls_ocsp: boolean;
tls: boolean;
};
readonly features: ProcessFeatures;
/**
* `process.umask()` returns the Node.js process's file mode creation mask. Child
* processes inherit the mask from the parent process.
@@ -1491,18 +1762,7 @@ declare module "process" {
* If no IPC channel exists, this property is undefined.
* @since v7.1.0
*/
channel?: {
/**
* This method makes the IPC channel keep the event loop of the process running if .unref() has been called before.
* @since v7.1.0
*/
ref(): void;
/**
* This method makes the IPC channel not keep the event loop of the process running, and lets it finish even while the channel is open.
* @since v7.1.0
*/
unref(): void;
};
channel?: Control;
/**
* If Node.js is spawned with an IPC channel, the `process.send()` method can be
* used to send messages to the parent process. Messages will be received as a `'message'` event on the parent's `ChildProcess` object.
@@ -1516,10 +1776,8 @@ declare module "process" {
*/
send?(
message: any,
sendHandle?: any,
options?: {
keepOpen?: boolean | undefined;
},
sendHandle?: SendHandle,
options?: MessageOptions,
callback?: (error: Error | null) => void,
): boolean;
/**
@@ -1585,11 +1843,11 @@ declare module "process" {
*/
allowedNodeEnvironmentFlags: ReadonlySet<string>;
/**
* `process.report` is an object whose methods are used to generate diagnostic
* reports for the current process. Additional documentation is available in the `report documentation`.
* `process.report` is an object whose methods are used to generate diagnostic reports for the current process.
* Additional documentation is available in the [report documentation](https://nodejs.org/docs/latest-v24.x/api/report.html).
* @since v11.8.0
*/
report?: ProcessReport | undefined;
report: ProcessReport;
/**
* ```js
* import { resourceUsage } from 'node:process';
@@ -1651,6 +1909,56 @@ declare module "process" {
* @since v0.8.0
*/
traceDeprecation: boolean;
/**
* An object is "refable" if it implements the Node.js "Refable protocol".
* Specifically, this means that the object implements the `Symbol.for('nodejs.ref')`
* and `Symbol.for('nodejs.unref')` methods. "Ref'd" objects will keep the Node.js
* event loop alive, while "unref'd" objects will not. Historically, this was
* implemented by using `ref()` and `unref()` methods directly on the objects.
* This pattern, however, is being deprecated in favor of the "Refable protocol"
* in order to better support Web Platform API types whose APIs cannot be modified
* to add `ref()` and `unref()` methods but still need to support that behavior.
* @since v22.14.0
* @experimental
* @param maybeRefable An object that may be "refable".
*/
ref(maybeRefable: any): void;
/**
* An object is "unrefable" if it implements the Node.js "Refable protocol".
* Specifically, this means that the object implements the `Symbol.for('nodejs.ref')`
* and `Symbol.for('nodejs.unref')` methods. "Ref'd" objects will keep the Node.js
* event loop alive, while "unref'd" objects will not. Historically, this was
* implemented by using `ref()` and `unref()` methods directly on the objects.
* This pattern, however, is being deprecated in favor of the "Refable protocol"
* in order to better support Web Platform API types whose APIs cannot be modified
* to add `ref()` and `unref()` methods but still need to support that behavior.
* @since v22.14.0
* @experimental
* @param maybeRefable An object that may be "unref'd".
*/
unref(maybeRefable: any): void;
/**
* Replaces the current process with a new process.
*
* This is achieved by using the `execve` POSIX function and therefore no memory or other
* resources from the current process are preserved, except for the standard input,
* standard output and standard error file descriptor.
*
* All other resources are discarded by the system when the processes are swapped, without triggering
* any exit or close events and without running any cleanup handler.
*
* This function will never return, unless an error occurred.
*
* This function is not available on Windows or IBM i.
* @since v22.15.0
* @experimental
* @param file The name or path of the executable file to run.
* @param args List of string arguments. No argument can contain a null-byte (`\u0000`).
* @param env Environment key-value pairs.
* No key or value can contain a null-byte (`\u0000`).
* **Default:** `process.env`.
*/
execve?(file: string, args?: readonly string[], env?: ProcessEnv): never;
/* EventEmitter */
addListener(event: "beforeExit", listener: BeforeExitListener): this;
addListener(event: "disconnect", listener: DisconnectListener): this;
@@ -1672,7 +1980,7 @@ declare module "process" {
emit(event: "uncaughtExceptionMonitor", error: Error): boolean;
emit(event: "unhandledRejection", reason: unknown, promise: Promise<unknown>): boolean;
emit(event: "warning", warning: Error): boolean;
emit(event: "message", message: unknown, sendHandle: unknown): this;
emit(event: "message", message: unknown, sendHandle: SendHandle): this;
emit(event: Signals, signal?: Signals): boolean;
emit(
event: "multipleResolves",

View File

@@ -8,7 +8,7 @@
* can be accessed using:
*
* ```js
* const punycode = require('punycode');
* import punycode from 'node:punycode';
* ```
*
* [Punycode](https://tools.ietf.org/html/rfc3492) is a character encoding scheme defined by RFC 3492 that is
@@ -24,7 +24,7 @@
* made available to developers as a convenience. Fixes or other modifications to
* the module must be directed to the [Punycode.js](https://github.com/bestiejs/punycode.js) project.
* @deprecated Since v7.0.0 - Deprecated
* @see [source](https://github.com/nodejs/node/blob/v20.13.1/lib/punycode.js)
* @see [source](https://github.com/nodejs/node/blob/v24.x/lib/punycode.js)
*/
declare module "punycode" {
/**

View File

@@ -3,13 +3,13 @@
* query strings. It can be accessed using:
*
* ```js
* const querystring = require('node:querystring');
* import querystring from 'node:querystring';
* ```
*
* `querystring` is more performant than `URLSearchParams` but is not a
* standardized API. Use `URLSearchParams` when performance is not critical or
* when compatibility with browser code is desirable.
* @see [source](https://github.com/nodejs/node/blob/v20.13.1/lib/querystring.js)
* @see [source](https://github.com/nodejs/node/blob/v24.x/lib/querystring.js)
*/
declare module "querystring" {
interface StringifyOptions {
@@ -37,9 +37,8 @@ declare module "querystring" {
| string
| number
| boolean
| readonly string[]
| readonly number[]
| readonly boolean[]
| bigint
| ReadonlyArray<string | number | boolean | bigint>
| null
>
{}

View File

@@ -1,6 +1,6 @@
/**
* The `node:readline` module provides an interface for reading data from a [Readable](https://nodejs.org/docs/latest-v20.x/api/stream.html#readable-streams) stream
* (such as [`process.stdin`](https://nodejs.org/docs/latest-v20.x/api/process.html#processstdin)) one line at a time.
* The `node:readline` module provides an interface for reading data from a [Readable](https://nodejs.org/docs/latest-v24.x/api/stream.html#readable-streams) stream
* (such as [`process.stdin`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstdin)) one line at a time.
*
* To use the promise-based APIs:
*
@@ -31,7 +31,7 @@
*
* Once this code is invoked, the Node.js application will not terminate until the `readline.Interface` is closed because the interface waits for data to be
* received on the `input` stream.
* @see [source](https://github.com/nodejs/node/blob/v20.13.1/lib/readline.js)
* @see [source](https://github.com/nodejs/node/blob/v24.x/lib/readline.js)
*/
declare module "readline" {
import { Abortable, EventEmitter } from "node:events";
@@ -46,12 +46,12 @@ declare module "readline" {
}
/**
* Instances of the `readline.Interface` class are constructed using the `readline.createInterface()` method. Every instance is associated with a
* single `input` [Readable](https://nodejs.org/docs/latest-v20.x/api/stream.html#readable-streams) stream and a single `output` [Writable](https://nodejs.org/docs/latest-v20.x/api/stream.html#writable-streams) stream.
* single `input` [Readable](https://nodejs.org/docs/latest-v24.x/api/stream.html#readable-streams) stream and a single `output` [Writable](https://nodejs.org/docs/latest-v24.x/api/stream.html#writable-streams) stream.
* The `output` stream is used to print prompts for user input that arrives on,
* and is read from, the `input` stream.
* @since v0.1.104
*/
export class Interface extends EventEmitter {
export class Interface extends EventEmitter implements Disposable {
readonly terminal: boolean;
/**
* The current input data being processed by node.
@@ -100,7 +100,7 @@ declare module "readline" {
* > Instances of the `readline.Interface` class are constructed using the
* > `readline.createInterface()` method.
*
* @see https://nodejs.org/dist/latest-v20.x/docs/api/readline.html#class-interfaceconstructor
* @see https://nodejs.org/dist/latest-v24.x/docs/api/readline.html#class-interfaceconstructor
*/
protected constructor(
input: NodeJS.ReadableStream,
@@ -114,7 +114,7 @@ declare module "readline" {
* > Instances of the `readline.Interface` class are constructed using the
* > `readline.createInterface()` method.
*
* @see https://nodejs.org/dist/latest-v20.x/docs/api/readline.html#class-interfaceconstructor
* @see https://nodejs.org/dist/latest-v24.x/docs/api/readline.html#class-interfaceconstructor
*/
protected constructor(options: ReadLineOptions);
/**
@@ -208,6 +208,11 @@ declare module "readline" {
* @since v0.1.98
*/
close(): void;
/**
* Alias for `rl.close()`.
* @since v22.15.0
*/
[Symbol.dispose](): void;
/**
* The `rl.write()` method will write either `data` or a key sequence identified
* by `key` to the `output`. The `key` argument is supported only if `output` is
@@ -304,7 +309,7 @@ declare module "readline" {
prependOnceListener(event: "SIGINT", listener: () => void): this;
prependOnceListener(event: "SIGTSTP", listener: () => void): this;
prependOnceListener(event: "history", listener: (history: string[]) => void): this;
[Symbol.asyncIterator](): AsyncIterableIterator<string>;
[Symbol.asyncIterator](): NodeJS.AsyncIterator<string>;
}
export type ReadLine = Interface; // type forwarded for backwards compatibility
export type Completer = (line: string) => CompleterResult;
@@ -314,35 +319,84 @@ declare module "readline" {
) => void;
export type CompleterResult = [string[], string];
export interface ReadLineOptions {
/**
* The [`Readable`](https://nodejs.org/docs/latest-v24.x/api/stream.html#readable-streams) stream to listen to
*/
input: NodeJS.ReadableStream;
/**
* The [`Writable`](https://nodejs.org/docs/latest-v24.x/api/stream.html#writable-streams) stream to write readline data to.
*/
output?: NodeJS.WritableStream | undefined;
/**
* An optional function used for Tab autocompletion.
*/
completer?: Completer | AsyncCompleter | undefined;
/**
* `true` if the `input` and `output` streams should be treated like a TTY,
* and have ANSI/VT100 escape codes written to it.
* Default: checking `isTTY` on the `output` stream upon instantiation.
*/
terminal?: boolean | undefined;
/**
* Initial list of history lines. This option makes sense
* only if `terminal` is set to `true` by the user or by an internal `output`
* check, otherwise the history caching mechanism is not initialized at all.
* Initial list of history lines.
* This option makes sense only if `terminal` is set to `true` by the user or by an internal `output` check,
* otherwise the history caching mechanism is not initialized at all.
* @default []
*/
history?: string[] | undefined;
historySize?: number | undefined;
prompt?: string | undefined;
crlfDelay?: number | undefined;
/**
* If `true`, when a new input line added
* to the history list duplicates an older one, this removes the older line
* from the list.
* Maximum number of history lines retained.
* To disable the history set this value to `0`.
* This option makes sense only if `terminal` is set to `true` by the user or by an internal `output` check,
* otherwise the history caching mechanism is not initialized at all.
* @default 30
*/
historySize?: number | undefined;
/**
* If `true`, when a new input line added to the history list duplicates an older one,
* this removes the older line from the list.
* @default false
*/
removeHistoryDuplicates?: boolean | undefined;
/**
* The prompt string to use.
* @default "> "
*/
prompt?: string | undefined;
/**
* If the delay between `\r` and `\n` exceeds `crlfDelay` milliseconds,
* both `\r` and `\n` will be treated as separate end-of-line input.
* `crlfDelay` will be coerced to a number no less than `100`.
* It can be set to `Infinity`, in which case
* `\r` followed by `\n` will always be considered a single newline
* (which may be reasonable for [reading files](https://nodejs.org/docs/latest-v24.x/api/readline.html#example-read-file-stream-line-by-line) with `\r\n` line delimiter).
* @default 100
*/
crlfDelay?: number | undefined;
/**
* The duration `readline` will wait for a character
* (when reading an ambiguous key sequence in milliseconds
* one that can both form a complete key sequence using the input read so far
* and can take additional input to complete a longer key sequence).
* @default 500
*/
escapeCodeTimeout?: number | undefined;
/**
* The number of spaces a tab is equal to (minimum 1).
* @default 8
*/
tabSize?: number | undefined;
/**
* Allows closing the interface using an AbortSignal.
* Aborting the signal will internally call `close` on the interface.
*/
signal?: AbortSignal | undefined;
}
/**
* The `readline.createInterface()` method creates a new `readline.Interface` instance.
*
* ```js
* const readline = require('node:readline');
* import readline from 'node:readline';
* const rl = readline.createInterface({
* input: process.stdin,
* output: process.stdout,
@@ -398,7 +452,7 @@ declare module "readline" {
* implement a small command-line interface:
*
* ```js
* const readline = require('node:readline');
* import readline from 'node:readline';
* const rl = readline.createInterface({
* input: process.stdin,
* output: process.stdout,
@@ -430,8 +484,8 @@ declare module "readline" {
* well as a `for await...of` loop:
*
* ```js
* const fs = require('node:fs');
* const readline = require('node:readline');
* import fs from 'node:fs';
* import readline from 'node:readline';
*
* async function processLineByLine() {
* const fileStream = fs.createReadStream('input.txt');
@@ -455,8 +509,8 @@ declare module "readline" {
* Alternatively, one could use the `'line'` event:
*
* ```js
* const fs = require('node:fs');
* const readline = require('node:readline');
* import fs from 'node:fs';
* import readline from 'node:readline';
*
* const rl = readline.createInterface({
* input: fs.createReadStream('sample.txt'),
@@ -471,9 +525,9 @@ declare module "readline" {
* Currently, `for await...of` loop can be a bit slower. If `async` / `await` flow and speed are both essential, a mixed approach can be applied:
*
* ```js
* const { once } = require('node:events');
* const { createReadStream } = require('node:fs');
* const { createInterface } = require('node:readline');
* import { once } from 'node:events';
* import { createReadStream } from 'node:fs';
* import { createInterface } from 'node:readline';
*
* (async function processLineByLine() {
* try {
@@ -503,7 +557,7 @@ declare module "readline" {
cols: number;
}
/**
* The `readline.clearLine()` method clears current line of given [TTY](https://nodejs.org/docs/latest-v20.x/api/tty.html) stream
* The `readline.clearLine()` method clears current line of given [TTY](https://nodejs.org/docs/latest-v24.x/api/tty.html) stream
* in a specified direction identified by `dir`.
* @since v0.7.7
* @param callback Invoked once the operation completes.
@@ -511,7 +565,7 @@ declare module "readline" {
*/
export function clearLine(stream: NodeJS.WritableStream, dir: Direction, callback?: () => void): boolean;
/**
* The `readline.clearScreenDown()` method clears the given [TTY](https://nodejs.org/docs/latest-v20.x/api/tty.html) stream from
* The `readline.clearScreenDown()` method clears the given [TTY](https://nodejs.org/docs/latest-v24.x/api/tty.html) stream from
* the current position of the cursor down.
* @since v0.7.7
* @param callback Invoked once the operation completes.
@@ -520,7 +574,7 @@ declare module "readline" {
export function clearScreenDown(stream: NodeJS.WritableStream, callback?: () => void): boolean;
/**
* The `readline.cursorTo()` method moves cursor to the specified position in a
* given [TTY](https://nodejs.org/docs/latest-v20.x/api/tty.html) `stream`.
* given [TTY](https://nodejs.org/docs/latest-v24.x/api/tty.html) `stream`.
* @since v0.7.7
* @param callback Invoked once the operation completes.
* @return `false` if `stream` wishes for the calling code to wait for the `'drain'` event to be emitted before continuing to write additional data; otherwise `true`.
@@ -528,7 +582,7 @@ declare module "readline" {
export function cursorTo(stream: NodeJS.WritableStream, x: number, y?: number, callback?: () => void): boolean;
/**
* The `readline.moveCursor()` method moves the cursor _relative_ to its current
* position in a given [TTY](https://nodejs.org/docs/latest-v20.x/api/tty.html) `stream`.
* position in a given [TTY](https://nodejs.org/docs/latest-v24.x/api/tty.html) `stream`.
* @since v0.7.7
* @param callback Invoked once the operation completes.
* @return `false` if `stream` wishes for the calling code to wait for the `'drain'` event to be emitted before continuing to write additional data; otherwise `true`.

View File

@@ -1,10 +1,14 @@
/**
* @since v17.0.0
* @experimental
*/
declare module "readline/promises" {
import { AsyncCompleter, Completer, Direction, Interface as _Interface, ReadLineOptions } from "node:readline";
import { Abortable } from "node:events";
import {
CompleterResult,
Direction,
Interface as _Interface,
ReadLineOptions as _ReadLineOptions,
} from "node:readline";
/**
* Instances of the `readlinePromises.Interface` class are constructed using the `readlinePromises.createInterface()` method. Every instance is associated with a
* single `input` `Readable` stream and a single `output` `Writable` stream.
@@ -60,7 +64,7 @@ declare module "readline/promises" {
constructor(
stream: NodeJS.WritableStream,
options?: {
autoCommit?: boolean;
autoCommit?: boolean | undefined;
},
);
/**
@@ -111,11 +115,18 @@ declare module "readline/promises" {
*/
rollback(): this;
}
type Completer = (line: string) => CompleterResult | Promise<CompleterResult>;
interface ReadLineOptions extends Omit<_ReadLineOptions, "completer"> {
/**
* An optional function used for Tab autocompletion.
*/
completer?: Completer | undefined;
}
/**
* The `readlinePromises.createInterface()` method creates a new `readlinePromises.Interface` instance.
*
* ```js
* const readlinePromises = require('node:readline/promises');
* import readlinePromises from 'node:readline/promises';
* const rl = readlinePromises.createInterface({
* input: process.stdin,
* output: process.stdout,
@@ -140,7 +151,7 @@ declare module "readline/promises" {
function createInterface(
input: NodeJS.ReadableStream,
output?: NodeJS.WritableStream,
completer?: Completer | AsyncCompleter,
completer?: Completer,
terminal?: boolean,
): Interface;
function createInterface(options: ReadLineOptions): Interface;

View File

@@ -4,9 +4,9 @@
* applications. It can be accessed using:
*
* ```js
* const repl = require('node:repl');
* import repl from 'node:repl';
* ```
* @see [source](https://github.com/nodejs/node/blob/v20.13.1/lib/repl.js)
* @see [source](https://github.com/nodejs/node/blob/v24.x/lib/repl.js)
*/
declare module "repl" {
import { AsyncCompleter, Completer, Interface } from "node:readline";
@@ -37,12 +37,10 @@ declare module "repl" {
terminal?: boolean | undefined;
/**
* The function to be used when evaluating each given line of input.
* Default: an async wrapper for the JavaScript `eval()` function. An `eval` function can
* **Default:** an async wrapper for the JavaScript `eval()` function. An `eval` function can
* error with `repl.Recoverable` to indicate the input was incomplete and prompt for
* additional lines.
*
* @see https://nodejs.org/dist/latest-v20.x/docs/api/repl.html#repl_default_evaluation
* @see https://nodejs.org/dist/latest-v20.x/docs/api/repl.html#repl_custom_evaluation_functions
* additional lines. See the [custom evaluation functions](https://nodejs.org/dist/latest-v24.x/docs/api/repl.html#custom-evaluation-functions)
* section for more details.
*/
eval?: REPLEval | undefined;
/**
@@ -74,13 +72,13 @@ declare module "repl" {
* The function to invoke to format the output of each command before writing to `output`.
* @default a wrapper for `util.inspect`
*
* @see https://nodejs.org/dist/latest-v20.x/docs/api/repl.html#repl_customizing_repl_output
* @see https://nodejs.org/dist/latest-v24.x/docs/api/repl.html#repl_customizing_repl_output
*/
writer?: REPLWriter | undefined;
/**
* An optional function used for custom Tab auto completion.
*
* @see https://nodejs.org/dist/latest-v20.x/docs/api/readline.html#readline_use_of_the_completer_function
* @see https://nodejs.org/dist/latest-v24.x/docs/api/readline.html#readline_use_of_the_completer_function
*/
completer?: Completer | AsyncCompleter | undefined;
/**
@@ -125,12 +123,18 @@ declare module "repl" {
*/
action: REPLCommandAction;
}
interface REPLServerSetupHistoryOptions {
filePath?: string | undefined;
size?: number | undefined;
removeHistoryDuplicates?: boolean | undefined;
onHistoryFileLoaded?: ((err: Error | null, repl: REPLServer) => void) | undefined;
}
/**
* Instances of `repl.REPLServer` are created using the {@link start} method
* or directly using the JavaScript `new` keyword.
*
* ```js
* const repl = require('node:repl');
* import repl from 'node:repl';
*
* const options = { useColors: true };
*
@@ -168,33 +172,33 @@ declare module "repl" {
/**
* A value indicating whether the REPL is currently in "editor mode".
*
* @see https://nodejs.org/dist/latest-v20.x/docs/api/repl.html#repl_commands_and_special_keys
* @see https://nodejs.org/dist/latest-v24.x/docs/api/repl.html#repl_commands_and_special_keys
*/
readonly editorMode: boolean;
/**
* A value indicating whether the `_` variable has been assigned.
*
* @see https://nodejs.org/dist/latest-v20.x/docs/api/repl.html#repl_assignment_of_the_underscore_variable
* @see https://nodejs.org/dist/latest-v24.x/docs/api/repl.html#repl_assignment_of_the_underscore_variable
*/
readonly underscoreAssigned: boolean;
/**
* The last evaluation result from the REPL (assigned to the `_` variable inside of the REPL).
*
* @see https://nodejs.org/dist/latest-v20.x/docs/api/repl.html#repl_assignment_of_the_underscore_variable
* @see https://nodejs.org/dist/latest-v24.x/docs/api/repl.html#repl_assignment_of_the_underscore_variable
*/
readonly last: any;
/**
* A value indicating whether the `_error` variable has been assigned.
*
* @since v9.8.0
* @see https://nodejs.org/dist/latest-v20.x/docs/api/repl.html#repl_assignment_of_the_underscore_variable
* @see https://nodejs.org/dist/latest-v24.x/docs/api/repl.html#repl_assignment_of_the_underscore_variable
*/
readonly underscoreErrAssigned: boolean;
/**
* The last error raised inside the REPL (assigned to the `_error` variable inside of the REPL).
*
* @since v9.8.0
* @see https://nodejs.org/dist/latest-v20.x/docs/api/repl.html#repl_assignment_of_the_underscore_variable
* @see https://nodejs.org/dist/latest-v24.x/docs/api/repl.html#repl_assignment_of_the_underscore_variable
*/
readonly lastError: any;
/**
@@ -246,7 +250,7 @@ declare module "repl" {
*
* `REPLServer` cannot be subclassed due to implementation specifics in NodeJS.
*
* @see https://nodejs.org/dist/latest-v20.x/docs/api/repl.html#repl_class_replserver
* @see https://nodejs.org/dist/latest-v24.x/docs/api/repl.html#repl_class_replserver
*/
private constructor();
/**
@@ -257,7 +261,7 @@ declare module "repl" {
* The following example shows two new commands added to the REPL instance:
*
* ```js
* const repl = require('node:repl');
* import repl from 'node:repl';
*
* const replServer = repl.start({ prompt: '> ' });
* replServer.defineCommand('sayhello', {
@@ -291,7 +295,7 @@ declare module "repl" {
* The `replServer.displayPrompt()` method readies the REPL instance for input
* from the user, printing the configured `prompt` to a new line in the `output` and resuming the `input` to accept new input.
*
* When multi-line input is being entered, an ellipsis is printed rather than the
* When multi-line input is being entered, a pipe `'|'` is printed rather than the
* 'prompt'.
*
* When `preserveCursor` is `true`, the cursor placement will not be reset to `0`.
@@ -318,7 +322,11 @@ declare module "repl" {
* @param historyPath the path to the history file
* @param callback called when history writes are ready or upon error
*/
setupHistory(path: string, callback: (err: Error | null, repl: this) => void): void;
setupHistory(historyPath: string, callback: (err: Error | null, repl: this) => void): void;
setupHistory(
historyConfig?: REPLServerSetupHistoryOptions,
callback?: (err: Error | null, repl: this) => void,
): void;
/**
* events.EventEmitter
* 1. close - inherited from `readline.Interface`
@@ -407,7 +415,7 @@ declare module "repl" {
* If `options` is a string, then it specifies the input prompt:
*
* ```js
* const repl = require('node:repl');
* import repl from 'node:repl';
*
* // a Unix style prompt
* repl.start('$ ');
@@ -418,7 +426,7 @@ declare module "repl" {
/**
* Indicates a recoverable error that a `REPLServer` can use to support multi-line input.
*
* @see https://nodejs.org/dist/latest-v20.x/docs/api/repl.html#repl_recoverable_errors
* @see https://nodejs.org/dist/latest-v24.x/docs/api/repl.html#repl_recoverable_errors
*/
class Recoverable extends SyntaxError {
err: Error;

View File

@@ -111,7 +111,7 @@
* ```
* @since v19.7.0, v18.16.0
* @experimental
* @see [source](https://github.com/nodejs/node/blob/v20.12.0/src/node_sea.cc)
* @see [source](https://github.com/nodejs/node/blob/v24.x/src/node_sea.cc)
*/
declare module "node:sea" {
type AssetKey = string;
@@ -149,5 +149,14 @@ declare module "node:sea" {
* writes to the returned array buffer is likely to result in a crash.
* @since v20.12.0
*/
function getRawAsset(key: AssetKey): string | ArrayBuffer;
function getRawAsset(key: AssetKey): ArrayBuffer;
/**
* This method can be used to retrieve an array of all the keys of assets
* embedded into the single-executable application.
* An error is thrown when not running inside a single-executable application.
* @since v24.8.0
* @returns An array containing all the keys of the assets
* embedded in the executable. If no assets are embedded, returns an empty array.
*/
function getAssetKeys(): string[];
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,11 +1,37 @@
/**
* The utility consumer functions provide common options for consuming
* streams.
* @since v16.7.0
*/
declare module "stream/consumers" {
import { Blob as NodeBlob } from "node:buffer";
import { Readable } from "node:stream";
function buffer(stream: NodeJS.ReadableStream | Readable | AsyncIterable<any>): Promise<Buffer>;
function text(stream: NodeJS.ReadableStream | Readable | AsyncIterable<any>): Promise<string>;
function arrayBuffer(stream: NodeJS.ReadableStream | Readable | AsyncIterable<any>): Promise<ArrayBuffer>;
function blob(stream: NodeJS.ReadableStream | Readable | AsyncIterable<any>): Promise<NodeBlob>;
function json(stream: NodeJS.ReadableStream | Readable | AsyncIterable<any>): Promise<unknown>;
import { Blob as NodeBlob, NonSharedBuffer } from "node:buffer";
import { ReadableStream as WebReadableStream } from "node:stream/web";
/**
* @since v16.7.0
* @returns Fulfills with an `ArrayBuffer` containing the full contents of the stream.
*/
function arrayBuffer(stream: WebReadableStream | NodeJS.ReadableStream | AsyncIterable<any>): Promise<ArrayBuffer>;
/**
* @since v16.7.0
* @returns Fulfills with a `Blob` containing the full contents of the stream.
*/
function blob(stream: WebReadableStream | NodeJS.ReadableStream | AsyncIterable<any>): Promise<NodeBlob>;
/**
* @since v16.7.0
* @returns Fulfills with a `Buffer` containing the full contents of the stream.
*/
function buffer(stream: WebReadableStream | NodeJS.ReadableStream | AsyncIterable<any>): Promise<NonSharedBuffer>;
/**
* @since v16.7.0
* @returns Fulfills with the contents of the stream parsed as a
* UTF-8 encoded string that is then passed through `JSON.parse()`.
*/
function json(stream: WebReadableStream | NodeJS.ReadableStream | AsyncIterable<any>): Promise<unknown>;
/**
* @since v16.7.0
* @returns Fulfills with the contents of the stream parsed as a UTF-8 encoded string.
*/
function text(stream: WebReadableStream | NodeJS.ReadableStream | AsyncIterable<any>): Promise<string>;
}
declare module "node:stream/consumers" {
export * from "stream/consumers";

View File

@@ -1,12 +1,19 @@
declare module "stream/promises" {
import {
FinishedOptions,
FinishedOptions as _FinishedOptions,
PipelineDestination,
PipelineOptions,
PipelinePromise,
PipelineSource,
PipelineTransform,
} from "node:stream";
interface FinishedOptions extends _FinishedOptions {
/**
* If true, removes the listeners registered by this function before the promise is fulfilled.
* @default false
*/
cleanup?: boolean | undefined;
}
function finished(
stream: NodeJS.ReadableStream | NodeJS.WritableStream | NodeJS.ReadWriteStream,
options?: FinishedOptions,

View File

@@ -1,3 +1,36 @@
type _ByteLengthQueuingStrategy = typeof globalThis extends { onmessage: any } ? {}
: import("stream/web").ByteLengthQueuingStrategy;
type _CountQueuingStrategy = typeof globalThis extends { onmessage: any } ? {}
: import("stream/web").CountQueuingStrategy;
type _QueuingStrategy<T = any> = typeof globalThis extends { onmessage: any } ? {}
: import("stream/web").QueuingStrategy<T>;
type _ReadableByteStreamController = typeof globalThis extends { onmessage: any } ? {}
: import("stream/web").ReadableByteStreamController;
type _ReadableStream<R = any> = typeof globalThis extends { onmessage: any } ? {}
: import("stream/web").ReadableStream<R>;
type _ReadableStreamBYOBReader = typeof globalThis extends { onmessage: any } ? {}
: import("stream/web").ReadableStreamBYOBReader;
type _ReadableStreamBYOBRequest = typeof globalThis extends { onmessage: any } ? {}
: import("stream/web").ReadableStreamBYOBRequest;
type _ReadableStreamDefaultController<R = any> = typeof globalThis extends { onmessage: any } ? {}
: import("stream/web").ReadableStreamDefaultController<R>;
type _ReadableStreamDefaultReader<R = any> = typeof globalThis extends { onmessage: any } ? {}
: import("stream/web").ReadableStreamDefaultReader<R>;
type _TextDecoderStream = typeof globalThis extends { onmessage: any } ? {}
: import("stream/web").TextDecoderStream;
type _TextEncoderStream = typeof globalThis extends { onmessage: any } ? {}
: import("stream/web").TextEncoderStream;
type _TransformStream<I = any, O = any> = typeof globalThis extends { onmessage: any } ? {}
: import("stream/web").TransformStream<I, O>;
type _TransformStreamDefaultController<O = any> = typeof globalThis extends { onmessage: any } ? {}
: import("stream/web").TransformStreamDefaultController<O>;
type _WritableStream<W = any> = typeof globalThis extends { onmessage: any } ? {}
: import("stream/web").WritableStream<W>;
type _WritableStreamDefaultController = typeof globalThis extends { onmessage: any } ? {}
: import("stream/web").WritableStreamDefaultController;
type _WritableStreamDefaultWriter<W = any> = typeof globalThis extends { onmessage: any } ? {}
: import("stream/web").WritableStreamDefaultWriter<W>;
declare module "stream/web" {
// stub module, pending copy&paste from .d.ts or manual impl
// copy from lib.dom.d.ts
@@ -62,21 +95,10 @@ declare module "stream/web" {
signal?: AbortSignal;
}
interface ReadableStreamGenericReader {
readonly closed: Promise<undefined>;
readonly closed: Promise<void>;
cancel(reason?: any): Promise<void>;
}
interface ReadableStreamDefaultReadValueResult<T> {
done: false;
value: T;
}
interface ReadableStreamDefaultReadDoneResult {
done: true;
value?: undefined;
}
type ReadableStreamController<T> = ReadableStreamDefaultController<T>;
type ReadableStreamDefaultReadResult<T> =
| ReadableStreamDefaultReadValueResult<T>
| ReadableStreamDefaultReadDoneResult;
interface ReadableStreamReadValueResult<T> {
done: false;
value: T;
@@ -119,6 +141,9 @@ declare module "stream/web" {
interface TransformerTransformCallback<I, O> {
(chunk: I, controller: TransformStreamDefaultController<O>): void | PromiseLike<void>;
}
interface TransformerCancelCallback {
(reason: any): void | PromiseLike<void>;
}
interface UnderlyingByteSource {
autoAllocateChunkSize?: number;
cancel?: ReadableStreamErrorCallback;
@@ -142,17 +167,21 @@ declare module "stream/web" {
interface ReadableStreamErrorCallback {
(reason: any): void | PromiseLike<void>;
}
interface ReadableStreamAsyncIterator<T> extends NodeJS.AsyncIterator<T, NodeJS.BuiltinIteratorReturn, unknown> {
[Symbol.asyncIterator](): ReadableStreamAsyncIterator<T>;
}
/** This Streams API interface represents a readable stream of byte data. */
interface ReadableStream<R = any> {
readonly locked: boolean;
cancel(reason?: any): Promise<void>;
getReader(): ReadableStreamDefaultReader<R>;
getReader(options: { mode: "byob" }): ReadableStreamBYOBReader;
getReader(): ReadableStreamDefaultReader<R>;
getReader(options?: ReadableStreamGetReaderOptions): ReadableStreamReader<R>;
pipeThrough<T>(transform: ReadableWritablePair<T, R>, options?: StreamPipeOptions): ReadableStream<T>;
pipeTo(destination: WritableStream<R>, options?: StreamPipeOptions): Promise<void>;
tee(): [ReadableStream<R>, ReadableStream<R>];
values(options?: { preventCancel?: boolean }): AsyncIterableIterator<R>;
[Symbol.asyncIterator](): AsyncIterableIterator<R>;
values(options?: { preventCancel?: boolean }): ReadableStreamAsyncIterator<R>;
[Symbol.asyncIterator](): ReadableStreamAsyncIterator<R>;
}
const ReadableStream: {
prototype: ReadableStream;
@@ -160,20 +189,53 @@ declare module "stream/web" {
new(underlyingSource: UnderlyingByteSource, strategy?: QueuingStrategy<Uint8Array>): ReadableStream<Uint8Array>;
new<R = any>(underlyingSource?: UnderlyingSource<R>, strategy?: QueuingStrategy<R>): ReadableStream<R>;
};
type ReadableStreamReaderMode = "byob";
interface ReadableStreamGetReaderOptions {
/**
* Creates a ReadableStreamBYOBReader and locks the stream to the new reader.
*
* This call behaves the same way as the no-argument variant, except that it only works on readable byte streams, i.e. streams which were constructed specifically with the ability to handle "bring your own buffer" reading. The returned BYOB reader provides the ability to directly read individual chunks from the stream via its read() method, into developer-supplied buffers, allowing more precise control over allocation.
*/
mode?: ReadableStreamReaderMode;
}
type ReadableStreamReader<T> = ReadableStreamDefaultReader<T> | ReadableStreamBYOBReader;
interface ReadableStreamDefaultReader<R = any> extends ReadableStreamGenericReader {
read(): Promise<ReadableStreamDefaultReadResult<R>>;
read(): Promise<ReadableStreamReadResult<R>>;
releaseLock(): void;
}
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamBYOBReader) */
interface ReadableStreamBYOBReader extends ReadableStreamGenericReader {
read<T extends ArrayBufferView>(view: T): Promise<ReadableStreamReadResult<T>>;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamBYOBReader/read) */
read<T extends ArrayBufferView>(
view: T,
options?: {
min?: number;
},
): Promise<ReadableStreamReadResult<T>>;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamBYOBReader/releaseLock) */
releaseLock(): void;
}
const ReadableStreamDefaultReader: {
prototype: ReadableStreamDefaultReader;
new<R = any>(stream: ReadableStream<R>): ReadableStreamDefaultReader<R>;
};
const ReadableStreamBYOBReader: any;
const ReadableStreamBYOBRequest: any;
const ReadableStreamBYOBReader: {
prototype: ReadableStreamBYOBReader;
new(stream: ReadableStream): ReadableStreamBYOBReader;
};
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamBYOBRequest) */
interface ReadableStreamBYOBRequest {
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamBYOBRequest/view) */
readonly view: ArrayBufferView | null;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamBYOBRequest/respond) */
respond(bytesWritten: number): void;
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ReadableStreamBYOBRequest/respondWithNewView) */
respondWithNewView(view: ArrayBufferView): void;
}
const ReadableStreamBYOBRequest: {
prototype: ReadableStreamBYOBRequest;
new(): ReadableStreamBYOBRequest;
};
interface ReadableByteStreamController {
readonly byobRequest: undefined;
readonly desiredSize: number | null;
@@ -200,6 +262,7 @@ declare module "stream/web" {
readableType?: undefined;
start?: TransformerStartCallback<O>;
transform?: TransformerTransformCallback<I, O>;
cancel?: TransformerCancelCallback;
writableType?: undefined;
}
interface TransformStream<I = any, O = any> {
@@ -246,9 +309,9 @@ declare module "stream/web" {
* sink.
*/
interface WritableStreamDefaultWriter<W = any> {
readonly closed: Promise<undefined>;
readonly closed: Promise<void>;
readonly desiredSize: number | null;
readonly ready: Promise<undefined>;
readonly ready: Promise<void>;
abort(reason?: any): Promise<void>;
close(): Promise<void>;
releaseLock(): void;
@@ -345,22 +408,165 @@ declare module "stream/web" {
prototype: TextDecoderStream;
new(encoding?: string, options?: TextDecoderOptions): TextDecoderStream;
};
interface CompressionStream<R = any, W = any> {
readonly readable: ReadableStream<R>;
readonly writable: WritableStream<W>;
type CompressionFormat = "brotli" | "deflate" | "deflate-raw" | "gzip";
class CompressionStream {
constructor(format: CompressionFormat);
readonly readable: ReadableStream;
readonly writable: WritableStream;
}
const CompressionStream: {
prototype: CompressionStream;
new<R = any, W = any>(format: "deflate" | "deflate-raw" | "gzip"): CompressionStream<R, W>;
};
interface DecompressionStream<R = any, W = any> {
readonly readable: ReadableStream<R>;
readonly writable: WritableStream<W>;
class DecompressionStream {
constructor(format: CompressionFormat);
readonly readable: ReadableStream;
readonly writable: WritableStream;
}
global {
interface ByteLengthQueuingStrategy extends _ByteLengthQueuingStrategy {}
/**
* `ByteLengthQueuingStrategy` class is a global reference for `import { ByteLengthQueuingStrategy } from 'node:stream/web'`.
* https://nodejs.org/api/globals.html#class-bytelengthqueuingstrategy
* @since v18.0.0
*/
var ByteLengthQueuingStrategy: typeof globalThis extends { onmessage: any; ByteLengthQueuingStrategy: infer T }
? T
: typeof import("stream/web").ByteLengthQueuingStrategy;
interface CountQueuingStrategy extends _CountQueuingStrategy {}
/**
* `CountQueuingStrategy` class is a global reference for `import { CountQueuingStrategy } from 'node:stream/web'`.
* https://nodejs.org/api/globals.html#class-countqueuingstrategy
* @since v18.0.0
*/
var CountQueuingStrategy: typeof globalThis extends { onmessage: any; CountQueuingStrategy: infer T } ? T
: typeof import("stream/web").CountQueuingStrategy;
interface QueuingStrategy<T = any> extends _QueuingStrategy<T> {}
interface ReadableByteStreamController extends _ReadableByteStreamController {}
/**
* `ReadableByteStreamController` class is a global reference for `import { ReadableByteStreamController } from 'node:stream/web'`.
* https://nodejs.org/api/globals.html#class-readablebytestreamcontroller
* @since v18.0.0
*/
var ReadableByteStreamController: typeof globalThis extends
{ onmessage: any; ReadableByteStreamController: infer T } ? T
: typeof import("stream/web").ReadableByteStreamController;
interface ReadableStream<R = any> extends _ReadableStream<R> {}
/**
* `ReadableStream` class is a global reference for `import { ReadableStream } from 'node:stream/web'`.
* https://nodejs.org/api/globals.html#class-readablestream
* @since v18.0.0
*/
var ReadableStream: typeof globalThis extends { onmessage: any; ReadableStream: infer T } ? T
: typeof import("stream/web").ReadableStream;
interface ReadableStreamBYOBReader extends _ReadableStreamBYOBReader {}
/**
* `ReadableStreamBYOBReader` class is a global reference for `import { ReadableStreamBYOBReader } from 'node:stream/web'`.
* https://nodejs.org/api/globals.html#class-readablestreambyobreader
* @since v18.0.0
*/
var ReadableStreamBYOBReader: typeof globalThis extends { onmessage: any; ReadableStreamBYOBReader: infer T }
? T
: typeof import("stream/web").ReadableStreamBYOBReader;
interface ReadableStreamBYOBRequest extends _ReadableStreamBYOBRequest {}
/**
* `ReadableStreamBYOBRequest` class is a global reference for `import { ReadableStreamBYOBRequest } from 'node:stream/web'`.
* https://nodejs.org/api/globals.html#class-readablestreambyobrequest
* @since v18.0.0
*/
var ReadableStreamBYOBRequest: typeof globalThis extends { onmessage: any; ReadableStreamBYOBRequest: infer T }
? T
: typeof import("stream/web").ReadableStreamBYOBRequest;
interface ReadableStreamDefaultController<R = any> extends _ReadableStreamDefaultController<R> {}
/**
* `ReadableStreamDefaultController` class is a global reference for `import { ReadableStreamDefaultController } from 'node:stream/web'`.
* https://nodejs.org/api/globals.html#class-readablestreamdefaultcontroller
* @since v18.0.0
*/
var ReadableStreamDefaultController: typeof globalThis extends
{ onmessage: any; ReadableStreamDefaultController: infer T } ? T
: typeof import("stream/web").ReadableStreamDefaultController;
interface ReadableStreamDefaultReader<R = any> extends _ReadableStreamDefaultReader<R> {}
/**
* `ReadableStreamDefaultReader` class is a global reference for `import { ReadableStreamDefaultReader } from 'node:stream/web'`.
* https://nodejs.org/api/globals.html#class-readablestreamdefaultreader
* @since v18.0.0
*/
var ReadableStreamDefaultReader: typeof globalThis extends
{ onmessage: any; ReadableStreamDefaultReader: infer T } ? T
: typeof import("stream/web").ReadableStreamDefaultReader;
interface TextDecoderStream extends _TextDecoderStream {}
/**
* `TextDecoderStream` class is a global reference for `import { TextDecoderStream } from 'node:stream/web'`.
* https://nodejs.org/api/globals.html#class-textdecoderstream
* @since v18.0.0
*/
var TextDecoderStream: typeof globalThis extends { onmessage: any; TextDecoderStream: infer T } ? T
: typeof import("stream/web").TextDecoderStream;
interface TextEncoderStream extends _TextEncoderStream {}
/**
* `TextEncoderStream` class is a global reference for `import { TextEncoderStream } from 'node:stream/web'`.
* https://nodejs.org/api/globals.html#class-textencoderstream
* @since v18.0.0
*/
var TextEncoderStream: typeof globalThis extends { onmessage: any; TextEncoderStream: infer T } ? T
: typeof import("stream/web").TextEncoderStream;
interface TransformStream<I = any, O = any> extends _TransformStream<I, O> {}
/**
* `TransformStream` class is a global reference for `import { TransformStream } from 'node:stream/web'`.
* https://nodejs.org/api/globals.html#class-transformstream
* @since v18.0.0
*/
var TransformStream: typeof globalThis extends { onmessage: any; TransformStream: infer T } ? T
: typeof import("stream/web").TransformStream;
interface TransformStreamDefaultController<O = any> extends _TransformStreamDefaultController<O> {}
/**
* `TransformStreamDefaultController` class is a global reference for `import { TransformStreamDefaultController } from 'node:stream/web'`.
* https://nodejs.org/api/globals.html#class-transformstreamdefaultcontroller
* @since v18.0.0
*/
var TransformStreamDefaultController: typeof globalThis extends
{ onmessage: any; TransformStreamDefaultController: infer T } ? T
: typeof import("stream/web").TransformStreamDefaultController;
interface WritableStream<W = any> extends _WritableStream<W> {}
/**
* `WritableStream` class is a global reference for `import { WritableStream } from 'node:stream/web'`.
* https://nodejs.org/api/globals.html#class-writablestream
* @since v18.0.0
*/
var WritableStream: typeof globalThis extends { onmessage: any; WritableStream: infer T } ? T
: typeof import("stream/web").WritableStream;
interface WritableStreamDefaultController extends _WritableStreamDefaultController {}
/**
* `WritableStreamDefaultController` class is a global reference for `import { WritableStreamDefaultController } from 'node:stream/web'`.
* https://nodejs.org/api/globals.html#class-writablestreamdefaultcontroller
* @since v18.0.0
*/
var WritableStreamDefaultController: typeof globalThis extends
{ onmessage: any; WritableStreamDefaultController: infer T } ? T
: typeof import("stream/web").WritableStreamDefaultController;
interface WritableStreamDefaultWriter<W = any> extends _WritableStreamDefaultWriter<W> {}
/**
* `WritableStreamDefaultWriter` class is a global reference for `import { WritableStreamDefaultWriter } from 'node:stream/web'`.
* https://nodejs.org/api/globals.html#class-writablestreamdefaultwriter
* @since v18.0.0
*/
var WritableStreamDefaultWriter: typeof globalThis extends
{ onmessage: any; WritableStreamDefaultWriter: infer T } ? T
: typeof import("stream/web").WritableStreamDefaultWriter;
}
const DecompressionStream: {
prototype: DecompressionStream;
new<R = any, W = any>(format: "deflate" | "deflate-raw" | "gzip"): DecompressionStream<R, W>;
};
}
declare module "node:stream/web" {
export * from "stream/web";

View File

@@ -4,13 +4,13 @@
* characters. It can be accessed using:
*
* ```js
* const { StringDecoder } = require('node:string_decoder');
* import { StringDecoder } from 'node:string_decoder';
* ```
*
* The following example shows the basic use of the `StringDecoder` class.
*
* ```js
* const { StringDecoder } = require('node:string_decoder');
* import { StringDecoder } from 'node:string_decoder';
* const decoder = new StringDecoder('utf8');
*
* const cent = Buffer.from([0xC2, 0xA2]);
@@ -29,14 +29,14 @@
* symbol (`€`) are written over three separate operations:
*
* ```js
* const { StringDecoder } = require('node:string_decoder');
* import { StringDecoder } from 'node:string_decoder';
* const decoder = new StringDecoder('utf8');
*
* decoder.write(Buffer.from([0xE2]));
* decoder.write(Buffer.from([0x82]));
* console.log(decoder.end(Buffer.from([0xAC]))); // Prints: €
* ```
* @see [source](https://github.com/nodejs/node/blob/v20.13.1/lib/string_decoder.js)
* @see [source](https://github.com/nodejs/node/blob/v24.x/lib/string_decoder.js)
*/
declare module "string_decoder" {
class StringDecoder {
@@ -48,7 +48,7 @@ declare module "string_decoder" {
* @since v0.1.99
* @param buffer The bytes to decode.
*/
write(buffer: string | Buffer | NodeJS.ArrayBufferView): string;
write(buffer: string | NodeJS.ArrayBufferView): string;
/**
* Returns any remaining input stored in the internal buffer as a string. Bytes
* representing incomplete UTF-8 and UTF-16 characters will be replaced with
@@ -59,7 +59,7 @@ declare module "string_decoder" {
* @since v0.9.3
* @param buffer The bytes to decode.
*/
end(buffer?: string | Buffer | NodeJS.ArrayBufferView): string;
end(buffer?: string | NodeJS.ArrayBufferView): string;
}
}
declare module "node:string_decoder" {

File diff suppressed because it is too large Load Diff

View File

@@ -1,21 +1,17 @@
/**
* The `timer` module exposes a global API for scheduling functions to
* be called at some future period of time. Because the timer functions are
* globals, there is no need to call `require('node:timers')` to use the API.
* globals, there is no need to import `node:timers` to use the API.
*
* The timer functions within Node.js implement a similar API as the timers API
* provided by Web Browsers but use a different internal implementation that is
* built around the Node.js [Event Loop](https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/#setimmediate-vs-settimeout).
* @see [source](https://github.com/nodejs/node/blob/v20.13.1/lib/timers.js)
* @see [source](https://github.com/nodejs/node/blob/v24.x/lib/timers.js)
*/
declare module "timers" {
import { Abortable } from "node:events";
import {
setImmediate as setImmediatePromise,
setInterval as setIntervalPromise,
setTimeout as setTimeoutPromise,
} from "node:timers/promises";
interface TimerOptions extends Abortable {
import * as promises from "node:timers/promises";
export interface TimerOptions extends Abortable {
/**
* Set to `false` to indicate that the scheduled `Timeout`
* should not require the Node.js event loop to remain active.
@@ -23,38 +19,33 @@ declare module "timers" {
*/
ref?: boolean | undefined;
}
let setTimeout: typeof global.setTimeout;
let clearTimeout: typeof global.clearTimeout;
let setInterval: typeof global.setInterval;
let clearInterval: typeof global.clearInterval;
let setImmediate: typeof global.setImmediate;
let clearImmediate: typeof global.clearImmediate;
global {
namespace NodeJS {
// compatibility with older typings
interface Timer extends RefCounted {
hasRef(): boolean;
refresh(): this;
[Symbol.toPrimitive](): number;
}
/**
* This object is created internally and is returned from `setImmediate()`. It
* can be passed to `clearImmediate()` in order to cancel the scheduled
* actions.
*
* By default, when an immediate is scheduled, the Node.js event loop will continue
* running as long as the immediate is active. The `Immediate` object returned by `setImmediate()` exports both `immediate.ref()` and `immediate.unref()` functions that can be used to
* control this default behavior.
* running as long as the immediate is active. The `Immediate` object returned by
* `setImmediate()` exports both `immediate.ref()` and `immediate.unref()`
* functions that can be used to control this default behavior.
*/
class Immediate implements RefCounted {
interface Immediate extends RefCounted, Disposable {
/**
* When called, requests that the Node.js event loop _not_ exit so long as the `Immediate` is active. Calling `immediate.ref()` multiple times will have no
* If true, the `Immediate` object will keep the Node.js event loop active.
* @since v11.0.0
*/
hasRef(): boolean;
/**
* When called, requests that the Node.js event loop _not_ exit so long as the
* `Immediate` is active. Calling `immediate.ref()` multiple times will have no
* effect.
*
* By default, all `Immediate` objects are "ref'ed", making it normally unnecessary
* to call `immediate.ref()` unless `immediate.unref()` had been called previously.
* @since v9.7.0
* @return a reference to `immediate`
* @returns a reference to `immediate`
*/
ref(): this;
/**
@@ -63,53 +54,58 @@ declare module "timers" {
* running, the process may exit before the `Immediate` object's callback is
* invoked. Calling `immediate.unref()` multiple times will have no effect.
* @since v9.7.0
* @return a reference to `immediate`
* @returns a reference to `immediate`
*/
unref(): this;
/**
* If true, the `Immediate` object will keep the Node.js event loop active.
* @since v11.0.0
*/
hasRef(): boolean;
_onImmediate: Function; // to distinguish it from the Timeout class
/**
* Cancels the immediate. This is similar to calling `clearImmediate()`.
* @since v20.5.0
* @since v20.5.0, v18.18.0
*/
[Symbol.dispose](): void;
_onImmediate(...args: any[]): void;
}
// Legacy interface used in Node.js v9 and prior
// TODO: remove in a future major version bump
/** @deprecated Use `NodeJS.Timeout` instead. */
interface Timer extends RefCounted {
hasRef(): boolean;
refresh(): this;
[Symbol.toPrimitive](): number;
}
/**
* This object is created internally and is returned from `setTimeout()` and `setInterval()`. It can be passed to either `clearTimeout()` or `clearInterval()` in order to cancel the
* scheduled actions.
* This object is created internally and is returned from `setTimeout()` and
* `setInterval()`. It can be passed to either `clearTimeout()` or
* `clearInterval()` in order to cancel the scheduled actions.
*
* By default, when a timer is scheduled using either `setTimeout()` or `setInterval()`, the Node.js event loop will continue running as long as the
* By default, when a timer is scheduled using either `setTimeout()` or
* `setInterval()`, the Node.js event loop will continue running as long as the
* timer is active. Each of the `Timeout` objects returned by these functions
* export both `timeout.ref()` and `timeout.unref()` functions that can be used to
* control this default behavior.
*/
class Timeout implements Timer {
interface Timeout extends RefCounted, Disposable, Timer {
/**
* When called, requests that the Node.js event loop _not_ exit so long as the`Timeout` is active. Calling `timeout.ref()` multiple times will have no effect.
*
* By default, all `Timeout` objects are "ref'ed", making it normally unnecessary
* to call `timeout.ref()` unless `timeout.unref()` had been called previously.
* Cancels the timeout.
* @since v0.9.1
* @return a reference to `timeout`
* @legacy Use `clearTimeout()` instead.
* @returns a reference to `timeout`
*/
ref(): this;
/**
* When called, the active `Timeout` object will not require the Node.js event loop
* to remain active. If there is no other activity keeping the event loop running,
* the process may exit before the `Timeout` object's callback is invoked. Calling `timeout.unref()` multiple times will have no effect.
* @since v0.9.1
* @return a reference to `timeout`
*/
unref(): this;
close(): this;
/**
* If true, the `Timeout` object will keep the Node.js event loop active.
* @since v11.0.0
*/
hasRef(): boolean;
/**
* When called, requests that the Node.js event loop _not_ exit so long as the
* `Timeout` is active. Calling `timeout.ref()` multiple times will have no effect.
*
* By default, all `Timeout` objects are "ref'ed", making it normally unnecessary
* to call `timeout.ref()` unless `timeout.unref()` had been called previously.
* @since v0.9.1
* @returns a reference to `timeout`
*/
ref(): this;
/**
* Sets the timer's start time to the current time, and reschedules the timer to
* call its callback at the previously specified duration adjusted to the current
@@ -119,85 +115,36 @@ declare module "timers" {
* Using this on a timer that has already called its callback will reactivate the
* timer.
* @since v10.2.0
* @return a reference to `timeout`
* @returns a reference to `timeout`
*/
refresh(): this;
/**
* When called, the active `Timeout` object will not require the Node.js event loop
* to remain active. If there is no other activity keeping the event loop running,
* the process may exit before the `Timeout` object's callback is invoked. Calling
* `timeout.unref()` multiple times will have no effect.
* @since v0.9.1
* @returns a reference to `timeout`
*/
unref(): this;
/**
* Coerce a `Timeout` to a primitive. The primitive can be used to
* clear the `Timeout`. The primitive can only be used in the
* same thread where the timeout was created. Therefore, to use it
* across `worker_threads` it must first be passed to the correct
* thread. This allows enhanced compatibility with browser
* `setTimeout()` and `setInterval()` implementations.
* @since v14.9.0, v12.19.0
*/
[Symbol.toPrimitive](): number;
/**
* Cancels the timeout.
* @since v20.5.0
* @since v20.5.0, v18.18.0
*/
[Symbol.dispose](): void;
_onTimeout(...args: any[]): void;
}
}
/**
* Schedules execution of a one-time `callback` after `delay` milliseconds.
*
* The `callback` will likely not be invoked in precisely `delay` milliseconds.
* Node.js makes no guarantees about the exact timing of when callbacks will fire,
* nor of their ordering. The callback will be called as close as possible to the
* time specified.
*
* When `delay` is larger than `2147483647` or less than `1`, the `delay` will be set to `1`. Non-integer delays are truncated to an integer.
*
* If `callback` is not a function, a `TypeError` will be thrown.
*
* This method has a custom variant for promises that is available using `timersPromises.setTimeout()`.
* @since v0.0.1
* @param callback The function to call when the timer elapses.
* @param [delay=1] The number of milliseconds to wait before calling the `callback`.
* @param args Optional arguments to pass when the `callback` is called.
* @return for use with {@link clearTimeout}
*/
function setTimeout<TArgs extends any[]>(
callback: (...args: TArgs) => void,
ms?: number,
...args: TArgs
): NodeJS.Timeout;
// util.promisify no rest args compability
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
function setTimeout(callback: (args: void) => void, ms?: number): NodeJS.Timeout;
namespace setTimeout {
const __promisify__: typeof setTimeoutPromise;
}
/**
* Cancels a `Timeout` object created by `setTimeout()`.
* @since v0.0.1
* @param timeout A `Timeout` object as returned by {@link setTimeout} or the `primitive` of the `Timeout` object as a string or a number.
*/
function clearTimeout(timeoutId: NodeJS.Timeout | string | number | undefined): void;
/**
* Schedules repeated execution of `callback` every `delay` milliseconds.
*
* When `delay` is larger than `2147483647` or less than `1`, the `delay` will be
* set to `1`. Non-integer delays are truncated to an integer.
*
* If `callback` is not a function, a `TypeError` will be thrown.
*
* This method has a custom variant for promises that is available using `timersPromises.setInterval()`.
* @since v0.0.1
* @param callback The function to call when the timer elapses.
* @param [delay=1] The number of milliseconds to wait before calling the `callback`.
* @param args Optional arguments to pass when the `callback` is called.
* @return for use with {@link clearInterval}
*/
function setInterval<TArgs extends any[]>(
callback: (...args: TArgs) => void,
ms?: number,
...args: TArgs
): NodeJS.Timeout;
// util.promisify no rest args compability
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
function setInterval(callback: (args: void) => void, ms?: number): NodeJS.Timeout;
namespace setInterval {
const __promisify__: typeof setIntervalPromise;
}
/**
* Cancels a `Timeout` object created by `setInterval()`.
* @since v0.0.1
* @param timeout A `Timeout` object as returned by {@link setInterval} or the `primitive` of the `Timeout` object as a string or a number.
*/
function clearInterval(intervalId: NodeJS.Timeout | string | number | undefined): void;
/**
* Schedules the "immediate" execution of the `callback` after I/O events'
* callbacks.
@@ -210,30 +157,128 @@ declare module "timers" {
*
* If `callback` is not a function, a `TypeError` will be thrown.
*
* This method has a custom variant for promises that is available using `timersPromises.setImmediate()`.
* This method has a custom variant for promises that is available using
* `timersPromises.setImmediate()`.
* @since v0.9.1
* @param callback The function to call at the end of this turn of the Node.js `Event Loop`
* @param callback The function to call at the end of this turn of
* the Node.js [Event Loop](https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/#setimmediate-vs-settimeout)
* @param args Optional arguments to pass when the `callback` is called.
* @return for use with {@link clearImmediate}
* @returns for use with `clearImmediate()`
*/
function setImmediate<TArgs extends any[]>(
callback: (...args: TArgs) => void,
...args: TArgs
): NodeJS.Immediate;
// util.promisify no rest args compability
// Allow a single void-accepting argument to be optional in arguments lists.
// Allows usage such as `new Promise(resolve => setTimeout(resolve, ms))` (#54258)
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
function setImmediate(callback: (args: void) => void): NodeJS.Immediate;
function setImmediate(callback: (_: void) => void): NodeJS.Immediate;
namespace setImmediate {
const __promisify__: typeof setImmediatePromise;
import __promisify__ = promises.setImmediate;
export { __promisify__ };
}
/**
* Schedules repeated execution of `callback` every `delay` milliseconds.
*
* When `delay` is larger than `2147483647` or less than `1` or `NaN`, the `delay`
* will be set to `1`. Non-integer delays are truncated to an integer.
*
* If `callback` is not a function, a `TypeError` will be thrown.
*
* This method has a custom variant for promises that is available using
* `timersPromises.setInterval()`.
* @since v0.0.1
* @param callback The function to call when the timer elapses.
* @param delay The number of milliseconds to wait before calling the
* `callback`. **Default:** `1`.
* @param args Optional arguments to pass when the `callback` is called.
* @returns for use with `clearInterval()`
*/
function setInterval<TArgs extends any[]>(
callback: (...args: TArgs) => void,
delay?: number,
...args: TArgs
): NodeJS.Timeout;
// Allow a single void-accepting argument to be optional in arguments lists.
// Allows usage such as `new Promise(resolve => setTimeout(resolve, ms))` (#54258)
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
function setInterval(callback: (_: void) => void, delay?: number): NodeJS.Timeout;
/**
* Schedules execution of a one-time `callback` after `delay` milliseconds.
*
* The `callback` will likely not be invoked in precisely `delay` milliseconds.
* Node.js makes no guarantees about the exact timing of when callbacks will fire,
* nor of their ordering. The callback will be called as close as possible to the
* time specified.
*
* When `delay` is larger than `2147483647` or less than `1` or `NaN`, the `delay`
* will be set to `1`. Non-integer delays are truncated to an integer.
*
* If `callback` is not a function, a `TypeError` will be thrown.
*
* This method has a custom variant for promises that is available using
* `timersPromises.setTimeout()`.
* @since v0.0.1
* @param callback The function to call when the timer elapses.
* @param delay The number of milliseconds to wait before calling the
* `callback`. **Default:** `1`.
* @param args Optional arguments to pass when the `callback` is called.
* @returns for use with `clearTimeout()`
*/
function setTimeout<TArgs extends any[]>(
callback: (...args: TArgs) => void,
delay?: number,
...args: TArgs
): NodeJS.Timeout;
// Allow a single void-accepting argument to be optional in arguments lists.
// Allows usage such as `new Promise(resolve => setTimeout(resolve, ms))` (#54258)
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
function setTimeout(callback: (_: void) => void, delay?: number): NodeJS.Timeout;
namespace setTimeout {
import __promisify__ = promises.setTimeout;
export { __promisify__ };
}
/**
* Cancels an `Immediate` object created by `setImmediate()`.
* @since v0.9.1
* @param immediate An `Immediate` object as returned by {@link setImmediate}.
* @param immediate An `Immediate` object as returned by `setImmediate()`.
*/
function clearImmediate(immediate: NodeJS.Immediate | undefined): void;
/**
* Cancels a `Timeout` object created by `setInterval()`.
* @since v0.0.1
* @param timeout A `Timeout` object as returned by `setInterval()`
* or the primitive of the `Timeout` object as a string or a number.
*/
function clearInterval(timeout: NodeJS.Timeout | string | number | undefined): void;
/**
* Cancels a `Timeout` object created by `setTimeout()`.
* @since v0.0.1
* @param timeout A `Timeout` object as returned by `setTimeout()`
* or the primitive of the `Timeout` object as a string or a number.
*/
function clearTimeout(timeout: NodeJS.Timeout | string | number | undefined): void;
/**
* The `queueMicrotask()` method queues a microtask to invoke `callback`. If
* `callback` throws an exception, the `process` object `'uncaughtException'`
* event will be emitted.
*
* The microtask queue is managed by V8 and may be used in a similar manner to
* the `process.nextTick()` queue, which is managed by Node.js. The
* `process.nextTick()` queue is always processed before the microtask queue
* within each turn of the Node.js event loop.
* @since v11.0.0
* @param callback Function to be queued.
*/
function clearImmediate(immediateId: NodeJS.Immediate | undefined): void;
function queueMicrotask(callback: () => void): void;
}
import clearImmediate = globalThis.clearImmediate;
import clearInterval = globalThis.clearInterval;
import clearTimeout = globalThis.clearTimeout;
import setImmediate = globalThis.setImmediate;
import setInterval = globalThis.setInterval;
import setTimeout = globalThis.setTimeout;
export { clearImmediate, clearInterval, clearTimeout, promises, setImmediate, setInterval, setTimeout };
}
declare module "node:timers" {
export * from "timers";

View File

@@ -1,15 +1,17 @@
/**
* The `timers/promises` API provides an alternative set of timer functions
* that return `Promise` objects. The API is accessible via `require('node:timers/promises')`.
* that return `Promise` objects. The API is accessible via
* `require('node:timers/promises')`.
*
* ```js
* import {
* setTimeout,
* setImmediate,
* setInterval,
* } from 'timers/promises';
* } from 'node:timers/promises';
* ```
* @since v15.0.0
* @see [source](https://github.com/nodejs/node/blob/v24.x/lib/timers/promises.js)
*/
declare module "timers/promises" {
import { TimerOptions } from "node:timers";
@@ -17,14 +19,15 @@ declare module "timers/promises" {
* ```js
* import {
* setTimeout,
* } from 'timers/promises';
* } from 'node:timers/promises';
*
* const res = await setTimeout(100, 'result');
*
* console.log(res); // Prints 'result'
* ```
* @since v15.0.0
* @param [delay=1] The number of milliseconds to wait before fulfilling the promise.
* @param delay The number of milliseconds to wait before fulfilling the
* promise. **Default:** `1`.
* @param value A value with which the promise is fulfilled.
*/
function setTimeout<T = void>(delay?: number, value?: T, options?: TimerOptions): Promise<T>;
@@ -32,7 +35,7 @@ declare module "timers/promises" {
* ```js
* import {
* setImmediate,
* } from 'timers/promises';
* } from 'node:timers/promises';
*
* const res = await setImmediate('result');
*
@@ -50,7 +53,7 @@ declare module "timers/promises" {
* ```js
* import {
* setInterval,
* } from 'timers/promises';
* } from 'node:timers/promises';
*
* const interval = 100;
* for await (const startTime of setInterval(interval, Date.now())) {
@@ -62,33 +65,41 @@ declare module "timers/promises" {
* console.log(Date.now());
* ```
* @since v15.9.0
* @param delay The number of milliseconds to wait between iterations.
* **Default:** `1`.
* @param value A value with which the iterator returns.
*/
function setInterval<T = void>(delay?: number, value?: T, options?: TimerOptions): AsyncIterable<T>;
function setInterval<T = void>(delay?: number, value?: T, options?: TimerOptions): NodeJS.AsyncIterator<T>;
interface Scheduler {
/**
* An experimental API defined by the [Scheduling APIs](https://github.com/WICG/scheduling-apis) draft specification being developed as a standard Web Platform API.
* An experimental API defined by the [Scheduling APIs](https://github.com/WICG/scheduling-apis) draft specification
* being developed as a standard Web Platform API.
*
* Calling `timersPromises.scheduler.wait(delay, options)` is roughly equivalent to calling `timersPromises.setTimeout(delay, undefined, options)` except that the `ref`
* option is not supported.
* Calling `timersPromises.scheduler.wait(delay, options)` is roughly equivalent
* to calling `timersPromises.setTimeout(delay, undefined, options)` except that
* the `ref` option is not supported.
*
* ```js
* import { scheduler } from 'node:timers/promises';
*
* await scheduler.wait(1000); // Wait one second before continuing
* ```
* @since v16.14.0
* @since v17.3.0, v16.14.0
* @experimental
* @param [delay=1] The number of milliseconds to wait before fulfilling the promise.
* @param delay The number of milliseconds to wait before resolving the
* promise.
*/
wait: (delay?: number, options?: Pick<TimerOptions, "signal">) => Promise<void>;
wait(delay: number, options?: { signal?: AbortSignal }): Promise<void>;
/**
* An experimental API defined by the [Scheduling APIs](https://nodejs.org/docs/latest-v20.x/api/async_hooks.html#promise-execution-tracking) draft specification
* An experimental API defined by the [Scheduling APIs](https://github.com/WICG/scheduling-apis) draft specification
* being developed as a standard Web Platform API.
* Calling `timersPromises.scheduler.yield()` is equivalent to calling `timersPromises.setImmediate()` with no arguments.
* @since v16.14.0
*
* Calling `timersPromises.scheduler.yield()` is equivalent to calling
* `timersPromises.setImmediate()` with no arguments.
* @since v17.3.0, v16.14.0
* @experimental
*/
yield: () => Promise<void>;
yield(): Promise<void>;
}
const scheduler: Scheduler;
}

View File

@@ -4,11 +4,12 @@
* The module can be accessed using:
*
* ```js
* const tls = require('node:tls');
* import tls from 'node:tls';
* ```
* @see [source](https://github.com/nodejs/node/blob/v20.13.1/lib/tls.js)
* @see [source](https://github.com/nodejs/node/blob/v24.x/lib/tls.js)
*/
declare module "tls" {
import { NonSharedBuffer } from "node:buffer";
import { X509Certificate } from "node:crypto";
import * as net from "node:net";
import * as stream from "stream";
@@ -49,7 +50,7 @@ declare module "tls" {
/**
* The DER encoded X.509 certificate data.
*/
raw: Buffer;
raw: NonSharedBuffer;
/**
* The certificate subject.
*/
@@ -115,7 +116,7 @@ declare module "tls" {
/**
* The public key.
*/
pubkey?: Buffer;
pubkey?: NonSharedBuffer;
/**
* The ASN.1 name of the OID of the elliptic curve.
* Well-known curves are identified by an OID.
@@ -295,7 +296,7 @@ declare module "tls" {
* @since v9.9.0
* @return The latest `Finished` message that has been sent to the socket as part of a SSL/TLS handshake, or `undefined` if no `Finished` message has been sent yet.
*/
getFinished(): Buffer | undefined;
getFinished(): NonSharedBuffer | undefined;
/**
* Returns an object representing the peer's certificate. If the peer does not
* provide a certificate, an empty object will be returned. If the socket has been
@@ -322,7 +323,7 @@ declare module "tls" {
* @return The latest `Finished` message that is expected or has actually been received from the socket as part of a SSL/TLS handshake, or `undefined` if there is no `Finished` message so
* far.
*/
getPeerFinished(): Buffer | undefined;
getPeerFinished(): NonSharedBuffer | undefined;
/**
* Returns a string containing the negotiated SSL/TLS protocol version of the
* current connection. The value `'unknown'` will be returned for connected
@@ -352,7 +353,7 @@ declare module "tls" {
* must use the `'session'` event (it also works for TLSv1.2 and below).
* @since v0.11.4
*/
getSession(): Buffer | undefined;
getSession(): NonSharedBuffer | undefined;
/**
* See [SSL\_get\_shared\_sigalgs](https://www.openssl.org/docs/man1.1.1/man3/SSL_get_shared_sigalgs.html) for more information.
* @since v12.11.0
@@ -367,7 +368,7 @@ declare module "tls" {
* See `Session Resumption` for more information.
* @since v0.11.4
*/
getTLSTicket(): Buffer | undefined;
getTLSTicket(): NonSharedBuffer | undefined;
/**
* See `Session Resumption` for more information.
* @since v0.5.6
@@ -398,6 +399,14 @@ declare module "tls" {
},
callback: (err: Error | null) => void,
): undefined | boolean;
/**
* The `tlsSocket.setKeyCert()` method sets the private key and certificate to use for the socket.
* This is mainly useful if you wish to select a server certificate from a TLS server's `ALPNCallback`.
* @since v22.5.0, v20.17.0
* @param context An object containing at least `key` and `cert` properties from the {@link createSecureContext()} `options`,
* or a TLS context object created with {@link createSecureContext()} itself.
*/
setKeyCert(context: SecureContextOptions | SecureContext): void;
/**
* The `tlsSocket.setMaxSendFragment()` method sets the maximum TLS fragment size.
* Returns `true` if setting the limit succeeded; `false` otherwise.
@@ -470,37 +479,37 @@ declare module "tls" {
* @param context Optionally provide a context.
* @return requested bytes of the keying material
*/
exportKeyingMaterial(length: number, label: string, context: Buffer): Buffer;
exportKeyingMaterial(length: number, label: string, context: Buffer): NonSharedBuffer;
addListener(event: string, listener: (...args: any[]) => void): this;
addListener(event: "OCSPResponse", listener: (response: Buffer) => void): this;
addListener(event: "OCSPResponse", listener: (response: NonSharedBuffer) => void): this;
addListener(event: "secureConnect", listener: () => void): this;
addListener(event: "session", listener: (session: Buffer) => void): this;
addListener(event: "keylog", listener: (line: Buffer) => void): this;
addListener(event: "session", listener: (session: NonSharedBuffer) => void): this;
addListener(event: "keylog", listener: (line: NonSharedBuffer) => void): this;
emit(event: string | symbol, ...args: any[]): boolean;
emit(event: "OCSPResponse", response: Buffer): boolean;
emit(event: "OCSPResponse", response: NonSharedBuffer): boolean;
emit(event: "secureConnect"): boolean;
emit(event: "session", session: Buffer): boolean;
emit(event: "keylog", line: Buffer): boolean;
emit(event: "session", session: NonSharedBuffer): boolean;
emit(event: "keylog", line: NonSharedBuffer): boolean;
on(event: string, listener: (...args: any[]) => void): this;
on(event: "OCSPResponse", listener: (response: Buffer) => void): this;
on(event: "OCSPResponse", listener: (response: NonSharedBuffer) => void): this;
on(event: "secureConnect", listener: () => void): this;
on(event: "session", listener: (session: Buffer) => void): this;
on(event: "keylog", listener: (line: Buffer) => void): this;
on(event: "session", listener: (session: NonSharedBuffer) => void): this;
on(event: "keylog", listener: (line: NonSharedBuffer) => void): this;
once(event: string, listener: (...args: any[]) => void): this;
once(event: "OCSPResponse", listener: (response: Buffer) => void): this;
once(event: "OCSPResponse", listener: (response: NonSharedBuffer) => void): this;
once(event: "secureConnect", listener: () => void): this;
once(event: "session", listener: (session: Buffer) => void): this;
once(event: "keylog", listener: (line: Buffer) => void): this;
once(event: "session", listener: (session: NonSharedBuffer) => void): this;
once(event: "keylog", listener: (line: NonSharedBuffer) => void): this;
prependListener(event: string, listener: (...args: any[]) => void): this;
prependListener(event: "OCSPResponse", listener: (response: Buffer) => void): this;
prependListener(event: "OCSPResponse", listener: (response: NonSharedBuffer) => void): this;
prependListener(event: "secureConnect", listener: () => void): this;
prependListener(event: "session", listener: (session: Buffer) => void): this;
prependListener(event: "keylog", listener: (line: Buffer) => void): this;
prependListener(event: "session", listener: (session: NonSharedBuffer) => void): this;
prependListener(event: "keylog", listener: (line: NonSharedBuffer) => void): this;
prependOnceListener(event: string, listener: (...args: any[]) => void): this;
prependOnceListener(event: "OCSPResponse", listener: (response: Buffer) => void): this;
prependOnceListener(event: "OCSPResponse", listener: (response: NonSharedBuffer) => void): this;
prependOnceListener(event: "secureConnect", listener: () => void): this;
prependOnceListener(event: "session", listener: (session: Buffer) => void): this;
prependOnceListener(event: "keylog", listener: (line: Buffer) => void): this;
prependOnceListener(event: "session", listener: (session: NonSharedBuffer) => void): this;
prependOnceListener(event: "keylog", listener: (line: NonSharedBuffer) => void): this;
}
interface CommonConnectionOptions {
/**
@@ -523,7 +532,7 @@ declare module "tls" {
* An array of strings or a Buffer naming possible ALPN protocols.
* (Protocols should be ordered by their priority.)
*/
ALPNProtocols?: string[] | Uint8Array[] | Uint8Array | undefined;
ALPNProtocols?: readonly string[] | NodeJS.ArrayBufferView | undefined;
/**
* SNICallback(servername, cb) <Function> A function that will be
* called if the client supports SNI TLS extension. Two arguments
@@ -578,7 +587,7 @@ declare module "tls" {
* requires explicitly specifying a cipher suite with the `ciphers` option.
* More information can be found in the RFC 4279.
*/
pskCallback?(socket: TLSSocket, identity: string): DataView | NodeJS.TypedArray | null;
pskCallback?: ((socket: TLSSocket, identity: string) => NodeJS.ArrayBufferView | null) | undefined;
/**
* hint to send to a client to help
* with selecting the identity during TLS-PSK negotiation. Will be ignored
@@ -588,7 +597,7 @@ declare module "tls" {
pskIdentityHint?: string | undefined;
}
interface PSKCallbackNegotation {
psk: DataView | NodeJS.TypedArray;
psk: NodeJS.ArrayBufferView;
identity: string;
}
interface ConnectionOptions extends SecureContextOptions, CommonConnectionOptions {
@@ -619,7 +628,7 @@ declare module "tls" {
* compatible with the selected cipher's digest.
* `identity` must use UTF-8 encoding.
*/
pskCallback?(hint: string | null): PSKCallbackNegotation | null;
pskCallback?: ((hint: string | null) => PSKCallbackNegotation | null) | undefined;
}
/**
* Accepts encrypted connections using TLS or SSL.
@@ -639,7 +648,7 @@ declare module "tls" {
* @param context An object containing any of the possible properties from the {@link createSecureContext} `options` arguments (e.g. `key`, `cert`, `ca`, etc), or a TLS context object created
* with {@link createSecureContext} itself.
*/
addContext(hostname: string, context: SecureContextOptions): void;
addContext(hostname: string, context: SecureContextOptions | SecureContext): void;
/**
* Returns the session ticket keys.
*
@@ -647,7 +656,7 @@ declare module "tls" {
* @since v3.0.0
* @return A 48-byte buffer containing the session ticket keys.
*/
getTicketKeys(): Buffer;
getTicketKeys(): NonSharedBuffer;
/**
* The `server.setSecureContext()` method replaces the secure context of an
* existing server. Existing connections to the server are not interrupted.
@@ -679,122 +688,138 @@ declare module "tls" {
addListener(event: "tlsClientError", listener: (err: Error, tlsSocket: TLSSocket) => void): this;
addListener(
event: "newSession",
listener: (sessionId: Buffer, sessionData: Buffer, callback: () => void) => void,
listener: (sessionId: NonSharedBuffer, sessionData: NonSharedBuffer, callback: () => void) => void,
): this;
addListener(
event: "OCSPRequest",
listener: (
certificate: Buffer,
issuer: Buffer,
callback: (err: Error | null, resp: Buffer) => void,
certificate: NonSharedBuffer,
issuer: NonSharedBuffer,
callback: (err: Error | null, resp: Buffer | null) => void,
) => void,
): this;
addListener(
event: "resumeSession",
listener: (sessionId: Buffer, callback: (err: Error | null, sessionData: Buffer | null) => void) => void,
listener: (
sessionId: NonSharedBuffer,
callback: (err: Error | null, sessionData: Buffer | null) => void,
) => void,
): this;
addListener(event: "secureConnection", listener: (tlsSocket: TLSSocket) => void): this;
addListener(event: "keylog", listener: (line: Buffer, tlsSocket: TLSSocket) => void): this;
addListener(event: "keylog", listener: (line: NonSharedBuffer, tlsSocket: TLSSocket) => void): this;
emit(event: string | symbol, ...args: any[]): boolean;
emit(event: "tlsClientError", err: Error, tlsSocket: TLSSocket): boolean;
emit(event: "newSession", sessionId: Buffer, sessionData: Buffer, callback: () => void): boolean;
emit(
event: "newSession",
sessionId: NonSharedBuffer,
sessionData: NonSharedBuffer,
callback: () => void,
): boolean;
emit(
event: "OCSPRequest",
certificate: Buffer,
issuer: Buffer,
callback: (err: Error | null, resp: Buffer) => void,
certificate: NonSharedBuffer,
issuer: NonSharedBuffer,
callback: (err: Error | null, resp: Buffer | null) => void,
): boolean;
emit(
event: "resumeSession",
sessionId: Buffer,
sessionId: NonSharedBuffer,
callback: (err: Error | null, sessionData: Buffer | null) => void,
): boolean;
emit(event: "secureConnection", tlsSocket: TLSSocket): boolean;
emit(event: "keylog", line: Buffer, tlsSocket: TLSSocket): boolean;
emit(event: "keylog", line: NonSharedBuffer, tlsSocket: TLSSocket): boolean;
on(event: string, listener: (...args: any[]) => void): this;
on(event: "tlsClientError", listener: (err: Error, tlsSocket: TLSSocket) => void): this;
on(event: "newSession", listener: (sessionId: Buffer, sessionData: Buffer, callback: () => void) => void): this;
on(
event: "newSession",
listener: (sessionId: NonSharedBuffer, sessionData: NonSharedBuffer, callback: () => void) => void,
): this;
on(
event: "OCSPRequest",
listener: (
certificate: Buffer,
issuer: Buffer,
callback: (err: Error | null, resp: Buffer) => void,
certificate: NonSharedBuffer,
issuer: NonSharedBuffer,
callback: (err: Error | null, resp: Buffer | null) => void,
) => void,
): this;
on(
event: "resumeSession",
listener: (sessionId: Buffer, callback: (err: Error | null, sessionData: Buffer | null) => void) => void,
listener: (
sessionId: NonSharedBuffer,
callback: (err: Error | null, sessionData: Buffer | null) => void,
) => void,
): this;
on(event: "secureConnection", listener: (tlsSocket: TLSSocket) => void): this;
on(event: "keylog", listener: (line: Buffer, tlsSocket: TLSSocket) => void): this;
on(event: "keylog", listener: (line: NonSharedBuffer, tlsSocket: TLSSocket) => void): this;
once(event: string, listener: (...args: any[]) => void): this;
once(event: "tlsClientError", listener: (err: Error, tlsSocket: TLSSocket) => void): this;
once(
event: "newSession",
listener: (sessionId: Buffer, sessionData: Buffer, callback: () => void) => void,
listener: (sessionId: NonSharedBuffer, sessionData: NonSharedBuffer, callback: () => void) => void,
): this;
once(
event: "OCSPRequest",
listener: (
certificate: Buffer,
issuer: Buffer,
callback: (err: Error | null, resp: Buffer) => void,
certificate: NonSharedBuffer,
issuer: NonSharedBuffer,
callback: (err: Error | null, resp: Buffer | null) => void,
) => void,
): this;
once(
event: "resumeSession",
listener: (sessionId: Buffer, callback: (err: Error | null, sessionData: Buffer | null) => void) => void,
listener: (
sessionId: NonSharedBuffer,
callback: (err: Error | null, sessionData: Buffer | null) => void,
) => void,
): this;
once(event: "secureConnection", listener: (tlsSocket: TLSSocket) => void): this;
once(event: "keylog", listener: (line: Buffer, tlsSocket: TLSSocket) => void): this;
once(event: "keylog", listener: (line: NonSharedBuffer, tlsSocket: TLSSocket) => void): this;
prependListener(event: string, listener: (...args: any[]) => void): this;
prependListener(event: "tlsClientError", listener: (err: Error, tlsSocket: TLSSocket) => void): this;
prependListener(
event: "newSession",
listener: (sessionId: Buffer, sessionData: Buffer, callback: () => void) => void,
listener: (sessionId: NonSharedBuffer, sessionData: NonSharedBuffer, callback: () => void) => void,
): this;
prependListener(
event: "OCSPRequest",
listener: (
certificate: Buffer,
issuer: Buffer,
callback: (err: Error | null, resp: Buffer) => void,
certificate: NonSharedBuffer,
issuer: NonSharedBuffer,
callback: (err: Error | null, resp: Buffer | null) => void,
) => void,
): this;
prependListener(
event: "resumeSession",
listener: (sessionId: Buffer, callback: (err: Error | null, sessionData: Buffer | null) => void) => void,
listener: (
sessionId: NonSharedBuffer,
callback: (err: Error | null, sessionData: Buffer | null) => void,
) => void,
): this;
prependListener(event: "secureConnection", listener: (tlsSocket: TLSSocket) => void): this;
prependListener(event: "keylog", listener: (line: Buffer, tlsSocket: TLSSocket) => void): this;
prependListener(event: "keylog", listener: (line: NonSharedBuffer, tlsSocket: TLSSocket) => void): this;
prependOnceListener(event: string, listener: (...args: any[]) => void): this;
prependOnceListener(event: "tlsClientError", listener: (err: Error, tlsSocket: TLSSocket) => void): this;
prependOnceListener(
event: "newSession",
listener: (sessionId: Buffer, sessionData: Buffer, callback: () => void) => void,
listener: (sessionId: NonSharedBuffer, sessionData: NonSharedBuffer, callback: () => void) => void,
): this;
prependOnceListener(
event: "OCSPRequest",
listener: (
certificate: Buffer,
issuer: Buffer,
callback: (err: Error | null, resp: Buffer) => void,
certificate: NonSharedBuffer,
issuer: NonSharedBuffer,
callback: (err: Error | null, resp: Buffer | null) => void,
) => void,
): this;
prependOnceListener(
event: "resumeSession",
listener: (sessionId: Buffer, callback: (err: Error | null, sessionData: Buffer | null) => void) => void,
listener: (
sessionId: NonSharedBuffer,
callback: (err: Error | null, sessionData: Buffer | null) => void,
) => void,
): this;
prependOnceListener(event: "secureConnection", listener: (tlsSocket: TLSSocket) => void): this;
prependOnceListener(event: "keylog", listener: (line: Buffer, tlsSocket: TLSSocket) => void): this;
}
/**
* @deprecated since v0.11.3 Use `tls.TLSSocket` instead.
*/
interface SecurePair {
encrypted: TLSSocket;
cleartext: TLSSocket;
prependOnceListener(event: "keylog", listener: (line: NonSharedBuffer, tlsSocket: TLSSocket) => void): this;
}
type SecureVersion = "TLSv1.3" | "TLSv1.2" | "TLSv1.1" | "TLSv1";
interface SecureContextOptions {
@@ -809,6 +834,12 @@ declare module "tls" {
* This option cannot be used with the `ALPNProtocols` option, and setting both options will throw an error.
*/
ALPNCallback?: ((arg: { servername: string; protocols: string[] }) => string | undefined) | undefined;
/**
* Treat intermediate (non-self-signed)
* certificates in the trust CA certificate list as trusted.
* @since v22.9.0, v20.18.0
*/
allowPartialTrustChain?: boolean | undefined;
/**
* Optionally override the trusted CA certificates. Default is to trust
* the well-known CAs curated by Mozilla. Mozilla's CAs are completely
@@ -843,6 +874,7 @@ declare module "tls" {
ciphers?: string | undefined;
/**
* Name of an OpenSSL engine which can provide the client certificate.
* @deprecated
*/
clientCertEngine?: string | undefined;
/**
@@ -885,12 +917,14 @@ declare module "tls" {
/**
* Name of an OpenSSL engine to get private key from. Should be used
* together with privateKeyIdentifier.
* @deprecated
*/
privateKeyEngine?: string | undefined;
/**
* Identifier of a private key managed by an OpenSSL engine. Should be
* used together with privateKeyEngine. Should not be set together with
* key, because both options define a private key in different ways.
* @deprecated
*/
privateKeyIdentifier?: string | undefined;
/**
@@ -1000,8 +1034,8 @@ declare module "tls" {
* The following illustrates a simple echo server:
*
* ```js
* const tls = require('node:tls');
* const fs = require('node:fs');
* import tls from 'node:tls';
* import fs from 'node:fs';
*
* const options = {
* key: fs.readFileSync('server-key.pem'),
@@ -1046,8 +1080,8 @@ declare module "tls" {
*
* ```js
* // Assumes an echo server that is listening on port 8000.
* const tls = require('node:tls');
* const fs = require('node:fs');
* import tls from 'node:tls';
* import fs from 'node:fs';
*
* const options = {
* // Necessary only if the server requires client certificate authentication.
@@ -1085,45 +1119,6 @@ declare module "tls" {
secureConnectListener?: () => void,
): TLSSocket;
function connect(port: number, options?: ConnectionOptions, secureConnectListener?: () => void): TLSSocket;
/**
* Creates a new secure pair object with two streams, one of which reads and writes
* the encrypted data and the other of which reads and writes the cleartext data.
* Generally, the encrypted stream is piped to/from an incoming encrypted data
* stream and the cleartext one is used as a replacement for the initial encrypted
* stream.
*
* `tls.createSecurePair()` returns a `tls.SecurePair` object with `cleartext` and `encrypted` stream properties.
*
* Using `cleartext` has the same API as {@link TLSSocket}.
*
* The `tls.createSecurePair()` method is now deprecated in favor of`tls.TLSSocket()`. For example, the code:
*
* ```js
* pair = tls.createSecurePair(// ... );
* pair.encrypted.pipe(socket);
* socket.pipe(pair.encrypted);
* ```
*
* can be replaced by:
*
* ```js
* secureSocket = tls.TLSSocket(socket, options);
* ```
*
* where `secureSocket` has the same API as `pair.cleartext`.
* @since v0.3.2
* @deprecated Since v0.11.3 - Use {@link TLSSocket} instead.
* @param context A secure context object as returned by `tls.createSecureContext()`
* @param isServer `true` to specify that this TLS connection should be opened as a server.
* @param requestCert `true` to specify whether a server should request a certificate from a connecting client. Only applies when `isServer` is `true`.
* @param rejectUnauthorized If not `false` a server automatically reject clients with invalid certificates. Only applies when `isServer` is `true`.
*/
function createSecurePair(
context?: SecureContext,
isServer?: boolean,
requestCert?: boolean,
rejectUnauthorized?: boolean,
): SecurePair;
/**
* `{@link createServer}` sets the default value of the `honorCipherOrder` option
* to `true`, other APIs that create secure contexts leave it unset.
@@ -1149,13 +1144,38 @@ declare module "tls" {
* @since v0.11.13
*/
function createSecureContext(options?: SecureContextOptions): SecureContext;
/**
* Returns an array containing the CA certificates from various sources, depending on `type`:
*
* * `"default"`: return the CA certificates that will be used by the Node.js TLS clients by default.
* * When `--use-bundled-ca` is enabled (default), or `--use-openssl-ca` is not enabled,
* this would include CA certificates from the bundled Mozilla CA store.
* * When `--use-system-ca` is enabled, this would also include certificates from the system's
* trusted store.
* * When `NODE_EXTRA_CA_CERTS` is used, this would also include certificates loaded from the specified
* file.
* * `"system"`: return the CA certificates that are loaded from the system's trusted store, according
* to rules set by `--use-system-ca`. This can be used to get the certificates from the system
* when `--use-system-ca` is not enabled.
* * `"bundled"`: return the CA certificates from the bundled Mozilla CA store. This would be the same
* as `tls.rootCertificates`.
* * `"extra"`: return the CA certificates loaded from `NODE_EXTRA_CA_CERTS`. It's an empty array if
* `NODE_EXTRA_CA_CERTS` is not set.
* @since v22.15.0
* @param type The type of CA certificates that will be returned. Valid values
* are `"default"`, `"system"`, `"bundled"` and `"extra"`.
* **Default:** `"default"`.
* @returns An array of PEM-encoded certificates. The array may contain duplicates
* if the same certificate is repeatedly stored in multiple sources.
*/
function getCACertificates(type?: "default" | "system" | "bundled" | "extra"): string[];
/**
* Returns an array with the names of the supported TLS ciphers. The names are
* lower-case for historical reasons, but must be uppercased to be used in
* the `ciphers` option of `{@link createSecureContext}`.
*
* Not all supported ciphers are enabled by default. See
* [Modifying the default TLS cipher suite](https://nodejs.org/docs/latest-v20.x/api/tls.html#modifying-the-default-tls-cipher-suite).
* [Modifying the default TLS cipher suite](https://nodejs.org/docs/latest-v24.x/api/tls.html#modifying-the-default-tls-cipher-suite).
*
* Cipher names that start with `'tls_'` are for TLSv1.3, all the others are for
* TLSv1.2 and below.
@@ -1166,6 +1186,38 @@ declare module "tls" {
* @since v0.10.2
*/
function getCiphers(): string[];
/**
* Sets the default CA certificates used by Node.js TLS clients. If the provided
* certificates are parsed successfully, they will become the default CA
* certificate list returned by {@link getCACertificates} and used
* by subsequent TLS connections that don't specify their own CA certificates.
* The certificates will be deduplicated before being set as the default.
*
* This function only affects the current Node.js thread. Previous
* sessions cached by the HTTPS agent won't be affected by this change, so
* this method should be called before any unwanted cachable TLS connections are
* made.
*
* To use system CA certificates as the default:
*
* ```js
* import tls from 'node:tls';
* tls.setDefaultCACertificates(tls.getCACertificates('system'));
* ```
*
* This function completely replaces the default CA certificate list. To add additional
* certificates to the existing defaults, get the current certificates and append to them:
*
* ```js
* import tls from 'node:tls';
* const currentCerts = tls.getCACertificates('default');
* const additionalCerts = ['-----BEGIN CERTIFICATE-----\n...'];
* tls.setDefaultCACertificates([...currentCerts, ...additionalCerts]);
* ```
* @since v24.5.0
* @param certs An array of CA certificates in PEM format.
*/
function setDefaultCACertificates(certs: ReadonlyArray<string | NodeJS.ArrayBufferView>): void;
/**
* The default curve name to use for ECDH key agreement in a tls server.
* The default value is `'auto'`. See `{@link createSecureContext()}` for further

View File

@@ -9,8 +9,8 @@
* The available categories are:
*
* * `node`: An empty placeholder.
* * `node.async_hooks`: Enables capture of detailed [`async_hooks`](https://nodejs.org/docs/latest-v20.x/api/async_hooks.html) trace data.
* The [`async_hooks`](https://nodejs.org/docs/latest-v20.x/api/async_hooks.html) events have a unique `asyncId` and a special `triggerId` `triggerAsyncId` property.
* * `node.async_hooks`: Enables capture of detailed [`async_hooks`](https://nodejs.org/docs/latest-v24.x/api/async_hooks.html) trace data.
* The [`async_hooks`](https://nodejs.org/docs/latest-v24.x/api/async_hooks.html) events have a unique `asyncId` and a special `triggerId` `triggerAsyncId` property.
* * `node.bootstrap`: Enables capture of Node.js bootstrap milestones.
* * `node.console`: Enables capture of `console.time()` and `console.count()` output.
* * `node.threadpoolwork.sync`: Enables capture of trace data for threadpool synchronous operations, such as `blob`, `zlib`, `crypto` and `node_api`.
@@ -22,7 +22,7 @@
* * `node.fs_dir.sync`: Enables capture of trace data for file system sync directory methods.
* * `node.fs.async`: Enables capture of trace data for file system async methods.
* * `node.fs_dir.async`: Enables capture of trace data for file system async directory methods.
* * `node.perf`: Enables capture of [Performance API](https://nodejs.org/docs/latest-v20.x/api/perf_hooks.html) measurements.
* * `node.perf`: Enables capture of [Performance API](https://nodejs.org/docs/latest-v24.x/api/perf_hooks.html) measurements.
* * `node.perf.usertiming`: Enables capture of only Performance API User Timing
* measures and marks.
* * `node.perf.timerify`: Enables capture of only Performance API timerify
@@ -30,7 +30,7 @@
* * `node.promises.rejections`: Enables capture of trace data tracking the number
* of unhandled Promise rejections and handled-after-rejections.
* * `node.vm.script`: Enables capture of trace data for the `node:vm` module's `runInNewContext()`, `runInContext()`, and `runInThisContext()` methods.
* * `v8`: The [V8](https://nodejs.org/docs/latest-v20.x/api/v8.html) events are GC, compiling, and execution related.
* * `v8`: The [V8](https://nodejs.org/docs/latest-v24.x/api/v8.html) events are GC, compiling, and execution related.
* * `node.http`: Enables capture of trace data for http request / response.
*
* By default the `node`, `node.async_hooks`, and `v8` categories are enabled.
@@ -53,7 +53,7 @@
* Alternatively, trace events may be enabled using the `node:trace_events` module:
*
* ```js
* const trace_events = require('node:trace_events');
* import trace_events from 'node:trace_events';
* const tracing = trace_events.createTracing({ categories: ['node.perf'] });
* tracing.enable(); // Enable trace event capture for the 'node.perf' category
*
@@ -88,9 +88,9 @@
* However the trace-event timestamps are expressed in microseconds,
* unlike `process.hrtime()` which returns nanoseconds.
*
* The features from this module are not available in [`Worker`](https://nodejs.org/docs/latest-v20.x/api/worker_threads.html#class-worker) threads.
* The features from this module are not available in [`Worker`](https://nodejs.org/docs/latest-v24.x/api/worker_threads.html#class-worker) threads.
* @experimental
* @see [source](https://github.com/nodejs/node/blob/v20.13.1/lib/trace_events.js)
* @see [source](https://github.com/nodejs/node/blob/v24.x/lib/trace_events.js)
*/
declare module "trace_events" {
/**
@@ -118,7 +118,7 @@ declare module "trace_events" {
* will be disabled.
*
* ```js
* const trace_events = require('node:trace_events');
* import trace_events from 'node:trace_events';
* const t1 = trace_events.createTracing({ categories: ['node', 'v8'] });
* const t2 = trace_events.createTracing({ categories: ['node.perf', 'node'] });
* t1.enable();
@@ -159,7 +159,7 @@ declare module "trace_events" {
* Creates and returns a `Tracing` object for the given set of `categories`.
*
* ```js
* const trace_events = require('node:trace_events');
* import trace_events from 'node:trace_events';
* const categories = ['node.perf', 'node.async_hooks'];
* const tracing = trace_events.createTracing({ categories });
* tracing.enable();
@@ -178,7 +178,7 @@ declare module "trace_events" {
* Given the file `test.js` below, the command `node --trace-event-categories node.perf test.js` will print `'node.async_hooks,node.perf'` to the console.
*
* ```js
* const trace_events = require('node:trace_events');
* import trace_events from 'node:trace_events';
* const t1 = trace_events.createTracing({ categories: ['node.async_hooks'] });
* const t2 = trace_events.createTracing({ categories: ['node.perf'] });
* const t3 = trace_events.createTracing({ categories: ['v8'] });

View File

@@ -3,7 +3,7 @@
* directly. However, it can be accessed using:
*
* ```js
* const tty = require('node:tty');
* import tty from 'node:tty';
* ```
*
* When Node.js detects that it is being run with a text terminal ("TTY")
@@ -21,7 +21,7 @@
*
* In most cases, there should be little to no reason for an application to
* manually create instances of the `tty.ReadStream` and `tty.WriteStream` classes.
* @see [source](https://github.com/nodejs/node/blob/v20.13.1/lib/tty.js)
* @see [source](https://github.com/nodejs/node/blob/v24.x/lib/tty.js)
*/
declare module "tty" {
import * as net from "node:net";

View File

@@ -5,10 +5,10 @@
* ```js
* import url from 'node:url';
* ```
* @see [source](https://github.com/nodejs/node/blob/v20.13.1/lib/url.js)
* @see [source](https://github.com/nodejs/node/blob/v24.x/lib/url.js)
*/
declare module "url" {
import { Blob as NodeBlob } from "node:buffer";
import { Blob as NodeBlob, NonSharedBuffer } from "node:buffer";
import { ClientRequestArgs } from "node:http";
import { ParsedUrlQuery, ParsedUrlQueryInput } from "node:querystring";
// Input to `url.format`
@@ -50,10 +50,18 @@ declare module "url" {
/**
* `true` if the `path` should be return as a windows filepath, `false` for posix, and `undefined` for the system default.
* @default undefined
* @since v22.1.0
*/
windows?: boolean | undefined;
}
interface PathToFileUrlOptions {
/**
* `true` if the `path` should be return as a windows filepath, `false` for posix, and `undefined` for the system default.
* @default undefined
* @since v22.1.0
*/
windows?: boolean | undefined;
}
interface PathToFileUrlOptions extends FileUrlToPathOptions {}
/**
* The `url.parse()` method takes a URL string, parses it, and returns a URL
* object.
@@ -63,20 +71,44 @@ declare module "url" {
* A `URIError` is thrown if the `auth` property is present but cannot be decoded.
*
* `url.parse()` uses a lenient, non-standard algorithm for parsing URL
* strings. It is prone to security issues such as [host name spoofing](https://hackerone.com/reports/678487) and incorrect handling of usernames and passwords. Do not use with untrusted
* input. CVEs are not issued for `url.parse()` vulnerabilities. Use the `WHATWG URL` API instead.
* strings. It is prone to security issues such as [host name spoofing](https://hackerone.com/reports/678487)
* and incorrect handling of usernames and passwords. Do not use with untrusted
* input. CVEs are not issued for `url.parse()` vulnerabilities. Use the
* [WHATWG URL](https://nodejs.org/docs/latest-v24.x/api/url.html#the-whatwg-url-api) API instead, for example:
*
* ```js
* function getURL(req) {
* const proto = req.headers['x-forwarded-proto'] || 'https';
* const host = req.headers['x-forwarded-host'] || req.headers.host || 'example.com';
* return new URL(req.url || '/', `${proto}://${host}`);
* }
* ```
*
* The example above assumes well-formed headers are forwarded from a reverse
* proxy to your Node.js server. If you are not using a reverse proxy, you should
* use the example below:
*
* ```js
* function getURL(req) {
* return new URL(req.url || '/', 'https://example.com');
* }
* ```
* @since v0.1.25
* @deprecated Use the WHATWG URL API instead.
* @param urlString The URL string to parse.
* @param [parseQueryString=false] If `true`, the `query` property will always be set to an object returned by the {@link querystring} module's `parse()` method. If `false`, the `query` property
* on the returned URL object will be an unparsed, undecoded string.
* @param [slashesDenoteHost=false] If `true`, the first token after the literal string `//` and preceding the next `/` will be interpreted as the `host`. For instance, given `//foo/bar`, the
* result would be `{host: 'foo', pathname: '/bar'}` rather than `{pathname: '//foo/bar'}`.
* @param parseQueryString If `true`, the `query` property will always
* be set to an object returned by the [`querystring`](https://nodejs.org/docs/latest-v24.x/api/querystring.html) module's `parse()`
* method. If `false`, the `query` property on the returned URL object will be an
* unparsed, undecoded string. **Default:** `false`.
* @param slashesDenoteHost If `true`, the first token after the literal
* string `//` and preceding the next `/` will be interpreted as the `host`.
* For instance, given `//foo/bar`, the result would be
* `{host: 'foo', pathname: '/bar'}` rather than `{pathname: '//foo/bar'}`.
* **Default:** `false`.
*/
function parse(urlString: string): UrlWithStringQuery;
function parse(
urlString: string,
parseQueryString: false | undefined,
parseQueryString?: false,
slashesDenoteHost?: boolean,
): UrlWithStringQuery;
function parse(urlString: string, parseQueryString: true, slashesDenoteHost?: boolean): UrlWithParsedQuery;
@@ -85,7 +117,7 @@ declare module "url" {
* The `url.format()` method returns a formatted URL string derived from `urlObject`.
*
* ```js
* const url = require('node:url');
* import url from 'node:url';
* url.format({
* protocol: 'https',
* hostname: 'example.com',
@@ -149,7 +181,7 @@ declare module "url" {
* The `url.format()` method returns a formatted URL string derived from `urlObject`.
*
* ```js
* const url = require('node:url');
* import url from 'node:url';
* url.format({
* protocol: 'https',
* hostname: 'example.com',
@@ -214,7 +246,7 @@ declare module "url" {
* manner similar to that of a web browser resolving an anchor tag.
*
* ```js
* const url = require('node:url');
* import url from 'node:url';
* url.resolve('/one/two/three', 'four'); // '/one/two/four'
* url.resolve('http://example.com/', '/one'); // 'http://example.com/one'
* url.resolve('http://example.com/one', '/two'); // 'http://example.com/two'
@@ -307,6 +339,17 @@ declare module "url" {
* @return The fully-resolved platform-specific Node.js file path.
*/
function fileURLToPath(url: string | URL, options?: FileUrlToPathOptions): string;
/**
* Like `url.fileURLToPath(...)` except that instead of returning a string
* representation of the path, a `Buffer` is returned. This conversion is
* helpful when the input URL contains percent-encoded segments that are
* not valid UTF-8 / Unicode sequences.
* @since v24.3.0
* @param url The file URL string or URL object to convert to a path.
* @returns The fully-resolved platform-specific Node.js file path
* as a `Buffer`.
*/
function fileURLToPathBuffer(url: string | URL, options?: FileUrlToPathOptions): NonSharedBuffer;
/**
* This function ensures that `path` is resolved absolutely, and that the URL
* control characters are correctly encoded when converting into a File URL.
@@ -392,10 +435,10 @@ declare module "url" {
* Creates a `'blob:nodedata:...'` URL string that represents the given `Blob` object and can be used to retrieve the `Blob` later.
*
* ```js
* const {
* import {
* Blob,
* resolveObjectURL,
* } = require('node:buffer');
* } from 'node:buffer';
*
* const blob = new Blob(['hello']);
* const id = URL.createObjectURL(blob);
@@ -412,14 +455,12 @@ declare module "url" {
* Threads, `Blob` objects registered within one Worker will not be available
* to other workers or the main thread.
* @since v16.7.0
* @experimental
*/
static createObjectURL(blob: NodeBlob): string;
/**
* Removes the stored `Blob` identified by the given ID. Attempting to revoke a
* ID that isn't registered will silently fail.
* @since v16.7.0
* @experimental
* @param id A `'blob:nodedata:...` URL string returned by a prior call to `URL.createObjectURL()`.
*/
static revokeObjectURL(id: string): void;
@@ -437,6 +478,18 @@ declare module "url" {
* @param base The base URL to resolve against if the `input` is not absolute. If `base` is not a string, it is `converted to a string` first.
*/
static canParse(input: string, base?: string): boolean;
/**
* Parses a string as a URL. If `base` is provided, it will be used as the base
* URL for the purpose of resolving non-absolute `input` URLs. Returns `null`
* if the parameters can't be resolved to a valid URL.
* @since v22.1.0
* @param input The absolute or relative input URL to parse. If `input`
* is relative, then `base` is required. If `input` is absolute, the `base`
* is ignored. If `input` is not a string, it is [converted to a string](https://tc39.es/ecma262/#sec-tostring) first.
* @param base The base URL to resolve against if the `input` is not
* absolute. If `base` is not a string, it is [converted to a string](https://tc39.es/ecma262/#sec-tostring) first.
*/
static parse(input: string, base?: string): URL | null;
constructor(input: string | { toString: () => string }, base?: string | URL);
/**
* Gets and sets the fragment portion of the URL.
@@ -740,6 +793,57 @@ declare module "url" {
*/
toJSON(): string;
}
interface URLPatternComponentResult {
input: string;
groups: Record<string, string | undefined>;
}
interface URLPatternInit {
protocol?: string;
username?: string;
password?: string;
hostname?: string;
port?: string;
pathname?: string;
search?: string;
hash?: string;
baseURL?: string;
}
interface URLPatternOptions {
ignoreCase?: boolean;
}
interface URLPatternResult {
inputs: (string | URLPatternInit)[];
protocol: URLPatternComponentResult;
username: URLPatternComponentResult;
password: URLPatternComponentResult;
hostname: URLPatternComponentResult;
port: URLPatternComponentResult;
pathname: URLPatternComponentResult;
search: URLPatternComponentResult;
hash: URLPatternComponentResult;
}
/**
* @since v23.8.0
* @experimental
*/
class URLPattern {
constructor(input: string | URLPatternInit, baseURL: string, options?: URLPatternOptions);
constructor(input?: string | URLPatternInit, options?: URLPatternOptions);
exec(input?: string | URLPatternInit, baseURL?: string): URLPatternResult | null;
readonly hasRegExpGroups: boolean;
readonly hash: string;
readonly hostname: string;
readonly password: string;
readonly pathname: string;
readonly port: string;
readonly protocol: string;
readonly search: string;
test(input?: string | URLPatternInit, baseURL?: string): boolean;
readonly username: string;
}
interface URLSearchParamsIterator<T> extends NodeJS.Iterator<T, NodeJS.BuiltinIteratorReturn, unknown> {
[Symbol.iterator](): URLSearchParamsIterator<T>;
}
/**
* The `URLSearchParams` API provides read and write access to the query of a `URL`. The `URLSearchParams` class can also be used standalone with one of the
* four following constructors.
@@ -808,9 +912,9 @@ declare module "url" {
* Returns an ES6 `Iterator` over each of the name-value pairs in the query.
* Each item of the iterator is a JavaScript `Array`. The first item of the `Array` is the `name`, the second item of the `Array` is the `value`.
*
* Alias for `urlSearchParams[@@iterator]()`.
* Alias for `urlSearchParams[Symbol.iterator]()`.
*/
entries(): IterableIterator<[string, string]>;
entries(): URLSearchParamsIterator<[string, string]>;
/**
* Iterates over each name-value pair in the query and invokes the given function.
*
@@ -864,7 +968,7 @@ declare module "url" {
* // foo
* ```
*/
keys(): IterableIterator<string>;
keys(): URLSearchParamsIterator<string>;
/**
* Sets the value in the `URLSearchParams` object associated with `name` to `value`. If there are any pre-existing name-value pairs whose names are `name`,
* set the first such pair's value to `value` and remove all others. If not,
@@ -914,37 +1018,38 @@ declare module "url" {
/**
* Returns an ES6 `Iterator` over the values of each name-value pair.
*/
values(): IterableIterator<string>;
[Symbol.iterator](): IterableIterator<[string, string]>;
values(): URLSearchParamsIterator<string>;
[Symbol.iterator](): URLSearchParamsIterator<[string, string]>;
}
import { URL as _URL, URLSearchParams as _URLSearchParams } from "url";
import {
URL as _URL,
URLPattern as _URLPattern,
URLPatternInit as _URLPatternInit,
URLPatternResult as _URLPatternResult,
URLSearchParams as _URLSearchParams,
} from "url";
global {
interface URLSearchParams extends _URLSearchParams {}
interface URL extends _URL {}
interface Global {
URL: typeof _URL;
URLSearchParams: typeof _URLSearchParams;
}
/**
* `URL` class is a global reference for `require('url').URL`
* https://nodejs.org/api/url.html#the-whatwg-url-api
* @since v10.0.0
*/
var URL: typeof globalThis extends {
onmessage: any;
URL: infer T;
} ? T
: typeof _URL;
/**
* `URLSearchParams` class is a global reference for `require('url').URLSearchParams`
* https://nodejs.org/api/url.html#class-urlsearchparams
* @since v10.0.0
*/
interface URLSearchParams extends _URLSearchParams {}
var URLSearchParams: typeof globalThis extends {
onmessage: any;
URLSearchParams: infer T;
} ? T
: typeof _URLSearchParams;
interface URLPatternInit extends _URLPatternInit {}
interface URLPatternResult extends _URLPatternResult {}
interface URLPattern extends _URLPattern {}
var URLPattern: typeof globalThis extends {
onmessage: any;
scheduler: any; // Must be a var introduced at the same time as URLPattern.
URLPattern: infer T;
} ? T
: typeof _URLPattern;
}
}
declare module "node:url" {

File diff suppressed because it is too large Load Diff

View File

@@ -2,11 +2,12 @@
* The `node:v8` module exposes APIs that are specific to the version of [V8](https://developers.google.com/v8/) built into the Node.js binary. It can be accessed using:
*
* ```js
* const v8 = require('node:v8');
* import v8 from 'node:v8';
* ```
* @see [source](https://github.com/nodejs/node/blob/v20.13.1/lib/v8.js)
* @see [source](https://github.com/nodejs/node/blob/v24.x/lib/v8.js)
*/
declare module "v8" {
import { NonSharedBuffer } from "node:buffer";
import { Readable } from "node:stream";
interface HeapSpaceInfo {
space_name: string;
@@ -43,12 +44,12 @@ declare module "v8" {
* If true, expose internals in the heap snapshot.
* @default false
*/
exposeInternals?: boolean;
exposeInternals?: boolean | undefined;
/**
* If true, expose numeric values in artificial fields.
* @default false
*/
exposeNumericValues?: boolean;
exposeNumericValues?: boolean | undefined;
}
/**
* Returns an integer representing a version tag derived from the V8 version,
@@ -113,6 +114,87 @@ declare module "v8" {
* @since v1.0.0
*/
function getHeapStatistics(): HeapInfo;
/**
* It returns an object with a structure similar to the
* [`cppgc::HeapStatistics`](https://v8docs.nodesource.com/node-22.4/d7/d51/heap-statistics_8h_source.html)
* object. See the [V8 documentation](https://v8docs.nodesource.com/node-22.4/df/d2f/structcppgc_1_1_heap_statistics.html)
* for more information about the properties of the object.
*
* ```js
* // Detailed
* ({
* committed_size_bytes: 131072,
* resident_size_bytes: 131072,
* used_size_bytes: 152,
* space_statistics: [
* {
* name: 'NormalPageSpace0',
* committed_size_bytes: 0,
* resident_size_bytes: 0,
* used_size_bytes: 0,
* page_stats: [{}],
* free_list_stats: {},
* },
* {
* name: 'NormalPageSpace1',
* committed_size_bytes: 131072,
* resident_size_bytes: 131072,
* used_size_bytes: 152,
* page_stats: [{}],
* free_list_stats: {},
* },
* {
* name: 'NormalPageSpace2',
* committed_size_bytes: 0,
* resident_size_bytes: 0,
* used_size_bytes: 0,
* page_stats: [{}],
* free_list_stats: {},
* },
* {
* name: 'NormalPageSpace3',
* committed_size_bytes: 0,
* resident_size_bytes: 0,
* used_size_bytes: 0,
* page_stats: [{}],
* free_list_stats: {},
* },
* {
* name: 'LargePageSpace',
* committed_size_bytes: 0,
* resident_size_bytes: 0,
* used_size_bytes: 0,
* page_stats: [{}],
* free_list_stats: {},
* },
* ],
* type_names: [],
* detail_level: 'detailed',
* });
* ```
*
* ```js
* // Brief
* ({
* committed_size_bytes: 131072,
* resident_size_bytes: 131072,
* used_size_bytes: 128864,
* space_statistics: [],
* type_names: [],
* detail_level: 'brief',
* });
* ```
* @since v22.15.0
* @param detailLevel **Default:** `'detailed'`. Specifies the level of detail in the returned statistics.
* Accepted values are:
* * `'brief'`: Brief statistics contain only the top-level
* allocated and used
* memory statistics for the entire heap.
* * `'detailed'`: Detailed statistics also contain a break
* down per space and page, as well as freelist statistics
* and object type histograms.
*/
function getCppHeapStatistics(detailLevel?: "brief" | "detailed"): object;
/**
* Returns statistics about the V8 heap spaces, i.e. the segments which make up
* the V8 heap. Neither the ordering of heap spaces, nor the availability of a
@@ -176,7 +258,7 @@ declare module "v8" {
*
* ```js
* // Print GC events to stdout for one minute.
* const v8 = require('node:v8');
* import v8 from 'node:v8';
* v8.setFlagsFromString('--trace_gc');
* setTimeout(() => { v8.setFlagsFromString('--notrace_gc'); }, 60e3);
* ```
@@ -243,7 +325,7 @@ declare module "v8" {
*
* ```js
* // Print heap snapshot to the console
* const v8 = require('node:v8');
* import v8 from 'node:v8';
* const stream = v8.getHeapSnapshot();
* stream.pipe(process.stdout);
* ```
@@ -268,12 +350,12 @@ declare module "v8" {
* for a duration depending on the heap size.
*
* ```js
* const { writeHeapSnapshot } = require('node:v8');
* const {
* import { writeHeapSnapshot } from 'node:v8';
* import {
* Worker,
* isMainThread,
* parentPort,
* } = require('node:worker_threads');
* } from 'node:worker_threads';
*
* if (isMainThread) {
* const worker = new Worker(__filename);
@@ -319,6 +401,71 @@ declare module "v8" {
* @since v12.8.0
*/
function getHeapCodeStatistics(): HeapCodeStatistics;
/**
* @since v24.8.0
*/
interface CPUProfileHandle {
/**
* Stopping collecting the profile, then return a Promise that fulfills with an error or the
* profile data.
* @since v24.8.0
*/
stop(): Promise<string>;
/**
* Stopping collecting the profile and the profile will be discarded.
* @since v24.8.0
*/
[Symbol.asyncDispose](): Promise<void>;
}
/**
* @since v24.9.0
*/
interface HeapProfileHandle {
/**
* Stopping collecting the profile, then return a Promise that fulfills with an error or the
* profile data.
* @since v24.9.0
*/
stop(): Promise<string>;
/**
* Stopping collecting the profile and the profile will be discarded.
* @since v24.9.0
*/
[Symbol.asyncDispose](): Promise<void>;
}
/**
* V8 only supports `Latin-1/ISO-8859-1` and `UTF16` as the underlying representation of a string.
* If the `content` uses `Latin-1/ISO-8859-1` as the underlying representation, this function will return true;
* otherwise, it returns false.
*
* If this method returns false, that does not mean that the string contains some characters not in `Latin-1/ISO-8859-1`.
* Sometimes a `Latin-1` string may also be represented as `UTF16`.
*
* ```js
* const { isStringOneByteRepresentation } = require('node:v8');
*
* const Encoding = {
* latin1: 1,
* utf16le: 2,
* };
* const buffer = Buffer.alloc(100);
* function writeString(input) {
* if (isStringOneByteRepresentation(input)) {
* buffer.writeUint8(Encoding.latin1);
* buffer.writeUint32LE(input.length, 1);
* buffer.write(input, 5, 'latin1');
* } else {
* buffer.writeUint8(Encoding.utf16le);
* buffer.writeUint32LE(input.length * 2, 1);
* buffer.write(input, 5, 'utf16le');
* }
* }
* writeString('hello');
* writeString('你好');
* ```
* @since v23.10.0, v22.15.0
*/
function isStringOneByteRepresentation(content: string): boolean;
/**
* @since v8.0.0
*/
@@ -339,7 +486,7 @@ declare module "v8" {
* the buffer is released. Calling this method results in undefined behavior
* if a previous write has failed.
*/
releaseBuffer(): Buffer;
releaseBuffer(): NonSharedBuffer;
/**
* Marks an `ArrayBuffer` as having its contents transferred out of band.
* Pass the corresponding `ArrayBuffer` in the deserializing context to `deserializer.transferArrayBuffer()`.
@@ -367,7 +514,7 @@ declare module "v8" {
* will require a way to compute the length of the buffer.
* For use inside of a custom `serializer._writeHostObject()`.
*/
writeRawBytes(buffer: NodeJS.TypedArray): void;
writeRawBytes(buffer: NodeJS.ArrayBufferView): void;
}
/**
* A subclass of `Serializer` that serializes `TypedArray`(in particular `Buffer`) and `DataView` objects as host objects, and only
@@ -438,14 +585,14 @@ declare module "v8" {
* larger than `buffer.constants.MAX_LENGTH`.
* @since v8.0.0
*/
function serialize(value: any): Buffer;
function serialize(value: any): NonSharedBuffer;
/**
* Uses a `DefaultDeserializer` with default options to read a JS value
* from a buffer.
* @since v8.0.0
* @param buffer A buffer returned by {@link serialize}.
*/
function deserialize(buffer: NodeJS.TypedArray): any;
function deserialize(buffer: NodeJS.ArrayBufferView): any;
/**
* The `v8.takeCoverage()` method allows the user to write the coverage started by `NODE_V8_COVERAGE` to disk on demand. This method can be invoked multiple
* times during the lifetime of the process. Each time the execution counter will
@@ -466,8 +613,7 @@ declare module "v8" {
function stopCoverage(): void;
/**
* The API is a no-op if `--heapsnapshot-near-heap-limit` is already set from the command line or the API is called more than once.
* `limit` must be a positive integer. See [`--heapsnapshot-near-heap-limit`](https://nodejs.org/docs/latest-v20.x/api/cli.html#--heapsnapshot-near-heap-limitmax_count) for more information.
* @experimental
* `limit` must be a positive integer. See [`--heapsnapshot-near-heap-limit`](https://nodejs.org/docs/latest-v24.x/api/cli.html#--heapsnapshot-near-heap-limitmax_count) for more information.
* @since v18.10.0, v16.18.0
*/
function setHeapSnapshotNearHeapLimit(limit: number): void;
@@ -550,7 +696,7 @@ declare module "v8" {
* Here's an example.
*
* ```js
* const { GCProfiler } = require('v8');
* import { GCProfiler } from 'node:v8';
* const profiler = new GCProfiler();
* profiler.start();
* setTimeout(() => {
@@ -693,33 +839,6 @@ declare module "v8" {
*/
const promiseHooks: PromiseHooks;
type StartupSnapshotCallbackFn = (args: any) => any;
interface StartupSnapshot {
/**
* Add a callback that will be called when the Node.js instance is about to get serialized into a snapshot and exit.
* This can be used to release resources that should not or cannot be serialized or to convert user data into a form more suitable for serialization.
* @since v18.6.0, v16.17.0
*/
addSerializeCallback(callback: StartupSnapshotCallbackFn, data?: any): void;
/**
* Add a callback that will be called when the Node.js instance is deserialized from a snapshot.
* The `callback` and the `data` (if provided) will be serialized into the snapshot, they can be used to re-initialize the state of the application or
* to re-acquire resources that the application needs when the application is restarted from the snapshot.
* @since v18.6.0, v16.17.0
*/
addDeserializeCallback(callback: StartupSnapshotCallbackFn, data?: any): void;
/**
* This sets the entry point of the Node.js application when it is deserialized from a snapshot. This can be called only once in the snapshot building script.
* If called, the deserialized application no longer needs an additional entry point script to start up and will simply invoke the callback along with the deserialized
* data (if provided), otherwise an entry point script still needs to be provided to the deserialized application.
* @since v18.6.0, v16.17.0
*/
setDeserializeMainFunction(callback: StartupSnapshotCallbackFn, data?: any): void;
/**
* Returns true if the Node.js instance is run to build a snapshot.
* @since v18.6.0, v16.17.0
*/
isBuildingSnapshot(): boolean;
}
/**
* The `v8.startupSnapshot` interface can be used to add serialization and deserialization hooks for custom startup snapshots.
*
@@ -736,12 +855,12 @@ declare module "v8" {
* ```js
* 'use strict';
*
* const fs = require('node:fs');
* const zlib = require('node:zlib');
* const path = require('node:path');
* const assert = require('node:assert');
* import fs from 'node:fs';
* import zlib from 'node:zlib';
* import path from 'node:path';
* import assert from 'node:assert';
*
* const v8 = require('node:v8');
* import v8 from 'node:v8';
*
* class BookShelf {
* storage = new Map();
@@ -798,10 +917,35 @@ declare module "v8" {
*
* Currently the application deserialized from a user-land snapshot cannot be snapshotted again, so these APIs are only available to applications that are not deserialized from a user-land snapshot.
*
* @experimental
* @since v18.6.0, v16.17.0
*/
const startupSnapshot: StartupSnapshot;
namespace startupSnapshot {
/**
* Add a callback that will be called when the Node.js instance is about to get serialized into a snapshot and exit.
* This can be used to release resources that should not or cannot be serialized or to convert user data into a form more suitable for serialization.
* @since v18.6.0, v16.17.0
*/
function addSerializeCallback(callback: StartupSnapshotCallbackFn, data?: any): void;
/**
* Add a callback that will be called when the Node.js instance is deserialized from a snapshot.
* The `callback` and the `data` (if provided) will be serialized into the snapshot, they can be used to re-initialize the state of the application or
* to re-acquire resources that the application needs when the application is restarted from the snapshot.
* @since v18.6.0, v16.17.0
*/
function addDeserializeCallback(callback: StartupSnapshotCallbackFn, data?: any): void;
/**
* This sets the entry point of the Node.js application when it is deserialized from a snapshot. This can be called only once in the snapshot building script.
* If called, the deserialized application no longer needs an additional entry point script to start up and will simply invoke the callback along with the deserialized
* data (if provided), otherwise an entry point script still needs to be provided to the deserialized application.
* @since v18.6.0, v16.17.0
*/
function setDeserializeMainFunction(callback: StartupSnapshotCallbackFn, data?: any): void;
/**
* Returns true if the Node.js instance is run to build a snapshot.
* @since v18.6.0, v16.17.0
*/
function isBuildingSnapshot(): boolean;
}
}
declare module "node:v8" {
export * from "v8";

Some files were not shown because too many files have changed in this diff Show More