init commit
15
.gitignore
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea/caches
|
||||
/.idea/libraries
|
||||
/.idea/modules.xml
|
||||
/.idea/workspace.xml
|
||||
/.idea/navEditor.xml
|
||||
/.idea/assetWizardSettings.xml
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
||||
.externalNativeBuild
|
||||
.cxx
|
||||
local.properties
|
||||
3
.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
1
app/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/build
|
||||
105
app/build.gradle.kts
Normal file
@@ -0,0 +1,105 @@
|
||||
plugins {
|
||||
alias(libs.plugins.android.application)
|
||||
alias(libs.plugins.kotlin.android)
|
||||
alias(libs.plugins.kotlin.compose)
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "com.example.godeye"
|
||||
compileSdk = 36
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "com.example.godeye"
|
||||
minSdk = 24
|
||||
targetSdk = 36
|
||||
versionCode = 1
|
||||
versionName = "1.0"
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
isMinifyEnabled = false
|
||||
proguardFiles(
|
||||
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||
"proguard-rules.pro"
|
||||
)
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
}
|
||||
kotlinOptions {
|
||||
jvmTarget = "17"
|
||||
}
|
||||
buildFeatures {
|
||||
compose = true
|
||||
viewBinding = true
|
||||
}
|
||||
|
||||
// Исправляем проблему с Java toolchain
|
||||
java {
|
||||
toolchain {
|
||||
languageVersion.set(JavaLanguageVersion.of(17))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// Core Android
|
||||
implementation(libs.androidx.core.ktx)
|
||||
implementation(libs.androidx.lifecycle.runtime.ktx)
|
||||
implementation(libs.androidx.activity.compose)
|
||||
implementation(platform(libs.androidx.compose.bom))
|
||||
implementation(libs.androidx.compose.ui)
|
||||
implementation(libs.androidx.compose.ui.graphics)
|
||||
implementation(libs.androidx.compose.ui.tooling.preview)
|
||||
implementation(libs.androidx.compose.material3)
|
||||
|
||||
// ViewModel and LiveData
|
||||
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0")
|
||||
implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.7.0")
|
||||
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.7.0")
|
||||
implementation("androidx.activity:activity-ktx:1.8.2")
|
||||
|
||||
// Socket.IO для WebSocket соединения
|
||||
implementation("io.socket:socket.io-client:2.1.2")
|
||||
|
||||
// Пока уберем WebRTC зависимость - создадим заглушку для демонстрации
|
||||
// В реальном проекте нужно будет настроить правильную WebRTC библиотеку
|
||||
|
||||
// Camera2 API
|
||||
implementation("androidx.camera:camera-core:1.3.1")
|
||||
implementation("androidx.camera:camera-camera2:1.3.1")
|
||||
implementation("androidx.camera:camera-lifecycle:1.3.1")
|
||||
implementation("androidx.camera:camera-view:1.3.1")
|
||||
|
||||
// JSON парсинг
|
||||
implementation("com.google.code.gson:gson:2.10.1")
|
||||
|
||||
// Корутины
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")
|
||||
|
||||
// RecyclerView
|
||||
implementation("androidx.recyclerview:recyclerview:1.3.2")
|
||||
|
||||
// Work Manager для фоновых задач
|
||||
implementation("androidx.work:work-runtime-ktx:2.9.0")
|
||||
|
||||
// Permissions
|
||||
implementation("androidx.activity:activity-compose:1.8.2")
|
||||
|
||||
// Navigation
|
||||
implementation("androidx.navigation:navigation-compose:2.7.6")
|
||||
|
||||
// Testing
|
||||
testImplementation(libs.junit)
|
||||
androidTestImplementation(libs.androidx.junit)
|
||||
androidTestImplementation(libs.androidx.espresso.core)
|
||||
androidTestImplementation(platform(libs.androidx.compose.bom))
|
||||
androidTestImplementation(libs.androidx.compose.ui.test.junit4)
|
||||
debugImplementation(libs.androidx.compose.ui.tooling)
|
||||
debugImplementation(libs.androidx.compose.ui.test.manifest)
|
||||
}
|
||||
21
app/proguard-rules.pro
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.example.godeye
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* See [testing documentation](http://d.android.com/tools/testing).
|
||||
*/
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ExampleInstrumentedTest {
|
||||
@Test
|
||||
fun useAppContext() {
|
||||
// Context of the app under test.
|
||||
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
assertEquals("com.example.godeye", appContext.packageName)
|
||||
}
|
||||
}
|
||||
57
app/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,57 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<!-- Основные разрешения -->
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_CAMERA" />
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
|
||||
<!-- Требования к оборудованию -->
|
||||
<uses-feature android:name="android.hardware.camera" android:required="true" />
|
||||
<uses-feature android:name="android.hardware.camera.autofocus" />
|
||||
<uses-feature android:name="android.hardware.microphone" android:required="true" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||
android:fullBackupContent="@xml/backup_rules"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.GodEye">
|
||||
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/Theme.GodEye"
|
||||
android:screenOrientation="portrait">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<!-- Socket Service для WebSocket соединения -->
|
||||
<service
|
||||
android:name=".services.SocketService"
|
||||
android:enabled="true"
|
||||
android:exported="false"
|
||||
android:foregroundServiceType="camera" />
|
||||
|
||||
<!-- Camera Service для работы с камерой -->
|
||||
<service
|
||||
android:name=".services.CameraService"
|
||||
android:enabled="true"
|
||||
android:exported="false"
|
||||
android:foregroundServiceType="camera" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
118
app/src/main/java/com/example/godeye/MainActivity.kt
Normal file
@@ -0,0 +1,118 @@
|
||||
package com.example.godeye
|
||||
|
||||
import android.Manifest
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Bundle
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.activity.viewModels
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.SnackbarHost
|
||||
import androidx.compose.material3.SnackbarHostState
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.example.godeye.managers.PermissionManager
|
||||
import com.example.godeye.ui.screens.MainScreen
|
||||
import com.example.godeye.ui.theme.GodEyeTheme
|
||||
import com.example.godeye.ui.viewmodels.MainViewModel
|
||||
import com.example.godeye.utils.Logger
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class MainActivity : ComponentActivity() {
|
||||
|
||||
private val viewModel: MainViewModel by viewModels()
|
||||
private lateinit var permissionManager: PermissionManager
|
||||
|
||||
// Launcher для запроса разрешений
|
||||
private val permissionsLauncher = registerForActivityResult(
|
||||
ActivityResultContracts.RequestMultiplePermissions()
|
||||
) { permissions ->
|
||||
val allGranted = permissions.values.all { it }
|
||||
if (allGranted) {
|
||||
Logger.d("All permissions granted")
|
||||
viewModel.startServices() // Запуск сервисов после получения разрешений
|
||||
} else {
|
||||
Logger.w("Some permissions were denied")
|
||||
val deniedPermissions = permissions.filterValues { !it }.keys
|
||||
Logger.w("Denied permissions: ${deniedPermissions.joinToString(", ")}")
|
||||
}
|
||||
|
||||
// Логируем статус разрешений
|
||||
permissionManager.logPermissionsStatus()
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
Logger.d("MainActivity created")
|
||||
permissionManager = PermissionManager(this)
|
||||
|
||||
// Проверяем разрешения при запуске
|
||||
checkAndRequestPermissions()
|
||||
if (permissionManager.hasAllRequiredPermissions()) {
|
||||
viewModel.startServices() // Запуск сервисов если разрешения уже есть
|
||||
}
|
||||
|
||||
setContent {
|
||||
GodEyeTheme {
|
||||
val snackbarHostState = remember { SnackbarHostState() }
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
|
||||
Surface(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
color = MaterialTheme.colorScheme.background
|
||||
) {
|
||||
Scaffold(
|
||||
snackbarHost = { SnackbarHost(snackbarHostState) }
|
||||
) { paddingValues ->
|
||||
MainScreen(
|
||||
viewModel = viewModel,
|
||||
onRequestPermissions = {
|
||||
requestMissingPermissions()
|
||||
},
|
||||
onShowError = { message ->
|
||||
coroutineScope.launch {
|
||||
snackbarHostState.showSnackbar(message)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверить и запросить недостающие разрешения
|
||||
*/
|
||||
private fun checkAndRequestPermissions() {
|
||||
if (!permissionManager.hasAllRequiredPermissions()) {
|
||||
Logger.d("Some permissions are missing, requesting...")
|
||||
requestMissingPermissions()
|
||||
} else {
|
||||
Logger.d("All required permissions are granted")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Запросить недостающие разрешения
|
||||
*/
|
||||
private fun requestMissingPermissions() {
|
||||
val missingPermissions = permissionManager.getMissingPermissions()
|
||||
if (missingPermissions.isNotEmpty()) {
|
||||
Logger.d("Requesting permissions: ${missingPermissions.joinToString(", ")}")
|
||||
permissionsLauncher.launch(missingPermissions.toTypedArray())
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
Logger.d("MainActivity destroyed")
|
||||
}
|
||||
}
|
||||
245
app/src/main/java/com/example/godeye/managers/CameraManager.kt
Normal file
@@ -0,0 +1,245 @@
|
||||
package com.example.godeye.managers
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.graphics.SurfaceTexture
|
||||
import android.hardware.camera2.*
|
||||
import android.media.MediaRecorder
|
||||
import android.os.Handler
|
||||
import android.os.HandlerThread
|
||||
import android.util.Size
|
||||
import android.view.Surface
|
||||
import com.example.godeye.models.AppError
|
||||
import com.example.godeye.utils.Constants
|
||||
import com.example.godeye.utils.Logger
|
||||
import com.example.godeye.utils.getCameraIdForType
|
||||
import com.example.godeye.utils.getAvailableCameraTypes
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
|
||||
/**
|
||||
* Менеджер для управления камерами устройства
|
||||
*/
|
||||
class CameraManager(private val context: Context) {
|
||||
|
||||
private val cameraManager = context.getSystemService(Context.CAMERA_SERVICE) as android.hardware.camera2.CameraManager
|
||||
private var currentCameraId: String? = null
|
||||
private var captureSession: CameraCaptureSession? = null
|
||||
private var cameraDevice: CameraDevice? = null
|
||||
private var backgroundThread: HandlerThread? = null
|
||||
private var backgroundHandler: Handler? = null
|
||||
|
||||
private val _isRecording = MutableStateFlow(false)
|
||||
val isRecording: StateFlow<Boolean> = _isRecording.asStateFlow()
|
||||
|
||||
private val _currentCameraType = MutableStateFlow<String?>(null)
|
||||
val currentCameraType: StateFlow<String?> = _currentCameraType.asStateFlow()
|
||||
|
||||
private val _error = MutableStateFlow<AppError?>(null)
|
||||
val error: StateFlow<AppError?> = _error.asStateFlow()
|
||||
|
||||
/**
|
||||
* Инициализация фонового потока для камеры
|
||||
*/
|
||||
private fun startBackgroundThread() {
|
||||
backgroundThread = HandlerThread("CameraBackground").also { it.start() }
|
||||
backgroundHandler = Handler(backgroundThread?.looper!!)
|
||||
}
|
||||
|
||||
/**
|
||||
* Остановка фонового потока
|
||||
*/
|
||||
private fun stopBackgroundThread() {
|
||||
backgroundThread?.quitSafely()
|
||||
try {
|
||||
backgroundThread?.join()
|
||||
backgroundThread = null
|
||||
backgroundHandler = null
|
||||
} catch (e: InterruptedException) {
|
||||
Logger.e("Error stopping background thread", e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить список доступных типов камер
|
||||
*/
|
||||
fun getAvailableCameraTypes(): List<String> {
|
||||
return cameraManager.getAvailableCameraTypes()
|
||||
}
|
||||
|
||||
/**
|
||||
* Открыть камеру указанного типа
|
||||
*/
|
||||
@SuppressLint("MissingPermission")
|
||||
fun openCamera(cameraType: String, surface: Surface, onSuccess: () -> Unit = {}, onError: (AppError) -> Unit = {}) {
|
||||
try {
|
||||
val cameraId = cameraManager.getCameraIdForType(cameraType)
|
||||
if (cameraId == null) {
|
||||
val error = AppError.CameraError("Camera type $cameraType not available")
|
||||
_error.value = error
|
||||
onError(error)
|
||||
return
|
||||
}
|
||||
|
||||
startBackgroundThread()
|
||||
|
||||
cameraManager.openCamera(cameraId, object : CameraDevice.StateCallback() {
|
||||
override fun onOpened(camera: CameraDevice) {
|
||||
Logger.d("Camera opened: $cameraId")
|
||||
cameraDevice = camera
|
||||
currentCameraId = cameraId
|
||||
_currentCameraType.value = cameraType
|
||||
createCameraPreviewSession(surface, onSuccess, onError)
|
||||
}
|
||||
|
||||
override fun onDisconnected(camera: CameraDevice) {
|
||||
Logger.d("Camera disconnected: $cameraId")
|
||||
camera.close()
|
||||
cameraDevice = null
|
||||
currentCameraId = null
|
||||
_currentCameraType.value = null
|
||||
}
|
||||
|
||||
override fun onError(camera: CameraDevice, error: Int) {
|
||||
Logger.e("Camera error: $error")
|
||||
camera.close()
|
||||
cameraDevice = null
|
||||
currentCameraId = null
|
||||
_currentCameraType.value = null
|
||||
val appError = AppError.CameraError("Camera error: $error")
|
||||
_error.value = appError
|
||||
onError(appError)
|
||||
}
|
||||
}, backgroundHandler)
|
||||
|
||||
} catch (e: Exception) {
|
||||
Logger.e("Error opening camera", e)
|
||||
val error = AppError.CameraError("Failed to open camera: ${e.message}")
|
||||
_error.value = error
|
||||
onError(error)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Создать сессию предварительного просмотра камеры
|
||||
*/
|
||||
private fun createCameraPreviewSession(surface: Surface, onSuccess: () -> Unit, onError: (AppError) -> Unit) {
|
||||
try {
|
||||
val cameraDevice = this.cameraDevice ?: run {
|
||||
val error = AppError.CameraError("Camera device is null")
|
||||
_error.value = error
|
||||
onError(error)
|
||||
return
|
||||
}
|
||||
|
||||
val captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW)
|
||||
captureRequestBuilder.addTarget(surface)
|
||||
|
||||
// Используем совместимый подход для всех версий Android
|
||||
@Suppress("DEPRECATION")
|
||||
cameraDevice.createCaptureSession(
|
||||
listOf(surface),
|
||||
object : CameraCaptureSession.StateCallback() {
|
||||
override fun onConfigured(session: CameraCaptureSession) {
|
||||
captureSession = session
|
||||
try {
|
||||
captureRequestBuilder.set(
|
||||
CaptureRequest.CONTROL_AF_MODE,
|
||||
CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE
|
||||
)
|
||||
|
||||
val captureRequest = captureRequestBuilder.build()
|
||||
session.setRepeatingRequest(captureRequest, null, backgroundHandler)
|
||||
_isRecording.value = true
|
||||
Logger.d("Camera preview session created successfully")
|
||||
onSuccess()
|
||||
} catch (e: Exception) {
|
||||
Logger.e("Error starting camera preview", e)
|
||||
val error = AppError.CameraError("Failed to start preview: ${e.message}")
|
||||
_error.value = error
|
||||
onError(error)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onConfigureFailed(session: CameraCaptureSession) {
|
||||
Logger.e("Camera capture session configuration failed")
|
||||
val error = AppError.CameraError("Failed to configure capture session")
|
||||
_error.value = error
|
||||
onError(error)
|
||||
}
|
||||
},
|
||||
backgroundHandler
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
Logger.e("Error creating camera preview session", e)
|
||||
val error = AppError.CameraError("Failed to create preview session: ${e.message}")
|
||||
_error.value = error
|
||||
onError(error)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Переключить на другой тип камеры
|
||||
*/
|
||||
fun switchCamera(newCameraType: String, surface: Surface, onSuccess: () -> Unit = {}, onError: (AppError) -> Unit = {}) {
|
||||
Logger.d("Switching camera from ${_currentCameraType.value} to $newCameraType")
|
||||
closeCamera()
|
||||
openCamera(newCameraType, surface, onSuccess, onError)
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить оптимальный размер для предварительного просмотра
|
||||
*/
|
||||
fun getOptimalPreviewSize(cameraType: String): Size? {
|
||||
return try {
|
||||
val cameraId = cameraManager.getCameraIdForType(cameraType) ?: return null
|
||||
val characteristics = cameraManager.getCameraCharacteristics(cameraId)
|
||||
val map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)
|
||||
val outputSizes = map?.getOutputSizes(SurfaceTexture::class.java)
|
||||
|
||||
// Выбираем размер близкий к 1080p, но не превышающий его
|
||||
outputSizes?.find { it.width <= 1920 && it.height <= 1080 }
|
||||
?: outputSizes?.minByOrNull { it.width * it.height }
|
||||
} catch (e: Exception) {
|
||||
Logger.e("Error getting optimal preview size", e)
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Закрыть текущую камеру
|
||||
*/
|
||||
fun closeCamera() {
|
||||
try {
|
||||
captureSession?.close()
|
||||
captureSession = null
|
||||
|
||||
cameraDevice?.close()
|
||||
cameraDevice = null
|
||||
|
||||
currentCameraId = null
|
||||
_currentCameraType.value = null
|
||||
_isRecording.value = false
|
||||
|
||||
stopBackgroundThread()
|
||||
Logger.d("Camera closed successfully")
|
||||
} catch (e: Exception) {
|
||||
Logger.e("Error closing camera", e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверить, открыта ли камера
|
||||
*/
|
||||
fun isCameraOpen(): Boolean {
|
||||
return cameraDevice != null
|
||||
}
|
||||
|
||||
/**
|
||||
* Очистить ошибку
|
||||
*/
|
||||
fun clearError() {
|
||||
_error.value = null
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
package com.example.godeye.managers
|
||||
|
||||
import android.Manifest
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageManager
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.example.godeye.utils.Logger
|
||||
|
||||
/**
|
||||
* Менеджер для управления разрешениями приложения
|
||||
*/
|
||||
class PermissionManager(private val context: Context) {
|
||||
|
||||
companion object {
|
||||
val REQUIRED_PERMISSIONS = arrayOf(
|
||||
Manifest.permission.CAMERA,
|
||||
Manifest.permission.RECORD_AUDIO,
|
||||
Manifest.permission.INTERNET,
|
||||
Manifest.permission.ACCESS_NETWORK_STATE,
|
||||
Manifest.permission.WAKE_LOCK,
|
||||
Manifest.permission.FOREGROUND_SERVICE,
|
||||
Manifest.permission.POST_NOTIFICATIONS
|
||||
)
|
||||
|
||||
val CAMERA_PERMISSIONS = arrayOf(
|
||||
Manifest.permission.CAMERA,
|
||||
Manifest.permission.RECORD_AUDIO
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверить, есть ли все необходимые разрешения
|
||||
*/
|
||||
fun hasAllRequiredPermissions(): Boolean {
|
||||
return REQUIRED_PERMISSIONS.all { permission ->
|
||||
ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверить разрешения для камеры
|
||||
*/
|
||||
fun hasCameraPermissions(): Boolean {
|
||||
return CAMERA_PERMISSIONS.all { permission ->
|
||||
ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверить конкретное разрешение
|
||||
*/
|
||||
fun hasPermission(permission: String): Boolean {
|
||||
return ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить список отсутствующих разрешений
|
||||
*/
|
||||
fun getMissingPermissions(): List<String> {
|
||||
return REQUIRED_PERMISSIONS.filter { permission ->
|
||||
ContextCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить список отсутствующих разрешений для камеры
|
||||
*/
|
||||
fun getMissingCameraPermissions(): List<String> {
|
||||
return CAMERA_PERMISSIONS.filter { permission ->
|
||||
ContextCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверить критические разрешения для основной функциональности
|
||||
*/
|
||||
fun hasCriticalPermissions(): Boolean {
|
||||
val criticalPermissions = arrayOf(
|
||||
Manifest.permission.CAMERA,
|
||||
Manifest.permission.RECORD_AUDIO,
|
||||
Manifest.permission.INTERNET
|
||||
)
|
||||
|
||||
return criticalPermissions.all { permission ->
|
||||
ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Логирование состояния разрешений
|
||||
*/
|
||||
fun logPermissionsStatus() {
|
||||
Logger.d("=== Permission Status ===")
|
||||
REQUIRED_PERMISSIONS.forEach { permission ->
|
||||
val granted = hasPermission(permission)
|
||||
Logger.d("$permission: ${if (granted) "GRANTED" else "DENIED"}")
|
||||
}
|
||||
Logger.d("All required permissions: ${hasAllRequiredPermissions()}")
|
||||
Logger.d("Camera permissions: ${hasCameraPermissions()}")
|
||||
Logger.d("Critical permissions: ${hasCriticalPermissions()}")
|
||||
}
|
||||
}
|
||||
152
app/src/main/java/com/example/godeye/managers/SessionManager.kt
Normal file
@@ -0,0 +1,152 @@
|
||||
package com.example.godeye.managers
|
||||
|
||||
import com.example.godeye.models.CameraSession
|
||||
import com.example.godeye.utils.Logger
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
|
||||
/**
|
||||
* Менеджер для управления активными сессиями с операторами
|
||||
*/
|
||||
class SessionManager {
|
||||
|
||||
private val _activeSessions = MutableStateFlow<List<CameraSession>>(emptyList())
|
||||
val activeSessions: StateFlow<List<CameraSession>> = _activeSessions.asStateFlow()
|
||||
|
||||
/**
|
||||
* Добавить новую сессию
|
||||
*/
|
||||
fun addSession(sessionId: String, operatorId: String, cameraType: String) {
|
||||
val newSession = CameraSession(
|
||||
sessionId = sessionId,
|
||||
operatorId = operatorId,
|
||||
cameraType = cameraType,
|
||||
startTime = System.currentTimeMillis(),
|
||||
isActive = true,
|
||||
webRTCConnected = false
|
||||
)
|
||||
|
||||
val currentSessions = _activeSessions.value.toMutableList()
|
||||
// Удаляем существующую сессию с тем же ID, если есть
|
||||
currentSessions.removeAll { it.sessionId == sessionId }
|
||||
currentSessions.add(newSession)
|
||||
_activeSessions.value = currentSessions
|
||||
|
||||
Logger.d("Session added: $sessionId, operator: $operatorId, camera: $cameraType")
|
||||
}
|
||||
|
||||
/**
|
||||
* Обновить статус WebRTC соединения для сессии
|
||||
*/
|
||||
fun updateWebRTCStatus(sessionId: String, connected: Boolean) {
|
||||
val currentSessions = _activeSessions.value.toMutableList()
|
||||
val sessionIndex = currentSessions.indexOfFirst { it.sessionId == sessionId }
|
||||
|
||||
if (sessionIndex != -1) {
|
||||
currentSessions[sessionIndex] = currentSessions[sessionIndex].copy(
|
||||
webRTCConnected = connected
|
||||
)
|
||||
_activeSessions.value = currentSessions
|
||||
Logger.d("WebRTC status updated for session $sessionId: $connected")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Переключить камеру для сессии
|
||||
*/
|
||||
fun switchCameraForSession(sessionId: String, newCameraType: String) {
|
||||
val currentSessions = _activeSessions.value.toMutableList()
|
||||
val sessionIndex = currentSessions.indexOfFirst { it.sessionId == sessionId }
|
||||
|
||||
if (sessionIndex != -1) {
|
||||
currentSessions[sessionIndex] = currentSessions[sessionIndex].copy(
|
||||
cameraType = newCameraType
|
||||
)
|
||||
_activeSessions.value = currentSessions
|
||||
Logger.d("Camera switched for session $sessionId to $newCameraType")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Завершить сессию
|
||||
*/
|
||||
fun endSession(sessionId: String) {
|
||||
val currentSessions = _activeSessions.value.toMutableList()
|
||||
val removed = currentSessions.removeAll { it.sessionId == sessionId }
|
||||
|
||||
if (removed) {
|
||||
_activeSessions.value = currentSessions
|
||||
Logger.d("Session ended: $sessionId")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить сессию по ID
|
||||
*/
|
||||
fun getSession(sessionId: String): CameraSession? {
|
||||
return _activeSessions.value.find { it.sessionId == sessionId }
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверить, есть ли активные сессии
|
||||
*/
|
||||
fun hasActiveSessions(): Boolean {
|
||||
return _activeSessions.value.isNotEmpty()
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить количество активных сессий
|
||||
*/
|
||||
fun getActiveSessionCount(): Int {
|
||||
return _activeSessions.value.size
|
||||
}
|
||||
|
||||
/**
|
||||
* Завершить все сессии
|
||||
*/
|
||||
fun endAllSessions() {
|
||||
val sessionIds = _activeSessions.value.map { it.sessionId }
|
||||
_activeSessions.value = emptyList()
|
||||
Logger.d("All sessions ended: ${sessionIds.joinToString(", ")}")
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить текущий тип камеры для активной сессии
|
||||
*/
|
||||
fun getCurrentCameraType(): String? {
|
||||
return _activeSessions.value.firstOrNull()?.cameraType
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверить, подключен ли WebRTC для сессии
|
||||
*/
|
||||
fun isWebRTCConnected(sessionId: String): Boolean {
|
||||
return getSession(sessionId)?.webRTCConnected ?: false
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить статистику сессий
|
||||
*/
|
||||
fun getSessionStats(): SessionStats {
|
||||
val sessions = _activeSessions.value
|
||||
return SessionStats(
|
||||
totalSessions = sessions.size,
|
||||
connectedSessions = sessions.count { it.webRTCConnected },
|
||||
activeSessions = sessions.count { it.isActive },
|
||||
oldestSessionTime = sessions.minOfOrNull { it.startTime },
|
||||
newestSessionTime = sessions.maxOfOrNull { it.startTime }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Статистика сессий
|
||||
*/
|
||||
data class SessionStats(
|
||||
val totalSessions: Int,
|
||||
val connectedSessions: Int,
|
||||
val activeSessions: Int,
|
||||
val oldestSessionTime: Long?,
|
||||
val newestSessionTime: Long?
|
||||
)
|
||||
145
app/src/main/java/com/example/godeye/managers/WebRTCManager.kt
Normal file
@@ -0,0 +1,145 @@
|
||||
package com.example.godeye.managers
|
||||
|
||||
import android.content.Context
|
||||
import com.example.godeye.models.AppError
|
||||
import com.example.godeye.models.WebRTCConnectionState
|
||||
import com.example.godeye.utils.Constants
|
||||
import com.example.godeye.utils.Logger
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
|
||||
/**
|
||||
* Менеджер для управления WebRTC соединениями (заглушка)
|
||||
* В реальном проекте здесь будет полная реализация с WebRTC библиотекой
|
||||
*/
|
||||
class WebRTCManager(private val context: Context) {
|
||||
|
||||
private val _connectionState = MutableStateFlow(WebRTCConnectionState.NEW)
|
||||
val connectionState: StateFlow<WebRTCConnectionState> = _connectionState.asStateFlow()
|
||||
|
||||
private val _error = MutableStateFlow<AppError?>(null)
|
||||
val error: StateFlow<AppError?> = _error.asStateFlow()
|
||||
|
||||
// Callback для передачи событий WebRTC
|
||||
private var onOfferCreated: ((String) -> Unit)? = null
|
||||
private var onAnswerCreated: ((String) -> Unit)? = null
|
||||
private var onIceCandidateCreated: ((String, String, Int) -> Unit)? = null
|
||||
|
||||
/**
|
||||
* Инициализация WebRTC (заглушка)
|
||||
*/
|
||||
fun initialize() {
|
||||
try {
|
||||
Logger.d("WebRTC initialized (stub implementation)")
|
||||
} catch (e: Exception) {
|
||||
Logger.e("Error initializing WebRTC", e)
|
||||
_error.value = AppError.WebRTCConnectionFailed
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Создать PeerConnection (заглушка)
|
||||
*/
|
||||
fun createPeerConnection(
|
||||
onOfferCreated: (String) -> Unit,
|
||||
onAnswerCreated: (String) -> Unit,
|
||||
onIceCandidateCreated: (String, String, Int) -> Unit
|
||||
) {
|
||||
try {
|
||||
this.onOfferCreated = onOfferCreated
|
||||
this.onAnswerCreated = onAnswerCreated
|
||||
this.onIceCandidateCreated = onIceCandidateCreated
|
||||
|
||||
Logger.d("PeerConnection created (stub implementation)")
|
||||
} catch (e: Exception) {
|
||||
Logger.e("Error creating PeerConnection", e)
|
||||
_error.value = AppError.WebRTCConnectionFailed
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Создать локальные медиа треки (заглушка)
|
||||
*/
|
||||
fun createLocalMediaTracks(cameraType: String) {
|
||||
try {
|
||||
Logger.d("Local media tracks created for $cameraType (stub implementation)")
|
||||
} catch (e: Exception) {
|
||||
Logger.e("Error creating local media tracks", e)
|
||||
_error.value = AppError.WebRTCConnectionFailed
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Создать Offer (заглушка)
|
||||
*/
|
||||
fun createOffer() {
|
||||
try {
|
||||
// Симулируем создание offer
|
||||
val mockOffer = "v=0\r\no=- 123456 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\nm=video 9 UDP/TLS/RTP/SAVPF 96\r\nc=IN IP4 127.0.0.1\r\na=rtcp:9 IN IP4 127.0.0.1"
|
||||
onOfferCreated?.invoke(mockOffer)
|
||||
Logger.d("Offer created (stub implementation)")
|
||||
|
||||
// Симулируем успешное соединение через некоторое время
|
||||
_connectionState.value = WebRTCConnectionState.CONNECTED
|
||||
} catch (e: Exception) {
|
||||
Logger.e("Error creating offer", e)
|
||||
_error.value = AppError.WebRTCConnectionFailed
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Обработать Answer (заглушка)
|
||||
*/
|
||||
fun handleAnswer(answerSdp: String) {
|
||||
try {
|
||||
Logger.d("Answer processed (stub implementation): ${answerSdp.take(50)}...")
|
||||
_connectionState.value = WebRTCConnectionState.CONNECTED
|
||||
} catch (e: Exception) {
|
||||
Logger.e("Error handling answer", e)
|
||||
_error.value = AppError.WebRTCConnectionFailed
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Добавить ICE candidate (заглушка)
|
||||
*/
|
||||
fun addIceCandidate(candidateSdp: String, sdpMid: String, sdpMLineIndex: Int) {
|
||||
try {
|
||||
Logger.d("ICE candidate added (stub implementation): $candidateSdp")
|
||||
} catch (e: Exception) {
|
||||
Logger.e("Error adding ICE candidate", e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Переключить камеру (заглушка)
|
||||
*/
|
||||
fun switchCamera(newCameraType: String) {
|
||||
try {
|
||||
Logger.d("Camera switched to: $newCameraType (stub implementation)")
|
||||
} catch (e: Exception) {
|
||||
Logger.e("Error switching camera", e)
|
||||
_error.value = AppError.CameraError("Failed to switch camera: ${e.message}")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Закрыть WebRTC соединение (заглушка)
|
||||
*/
|
||||
fun close() {
|
||||
try {
|
||||
_connectionState.value = WebRTCConnectionState.CLOSED
|
||||
Logger.d("WebRTC connection closed (stub implementation)")
|
||||
} catch (e: Exception) {
|
||||
Logger.e("Error closing WebRTC connection", e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Очистить ошибку
|
||||
*/
|
||||
fun clearError() {
|
||||
_error.value = null
|
||||
}
|
||||
}
|
||||
154
app/src/main/java/com/example/godeye/models/Models.kt
Normal file
@@ -0,0 +1,154 @@
|
||||
package com.example.godeye.models
|
||||
|
||||
import android.os.Build
|
||||
|
||||
/**
|
||||
* Информация об устройстве для регистрации на сервере
|
||||
*/
|
||||
data class DeviceInfo(
|
||||
val model: String = Build.MODEL,
|
||||
val androidVersion: String = Build.VERSION.RELEASE,
|
||||
val appVersion: String = "1.0.0", // Заменяем BuildConfig на хардкод для упрощения
|
||||
val availableCameras: List<String>
|
||||
)
|
||||
|
||||
/**
|
||||
* Активная сессия с оператором
|
||||
*/
|
||||
data class CameraSession(
|
||||
val sessionId: String,
|
||||
val operatorId: String,
|
||||
val cameraType: String,
|
||||
val startTime: Long,
|
||||
var isActive: Boolean = true,
|
||||
var webRTCConnected: Boolean = false
|
||||
)
|
||||
|
||||
/**
|
||||
* Запрос доступа к камере от оператора
|
||||
*/
|
||||
data class CameraRequest(
|
||||
val sessionId: String,
|
||||
val operatorId: String,
|
||||
val cameraType: String,
|
||||
val timestamp: Long = System.currentTimeMillis()
|
||||
)
|
||||
|
||||
/**
|
||||
* Ответ на запрос доступа к камере
|
||||
*/
|
||||
data class CameraResponse(
|
||||
val sessionId: String,
|
||||
val accepted: Boolean,
|
||||
val reason: String? = null
|
||||
)
|
||||
|
||||
/**
|
||||
* WebRTC Offer/Answer данные
|
||||
*/
|
||||
data class WebRTCMessage(
|
||||
val sessionId: String,
|
||||
val type: String, // "offer", "answer", "ice-candidate"
|
||||
val sdp: String? = null,
|
||||
val candidate: String? = null,
|
||||
val sdpMid: String? = null,
|
||||
val sdpMLineIndex: Int? = null
|
||||
)
|
||||
|
||||
/**
|
||||
* События Socket.IO
|
||||
*/
|
||||
sealed class SocketEvent {
|
||||
data class RegisterAndroid(
|
||||
val deviceId: String,
|
||||
val deviceInfo: DeviceInfo
|
||||
) : SocketEvent()
|
||||
|
||||
data class CameraRequest(
|
||||
val sessionId: String,
|
||||
val operatorId: String,
|
||||
val cameraType: String
|
||||
) : SocketEvent()
|
||||
|
||||
data class CameraResponse(
|
||||
val sessionId: String,
|
||||
val accepted: Boolean,
|
||||
val reason: String? = null
|
||||
) : SocketEvent()
|
||||
|
||||
data class CameraDisconnect(
|
||||
val sessionId: String
|
||||
) : SocketEvent()
|
||||
|
||||
data class CameraSwitch(
|
||||
val sessionId: String,
|
||||
val newCameraType: String
|
||||
) : SocketEvent()
|
||||
|
||||
data class WebRTCOffer(
|
||||
val sessionId: String,
|
||||
val offer: String
|
||||
) : SocketEvent()
|
||||
|
||||
data class WebRTCAnswer(
|
||||
val sessionId: String,
|
||||
val answer: String
|
||||
) : SocketEvent()
|
||||
|
||||
data class WebRTCIceCandidate(
|
||||
val sessionId: String,
|
||||
val candidate: String,
|
||||
val sdpMid: String,
|
||||
val sdpMLineIndex: Int
|
||||
) : SocketEvent()
|
||||
}
|
||||
|
||||
/**
|
||||
* Состояния подключения
|
||||
*/
|
||||
enum class ConnectionState {
|
||||
DISCONNECTED,
|
||||
CONNECTING,
|
||||
CONNECTED,
|
||||
ERROR,
|
||||
RECONNECTING
|
||||
}
|
||||
|
||||
/**
|
||||
* Состояния WebRTC соединения
|
||||
*/
|
||||
enum class WebRTCConnectionState {
|
||||
NEW,
|
||||
CONNECTING,
|
||||
CONNECTED,
|
||||
DISCONNECTED,
|
||||
FAILED,
|
||||
CLOSED
|
||||
}
|
||||
|
||||
/**
|
||||
* Типы ошибок приложения
|
||||
*/
|
||||
sealed class AppError {
|
||||
object NetworkError : AppError()
|
||||
object CameraPermissionDenied : AppError()
|
||||
object AudioPermissionDenied : AppError()
|
||||
object CameraNotAvailable : AppError()
|
||||
object WebRTCConnectionFailed : AppError()
|
||||
data class SocketError(val message: String) : AppError()
|
||||
data class CameraError(val message: String) : AppError()
|
||||
data class UnknownError(val throwable: Throwable) : AppError()
|
||||
}
|
||||
|
||||
/**
|
||||
* UI состояние главного экрана
|
||||
*/
|
||||
data class MainScreenState(
|
||||
val deviceId: String = "",
|
||||
val serverUrl: String = "",
|
||||
val connectionState: ConnectionState = ConnectionState.DISCONNECTED,
|
||||
val activeSessions: List<CameraSession> = emptyList(),
|
||||
val isLoading: Boolean = false,
|
||||
val error: AppError? = null,
|
||||
val showCameraRequest: CameraRequest? = null
|
||||
)
|
||||
425
app/src/main/java/com/example/godeye/services/CameraService.kt
Normal file
@@ -0,0 +1,425 @@
|
||||
package com.example.godeye.services
|
||||
|
||||
import android.app.*
|
||||
import android.content.Intent
|
||||
import android.graphics.SurfaceTexture
|
||||
import android.os.Binder
|
||||
import android.os.IBinder
|
||||
import android.view.Surface
|
||||
import androidx.core.app.NotificationCompat
|
||||
import com.example.godeye.MainActivity
|
||||
import com.example.godeye.R
|
||||
import com.example.godeye.managers.CameraManager
|
||||
import com.example.godeye.managers.SessionManager
|
||||
import com.example.godeye.managers.WebRTCManager
|
||||
import com.example.godeye.models.AppError
|
||||
import com.example.godeye.models.WebRTCConnectionState
|
||||
import com.example.godeye.utils.Constants
|
||||
import com.example.godeye.utils.Logger
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.*
|
||||
|
||||
/**
|
||||
* Сервис для управления камерой и WebRTC соединениями
|
||||
*/
|
||||
class CameraService : Service() {
|
||||
|
||||
private val binder = LocalBinder()
|
||||
private val serviceScope = CoroutineScope(SupervisorJob() + Dispatchers.Main)
|
||||
|
||||
private lateinit var cameraManager: CameraManager
|
||||
private lateinit var webRTCManager: WebRTCManager
|
||||
private lateinit var sessionManager: SessionManager
|
||||
|
||||
// Surface для WebRTC видео
|
||||
private var webRTCSurface: Surface? = null
|
||||
private var surfaceTexture: SurfaceTexture? = null
|
||||
|
||||
// StateFlows для отслеживания состояния
|
||||
private val _isActive = MutableStateFlow(false)
|
||||
val isActive: StateFlow<Boolean> = _isActive.asStateFlow()
|
||||
|
||||
private val _error = MutableStateFlow<AppError?>(null)
|
||||
val error: StateFlow<AppError?> = _error.asStateFlow()
|
||||
|
||||
// Callbacks для передачи WebRTC событий
|
||||
private var onWebRTCOfferCreated: ((String, String) -> Unit)? = null // sessionId, offer
|
||||
private var onWebRTCIceCandidateCreated: ((String, String, String, Int) -> Unit)? = null // sessionId, candidate, sdpMid, sdpMLineIndex
|
||||
|
||||
inner class LocalBinder : Binder() {
|
||||
fun getService(): CameraService = this@CameraService
|
||||
}
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
Logger.d("CameraService created")
|
||||
|
||||
cameraManager = CameraManager(this)
|
||||
webRTCManager = WebRTCManager(this)
|
||||
sessionManager = SessionManager()
|
||||
|
||||
// Инициализация WebRTC
|
||||
webRTCManager.initialize()
|
||||
|
||||
createNotificationChannel()
|
||||
observeManagerStates()
|
||||
}
|
||||
|
||||
override fun onBind(intent: Intent?): IBinder = binder
|
||||
|
||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||
startForeground(Constants.FOREGROUND_SERVICE_ID + 1, createNotification())
|
||||
return START_STICKY
|
||||
}
|
||||
|
||||
/**
|
||||
* Установить callbacks для WebRTC событий
|
||||
*/
|
||||
fun setWebRTCCallbacks(
|
||||
onOfferCreated: (String, String) -> Unit,
|
||||
onIceCandidateCreated: (String, String, String, Int) -> Unit
|
||||
) {
|
||||
this.onWebRTCOfferCreated = onOfferCreated
|
||||
this.onWebRTCIceCandidateCreated = onIceCandidateCreated
|
||||
}
|
||||
|
||||
/**
|
||||
* Начать камера сессию
|
||||
*/
|
||||
fun startCameraSession(sessionId: String, operatorId: String, cameraType: String) {
|
||||
serviceScope.launch {
|
||||
try {
|
||||
Logger.d("Starting camera session: $sessionId, camera: $cameraType")
|
||||
|
||||
// Добавляем сессию в менеджер
|
||||
sessionManager.addSession(sessionId, operatorId, cameraType)
|
||||
|
||||
// Создаем Surface для WebRTC
|
||||
setupWebRTCSurface()
|
||||
|
||||
// Создаем WebRTC соединение
|
||||
webRTCManager.createPeerConnection(
|
||||
onOfferCreated = { offer ->
|
||||
onWebRTCOfferCreated?.invoke(sessionId, offer)
|
||||
},
|
||||
onAnswerCreated = { answer ->
|
||||
// Ответ не используется, так как мы создаем offer
|
||||
},
|
||||
onIceCandidateCreated = { candidate, sdpMid, sdpMLineIndex ->
|
||||
onWebRTCIceCandidateCreated?.invoke(sessionId, candidate, sdpMid, sdpMLineIndex)
|
||||
}
|
||||
)
|
||||
|
||||
// Создаем локальные медиа треки
|
||||
webRTCManager.createLocalMediaTracks(cameraType)
|
||||
|
||||
// Открываем камеру
|
||||
webRTCSurface?.let { surface ->
|
||||
cameraManager.openCamera(
|
||||
cameraType = cameraType,
|
||||
surface = surface,
|
||||
onSuccess = {
|
||||
Logger.d("Camera opened successfully for session: $sessionId")
|
||||
_isActive.value = true
|
||||
|
||||
// Создаем WebRTC offer
|
||||
webRTCManager.createOffer()
|
||||
},
|
||||
onError = { error ->
|
||||
Logger.e("Failed to open camera for session: $sessionId")
|
||||
_error.value = error
|
||||
sessionManager.endSession(sessionId)
|
||||
}
|
||||
)
|
||||
} ?: run {
|
||||
val error = AppError.CameraError("WebRTC surface not available")
|
||||
_error.value = error
|
||||
sessionManager.endSession(sessionId)
|
||||
}
|
||||
|
||||
} catch (e: Exception) {
|
||||
Logger.e("Error starting camera session", e)
|
||||
_error.value = AppError.UnknownError(e)
|
||||
sessionManager.endSession(sessionId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Обработать WebRTC answer
|
||||
*/
|
||||
fun handleWebRTCAnswer(sessionId: String, answer: String) {
|
||||
serviceScope.launch {
|
||||
try {
|
||||
Logger.d("Handling WebRTC answer for session: $sessionId")
|
||||
webRTCManager.handleAnswer(answer)
|
||||
sessionManager.updateWebRTCStatus(sessionId, true)
|
||||
} catch (e: Exception) {
|
||||
Logger.e("Error handling WebRTC answer", e)
|
||||
_error.value = AppError.WebRTCConnectionFailed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Добавить ICE candidate
|
||||
*/
|
||||
fun addIceCandidate(sessionId: String, candidate: String, sdpMid: String, sdpMLineIndex: Int) {
|
||||
serviceScope.launch {
|
||||
try {
|
||||
Logger.d("Adding ICE candidate for session: $sessionId")
|
||||
webRTCManager.addIceCandidate(candidate, sdpMid, sdpMLineIndex)
|
||||
} catch (e: Exception) {
|
||||
Logger.e("Error adding ICE candidate", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Переключить камеру
|
||||
*/
|
||||
fun switchCamera(sessionId: String, newCameraType: String) {
|
||||
serviceScope.launch {
|
||||
try {
|
||||
Logger.d("Switching camera for session $sessionId to $newCameraType")
|
||||
|
||||
// Обновляем тип камеры в сессии
|
||||
sessionManager.switchCameraForSession(sessionId, newCameraType)
|
||||
|
||||
// Переключаем камеру в WebRTC
|
||||
webRTCManager.switchCamera(newCameraType)
|
||||
|
||||
// Переключаем физическую камеру
|
||||
webRTCSurface?.let { surface ->
|
||||
cameraManager.switchCamera(
|
||||
newCameraType = newCameraType,
|
||||
surface = surface,
|
||||
onSuccess = {
|
||||
Logger.d("Camera switched successfully to: $newCameraType")
|
||||
},
|
||||
onError = { error ->
|
||||
Logger.e("Failed to switch camera to: $newCameraType")
|
||||
_error.value = error
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
} catch (e: Exception) {
|
||||
Logger.e("Error switching camera", e)
|
||||
_error.value = AppError.CameraError("Failed to switch camera: ${e.message}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Завершить сессию
|
||||
*/
|
||||
fun endSession(sessionId: String) {
|
||||
serviceScope.launch {
|
||||
try {
|
||||
Logger.d("Ending session: $sessionId")
|
||||
|
||||
// Закрываем камеру
|
||||
cameraManager.closeCamera()
|
||||
|
||||
// Закрываем WebRTC соединение
|
||||
webRTCManager.close()
|
||||
|
||||
// Удаляем сессию
|
||||
sessionManager.endSession(sessionId)
|
||||
|
||||
// Очищаем Surface
|
||||
cleanupWebRTCSurface()
|
||||
|
||||
_isActive.value = false
|
||||
Logger.d("Session ended successfully: $sessionId")
|
||||
|
||||
// Если нет активных сессий, останавливаем сервис
|
||||
if (!sessionManager.hasActiveSessions()) {
|
||||
stopSelf()
|
||||
}
|
||||
|
||||
} catch (e: Exception) {
|
||||
Logger.e("Error ending session", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Завершить все сессии
|
||||
*/
|
||||
fun endAllSessions() {
|
||||
serviceScope.launch {
|
||||
try {
|
||||
Logger.d("Ending all sessions")
|
||||
|
||||
// Закрываем камеру
|
||||
cameraManager.closeCamera()
|
||||
|
||||
// Закрываем WebRTC соединение
|
||||
webRTCManager.close()
|
||||
|
||||
// Удаляем все сессии
|
||||
sessionManager.endAllSessions()
|
||||
|
||||
// Очищаем Surface
|
||||
cleanupWebRTCSurface()
|
||||
|
||||
_isActive.value = false
|
||||
Logger.d("All sessions ended successfully")
|
||||
|
||||
stopSelf()
|
||||
|
||||
} catch (e: Exception) {
|
||||
Logger.e("Error ending all sessions", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Настроить Surface для WebRTC
|
||||
*/
|
||||
private fun setupWebRTCSurface() {
|
||||
try {
|
||||
// Создаем SurfaceTexture для WebRTC
|
||||
surfaceTexture = SurfaceTexture(0).apply {
|
||||
setDefaultBufferSize(1280, 720)
|
||||
}
|
||||
webRTCSurface = Surface(surfaceTexture)
|
||||
Logger.d("WebRTC surface created successfully")
|
||||
} catch (e: Exception) {
|
||||
Logger.e("Error creating WebRTC surface", e)
|
||||
_error.value = AppError.CameraError("Failed to create WebRTC surface: ${e.message}")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Очистить WebRTC Surface
|
||||
*/
|
||||
private fun cleanupWebRTCSurface() {
|
||||
try {
|
||||
webRTCSurface?.release()
|
||||
webRTCSurface = null
|
||||
|
||||
surfaceTexture?.release()
|
||||
surfaceTexture = null
|
||||
|
||||
Logger.d("WebRTC surface cleaned up")
|
||||
} catch (e: Exception) {
|
||||
Logger.e("Error cleaning up WebRTC surface", e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Наблюдать за состояниями менеджеров
|
||||
*/
|
||||
private fun observeManagerStates() {
|
||||
serviceScope.launch {
|
||||
// Наблюдаем за ошибками камеры
|
||||
cameraManager.error.collect { error ->
|
||||
error?.let {
|
||||
_error.value = it
|
||||
Logger.e("Camera manager error: $it")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
serviceScope.launch {
|
||||
// Наблюдаем за ошибками WebRTC
|
||||
webRTCManager.error.collect { error ->
|
||||
error?.let {
|
||||
_error.value = it
|
||||
Logger.e("WebRTC manager error: $it")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
serviceScope.launch {
|
||||
// Наблюдаем за состоянием WebRTC соединения
|
||||
webRTCManager.connectionState.collect { state ->
|
||||
Logger.d("WebRTC connection state: $state")
|
||||
when (state) {
|
||||
WebRTCConnectionState.CONNECTED -> {
|
||||
// Обновляем статус всех активных сессий
|
||||
sessionManager.activeSessions.value.forEach { session ->
|
||||
sessionManager.updateWebRTCStatus(session.sessionId, true)
|
||||
}
|
||||
}
|
||||
WebRTCConnectionState.FAILED,
|
||||
WebRTCConnectionState.DISCONNECTED -> {
|
||||
// Обновляем статус всех активных сессий
|
||||
sessionManager.activeSessions.value.forEach { session ->
|
||||
sessionManager.updateWebRTCStatus(session.sessionId, false)
|
||||
}
|
||||
}
|
||||
else -> { /* Игнорируем другие состояния */ }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить менеджер сессий
|
||||
*/
|
||||
fun getSessionManager(): SessionManager = sessionManager
|
||||
|
||||
/**
|
||||
* Создать канал уведомлений
|
||||
*/
|
||||
private fun createNotificationChannel() {
|
||||
val channel = NotificationChannel(
|
||||
"${Constants.NOTIFICATION_CHANNEL_ID}_camera",
|
||||
"GodEye Camera Service",
|
||||
NotificationManager.IMPORTANCE_LOW
|
||||
).apply {
|
||||
description = "Уведомления о работе камеры GodEye"
|
||||
setShowBadge(false)
|
||||
}
|
||||
|
||||
val notificationManager = getSystemService(NotificationManager::class.java)
|
||||
notificationManager.createNotificationChannel(channel)
|
||||
}
|
||||
|
||||
/**
|
||||
* Создать уведомление для foreground service
|
||||
*/
|
||||
private fun createNotification(): Notification {
|
||||
val intent = Intent(this, MainActivity::class.java)
|
||||
val pendingIntent = PendingIntent.getActivity(
|
||||
this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
|
||||
val activeSessionsCount = sessionManager.getActiveSessionCount()
|
||||
val statusText = if (activeSessionsCount > 0) {
|
||||
"Активных сессий: $activeSessionsCount"
|
||||
} else {
|
||||
"Камера готова к работе"
|
||||
}
|
||||
|
||||
return NotificationCompat.Builder(this, "${Constants.NOTIFICATION_CHANNEL_ID}_camera")
|
||||
.setContentTitle("GodEye Camera")
|
||||
.setContentText(statusText)
|
||||
.setSmallIcon(R.drawable.ic_launcher_foreground)
|
||||
.setContentIntent(pendingIntent)
|
||||
.setOngoing(true)
|
||||
.setForegroundServiceBehavior(NotificationCompat.FOREGROUND_SERVICE_IMMEDIATE)
|
||||
.build()
|
||||
}
|
||||
|
||||
/**
|
||||
* Очистить ошибку
|
||||
*/
|
||||
fun clearError() {
|
||||
_error.value = null
|
||||
cameraManager.clearError()
|
||||
webRTCManager.clearError()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
serviceScope.launch {
|
||||
endAllSessions()
|
||||
}
|
||||
Logger.d("CameraService destroyed")
|
||||
}
|
||||
}
|
||||
430
app/src/main/java/com/example/godeye/services/SocketService.kt
Normal file
@@ -0,0 +1,430 @@
|
||||
package com.example.godeye.services
|
||||
|
||||
import android.app.*
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Binder
|
||||
import android.os.IBinder
|
||||
import androidx.core.app.NotificationCompat
|
||||
import com.example.godeye.MainActivity
|
||||
import com.example.godeye.R
|
||||
import com.example.godeye.managers.PermissionManager
|
||||
import com.example.godeye.models.*
|
||||
import com.example.godeye.utils.Constants
|
||||
import com.example.godeye.utils.Logger
|
||||
import com.example.godeye.utils.generateDeviceId
|
||||
import com.example.godeye.utils.getAvailableCameraTypes
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.JsonObject
|
||||
import io.socket.client.IO
|
||||
import io.socket.client.Socket
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import org.json.JSONObject
|
||||
import java.net.URI
|
||||
|
||||
/**
|
||||
* Сервис для управления WebSocket соединением с backend сервером
|
||||
*/
|
||||
class SocketService : Service() {
|
||||
|
||||
private val binder = LocalBinder()
|
||||
private var socket: Socket? = null
|
||||
private val gson = Gson()
|
||||
private val serviceScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
|
||||
|
||||
private lateinit var permissionManager: PermissionManager
|
||||
|
||||
// StateFlows для отслеживания состояния
|
||||
private val _connectionState = MutableStateFlow(ConnectionState.DISCONNECTED)
|
||||
val connectionState: StateFlow<ConnectionState> = _connectionState.asStateFlow()
|
||||
|
||||
private val _deviceId = MutableStateFlow("")
|
||||
val deviceId: StateFlow<String> = _deviceId.asStateFlow()
|
||||
|
||||
private val _error = MutableStateFlow<AppError?>(null)
|
||||
val error: StateFlow<AppError?> = _error.asStateFlow()
|
||||
|
||||
// События для UI
|
||||
private val _cameraRequest = MutableStateFlow<CameraRequest?>(null)
|
||||
val cameraRequest: StateFlow<CameraRequest?> = _cameraRequest.asStateFlow()
|
||||
|
||||
private val _webrtcOffer = MutableStateFlow<WebRTCMessage?>(null)
|
||||
val webrtcOffer: StateFlow<WebRTCMessage?> = _webrtcOffer.asStateFlow()
|
||||
|
||||
private val _webrtcAnswer = MutableStateFlow<WebRTCMessage?>(null)
|
||||
val webrtcAnswer: StateFlow<WebRTCMessage?> = _webrtcAnswer.asStateFlow()
|
||||
|
||||
private val _webrtcIceCandidate = MutableStateFlow<WebRTCMessage?>(null)
|
||||
val webrtcIceCandidate: StateFlow<WebRTCMessage?> = _webrtcIceCandidate.asStateFlow()
|
||||
|
||||
private val _cameraSwitchRequest = MutableStateFlow<Pair<String, String>?>(null) // sessionId, newCameraType
|
||||
val cameraSwitchRequest: StateFlow<Pair<String, String>?> = _cameraSwitchRequest.asStateFlow()
|
||||
|
||||
private val _sessionDisconnect = MutableStateFlow<String?>(null) // sessionId
|
||||
val sessionDisconnect: StateFlow<String?> = _sessionDisconnect.asStateFlow()
|
||||
|
||||
inner class LocalBinder : Binder() {
|
||||
fun getService(): SocketService = this@SocketService
|
||||
}
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
Logger.d("SocketService created")
|
||||
permissionManager = PermissionManager(this)
|
||||
_deviceId.value = generateDeviceId()
|
||||
createNotificationChannel()
|
||||
}
|
||||
|
||||
override fun onBind(intent: Intent?): IBinder = binder
|
||||
|
||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||
startForeground(Constants.FOREGROUND_SERVICE_ID, createNotification())
|
||||
return START_STICKY
|
||||
}
|
||||
|
||||
/**
|
||||
* Подключиться к серверу
|
||||
*/
|
||||
fun connect(serverUrl: String) {
|
||||
serviceScope.launch {
|
||||
try {
|
||||
_connectionState.value = ConnectionState.CONNECTING
|
||||
Logger.d("Connecting to server: $serverUrl")
|
||||
|
||||
// Дополнительная проверка URL
|
||||
if (serverUrl.isBlank()) {
|
||||
Logger.e("Server URL is empty")
|
||||
_connectionState.value = ConnectionState.ERROR
|
||||
_error.value = AppError.NetworkError
|
||||
return@launch
|
||||
}
|
||||
|
||||
Logger.d("Creating URI from: $serverUrl")
|
||||
val uri = URI.create(serverUrl)
|
||||
Logger.d("URI created successfully: $uri")
|
||||
|
||||
Logger.d("Creating Socket.IO client")
|
||||
val options = IO.Options().apply {
|
||||
timeout = 10000 // Увеличиваем таймаут до 10 секунд
|
||||
reconnection = true
|
||||
reconnectionDelay = 2000 // Увеличиваем задержку между попытками
|
||||
reconnectionAttempts = 3 // Уменьшаем количество попыток
|
||||
forceNew = true // Принудительно создаваем новое соединение
|
||||
}
|
||||
|
||||
socket = IO.socket(uri, options).apply {
|
||||
Logger.d("Socket.IO client created, setting up listeners")
|
||||
setupEventListeners()
|
||||
Logger.d("Listeners set up, initiating connection")
|
||||
connect()
|
||||
Logger.d("Connection initiated")
|
||||
}
|
||||
|
||||
// Добавляем таймаут для проверки подключения
|
||||
launch {
|
||||
kotlinx.coroutines.delay(15000) // Ждем 15 секунд
|
||||
if (_connectionState.value == ConnectionState.CONNECTING) {
|
||||
Logger.w("Connection timeout after 15 seconds")
|
||||
_connectionState.value = ConnectionState.ERROR
|
||||
_error.value = AppError.SocketError("Connection timeout - server may be unreachable")
|
||||
socket?.disconnect()
|
||||
}
|
||||
}
|
||||
|
||||
} catch (e: Exception) {
|
||||
Logger.e("Error connecting to server: ${e.message}", e)
|
||||
_connectionState.value = ConnectionState.ERROR
|
||||
_error.value = AppError.SocketError("Connection failed: ${e.message}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Отключиться от сервера
|
||||
*/
|
||||
fun disconnect() {
|
||||
serviceScope.launch {
|
||||
try {
|
||||
socket?.disconnect()
|
||||
socket?.close()
|
||||
socket = null
|
||||
_connectionState.value = ConnectionState.DISCONNECTED
|
||||
Logger.d("Disconnected from server")
|
||||
} catch (e: Exception) {
|
||||
Logger.e("Error disconnecting from server", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Настроить обработчики событий Socket.IO
|
||||
*/
|
||||
private fun setupEventListeners() {
|
||||
socket?.apply {
|
||||
Logger.d("Setting up Socket.IO event listeners")
|
||||
|
||||
on(Socket.EVENT_CONNECT) {
|
||||
Logger.d("✅ Socket connected successfully")
|
||||
_connectionState.value = ConnectionState.CONNECTED
|
||||
registerDevice()
|
||||
}
|
||||
|
||||
on(Socket.EVENT_DISCONNECT) { args ->
|
||||
val reason = args.firstOrNull()?.toString() ?: "unknown"
|
||||
Logger.d("❌ Socket disconnected: $reason")
|
||||
_connectionState.value = ConnectionState.DISCONNECTED
|
||||
}
|
||||
|
||||
on(Socket.EVENT_CONNECT_ERROR) { args ->
|
||||
val error = args.firstOrNull()?.toString() ?: "Unknown connection error"
|
||||
Logger.e("🔥 Socket connection error: $error")
|
||||
_connectionState.value = ConnectionState.ERROR
|
||||
_error.value = AppError.SocketError(error)
|
||||
}
|
||||
|
||||
on(Constants.SocketEvents.REGISTER_SUCCESS) { args ->
|
||||
Logger.d("Device registered successfully")
|
||||
val data = args.firstOrNull()?.toString()
|
||||
Logger.d("Registration response: $data")
|
||||
}
|
||||
|
||||
on(Constants.SocketEvents.REGISTER_ERROR) { args ->
|
||||
val error = args.firstOrNull()?.toString() ?: "Registration failed"
|
||||
Logger.e("Device registration error: $error")
|
||||
_error.value = AppError.SocketError(error)
|
||||
}
|
||||
|
||||
on(Constants.SocketEvents.CAMERA_REQUEST) { args ->
|
||||
try {
|
||||
val data = JSONObject(args[0].toString())
|
||||
val request = CameraRequest(
|
||||
sessionId = data.getString("sessionId"),
|
||||
operatorId = data.getString("operatorId"),
|
||||
cameraType = data.getString("cameraType")
|
||||
)
|
||||
Logger.d("Camera request received: $request")
|
||||
_cameraRequest.value = request
|
||||
} catch (e: Exception) {
|
||||
Logger.e("Error parsing camera request", e)
|
||||
}
|
||||
}
|
||||
|
||||
on(Constants.SocketEvents.CAMERA_DISCONNECT) { args ->
|
||||
try {
|
||||
val data = JSONObject(args[0].toString())
|
||||
val sessionId = data.getString("sessionId")
|
||||
Logger.d("Camera disconnect received for session: $sessionId")
|
||||
_sessionDisconnect.value = sessionId
|
||||
} catch (e: Exception) {
|
||||
Logger.e("Error parsing camera disconnect", e)
|
||||
}
|
||||
}
|
||||
|
||||
on(Constants.SocketEvents.CAMERA_SWITCH) { args ->
|
||||
try {
|
||||
val data = JSONObject(args[0].toString())
|
||||
val sessionId = data.getString("sessionId")
|
||||
val newCameraType = data.getString("newCameraType")
|
||||
Logger.d("Camera switch request: $sessionId -> $newCameraType")
|
||||
_cameraSwitchRequest.value = Pair(sessionId, newCameraType)
|
||||
} catch (e: Exception) {
|
||||
Logger.e("Error parsing camera switch", e)
|
||||
}
|
||||
}
|
||||
|
||||
on(Constants.SocketEvents.WEBRTC_OFFER) { args ->
|
||||
try {
|
||||
val data = JSONObject(args[0].toString())
|
||||
val message = WebRTCMessage(
|
||||
sessionId = data.getString("sessionId"),
|
||||
type = "offer",
|
||||
sdp = data.getString("offer")
|
||||
)
|
||||
Logger.d("WebRTC offer received for session: ${message.sessionId}")
|
||||
_webrtcOffer.value = message
|
||||
} catch (e: Exception) {
|
||||
Logger.e("Error parsing WebRTC offer", e)
|
||||
}
|
||||
}
|
||||
|
||||
on(Constants.SocketEvents.WEBRTC_ICE_CANDIDATE) { args ->
|
||||
try {
|
||||
val data = JSONObject(args[0].toString())
|
||||
val message = WebRTCMessage(
|
||||
sessionId = data.getString("sessionId"),
|
||||
type = "ice-candidate",
|
||||
candidate = data.getString("candidate"),
|
||||
sdpMid = data.getString("sdpMid"),
|
||||
sdpMLineIndex = data.getInt("sdpMLineIndex")
|
||||
)
|
||||
Logger.d("WebRTC ICE candidate received for session: ${message.sessionId}")
|
||||
_webrtcIceCandidate.value = message
|
||||
} catch (e: Exception) {
|
||||
Logger.e("Error parsing WebRTC ICE candidate", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Зарегистрировать устройство на сервере
|
||||
*/
|
||||
private fun registerDevice() {
|
||||
try {
|
||||
val cameraManager = getSystemService(Context.CAMERA_SERVICE) as android.hardware.camera2.CameraManager
|
||||
val deviceInfo = DeviceInfo(
|
||||
availableCameras = cameraManager.getAvailableCameraTypes()
|
||||
)
|
||||
|
||||
val registrationData = JsonObject().apply {
|
||||
addProperty("deviceId", _deviceId.value)
|
||||
add("deviceInfo", gson.toJsonTree(deviceInfo))
|
||||
}
|
||||
|
||||
socket?.emit(Constants.SocketEvents.REGISTER_ANDROID, registrationData)
|
||||
Logger.d("Device registration sent: $registrationData")
|
||||
|
||||
} catch (e: Exception) {
|
||||
Logger.e("Error registering device", e)
|
||||
_error.value = AppError.SocketError("Failed to register device: ${e.message}")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Отправить ответ на запрос камеры
|
||||
*/
|
||||
fun sendCameraResponse(sessionId: String, accepted: Boolean, reason: String? = null) {
|
||||
try {
|
||||
val response = JsonObject().apply {
|
||||
addProperty("sessionId", sessionId)
|
||||
addProperty("accepted", accepted)
|
||||
reason?.let { addProperty("reason", it) }
|
||||
}
|
||||
|
||||
socket?.emit(Constants.SocketEvents.CAMERA_RESPONSE, response)
|
||||
Logger.d("Camera response sent: $response")
|
||||
|
||||
} catch (e: Exception) {
|
||||
Logger.e("Error sending camera response", e)
|
||||
_error.value = AppError.SocketError("Failed to send camera response: ${e.message}")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Отправить WebRTC answer
|
||||
*/
|
||||
fun sendWebRTCAnswer(sessionId: String, answer: String) {
|
||||
try {
|
||||
val data = JsonObject().apply {
|
||||
addProperty("sessionId", sessionId)
|
||||
addProperty("answer", answer)
|
||||
}
|
||||
|
||||
socket?.emit(Constants.SocketEvents.WEBRTC_ANSWER, data)
|
||||
Logger.d("WebRTC answer sent for session: $sessionId")
|
||||
|
||||
} catch (e: Exception) {
|
||||
Logger.e("Error sending WebRTC answer", e)
|
||||
_error.value = AppError.SocketError("Failed to send WebRTC answer: ${e.message}")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Отправить ICE candidate
|
||||
*/
|
||||
fun sendIceCandidate(sessionId: String, candidate: String, sdpMid: String, sdpMLineIndex: Int) {
|
||||
try {
|
||||
val data = JsonObject().apply {
|
||||
addProperty("sessionId", sessionId)
|
||||
addProperty("candidate", candidate)
|
||||
addProperty("sdpMid", sdpMid)
|
||||
addProperty("sdpMLineIndex", sdpMLineIndex)
|
||||
}
|
||||
|
||||
socket?.emit(Constants.SocketEvents.WEBRTC_ICE_CANDIDATE, data)
|
||||
Logger.d("ICE candidate sent for session: $sessionId")
|
||||
|
||||
} catch (e: Exception) {
|
||||
Logger.e("Error sending ICE candidate", e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Создать канал уведомлений
|
||||
*/
|
||||
private fun createNotificationChannel() {
|
||||
val channel = NotificationChannel(
|
||||
Constants.NOTIFICATION_CHANNEL_ID,
|
||||
"GodEye Service",
|
||||
NotificationManager.IMPORTANCE_LOW
|
||||
).apply {
|
||||
description = "Уведомления о состоянии подключения GodEye"
|
||||
setShowBadge(false)
|
||||
}
|
||||
|
||||
val notificationManager = getSystemService(NotificationManager::class.java)
|
||||
notificationManager.createNotificationChannel(channel)
|
||||
}
|
||||
|
||||
/**
|
||||
* Создать уведомление для foreground service
|
||||
*/
|
||||
private fun createNotification(): Notification {
|
||||
val intent = Intent(this, MainActivity::class.java)
|
||||
val pendingIntent = PendingIntent.getActivity(
|
||||
this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
|
||||
val statusText = when (_connectionState.value) {
|
||||
ConnectionState.CONNECTED -> "Подключено"
|
||||
ConnectionState.CONNECTING -> "Подключение..."
|
||||
ConnectionState.RECONNECTING -> "Переподключение..."
|
||||
ConnectionState.DISCONNECTED -> "Отключено"
|
||||
ConnectionState.ERROR -> "Ошибка подключения"
|
||||
}
|
||||
|
||||
return NotificationCompat.Builder(this, Constants.NOTIFICATION_CHANNEL_ID)
|
||||
.setContentTitle("GodEye Signal Center")
|
||||
.setContentText("Статус: $statusText")
|
||||
.setSmallIcon(R.drawable.ic_launcher_foreground)
|
||||
.setContentIntent(pendingIntent)
|
||||
.setOngoing(true)
|
||||
.setForegroundServiceBehavior(NotificationCompat.FOREGROUND_SERVICE_IMMEDIATE)
|
||||
.build()
|
||||
}
|
||||
|
||||
/**
|
||||
* Обновить уведомление
|
||||
*/
|
||||
private fun updateNotification() {
|
||||
val notificationManager = getSystemService(NotificationManager::class.java)
|
||||
notificationManager.notify(Constants.FOREGROUND_SERVICE_ID, createNotification())
|
||||
}
|
||||
|
||||
/**
|
||||
* Очистить события
|
||||
*/
|
||||
fun clearCameraRequest() {
|
||||
_cameraRequest.value = null
|
||||
}
|
||||
|
||||
fun clearWebRTCOffer() {
|
||||
_webrtcOffer.value = null
|
||||
}
|
||||
|
||||
fun clearError() {
|
||||
_error.value = null
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
disconnect()
|
||||
Logger.d("SocketService destroyed")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
package com.example.godeye.ui.components
|
||||
|
||||
import android.util.Log
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Person
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import com.example.godeye.R
|
||||
import com.example.godeye.models.CameraRequest
|
||||
import com.example.godeye.utils.Constants
|
||||
|
||||
/**
|
||||
* Диалог запроса доступа к камере от оператора
|
||||
*/
|
||||
@Composable
|
||||
fun CameraRequestDialog(
|
||||
request: CameraRequest,
|
||||
onAccept: () -> Unit,
|
||||
onDeny: () -> Unit,
|
||||
onDismiss: () -> Unit
|
||||
) {
|
||||
var rememberChoice by remember { mutableStateOf(false) }
|
||||
|
||||
// Лог открытия диалога
|
||||
LaunchedEffect(Unit) {
|
||||
Log.d("GodEye", "CameraRequestDialog открыт: sessionId=${request.sessionId}, operatorId=${request.operatorId}, cameraType=${request.cameraType}")
|
||||
}
|
||||
|
||||
Dialog(onDismissRequest = {
|
||||
Log.d("GodEye", "Диалог закрыт пользователем")
|
||||
onDismiss()
|
||||
}) {
|
||||
Card(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(16.dp),
|
||||
shape = RoundedCornerShape(16.dp),
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = 8.dp)
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(24.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
// Иконка камеры
|
||||
Icon(
|
||||
imageVector = Icons.Default.Person, // Заменено с PhotoCamera на Person
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(48.dp),
|
||||
tint = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
// Заголовок
|
||||
Text(
|
||||
text = stringResource(R.string.camera_request_title),
|
||||
style = MaterialTheme.typography.headlineSmall,
|
||||
fontWeight = FontWeight.Bold,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
// Основное сообщение
|
||||
Text(
|
||||
text = stringResource(
|
||||
R.string.camera_request_message,
|
||||
request.operatorId,
|
||||
getCameraTypeName(request.cameraType)
|
||||
),
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
|
||||
// ID сессии
|
||||
Text(
|
||||
text = stringResource(R.string.session_id_label, request.sessionId),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
|
||||
// Чекбокс "Запомнить выбор"
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Checkbox(
|
||||
checked = rememberChoice,
|
||||
onCheckedChange = { rememberChoice = it }
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
Text(
|
||||
text = stringResource(R.string.remember_choice),
|
||||
style = MaterialTheme.typography.bodyMedium
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
|
||||
// Кнопки
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp)
|
||||
) {
|
||||
// Кнопка "Отклонить"
|
||||
OutlinedButton(
|
||||
onClick = {
|
||||
Log.d("GodEye", "Пользователь отклонил запрос камеры")
|
||||
onDeny()
|
||||
},
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.height(48.dp)
|
||||
) {
|
||||
Text(stringResource(R.string.deny_button))
|
||||
}
|
||||
|
||||
// Кнопка "Разрешить"
|
||||
Button(
|
||||
onClick = {
|
||||
Log.d("GodEye", "Пользователь разрешил доступ к камере")
|
||||
onAccept()
|
||||
},
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.height(48.dp)
|
||||
) {
|
||||
Text(stringResource(R.string.allow_button))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить локализованное название типа камеры
|
||||
*/
|
||||
@Composable
|
||||
private fun getCameraTypeName(cameraType: String): String {
|
||||
return when (cameraType) {
|
||||
Constants.CameraTypes.BACK -> stringResource(R.string.camera_type_back)
|
||||
Constants.CameraTypes.FRONT -> stringResource(R.string.camera_type_front)
|
||||
Constants.CameraTypes.WIDE -> stringResource(R.string.camera_type_wide)
|
||||
Constants.CameraTypes.TELEPHOTO -> stringResource(R.string.camera_type_telephoto)
|
||||
else -> cameraType
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
package com.example.godeye.ui.components
|
||||
|
||||
import androidx.compose.animation.core.*
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.*
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.rotate
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.example.godeye.R
|
||||
import com.example.godeye.models.ConnectionState
|
||||
|
||||
/**
|
||||
* Компонент для отображения статуса подключения к серверу
|
||||
*/
|
||||
@Composable
|
||||
fun ConnectionStatusCard(
|
||||
connectionState: ConnectionState,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
val (icon, color, statusText) = getConnectionStateInfo(connectionState)
|
||||
|
||||
Card(
|
||||
modifier = modifier.fillMaxWidth(),
|
||||
shape = RoundedCornerShape(12.dp),
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = 4.dp),
|
||||
colors = CardDefaults.cardColors(
|
||||
containerColor = color.copy(alpha = 0.1f)
|
||||
)
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(16.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
// Иконка с анимацией для состояний загрузки
|
||||
ConnectionIcon(
|
||||
icon = icon,
|
||||
color = color,
|
||||
isAnimated = connectionState == ConnectionState.CONNECTING ||
|
||||
connectionState == ConnectionState.RECONNECTING
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.width(12.dp))
|
||||
|
||||
// Текст статуса
|
||||
Column {
|
||||
Text(
|
||||
text = stringResource(R.string.connection_status_label),
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Text(
|
||||
text = statusText,
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = color
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Анимированная иконка подключения
|
||||
*/
|
||||
@Composable
|
||||
private fun ConnectionIcon(
|
||||
icon: ImageVector,
|
||||
color: androidx.compose.ui.graphics.Color,
|
||||
isAnimated: Boolean,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
if (isAnimated) {
|
||||
val infiniteTransition = rememberInfiniteTransition(label = "connection_animation")
|
||||
val rotation by infiniteTransition.animateFloat(
|
||||
initialValue = 0f,
|
||||
targetValue = 360f,
|
||||
animationSpec = infiniteRepeatable(
|
||||
animation = tween(1000, easing = LinearEasing),
|
||||
repeatMode = RepeatMode.Restart
|
||||
),
|
||||
label = "rotation"
|
||||
)
|
||||
|
||||
Icon(
|
||||
imageVector = icon,
|
||||
contentDescription = null,
|
||||
modifier = modifier
|
||||
.size(24.dp)
|
||||
.rotate(rotation),
|
||||
tint = color
|
||||
)
|
||||
} else {
|
||||
Icon(
|
||||
imageVector = icon,
|
||||
contentDescription = null,
|
||||
modifier = modifier.size(24.dp),
|
||||
tint = color
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить информацию о состоянии подключения
|
||||
*/
|
||||
@Composable
|
||||
private fun getConnectionStateInfo(
|
||||
connectionState: ConnectionState
|
||||
): Triple<ImageVector, androidx.compose.ui.graphics.Color, String> {
|
||||
return when (connectionState) {
|
||||
ConnectionState.DISCONNECTED -> Triple(
|
||||
Icons.Default.Close,
|
||||
MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
stringResource(R.string.status_disconnected)
|
||||
)
|
||||
ConnectionState.CONNECTING -> Triple(
|
||||
Icons.Default.Refresh,
|
||||
MaterialTheme.colorScheme.primary,
|
||||
stringResource(R.string.status_connecting)
|
||||
)
|
||||
ConnectionState.CONNECTED -> Triple(
|
||||
Icons.Default.CheckCircle,
|
||||
MaterialTheme.colorScheme.primary,
|
||||
stringResource(R.string.status_connected)
|
||||
)
|
||||
ConnectionState.ERROR -> Triple(
|
||||
Icons.Default.Warning,
|
||||
MaterialTheme.colorScheme.error,
|
||||
stringResource(R.string.status_error)
|
||||
)
|
||||
ConnectionState.RECONNECTING -> Triple(
|
||||
Icons.Default.Refresh,
|
||||
MaterialTheme.colorScheme.secondary,
|
||||
stringResource(R.string.status_reconnecting)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
package com.example.godeye.ui.components
|
||||
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Person
|
||||
import androidx.compose.material.icons.filled.Close
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.example.godeye.R
|
||||
import com.example.godeye.models.CameraSession
|
||||
import com.example.godeye.utils.Constants
|
||||
import kotlinx.coroutines.delay
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Компонент для отображения списка активных сессий
|
||||
*/
|
||||
@Composable
|
||||
fun SessionsList(
|
||||
sessions: List<CameraSession>,
|
||||
onEndSession: (String) -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
if (sessions.isEmpty()) {
|
||||
// Пустое состояние
|
||||
Box(
|
||||
modifier = modifier.fillMaxWidth(),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.no_active_sessions),
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
} else {
|
||||
LazyColumn(
|
||||
modifier = modifier.fillMaxWidth(),
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||
contentPadding = PaddingValues(vertical = 8.dp)
|
||||
) {
|
||||
items(sessions, key = { it.sessionId }) { session ->
|
||||
SessionItem(
|
||||
session = session,
|
||||
onEndSession = { onEndSession(session.sessionId) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Элемент списка сессий
|
||||
*/
|
||||
@Composable
|
||||
fun SessionItem(
|
||||
session: CameraSession,
|
||||
onEndSession: () -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
Card(
|
||||
modifier = modifier.fillMaxWidth(),
|
||||
shape = RoundedCornerShape(12.dp),
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = 4.dp)
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(16.dp)
|
||||
) {
|
||||
// Заголовок с оператором
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Person,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(20.dp),
|
||||
tint = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
Text(
|
||||
text = "${stringResource(R.string.session_operator_label)} ${session.operatorId}",
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
}
|
||||
|
||||
// Статус WebRTC
|
||||
WebRTCStatusChip(isConnected = session.webRTCConnected)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
|
||||
// Информация о камере
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Person, // Заменено с Camera на Person
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(18.dp),
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
Text(
|
||||
text = "${stringResource(R.string.session_camera_label)} ${getCameraTypeName(session.cameraType)}",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
|
||||
// Длительность сессии
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
SessionDuration(startTime = session.startTime)
|
||||
|
||||
// Кнопка завершения сессии
|
||||
FilledTonalButton(
|
||||
onClick = onEndSession,
|
||||
colors = ButtonDefaults.filledTonalButtonColors(
|
||||
containerColor = MaterialTheme.colorScheme.errorContainer,
|
||||
contentColor = MaterialTheme.colorScheme.onErrorContainer
|
||||
)
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Close,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(18.dp)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(4.dp))
|
||||
Text(stringResource(R.string.end_session_button))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Компонент для отображения статуса WebRTC соединения
|
||||
*/
|
||||
@Composable
|
||||
fun WebRTCStatusChip(
|
||||
isConnected: Boolean,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
val backgroundColor = if (isConnected) {
|
||||
MaterialTheme.colorScheme.primaryContainer
|
||||
} else {
|
||||
MaterialTheme.colorScheme.errorContainer
|
||||
}
|
||||
|
||||
val contentColor = if (isConnected) {
|
||||
MaterialTheme.colorScheme.onPrimaryContainer
|
||||
} else {
|
||||
MaterialTheme.colorScheme.onErrorContainer
|
||||
}
|
||||
|
||||
val statusText = if (isConnected) {
|
||||
stringResource(R.string.webrtc_connected)
|
||||
} else {
|
||||
stringResource(R.string.webrtc_disconnected)
|
||||
}
|
||||
|
||||
Surface(
|
||||
modifier = modifier,
|
||||
shape = RoundedCornerShape(16.dp),
|
||||
color = backgroundColor
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.session_webrtc_status, statusText),
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
color = contentColor,
|
||||
modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Компонент для отображения длительности сессии
|
||||
*/
|
||||
@Composable
|
||||
fun SessionDuration(
|
||||
startTime: Long,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
var currentTime by remember { mutableStateOf(System.currentTimeMillis()) }
|
||||
|
||||
// Обновляем время каждую секунду
|
||||
LaunchedEffect(startTime) {
|
||||
while (true) {
|
||||
currentTime = System.currentTimeMillis()
|
||||
delay(1000)
|
||||
}
|
||||
}
|
||||
|
||||
val duration = currentTime - startTime
|
||||
val hours = (duration / (1000 * 60 * 60)) % 24
|
||||
val minutes = (duration / (1000 * 60)) % 60
|
||||
val seconds = (duration / 1000) % 60
|
||||
|
||||
Text(
|
||||
text = "${stringResource(R.string.session_duration_label)} ${String.format("%02d:%02d:%02d", hours, minutes, seconds)}",
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = modifier
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить локализованное название типа камеры
|
||||
*/
|
||||
@Composable
|
||||
private fun getCameraTypeName(cameraType: String): String {
|
||||
return when (cameraType) {
|
||||
Constants.CameraTypes.BACK -> stringResource(R.string.camera_type_back)
|
||||
Constants.CameraTypes.FRONT -> stringResource(R.string.camera_type_front)
|
||||
Constants.CameraTypes.WIDE -> stringResource(R.string.camera_type_wide)
|
||||
Constants.CameraTypes.TELEPHOTO -> stringResource(R.string.camera_type_telephoto)
|
||||
else -> cameraType
|
||||
}
|
||||
}
|
||||
318
app/src/main/java/com/example/godeye/ui/screens/MainScreen.kt
Normal file
@@ -0,0 +1,318 @@
|
||||
package com.example.godeye.ui.screens
|
||||
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Settings
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.example.godeye.R
|
||||
import com.example.godeye.models.ConnectionState
|
||||
import com.example.godeye.models.MainScreenState
|
||||
import com.example.godeye.ui.components.CameraRequestDialog
|
||||
import com.example.godeye.ui.components.ConnectionStatusCard
|
||||
import com.example.godeye.ui.components.SessionsList
|
||||
import com.example.godeye.ui.viewmodels.MainViewModel
|
||||
import com.example.godeye.ui.viewmodels.UiEvent
|
||||
import com.example.godeye.utils.collectAsEffect
|
||||
|
||||
/**
|
||||
* Главный экран приложения
|
||||
*/
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun MainScreen(
|
||||
viewModel: MainViewModel = viewModel(),
|
||||
onRequestPermissions: () -> Unit,
|
||||
onShowError: (String) -> Unit
|
||||
) {
|
||||
val uiState by viewModel.uiState.collectAsState()
|
||||
var serverUrl by remember { mutableStateOf("") }
|
||||
|
||||
// Синхронизируем локальное состояние с ViewModel
|
||||
LaunchedEffect(uiState.serverUrl) {
|
||||
serverUrl = uiState.serverUrl
|
||||
}
|
||||
|
||||
// Обработка UI событий
|
||||
LaunchedEffect(viewModel) {
|
||||
viewModel.events.collect { event ->
|
||||
when (event) {
|
||||
is UiEvent.RequestPermissions -> onRequestPermissions()
|
||||
is UiEvent.ShowError -> {
|
||||
// Получаем текст ошибки внутри LaunchedEffect
|
||||
val errorMessage = when (event.error) {
|
||||
is com.example.godeye.models.AppError.NetworkError -> "Ошибка сети"
|
||||
is com.example.godeye.models.AppError.CameraPermissionDenied -> "Нет разрешения на камеру"
|
||||
is com.example.godeye.models.AppError.AudioPermissionDenied -> "Нет разрешения на микрофон"
|
||||
is com.example.godeye.models.AppError.CameraNotAvailable -> "Камера недоступна"
|
||||
is com.example.godeye.models.AppError.WebRTCConnectionFailed -> "Ошибка WebRTC соединения"
|
||||
is com.example.godeye.models.AppError.SocketError -> "Ошибка WebSocket: ${event.error.message}"
|
||||
is com.example.godeye.models.AppError.CameraError -> "Ошибка камеры: ${event.error.message}"
|
||||
is com.example.godeye.models.AppError.UnknownError -> "Неизвестная ошибка"
|
||||
}
|
||||
onShowError(errorMessage)
|
||||
}
|
||||
is UiEvent.ShowMessage -> onShowError(event.message)
|
||||
is UiEvent.ShowCameraRequestDialog -> {
|
||||
// Диалог будет показан через состояние showCameraRequest
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
title = {
|
||||
Text(
|
||||
text = stringResource(R.string.app_name),
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
},
|
||||
actions = {
|
||||
IconButton(onClick = { /* TODO: Настройки */ }) {
|
||||
Icon(Icons.Default.Settings, contentDescription = stringResource(R.string.settings))
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
) { paddingValues ->
|
||||
Box(modifier = Modifier.fillMaxSize()) {
|
||||
MainContent(
|
||||
uiState = uiState,
|
||||
serverUrl = serverUrl,
|
||||
onServerUrlChange = { serverUrl = it },
|
||||
onConnect = {
|
||||
viewModel.updateServerUrl(serverUrl)
|
||||
viewModel.connect()
|
||||
},
|
||||
onDisconnect = viewModel::disconnect,
|
||||
onEndSession = viewModel::endSession,
|
||||
modifier = Modifier.padding(paddingValues)
|
||||
)
|
||||
|
||||
// Диалог запроса камеры
|
||||
uiState.showCameraRequest?.let { request ->
|
||||
CameraRequestDialog(
|
||||
request = request,
|
||||
onAccept = { viewModel.respondToCameraRequest(request.sessionId, true) },
|
||||
onDeny = { viewModel.respondToCameraRequest(request.sessionId, false) },
|
||||
onDismiss = { viewModel.respondToCameraRequest(request.sessionId, false) }
|
||||
)
|
||||
}
|
||||
|
||||
// Индикатор загрузки
|
||||
if (uiState.isLoading) {
|
||||
Box(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Card(
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = 8.dp)
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.padding(16.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
CircularProgressIndicator(modifier = Modifier.size(24.dp))
|
||||
Spacer(modifier = Modifier.width(12.dp))
|
||||
Text(stringResource(R.string.loading))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Основное содержимое экрана
|
||||
*/
|
||||
@Composable
|
||||
private fun MainContent(
|
||||
uiState: MainScreenState,
|
||||
serverUrl: String,
|
||||
onServerUrlChange: (String) -> Unit,
|
||||
onConnect: () -> Unit,
|
||||
onDisconnect: () -> Unit,
|
||||
onEndSession: (String) -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxSize()
|
||||
.padding(16.dp)
|
||||
.verticalScroll(rememberScrollState()),
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp)
|
||||
) {
|
||||
// Информация об устройстве
|
||||
DeviceInfoCard(deviceId = uiState.deviceId)
|
||||
|
||||
// Статус подключения
|
||||
ConnectionStatusCard(connectionState = uiState.connectionState)
|
||||
|
||||
// Настройки подключения
|
||||
ConnectionSettingsCard(
|
||||
serverUrl = serverUrl,
|
||||
onServerUrlChange = onServerUrlChange,
|
||||
connectionState = uiState.connectionState,
|
||||
onConnect = onConnect,
|
||||
onDisconnect = onDisconnect
|
||||
)
|
||||
|
||||
// Список активных сессий
|
||||
ActiveSessionsCard(
|
||||
sessions = uiState.activeSessions,
|
||||
onEndSession = onEndSession
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Карточка с информацией об устройстве
|
||||
*/
|
||||
@Composable
|
||||
private fun DeviceInfoCard(
|
||||
deviceId: String,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
Card(
|
||||
modifier = modifier.fillMaxWidth(),
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = 4.dp)
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(16.dp)
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.device_id_label),
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Spacer(modifier = Modifier.height(4.dp))
|
||||
Text(
|
||||
text = deviceId.ifEmpty { "..." },
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Карточка настроек подключения
|
||||
*/
|
||||
@Composable
|
||||
private fun ConnectionSettingsCard(
|
||||
serverUrl: String,
|
||||
onServerUrlChange: (String) -> Unit,
|
||||
connectionState: ConnectionState,
|
||||
onConnect: () -> Unit,
|
||||
onDisconnect: () -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
Card(
|
||||
modifier = modifier.fillMaxWidth(),
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = 4.dp)
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(16.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp)
|
||||
) {
|
||||
// Поле ввода URL сервера
|
||||
OutlinedTextField(
|
||||
value = serverUrl,
|
||||
onValueChange = onServerUrlChange,
|
||||
label = { Text(stringResource(R.string.server_url_label)) },
|
||||
placeholder = { Text(stringResource(R.string.server_url_hint)) },
|
||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Uri),
|
||||
enabled = connectionState == ConnectionState.DISCONNECTED,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
singleLine = true
|
||||
)
|
||||
|
||||
// Кнопка подключения/отключения
|
||||
val isConnected = connectionState == ConnectionState.CONNECTED
|
||||
val isLoading = connectionState == ConnectionState.CONNECTING ||
|
||||
connectionState == ConnectionState.RECONNECTING
|
||||
|
||||
Button(
|
||||
onClick = if (isConnected) onDisconnect else onConnect,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
enabled = !isLoading && serverUrl.isNotBlank()
|
||||
) {
|
||||
if (isLoading) {
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier.size(16.dp),
|
||||
strokeWidth = 2.dp,
|
||||
color = MaterialTheme.colorScheme.onPrimary
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
}
|
||||
Text(
|
||||
if (isConnected) stringResource(R.string.disconnect_button)
|
||||
else stringResource(R.string.connect_button)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Карточка активных сессий
|
||||
*/
|
||||
@Composable
|
||||
private fun ActiveSessionsCard(
|
||||
sessions: List<com.example.godeye.models.CameraSession>,
|
||||
onEndSession: (String) -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
Card(
|
||||
modifier = modifier.fillMaxWidth(),
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = 4.dp)
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(16.dp)
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.active_sessions_label),
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
|
||||
if (sessions.isNotEmpty()) {
|
||||
Badge {
|
||||
Text("${sessions.size}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
|
||||
SessionsList(
|
||||
sessions = sessions,
|
||||
onEndSession = onEndSession
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
11
app/src/main/java/com/example/godeye/ui/theme/Color.kt
Normal file
@@ -0,0 +1,11 @@
|
||||
package com.example.godeye.ui.theme
|
||||
|
||||
import androidx.compose.ui.graphics.Color
|
||||
|
||||
val Purple80 = Color(0xFFD0BCFF)
|
||||
val PurpleGrey80 = Color(0xFFCCC2DC)
|
||||
val Pink80 = Color(0xFFEFB8C8)
|
||||
|
||||
val Purple40 = Color(0xFF6650a4)
|
||||
val PurpleGrey40 = Color(0xFF625b71)
|
||||
val Pink40 = Color(0xFF7D5260)
|
||||
58
app/src/main/java/com/example/godeye/ui/theme/Theme.kt
Normal file
@@ -0,0 +1,58 @@
|
||||
package com.example.godeye.ui.theme
|
||||
|
||||
import android.app.Activity
|
||||
import android.os.Build
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.darkColorScheme
|
||||
import androidx.compose.material3.dynamicDarkColorScheme
|
||||
import androidx.compose.material3.dynamicLightColorScheme
|
||||
import androidx.compose.material3.lightColorScheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
|
||||
private val DarkColorScheme = darkColorScheme(
|
||||
primary = Purple80,
|
||||
secondary = PurpleGrey80,
|
||||
tertiary = Pink80
|
||||
)
|
||||
|
||||
private val LightColorScheme = lightColorScheme(
|
||||
primary = Purple40,
|
||||
secondary = PurpleGrey40,
|
||||
tertiary = Pink40
|
||||
|
||||
/* Other default colors to override
|
||||
background = Color(0xFFFFFBFE),
|
||||
surface = Color(0xFFFFFBFE),
|
||||
onPrimary = Color.White,
|
||||
onSecondary = Color.White,
|
||||
onTertiary = Color.White,
|
||||
onBackground = Color(0xFF1C1B1F),
|
||||
onSurface = Color(0xFF1C1B1F),
|
||||
*/
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun GodEyeTheme(
|
||||
darkTheme: Boolean = isSystemInDarkTheme(),
|
||||
// Dynamic color is available on Android 12+
|
||||
dynamicColor: Boolean = true,
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
val colorScheme = when {
|
||||
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
|
||||
val context = LocalContext.current
|
||||
if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
|
||||
}
|
||||
|
||||
darkTheme -> DarkColorScheme
|
||||
else -> LightColorScheme
|
||||
}
|
||||
|
||||
MaterialTheme(
|
||||
colorScheme = colorScheme,
|
||||
typography = Typography,
|
||||
content = content
|
||||
)
|
||||
}
|
||||
34
app/src/main/java/com/example/godeye/ui/theme/Type.kt
Normal file
@@ -0,0 +1,34 @@
|
||||
package com.example.godeye.ui.theme
|
||||
|
||||
import androidx.compose.material3.Typography
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.sp
|
||||
|
||||
// Set of Material typography styles to start with
|
||||
val Typography = Typography(
|
||||
bodyLarge = TextStyle(
|
||||
fontFamily = FontFamily.Default,
|
||||
fontWeight = FontWeight.Normal,
|
||||
fontSize = 16.sp,
|
||||
lineHeight = 24.sp,
|
||||
letterSpacing = 0.5.sp
|
||||
)
|
||||
/* Other default text styles to override
|
||||
titleLarge = TextStyle(
|
||||
fontFamily = FontFamily.Default,
|
||||
fontWeight = FontWeight.Normal,
|
||||
fontSize = 22.sp,
|
||||
lineHeight = 28.sp,
|
||||
letterSpacing = 0.sp
|
||||
),
|
||||
labelSmall = TextStyle(
|
||||
fontFamily = FontFamily.Default,
|
||||
fontWeight = FontWeight.Medium,
|
||||
fontSize = 11.sp,
|
||||
lineHeight = 16.sp,
|
||||
letterSpacing = 0.5.sp
|
||||
)
|
||||
*/
|
||||
)
|
||||
@@ -0,0 +1,385 @@
|
||||
package com.example.godeye.ui.viewmodels
|
||||
|
||||
import android.app.Application
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.ServiceConnection
|
||||
import android.os.IBinder
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.example.godeye.managers.PermissionManager
|
||||
import com.example.godeye.models.*
|
||||
import com.example.godeye.services.CameraService
|
||||
import com.example.godeye.services.SocketService
|
||||
import com.example.godeye.utils.Constants
|
||||
import com.example.godeye.utils.Logger
|
||||
import com.example.godeye.utils.getPreferences
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
/**
|
||||
* ViewModel для главного экрана приложения
|
||||
*/
|
||||
class MainViewModel(application: Application) : AndroidViewModel(application) {
|
||||
|
||||
private val context = getApplication<Application>()
|
||||
private val permissionManager = PermissionManager(context)
|
||||
|
||||
// Сервисы
|
||||
private var socketService: SocketService? = null
|
||||
private var cameraService: CameraService? = null
|
||||
private var socketServiceBound = false
|
||||
private var cameraServiceBound = false
|
||||
|
||||
// UI State
|
||||
private val _uiState = MutableStateFlow(MainScreenState())
|
||||
val uiState: StateFlow<MainScreenState> = _uiState.asStateFlow()
|
||||
|
||||
// События для UI
|
||||
private val _events = MutableSharedFlow<UiEvent>()
|
||||
val events: SharedFlow<UiEvent> = _events.asSharedFlow()
|
||||
|
||||
init {
|
||||
loadSavedSettings()
|
||||
// startServices() убран отсюда
|
||||
}
|
||||
|
||||
/**
|
||||
* Загрузить сохраненные настройки
|
||||
*/
|
||||
private fun loadSavedSettings() {
|
||||
val prefs = context.getPreferences()
|
||||
val serverUrl = prefs.getString(Constants.PreferenceKeys.SERVER_URL, Constants.DEFAULT_SERVER_URL) ?: Constants.DEFAULT_SERVER_URL
|
||||
val deviceId = prefs.getString(Constants.PreferenceKeys.DEVICE_ID, "") ?: ""
|
||||
|
||||
_uiState.value = _uiState.value.copy(
|
||||
serverUrl = serverUrl,
|
||||
deviceId = deviceId
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Запустить сервисы (вызывать из MainActivity после проверки разрешений)
|
||||
*/
|
||||
fun startServices() {
|
||||
// Запуск SocketService
|
||||
val socketIntent = Intent(context, SocketService::class.java)
|
||||
context.startForegroundService(socketIntent)
|
||||
context.bindService(socketIntent, socketConnection, Context.BIND_AUTO_CREATE)
|
||||
|
||||
// Запуск CameraService
|
||||
val cameraIntent = Intent(context, CameraService::class.java)
|
||||
context.startForegroundService(cameraIntent)
|
||||
context.bindService(cameraIntent, cameraConnection, Context.BIND_AUTO_CREATE)
|
||||
}
|
||||
|
||||
/**
|
||||
* ServiceConnection для SocketService
|
||||
*/
|
||||
private val socketConnection = object : ServiceConnection {
|
||||
override fun onServiceConnected(className: ComponentName, service: IBinder) {
|
||||
val binder = service as SocketService.LocalBinder
|
||||
socketService = binder.getService()
|
||||
socketServiceBound = true
|
||||
|
||||
Logger.d("SocketService connected")
|
||||
observeSocketService()
|
||||
}
|
||||
|
||||
override fun onServiceDisconnected(arg0: ComponentName) {
|
||||
socketServiceBound = false
|
||||
socketService = null
|
||||
Logger.d("SocketService disconnected")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ServiceConnection для CameraService
|
||||
*/
|
||||
private val cameraConnection = object : ServiceConnection {
|
||||
override fun onServiceConnected(className: ComponentName, service: IBinder) {
|
||||
val binder = service as CameraService.LocalBinder
|
||||
cameraService = binder.getService()
|
||||
cameraServiceBound = true
|
||||
|
||||
Logger.d("CameraService connected")
|
||||
observeCameraService()
|
||||
setupCameraServiceCallbacks()
|
||||
}
|
||||
|
||||
override fun onServiceDisconnected(arg0: ComponentName) {
|
||||
cameraServiceBound = false
|
||||
cameraService = null
|
||||
Logger.d("CameraService disconnected")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Наблюдать за состоянием SocketService
|
||||
*/
|
||||
private fun observeSocketService() {
|
||||
val service = socketService ?: return
|
||||
|
||||
viewModelScope.launch {
|
||||
service.connectionState.collect { state ->
|
||||
_uiState.value = _uiState.value.copy(connectionState = state)
|
||||
}
|
||||
}
|
||||
|
||||
viewModelScope.launch {
|
||||
service.deviceId.collect { deviceId ->
|
||||
_uiState.value = _uiState.value.copy(deviceId = deviceId)
|
||||
}
|
||||
}
|
||||
|
||||
viewModelScope.launch {
|
||||
service.error.collect { error ->
|
||||
error?.let {
|
||||
_uiState.value = _uiState.value.copy(error = it)
|
||||
_events.emit(UiEvent.ShowError(it))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
viewModelScope.launch {
|
||||
service.cameraRequest.collect { request ->
|
||||
request?.let {
|
||||
_uiState.value = _uiState.value.copy(showCameraRequest = it)
|
||||
_events.emit(UiEvent.ShowCameraRequestDialog(it))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
viewModelScope.launch {
|
||||
service.webrtcOffer.collect { offer ->
|
||||
offer?.let {
|
||||
handleWebRTCOffer(it)
|
||||
service.clearWebRTCOffer()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
viewModelScope.launch {
|
||||
service.webrtcIceCandidate.collect { candidate ->
|
||||
candidate?.let {
|
||||
handleWebRTCIceCandidate(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
viewModelScope.launch {
|
||||
service.cameraSwitchRequest.collect { request ->
|
||||
request?.let { (sessionId, cameraType) ->
|
||||
handleCameraSwitch(sessionId, cameraType)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
viewModelScope.launch {
|
||||
service.sessionDisconnect.collect { sessionId ->
|
||||
sessionId?.let {
|
||||
handleSessionDisconnect(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Наблюдать за состоянием CameraService
|
||||
*/
|
||||
private fun observeCameraService() {
|
||||
val service = cameraService ?: return
|
||||
|
||||
viewModelScope.launch {
|
||||
service.getSessionManager().activeSessions.collect { sessions ->
|
||||
_uiState.value = _uiState.value.copy(activeSessions = sessions)
|
||||
}
|
||||
}
|
||||
|
||||
viewModelScope.launch {
|
||||
service.error.collect { error ->
|
||||
error?.let {
|
||||
_uiState.value = _uiState.value.copy(error = it)
|
||||
_events.emit(UiEvent.ShowError(it))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Настроить callbacks для CameraService
|
||||
*/
|
||||
private fun setupCameraServiceCallbacks() {
|
||||
cameraService?.setWebRTCCallbacks(
|
||||
onOfferCreated = { sessionId, offer ->
|
||||
// WebRTC offer создан, но в нашем случае мы получаем offer от оператора
|
||||
Logger.d("WebRTC offer created for session: $sessionId")
|
||||
},
|
||||
onIceCandidateCreated = { sessionId, candidate, sdpMid, sdpMLineIndex ->
|
||||
socketService?.sendIceCandidate(sessionId, candidate, sdpMid, sdpMLineIndex)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Подключиться к серверу
|
||||
*/
|
||||
fun connect() {
|
||||
if (!permissionManager.hasCriticalPermissions()) {
|
||||
_events.tryEmit(UiEvent.RequestPermissions)
|
||||
return
|
||||
}
|
||||
|
||||
val serverUrl = _uiState.value.serverUrl
|
||||
if (serverUrl.isBlank()) {
|
||||
_events.tryEmit(UiEvent.ShowError(AppError.SocketError("Введите URL сервера")))
|
||||
return
|
||||
}
|
||||
|
||||
// Сохраняем URL сервера
|
||||
context.getPreferences().edit()
|
||||
.putString(Constants.PreferenceKeys.SERVER_URL, serverUrl)
|
||||
.apply()
|
||||
|
||||
_uiState.value = _uiState.value.copy(isLoading = true)
|
||||
socketService?.connect(serverUrl)
|
||||
}
|
||||
|
||||
/**
|
||||
* Отключиться от сервера
|
||||
*/
|
||||
fun disconnect() {
|
||||
_uiState.value = _uiState.value.copy(isLoading = true)
|
||||
socketService?.disconnect()
|
||||
cameraService?.endAllSessions()
|
||||
}
|
||||
|
||||
/**
|
||||
* Обновить URL сервера
|
||||
*/
|
||||
fun updateServerUrl(url: String) {
|
||||
_uiState.value = _uiState.value.copy(serverUrl = url)
|
||||
}
|
||||
|
||||
/**
|
||||
* Ответить на запрос камеры
|
||||
*/
|
||||
fun respondToCameraRequest(sessionId: String, accepted: Boolean, reason: String? = null) {
|
||||
socketService?.sendCameraResponse(sessionId, accepted, reason)
|
||||
|
||||
if (accepted) {
|
||||
// Получаем информацию о запросе
|
||||
val request = _uiState.value.showCameraRequest
|
||||
if (request != null && request.sessionId == sessionId) {
|
||||
// Начинаем камера сессию
|
||||
cameraService?.startCameraSession(sessionId, request.operatorId, request.cameraType)
|
||||
}
|
||||
}
|
||||
|
||||
// Очищаем запрос из UI
|
||||
_uiState.value = _uiState.value.copy(showCameraRequest = null)
|
||||
socketService?.clearCameraRequest()
|
||||
}
|
||||
|
||||
/**
|
||||
* Завершить сессию
|
||||
*/
|
||||
fun endSession(sessionId: String) {
|
||||
cameraService?.endSession(sessionId)
|
||||
}
|
||||
|
||||
/**
|
||||
* Обработать WebRTC Offer
|
||||
*/
|
||||
private fun handleWebRTCOffer(offer: WebRTCMessage) {
|
||||
val sessionId = offer.sessionId
|
||||
val offerSdp = offer.sdp ?: return
|
||||
|
||||
Logger.d("Handling WebRTC offer for session: $sessionId")
|
||||
// В нашем случае мы не обрабатываем offer, так как создаем его сами
|
||||
// Но можно добавить логику для обработки offer от оператора
|
||||
}
|
||||
|
||||
/**
|
||||
* Обработать WebRTC ICE Candidate
|
||||
*/
|
||||
private fun handleWebRTCIceCandidate(candidate: WebRTCMessage) {
|
||||
val sessionId = candidate.sessionId
|
||||
val candidateSdp = candidate.candidate ?: return
|
||||
val sdpMid = candidate.sdpMid ?: return
|
||||
val sdpMLineIndex = candidate.sdpMLineIndex ?: return
|
||||
|
||||
Logger.d("Handling ICE candidate for session: $sessionId")
|
||||
cameraService?.addIceCandidate(sessionId, candidateSdp, sdpMid, sdpMLineIndex)
|
||||
}
|
||||
|
||||
/**
|
||||
* Обработать переключение камеры
|
||||
*/
|
||||
private fun handleCameraSwitch(sessionId: String, newCameraType: String) {
|
||||
Logger.d("Handling camera switch for session $sessionId to $newCameraType")
|
||||
cameraService?.switchCamera(sessionId, newCameraType)
|
||||
}
|
||||
|
||||
/**
|
||||
* Обработать отключение сессии
|
||||
*/
|
||||
private fun handleSessionDisconnect(sessionId: String) {
|
||||
Logger.d("Handling session disconnect: $sessionId")
|
||||
cameraService?.endSession(sessionId)
|
||||
}
|
||||
|
||||
/**
|
||||
* Очистить ошибку
|
||||
*/
|
||||
fun clearError() {
|
||||
_uiState.value = _uiState.value.copy(error = null)
|
||||
socketService?.clearError()
|
||||
cameraService?.clearError()
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверить разрешения
|
||||
*/
|
||||
fun checkPermissions(): Boolean {
|
||||
return permissionManager.hasAllRequiredPermissions()
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить отсутствующие разрешения
|
||||
*/
|
||||
fun getMissingPermissions(): List<String> {
|
||||
return permissionManager.getMissingPermissions()
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
super.onCleared()
|
||||
|
||||
// Отвязка сервисов
|
||||
try {
|
||||
if (socketServiceBound) {
|
||||
context.unbindService(socketConnection)
|
||||
socketServiceBound = false
|
||||
}
|
||||
if (cameraServiceBound) {
|
||||
context.unbindService(cameraConnection)
|
||||
cameraServiceBound = false
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Logger.e("Error unbinding services", e)
|
||||
}
|
||||
|
||||
Logger.d("MainViewModel cleared")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* События UI для обработки в Activity/Compose
|
||||
*/
|
||||
sealed class UiEvent {
|
||||
object RequestPermissions : UiEvent()
|
||||
data class ShowError(val error: AppError) : UiEvent()
|
||||
data class ShowCameraRequestDialog(val request: CameraRequest) : UiEvent()
|
||||
data class ShowMessage(val message: String) : UiEvent()
|
||||
}
|
||||
49
app/src/main/java/com/example/godeye/utils/Constants.kt
Normal file
@@ -0,0 +1,49 @@
|
||||
package com.example.godeye.utils
|
||||
|
||||
object Constants {
|
||||
// WebSocket события
|
||||
object SocketEvents {
|
||||
const val REGISTER_ANDROID = "register:android"
|
||||
const val REGISTER_SUCCESS = "register:success"
|
||||
const val REGISTER_ERROR = "register:error"
|
||||
const val CAMERA_REQUEST = "camera:request"
|
||||
const val CAMERA_RESPONSE = "camera:response"
|
||||
const val CAMERA_DISCONNECT = "camera:disconnect"
|
||||
const val CAMERA_SWITCH = "camera:switch"
|
||||
const val WEBRTC_OFFER = "webrtc:offer"
|
||||
const val WEBRTC_ANSWER = "webrtc:answer"
|
||||
const val WEBRTC_ICE_CANDIDATE = "webrtc:ice-candidate"
|
||||
}
|
||||
|
||||
// Типы камер
|
||||
object CameraTypes {
|
||||
const val BACK = "back"
|
||||
const val FRONT = "front"
|
||||
const val WIDE = "wide"
|
||||
const val TELEPHOTO = "telephoto"
|
||||
}
|
||||
|
||||
// SharedPreferences ключи
|
||||
object PreferenceKeys {
|
||||
const val SERVER_URL = "server_url"
|
||||
const val DEVICE_ID = "device_id"
|
||||
const val AUTO_ACCEPT_REQUESTS = "auto_accept_requests"
|
||||
const val CAMERA_QUALITY = "camera_quality"
|
||||
const val NOTIFICATION_ENABLED = "notification_enabled"
|
||||
}
|
||||
|
||||
// Настройки по умолчанию
|
||||
const val DEFAULT_SERVER_URL = "http://10.0.2.2:3001" // Специальный IP для Android эмулятора
|
||||
const val SOCKET_CONNECTION_TIMEOUT = 10000L
|
||||
const val WEBRTC_CONNECTION_TIMEOUT = 15000L
|
||||
|
||||
// Уведомления
|
||||
const val NOTIFICATION_CHANNEL_ID = "godeye_service_channel"
|
||||
const val FOREGROUND_SERVICE_ID = 1001
|
||||
|
||||
// WebRTC настройки
|
||||
val STUN_SERVERS = listOf(
|
||||
"stun:stun.l.google.com:19302",
|
||||
"stun:stun1.l.google.com:19302"
|
||||
)
|
||||
}
|
||||
140
app/src/main/java/com/example/godeye/utils/Extensions.kt
Normal file
@@ -0,0 +1,140 @@
|
||||
package com.example.godeye.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import android.hardware.camera2.CameraCharacteristics
|
||||
import android.hardware.camera2.CameraManager
|
||||
import android.util.Log
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.ui.platform.LocalLifecycleOwner
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.repeatOnLifecycle
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Расширения для Context
|
||||
*/
|
||||
fun Context.getPreferences(): SharedPreferences {
|
||||
return getSharedPreferences("godeye_prefs", Context.MODE_PRIVATE)
|
||||
}
|
||||
|
||||
fun Context.generateDeviceId(): String {
|
||||
val prefs = getPreferences()
|
||||
var deviceId = prefs.getString(Constants.PreferenceKeys.DEVICE_ID, null)
|
||||
if (deviceId == null) {
|
||||
deviceId = "android_${UUID.randomUUID().toString().take(8)}"
|
||||
prefs.edit().putString(Constants.PreferenceKeys.DEVICE_ID, deviceId).apply()
|
||||
}
|
||||
return deviceId
|
||||
}
|
||||
|
||||
/**
|
||||
* Расширения для CameraManager
|
||||
*/
|
||||
fun CameraManager.getAvailableCameraTypes(): List<String> {
|
||||
val cameras = mutableListOf<String>()
|
||||
try {
|
||||
for (cameraId in cameraIdList) {
|
||||
val characteristics = getCameraCharacteristics(cameraId)
|
||||
val facing = characteristics.get(CameraCharacteristics.LENS_FACING)
|
||||
|
||||
when (facing) {
|
||||
CameraCharacteristics.LENS_FACING_BACK -> {
|
||||
// Проверяем на широкоугольный и телеобъектив
|
||||
val focalLengths = characteristics.get(CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS)
|
||||
if (focalLengths != null && focalLengths.isNotEmpty()) {
|
||||
val minFocalLength = focalLengths.minOrNull() ?: 0f
|
||||
val maxFocalLength = focalLengths.maxOrNull() ?: 0f
|
||||
|
||||
when {
|
||||
minFocalLength < 2.8f -> cameras.add(Constants.CameraTypes.WIDE)
|
||||
maxFocalLength > 5.5f -> cameras.add(Constants.CameraTypes.TELEPHOTO)
|
||||
else -> cameras.add(Constants.CameraTypes.BACK)
|
||||
}
|
||||
} else {
|
||||
cameras.add(Constants.CameraTypes.BACK)
|
||||
}
|
||||
}
|
||||
CameraCharacteristics.LENS_FACING_FRONT -> cameras.add(Constants.CameraTypes.FRONT)
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e("CameraExtensions", "Error getting cameras", e)
|
||||
// Добавляем базовые камеры как fallback
|
||||
cameras.add(Constants.CameraTypes.BACK)
|
||||
cameras.add(Constants.CameraTypes.FRONT)
|
||||
}
|
||||
return cameras.distinct()
|
||||
}
|
||||
|
||||
fun CameraManager.getCameraIdForType(cameraType: String): String? {
|
||||
return try {
|
||||
for (cameraId in cameraIdList) {
|
||||
val characteristics = getCameraCharacteristics(cameraId)
|
||||
val facing = characteristics.get(CameraCharacteristics.LENS_FACING)
|
||||
|
||||
when (cameraType) {
|
||||
Constants.CameraTypes.FRONT -> {
|
||||
if (facing == CameraCharacteristics.LENS_FACING_FRONT) {
|
||||
return cameraId
|
||||
}
|
||||
}
|
||||
Constants.CameraTypes.BACK,
|
||||
Constants.CameraTypes.WIDE,
|
||||
Constants.CameraTypes.TELEPHOTO -> {
|
||||
if (facing == CameraCharacteristics.LENS_FACING_BACK) {
|
||||
// Для простоты используем первую найденную заднюю камеру
|
||||
// В реальном проекте здесь была бы более сложная логика
|
||||
return cameraId
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
null
|
||||
} catch (e: Exception) {
|
||||
Log.e("CameraExtensions", "Error finding camera for type $cameraType", e)
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compose расширения для Flow
|
||||
*/
|
||||
@Composable
|
||||
fun <T> Flow<T>.collectAsEffect(
|
||||
key: Any? = null,
|
||||
action: suspend (T) -> Unit
|
||||
) {
|
||||
val lifecycleOwner = LocalLifecycleOwner.current
|
||||
LaunchedEffect(key) {
|
||||
lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||
collect(action)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Логирование
|
||||
*/
|
||||
object Logger {
|
||||
private const val TAG = "GodEye"
|
||||
|
||||
fun d(message: String, tag: String = TAG) {
|
||||
Log.d(tag, message)
|
||||
}
|
||||
|
||||
fun e(message: String, throwable: Throwable? = null, tag: String = TAG) {
|
||||
Log.e(tag, message, throwable)
|
||||
}
|
||||
|
||||
fun i(message: String, tag: String = TAG) {
|
||||
Log.i(tag, message)
|
||||
}
|
||||
|
||||
fun w(message: String, tag: String = TAG) {
|
||||
Log.w(tag, message)
|
||||
}
|
||||
}
|
||||
170
app/src/main/res/drawable/ic_launcher_background.xml
Normal file
@@ -0,0 +1,170 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path
|
||||
android:fillColor="#3DDC84"
|
||||
android:pathData="M0,0h108v108h-108z" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M9,0L9,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,0L19,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,0L29,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,0L39,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,0L49,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,0L59,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,0L69,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,0L79,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M89,0L89,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M99,0L99,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,9L108,9"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,19L108,19"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,29L108,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,39L108,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,49L108,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,59L108,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,69L108,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,79L108,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,89L108,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,99L108,99"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,29L89,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,39L89,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,49L89,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,59L89,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,69L89,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,79L89,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,19L29,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,19L39,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,19L49,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,19L59,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,19L69,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,19L79,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
</vector>
|
||||
30
app/src/main/res/drawable/ic_launcher_foreground.xml
Normal file
@@ -0,0 +1,30 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:endX="85.84757"
|
||||
android:endY="92.4963"
|
||||
android:startX="42.9492"
|
||||
android:startY="49.59793"
|
||||
android:type="linear">
|
||||
<item
|
||||
android:color="#44000000"
|
||||
android:offset="0.0" />
|
||||
<item
|
||||
android:color="#00000000"
|
||||
android:offset="1.0" />
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillType="nonZero"
|
||||
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
|
||||
android:strokeWidth="1"
|
||||
android:strokeColor="#00000000" />
|
||||
</vector>
|
||||
6
app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
6
app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
BIN
app/src/main/res/mipmap-hdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 982 B |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 7.6 KiB |
10
app/src/main/res/values/colors.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="purple_200">#FFBB86FC</color>
|
||||
<color name="purple_500">#FF6200EE</color>
|
||||
<color name="purple_700">#FF3700B3</color>
|
||||
<color name="teal_200">#FF03DAC5</color>
|
||||
<color name="teal_700">#FF018786</color>
|
||||
<color name="black">#FF000000</color>
|
||||
<color name="white">#FFFFFFFF</color>
|
||||
</resources>
|
||||
80
app/src/main/res/values/strings.xml
Normal file
@@ -0,0 +1,80 @@
|
||||
<resources>
|
||||
<string name="app_name">GodEye Signal Center</string>
|
||||
|
||||
<!-- Главный экран -->
|
||||
<string name="device_id_label">ID устройства:</string>
|
||||
<string name="server_url_label">URL сервера:</string>
|
||||
<string name="server_url_hint">http://192.168.1.100:3001</string>
|
||||
<string name="connection_status_label">Статус подключения:</string>
|
||||
<string name="connect_button">Подключиться</string>
|
||||
<string name="disconnect_button">Отключиться</string>
|
||||
<string name="active_sessions_label">Активные сессии:</string>
|
||||
<string name="no_active_sessions">Нет активных сессий</string>
|
||||
|
||||
<!-- Статусы подключения -->
|
||||
<string name="status_disconnected">Отключено</string>
|
||||
<string name="status_connecting">Подключение...</string>
|
||||
<string name="status_connected">Подключено</string>
|
||||
<string name="status_error">Ошибка подключения</string>
|
||||
<string name="status_reconnecting">Переподключение...</string>
|
||||
|
||||
<!-- Диалог запроса камеры -->
|
||||
<string name="camera_request_title">Запрос доступа к камере</string>
|
||||
<string name="camera_request_message">Оператор %1$s запрашивает доступ к камере %2$s</string>
|
||||
<string name="session_id_label">ID сессии: %1$s</string>
|
||||
<string name="allow_button">Разрешить</string>
|
||||
<string name="deny_button">Отклонить</string>
|
||||
<string name="remember_choice">Запомнить для этого оператора</string>
|
||||
|
||||
<!-- Типы камер -->
|
||||
<string name="camera_type_back">Основная</string>
|
||||
<string name="camera_type_front">Фронтальная</string>
|
||||
<string name="camera_type_wide">Широкоугольная</string>
|
||||
<string name="camera_type_telephoto">Телеобъектив</string>
|
||||
|
||||
<!-- Сессии -->
|
||||
<string name="session_operator_label">Оператор:</string>
|
||||
<string name="session_camera_label">Камера:</string>
|
||||
<string name="session_duration_label">Длительность:</string>
|
||||
<string name="session_webrtc_status">WebRTC: %1$s</string>
|
||||
<string name="webrtc_connected">Подключено</string>
|
||||
<string name="webrtc_disconnected">Отключено</string>
|
||||
<string name="end_session_button">Завершить</string>
|
||||
|
||||
<!-- Ошибки -->
|
||||
<string name="error_network">Ошибка сети</string>
|
||||
<string name="error_camera_permission">Нет разрешения на камеру</string>
|
||||
<string name="error_audio_permission">Нет разрешения на микрофон</string>
|
||||
<string name="error_camera_not_available">Камера недоступна</string>
|
||||
<string name="error_webrtc_connection_failed">Ошибка WebRTC соединения</string>
|
||||
<string name="error_socket">Ошибка WebSocket: %1$s</string>
|
||||
<string name="error_camera">Ошибка камеры: %1$s</string>
|
||||
<string name="error_unknown">Неизвестная ошибка</string>
|
||||
|
||||
<!-- Разрешения -->
|
||||
<string name="permissions_required_title">Необходимы разрешения</string>
|
||||
<string name="permissions_required_message">Для работы приложения необходимы разрешения на камеру, микрофон и уведомления</string>
|
||||
<string name="grant_permissions_button">Предоставить разрешения</string>
|
||||
<string name="permissions_denied_message">Без разрешений приложение не может работать</string>
|
||||
|
||||
<!-- Уведомления -->
|
||||
<string name="notification_service_title">GodEye Signal Center</string>
|
||||
<string name="notification_service_connected">Подключено к серверу</string>
|
||||
<string name="notification_service_disconnected">Отключено от сервера</string>
|
||||
<string name="notification_camera_title">GodEye Camera</string>
|
||||
<string name="notification_camera_active">Активных сессий: %1$d</string>
|
||||
<string name="notification_camera_ready">Камера готова к работе</string>
|
||||
|
||||
<!-- Общие -->
|
||||
<string name="ok">OK</string>
|
||||
<string name="cancel">Отмена</string>
|
||||
<string name="settings">Настройки</string>
|
||||
<string name="loading">Загрузка...</string>
|
||||
<string name="retry">Повторить</string>
|
||||
|
||||
<!-- Время -->
|
||||
<string name="duration_format">%1$02d:%2$02d:%3$02d</string>
|
||||
<string name="time_seconds">сек</string>
|
||||
<string name="time_minutes">мин</string>
|
||||
<string name="time_hours">ч</string>
|
||||
</resources>
|
||||
5
app/src/main/res/values/themes.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<style name="Theme.GodEye" parent="android:Theme.Material.Light.NoActionBar" />
|
||||
</resources>
|
||||
13
app/src/main/res/xml/backup_rules.xml
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
Sample backup rules file; uncomment and customize as necessary.
|
||||
See https://developer.android.com/guide/topics/data/autobackup
|
||||
for details.
|
||||
Note: This file is ignored for devices older than API 31
|
||||
See https://developer.android.com/about/versions/12/backup-restore
|
||||
-->
|
||||
<full-backup-content>
|
||||
<!--
|
||||
<include domain="sharedpref" path="."/>
|
||||
<exclude domain="sharedpref" path="device.xml"/>
|
||||
-->
|
||||
</full-backup-content>
|
||||
19
app/src/main/res/xml/data_extraction_rules.xml
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
Sample data extraction rules file; uncomment and customize as necessary.
|
||||
See https://developer.android.com/about/versions/12/backup-restore#xml-changes
|
||||
for details.
|
||||
-->
|
||||
<data-extraction-rules>
|
||||
<cloud-backup>
|
||||
<!-- TODO: Use <include> and <exclude> to control what is backed up.
|
||||
<include .../>
|
||||
<exclude .../>
|
||||
-->
|
||||
</cloud-backup>
|
||||
<!--
|
||||
<device-transfer>
|
||||
<include .../>
|
||||
<exclude .../>
|
||||
</device-transfer>
|
||||
-->
|
||||
</data-extraction-rules>
|
||||
17
app/src/test/java/com/example/godeye/ExampleUnitTest.kt
Normal file
@@ -0,0 +1,17 @@
|
||||
package com.example.godeye
|
||||
|
||||
import org.junit.Test
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
* See [testing documentation](http://d.android.com/tools/testing).
|
||||
*/
|
||||
class ExampleUnitTest {
|
||||
@Test
|
||||
fun addition_isCorrect() {
|
||||
assertEquals(4, 2 + 2)
|
||||
}
|
||||
}
|
||||
6
build.gradle.kts
Normal file
@@ -0,0 +1,6 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
plugins {
|
||||
alias(libs.plugins.android.application) apply false
|
||||
alias(libs.plugins.kotlin.android) apply false
|
||||
alias(libs.plugins.kotlin.compose) apply false
|
||||
}
|
||||
23
gradle.properties
Normal file
@@ -0,0 +1,23 @@
|
||||
# Project-wide Gradle settings.
|
||||
# IDE (e.g. Android Studio) users:
|
||||
# Gradle settings configured through the IDE *will override*
|
||||
# any settings specified in this file.
|
||||
# For more details on how to configure your build environment visit
|
||||
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||
# Specifies the JVM arguments used for the daemon process.
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
# This option should only be used with decoupled projects. For more details, visit
|
||||
# https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects
|
||||
# org.gradle.parallel=true
|
||||
# AndroidX package structure to make it clearer which packages are bundled with the
|
||||
# Android operating system, and which are packaged with your app's APK
|
||||
# https://developer.android.com/topic/libraries/support-library/androidx-rn
|
||||
android.useAndroidX=true
|
||||
# Kotlin code style for this project: "official" or "obsolete":
|
||||
kotlin.code.style=official
|
||||
# Enables namespacing of each library's R class so that its R class includes only the
|
||||
# resources declared in the library itself and none from the library's dependencies,
|
||||
# thereby reducing the size of the R class for that library
|
||||
android.nonTransitiveRClass=true
|
||||
32
gradle/libs.versions.toml
Normal file
@@ -0,0 +1,32 @@
|
||||
[versions]
|
||||
agp = "8.13.0"
|
||||
kotlin = "2.0.21"
|
||||
coreKtx = "1.17.0"
|
||||
junit = "4.13.2"
|
||||
junitVersion = "1.3.0"
|
||||
espressoCore = "3.7.0"
|
||||
lifecycleRuntimeKtx = "2.9.4"
|
||||
activityCompose = "1.11.0"
|
||||
composeBom = "2024.09.00"
|
||||
|
||||
[libraries]
|
||||
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
||||
junit = { group = "junit", name = "junit", version.ref = "junit" }
|
||||
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
|
||||
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
|
||||
androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" }
|
||||
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" }
|
||||
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
|
||||
androidx-compose-ui = { group = "androidx.compose.ui", name = "ui" }
|
||||
androidx-compose-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" }
|
||||
androidx-compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
|
||||
androidx-compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
|
||||
androidx-compose-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
|
||||
androidx-compose-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
|
||||
androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3" }
|
||||
|
||||
[plugins]
|
||||
android-application = { id = "com.android.application", version.ref = "agp" }
|
||||
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
|
||||
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
|
||||
|
||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
6
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
#Mon Sep 29 19:41:55 KST 2025
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
185
gradlew
vendored
Executable file
@@ -0,0 +1,185 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# Copyright 2015 the original author or authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=`save "$@"`
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
89
gradlew.bat
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
1
node_modules/.bin/mime
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../mime/cli.js
|
||||
1
node_modules/.bin/nodemon
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../nodemon/bin/nodemon.js
|
||||
1
node_modules/.bin/nodetouch
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../touch/bin/nodetouch.js
|
||||
1
node_modules/.bin/semver
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../semver/bin/semver.js
|
||||
1316
node_modules/.package-lock.json
generated
vendored
Normal file
24
node_modules/@socket.io/component-emitter/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2014 Component contributors <dev@component.io>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
79
node_modules/@socket.io/component-emitter/Readme.md
generated
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
# `@socket.io/component-emitter`
|
||||
|
||||
Event emitter component.
|
||||
|
||||
This project is a fork of the [`component-emitter`](https://github.com/sindresorhus/component-emitter) project, with [Socket.IO](https://socket.io/)-specific TypeScript typings.
|
||||
|
||||
## Installation
|
||||
|
||||
```
|
||||
$ npm i @socket.io/component-emitter
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### Emitter(obj)
|
||||
|
||||
The `Emitter` may also be used as a mixin. For example
|
||||
a "plain" object may become an emitter, or you may
|
||||
extend an existing prototype.
|
||||
|
||||
As an `Emitter` instance:
|
||||
|
||||
```js
|
||||
import { Emitter } from '@socket.io/component-emitter';
|
||||
|
||||
var emitter = new Emitter;
|
||||
emitter.emit('something');
|
||||
```
|
||||
|
||||
As a mixin:
|
||||
|
||||
```js
|
||||
import { Emitter } from '@socket.io/component-emitter';
|
||||
|
||||
var user = { name: 'tobi' };
|
||||
Emitter(user);
|
||||
|
||||
user.emit('im a user');
|
||||
```
|
||||
|
||||
As a prototype mixin:
|
||||
|
||||
```js
|
||||
import { Emitter } from '@socket.io/component-emitter';
|
||||
|
||||
Emitter(User.prototype);
|
||||
```
|
||||
|
||||
### Emitter#on(event, fn)
|
||||
|
||||
Register an `event` handler `fn`.
|
||||
|
||||
### Emitter#once(event, fn)
|
||||
|
||||
Register a single-shot `event` handler `fn`,
|
||||
removed immediately after it is invoked the
|
||||
first time.
|
||||
|
||||
### Emitter#off(event, fn)
|
||||
|
||||
* Pass `event` and `fn` to remove a listener.
|
||||
* Pass `event` to remove all listeners on that event.
|
||||
* Pass nothing to remove all listeners on all events.
|
||||
|
||||
### Emitter#emit(event, ...)
|
||||
|
||||
Emit an `event` with variable option args.
|
||||
|
||||
### Emitter#listeners(event)
|
||||
|
||||
Return an array of callbacks, or an empty array.
|
||||
|
||||
### Emitter#hasListeners(event)
|
||||
|
||||
Check if this emitter has `event` handlers.
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
179
node_modules/@socket.io/component-emitter/lib/cjs/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,179 @@
|
||||
/**
|
||||
* An events map is an interface that maps event names to their value, which
|
||||
* represents the type of the `on` listener.
|
||||
*/
|
||||
export interface EventsMap {
|
||||
[event: string]: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* The default events map, used if no EventsMap is given. Using this EventsMap
|
||||
* is equivalent to accepting all event names, and any data.
|
||||
*/
|
||||
export interface DefaultEventsMap {
|
||||
[event: string]: (...args: any[]) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a union type containing all the keys of an event map.
|
||||
*/
|
||||
export type EventNames<Map extends EventsMap> = keyof Map & (string | symbol);
|
||||
|
||||
/** The tuple type representing the parameters of an event listener */
|
||||
export type EventParams<
|
||||
Map extends EventsMap,
|
||||
Ev extends EventNames<Map>
|
||||
> = Parameters<Map[Ev]>;
|
||||
|
||||
/**
|
||||
* The event names that are either in ReservedEvents or in UserEvents
|
||||
*/
|
||||
export type ReservedOrUserEventNames<
|
||||
ReservedEventsMap extends EventsMap,
|
||||
UserEvents extends EventsMap
|
||||
> = EventNames<ReservedEventsMap> | EventNames<UserEvents>;
|
||||
|
||||
/**
|
||||
* Type of a listener of a user event or a reserved event. If `Ev` is in
|
||||
* `ReservedEvents`, the reserved event listener is returned.
|
||||
*/
|
||||
export type ReservedOrUserListener<
|
||||
ReservedEvents extends EventsMap,
|
||||
UserEvents extends EventsMap,
|
||||
Ev extends ReservedOrUserEventNames<ReservedEvents, UserEvents>
|
||||
> = FallbackToUntypedListener<
|
||||
Ev extends EventNames<ReservedEvents>
|
||||
? ReservedEvents[Ev]
|
||||
: Ev extends EventNames<UserEvents>
|
||||
? UserEvents[Ev]
|
||||
: never
|
||||
>;
|
||||
|
||||
/**
|
||||
* Returns an untyped listener type if `T` is `never`; otherwise, returns `T`.
|
||||
*
|
||||
* This is a hack to mitigate https://github.com/socketio/socket.io/issues/3833.
|
||||
* Needed because of https://github.com/microsoft/TypeScript/issues/41778
|
||||
*/
|
||||
type FallbackToUntypedListener<T> = [T] extends [never]
|
||||
? (...args: any[]) => void | Promise<void>
|
||||
: T;
|
||||
|
||||
/**
|
||||
* Strictly typed version of an `EventEmitter`. A `TypedEventEmitter` takes type
|
||||
* parameters for mappings of event names to event data types, and strictly
|
||||
* types method calls to the `EventEmitter` according to these event maps.
|
||||
*
|
||||
* @typeParam ListenEvents - `EventsMap` of user-defined events that can be
|
||||
* listened to with `on` or `once`
|
||||
* @typeParam EmitEvents - `EventsMap` of user-defined events that can be
|
||||
* emitted with `emit`
|
||||
* @typeParam ReservedEvents - `EventsMap` of reserved events, that can be
|
||||
* emitted by socket.io with `emitReserved`, and can be listened to with
|
||||
* `listen`.
|
||||
*/
|
||||
export class Emitter<
|
||||
ListenEvents extends EventsMap,
|
||||
EmitEvents extends EventsMap,
|
||||
ReservedEvents extends EventsMap = {}
|
||||
> {
|
||||
/**
|
||||
* Adds the `listener` function as an event listener for `ev`.
|
||||
*
|
||||
* @param ev Name of the event
|
||||
* @param listener Callback function
|
||||
*/
|
||||
on<Ev extends ReservedOrUserEventNames<ReservedEvents, ListenEvents>>(
|
||||
ev: Ev,
|
||||
listener: ReservedOrUserListener<ReservedEvents, ListenEvents, Ev>
|
||||
): this;
|
||||
|
||||
/**
|
||||
* Adds a one-time `listener` function as an event listener for `ev`.
|
||||
*
|
||||
* @param ev Name of the event
|
||||
* @param listener Callback function
|
||||
*/
|
||||
once<Ev extends ReservedOrUserEventNames<ReservedEvents, ListenEvents>>(
|
||||
ev: Ev,
|
||||
listener: ReservedOrUserListener<ReservedEvents, ListenEvents, Ev>
|
||||
): this;
|
||||
|
||||
/**
|
||||
* Removes the `listener` function as an event listener for `ev`.
|
||||
*
|
||||
* @param ev Name of the event
|
||||
* @param listener Callback function
|
||||
*/
|
||||
off<Ev extends ReservedOrUserEventNames<ReservedEvents, ListenEvents>>(
|
||||
ev?: Ev,
|
||||
listener?: ReservedOrUserListener<ReservedEvents, ListenEvents, Ev>
|
||||
): this;
|
||||
|
||||
/**
|
||||
* Emits an event.
|
||||
*
|
||||
* @param ev Name of the event
|
||||
* @param args Values to send to listeners of this event
|
||||
*/
|
||||
emit<Ev extends EventNames<EmitEvents>>(
|
||||
ev: Ev,
|
||||
...args: EventParams<EmitEvents, Ev>
|
||||
): this;
|
||||
|
||||
/**
|
||||
* Emits a reserved event.
|
||||
*
|
||||
* This method is `protected`, so that only a class extending
|
||||
* `StrictEventEmitter` can emit its own reserved events.
|
||||
*
|
||||
* @param ev Reserved event name
|
||||
* @param args Arguments to emit along with the event
|
||||
*/
|
||||
protected emitReserved<Ev extends EventNames<ReservedEvents>>(
|
||||
ev: Ev,
|
||||
...args: EventParams<ReservedEvents, Ev>
|
||||
): this;
|
||||
|
||||
/**
|
||||
* Returns the listeners listening to an event.
|
||||
*
|
||||
* @param event Event name
|
||||
* @returns Array of listeners subscribed to `event`
|
||||
*/
|
||||
listeners<Ev extends ReservedOrUserEventNames<ReservedEvents, ListenEvents>>(
|
||||
event: Ev
|
||||
): ReservedOrUserListener<ReservedEvents, ListenEvents, Ev>[];
|
||||
|
||||
/**
|
||||
* Returns true if there is a listener for this event.
|
||||
*
|
||||
* @param event Event name
|
||||
* @returns boolean
|
||||
*/
|
||||
hasListeners<
|
||||
Ev extends ReservedOrUserEventNames<ReservedEvents, ListenEvents>
|
||||
>(event: Ev): boolean;
|
||||
|
||||
/**
|
||||
* Removes the `listener` function as an event listener for `ev`.
|
||||
*
|
||||
* @param ev Name of the event
|
||||
* @param listener Callback function
|
||||
*/
|
||||
removeListener<
|
||||
Ev extends ReservedOrUserEventNames<ReservedEvents, ListenEvents>
|
||||
>(
|
||||
ev?: Ev,
|
||||
listener?: ReservedOrUserListener<ReservedEvents, ListenEvents, Ev>
|
||||
): this;
|
||||
|
||||
/**
|
||||
* Removes all `listener` function as an event listener for `ev`.
|
||||
*
|
||||
* @param ev Name of the event
|
||||
*/
|
||||
removeAllListeners<
|
||||
Ev extends ReservedOrUserEventNames<ReservedEvents, ListenEvents>
|
||||
>(ev?: Ev): this;
|
||||
}
|
||||
176
node_modules/@socket.io/component-emitter/lib/cjs/index.js
generated
vendored
Normal file
@@ -0,0 +1,176 @@
|
||||
|
||||
/**
|
||||
* Expose `Emitter`.
|
||||
*/
|
||||
|
||||
exports.Emitter = Emitter;
|
||||
|
||||
/**
|
||||
* Initialize a new `Emitter`.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function Emitter(obj) {
|
||||
if (obj) return mixin(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mixin the emitter properties.
|
||||
*
|
||||
* @param {Object} obj
|
||||
* @return {Object}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function mixin(obj) {
|
||||
for (var key in Emitter.prototype) {
|
||||
obj[key] = Emitter.prototype[key];
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Listen on the given `event` with `fn`.
|
||||
*
|
||||
* @param {String} event
|
||||
* @param {Function} fn
|
||||
* @return {Emitter}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Emitter.prototype.on =
|
||||
Emitter.prototype.addEventListener = function(event, fn){
|
||||
this._callbacks = this._callbacks || {};
|
||||
(this._callbacks['$' + event] = this._callbacks['$' + event] || [])
|
||||
.push(fn);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds an `event` listener that will be invoked a single
|
||||
* time then automatically removed.
|
||||
*
|
||||
* @param {String} event
|
||||
* @param {Function} fn
|
||||
* @return {Emitter}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Emitter.prototype.once = function(event, fn){
|
||||
function on() {
|
||||
this.off(event, on);
|
||||
fn.apply(this, arguments);
|
||||
}
|
||||
|
||||
on.fn = fn;
|
||||
this.on(event, on);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove the given callback for `event` or all
|
||||
* registered callbacks.
|
||||
*
|
||||
* @param {String} event
|
||||
* @param {Function} fn
|
||||
* @return {Emitter}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Emitter.prototype.off =
|
||||
Emitter.prototype.removeListener =
|
||||
Emitter.prototype.removeAllListeners =
|
||||
Emitter.prototype.removeEventListener = function(event, fn){
|
||||
this._callbacks = this._callbacks || {};
|
||||
|
||||
// all
|
||||
if (0 == arguments.length) {
|
||||
this._callbacks = {};
|
||||
return this;
|
||||
}
|
||||
|
||||
// specific event
|
||||
var callbacks = this._callbacks['$' + event];
|
||||
if (!callbacks) return this;
|
||||
|
||||
// remove all handlers
|
||||
if (1 == arguments.length) {
|
||||
delete this._callbacks['$' + event];
|
||||
return this;
|
||||
}
|
||||
|
||||
// remove specific handler
|
||||
var cb;
|
||||
for (var i = 0; i < callbacks.length; i++) {
|
||||
cb = callbacks[i];
|
||||
if (cb === fn || cb.fn === fn) {
|
||||
callbacks.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove event specific arrays for event types that no
|
||||
// one is subscribed for to avoid memory leak.
|
||||
if (callbacks.length === 0) {
|
||||
delete this._callbacks['$' + event];
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Emit `event` with the given args.
|
||||
*
|
||||
* @param {String} event
|
||||
* @param {Mixed} ...
|
||||
* @return {Emitter}
|
||||
*/
|
||||
|
||||
Emitter.prototype.emit = function(event){
|
||||
this._callbacks = this._callbacks || {};
|
||||
|
||||
var args = new Array(arguments.length - 1)
|
||||
, callbacks = this._callbacks['$' + event];
|
||||
|
||||
for (var i = 1; i < arguments.length; i++) {
|
||||
args[i - 1] = arguments[i];
|
||||
}
|
||||
|
||||
if (callbacks) {
|
||||
callbacks = callbacks.slice(0);
|
||||
for (var i = 0, len = callbacks.length; i < len; ++i) {
|
||||
callbacks[i].apply(this, args);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
// alias used for reserved events (protected method)
|
||||
Emitter.prototype.emitReserved = Emitter.prototype.emit;
|
||||
|
||||
/**
|
||||
* Return array of callbacks for `event`.
|
||||
*
|
||||
* @param {String} event
|
||||
* @return {Array}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Emitter.prototype.listeners = function(event){
|
||||
this._callbacks = this._callbacks || {};
|
||||
return this._callbacks['$' + event] || [];
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if this emitter has `event` handlers.
|
||||
*
|
||||
* @param {String} event
|
||||
* @return {Boolean}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Emitter.prototype.hasListeners = function(event){
|
||||
return !! this.listeners(event).length;
|
||||
};
|
||||
4
node_modules/@socket.io/component-emitter/lib/cjs/package.json
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"name": "@socket.io/component-emitter",
|
||||
"type": "commonjs"
|
||||
}
|
||||
179
node_modules/@socket.io/component-emitter/lib/esm/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,179 @@
|
||||
/**
|
||||
* An events map is an interface that maps event names to their value, which
|
||||
* represents the type of the `on` listener.
|
||||
*/
|
||||
export interface EventsMap {
|
||||
[event: string]: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* The default events map, used if no EventsMap is given. Using this EventsMap
|
||||
* is equivalent to accepting all event names, and any data.
|
||||
*/
|
||||
export interface DefaultEventsMap {
|
||||
[event: string]: (...args: any[]) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a union type containing all the keys of an event map.
|
||||
*/
|
||||
export type EventNames<Map extends EventsMap> = keyof Map & (string | symbol);
|
||||
|
||||
/** The tuple type representing the parameters of an event listener */
|
||||
export type EventParams<
|
||||
Map extends EventsMap,
|
||||
Ev extends EventNames<Map>
|
||||
> = Parameters<Map[Ev]>;
|
||||
|
||||
/**
|
||||
* The event names that are either in ReservedEvents or in UserEvents
|
||||
*/
|
||||
export type ReservedOrUserEventNames<
|
||||
ReservedEventsMap extends EventsMap,
|
||||
UserEvents extends EventsMap
|
||||
> = EventNames<ReservedEventsMap> | EventNames<UserEvents>;
|
||||
|
||||
/**
|
||||
* Type of a listener of a user event or a reserved event. If `Ev` is in
|
||||
* `ReservedEvents`, the reserved event listener is returned.
|
||||
*/
|
||||
export type ReservedOrUserListener<
|
||||
ReservedEvents extends EventsMap,
|
||||
UserEvents extends EventsMap,
|
||||
Ev extends ReservedOrUserEventNames<ReservedEvents, UserEvents>
|
||||
> = FallbackToUntypedListener<
|
||||
Ev extends EventNames<ReservedEvents>
|
||||
? ReservedEvents[Ev]
|
||||
: Ev extends EventNames<UserEvents>
|
||||
? UserEvents[Ev]
|
||||
: never
|
||||
>;
|
||||
|
||||
/**
|
||||
* Returns an untyped listener type if `T` is `never`; otherwise, returns `T`.
|
||||
*
|
||||
* This is a hack to mitigate https://github.com/socketio/socket.io/issues/3833.
|
||||
* Needed because of https://github.com/microsoft/TypeScript/issues/41778
|
||||
*/
|
||||
type FallbackToUntypedListener<T> = [T] extends [never]
|
||||
? (...args: any[]) => void | Promise<void>
|
||||
: T;
|
||||
|
||||
/**
|
||||
* Strictly typed version of an `EventEmitter`. A `TypedEventEmitter` takes type
|
||||
* parameters for mappings of event names to event data types, and strictly
|
||||
* types method calls to the `EventEmitter` according to these event maps.
|
||||
*
|
||||
* @typeParam ListenEvents - `EventsMap` of user-defined events that can be
|
||||
* listened to with `on` or `once`
|
||||
* @typeParam EmitEvents - `EventsMap` of user-defined events that can be
|
||||
* emitted with `emit`
|
||||
* @typeParam ReservedEvents - `EventsMap` of reserved events, that can be
|
||||
* emitted by socket.io with `emitReserved`, and can be listened to with
|
||||
* `listen`.
|
||||
*/
|
||||
export class Emitter<
|
||||
ListenEvents extends EventsMap,
|
||||
EmitEvents extends EventsMap,
|
||||
ReservedEvents extends EventsMap = {}
|
||||
> {
|
||||
/**
|
||||
* Adds the `listener` function as an event listener for `ev`.
|
||||
*
|
||||
* @param ev Name of the event
|
||||
* @param listener Callback function
|
||||
*/
|
||||
on<Ev extends ReservedOrUserEventNames<ReservedEvents, ListenEvents>>(
|
||||
ev: Ev,
|
||||
listener: ReservedOrUserListener<ReservedEvents, ListenEvents, Ev>
|
||||
): this;
|
||||
|
||||
/**
|
||||
* Adds a one-time `listener` function as an event listener for `ev`.
|
||||
*
|
||||
* @param ev Name of the event
|
||||
* @param listener Callback function
|
||||
*/
|
||||
once<Ev extends ReservedOrUserEventNames<ReservedEvents, ListenEvents>>(
|
||||
ev: Ev,
|
||||
listener: ReservedOrUserListener<ReservedEvents, ListenEvents, Ev>
|
||||
): this;
|
||||
|
||||
/**
|
||||
* Removes the `listener` function as an event listener for `ev`.
|
||||
*
|
||||
* @param ev Name of the event
|
||||
* @param listener Callback function
|
||||
*/
|
||||
off<Ev extends ReservedOrUserEventNames<ReservedEvents, ListenEvents>>(
|
||||
ev?: Ev,
|
||||
listener?: ReservedOrUserListener<ReservedEvents, ListenEvents, Ev>
|
||||
): this;
|
||||
|
||||
/**
|
||||
* Emits an event.
|
||||
*
|
||||
* @param ev Name of the event
|
||||
* @param args Values to send to listeners of this event
|
||||
*/
|
||||
emit<Ev extends EventNames<EmitEvents>>(
|
||||
ev: Ev,
|
||||
...args: EventParams<EmitEvents, Ev>
|
||||
): this;
|
||||
|
||||
/**
|
||||
* Emits a reserved event.
|
||||
*
|
||||
* This method is `protected`, so that only a class extending
|
||||
* `StrictEventEmitter` can emit its own reserved events.
|
||||
*
|
||||
* @param ev Reserved event name
|
||||
* @param args Arguments to emit along with the event
|
||||
*/
|
||||
protected emitReserved<Ev extends EventNames<ReservedEvents>>(
|
||||
ev: Ev,
|
||||
...args: EventParams<ReservedEvents, Ev>
|
||||
): this;
|
||||
|
||||
/**
|
||||
* Returns the listeners listening to an event.
|
||||
*
|
||||
* @param event Event name
|
||||
* @returns Array of listeners subscribed to `event`
|
||||
*/
|
||||
listeners<Ev extends ReservedOrUserEventNames<ReservedEvents, ListenEvents>>(
|
||||
event: Ev
|
||||
): ReservedOrUserListener<ReservedEvents, ListenEvents, Ev>[];
|
||||
|
||||
/**
|
||||
* Returns true if there is a listener for this event.
|
||||
*
|
||||
* @param event Event name
|
||||
* @returns boolean
|
||||
*/
|
||||
hasListeners<
|
||||
Ev extends ReservedOrUserEventNames<ReservedEvents, ListenEvents>
|
||||
>(event: Ev): boolean;
|
||||
|
||||
/**
|
||||
* Removes the `listener` function as an event listener for `ev`.
|
||||
*
|
||||
* @param ev Name of the event
|
||||
* @param listener Callback function
|
||||
*/
|
||||
removeListener<
|
||||
Ev extends ReservedOrUserEventNames<ReservedEvents, ListenEvents>
|
||||
>(
|
||||
ev?: Ev,
|
||||
listener?: ReservedOrUserListener<ReservedEvents, ListenEvents, Ev>
|
||||
): this;
|
||||
|
||||
/**
|
||||
* Removes all `listener` function as an event listener for `ev`.
|
||||
*
|
||||
* @param ev Name of the event
|
||||
*/
|
||||
removeAllListeners<
|
||||
Ev extends ReservedOrUserEventNames<ReservedEvents, ListenEvents>
|
||||
>(ev?: Ev): this;
|
||||
}
|
||||
169
node_modules/@socket.io/component-emitter/lib/esm/index.js
generated
vendored
Normal file
@@ -0,0 +1,169 @@
|
||||
/**
|
||||
* Initialize a new `Emitter`.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
export function Emitter(obj) {
|
||||
if (obj) return mixin(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mixin the emitter properties.
|
||||
*
|
||||
* @param {Object} obj
|
||||
* @return {Object}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function mixin(obj) {
|
||||
for (var key in Emitter.prototype) {
|
||||
obj[key] = Emitter.prototype[key];
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Listen on the given `event` with `fn`.
|
||||
*
|
||||
* @param {String} event
|
||||
* @param {Function} fn
|
||||
* @return {Emitter}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Emitter.prototype.on =
|
||||
Emitter.prototype.addEventListener = function(event, fn){
|
||||
this._callbacks = this._callbacks || {};
|
||||
(this._callbacks['$' + event] = this._callbacks['$' + event] || [])
|
||||
.push(fn);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds an `event` listener that will be invoked a single
|
||||
* time then automatically removed.
|
||||
*
|
||||
* @param {String} event
|
||||
* @param {Function} fn
|
||||
* @return {Emitter}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Emitter.prototype.once = function(event, fn){
|
||||
function on() {
|
||||
this.off(event, on);
|
||||
fn.apply(this, arguments);
|
||||
}
|
||||
|
||||
on.fn = fn;
|
||||
this.on(event, on);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove the given callback for `event` or all
|
||||
* registered callbacks.
|
||||
*
|
||||
* @param {String} event
|
||||
* @param {Function} fn
|
||||
* @return {Emitter}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Emitter.prototype.off =
|
||||
Emitter.prototype.removeListener =
|
||||
Emitter.prototype.removeAllListeners =
|
||||
Emitter.prototype.removeEventListener = function(event, fn){
|
||||
this._callbacks = this._callbacks || {};
|
||||
|
||||
// all
|
||||
if (0 == arguments.length) {
|
||||
this._callbacks = {};
|
||||
return this;
|
||||
}
|
||||
|
||||
// specific event
|
||||
var callbacks = this._callbacks['$' + event];
|
||||
if (!callbacks) return this;
|
||||
|
||||
// remove all handlers
|
||||
if (1 == arguments.length) {
|
||||
delete this._callbacks['$' + event];
|
||||
return this;
|
||||
}
|
||||
|
||||
// remove specific handler
|
||||
var cb;
|
||||
for (var i = 0; i < callbacks.length; i++) {
|
||||
cb = callbacks[i];
|
||||
if (cb === fn || cb.fn === fn) {
|
||||
callbacks.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove event specific arrays for event types that no
|
||||
// one is subscribed for to avoid memory leak.
|
||||
if (callbacks.length === 0) {
|
||||
delete this._callbacks['$' + event];
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Emit `event` with the given args.
|
||||
*
|
||||
* @param {String} event
|
||||
* @param {Mixed} ...
|
||||
* @return {Emitter}
|
||||
*/
|
||||
|
||||
Emitter.prototype.emit = function(event){
|
||||
this._callbacks = this._callbacks || {};
|
||||
|
||||
var args = new Array(arguments.length - 1)
|
||||
, callbacks = this._callbacks['$' + event];
|
||||
|
||||
for (var i = 1; i < arguments.length; i++) {
|
||||
args[i - 1] = arguments[i];
|
||||
}
|
||||
|
||||
if (callbacks) {
|
||||
callbacks = callbacks.slice(0);
|
||||
for (var i = 0, len = callbacks.length; i < len; ++i) {
|
||||
callbacks[i].apply(this, args);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
// alias used for reserved events (protected method)
|
||||
Emitter.prototype.emitReserved = Emitter.prototype.emit;
|
||||
|
||||
/**
|
||||
* Return array of callbacks for `event`.
|
||||
*
|
||||
* @param {String} event
|
||||
* @return {Array}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Emitter.prototype.listeners = function(event){
|
||||
this._callbacks = this._callbacks || {};
|
||||
return this._callbacks['$' + event] || [];
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if this emitter has `event` handlers.
|
||||
*
|
||||
* @param {String} event
|
||||
* @return {Boolean}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Emitter.prototype.hasListeners = function(event){
|
||||
return !! this.listeners(event).length;
|
||||
};
|
||||
4
node_modules/@socket.io/component-emitter/lib/esm/package.json
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"name": "@socket.io/component-emitter",
|
||||
"type": "module"
|
||||
}
|
||||
28
node_modules/@socket.io/component-emitter/package.json
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "@socket.io/component-emitter",
|
||||
"description": "Event emitter",
|
||||
"version": "3.1.2",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"mocha": "*",
|
||||
"should": "*"
|
||||
},
|
||||
"component": {
|
||||
"scripts": {
|
||||
"emitter/index.js": "index.js"
|
||||
}
|
||||
},
|
||||
"main": "./lib/cjs/index.js",
|
||||
"module": "./lib/esm/index.js",
|
||||
"types": "./lib/cjs/index.d.ts",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/socketio/emitter.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "make test"
|
||||
},
|
||||
"files": [
|
||||
"lib/"
|
||||
]
|
||||
}
|
||||
21
node_modules/@types/cors/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE
|
||||
75
node_modules/@types/cors/README.md
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
# Installation
|
||||
> `npm install --save @types/cors`
|
||||
|
||||
# Summary
|
||||
This package contains type definitions for cors (https://github.com/expressjs/cors/).
|
||||
|
||||
# Details
|
||||
Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/cors.
|
||||
## [index.d.ts](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/cors/index.d.ts)
|
||||
````ts
|
||||
/// <reference types="node" />
|
||||
|
||||
import { IncomingHttpHeaders } from "http";
|
||||
|
||||
type StaticOrigin = boolean | string | RegExp | Array<boolean | string | RegExp>;
|
||||
|
||||
type CustomOrigin = (
|
||||
requestOrigin: string | undefined,
|
||||
callback: (err: Error | null, origin?: StaticOrigin) => void,
|
||||
) => void;
|
||||
|
||||
declare namespace e {
|
||||
interface CorsRequest {
|
||||
method?: string | undefined;
|
||||
headers: IncomingHttpHeaders;
|
||||
}
|
||||
interface CorsOptions {
|
||||
/**
|
||||
* @default '*'
|
||||
*/
|
||||
origin?: StaticOrigin | CustomOrigin | undefined;
|
||||
/**
|
||||
* @default 'GET,HEAD,PUT,PATCH,POST,DELETE'
|
||||
*/
|
||||
methods?: string | string[] | undefined;
|
||||
allowedHeaders?: string | string[] | undefined;
|
||||
exposedHeaders?: string | string[] | undefined;
|
||||
credentials?: boolean | undefined;
|
||||
maxAge?: number | undefined;
|
||||
/**
|
||||
* @default false
|
||||
*/
|
||||
preflightContinue?: boolean | undefined;
|
||||
/**
|
||||
* @default 204
|
||||
*/
|
||||
optionsSuccessStatus?: number | undefined;
|
||||
}
|
||||
type CorsOptionsDelegate<T extends CorsRequest = CorsRequest> = (
|
||||
req: T,
|
||||
callback: (err: Error | null, options?: CorsOptions) => void,
|
||||
) => void;
|
||||
}
|
||||
|
||||
declare function e<T extends e.CorsRequest = e.CorsRequest>(
|
||||
options?: e.CorsOptions | e.CorsOptionsDelegate<T>,
|
||||
): (
|
||||
req: T,
|
||||
res: {
|
||||
statusCode?: number | undefined;
|
||||
setHeader(key: string, value: string): any;
|
||||
end(): any;
|
||||
},
|
||||
next: (err?: any) => any,
|
||||
) => void;
|
||||
export = e;
|
||||
|
||||
````
|
||||
|
||||
### Additional Details
|
||||
* Last updated: Sat, 07 Jun 2025 02:15:25 GMT
|
||||
* Dependencies: [@types/node](https://npmjs.com/package/@types/node)
|
||||
|
||||
# Credits
|
||||
These definitions were written by [Alan Plum](https://github.com/pluma), [Gaurav Sharma](https://github.com/gtpan77), and [Sebastian Beltran](https://github.com/bjohansebas).
|
||||
56
node_modules/@types/cors/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
/// <reference types="node" />
|
||||
|
||||
import { IncomingHttpHeaders } from "http";
|
||||
|
||||
type StaticOrigin = boolean | string | RegExp | Array<boolean | string | RegExp>;
|
||||
|
||||
type CustomOrigin = (
|
||||
requestOrigin: string | undefined,
|
||||
callback: (err: Error | null, origin?: StaticOrigin) => void,
|
||||
) => void;
|
||||
|
||||
declare namespace e {
|
||||
interface CorsRequest {
|
||||
method?: string | undefined;
|
||||
headers: IncomingHttpHeaders;
|
||||
}
|
||||
interface CorsOptions {
|
||||
/**
|
||||
* @default '*'
|
||||
*/
|
||||
origin?: StaticOrigin | CustomOrigin | undefined;
|
||||
/**
|
||||
* @default 'GET,HEAD,PUT,PATCH,POST,DELETE'
|
||||
*/
|
||||
methods?: string | string[] | undefined;
|
||||
allowedHeaders?: string | string[] | undefined;
|
||||
exposedHeaders?: string | string[] | undefined;
|
||||
credentials?: boolean | undefined;
|
||||
maxAge?: number | undefined;
|
||||
/**
|
||||
* @default false
|
||||
*/
|
||||
preflightContinue?: boolean | undefined;
|
||||
/**
|
||||
* @default 204
|
||||
*/
|
||||
optionsSuccessStatus?: number | undefined;
|
||||
}
|
||||
type CorsOptionsDelegate<T extends CorsRequest = CorsRequest> = (
|
||||
req: T,
|
||||
callback: (err: Error | null, options?: CorsOptions) => void,
|
||||
) => void;
|
||||
}
|
||||
|
||||
declare function e<T extends e.CorsRequest = e.CorsRequest>(
|
||||
options?: e.CorsOptions | e.CorsOptionsDelegate<T>,
|
||||
): (
|
||||
req: T,
|
||||
res: {
|
||||
statusCode?: number | undefined;
|
||||
setHeader(key: string, value: string): any;
|
||||
end(): any;
|
||||
},
|
||||
next: (err?: any) => any,
|
||||
) => void;
|
||||
export = e;
|
||||
38
node_modules/@types/cors/package.json
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"name": "@types/cors",
|
||||
"version": "2.8.19",
|
||||
"description": "TypeScript definitions for cors",
|
||||
"homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/cors",
|
||||
"license": "MIT",
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Alan Plum",
|
||||
"githubUsername": "pluma",
|
||||
"url": "https://github.com/pluma"
|
||||
},
|
||||
{
|
||||
"name": "Gaurav Sharma",
|
||||
"githubUsername": "gtpan77",
|
||||
"url": "https://github.com/gtpan77"
|
||||
},
|
||||
{
|
||||
"name": "Sebastian Beltran",
|
||||
"githubUsername": "bjohansebas",
|
||||
"url": "https://github.com/bjohansebas"
|
||||
}
|
||||
],
|
||||
"main": "",
|
||||
"types": "index.d.ts",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git",
|
||||
"directory": "types/cors"
|
||||
},
|
||||
"scripts": {},
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
},
|
||||
"peerDependencies": {},
|
||||
"typesPublisherContentHash": "a090e558c5f443573318c2955deecddc840bd8dfaac7cdedf31c7f6ede8d0b47",
|
||||
"typeScriptVersion": "5.1"
|
||||
}
|
||||
21
node_modules/@types/node/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) Microsoft Corporation.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE
|
||||
15
node_modules/@types/node/README.md
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
# Installation
|
||||
> `npm install --save @types/node`
|
||||
|
||||
# Summary
|
||||
This package contains type definitions for node (https://nodejs.org/).
|
||||
|
||||
# Details
|
||||
Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node.
|
||||
|
||||
### Additional Details
|
||||
* Last updated: Thu, 18 Sep 2025 00:04:03 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), [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).
|
||||
1056
node_modules/@types/node/assert.d.ts
generated
vendored
Normal file
8
node_modules/@types/node/assert/strict.d.ts
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
declare module "assert/strict" {
|
||||
import { strict } from "node:assert";
|
||||
export = strict;
|
||||
}
|
||||
declare module "node:assert/strict" {
|
||||
import { strict } from "node:assert";
|
||||
export = strict;
|
||||
}
|
||||
623
node_modules/@types/node/async_hooks.d.ts
generated
vendored
Normal file
@@ -0,0 +1,623 @@
|
||||
/**
|
||||
* 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-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:
|
||||
*
|
||||
* ```js
|
||||
* import async_hooks from 'node:async_hooks';
|
||||
* ```
|
||||
* @experimental
|
||||
* @see [source](https://github.com/nodejs/node/blob/v24.x/lib/async_hooks.js)
|
||||
*/
|
||||
declare module "async_hooks" {
|
||||
/**
|
||||
* ```js
|
||||
* import { executionAsyncId } from 'node:async_hooks';
|
||||
* import fs from 'node:fs';
|
||||
*
|
||||
* console.log(executionAsyncId()); // 1 - bootstrap
|
||||
* const path = '.';
|
||||
* fs.open(path, 'r', (err, fd) => {
|
||||
* console.log(executionAsyncId()); // 6 - open()
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* The ID returned from `executionAsyncId()` is related to execution timing, not
|
||||
* causality (which is covered by `triggerAsyncId()`):
|
||||
*
|
||||
* ```js
|
||||
* const server = net.createServer((conn) => {
|
||||
* // Returns the ID of the server, not of the new connection, because the
|
||||
* // callback runs in the execution scope of the server's MakeCallback().
|
||||
* async_hooks.executionAsyncId();
|
||||
*
|
||||
* }).listen(port, () => {
|
||||
* // Returns the ID of a TickObject (process.nextTick()) because all
|
||||
* // callbacks passed to .listen() are wrapped in a nextTick().
|
||||
* async_hooks.executionAsyncId();
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* Promise contexts may not get precise `executionAsyncIds` by default.
|
||||
* 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.
|
||||
*/
|
||||
function executionAsyncId(): number;
|
||||
/**
|
||||
* Resource objects returned by `executionAsyncResource()` are most often internal
|
||||
* Node.js handle objects with undocumented APIs. Using any functions or properties
|
||||
* on the object is likely to crash your application and should be avoided.
|
||||
*
|
||||
* Using `executionAsyncResource()` in the top-level execution context will
|
||||
* return an empty object as there is no handle or request object to use,
|
||||
* but having an object representing the top-level can be helpful.
|
||||
*
|
||||
* ```js
|
||||
* import { open } from 'node:fs';
|
||||
* import { executionAsyncId, executionAsyncResource } from 'node:async_hooks';
|
||||
*
|
||||
* console.log(executionAsyncId(), executionAsyncResource()); // 1 {}
|
||||
* open(new URL(import.meta.url), 'r', (err, fd) => {
|
||||
* console.log(executionAsyncId(), executionAsyncResource()); // 7 FSReqWrap
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* This can be used to implement continuation local storage without the
|
||||
* use of a tracking `Map` to store the metadata:
|
||||
*
|
||||
* ```js
|
||||
* import { createServer } from 'node:http';
|
||||
* import {
|
||||
* executionAsyncId,
|
||||
* executionAsyncResource,
|
||||
* createHook,
|
||||
* } from 'node:async_hooks';
|
||||
* const sym = Symbol('state'); // Private symbol to avoid pollution
|
||||
*
|
||||
* createHook({
|
||||
* init(asyncId, type, triggerAsyncId, resource) {
|
||||
* const cr = executionAsyncResource();
|
||||
* if (cr) {
|
||||
* resource[sym] = cr[sym];
|
||||
* }
|
||||
* },
|
||||
* }).enable();
|
||||
*
|
||||
* const server = createServer((req, res) => {
|
||||
* executionAsyncResource()[sym] = { state: req.url };
|
||||
* setTimeout(function() {
|
||||
* res.end(JSON.stringify(executionAsyncResource()[sym]));
|
||||
* }, 100);
|
||||
* }).listen(3000);
|
||||
* ```
|
||||
* @since v13.9.0, v12.17.0
|
||||
* @return The resource representing the current execution. Useful to store data within the resource.
|
||||
*/
|
||||
function executionAsyncResource(): object;
|
||||
/**
|
||||
* ```js
|
||||
* const server = net.createServer((conn) => {
|
||||
* // The resource that caused (or triggered) this callback to be called
|
||||
* // was that of the new connection. Thus the return value of triggerAsyncId()
|
||||
* // is the asyncId of "conn".
|
||||
* async_hooks.triggerAsyncId();
|
||||
*
|
||||
* }).listen(port, () => {
|
||||
* // Even though all callbacks passed to .listen() are wrapped in a nextTick()
|
||||
* // the callback itself exists because the call to the server's .listen()
|
||||
* // was made. So the return value would be the ID of the server.
|
||||
* async_hooks.triggerAsyncId();
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* Promise contexts may not get valid `triggerAsyncId`s by default. See
|
||||
* 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;
|
||||
interface HookCallbacks {
|
||||
/**
|
||||
* Called when a class is constructed that has the possibility to emit an asynchronous event.
|
||||
* @param asyncId A unique ID for the async resource
|
||||
* @param type The type of the async resource
|
||||
* @param triggerAsyncId The unique ID of the async resource in whose execution context this async resource was created
|
||||
* @param resource Reference to the resource representing the async operation, needs to be released during destroy
|
||||
*/
|
||||
init?(asyncId: number, type: string, triggerAsyncId: number, resource: object): void;
|
||||
/**
|
||||
* When an asynchronous operation is initiated or completes a callback is called to notify the user.
|
||||
* The before callback is called just before said callback is executed.
|
||||
* @param asyncId the unique identifier assigned to the resource about to execute the callback.
|
||||
*/
|
||||
before?(asyncId: number): void;
|
||||
/**
|
||||
* Called immediately after the callback specified in `before` is completed.
|
||||
*
|
||||
* If an uncaught exception occurs during execution of the callback, then `after` will run after the `'uncaughtException'` event is emitted or a `domain`'s handler runs.
|
||||
* @param asyncId the unique identifier assigned to the resource which has executed the callback.
|
||||
*/
|
||||
after?(asyncId: number): void;
|
||||
/**
|
||||
* Called when a promise has resolve() called. This may not be in the same execution id
|
||||
* as the promise itself.
|
||||
* @param asyncId the unique id for the promise that was resolve()d.
|
||||
*/
|
||||
promiseResolve?(asyncId: number): void;
|
||||
/**
|
||||
* Called after the resource corresponding to asyncId is destroyed
|
||||
* @param asyncId a unique ID for the async resource
|
||||
*/
|
||||
destroy?(asyncId: number): void;
|
||||
}
|
||||
interface AsyncHook {
|
||||
/**
|
||||
* Enable the callbacks for a given AsyncHook instance. If no callbacks are provided enabling is a noop.
|
||||
*/
|
||||
enable(): this;
|
||||
/**
|
||||
* Disable the callbacks for a given AsyncHook instance from the global pool of AsyncHook callbacks to be executed. Once a hook has been disabled it will not be called again until enabled.
|
||||
*/
|
||||
disable(): this;
|
||||
}
|
||||
/**
|
||||
* Registers functions to be called for different lifetime events of each async
|
||||
* operation.
|
||||
*
|
||||
* The callbacks `init()`/`before()`/`after()`/`destroy()` are called for the
|
||||
* respective asynchronous event during a resource's lifetime.
|
||||
*
|
||||
* All callbacks are optional. For example, if only resource cleanup needs to
|
||||
* be tracked, then only the `destroy` callback needs to be passed. The
|
||||
* specifics of all functions that can be passed to `callbacks` is in the `Hook Callbacks` section.
|
||||
*
|
||||
* ```js
|
||||
* import { createHook } from 'node:async_hooks';
|
||||
*
|
||||
* const asyncHook = createHook({
|
||||
* init(asyncId, type, triggerAsyncId, resource) { },
|
||||
* destroy(asyncId) { },
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* The callbacks will be inherited via the prototype chain:
|
||||
*
|
||||
* ```js
|
||||
* class MyAsyncCallbacks {
|
||||
* init(asyncId, type, triggerAsyncId, resource) { }
|
||||
* destroy(asyncId) {}
|
||||
* }
|
||||
*
|
||||
* class MyAddedCallbacks extends MyAsyncCallbacks {
|
||||
* before(asyncId) { }
|
||||
* after(asyncId) { }
|
||||
* }
|
||||
*
|
||||
* const asyncHook = async_hooks.createHook(new MyAddedCallbacks());
|
||||
* ```
|
||||
*
|
||||
* Because promises are asynchronous resources whose lifecycle is tracked
|
||||
* via the async hooks mechanism, the `init()`, `before()`, `after()`, and`destroy()` callbacks _must not_ be async functions that return promises.
|
||||
* @since v8.1.0
|
||||
* @param callbacks The `Hook Callbacks` to register
|
||||
* @return Instance used for disabling and enabling hooks
|
||||
*/
|
||||
function createHook(callbacks: HookCallbacks): AsyncHook;
|
||||
interface AsyncResourceOptions {
|
||||
/**
|
||||
* The ID of the execution context that created this async event.
|
||||
* @default executionAsyncId()
|
||||
*/
|
||||
triggerAsyncId?: number | undefined;
|
||||
/**
|
||||
* Disables automatic `emitDestroy` when the object is garbage collected.
|
||||
* This usually does not need to be set (even if `emitDestroy` is called
|
||||
* manually), unless the resource's `asyncId` is retrieved and the
|
||||
* sensitive API's `emitDestroy` is called with it.
|
||||
* @default false
|
||||
*/
|
||||
requireManualDestroy?: boolean | undefined;
|
||||
}
|
||||
/**
|
||||
* The class `AsyncResource` is designed to be extended by the embedder's async
|
||||
* resources. Using this, users can easily trigger the lifetime events of their
|
||||
* own resources.
|
||||
*
|
||||
* The `init` hook will trigger when an `AsyncResource` is instantiated.
|
||||
*
|
||||
* The following is an overview of the `AsyncResource` API.
|
||||
*
|
||||
* ```js
|
||||
* import { AsyncResource, executionAsyncId } from 'node:async_hooks';
|
||||
*
|
||||
* // AsyncResource() is meant to be extended. Instantiating a
|
||||
* // new AsyncResource() also triggers init. If triggerAsyncId is omitted then
|
||||
* // async_hook.executionAsyncId() is used.
|
||||
* const asyncResource = new AsyncResource(
|
||||
* type, { triggerAsyncId: executionAsyncId(), requireManualDestroy: false },
|
||||
* );
|
||||
*
|
||||
* // Run a function in the execution context of the resource. This will
|
||||
* // * establish the context of the resource
|
||||
* // * trigger the AsyncHooks before callbacks
|
||||
* // * call the provided function `fn` with the supplied arguments
|
||||
* // * trigger the AsyncHooks after callbacks
|
||||
* // * restore the original execution context
|
||||
* asyncResource.runInAsyncScope(fn, thisArg, ...args);
|
||||
*
|
||||
* // Call AsyncHooks destroy callbacks.
|
||||
* asyncResource.emitDestroy();
|
||||
*
|
||||
* // Return the unique ID assigned to the AsyncResource instance.
|
||||
* asyncResource.asyncId();
|
||||
*
|
||||
* // Return the trigger ID for the AsyncResource instance.
|
||||
* asyncResource.triggerAsyncId();
|
||||
* ```
|
||||
*/
|
||||
class AsyncResource {
|
||||
/**
|
||||
* AsyncResource() is meant to be extended. Instantiating a
|
||||
* new AsyncResource() also triggers init. If triggerAsyncId is omitted then
|
||||
* async_hook.executionAsyncId() is used.
|
||||
* @param type The type of async event.
|
||||
* @param triggerAsyncId The ID of the execution context that created
|
||||
* this async event (default: `executionAsyncId()`), or an
|
||||
* AsyncResourceOptions object (since v9.3.0)
|
||||
*/
|
||||
constructor(type: string, triggerAsyncId?: number | AsyncResourceOptions);
|
||||
/**
|
||||
* Binds the given function to the current execution context.
|
||||
* @since v14.8.0, v12.19.0
|
||||
* @param fn The function to bind to the current execution context.
|
||||
* @param type An optional name to associate with the underlying `AsyncResource`.
|
||||
*/
|
||||
static bind<Func extends (this: ThisArg, ...args: any[]) => any, ThisArg>(
|
||||
fn: Func,
|
||||
type?: string,
|
||||
thisArg?: ThisArg,
|
||||
): Func;
|
||||
/**
|
||||
* Binds the given function to execute to this `AsyncResource`'s scope.
|
||||
* @since v14.8.0, v12.19.0
|
||||
* @param fn The function to bind to the current `AsyncResource`.
|
||||
*/
|
||||
bind<Func extends (...args: any[]) => any>(fn: Func): Func;
|
||||
/**
|
||||
* Call the provided function with the provided arguments in the execution context
|
||||
* of the async resource. This will establish the context, trigger the AsyncHooks
|
||||
* before callbacks, call the function, trigger the AsyncHooks after callbacks, and
|
||||
* then restore the original execution context.
|
||||
* @since v9.6.0
|
||||
* @param fn The function to call in the execution context of this async resource.
|
||||
* @param thisArg The receiver to be used for the function call.
|
||||
* @param args Optional arguments to pass to the function.
|
||||
*/
|
||||
runInAsyncScope<This, Result>(
|
||||
fn: (this: This, ...args: any[]) => Result,
|
||||
thisArg?: This,
|
||||
...args: any[]
|
||||
): Result;
|
||||
/**
|
||||
* Call all `destroy` hooks. This should only ever be called once. An error will
|
||||
* be thrown if it is called more than once. This **must** be manually called. If
|
||||
* the resource is left to be collected by the GC then the `destroy` hooks will
|
||||
* never be called.
|
||||
* @return A reference to `asyncResource`.
|
||||
*/
|
||||
emitDestroy(): this;
|
||||
/**
|
||||
* @return The unique `asyncId` assigned to the resource.
|
||||
*/
|
||||
asyncId(): number;
|
||||
/**
|
||||
* @return The same `triggerAsyncId` that is passed to the `AsyncResource` constructor.
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* While you can create your own implementation on top of the `node:async_hooks` module, `AsyncLocalStorage` should be preferred as it is a performant and memory
|
||||
* safe implementation that involves significant optimizations that are non-obvious
|
||||
* to implement.
|
||||
*
|
||||
* The following example uses `AsyncLocalStorage` to build a simple logger
|
||||
* that assigns IDs to incoming HTTP requests and includes them in messages
|
||||
* logged within each request.
|
||||
*
|
||||
* ```js
|
||||
* import http from 'node:http';
|
||||
* import { AsyncLocalStorage } from 'node:async_hooks';
|
||||
*
|
||||
* const asyncLocalStorage = new AsyncLocalStorage();
|
||||
*
|
||||
* function logWithId(msg) {
|
||||
* const id = asyncLocalStorage.getStore();
|
||||
* console.log(`${id !== undefined ? id : '-'}:`, msg);
|
||||
* }
|
||||
*
|
||||
* let idSeq = 0;
|
||||
* http.createServer((req, res) => {
|
||||
* asyncLocalStorage.run(idSeq++, () => {
|
||||
* logWithId('start');
|
||||
* // Imagine any chain of async operations here
|
||||
* setImmediate(() => {
|
||||
* logWithId('finish');
|
||||
* res.end();
|
||||
* });
|
||||
* });
|
||||
* }).listen(8080);
|
||||
*
|
||||
* http.get('http://localhost:8080');
|
||||
* http.get('http://localhost:8080');
|
||||
* // Prints:
|
||||
* // 0: start
|
||||
* // 0: finish
|
||||
* // 1: start
|
||||
* // 1: finish
|
||||
* ```
|
||||
*
|
||||
* Each instance of `AsyncLocalStorage` maintains an independent storage context.
|
||||
* Multiple instances can safely exist simultaneously without risk of interfering
|
||||
* with each other's data.
|
||||
* @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
|
||||
* @param fn The function to bind to the current execution context.
|
||||
* @return A new function that calls `fn` within the captured execution context.
|
||||
*/
|
||||
static bind<Func extends (...args: any[]) => any>(fn: Func): Func;
|
||||
/**
|
||||
* Captures the current execution context and returns a function that accepts a
|
||||
* function as an argument. Whenever the returned function is called, it
|
||||
* calls the function passed to it within the captured context.
|
||||
*
|
||||
* ```js
|
||||
* const asyncLocalStorage = new AsyncLocalStorage();
|
||||
* const runInAsyncScope = asyncLocalStorage.run(123, () => AsyncLocalStorage.snapshot());
|
||||
* const result = asyncLocalStorage.run(321, () => runInAsyncScope(() => asyncLocalStorage.getStore()));
|
||||
* console.log(result); // returns 123
|
||||
* ```
|
||||
*
|
||||
* AsyncLocalStorage.snapshot() can replace the use of AsyncResource for simple
|
||||
* async context tracking purposes, for example:
|
||||
*
|
||||
* ```js
|
||||
* class Foo {
|
||||
* #runInAsyncScope = AsyncLocalStorage.snapshot();
|
||||
*
|
||||
* get() { return this.#runInAsyncScope(() => asyncLocalStorage.getStore()); }
|
||||
* }
|
||||
*
|
||||
* const foo = asyncLocalStorage.run(123, () => new Foo());
|
||||
* console.log(asyncLocalStorage.run(321, () => foo.get())); // returns 123
|
||||
* ```
|
||||
* @since v19.8.0
|
||||
* @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;
|
||||
/**
|
||||
* Disables the instance of `AsyncLocalStorage`. All subsequent calls
|
||||
* to `asyncLocalStorage.getStore()` will return `undefined` until `asyncLocalStorage.run()` or `asyncLocalStorage.enterWith()` is called again.
|
||||
*
|
||||
* When calling `asyncLocalStorage.disable()`, all current contexts linked to the
|
||||
* instance will be exited.
|
||||
*
|
||||
* Calling `asyncLocalStorage.disable()` is required before the `asyncLocalStorage` can be garbage collected. This does not apply to stores
|
||||
* provided by the `asyncLocalStorage`, as those objects are garbage collected
|
||||
* along with the corresponding async resources.
|
||||
*
|
||||
* Use this method when the `asyncLocalStorage` is not in use anymore
|
||||
* in the current process.
|
||||
* @since v13.10.0, v12.17.0
|
||||
* @experimental
|
||||
*/
|
||||
disable(): void;
|
||||
/**
|
||||
* Returns the current store.
|
||||
* If called outside of an asynchronous context initialized by
|
||||
* calling `asyncLocalStorage.run()` or `asyncLocalStorage.enterWith()`, it
|
||||
* returns `undefined`.
|
||||
* @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.
|
||||
* The store is accessible to any asynchronous operations created within the
|
||||
* callback.
|
||||
*
|
||||
* The optional `args` are passed to the callback function.
|
||||
*
|
||||
* If the callback function throws an error, the error is thrown by `run()` too.
|
||||
* The stacktrace is not impacted by this call and the context is exited.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ```js
|
||||
* const store = { id: 2 };
|
||||
* try {
|
||||
* asyncLocalStorage.run(store, () => {
|
||||
* asyncLocalStorage.getStore(); // Returns the store object
|
||||
* setTimeout(() => {
|
||||
* asyncLocalStorage.getStore(); // Returns the store object
|
||||
* }, 200);
|
||||
* throw new Error();
|
||||
* });
|
||||
* } catch (e) {
|
||||
* asyncLocalStorage.getStore(); // Returns undefined
|
||||
* // The error will be caught here
|
||||
* }
|
||||
* ```
|
||||
* @since v13.10.0, v12.17.0
|
||||
*/
|
||||
run<R>(store: T, callback: () => R): R;
|
||||
run<R, TArgs extends any[]>(store: T, callback: (...args: TArgs) => R, ...args: TArgs): R;
|
||||
/**
|
||||
* Runs a function synchronously outside of a context and returns its
|
||||
* return value. The store is not accessible within the callback function or
|
||||
* the asynchronous operations created within the callback. Any `getStore()` call done within the callback function will always return `undefined`.
|
||||
*
|
||||
* The optional `args` are passed to the callback function.
|
||||
*
|
||||
* If the callback function throws an error, the error is thrown by `exit()` too.
|
||||
* The stacktrace is not impacted by this call and the context is re-entered.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ```js
|
||||
* // Within a call to run
|
||||
* try {
|
||||
* asyncLocalStorage.getStore(); // Returns the store object or value
|
||||
* asyncLocalStorage.exit(() => {
|
||||
* asyncLocalStorage.getStore(); // Returns undefined
|
||||
* throw new Error();
|
||||
* });
|
||||
* } catch (e) {
|
||||
* asyncLocalStorage.getStore(); // Returns the same object or value
|
||||
* // The error will be caught here
|
||||
* }
|
||||
* ```
|
||||
* @since v13.10.0, v12.17.0
|
||||
* @experimental
|
||||
*/
|
||||
exit<R, TArgs extends any[]>(callback: (...args: TArgs) => R, ...args: TArgs): R;
|
||||
/**
|
||||
* Transitions into the context for the remainder of the current
|
||||
* synchronous execution and then persists the store through any following
|
||||
* asynchronous calls.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ```js
|
||||
* const store = { id: 1 };
|
||||
* // Replaces previous store with the given store object
|
||||
* asyncLocalStorage.enterWith(store);
|
||||
* asyncLocalStorage.getStore(); // Returns the store object
|
||||
* someAsyncOperation(() => {
|
||||
* asyncLocalStorage.getStore(); // Returns the same object
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* This transition will continue for the _entire_ synchronous execution.
|
||||
* This means that if, for example, the context is entered within an event
|
||||
* handler subsequent event handlers will also run within that context unless
|
||||
* specifically bound to another context with an `AsyncResource`. That is why `run()` should be preferred over `enterWith()` unless there are strong reasons
|
||||
* to use the latter method.
|
||||
*
|
||||
* ```js
|
||||
* const store = { id: 1 };
|
||||
*
|
||||
* emitter.on('my-event', () => {
|
||||
* asyncLocalStorage.enterWith(store);
|
||||
* });
|
||||
* emitter.on('my-event', () => {
|
||||
* asyncLocalStorage.getStore(); // Returns the same object
|
||||
* });
|
||||
*
|
||||
* asyncLocalStorage.getStore(); // Returns undefined
|
||||
* emitter.emit('my-event');
|
||||
* asyncLocalStorage.getStore(); // Returns the same object
|
||||
* ```
|
||||
* @since v13.11.0, v12.17.0
|
||||
* @experimental
|
||||
*/
|
||||
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";
|
||||
}
|
||||
463
node_modules/@types/node/buffer.buffer.d.ts
generated
vendored
Normal file
@@ -0,0 +1,463 @@
|
||||
declare module "buffer" {
|
||||
type ImplicitArrayBuffer<T extends WithImplicitCoercion<ArrayBufferLike>> = T extends
|
||||
{ valueOf(): infer V extends ArrayBufferLike } ? V : T;
|
||||
global {
|
||||
interface BufferConstructor {
|
||||
// see buffer.d.ts for implementation shared with all TypeScript versions
|
||||
|
||||
/**
|
||||
* 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<ArrayBuffer>;
|
||||
/**
|
||||
* 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<ArrayBuffer>;
|
||||
/**
|
||||
* 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: ArrayLike<number>): Buffer<ArrayBuffer>;
|
||||
/**
|
||||
* 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<TArrayBuffer extends ArrayBufferLike = ArrayBuffer>(arrayBuffer: TArrayBuffer): Buffer<TArrayBuffer>;
|
||||
/**
|
||||
* 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(array: WithImplicitCoercion<ArrayLike<number>>): Buffer<ArrayBuffer>;
|
||||
/**
|
||||
* This creates a view of the `ArrayBuffer` without copying the underlying
|
||||
* memory. For example, when passed a reference to the `.buffer` property of a
|
||||
* `TypedArray` instance, the newly created `Buffer` will share the same
|
||||
* allocated memory as the `TypedArray`'s underlying `ArrayBuffer`.
|
||||
*
|
||||
* ```js
|
||||
* import { Buffer } from 'node:buffer';
|
||||
*
|
||||
* const arr = new Uint16Array(2);
|
||||
*
|
||||
* arr[0] = 5000;
|
||||
* arr[1] = 4000;
|
||||
*
|
||||
* // Shares memory with `arr`.
|
||||
* const buf = Buffer.from(arr.buffer);
|
||||
*
|
||||
* console.log(buf);
|
||||
* // Prints: <Buffer 88 13 a0 0f>
|
||||
*
|
||||
* // Changing the original Uint16Array changes the Buffer also.
|
||||
* arr[1] = 6000;
|
||||
*
|
||||
* console.log(buf);
|
||||
* // Prints: <Buffer 88 13 70 17>
|
||||
* ```
|
||||
*
|
||||
* The optional `byteOffset` and `length` arguments specify a memory range within
|
||||
* the `arrayBuffer` that will be shared by the `Buffer`.
|
||||
*
|
||||
* ```js
|
||||
* import { Buffer } from 'node:buffer';
|
||||
*
|
||||
* const ab = new ArrayBuffer(10);
|
||||
* const buf = Buffer.from(ab, 0, 2);
|
||||
*
|
||||
* console.log(buf.length);
|
||||
* // Prints: 2
|
||||
* ```
|
||||
*
|
||||
* A `TypeError` will be thrown if `arrayBuffer` is not an `ArrayBuffer` or a
|
||||
* `SharedArrayBuffer` or another type appropriate for `Buffer.from()`
|
||||
* variants.
|
||||
*
|
||||
* It is important to remember that a backing `ArrayBuffer` can cover a range
|
||||
* of memory that extends beyond the bounds of a `TypedArray` view. A new
|
||||
* `Buffer` created using the `buffer` property of a `TypedArray` may extend
|
||||
* beyond the range of the `TypedArray`:
|
||||
*
|
||||
* ```js
|
||||
* import { Buffer } from 'node:buffer';
|
||||
*
|
||||
* const arrA = Uint8Array.from([0x63, 0x64, 0x65, 0x66]); // 4 elements
|
||||
* const arrB = new Uint8Array(arrA.buffer, 1, 2); // 2 elements
|
||||
* console.log(arrA.buffer === arrB.buffer); // true
|
||||
*
|
||||
* const buf = Buffer.from(arrB.buffer);
|
||||
* console.log(buf);
|
||||
* // Prints: <Buffer 63 64 65 66>
|
||||
* ```
|
||||
* @since v5.10.0
|
||||
* @param arrayBuffer An `ArrayBuffer`, `SharedArrayBuffer`, for example the
|
||||
* `.buffer` property of a `TypedArray`.
|
||||
* @param byteOffset Index of first byte to expose. **Default:** `0`.
|
||||
* @param length Number of bytes to expose. **Default:**
|
||||
* `arrayBuffer.byteLength - byteOffset`.
|
||||
*/
|
||||
from<TArrayBuffer extends WithImplicitCoercion<ArrayBufferLike>>(
|
||||
arrayBuffer: TArrayBuffer,
|
||||
byteOffset?: number,
|
||||
length?: number,
|
||||
): Buffer<ImplicitArrayBuffer<TArrayBuffer>>;
|
||||
/**
|
||||
* Creates a new `Buffer` containing `string`. The `encoding` parameter identifies
|
||||
* the character encoding to be used when converting `string` into bytes.
|
||||
*
|
||||
* ```js
|
||||
* import { Buffer } from 'node:buffer';
|
||||
*
|
||||
* const buf1 = Buffer.from('this is a tést');
|
||||
* const buf2 = Buffer.from('7468697320697320612074c3a97374', 'hex');
|
||||
*
|
||||
* console.log(buf1.toString());
|
||||
* // Prints: this is a tést
|
||||
* console.log(buf2.toString());
|
||||
* // Prints: this is a tést
|
||||
* console.log(buf1.toString('latin1'));
|
||||
* // Prints: this is a tést
|
||||
* ```
|
||||
*
|
||||
* A `TypeError` will be thrown if `string` is not a string or another type
|
||||
* appropriate for `Buffer.from()` variants.
|
||||
*
|
||||
* `Buffer.from(string)` may also use the internal `Buffer` pool like
|
||||
* `Buffer.allocUnsafe()` does.
|
||||
* @since v5.10.0
|
||||
* @param string A string to encode.
|
||||
* @param encoding The encoding of `string`. **Default:** `'utf8'`.
|
||||
*/
|
||||
from(string: WithImplicitCoercion<string>, encoding?: BufferEncoding): Buffer<ArrayBuffer>;
|
||||
from(arrayOrString: WithImplicitCoercion<ArrayLike<number> | string>): Buffer<ArrayBuffer>;
|
||||
/**
|
||||
* Creates a new Buffer using the passed {data}
|
||||
* @param values to create a new Buffer
|
||||
*/
|
||||
of(...items: number[]): Buffer<ArrayBuffer>;
|
||||
/**
|
||||
* 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`. If the combined length of the `Buffer`s in `list` is
|
||||
* less than `totalLength`, the remaining space is filled with zeros.
|
||||
*
|
||||
* ```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<ArrayBuffer>;
|
||||
/**
|
||||
* 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<ArrayBuffer>;
|
||||
/**
|
||||
* 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<ArrayBuffer>;
|
||||
/**
|
||||
* 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<ArrayBuffer>;
|
||||
/**
|
||||
* 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<ArrayBuffer>;
|
||||
}
|
||||
interface Buffer<TArrayBuffer extends ArrayBufferLike = ArrayBufferLike> extends Uint8Array<TArrayBuffer> {
|
||||
// see buffer.d.ts for implementation shared with all TypeScript versions
|
||||
|
||||
/**
|
||||
* 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<ArrayBuffer>;
|
||||
/**
|
||||
* 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<TArrayBuffer>;
|
||||
}
|
||||
type NonSharedBuffer = Buffer<ArrayBuffer>;
|
||||
type AllowSharedBuffer = Buffer<ArrayBufferLike>;
|
||||
}
|
||||
/** @deprecated Use `Buffer.allocUnsafeSlow()` instead. */
|
||||
var SlowBuffer: {
|
||||
/** @deprecated Use `Buffer.allocUnsafeSlow()` instead. */
|
||||
new(size: number): Buffer<ArrayBuffer>;
|
||||
prototype: Buffer;
|
||||
};
|
||||
}
|
||||
1930
node_modules/@types/node/buffer.d.ts
generated
vendored
Normal file
1453
node_modules/@types/node/child_process.d.ts
generated
vendored
Normal file
579
node_modules/@types/node/cluster.d.ts
generated
vendored
Normal file
@@ -0,0 +1,579 @@
|
||||
/**
|
||||
* 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-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
|
||||
* server ports.
|
||||
*
|
||||
* ```js
|
||||
* import cluster from 'node:cluster';
|
||||
* import http from 'node:http';
|
||||
* import { availableParallelism } from 'node:os';
|
||||
* import process from 'node:process';
|
||||
*
|
||||
* const numCPUs = availableParallelism();
|
||||
*
|
||||
* if (cluster.isPrimary) {
|
||||
* console.log(`Primary ${process.pid} is running`);
|
||||
*
|
||||
* // Fork workers.
|
||||
* for (let i = 0; i < numCPUs; i++) {
|
||||
* cluster.fork();
|
||||
* }
|
||||
*
|
||||
* cluster.on('exit', (worker, code, signal) => {
|
||||
* console.log(`worker ${worker.process.pid} died`);
|
||||
* });
|
||||
* } else {
|
||||
* // Workers can share any TCP connection
|
||||
* // In this case it is an HTTP server
|
||||
* http.createServer((req, res) => {
|
||||
* res.writeHead(200);
|
||||
* res.end('hello world\n');
|
||||
* }).listen(8000);
|
||||
*
|
||||
* console.log(`Worker ${process.pid} started`);
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* Running Node.js will now share port 8000 between the workers:
|
||||
*
|
||||
* ```console
|
||||
* $ node server.js
|
||||
* Primary 3596 is running
|
||||
* Worker 4324 started
|
||||
* Worker 4520 started
|
||||
* Worker 6056 started
|
||||
* Worker 5644 started
|
||||
* ```
|
||||
*
|
||||
* 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/v24.x/lib/cluster.js)
|
||||
*/
|
||||
declare module "cluster" {
|
||||
import * as child from "node:child_process";
|
||||
import EventEmitter = require("node:events");
|
||||
import * as net from "node:net";
|
||||
type SerializationType = "json" | "advanced";
|
||||
export interface ClusterSettings {
|
||||
/**
|
||||
* List of string arguments passed to the Node.js executable.
|
||||
* @default process.execArgv
|
||||
*/
|
||||
execArgv?: string[] | undefined;
|
||||
/**
|
||||
* File path to worker file.
|
||||
* @default process.argv[1]
|
||||
*/
|
||||
exec?: string | undefined;
|
||||
/**
|
||||
* String arguments passed to worker.
|
||||
* @default process.argv.slice(2)
|
||||
*/
|
||||
args?: string[] | undefined;
|
||||
/**
|
||||
* Whether or not to send output to parent's stdio.
|
||||
* @default false
|
||||
*/
|
||||
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-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;
|
||||
/**
|
||||
* Sets the user identity of the process. (See [`setuid(2)`](https://man7.org/linux/man-pages/man2/setuid.2.html).)
|
||||
*/
|
||||
uid?: number | undefined;
|
||||
/**
|
||||
* Sets the group identity of the process. (See [`setgid(2)`](https://man7.org/linux/man-pages/man2/setgid.2.html).)
|
||||
*/
|
||||
gid?: number | undefined;
|
||||
/**
|
||||
* Sets inspector port of worker. This can be a number, or a function that takes no arguments and returns a number.
|
||||
* By default each worker gets its own port, incremented from the primary's `process.debugPort`.
|
||||
*/
|
||||
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-v24.x/api/child_process.html#advanced-serialization) for more details.
|
||||
* @default false
|
||||
*/
|
||||
serialization?: SerializationType | undefined;
|
||||
/**
|
||||
* Current working directory of the worker process.
|
||||
* @default undefined (inherits from parent process)
|
||||
*/
|
||||
cwd?: string | undefined;
|
||||
/**
|
||||
* Hide the forked processes console window that would normally be created on Windows systems.
|
||||
* @default false
|
||||
*/
|
||||
windowsHide?: boolean | undefined;
|
||||
}
|
||||
export interface Address {
|
||||
address: string;
|
||||
port: number;
|
||||
/**
|
||||
* The `addressType` is one of:
|
||||
*
|
||||
* * `4` (TCPv4)
|
||||
* * `6` (TCPv6)
|
||||
* * `-1` (Unix domain socket)
|
||||
* * `'udp4'` or `'udp6'` (UDPv4 or UDPv6)
|
||||
*/
|
||||
addressType: 4 | 6 | -1 | "udp4" | "udp6";
|
||||
}
|
||||
/**
|
||||
* A `Worker` object contains all public information and method about a worker.
|
||||
* In the primary it can be obtained using `cluster.workers`. In a worker
|
||||
* it can be obtained using `cluster.worker`.
|
||||
* @since v0.7.0
|
||||
*/
|
||||
export class Worker extends EventEmitter {
|
||||
/**
|
||||
* Each new worker is given its own unique id, this id is stored in the `id`.
|
||||
*
|
||||
* While a worker is alive, this is the key that indexes it in `cluster.workers`.
|
||||
* @since v0.8.0
|
||||
*/
|
||||
id: number;
|
||||
/**
|
||||
* 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-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
|
||||
* accidental disconnection.
|
||||
* @since v0.7.0
|
||||
*/
|
||||
process: child.ChildProcess;
|
||||
/**
|
||||
* 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-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()`.
|
||||
*
|
||||
* This example will echo back all messages from the primary:
|
||||
*
|
||||
* ```js
|
||||
* if (cluster.isPrimary) {
|
||||
* const worker = cluster.fork();
|
||||
* worker.send('hi there');
|
||||
*
|
||||
* } else if (cluster.isWorker) {
|
||||
* process.on('message', (msg) => {
|
||||
* process.send(msg);
|
||||
* });
|
||||
* }
|
||||
* ```
|
||||
* @since v0.7.0
|
||||
* @param options The `options` argument, if present, is an object used to parameterize the sending of certain types of handles.
|
||||
*/
|
||||
send(message: child.Serializable, callback?: (error: Error | null) => void): boolean;
|
||||
send(
|
||||
message: child.Serializable,
|
||||
sendHandle: child.SendHandle,
|
||||
callback?: (error: Error | null) => void,
|
||||
): boolean;
|
||||
send(
|
||||
message: child.Serializable,
|
||||
sendHandle: child.SendHandle,
|
||||
options?: child.MessageOptions,
|
||||
callback?: (error: Error | null) => void,
|
||||
): boolean;
|
||||
/**
|
||||
* This function will kill the worker. In the primary worker, it does this by
|
||||
* disconnecting the `worker.process`, and once disconnected, killing with `signal`. In the worker, it does it by killing the process with `signal`.
|
||||
*
|
||||
* The `kill()` function kills the worker process without waiting for a graceful
|
||||
* disconnect, it has the same behavior as `worker.process.kill()`.
|
||||
*
|
||||
* 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-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.
|
||||
*/
|
||||
kill(signal?: string): void;
|
||||
destroy(signal?: string): void;
|
||||
/**
|
||||
* In a worker, this function will close all servers, wait for the `'close'` event
|
||||
* on those servers, and then disconnect the IPC channel.
|
||||
*
|
||||
* In the primary, an internal message is sent to the worker causing it to call `.disconnect()` on itself.
|
||||
*
|
||||
* Causes `.exitedAfterDisconnect` to be set.
|
||||
*
|
||||
* After a server is closed, it will no longer accept new connections,
|
||||
* but connections may be accepted by any other listening worker. Existing
|
||||
* connections will be allowed to close as usual. When no more connections exist,
|
||||
* see `server.close()`, the IPC channel to the worker will close allowing it
|
||||
* to die gracefully.
|
||||
*
|
||||
* The above applies _only_ to server connections, client connections are not
|
||||
* automatically closed by workers, and disconnect does not wait for them to close
|
||||
* before exiting.
|
||||
*
|
||||
* In a worker, `process.disconnect` exists, but it is not this function;
|
||||
* it is `disconnect()`.
|
||||
*
|
||||
* Because long living server connections may block workers from disconnecting, it
|
||||
* may be useful to send a message, so application specific actions may be taken to
|
||||
* close them. It also may be useful to implement a timeout, killing a worker if
|
||||
* 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;
|
||||
*
|
||||
* worker.on('listening', (address) => {
|
||||
* worker.send('shutdown');
|
||||
* worker.disconnect();
|
||||
* timeout = setTimeout(() => {
|
||||
* worker.kill();
|
||||
* }, 2000);
|
||||
* });
|
||||
*
|
||||
* worker.on('disconnect', () => {
|
||||
* clearTimeout(timeout);
|
||||
* });
|
||||
*
|
||||
* } else if (cluster.isWorker) {
|
||||
* const server = net.createServer((socket) => {
|
||||
* // Connections never end
|
||||
* });
|
||||
*
|
||||
* server.listen(8000);
|
||||
*
|
||||
* process.on('message', (msg) => {
|
||||
* if (msg === 'shutdown') {
|
||||
* // Initiate graceful close of any connections to server
|
||||
* }
|
||||
* });
|
||||
* }
|
||||
* ```
|
||||
* @since v0.7.7
|
||||
* @return A reference to `worker`.
|
||||
*/
|
||||
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
|
||||
* has been created. It is disconnected after the `'disconnect'` event is emitted.
|
||||
* @since v0.11.14
|
||||
*/
|
||||
isConnected(): boolean;
|
||||
/**
|
||||
* This function returns `true` if the worker's process has terminated (either
|
||||
* because of exiting or being signaled). Otherwise, it returns `false`.
|
||||
*
|
||||
* ```js
|
||||
* import cluster from 'node:cluster';
|
||||
* import http from 'node:http';
|
||||
* import { availableParallelism } from 'node:os';
|
||||
* import process from 'node:process';
|
||||
*
|
||||
* const numCPUs = availableParallelism();
|
||||
*
|
||||
* if (cluster.isPrimary) {
|
||||
* console.log(`Primary ${process.pid} is running`);
|
||||
*
|
||||
* // Fork workers.
|
||||
* for (let i = 0; i < numCPUs; i++) {
|
||||
* cluster.fork();
|
||||
* }
|
||||
*
|
||||
* cluster.on('fork', (worker) => {
|
||||
* console.log('worker is dead:', worker.isDead());
|
||||
* });
|
||||
*
|
||||
* cluster.on('exit', (worker, code, signal) => {
|
||||
* console.log('worker is dead:', worker.isDead());
|
||||
* });
|
||||
* } else {
|
||||
* // Workers can share any TCP connection. In this case, it is an HTTP server.
|
||||
* http.createServer((req, res) => {
|
||||
* res.writeHead(200);
|
||||
* res.end(`Current process\n ${process.pid}`);
|
||||
* process.kill(process.pid);
|
||||
* }).listen(8000);
|
||||
* }
|
||||
* ```
|
||||
* @since v0.11.14
|
||||
*/
|
||||
isDead(): boolean;
|
||||
/**
|
||||
* This property is `true` if the worker exited due to `.disconnect()`.
|
||||
* If the worker exited any other way, it is `false`. If the
|
||||
* worker has not exited, it is `undefined`.
|
||||
*
|
||||
* The boolean `worker.exitedAfterDisconnect` allows distinguishing between
|
||||
* voluntary and accidental exit, the primary may choose not to respawn a worker
|
||||
* based on this value.
|
||||
*
|
||||
* ```js
|
||||
* cluster.on('exit', (worker, code, signal) => {
|
||||
* if (worker.exitedAfterDisconnect === true) {
|
||||
* console.log('Oh, it was just voluntary – no need to worry');
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* // kill worker
|
||||
* worker.kill();
|
||||
* ```
|
||||
* @since v6.0.0
|
||||
*/
|
||||
exitedAfterDisconnect: boolean;
|
||||
/**
|
||||
* events.EventEmitter
|
||||
* 1. disconnect
|
||||
* 2. error
|
||||
* 3. exit
|
||||
* 4. listening
|
||||
* 5. message
|
||||
* 6. online
|
||||
*/
|
||||
addListener(event: string, listener: (...args: any[]) => void): this;
|
||||
addListener(event: "disconnect", listener: () => void): this;
|
||||
addListener(event: "error", listener: (error: Error) => void): this;
|
||||
addListener(event: "exit", listener: (code: number, signal: string) => void): this;
|
||||
addListener(event: "listening", listener: (address: Address) => void): this;
|
||||
addListener(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined.
|
||||
addListener(event: "online", listener: () => void): this;
|
||||
emit(event: string | symbol, ...args: any[]): boolean;
|
||||
emit(event: "disconnect"): boolean;
|
||||
emit(event: "error", error: Error): boolean;
|
||||
emit(event: "exit", code: number, signal: string): boolean;
|
||||
emit(event: "listening", address: Address): boolean;
|
||||
emit(event: "message", message: any, handle: net.Socket | net.Server): boolean;
|
||||
emit(event: "online"): boolean;
|
||||
on(event: string, listener: (...args: any[]) => void): this;
|
||||
on(event: "disconnect", listener: () => void): this;
|
||||
on(event: "error", listener: (error: Error) => void): this;
|
||||
on(event: "exit", listener: (code: number, signal: string) => void): this;
|
||||
on(event: "listening", listener: (address: Address) => void): this;
|
||||
on(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined.
|
||||
on(event: "online", listener: () => void): this;
|
||||
once(event: string, listener: (...args: any[]) => void): this;
|
||||
once(event: "disconnect", listener: () => void): this;
|
||||
once(event: "error", listener: (error: Error) => void): this;
|
||||
once(event: "exit", listener: (code: number, signal: string) => void): this;
|
||||
once(event: "listening", listener: (address: Address) => void): this;
|
||||
once(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined.
|
||||
once(event: "online", listener: () => void): this;
|
||||
prependListener(event: string, listener: (...args: any[]) => void): this;
|
||||
prependListener(event: "disconnect", listener: () => void): this;
|
||||
prependListener(event: "error", listener: (error: Error) => void): this;
|
||||
prependListener(event: "exit", listener: (code: number, signal: string) => void): this;
|
||||
prependListener(event: "listening", listener: (address: Address) => void): this;
|
||||
prependListener(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined.
|
||||
prependListener(event: "online", listener: () => void): this;
|
||||
prependOnceListener(event: string, listener: (...args: any[]) => void): this;
|
||||
prependOnceListener(event: "disconnect", listener: () => void): this;
|
||||
prependOnceListener(event: "error", listener: (error: Error) => void): this;
|
||||
prependOnceListener(event: "exit", listener: (code: number, signal: string) => void): this;
|
||||
prependOnceListener(event: "listening", listener: (address: Address) => void): this;
|
||||
prependOnceListener(event: "message", listener: (message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined.
|
||||
prependOnceListener(event: "online", listener: () => void): this;
|
||||
}
|
||||
export interface Cluster extends EventEmitter {
|
||||
disconnect(callback?: () => void): void;
|
||||
/**
|
||||
* Spawn a new worker process.
|
||||
*
|
||||
* This can only be called from the primary process.
|
||||
* @param env Key/value pairs to add to worker process environment.
|
||||
* @since v0.6.0
|
||||
*/
|
||||
fork(env?: any): Worker;
|
||||
/** @deprecated since v16.0.0 - use isPrimary. */
|
||||
readonly isMaster: boolean;
|
||||
/**
|
||||
* True if the process is a primary. This is determined by the `process.env.NODE_UNIQUE_ID`. If `process.env.NODE_UNIQUE_ID`
|
||||
* is undefined, then `isPrimary` is `true`.
|
||||
* @since v16.0.0
|
||||
*/
|
||||
readonly isPrimary: boolean;
|
||||
/**
|
||||
* True if the process is not a primary (it is the negation of `cluster.isPrimary`).
|
||||
* @since v0.6.0
|
||||
*/
|
||||
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-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
|
||||
* IOCP handles without incurring a large performance hit.
|
||||
*
|
||||
* `cluster.schedulingPolicy` can also be set through the `NODE_CLUSTER_SCHED_POLICY` environment variable. Valid values are `'rr'` and `'none'`.
|
||||
* @since v0.11.2
|
||||
*/
|
||||
schedulingPolicy: number;
|
||||
/**
|
||||
* 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-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-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-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.
|
||||
*
|
||||
* ```js
|
||||
* import cluster from 'node:cluster';
|
||||
*
|
||||
* cluster.setupPrimary({
|
||||
* exec: 'worker.js',
|
||||
* args: ['--use', 'https'],
|
||||
* silent: true,
|
||||
* });
|
||||
* cluster.fork(); // https worker
|
||||
* cluster.setupPrimary({
|
||||
* exec: 'worker.js',
|
||||
* args: ['--use', 'http'],
|
||||
* });
|
||||
* cluster.fork(); // http worker
|
||||
* ```
|
||||
*
|
||||
* This can only be called from the primary process.
|
||||
* @since v16.0.0
|
||||
*/
|
||||
setupPrimary(settings?: ClusterSettings): void;
|
||||
/**
|
||||
* A reference to the current worker object. Not available in the primary process.
|
||||
*
|
||||
* ```js
|
||||
* import cluster from 'node:cluster';
|
||||
*
|
||||
* if (cluster.isPrimary) {
|
||||
* console.log('I am primary');
|
||||
* cluster.fork();
|
||||
* cluster.fork();
|
||||
* } else if (cluster.isWorker) {
|
||||
* console.log(`I am worker #${cluster.worker.id}`);
|
||||
* }
|
||||
* ```
|
||||
* @since v0.7.0
|
||||
*/
|
||||
readonly worker?: Worker | undefined;
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* A worker is removed from `cluster.workers` after the worker has disconnected _and_ exited. The order between these two events cannot be determined in advance. However, it
|
||||
* is guaranteed that the removal from the `cluster.workers` list happens before the last `'disconnect'` or `'exit'` event is emitted.
|
||||
*
|
||||
* ```js
|
||||
* import cluster from 'node:cluster';
|
||||
*
|
||||
* for (const worker of Object.values(cluster.workers)) {
|
||||
* worker.send('big announcement to all workers');
|
||||
* }
|
||||
* ```
|
||||
* @since v0.7.0
|
||||
*/
|
||||
readonly workers?: NodeJS.Dict<Worker> | undefined;
|
||||
readonly SCHED_NONE: number;
|
||||
readonly SCHED_RR: number;
|
||||
/**
|
||||
* events.EventEmitter
|
||||
* 1. disconnect
|
||||
* 2. exit
|
||||
* 3. fork
|
||||
* 4. listening
|
||||
* 5. message
|
||||
* 6. online
|
||||
* 7. setup
|
||||
*/
|
||||
addListener(event: string, listener: (...args: any[]) => void): this;
|
||||
addListener(event: "disconnect", listener: (worker: Worker) => void): this;
|
||||
addListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): this;
|
||||
addListener(event: "fork", listener: (worker: Worker) => void): this;
|
||||
addListener(event: "listening", listener: (worker: Worker, address: Address) => void): this;
|
||||
addListener(
|
||||
event: "message",
|
||||
listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void,
|
||||
): this; // the handle is a net.Socket or net.Server object, or undefined.
|
||||
addListener(event: "online", listener: (worker: Worker) => void): this;
|
||||
addListener(event: "setup", listener: (settings: ClusterSettings) => void): this;
|
||||
emit(event: string | symbol, ...args: any[]): boolean;
|
||||
emit(event: "disconnect", worker: Worker): boolean;
|
||||
emit(event: "exit", worker: Worker, code: number, signal: string): boolean;
|
||||
emit(event: "fork", worker: Worker): boolean;
|
||||
emit(event: "listening", worker: Worker, address: Address): boolean;
|
||||
emit(event: "message", worker: Worker, message: any, handle: net.Socket | net.Server): boolean;
|
||||
emit(event: "online", worker: Worker): boolean;
|
||||
emit(event: "setup", settings: ClusterSettings): boolean;
|
||||
on(event: string, listener: (...args: any[]) => void): this;
|
||||
on(event: "disconnect", listener: (worker: Worker) => void): this;
|
||||
on(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): this;
|
||||
on(event: "fork", listener: (worker: Worker) => void): this;
|
||||
on(event: "listening", listener: (worker: Worker, address: Address) => void): this;
|
||||
on(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined.
|
||||
on(event: "online", listener: (worker: Worker) => void): this;
|
||||
on(event: "setup", listener: (settings: ClusterSettings) => void): this;
|
||||
once(event: string, listener: (...args: any[]) => void): this;
|
||||
once(event: "disconnect", listener: (worker: Worker) => void): this;
|
||||
once(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): this;
|
||||
once(event: "fork", listener: (worker: Worker) => void): this;
|
||||
once(event: "listening", listener: (worker: Worker, address: Address) => void): this;
|
||||
once(event: "message", listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void): this; // the handle is a net.Socket or net.Server object, or undefined.
|
||||
once(event: "online", listener: (worker: Worker) => void): this;
|
||||
once(event: "setup", listener: (settings: ClusterSettings) => void): this;
|
||||
prependListener(event: string, listener: (...args: any[]) => void): this;
|
||||
prependListener(event: "disconnect", listener: (worker: Worker) => void): this;
|
||||
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,
|
||||
): this;
|
||||
prependListener(event: "online", listener: (worker: Worker) => void): this;
|
||||
prependListener(event: "setup", listener: (settings: ClusterSettings) => void): this;
|
||||
prependOnceListener(event: string, listener: (...args: any[]) => void): this;
|
||||
prependOnceListener(event: "disconnect", listener: (worker: Worker) => void): this;
|
||||
prependOnceListener(event: "exit", listener: (worker: Worker, code: number, signal: string) => void): this;
|
||||
prependOnceListener(event: "fork", listener: (worker: Worker) => void): this;
|
||||
prependOnceListener(event: "listening", listener: (worker: Worker, address: Address) => void): this;
|
||||
// the handle is a net.Socket or net.Server object, or undefined.
|
||||
prependOnceListener(
|
||||
event: "message",
|
||||
listener: (worker: Worker, message: any, handle: net.Socket | net.Server) => void,
|
||||
): this;
|
||||
prependOnceListener(event: "online", listener: (worker: Worker) => void): this;
|
||||
prependOnceListener(event: "setup", listener: (settings: ClusterSettings) => void): this;
|
||||
}
|
||||
const cluster: Cluster;
|
||||
export default cluster;
|
||||
}
|
||||
declare module "node:cluster" {
|
||||
export * from "cluster";
|
||||
export { default as default } from "cluster";
|
||||
}
|
||||
21
node_modules/@types/node/compatibility/iterators.d.ts
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
// Backwards-compatible iterator interfaces, augmented with iterator helper methods by lib.esnext.iterator in TypeScript 5.6.
|
||||
// The IterableIterator interface does not contain these methods, which creates assignability issues in places where IteratorObjects
|
||||
// are expected (eg. DOM-compatible APIs) if lib.esnext.iterator is loaded.
|
||||
// Also ensures that iterators returned by the Node API, which inherit from Iterator.prototype, correctly expose the iterator helper methods
|
||||
// if lib.esnext.iterator is loaded.
|
||||
// TODO: remove once this package no longer supports TS 5.5, and replace NodeJS.BuiltinIteratorReturn with BuiltinIteratorReturn.
|
||||
|
||||
// Placeholders for TS <5.6
|
||||
interface IteratorObject<T, TReturn, TNext> {}
|
||||
interface AsyncIteratorObject<T, TReturn, TNext> {}
|
||||
|
||||
declare namespace NodeJS {
|
||||
// Populate iterator methods for TS <5.6
|
||||
interface Iterator<T, TReturn, TNext> extends globalThis.Iterator<T, TReturn, TNext> {}
|
||||
interface AsyncIterator<T, TReturn, TNext> extends globalThis.AsyncIterator<T, TReturn, TNext> {}
|
||||
|
||||
// Polyfill for TS 5.6's instrinsic BuiltinIteratorReturn type, required for DOM-compatible iterators
|
||||
type BuiltinIteratorReturn = ReturnType<any[][typeof Symbol.iterator]> extends
|
||||
globalThis.Iterator<any, infer TReturn> ? TReturn
|
||||
: any;
|
||||
}
|
||||
452
node_modules/@types/node/console.d.ts
generated
vendored
Normal file
@@ -0,0 +1,452 @@
|
||||
/**
|
||||
* The `node:console` module provides a simple debugging console that is similar to
|
||||
* the JavaScript console mechanism provided by web browsers.
|
||||
*
|
||||
* 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-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-v24.x/api/process.html#a-note-on-process-io) for
|
||||
* more information.
|
||||
*
|
||||
* Example using the global `console`:
|
||||
*
|
||||
* ```js
|
||||
* console.log('hello world');
|
||||
* // Prints: hello world, to stdout
|
||||
* console.log('hello %s', 'world');
|
||||
* // Prints: hello world, to stdout
|
||||
* console.error(new Error('Whoops, something bad happened'));
|
||||
* // Prints error message and stack trace to stderr:
|
||||
* // Error: Whoops, something bad happened
|
||||
* // at [eval]:5:15
|
||||
* // at Script.runInThisContext (node:vm:132:18)
|
||||
* // at Object.runInThisContext (node:vm:309:38)
|
||||
* // at node:internal/process/execution:77:19
|
||||
* // at [eval]-wrapper:6:22
|
||||
* // at evalScript (node:internal/process/execution:76:60)
|
||||
* // at node:internal/main/eval_string:23:3
|
||||
*
|
||||
* const name = 'Will Robinson';
|
||||
* console.warn(`Danger ${name}! Danger!`);
|
||||
* // Prints: Danger Will Robinson! Danger!, to stderr
|
||||
* ```
|
||||
*
|
||||
* Example using the `Console` class:
|
||||
*
|
||||
* ```js
|
||||
* const out = getStreamSomehow();
|
||||
* const err = getStreamSomehow();
|
||||
* const myConsole = new console.Console(out, err);
|
||||
*
|
||||
* myConsole.log('hello world');
|
||||
* // Prints: hello world, to out
|
||||
* myConsole.log('hello %s', 'world');
|
||||
* // Prints: hello world, to out
|
||||
* myConsole.error(new Error('Whoops, something bad happened'));
|
||||
* // Prints: [Error: Whoops, something bad happened], to err
|
||||
*
|
||||
* const name = 'Will Robinson';
|
||||
* myConsole.warn(`Danger ${name}! Danger!`);
|
||||
* // Prints: Danger Will Robinson! Danger!, to err
|
||||
* ```
|
||||
* @see [source](https://github.com/nodejs/node/blob/v24.x/lib/console.js)
|
||||
*/
|
||||
declare module "console" {
|
||||
import console = require("node:console");
|
||||
export = console;
|
||||
}
|
||||
declare module "node:console" {
|
||||
import { InspectOptions } from "node:util";
|
||||
global {
|
||||
// This needs to be global to avoid TS2403 in case lib.dom.d.ts is present in the same build
|
||||
interface Console {
|
||||
Console: console.ConsoleConstructor;
|
||||
/**
|
||||
* `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-v24.x/api/util.html#utilformatformat-args).
|
||||
*
|
||||
* If `value` is [truthy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy), nothing happens.
|
||||
*
|
||||
* ```js
|
||||
* console.assert(true, 'does nothing');
|
||||
*
|
||||
* console.assert(false, 'Whoops %s work', 'didn\'t');
|
||||
* // Assertion failed: Whoops didn't work
|
||||
*
|
||||
* console.assert();
|
||||
* // Assertion failed
|
||||
* ```
|
||||
* @since v0.1.101
|
||||
* @param value The value tested for being truthy.
|
||||
* @param message All arguments besides `value` are used as error message.
|
||||
*/
|
||||
assert(value: any, message?: string, ...optionalParams: any[]): void;
|
||||
/**
|
||||
* When `stdout` is a TTY, calling `console.clear()` will attempt to clear the
|
||||
* TTY. When `stdout` is not a TTY, this method does nothing.
|
||||
*
|
||||
* The specific operation of `console.clear()` can vary across operating systems
|
||||
* and terminal types. For most Linux operating systems, `console.clear()` operates similarly to the `clear` shell command. On Windows, `console.clear()` will clear only the output in the
|
||||
* current terminal viewport for the Node.js
|
||||
* binary.
|
||||
* @since v8.3.0
|
||||
*/
|
||||
clear(): void;
|
||||
/**
|
||||
* Maintains an internal counter specific to `label` and outputs to `stdout` the
|
||||
* number of times `console.count()` has been called with the given `label`.
|
||||
*
|
||||
* ```js
|
||||
* > console.count()
|
||||
* default: 1
|
||||
* undefined
|
||||
* > console.count('default')
|
||||
* default: 2
|
||||
* undefined
|
||||
* > console.count('abc')
|
||||
* abc: 1
|
||||
* undefined
|
||||
* > console.count('xyz')
|
||||
* xyz: 1
|
||||
* undefined
|
||||
* > console.count('abc')
|
||||
* abc: 2
|
||||
* undefined
|
||||
* > console.count()
|
||||
* default: 3
|
||||
* undefined
|
||||
* >
|
||||
* ```
|
||||
* @since v8.3.0
|
||||
* @param [label='default'] The display label for the counter.
|
||||
*/
|
||||
count(label?: string): void;
|
||||
/**
|
||||
* Resets the internal counter specific to `label`.
|
||||
*
|
||||
* ```js
|
||||
* > console.count('abc');
|
||||
* abc: 1
|
||||
* undefined
|
||||
* > console.countReset('abc');
|
||||
* undefined
|
||||
* > console.count('abc');
|
||||
* abc: 1
|
||||
* undefined
|
||||
* >
|
||||
* ```
|
||||
* @since v8.3.0
|
||||
* @param [label='default'] The display label for the counter.
|
||||
*/
|
||||
countReset(label?: string): void;
|
||||
/**
|
||||
* The `console.debug()` function is an alias for {@link log}.
|
||||
* @since v8.0.0
|
||||
*/
|
||||
debug(message?: any, ...optionalParams: any[]): void;
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
dir(obj: any, options?: InspectOptions): void;
|
||||
/**
|
||||
* This method calls `console.log()` passing it the arguments received.
|
||||
* This method does not produce any XML formatting.
|
||||
* @since v8.0.0
|
||||
*/
|
||||
dirxml(...data: any[]): void;
|
||||
/**
|
||||
* 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-v24.x/api/util.html#utilformatformat-args)).
|
||||
*
|
||||
* ```js
|
||||
* const code = 5;
|
||||
* console.error('error #%d', code);
|
||||
* // Prints: error #5, to stderr
|
||||
* console.error('error', code);
|
||||
* // Prints: error 5, to stderr
|
||||
* ```
|
||||
*
|
||||
* If formatting elements (e.g. `%d`) are not found in the first string then
|
||||
* [`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
|
||||
*/
|
||||
error(message?: any, ...optionalParams: any[]): void;
|
||||
/**
|
||||
* Increases indentation of subsequent lines by spaces for `groupIndentation` length.
|
||||
*
|
||||
* If one or more `label`s are provided, those are printed first without the
|
||||
* additional indentation.
|
||||
* @since v8.5.0
|
||||
*/
|
||||
group(...label: any[]): void;
|
||||
/**
|
||||
* An alias for {@link group}.
|
||||
* @since v8.5.0
|
||||
*/
|
||||
groupCollapsed(...label: any[]): void;
|
||||
/**
|
||||
* Decreases indentation of subsequent lines by spaces for `groupIndentation` length.
|
||||
* @since v8.5.0
|
||||
*/
|
||||
groupEnd(): void;
|
||||
/**
|
||||
* The `console.info()` function is an alias for {@link log}.
|
||||
* @since v0.1.100
|
||||
*/
|
||||
info(message?: any, ...optionalParams: any[]): void;
|
||||
/**
|
||||
* 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-v24.x/api/util.html#utilformatformat-args)).
|
||||
*
|
||||
* ```js
|
||||
* const count = 5;
|
||||
* console.log('count: %d', count);
|
||||
* // Prints: count: 5, to stdout
|
||||
* console.log('count:', count);
|
||||
* // Prints: count: 5, to stdout
|
||||
* ```
|
||||
*
|
||||
* 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;
|
||||
/**
|
||||
* Try to construct a table with the columns of the properties of `tabularData` (or use `properties`) and rows of `tabularData` and log it. Falls back to just
|
||||
* logging the argument if it can't be parsed as tabular.
|
||||
*
|
||||
* ```js
|
||||
* // These can't be parsed as tabular data
|
||||
* console.table(Symbol());
|
||||
* // Symbol()
|
||||
*
|
||||
* console.table(undefined);
|
||||
* // undefined
|
||||
*
|
||||
* console.table([{ a: 1, b: 'Y' }, { a: 'Z', b: 2 }]);
|
||||
* // ┌─────────┬─────┬─────┐
|
||||
* // │ (index) │ a │ b │
|
||||
* // ├─────────┼─────┼─────┤
|
||||
* // │ 0 │ 1 │ 'Y' │
|
||||
* // │ 1 │ 'Z' │ 2 │
|
||||
* // └─────────┴─────┴─────┘
|
||||
*
|
||||
* console.table([{ a: 1, b: 'Y' }, { a: 'Z', b: 2 }], ['a']);
|
||||
* // ┌─────────┬─────┐
|
||||
* // │ (index) │ a │
|
||||
* // ├─────────┼─────┤
|
||||
* // │ 0 │ 1 │
|
||||
* // │ 1 │ 'Z' │
|
||||
* // └─────────┴─────┘
|
||||
* ```
|
||||
* @since v10.0.0
|
||||
* @param properties Alternate properties for constructing the table.
|
||||
*/
|
||||
table(tabularData: any, properties?: readonly string[]): void;
|
||||
/**
|
||||
* Starts a timer that can be used to compute the duration of an operation. Timers
|
||||
* are identified by a unique `label`. Use the same `label` when calling {@link timeEnd} to stop the timer and output the elapsed time in
|
||||
* suitable time units to `stdout`. For example, if the elapsed
|
||||
* time is 3869ms, `console.timeEnd()` displays "3.869s".
|
||||
* @since v0.1.104
|
||||
* @param [label='default']
|
||||
*/
|
||||
time(label?: string): void;
|
||||
/**
|
||||
* Stops a timer that was previously started by calling {@link time} and
|
||||
* prints the result to `stdout`:
|
||||
*
|
||||
* ```js
|
||||
* console.time('bunch-of-stuff');
|
||||
* // Do a bunch of stuff.
|
||||
* console.timeEnd('bunch-of-stuff');
|
||||
* // Prints: bunch-of-stuff: 225.438ms
|
||||
* ```
|
||||
* @since v0.1.104
|
||||
* @param [label='default']
|
||||
*/
|
||||
timeEnd(label?: string): void;
|
||||
/**
|
||||
* For a timer that was previously started by calling {@link time}, prints
|
||||
* the elapsed time and other `data` arguments to `stdout`:
|
||||
*
|
||||
* ```js
|
||||
* console.time('process');
|
||||
* const value = expensiveProcess1(); // Returns 42
|
||||
* console.timeLog('process', value);
|
||||
* // Prints "process: 365.227ms 42".
|
||||
* doExpensiveProcess2(value);
|
||||
* console.timeEnd('process');
|
||||
* ```
|
||||
* @since v10.7.0
|
||||
* @param [label='default']
|
||||
*/
|
||||
timeLog(label?: string, ...data: any[]): void;
|
||||
/**
|
||||
* 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
|
||||
* console.trace('Show me');
|
||||
* // Prints: (stack trace will vary based on where trace is called)
|
||||
* // Trace: Show me
|
||||
* // at repl:2:9
|
||||
* // at REPLServer.defaultEval (repl.js:248:27)
|
||||
* // at bound (domain.js:287:14)
|
||||
* // at REPLServer.runBound [as eval] (domain.js:300:12)
|
||||
* // at REPLServer.<anonymous> (repl.js:412:12)
|
||||
* // at emitOne (events.js:82:20)
|
||||
* // at REPLServer.emit (events.js:169:7)
|
||||
* // at REPLServer.Interface._onLine (readline.js:210:10)
|
||||
* // at REPLServer.Interface._line (readline.js:549:8)
|
||||
* // at REPLServer.Interface._ttyWrite (readline.js:826:14)
|
||||
* ```
|
||||
* @since v0.1.104
|
||||
*/
|
||||
trace(message?: any, ...optionalParams: any[]): void;
|
||||
/**
|
||||
* The `console.warn()` function is an alias for {@link error}.
|
||||
* @since v0.1.100
|
||||
*/
|
||||
warn(message?: any, ...optionalParams: any[]): void;
|
||||
// --- Inspector mode only ---
|
||||
/**
|
||||
* This method does not display anything unless used in the inspector. The `console.profile()`
|
||||
* method starts a JavaScript CPU profile with an optional label until {@link profileEnd}
|
||||
* is called. The profile is then added to the Profile panel of the inspector.
|
||||
*
|
||||
* ```js
|
||||
* console.profile('MyLabel');
|
||||
* // Some code
|
||||
* console.profileEnd('MyLabel');
|
||||
* // Adds the profile 'MyLabel' to the Profiles panel of the inspector.
|
||||
* ```
|
||||
* @since v8.0.0
|
||||
*/
|
||||
profile(label?: string): void;
|
||||
/**
|
||||
* This method does not display anything unless used in the inspector. Stops the current
|
||||
* JavaScript CPU profiling session if one has been started and prints the report to the
|
||||
* Profiles panel of the inspector. See {@link profile} for an example.
|
||||
*
|
||||
* If this method is called without a label, the most recently started profile is stopped.
|
||||
* @since v8.0.0
|
||||
*/
|
||||
profileEnd(label?: string): void;
|
||||
/**
|
||||
* This method does not display anything unless used in the inspector. The `console.timeStamp()`
|
||||
* method adds an event with the label `'label'` to the Timeline panel of the inspector.
|
||||
* @since v8.0.0
|
||||
*/
|
||||
timeStamp(label?: string): void;
|
||||
}
|
||||
/**
|
||||
* The `console` module provides a simple debugging console that is similar to the
|
||||
* JavaScript console mechanism provided by web browsers.
|
||||
*
|
||||
* 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-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-v24.x/api/process.html#a-note-on-process-io) for
|
||||
* more information.
|
||||
*
|
||||
* Example using the global `console`:
|
||||
*
|
||||
* ```js
|
||||
* console.log('hello world');
|
||||
* // Prints: hello world, to stdout
|
||||
* console.log('hello %s', 'world');
|
||||
* // Prints: hello world, to stdout
|
||||
* console.error(new Error('Whoops, something bad happened'));
|
||||
* // Prints error message and stack trace to stderr:
|
||||
* // Error: Whoops, something bad happened
|
||||
* // at [eval]:5:15
|
||||
* // at Script.runInThisContext (node:vm:132:18)
|
||||
* // at Object.runInThisContext (node:vm:309:38)
|
||||
* // at node:internal/process/execution:77:19
|
||||
* // at [eval]-wrapper:6:22
|
||||
* // at evalScript (node:internal/process/execution:76:60)
|
||||
* // at node:internal/main/eval_string:23:3
|
||||
*
|
||||
* const name = 'Will Robinson';
|
||||
* console.warn(`Danger ${name}! Danger!`);
|
||||
* // Prints: Danger Will Robinson! Danger!, to stderr
|
||||
* ```
|
||||
*
|
||||
* Example using the `Console` class:
|
||||
*
|
||||
* ```js
|
||||
* const out = getStreamSomehow();
|
||||
* const err = getStreamSomehow();
|
||||
* const myConsole = new console.Console(out, err);
|
||||
*
|
||||
* myConsole.log('hello world');
|
||||
* // Prints: hello world, to out
|
||||
* myConsole.log('hello %s', 'world');
|
||||
* // Prints: hello world, to out
|
||||
* myConsole.error(new Error('Whoops, something bad happened'));
|
||||
* // Prints: [Error: Whoops, something bad happened], to err
|
||||
*
|
||||
* const name = 'Will Robinson';
|
||||
* myConsole.warn(`Danger ${name}! Danger!`);
|
||||
* // Prints: Danger Will Robinson! Danger!, to err
|
||||
* ```
|
||||
* @see [source](https://github.com/nodejs/node/blob/v24.x/lib/console.js)
|
||||
*/
|
||||
namespace console {
|
||||
interface ConsoleConstructorOptions {
|
||||
stdout: NodeJS.WritableStream;
|
||||
stderr?: NodeJS.WritableStream | undefined;
|
||||
/**
|
||||
* Ignore errors when writing to the underlying streams.
|
||||
* @default true
|
||||
*/
|
||||
ignoreErrors?: boolean | undefined;
|
||||
/**
|
||||
* Set color support for this `Console` instance. Setting to true enables coloring while inspecting
|
||||
* values. Setting to `false` disables coloring while inspecting values. Setting to `'auto'` makes color
|
||||
* support depend on the value of the `isTTY` property and the value returned by `getColorDepth()` on the
|
||||
* respective stream. This option can not be used, if `inspectOptions.colors` is set as well.
|
||||
* @default auto
|
||||
*/
|
||||
colorMode?: boolean | "auto" | undefined;
|
||||
/**
|
||||
* Specifies options that are passed along to
|
||||
* [`util.inspect()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilinspectobject-options).
|
||||
*/
|
||||
inspectOptions?: InspectOptions | undefined;
|
||||
/**
|
||||
* Set group indentation.
|
||||
* @default 2
|
||||
*/
|
||||
groupIndentation?: number | undefined;
|
||||
}
|
||||
interface ConsoleConstructor {
|
||||
prototype: Console;
|
||||
new(stdout: NodeJS.WritableStream, stderr?: NodeJS.WritableStream, ignoreErrors?: boolean): Console;
|
||||
new(options: ConsoleConstructorOptions): Console;
|
||||
}
|
||||
}
|
||||
var console: Console;
|
||||
}
|
||||
export = globalThis.console;
|
||||
}
|
||||
21
node_modules/@types/node/constants.d.ts
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* @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" {
|
||||
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" {
|
||||
import constants = require("constants");
|
||||
export = constants;
|
||||
}
|
||||
4566
node_modules/@types/node/crypto.d.ts
generated
vendored
Normal file
599
node_modules/@types/node/dgram.d.ts
generated
vendored
Normal file
@@ -0,0 +1,599 @@
|
||||
/**
|
||||
* The `node:dgram` module provides an implementation of UDP datagram sockets.
|
||||
*
|
||||
* ```js
|
||||
* import dgram from 'node:dgram';
|
||||
*
|
||||
* const server = dgram.createSocket('udp4');
|
||||
*
|
||||
* server.on('error', (err) => {
|
||||
* console.error(`server error:\n${err.stack}`);
|
||||
* server.close();
|
||||
* });
|
||||
*
|
||||
* server.on('message', (msg, rinfo) => {
|
||||
* console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`);
|
||||
* });
|
||||
*
|
||||
* server.on('listening', () => {
|
||||
* const address = server.address();
|
||||
* console.log(`server listening ${address.address}:${address.port}`);
|
||||
* });
|
||||
*
|
||||
* server.bind(41234);
|
||||
* // Prints: server listening 0.0.0.0:41234
|
||||
* ```
|
||||
* @see [source](https://github.com/nodejs/node/blob/v24.x/lib/dgram.js)
|
||||
*/
|
||||
declare module "dgram" {
|
||||
import { AddressInfo, BlockList } from "node:net";
|
||||
import * as dns from "node:dns";
|
||||
import { Abortable, EventEmitter } from "node:events";
|
||||
interface RemoteInfo {
|
||||
address: string;
|
||||
family: "IPv4" | "IPv6";
|
||||
port: number;
|
||||
size: number;
|
||||
}
|
||||
interface BindOptions {
|
||||
port?: number | undefined;
|
||||
address?: string | undefined;
|
||||
exclusive?: boolean | undefined;
|
||||
fd?: number | undefined;
|
||||
}
|
||||
type SocketType = "udp4" | "udp6";
|
||||
interface SocketOptions extends Abortable {
|
||||
type: SocketType;
|
||||
reuseAddr?: boolean | undefined;
|
||||
reusePort?: boolean | undefined;
|
||||
/**
|
||||
* @default false
|
||||
*/
|
||||
ipv6Only?: boolean | undefined;
|
||||
recvBufferSize?: number | undefined;
|
||||
sendBufferSize?: number | undefined;
|
||||
lookup?:
|
||||
| ((
|
||||
hostname: string,
|
||||
options: dns.LookupOneOptions,
|
||||
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
|
||||
* messages. When `address` and `port` are not passed to `socket.bind()` the
|
||||
* method will bind the socket to the "all interfaces" address on a random port
|
||||
* (it does the right thing for both `udp4` and `udp6` sockets). The bound address
|
||||
* and port can be retrieved using `socket.address().address` and `socket.address().port`.
|
||||
*
|
||||
* If the `signal` option is enabled, calling `.abort()` on the corresponding `AbortController` is similar to calling `.close()` on the socket:
|
||||
*
|
||||
* ```js
|
||||
* const controller = new AbortController();
|
||||
* const { signal } = controller;
|
||||
* const server = dgram.createSocket({ type: 'udp4', signal });
|
||||
* server.on('message', (msg, rinfo) => {
|
||||
* console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`);
|
||||
* });
|
||||
* // Later, when you want to close the server.
|
||||
* controller.abort();
|
||||
* ```
|
||||
* @since v0.11.13
|
||||
* @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;
|
||||
/**
|
||||
* Encapsulates the datagram functionality.
|
||||
*
|
||||
* New instances of `dgram.Socket` are created using {@link createSocket}.
|
||||
* The `new` keyword is not to be used to create `dgram.Socket` instances.
|
||||
* @since v0.1.99
|
||||
*/
|
||||
class Socket extends EventEmitter {
|
||||
/**
|
||||
* Tells the kernel to join a multicast group at the given `multicastAddress` and `multicastInterface` using the `IP_ADD_MEMBERSHIP` socket option. If the `multicastInterface` argument is not
|
||||
* specified, the operating system will choose
|
||||
* one interface and will add membership to it. To add membership to every
|
||||
* available interface, call `addMembership` multiple times, once per interface.
|
||||
*
|
||||
* When called on an unbound socket, this method will implicitly bind to a random
|
||||
* port, listening on all interfaces.
|
||||
*
|
||||
* When sharing a UDP socket across multiple `cluster` workers, the`socket.addMembership()` function must be called only once or an`EADDRINUSE` error will occur:
|
||||
*
|
||||
* ```js
|
||||
* import cluster from 'node:cluster';
|
||||
* import dgram from 'node:dgram';
|
||||
*
|
||||
* if (cluster.isPrimary) {
|
||||
* cluster.fork(); // Works ok.
|
||||
* cluster.fork(); // Fails with EADDRINUSE.
|
||||
* } else {
|
||||
* const s = dgram.createSocket('udp4');
|
||||
* s.bind(1234, () => {
|
||||
* s.addMembership('224.0.0.114');
|
||||
* });
|
||||
* }
|
||||
* ```
|
||||
* @since v0.6.9
|
||||
*/
|
||||
addMembership(multicastAddress: string, multicastInterface?: string): void;
|
||||
/**
|
||||
* Returns an object containing the address information for a socket.
|
||||
* For UDP sockets, this object will contain `address`, `family`, and `port` properties.
|
||||
*
|
||||
* This method throws `EBADF` if called on an unbound socket.
|
||||
* @since v0.1.99
|
||||
*/
|
||||
address(): AddressInfo;
|
||||
/**
|
||||
* For UDP sockets, causes the `dgram.Socket` to listen for datagram
|
||||
* messages on a named `port` and optional `address`. If `port` is not
|
||||
* specified or is `0`, the operating system will attempt to bind to a
|
||||
* random port. If `address` is not specified, the operating system will
|
||||
* attempt to listen on all addresses. Once binding is complete, a `'listening'` event is emitted and the optional `callback` function is
|
||||
* called.
|
||||
*
|
||||
* Specifying both a `'listening'` event listener and passing a `callback` to the `socket.bind()` method is not harmful but not very
|
||||
* useful.
|
||||
*
|
||||
* A bound datagram socket keeps the Node.js process running to receive
|
||||
* datagram messages.
|
||||
*
|
||||
* If binding fails, an `'error'` event is generated. In rare case (e.g.
|
||||
* attempting to bind with a closed socket), an `Error` may be thrown.
|
||||
*
|
||||
* Example of a UDP server listening on port 41234:
|
||||
*
|
||||
* ```js
|
||||
* import dgram from 'node:dgram';
|
||||
*
|
||||
* const server = dgram.createSocket('udp4');
|
||||
*
|
||||
* server.on('error', (err) => {
|
||||
* console.error(`server error:\n${err.stack}`);
|
||||
* server.close();
|
||||
* });
|
||||
*
|
||||
* server.on('message', (msg, rinfo) => {
|
||||
* console.log(`server got: ${msg} from ${rinfo.address}:${rinfo.port}`);
|
||||
* });
|
||||
*
|
||||
* server.on('listening', () => {
|
||||
* const address = server.address();
|
||||
* console.log(`server listening ${address.address}:${address.port}`);
|
||||
* });
|
||||
*
|
||||
* server.bind(41234);
|
||||
* // Prints: server listening 0.0.0.0:41234
|
||||
* ```
|
||||
* @since v0.1.99
|
||||
* @param callback with no parameters. Called when binding is complete.
|
||||
*/
|
||||
bind(port?: number, address?: string, callback?: () => void): this;
|
||||
bind(port?: number, callback?: () => void): this;
|
||||
bind(callback?: () => void): this;
|
||||
bind(options: BindOptions, callback?: () => void): this;
|
||||
/**
|
||||
* Close the underlying socket and stop listening for data on it. If a callback is
|
||||
* provided, it is added as a listener for the `'close'` event.
|
||||
* @since v0.1.99
|
||||
* @param callback Called when the socket has been closed.
|
||||
*/
|
||||
close(callback?: () => void): this;
|
||||
/**
|
||||
* Associates the `dgram.Socket` to a remote address and port. Every
|
||||
* message sent by this handle is automatically sent to that destination. Also,
|
||||
* the socket will only receive messages from that remote peer.
|
||||
* Trying to call `connect()` on an already connected socket will result
|
||||
* in an `ERR_SOCKET_DGRAM_IS_CONNECTED` exception. If `address` is not
|
||||
* provided, `'127.0.0.1'` (for `udp4` sockets) or `'::1'` (for `udp6` sockets)
|
||||
* will be used by default. Once the connection is complete, a `'connect'` event
|
||||
* is emitted and the optional `callback` function is called. In case of failure,
|
||||
* the `callback` is called or, failing this, an `'error'` event is emitted.
|
||||
* @since v12.0.0
|
||||
* @param callback Called when the connection is completed or on error.
|
||||
*/
|
||||
connect(port: number, address?: string, callback?: () => void): void;
|
||||
connect(port: number, callback: () => void): void;
|
||||
/**
|
||||
* A synchronous function that disassociates a connected `dgram.Socket` from
|
||||
* its remote address. Trying to call `disconnect()` on an unbound or already
|
||||
* disconnected socket will result in an `ERR_SOCKET_DGRAM_NOT_CONNECTED` exception.
|
||||
* @since v12.0.0
|
||||
*/
|
||||
disconnect(): void;
|
||||
/**
|
||||
* Instructs the kernel to leave a multicast group at `multicastAddress` using the `IP_DROP_MEMBERSHIP` socket option. This method is automatically called by the
|
||||
* kernel when the socket is closed or the process terminates, so most apps will
|
||||
* never have reason to call this.
|
||||
*
|
||||
* If `multicastInterface` is not specified, the operating system will attempt to
|
||||
* drop membership on all valid interfaces.
|
||||
* @since v0.6.9
|
||||
*/
|
||||
dropMembership(multicastAddress: string, multicastInterface?: string): void;
|
||||
/**
|
||||
* This method throws `ERR_SOCKET_BUFFER_SIZE` if called on an unbound socket.
|
||||
* @since v8.7.0
|
||||
* @return the `SO_RCVBUF` socket receive buffer size in bytes.
|
||||
*/
|
||||
getRecvBufferSize(): number;
|
||||
/**
|
||||
* This method throws `ERR_SOCKET_BUFFER_SIZE` if called on an unbound socket.
|
||||
* @since v8.7.0
|
||||
* @return the `SO_SNDBUF` socket send buffer size in bytes.
|
||||
*/
|
||||
getSendBufferSize(): number;
|
||||
/**
|
||||
* @since v18.8.0, v16.19.0
|
||||
* @return Number of bytes queued for sending.
|
||||
*/
|
||||
getSendQueueSize(): number;
|
||||
/**
|
||||
* @since v18.8.0, v16.19.0
|
||||
* @return Number of send requests currently in the queue awaiting to be processed.
|
||||
*/
|
||||
getSendQueueCount(): number;
|
||||
/**
|
||||
* By default, binding a socket will cause it to block the Node.js process from
|
||||
* exiting as long as the socket is open. The `socket.unref()` method can be used
|
||||
* to exclude the socket from the reference counting that keeps the Node.js
|
||||
* process active. The `socket.ref()` method adds the socket back to the reference
|
||||
* counting and restores the default behavior.
|
||||
*
|
||||
* Calling `socket.ref()` multiples times will have no additional effect.
|
||||
*
|
||||
* The `socket.ref()` method returns a reference to the socket so calls can be
|
||||
* chained.
|
||||
* @since v0.9.1
|
||||
*/
|
||||
ref(): this;
|
||||
/**
|
||||
* Returns an object containing the `address`, `family`, and `port` of the remote
|
||||
* endpoint. This method throws an `ERR_SOCKET_DGRAM_NOT_CONNECTED` exception
|
||||
* if the socket is not connected.
|
||||
* @since v12.0.0
|
||||
*/
|
||||
remoteAddress(): AddressInfo;
|
||||
/**
|
||||
* Broadcasts a datagram on the socket.
|
||||
* For connectionless sockets, the destination `port` and `address` must be
|
||||
* specified. Connected sockets, on the other hand, will use their associated
|
||||
* remote endpoint, so the `port` and `address` arguments must not be set.
|
||||
*
|
||||
* The `msg` argument contains the message to be sent.
|
||||
* Depending on its type, different behavior can apply. If `msg` is a `Buffer`,
|
||||
* any `TypedArray` or a `DataView`,
|
||||
* the `offset` and `length` specify the offset within the `Buffer` where the
|
||||
* message begins and the number of bytes in the message, respectively.
|
||||
* If `msg` is a `String`, then it is automatically converted to a `Buffer` with `'utf8'` encoding. With messages that
|
||||
* contain multi-byte characters, `offset` and `length` will be calculated with
|
||||
* respect to `byte length` and not the character position.
|
||||
* If `msg` is an array, `offset` and `length` must not be specified.
|
||||
*
|
||||
* The `address` argument is a string. If the value of `address` is a host name,
|
||||
* DNS will be used to resolve the address of the host. If `address` is not
|
||||
* provided or otherwise nullish, `'127.0.0.1'` (for `udp4` sockets) or `'::1'` (for `udp6` sockets) will be used by default.
|
||||
*
|
||||
* If the socket has not been previously bound with a call to `bind`, the socket
|
||||
* is assigned a random port number and is bound to the "all interfaces" address
|
||||
* (`'0.0.0.0'` for `udp4` sockets, `'::0'` for `udp6` sockets.)
|
||||
*
|
||||
* An optional `callback` function may be specified to as a way of reporting
|
||||
* DNS errors or for determining when it is safe to reuse the `buf` object.
|
||||
* DNS lookups delay the time to send for at least one tick of the
|
||||
* Node.js event loop.
|
||||
*
|
||||
* The only way to know for sure that the datagram has been sent is by using a `callback`. If an error occurs and a `callback` is given, the error will be
|
||||
* passed as the first argument to the `callback`. If a `callback` is not given,
|
||||
* the error is emitted as an `'error'` event on the `socket` object.
|
||||
*
|
||||
* Offset and length are optional but both _must_ be set if either are used.
|
||||
* They are supported only when the first argument is a `Buffer`, a `TypedArray`,
|
||||
* or a `DataView`.
|
||||
*
|
||||
* This method throws `ERR_SOCKET_BAD_PORT` if called on an unbound socket.
|
||||
*
|
||||
* Example of sending a UDP packet to a port on `localhost`;
|
||||
*
|
||||
* ```js
|
||||
* import dgram from 'node:dgram';
|
||||
* import { Buffer } from 'node:buffer';
|
||||
*
|
||||
* const message = Buffer.from('Some bytes');
|
||||
* const client = dgram.createSocket('udp4');
|
||||
* client.send(message, 41234, 'localhost', (err) => {
|
||||
* client.close();
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* Example of sending a UDP packet composed of multiple buffers to a port on`127.0.0.1`;
|
||||
*
|
||||
* ```js
|
||||
* import dgram from 'node:dgram';
|
||||
* import { Buffer } from 'node:buffer';
|
||||
*
|
||||
* const buf1 = Buffer.from('Some ');
|
||||
* const buf2 = Buffer.from('bytes');
|
||||
* const client = dgram.createSocket('udp4');
|
||||
* client.send([buf1, buf2], 41234, (err) => {
|
||||
* client.close();
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* Sending multiple buffers might be faster or slower depending on the
|
||||
* application and operating system. Run benchmarks to
|
||||
* determine the optimal strategy on a case-by-case basis. Generally speaking,
|
||||
* however, sending multiple buffers is faster.
|
||||
*
|
||||
* Example of sending a UDP packet using a socket connected to a port on `localhost`:
|
||||
*
|
||||
* ```js
|
||||
* import dgram from 'node:dgram';
|
||||
* import { Buffer } from 'node:buffer';
|
||||
*
|
||||
* const message = Buffer.from('Some bytes');
|
||||
* const client = dgram.createSocket('udp4');
|
||||
* client.connect(41234, 'localhost', (err) => {
|
||||
* client.send(message, (err) => {
|
||||
* client.close();
|
||||
* });
|
||||
* });
|
||||
* ```
|
||||
* @since v0.1.99
|
||||
* @param msg Message to be sent.
|
||||
* @param offset Offset in the buffer where the message starts.
|
||||
* @param length Number of bytes in the message.
|
||||
* @param port Destination port.
|
||||
* @param address Destination host name or IP address.
|
||||
* @param callback Called when the message has been sent.
|
||||
*/
|
||||
send(
|
||||
msg: string | NodeJS.ArrayBufferView | readonly any[],
|
||||
port?: number,
|
||||
address?: string,
|
||||
callback?: (error: Error | null, bytes: number) => void,
|
||||
): void;
|
||||
send(
|
||||
msg: string | NodeJS.ArrayBufferView | readonly any[],
|
||||
port?: number,
|
||||
callback?: (error: Error | null, bytes: number) => void,
|
||||
): void;
|
||||
send(
|
||||
msg: string | NodeJS.ArrayBufferView | readonly any[],
|
||||
callback?: (error: Error | null, bytes: number) => void,
|
||||
): void;
|
||||
send(
|
||||
msg: string | NodeJS.ArrayBufferView,
|
||||
offset: number,
|
||||
length: number,
|
||||
port?: number,
|
||||
address?: string,
|
||||
callback?: (error: Error | null, bytes: number) => void,
|
||||
): void;
|
||||
send(
|
||||
msg: string | NodeJS.ArrayBufferView,
|
||||
offset: number,
|
||||
length: number,
|
||||
port?: number,
|
||||
callback?: (error: Error | null, bytes: number) => void,
|
||||
): void;
|
||||
send(
|
||||
msg: string | NodeJS.ArrayBufferView,
|
||||
offset: number,
|
||||
length: number,
|
||||
callback?: (error: Error | null, bytes: number) => void,
|
||||
): void;
|
||||
/**
|
||||
* Sets or clears the `SO_BROADCAST` socket option. When set to `true`, UDP
|
||||
* packets may be sent to a local interface's broadcast address.
|
||||
*
|
||||
* This method throws `EBADF` if called on an unbound socket.
|
||||
* @since v0.6.9
|
||||
*/
|
||||
setBroadcast(flag: boolean): void;
|
||||
/**
|
||||
* _All references to scope in this section are referring to [IPv6 Zone Indices](https://en.wikipedia.org/wiki/IPv6_address#Scoped_literal_IPv6_addresses), which are defined by [RFC
|
||||
* 4007](https://tools.ietf.org/html/rfc4007). In string form, an IP_
|
||||
* _with a scope index is written as `'IP%scope'` where scope is an interface name_
|
||||
* _or interface number._
|
||||
*
|
||||
* Sets the default outgoing multicast interface of the socket to a chosen
|
||||
* interface or back to system interface selection. The `multicastInterface` must
|
||||
* be a valid string representation of an IP from the socket's family.
|
||||
*
|
||||
* For IPv4 sockets, this should be the IP configured for the desired physical
|
||||
* interface. All packets sent to multicast on the socket will be sent on the
|
||||
* interface determined by the most recent successful use of this call.
|
||||
*
|
||||
* For IPv6 sockets, `multicastInterface` should include a scope to indicate the
|
||||
* interface as in the examples that follow. In IPv6, individual `send` calls can
|
||||
* also use explicit scope in addresses, so only packets sent to a multicast
|
||||
* address without specifying an explicit scope are affected by the most recent
|
||||
* successful use of this call.
|
||||
*
|
||||
* This method throws `EBADF` if called on an unbound socket.
|
||||
*
|
||||
* #### Example: IPv6 outgoing multicast interface
|
||||
*
|
||||
* On most systems, where scope format uses the interface name:
|
||||
*
|
||||
* ```js
|
||||
* const socket = dgram.createSocket('udp6');
|
||||
*
|
||||
* socket.bind(1234, () => {
|
||||
* socket.setMulticastInterface('::%eth1');
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* On Windows, where scope format uses an interface number:
|
||||
*
|
||||
* ```js
|
||||
* const socket = dgram.createSocket('udp6');
|
||||
*
|
||||
* socket.bind(1234, () => {
|
||||
* socket.setMulticastInterface('::%2');
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* #### Example: IPv4 outgoing multicast interface
|
||||
*
|
||||
* All systems use an IP of the host on the desired physical interface:
|
||||
*
|
||||
* ```js
|
||||
* const socket = dgram.createSocket('udp4');
|
||||
*
|
||||
* socket.bind(1234, () => {
|
||||
* socket.setMulticastInterface('10.0.0.2');
|
||||
* });
|
||||
* ```
|
||||
* @since v8.6.0
|
||||
*/
|
||||
setMulticastInterface(multicastInterface: string): void;
|
||||
/**
|
||||
* Sets or clears the `IP_MULTICAST_LOOP` socket option. When set to `true`,
|
||||
* multicast packets will also be received on the local interface.
|
||||
*
|
||||
* This method throws `EBADF` if called on an unbound socket.
|
||||
* @since v0.3.8
|
||||
*/
|
||||
setMulticastLoopback(flag: boolean): boolean;
|
||||
/**
|
||||
* Sets the `IP_MULTICAST_TTL` socket option. While TTL generally stands for
|
||||
* "Time to Live", in this context it specifies the number of IP hops that a
|
||||
* packet is allowed to travel through, specifically for multicast traffic. Each
|
||||
* router or gateway that forwards a packet decrements the TTL. If the TTL is
|
||||
* decremented to 0 by a router, it will not be forwarded.
|
||||
*
|
||||
* The `ttl` argument may be between 0 and 255\. The default on most systems is `1`.
|
||||
*
|
||||
* This method throws `EBADF` if called on an unbound socket.
|
||||
* @since v0.3.8
|
||||
*/
|
||||
setMulticastTTL(ttl: number): number;
|
||||
/**
|
||||
* Sets the `SO_RCVBUF` socket option. Sets the maximum socket receive buffer
|
||||
* in bytes.
|
||||
*
|
||||
* This method throws `ERR_SOCKET_BUFFER_SIZE` if called on an unbound socket.
|
||||
* @since v8.7.0
|
||||
*/
|
||||
setRecvBufferSize(size: number): void;
|
||||
/**
|
||||
* Sets the `SO_SNDBUF` socket option. Sets the maximum socket send buffer
|
||||
* in bytes.
|
||||
*
|
||||
* This method throws `ERR_SOCKET_BUFFER_SIZE` if called on an unbound socket.
|
||||
* @since v8.7.0
|
||||
*/
|
||||
setSendBufferSize(size: number): void;
|
||||
/**
|
||||
* Sets the `IP_TTL` socket option. While TTL generally stands for "Time to Live",
|
||||
* in this context it specifies the number of IP hops that a packet is allowed to
|
||||
* travel through. Each router or gateway that forwards a packet decrements the
|
||||
* TTL. If the TTL is decremented to 0 by a router, it will not be forwarded.
|
||||
* Changing TTL values is typically done for network probes or when multicasting.
|
||||
*
|
||||
* The `ttl` argument may be between 1 and 255\. The default on most systems
|
||||
* is 64.
|
||||
*
|
||||
* This method throws `EBADF` if called on an unbound socket.
|
||||
* @since v0.1.101
|
||||
*/
|
||||
setTTL(ttl: number): number;
|
||||
/**
|
||||
* By default, binding a socket will cause it to block the Node.js process from
|
||||
* exiting as long as the socket is open. The `socket.unref()` method can be used
|
||||
* to exclude the socket from the reference counting that keeps the Node.js
|
||||
* process active, allowing the process to exit even if the socket is still
|
||||
* listening.
|
||||
*
|
||||
* Calling `socket.unref()` multiple times will have no additional effect.
|
||||
*
|
||||
* The `socket.unref()` method returns a reference to the socket so calls can be
|
||||
* chained.
|
||||
* @since v0.9.1
|
||||
*/
|
||||
unref(): this;
|
||||
/**
|
||||
* Tells the kernel to join a source-specific multicast channel at the given `sourceAddress` and `groupAddress`, using the `multicastInterface` with the `IP_ADD_SOURCE_MEMBERSHIP` socket
|
||||
* option. If the `multicastInterface` argument
|
||||
* is not specified, the operating system will choose one interface and will add
|
||||
* membership to it. To add membership to every available interface, call `socket.addSourceSpecificMembership()` multiple times, once per interface.
|
||||
*
|
||||
* When called on an unbound socket, this method will implicitly bind to a random
|
||||
* port, listening on all interfaces.
|
||||
* @since v13.1.0, v12.16.0
|
||||
*/
|
||||
addSourceSpecificMembership(sourceAddress: string, groupAddress: string, multicastInterface?: string): void;
|
||||
/**
|
||||
* Instructs the kernel to leave a source-specific multicast channel at the given `sourceAddress` and `groupAddress` using the `IP_DROP_SOURCE_MEMBERSHIP` socket option. This method is
|
||||
* automatically called by the kernel when the
|
||||
* socket is closed or the process terminates, so most apps will never have
|
||||
* reason to call this.
|
||||
*
|
||||
* If `multicastInterface` is not specified, the operating system will attempt to
|
||||
* drop membership on all valid interfaces.
|
||||
* @since v13.1.0, v12.16.0
|
||||
*/
|
||||
dropSourceSpecificMembership(sourceAddress: string, groupAddress: string, multicastInterface?: string): void;
|
||||
/**
|
||||
* events.EventEmitter
|
||||
* 1. close
|
||||
* 2. connect
|
||||
* 3. error
|
||||
* 4. listening
|
||||
* 5. message
|
||||
*/
|
||||
addListener(event: string, listener: (...args: any[]) => void): this;
|
||||
addListener(event: "close", listener: () => void): this;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
/**
|
||||
* Calls `socket.close()` and returns a promise that fulfills when the socket has closed.
|
||||
* @since v20.5.0
|
||||
*/
|
||||
[Symbol.asyncDispose](): Promise<void>;
|
||||
}
|
||||
}
|
||||
declare module "node:dgram" {
|
||||
export * from "dgram";
|
||||
}
|
||||
578
node_modules/@types/node/diagnostics_channel.d.ts
generated
vendored
Normal file
@@ -0,0 +1,578 @@
|
||||
/**
|
||||
* The `node:diagnostics_channel` module provides an API to create named channels
|
||||
* to report arbitrary message data for diagnostics purposes.
|
||||
*
|
||||
* It can be accessed using:
|
||||
*
|
||||
* ```js
|
||||
* import diagnostics_channel from 'node:diagnostics_channel';
|
||||
* ```
|
||||
*
|
||||
* It is intended that a module writer wanting to report diagnostics messages
|
||||
* will create one or many top-level channels to report messages through.
|
||||
* Channels may also be acquired at runtime but it is not encouraged
|
||||
* due to the additional overhead of doing so. Channels may be exported for
|
||||
* convenience, but as long as the name is known it can be acquired anywhere.
|
||||
*
|
||||
* If you intend for your module to produce diagnostics data for others to
|
||||
* consume it is recommended that you include documentation of what named
|
||||
* channels are used along with the shape of the message data. Channel names
|
||||
* 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/v24.x/lib/diagnostics_channel.js)
|
||||
*/
|
||||
declare module "diagnostics_channel" {
|
||||
import { AsyncLocalStorage } from "node:async_hooks";
|
||||
/**
|
||||
* Check if there are active subscribers to the named channel. This is helpful if
|
||||
* the message you want to send might be expensive to prepare.
|
||||
*
|
||||
* This API is optional but helpful when trying to publish messages from very
|
||||
* performance-sensitive code.
|
||||
*
|
||||
* ```js
|
||||
* import diagnostics_channel from 'node:diagnostics_channel';
|
||||
*
|
||||
* if (diagnostics_channel.hasSubscribers('my-channel')) {
|
||||
* // There are subscribers, prepare and publish message
|
||||
* }
|
||||
* ```
|
||||
* @since v15.1.0, v14.17.0
|
||||
* @param name The channel name
|
||||
* @return If there are active subscribers
|
||||
*/
|
||||
function hasSubscribers(name: string | symbol): boolean;
|
||||
/**
|
||||
* This is the primary entry-point for anyone wanting to publish to a named
|
||||
* channel. It produces a channel object which is optimized to reduce overhead at
|
||||
* publish time as much as possible.
|
||||
*
|
||||
* ```js
|
||||
* import diagnostics_channel from 'node:diagnostics_channel';
|
||||
*
|
||||
* const channel = diagnostics_channel.channel('my-channel');
|
||||
* ```
|
||||
* @since v15.1.0, v14.17.0
|
||||
* @param name The channel name
|
||||
* @return The named channel object
|
||||
*/
|
||||
function channel(name: string | symbol): Channel;
|
||||
type ChannelListener = (message: unknown, name: string | symbol) => void;
|
||||
/**
|
||||
* Register a message handler to subscribe to this channel. This message handler
|
||||
* will be run synchronously whenever a message is published to the channel. Any
|
||||
* errors thrown in the message handler will trigger an `'uncaughtException'`.
|
||||
*
|
||||
* ```js
|
||||
* import diagnostics_channel from 'node:diagnostics_channel';
|
||||
*
|
||||
* diagnostics_channel.subscribe('my-channel', (message, name) => {
|
||||
* // Received data
|
||||
* });
|
||||
* ```
|
||||
* @since v18.7.0, v16.17.0
|
||||
* @param name The channel name
|
||||
* @param onMessage The handler to receive channel messages
|
||||
*/
|
||||
function subscribe(name: string | symbol, onMessage: ChannelListener): void;
|
||||
/**
|
||||
* Remove a message handler previously registered to this channel with {@link subscribe}.
|
||||
*
|
||||
* ```js
|
||||
* import diagnostics_channel from 'node:diagnostics_channel';
|
||||
*
|
||||
* function onMessage(message, name) {
|
||||
* // Received data
|
||||
* }
|
||||
*
|
||||
* diagnostics_channel.subscribe('my-channel', onMessage);
|
||||
*
|
||||
* diagnostics_channel.unsubscribe('my-channel', onMessage);
|
||||
* ```
|
||||
* @since v18.7.0, v16.17.0
|
||||
* @param name The channel name
|
||||
* @param onMessage The previous subscribed handler to remove
|
||||
* @return `true` if the handler was found, `false` otherwise.
|
||||
*/
|
||||
function unsubscribe(name: string | symbol, onMessage: ChannelListener): boolean;
|
||||
/**
|
||||
* Creates a `TracingChannel` wrapper for the given `TracingChannel Channels`. If a name is given, the corresponding tracing
|
||||
* channels will be created in the form of `tracing:${name}:${eventType}` where `eventType` corresponds to the types of `TracingChannel Channels`.
|
||||
*
|
||||
* ```js
|
||||
* import diagnostics_channel from 'node:diagnostics_channel';
|
||||
*
|
||||
* const channelsByName = diagnostics_channel.tracingChannel('my-channel');
|
||||
*
|
||||
* // or...
|
||||
*
|
||||
* const channelsByCollection = diagnostics_channel.tracingChannel({
|
||||
* start: diagnostics_channel.channel('tracing:my-channel:start'),
|
||||
* end: diagnostics_channel.channel('tracing:my-channel:end'),
|
||||
* asyncStart: diagnostics_channel.channel('tracing:my-channel:asyncStart'),
|
||||
* asyncEnd: diagnostics_channel.channel('tracing:my-channel:asyncEnd'),
|
||||
* error: diagnostics_channel.channel('tracing:my-channel:error'),
|
||||
* });
|
||||
* ```
|
||||
* @since v19.9.0
|
||||
* @experimental
|
||||
* @param nameOrChannels Channel name or object containing all the `TracingChannel Channels`
|
||||
* @return Collection of channels to trace with
|
||||
*/
|
||||
function tracingChannel<
|
||||
StoreType = unknown,
|
||||
ContextType extends object = StoreType extends object ? StoreType : object,
|
||||
>(
|
||||
nameOrChannels: string | TracingChannelCollection<StoreType, ContextType>,
|
||||
): TracingChannel<StoreType, ContextType>;
|
||||
/**
|
||||
* The class `Channel` represents an individual named channel within the data
|
||||
* pipeline. It is used to track subscribers and to publish messages when there
|
||||
* are subscribers present. It exists as a separate object to avoid channel
|
||||
* lookups at publish time, enabling very fast publish speeds and allowing
|
||||
* for heavy use while incurring very minimal cost. Channels are created with {@link channel}, constructing a channel directly
|
||||
* with `new Channel(name)` is not supported.
|
||||
* @since v15.1.0, v14.17.0
|
||||
*/
|
||||
class Channel<StoreType = unknown, ContextType = StoreType> {
|
||||
readonly name: string | symbol;
|
||||
/**
|
||||
* Check if there are active subscribers to this channel. This is helpful if
|
||||
* the message you want to send might be expensive to prepare.
|
||||
*
|
||||
* This API is optional but helpful when trying to publish messages from very
|
||||
* performance-sensitive code.
|
||||
*
|
||||
* ```js
|
||||
* import diagnostics_channel from 'node:diagnostics_channel';
|
||||
*
|
||||
* const channel = diagnostics_channel.channel('my-channel');
|
||||
*
|
||||
* if (channel.hasSubscribers) {
|
||||
* // There are subscribers, prepare and publish message
|
||||
* }
|
||||
* ```
|
||||
* @since v15.1.0, v14.17.0
|
||||
*/
|
||||
readonly hasSubscribers: boolean;
|
||||
private constructor(name: string | symbol);
|
||||
/**
|
||||
* Publish a message to any subscribers to the channel. This will trigger
|
||||
* message handlers synchronously so they will execute within the same context.
|
||||
*
|
||||
* ```js
|
||||
* import diagnostics_channel from 'node:diagnostics_channel';
|
||||
*
|
||||
* const channel = diagnostics_channel.channel('my-channel');
|
||||
*
|
||||
* channel.publish({
|
||||
* some: 'message',
|
||||
* });
|
||||
* ```
|
||||
* @since v15.1.0, v14.17.0
|
||||
* @param message The message to send to the channel subscribers
|
||||
*/
|
||||
publish(message: unknown): void;
|
||||
/**
|
||||
* Register a message handler to subscribe to this channel. This message handler
|
||||
* will be run synchronously whenever a message is published to the channel. Any
|
||||
* errors thrown in the message handler will trigger an `'uncaughtException'`.
|
||||
*
|
||||
* ```js
|
||||
* import diagnostics_channel from 'node:diagnostics_channel';
|
||||
*
|
||||
* const channel = diagnostics_channel.channel('my-channel');
|
||||
*
|
||||
* channel.subscribe((message, name) => {
|
||||
* // Received data
|
||||
* });
|
||||
* ```
|
||||
* @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;
|
||||
/**
|
||||
* Remove a message handler previously registered to this channel with `channel.subscribe(onMessage)`.
|
||||
*
|
||||
* ```js
|
||||
* import diagnostics_channel from 'node:diagnostics_channel';
|
||||
*
|
||||
* const channel = diagnostics_channel.channel('my-channel');
|
||||
*
|
||||
* function onMessage(message, name) {
|
||||
* // Received data
|
||||
* }
|
||||
*
|
||||
* channel.subscribe(onMessage);
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
unsubscribe(onMessage: ChannelListener): void;
|
||||
/**
|
||||
* When `channel.runStores(context, ...)` is called, the given context data
|
||||
* will be applied to any store bound to the channel. If the store has already been
|
||||
* bound the previous `transform` function will be replaced with the new one.
|
||||
* The `transform` function may be omitted to set the given context data as the
|
||||
* context directly.
|
||||
*
|
||||
* ```js
|
||||
* import diagnostics_channel from 'node:diagnostics_channel';
|
||||
* import { AsyncLocalStorage } from 'node:async_hooks';
|
||||
*
|
||||
* const store = new AsyncLocalStorage();
|
||||
*
|
||||
* const channel = diagnostics_channel.channel('my-channel');
|
||||
*
|
||||
* channel.bindStore(store, (data) => {
|
||||
* return { data };
|
||||
* });
|
||||
* ```
|
||||
* @since v19.9.0
|
||||
* @experimental
|
||||
* @param store The store to which to bind the context data
|
||||
* @param transform Transform context data before setting the store context
|
||||
*/
|
||||
bindStore(store: AsyncLocalStorage<StoreType>, transform?: (context: ContextType) => StoreType): void;
|
||||
/**
|
||||
* Remove a message handler previously registered to this channel with `channel.bindStore(store)`.
|
||||
*
|
||||
* ```js
|
||||
* import diagnostics_channel from 'node:diagnostics_channel';
|
||||
* import { AsyncLocalStorage } from 'node:async_hooks';
|
||||
*
|
||||
* const store = new AsyncLocalStorage();
|
||||
*
|
||||
* const channel = diagnostics_channel.channel('my-channel');
|
||||
*
|
||||
* channel.bindStore(store);
|
||||
* channel.unbindStore(store);
|
||||
* ```
|
||||
* @since v19.9.0
|
||||
* @experimental
|
||||
* @param store The store to unbind from the channel.
|
||||
* @return `true` if the store was found, `false` otherwise.
|
||||
*/
|
||||
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
|
||||
* the scope of that data is applied to the stores.
|
||||
*
|
||||
* If a transform function was given to `channel.bindStore(store)` it will be
|
||||
* applied to transform the message data before it becomes the context value for
|
||||
* the store. The prior storage context is accessible from within the transform
|
||||
* function in cases where context linking is required.
|
||||
*
|
||||
* The context applied to the store should be accessible in any async code which
|
||||
* continues from execution which began during the given function, however
|
||||
* there are some situations in which `context loss` may occur.
|
||||
*
|
||||
* ```js
|
||||
* import diagnostics_channel from 'node:diagnostics_channel';
|
||||
* import { AsyncLocalStorage } from 'node:async_hooks';
|
||||
*
|
||||
* const store = new AsyncLocalStorage();
|
||||
*
|
||||
* const channel = diagnostics_channel.channel('my-channel');
|
||||
*
|
||||
* channel.bindStore(store, (message) => {
|
||||
* const parent = store.getStore();
|
||||
* return new Span(message, parent);
|
||||
* });
|
||||
* channel.runStores({ some: 'message' }, () => {
|
||||
* store.getStore(); // Span({ some: 'message' })
|
||||
* });
|
||||
* ```
|
||||
* @since v19.9.0
|
||||
* @experimental
|
||||
* @param context Message to send to subscribers and bind to stores
|
||||
* @param fn Handler to run within the entered storage context
|
||||
* @param thisArg The receiver to be used for the function call.
|
||||
* @param args Optional arguments to pass to the function.
|
||||
*/
|
||||
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;
|
||||
end: (
|
||||
message: ContextType & {
|
||||
error?: unknown;
|
||||
result?: unknown;
|
||||
},
|
||||
) => void;
|
||||
asyncStart: (
|
||||
message: ContextType & {
|
||||
error?: unknown;
|
||||
result?: unknown;
|
||||
},
|
||||
) => void;
|
||||
asyncEnd: (
|
||||
message: ContextType & {
|
||||
error?: unknown;
|
||||
result?: unknown;
|
||||
},
|
||||
) => void;
|
||||
error: (
|
||||
message: ContextType & {
|
||||
error: unknown;
|
||||
},
|
||||
) => void;
|
||||
}
|
||||
interface TracingChannelCollection<StoreType = unknown, ContextType = StoreType> {
|
||||
start: Channel<StoreType, ContextType>;
|
||||
end: Channel<StoreType, ContextType>;
|
||||
asyncStart: Channel<StoreType, ContextType>;
|
||||
asyncEnd: Channel<StoreType, ContextType>;
|
||||
error: Channel<StoreType, ContextType>;
|
||||
}
|
||||
/**
|
||||
* The class `TracingChannel` is a collection of `TracingChannel Channels` which
|
||||
* together express a single traceable action. It is used to formalize and
|
||||
* simplify the process of producing events for tracing application flow. {@link tracingChannel} is used to construct a `TracingChannel`. As with `Channel` it is recommended to create and reuse a
|
||||
* single `TracingChannel` at the top-level of the file rather than creating them
|
||||
* dynamically.
|
||||
* @since v19.9.0
|
||||
* @experimental
|
||||
*/
|
||||
class TracingChannel<StoreType = unknown, ContextType extends object = {}> implements TracingChannelCollection {
|
||||
start: Channel<StoreType, ContextType>;
|
||||
end: Channel<StoreType, ContextType>;
|
||||
asyncStart: Channel<StoreType, ContextType>;
|
||||
asyncEnd: Channel<StoreType, ContextType>;
|
||||
error: Channel<StoreType, ContextType>;
|
||||
/**
|
||||
* Helper to subscribe a collection of functions to the corresponding channels.
|
||||
* This is the same as calling `channel.subscribe(onMessage)` on each channel
|
||||
* individually.
|
||||
*
|
||||
* ```js
|
||||
* import diagnostics_channel from 'node:diagnostics_channel';
|
||||
*
|
||||
* const channels = diagnostics_channel.tracingChannel('my-channel');
|
||||
*
|
||||
* channels.subscribe({
|
||||
* start(message) {
|
||||
* // Handle start message
|
||||
* },
|
||||
* end(message) {
|
||||
* // Handle end message
|
||||
* },
|
||||
* asyncStart(message) {
|
||||
* // Handle asyncStart message
|
||||
* },
|
||||
* asyncEnd(message) {
|
||||
* // Handle asyncEnd message
|
||||
* },
|
||||
* error(message) {
|
||||
* // Handle error message
|
||||
* },
|
||||
* });
|
||||
* ```
|
||||
* @since v19.9.0
|
||||
* @experimental
|
||||
* @param subscribers Set of `TracingChannel Channels` subscribers
|
||||
*/
|
||||
subscribe(subscribers: TracingChannelSubscribers<ContextType>): void;
|
||||
/**
|
||||
* Helper to unsubscribe a collection of functions from the corresponding channels.
|
||||
* This is the same as calling `channel.unsubscribe(onMessage)` on each channel
|
||||
* individually.
|
||||
*
|
||||
* ```js
|
||||
* import diagnostics_channel from 'node:diagnostics_channel';
|
||||
*
|
||||
* const channels = diagnostics_channel.tracingChannel('my-channel');
|
||||
*
|
||||
* channels.unsubscribe({
|
||||
* start(message) {
|
||||
* // Handle start message
|
||||
* },
|
||||
* end(message) {
|
||||
* // Handle end message
|
||||
* },
|
||||
* asyncStart(message) {
|
||||
* // Handle asyncStart message
|
||||
* },
|
||||
* asyncEnd(message) {
|
||||
* // Handle asyncEnd message
|
||||
* },
|
||||
* error(message) {
|
||||
* // Handle error message
|
||||
* },
|
||||
* });
|
||||
* ```
|
||||
* @since v19.9.0
|
||||
* @experimental
|
||||
* @param subscribers Set of `TracingChannel Channels` subscribers
|
||||
* @return `true` if all handlers were successfully unsubscribed, and `false` otherwise.
|
||||
*/
|
||||
unsubscribe(subscribers: TracingChannelSubscribers<ContextType>): void;
|
||||
/**
|
||||
* Trace a synchronous function call. This will always produce a `start event` and `end event` around the execution and may produce an `error event` if the given function throws an error.
|
||||
* This will run the given function using `channel.runStores(context, ...)` on the `start` channel which ensures all
|
||||
* events should have any bound stores set to match this trace context.
|
||||
*
|
||||
* To ensure only correct trace graphs are formed, events will only be published if subscribers are present prior to starting the trace. Subscriptions
|
||||
* which are added after the trace begins will not receive future events from that trace, only future traces will be seen.
|
||||
*
|
||||
* ```js
|
||||
* import diagnostics_channel from 'node:diagnostics_channel';
|
||||
*
|
||||
* const channels = diagnostics_channel.tracingChannel('my-channel');
|
||||
*
|
||||
* channels.traceSync(() => {
|
||||
* // Do something
|
||||
* }, {
|
||||
* some: 'thing',
|
||||
* });
|
||||
* ```
|
||||
* @since v19.9.0
|
||||
* @experimental
|
||||
* @param fn Function to wrap a trace around
|
||||
* @param context Shared object to correlate events through
|
||||
* @param thisArg The receiver to be used for the function call
|
||||
* @param args Optional arguments to pass to the function
|
||||
* @return The return value of the given function
|
||||
*/
|
||||
traceSync<ThisArg = any, Args extends any[] = any[], Result = any>(
|
||||
fn: (this: ThisArg, ...args: Args) => Result,
|
||||
context?: ContextType,
|
||||
thisArg?: ThisArg,
|
||||
...args: Args
|
||||
): 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
|
||||
* produce an `error event` if the given function throws an error or the
|
||||
* returned promise rejects. This will run the given function using `channel.runStores(context, ...)` on the `start` channel which ensures all
|
||||
* events should have any bound stores set to match this trace context.
|
||||
*
|
||||
* To ensure only correct trace graphs are formed, events will only be published if subscribers are present prior to starting the trace. Subscriptions
|
||||
* which are added after the trace begins will not receive future events from that trace, only future traces will be seen.
|
||||
*
|
||||
* ```js
|
||||
* import diagnostics_channel from 'node:diagnostics_channel';
|
||||
*
|
||||
* const channels = diagnostics_channel.tracingChannel('my-channel');
|
||||
*
|
||||
* channels.tracePromise(async () => {
|
||||
* // Do something
|
||||
* }, {
|
||||
* some: 'thing',
|
||||
* });
|
||||
* ```
|
||||
* @since v19.9.0
|
||||
* @experimental
|
||||
* @param fn Promise-returning function to wrap a trace around
|
||||
* @param context Shared object to correlate trace events through
|
||||
* @param thisArg The receiver to be used for the function call
|
||||
* @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[], Result = any>(
|
||||
fn: (this: ThisArg, ...args: Args) => Promise<Result>,
|
||||
context?: ContextType,
|
||||
thisArg?: ThisArg,
|
||||
...args: Args
|
||||
): 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
|
||||
* the returned
|
||||
* promise rejects. This will run the given function using `channel.runStores(context, ...)` on the `start` channel which ensures all
|
||||
* events should have any bound stores set to match this trace context.
|
||||
*
|
||||
* The `position` will be -1 by default to indicate the final argument should
|
||||
* be used as the callback.
|
||||
*
|
||||
* ```js
|
||||
* import diagnostics_channel from 'node:diagnostics_channel';
|
||||
*
|
||||
* const channels = diagnostics_channel.tracingChannel('my-channel');
|
||||
*
|
||||
* channels.traceCallback((arg1, callback) => {
|
||||
* // Do something
|
||||
* callback(null, 'result');
|
||||
* }, 1, {
|
||||
* some: 'thing',
|
||||
* }, thisArg, arg1, callback);
|
||||
* ```
|
||||
*
|
||||
* The callback will also be run with `channel.runStores(context, ...)` which
|
||||
* enables context loss recovery in some cases.
|
||||
*
|
||||
* To ensure only correct trace graphs are formed, events will only be published if subscribers are present prior to starting the trace. Subscriptions
|
||||
* which are added after the trace begins will not receive future events from that trace, only future traces will be seen.
|
||||
*
|
||||
* ```js
|
||||
* import diagnostics_channel from 'node:diagnostics_channel';
|
||||
* import { AsyncLocalStorage } from 'node:async_hooks';
|
||||
*
|
||||
* const channels = diagnostics_channel.tracingChannel('my-channel');
|
||||
* const myStore = new AsyncLocalStorage();
|
||||
*
|
||||
* // The start channel sets the initial store data to something
|
||||
* // and stores that store data value on the trace context object
|
||||
* channels.start.bindStore(myStore, (data) => {
|
||||
* const span = new Span(data);
|
||||
* data.span = span;
|
||||
* return span;
|
||||
* });
|
||||
*
|
||||
* // Then asyncStart can restore from that data it stored previously
|
||||
* channels.asyncStart.bindStore(myStore, (data) => {
|
||||
* return data.span;
|
||||
* });
|
||||
* ```
|
||||
* @since v19.9.0
|
||||
* @experimental
|
||||
* @param fn callback using function to wrap a trace around
|
||||
* @param position Zero-indexed argument position of expected callback
|
||||
* @param context Shared object to correlate trace events through
|
||||
* @param thisArg The receiver to be used for the function call
|
||||
* @param args Optional arguments to pass to the function
|
||||
* @return The return value of the given function
|
||||
*/
|
||||
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" {
|
||||
export * from "diagnostics_channel";
|
||||
}
|
||||
923
node_modules/@types/node/dns.d.ts
generated
vendored
Normal file
@@ -0,0 +1,923 @@
|
||||
/**
|
||||
* The `node:dns` module enables name resolution. For example, use it to look up IP
|
||||
* addresses of host names.
|
||||
*
|
||||
* Although named for the [Domain Name System (DNS)](https://en.wikipedia.org/wiki/Domain_Name_System), it does not always use the
|
||||
* DNS protocol for lookups. {@link lookup} uses the operating system
|
||||
* facilities to perform name resolution. It may not need to perform any network
|
||||
* communication. To perform name resolution the way other applications on the same
|
||||
* system do, use {@link lookup}.
|
||||
*
|
||||
* ```js
|
||||
* import dns from 'node:dns';
|
||||
*
|
||||
* dns.lookup('example.org', (err, address, family) => {
|
||||
* console.log('address: %j family: IPv%s', address, family);
|
||||
* });
|
||||
* // address: "93.184.216.34" family: IPv4
|
||||
* ```
|
||||
*
|
||||
* All other functions in the `node:dns` module connect to an actual DNS server to
|
||||
* perform name resolution. They will always use the network to perform DNS
|
||||
* queries. These functions do not use the same set of configuration files used by {@link lookup} (e.g. `/etc/hosts`). Use these functions to always perform
|
||||
* DNS queries, bypassing other name-resolution facilities.
|
||||
*
|
||||
* ```js
|
||||
* import dns from 'node:dns';
|
||||
*
|
||||
* dns.resolve4('archive.org', (err, addresses) => {
|
||||
* if (err) throw err;
|
||||
*
|
||||
* console.log(`addresses: ${JSON.stringify(addresses)}`);
|
||||
*
|
||||
* addresses.forEach((a) => {
|
||||
* dns.reverse(a, (err, hostnames) => {
|
||||
* if (err) {
|
||||
* throw err;
|
||||
* }
|
||||
* console.log(`reverse for ${a}: ${JSON.stringify(hostnames)}`);
|
||||
* });
|
||||
* });
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* 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";
|
||||
// Supported getaddrinfo flags.
|
||||
/**
|
||||
* Limits returned address types to the types of non-loopback addresses configured on the system. For example, IPv4 addresses are
|
||||
* only returned if the current system has at least one IPv4 address configured.
|
||||
*/
|
||||
export const ADDRCONFIG: number;
|
||||
/**
|
||||
* If the IPv6 family was specified, but no IPv6 addresses were found, then return IPv4 mapped IPv6 addresses. It is not supported
|
||||
* on some operating systems (e.g. FreeBSD 10.1).
|
||||
*/
|
||||
export const V4MAPPED: number;
|
||||
/**
|
||||
* If `dns.V4MAPPED` is specified, return resolved IPv6 addresses as
|
||||
* well as IPv4 mapped IPv6 addresses.
|
||||
*/
|
||||
export const ALL: number;
|
||||
export interface LookupOptions {
|
||||
/**
|
||||
* The record family. Must be `4`, `6`, or `0`. For backward compatibility reasons, `'IPv4'` and `'IPv6'` are interpreted
|
||||
* as `4` and `6` respectively. The value 0 indicates that either an IPv4 or IPv6 address is returned. If the value `0` is used
|
||||
* with `{ all: true } (see below)`, both IPv4 and IPv6 addresses are returned.
|
||||
* @default 0
|
||||
*/
|
||||
family?: number | "IPv4" | "IPv6" | undefined;
|
||||
/**
|
||||
* 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;
|
||||
/**
|
||||
* When `true`, the callback returns all resolved addresses in an array. Otherwise, returns a single address.
|
||||
* @default false
|
||||
*/
|
||||
all?: boolean | undefined;
|
||||
/**
|
||||
* 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-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}
|
||||
* @default true (addresses are not reordered)
|
||||
* @deprecated Please use `order` option
|
||||
*/
|
||||
verbatim?: boolean | undefined;
|
||||
}
|
||||
export interface LookupOneOptions extends LookupOptions {
|
||||
all?: false | undefined;
|
||||
}
|
||||
export interface LookupAllOptions extends LookupOptions {
|
||||
all: true;
|
||||
}
|
||||
export interface LookupAddress {
|
||||
/**
|
||||
* A string representation of an IPv4 or IPv6 address.
|
||||
*/
|
||||
address: string;
|
||||
/**
|
||||
* `4` or `6`, denoting the family of `address`, or `0` if the address is not an IPv4 or IPv6 address. `0` is a likely indicator of a
|
||||
* bug in the name resolution service used by the operating system.
|
||||
*/
|
||||
family: number;
|
||||
}
|
||||
/**
|
||||
* Resolves a host name (e.g. `'nodejs.org'`) into the first found A (IPv4) or
|
||||
* AAAA (IPv6) record. All `option` properties are optional. If `options` is an
|
||||
* integer, then it must be `4` or `6` – if `options` is `0` or not provided, then
|
||||
* IPv4 and IPv6 addresses are both returned if found.
|
||||
*
|
||||
* With the `all` option set to `true`, the arguments for `callback` change to `(err, addresses)`, with `addresses` being an array of objects with the
|
||||
* properties `address` and `family`.
|
||||
*
|
||||
* On error, `err` is an `Error` object, where `err.code` is the error code.
|
||||
* Keep in mind that `err.code` will be set to `'ENOTFOUND'` not only when
|
||||
* the host name does not exist but also when the lookup fails in other ways
|
||||
* such as no available file descriptors.
|
||||
*
|
||||
* `dns.lookup()` does not necessarily have anything to do with the DNS protocol.
|
||||
* 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-v24.x/api/dns.html#implementation-considerations)
|
||||
* before using `dns.lookup()`.
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* ```js
|
||||
* import dns from 'node:dns';
|
||||
* const options = {
|
||||
* family: 6,
|
||||
* hints: dns.ADDRCONFIG | dns.V4MAPPED,
|
||||
* };
|
||||
* dns.lookup('example.com', options, (err, address, family) =>
|
||||
* console.log('address: %j family: IPv%s', address, family));
|
||||
* // address: "2606:2800:220:1:248:1893:25c8:1946" family: IPv6
|
||||
*
|
||||
* // When options.all is true, the result will be an Array.
|
||||
* options.all = true;
|
||||
* dns.lookup('example.com', options, (err, addresses) =>
|
||||
* console.log('addresses: %j', addresses));
|
||||
* // 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-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
|
||||
*/
|
||||
export function lookup(
|
||||
hostname: string,
|
||||
family: number,
|
||||
callback: (err: NodeJS.ErrnoException | null, address: string, family: number) => void,
|
||||
): void;
|
||||
export function lookup(
|
||||
hostname: string,
|
||||
options: LookupOneOptions,
|
||||
callback: (err: NodeJS.ErrnoException | null, address: string, family: number) => void,
|
||||
): void;
|
||||
export function lookup(
|
||||
hostname: string,
|
||||
options: LookupAllOptions,
|
||||
callback: (err: NodeJS.ErrnoException | null, addresses: LookupAddress[]) => void,
|
||||
): void;
|
||||
export function lookup(
|
||||
hostname: string,
|
||||
options: LookupOptions,
|
||||
callback: (err: NodeJS.ErrnoException | null, address: string | LookupAddress[], family: number) => void,
|
||||
): void;
|
||||
export function lookup(
|
||||
hostname: string,
|
||||
callback: (err: NodeJS.ErrnoException | null, address: string, family: number) => void,
|
||||
): void;
|
||||
export namespace lookup {
|
||||
function __promisify__(hostname: string, options: LookupAllOptions): Promise<LookupAddress[]>;
|
||||
function __promisify__(hostname: string, options?: LookupOneOptions | number): Promise<LookupAddress>;
|
||||
function __promisify__(hostname: string, options: LookupOptions): Promise<LookupAddress | LookupAddress[]>;
|
||||
}
|
||||
/**
|
||||
* Resolves the given `address` and `port` into a host name and service using
|
||||
* the operating system's underlying `getnameinfo` implementation.
|
||||
*
|
||||
* 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-v24.x/api/errors.html#class-error) object,
|
||||
* where `err.code` is the error code.
|
||||
*
|
||||
* ```js
|
||||
* 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-v24.x/api/util.html#utilpromisifyoriginal) ed
|
||||
* version, it returns a `Promise` for an `Object` with `hostname` and `service` properties.
|
||||
* @since v0.11.14
|
||||
*/
|
||||
export function lookupService(
|
||||
address: string,
|
||||
port: number,
|
||||
callback: (err: NodeJS.ErrnoException | null, hostname: string, service: string) => void,
|
||||
): void;
|
||||
export namespace lookupService {
|
||||
function __promisify__(
|
||||
address: string,
|
||||
port: number,
|
||||
): Promise<{
|
||||
hostname: string;
|
||||
service: string;
|
||||
}>;
|
||||
}
|
||||
export interface ResolveOptions {
|
||||
ttl: boolean;
|
||||
}
|
||||
export interface ResolveWithTtlOptions extends ResolveOptions {
|
||||
ttl: true;
|
||||
}
|
||||
export interface RecordWithTtl {
|
||||
address: string;
|
||||
ttl: number;
|
||||
}
|
||||
/** @deprecated Use `AnyARecord` or `AnyAaaaRecord` instead. */
|
||||
export type AnyRecordWithTtl = AnyARecord | AnyAaaaRecord;
|
||||
export interface AnyARecord extends RecordWithTtl {
|
||||
type: "A";
|
||||
}
|
||||
export interface AnyAaaaRecord extends RecordWithTtl {
|
||||
type: "AAAA";
|
||||
}
|
||||
export interface CaaRecord {
|
||||
critical: number;
|
||||
issue?: string | undefined;
|
||||
issuewild?: string | undefined;
|
||||
iodef?: string | undefined;
|
||||
contactemail?: string | undefined;
|
||||
contactphone?: string | undefined;
|
||||
}
|
||||
export interface AnyCaaRecord extends CaaRecord {
|
||||
type: "CAA";
|
||||
}
|
||||
export interface MxRecord {
|
||||
priority: number;
|
||||
exchange: string;
|
||||
}
|
||||
export interface AnyMxRecord extends MxRecord {
|
||||
type: "MX";
|
||||
}
|
||||
export interface NaptrRecord {
|
||||
flags: string;
|
||||
service: string;
|
||||
regexp: string;
|
||||
replacement: string;
|
||||
order: number;
|
||||
preference: number;
|
||||
}
|
||||
export interface AnyNaptrRecord extends NaptrRecord {
|
||||
type: "NAPTR";
|
||||
}
|
||||
export interface SoaRecord {
|
||||
nsname: string;
|
||||
hostmaster: string;
|
||||
serial: number;
|
||||
refresh: number;
|
||||
retry: number;
|
||||
expire: number;
|
||||
minttl: number;
|
||||
}
|
||||
export interface AnySoaRecord extends SoaRecord {
|
||||
type: "SOA";
|
||||
}
|
||||
export interface SrvRecord {
|
||||
priority: number;
|
||||
weight: number;
|
||||
port: number;
|
||||
name: string;
|
||||
}
|
||||
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[];
|
||||
}
|
||||
export interface AnyNsRecord {
|
||||
type: "NS";
|
||||
value: string;
|
||||
}
|
||||
export interface AnyPtrRecord {
|
||||
type: "PTR";
|
||||
value: string;
|
||||
}
|
||||
export interface AnyCnameRecord {
|
||||
type: "CNAME";
|
||||
value: string;
|
||||
}
|
||||
export type AnyRecord =
|
||||
| AnyARecord
|
||||
| AnyAaaaRecord
|
||||
| AnyCaaRecord
|
||||
| AnyCnameRecord
|
||||
| AnyMxRecord
|
||||
| AnyNaptrRecord
|
||||
| AnyNsRecord
|
||||
| AnyPtrRecord
|
||||
| AnySoaRecord
|
||||
| AnySrvRecord
|
||||
| AnyTlsaRecord
|
||||
| AnyTxtRecord;
|
||||
/**
|
||||
* Uses the DNS protocol to resolve a host name (e.g. `'nodejs.org'`) into an array
|
||||
* of the resource records. The `callback` function has arguments `(err, records)`. When successful, `records` will be an array of resource
|
||||
* records. The type and structure of individual results varies based on `rrtype`:
|
||||
*
|
||||
* <omitted>
|
||||
*
|
||||
* 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.
|
||||
* @param [rrtype='A'] Resource record type.
|
||||
*/
|
||||
export function resolve(
|
||||
hostname: string,
|
||||
callback: (err: NodeJS.ErrnoException | null, addresses: string[]) => void,
|
||||
): void;
|
||||
export function resolve(
|
||||
hostname: string,
|
||||
rrtype: "A" | "AAAA" | "CNAME" | "NS" | "PTR",
|
||||
callback: (err: NodeJS.ErrnoException | null, addresses: string[]) => void,
|
||||
): void;
|
||||
export function resolve(
|
||||
hostname: string,
|
||||
rrtype: "ANY",
|
||||
callback: (err: NodeJS.ErrnoException | null, addresses: AnyRecord[]) => void,
|
||||
): void;
|
||||
export function resolve(
|
||||
hostname: string,
|
||||
rrtype: "CAA",
|
||||
callback: (err: NodeJS.ErrnoException | null, address: CaaRecord[]) => void,
|
||||
): void;
|
||||
export function resolve(
|
||||
hostname: string,
|
||||
rrtype: "MX",
|
||||
callback: (err: NodeJS.ErrnoException | null, addresses: MxRecord[]) => void,
|
||||
): void;
|
||||
export function resolve(
|
||||
hostname: string,
|
||||
rrtype: "NAPTR",
|
||||
callback: (err: NodeJS.ErrnoException | null, addresses: NaptrRecord[]) => void,
|
||||
): void;
|
||||
export function resolve(
|
||||
hostname: string,
|
||||
rrtype: "SOA",
|
||||
callback: (err: NodeJS.ErrnoException | null, addresses: SoaRecord) => void,
|
||||
): void;
|
||||
export function resolve(
|
||||
hostname: string,
|
||||
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",
|
||||
callback: (err: NodeJS.ErrnoException | null, addresses: string[][]) => void,
|
||||
): void;
|
||||
export function resolve(
|
||||
hostname: string,
|
||||
rrtype: string,
|
||||
callback: (
|
||||
err: NodeJS.ErrnoException | null,
|
||||
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[]
|
||||
| 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
|
||||
* will contain an array of IPv4 addresses (e.g.`['74.125.79.104', '74.125.79.105', '74.125.79.106']`).
|
||||
* @since v0.1.16
|
||||
* @param hostname Host name to resolve.
|
||||
*/
|
||||
export function resolve4(
|
||||
hostname: string,
|
||||
callback: (err: NodeJS.ErrnoException | null, addresses: string[]) => void,
|
||||
): void;
|
||||
export function resolve4(
|
||||
hostname: string,
|
||||
options: ResolveWithTtlOptions,
|
||||
callback: (err: NodeJS.ErrnoException | null, addresses: RecordWithTtl[]) => void,
|
||||
): void;
|
||||
export function resolve4(
|
||||
hostname: string,
|
||||
options: ResolveOptions,
|
||||
callback: (err: NodeJS.ErrnoException | null, addresses: string[] | RecordWithTtl[]) => void,
|
||||
): void;
|
||||
export namespace resolve4 {
|
||||
function __promisify__(hostname: string): Promise<string[]>;
|
||||
function __promisify__(hostname: string, options: ResolveWithTtlOptions): Promise<RecordWithTtl[]>;
|
||||
function __promisify__(hostname: string, options?: ResolveOptions): Promise<string[] | RecordWithTtl[]>;
|
||||
}
|
||||
/**
|
||||
* Uses the DNS protocol to resolve IPv6 addresses (`AAAA` records) for the `hostname`. The `addresses` argument passed to the `callback` function
|
||||
* will contain an array of IPv6 addresses.
|
||||
* @since v0.1.16
|
||||
* @param hostname Host name to resolve.
|
||||
*/
|
||||
export function resolve6(
|
||||
hostname: string,
|
||||
callback: (err: NodeJS.ErrnoException | null, addresses: string[]) => void,
|
||||
): void;
|
||||
export function resolve6(
|
||||
hostname: string,
|
||||
options: ResolveWithTtlOptions,
|
||||
callback: (err: NodeJS.ErrnoException | null, addresses: RecordWithTtl[]) => void,
|
||||
): void;
|
||||
export function resolve6(
|
||||
hostname: string,
|
||||
options: ResolveOptions,
|
||||
callback: (err: NodeJS.ErrnoException | null, addresses: string[] | RecordWithTtl[]) => void,
|
||||
): void;
|
||||
export namespace resolve6 {
|
||||
function __promisify__(hostname: string): Promise<string[]>;
|
||||
function __promisify__(hostname: string, options: ResolveWithTtlOptions): Promise<RecordWithTtl[]>;
|
||||
function __promisify__(hostname: string, options?: ResolveOptions): Promise<string[] | RecordWithTtl[]>;
|
||||
}
|
||||
/**
|
||||
* Uses the DNS protocol to resolve `CNAME` records for the `hostname`. The `addresses` argument passed to the `callback` function
|
||||
* will contain an array of canonical name records available for the `hostname` (e.g. `['bar.example.com']`).
|
||||
* @since v0.3.2
|
||||
*/
|
||||
export function resolveCname(
|
||||
hostname: string,
|
||||
callback: (err: NodeJS.ErrnoException | null, addresses: string[]) => void,
|
||||
): void;
|
||||
export namespace resolveCname {
|
||||
function __promisify__(hostname: string): Promise<string[]>;
|
||||
}
|
||||
/**
|
||||
* Uses the DNS protocol to resolve `CAA` records for the `hostname`. The `addresses` argument passed to the `callback` function
|
||||
* will contain an array of certification authority authorization records
|
||||
* available for the `hostname` (e.g. `[{critical: 0, iodef: 'mailto:pki@example.com'}, {critical: 128, issue: 'pki.example.com'}]`).
|
||||
* @since v15.0.0, v14.17.0
|
||||
*/
|
||||
export function resolveCaa(
|
||||
hostname: string,
|
||||
callback: (err: NodeJS.ErrnoException | null, records: CaaRecord[]) => void,
|
||||
): void;
|
||||
export namespace resolveCaa {
|
||||
function __promisify__(hostname: string): Promise<CaaRecord[]>;
|
||||
}
|
||||
/**
|
||||
* Uses the DNS protocol to resolve mail exchange records (`MX` records) for the `hostname`. The `addresses` argument passed to the `callback` function will
|
||||
* contain an array of objects containing both a `priority` and `exchange` property (e.g. `[{priority: 10, exchange: 'mx.example.com'}, ...]`).
|
||||
* @since v0.1.27
|
||||
*/
|
||||
export function resolveMx(
|
||||
hostname: string,
|
||||
callback: (err: NodeJS.ErrnoException | null, addresses: MxRecord[]) => void,
|
||||
): void;
|
||||
export namespace resolveMx {
|
||||
function __promisify__(hostname: string): Promise<MxRecord[]>;
|
||||
}
|
||||
/**
|
||||
* Uses the DNS protocol to resolve regular expression-based records (`NAPTR` records) for the `hostname`. The `addresses` argument passed to the `callback` function will contain an array of
|
||||
* objects with the following properties:
|
||||
*
|
||||
* * `flags`
|
||||
* * `service`
|
||||
* * `regexp`
|
||||
* * `replacement`
|
||||
* * `order`
|
||||
* * `preference`
|
||||
*
|
||||
* ```js
|
||||
* {
|
||||
* flags: 's',
|
||||
* service: 'SIP+D2U',
|
||||
* regexp: '',
|
||||
* replacement: '_sip._udp.example.com',
|
||||
* order: 30,
|
||||
* preference: 100
|
||||
* }
|
||||
* ```
|
||||
* @since v0.9.12
|
||||
*/
|
||||
export function resolveNaptr(
|
||||
hostname: string,
|
||||
callback: (err: NodeJS.ErrnoException | null, addresses: NaptrRecord[]) => void,
|
||||
): void;
|
||||
export namespace resolveNaptr {
|
||||
function __promisify__(hostname: string): Promise<NaptrRecord[]>;
|
||||
}
|
||||
/**
|
||||
* Uses the DNS protocol to resolve name server records (`NS` records) for the `hostname`. The `addresses` argument passed to the `callback` function will
|
||||
* contain an array of name server records available for `hostname` (e.g. `['ns1.example.com', 'ns2.example.com']`).
|
||||
* @since v0.1.90
|
||||
*/
|
||||
export function resolveNs(
|
||||
hostname: string,
|
||||
callback: (err: NodeJS.ErrnoException | null, addresses: string[]) => void,
|
||||
): void;
|
||||
export namespace resolveNs {
|
||||
function __promisify__(hostname: string): Promise<string[]>;
|
||||
}
|
||||
/**
|
||||
* Uses the DNS protocol to resolve pointer records (`PTR` records) for the `hostname`. The `addresses` argument passed to the `callback` function will
|
||||
* be an array of strings containing the reply records.
|
||||
* @since v6.0.0
|
||||
*/
|
||||
export function resolvePtr(
|
||||
hostname: string,
|
||||
callback: (err: NodeJS.ErrnoException | null, addresses: string[]) => void,
|
||||
): void;
|
||||
export namespace resolvePtr {
|
||||
function __promisify__(hostname: string): Promise<string[]>;
|
||||
}
|
||||
/**
|
||||
* Uses the DNS protocol to resolve a start of authority record (`SOA` record) for
|
||||
* the `hostname`. The `address` argument passed to the `callback` function will
|
||||
* be an object with the following properties:
|
||||
*
|
||||
* * `nsname`
|
||||
* * `hostmaster`
|
||||
* * `serial`
|
||||
* * `refresh`
|
||||
* * `retry`
|
||||
* * `expire`
|
||||
* * `minttl`
|
||||
*
|
||||
* ```js
|
||||
* {
|
||||
* nsname: 'ns.example.com',
|
||||
* hostmaster: 'root.example.com',
|
||||
* serial: 2013101809,
|
||||
* refresh: 10000,
|
||||
* retry: 2400,
|
||||
* expire: 604800,
|
||||
* minttl: 3600
|
||||
* }
|
||||
* ```
|
||||
* @since v0.11.10
|
||||
*/
|
||||
export function resolveSoa(
|
||||
hostname: string,
|
||||
callback: (err: NodeJS.ErrnoException | null, address: SoaRecord) => void,
|
||||
): void;
|
||||
export namespace resolveSoa {
|
||||
function __promisify__(hostname: string): Promise<SoaRecord>;
|
||||
}
|
||||
/**
|
||||
* Uses the DNS protocol to resolve service records (`SRV` records) for the `hostname`. The `addresses` argument passed to the `callback` function will
|
||||
* be an array of objects with the following properties:
|
||||
*
|
||||
* * `priority`
|
||||
* * `weight`
|
||||
* * `port`
|
||||
* * `name`
|
||||
*
|
||||
* ```js
|
||||
* {
|
||||
* priority: 10,
|
||||
* weight: 5,
|
||||
* port: 21223,
|
||||
* name: 'service.example.com'
|
||||
* }
|
||||
* ```
|
||||
* @since v0.1.27
|
||||
*/
|
||||
export function resolveSrv(
|
||||
hostname: string,
|
||||
callback: (err: NodeJS.ErrnoException | null, addresses: SrvRecord[]) => void,
|
||||
): void;
|
||||
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
|
||||
* one record. Depending on the use case, these could be either joined together or
|
||||
* treated separately.
|
||||
* @since v0.1.27
|
||||
*/
|
||||
export function resolveTxt(
|
||||
hostname: string,
|
||||
callback: (err: NodeJS.ErrnoException | null, addresses: string[][]) => void,
|
||||
): void;
|
||||
export namespace resolveTxt {
|
||||
function __promisify__(hostname: string): Promise<string[][]>;
|
||||
}
|
||||
/**
|
||||
* Uses the DNS protocol to resolve all records (also known as `ANY` or `*` query).
|
||||
* The `ret` argument passed to the `callback` function will be an array containing
|
||||
* various types of records. Each object has a property `type` that indicates the
|
||||
* type of the current record. And depending on the `type`, additional properties
|
||||
* will be present on the object:
|
||||
*
|
||||
* <omitted>
|
||||
*
|
||||
* Here is an example of the `ret` object passed to the callback:
|
||||
*
|
||||
* ```js
|
||||
* [ { type: 'A', address: '127.0.0.1', ttl: 299 },
|
||||
* { type: 'CNAME', value: 'example.com' },
|
||||
* { type: 'MX', exchange: 'alt4.aspmx.l.example.com', priority: 50 },
|
||||
* { type: 'NS', value: 'ns1.example.com' },
|
||||
* { type: 'TXT', entries: [ 'v=spf1 include:_spf.example.com ~all' ] },
|
||||
* { type: 'SOA',
|
||||
* nsname: 'ns1.example.com',
|
||||
* hostmaster: 'admin.example.com',
|
||||
* serial: 156696742,
|
||||
* refresh: 900,
|
||||
* retry: 900,
|
||||
* expire: 1800,
|
||||
* minttl: 60 } ]
|
||||
* ```
|
||||
*
|
||||
* DNS server operators may choose not to respond to `ANY` queries. It may be better to call individual methods like {@link resolve4}, {@link resolveMx}, and so on. For more details, see
|
||||
* [RFC 8482](https://tools.ietf.org/html/rfc8482).
|
||||
*/
|
||||
export function resolveAny(
|
||||
hostname: string,
|
||||
callback: (err: NodeJS.ErrnoException | null, addresses: AnyRecord[]) => void,
|
||||
): void;
|
||||
export namespace resolveAny {
|
||||
function __promisify__(hostname: string): Promise<AnyRecord[]>;
|
||||
}
|
||||
/**
|
||||
* 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-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(
|
||||
ip: string,
|
||||
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-v24.x/api/dns.html#dnspromiseslookuphostname-options).
|
||||
* The value could be:
|
||||
*
|
||||
* * `ipv4first`: for `order` defaulting to `ipv4first`.
|
||||
* * `ipv6first`: for `order` defaulting to `ipv6first`.
|
||||
* * `verbatim`: for `order` defaulting to `verbatim`.
|
||||
* @since v18.17.0
|
||||
*/
|
||||
export function getDefaultResultOrder(): "ipv4first" | "ipv6first" | "verbatim";
|
||||
/**
|
||||
* Sets the IP address and port of servers to be used when performing DNS
|
||||
* resolution. The `servers` argument is an array of [RFC 5952](https://tools.ietf.org/html/rfc5952#section-6) formatted
|
||||
* addresses. If the port is the IANA default DNS port (53) it can be omitted.
|
||||
*
|
||||
* ```js
|
||||
* dns.setServers([
|
||||
* '4.4.4.4',
|
||||
* '[2001:4860:4860::8888]',
|
||||
* '4.4.4.4:1053',
|
||||
* '[2001:4860:4860::8888]:1053',
|
||||
* ]);
|
||||
* ```
|
||||
*
|
||||
* An error will be thrown if an invalid address is provided.
|
||||
*
|
||||
* The `dns.setServers()` method must not be called while a DNS query is in
|
||||
* progress.
|
||||
*
|
||||
* The {@link setServers} method affects only {@link resolve}, `dns.resolve*()` and {@link reverse} (and specifically _not_ {@link lookup}).
|
||||
*
|
||||
* This method works much like [resolve.conf](https://man7.org/linux/man-pages/man5/resolv.conf.5.html).
|
||||
* That is, if attempting to resolve with the first server provided results in a `NOTFOUND` error, the `resolve()` method will _not_ attempt to resolve with
|
||||
* subsequent servers provided. Fallback DNS servers will only be used if the
|
||||
* earlier ones time out or result in some other error.
|
||||
* @since v0.11.3
|
||||
* @param servers array of [RFC 5952](https://datatracker.ietf.org/doc/html/rfc5952#section-6) formatted addresses
|
||||
*/
|
||||
export function setServers(servers: readonly string[]): void;
|
||||
/**
|
||||
* Returns an array of IP address strings, formatted according to [RFC 5952](https://tools.ietf.org/html/rfc5952#section-6),
|
||||
* that are currently configured for DNS resolution. A string will include a port
|
||||
* section if a custom port is used.
|
||||
*
|
||||
* ```js
|
||||
* [
|
||||
* '4.4.4.4',
|
||||
* '2001:4860:4860::8888',
|
||||
* '4.4.4.4:1053',
|
||||
* '[2001:4860:4860::8888]:1053',
|
||||
* ]
|
||||
* ```
|
||||
* @since v0.11.3
|
||||
*/
|
||||
export function getServers(): string[];
|
||||
/**
|
||||
* 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`.
|
||||
* * `ipv6first`: sets default `order` to `ipv6first`.
|
||||
* * `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-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'`.
|
||||
*/
|
||||
export function setDefaultResultOrder(order: "ipv4first" | "ipv6first" | "verbatim"): void;
|
||||
// Error codes
|
||||
export const NODATA: "ENODATA";
|
||||
export const FORMERR: "EFORMERR";
|
||||
export const SERVFAIL: "ESERVFAIL";
|
||||
export const NOTFOUND: "ENOTFOUND";
|
||||
export const NOTIMP: "ENOTIMP";
|
||||
export const REFUSED: "EREFUSED";
|
||||
export const BADQUERY: "EBADQUERY";
|
||||
export const BADNAME: "EBADNAME";
|
||||
export const BADFAMILY: "EBADFAMILY";
|
||||
export const BADRESP: "EBADRESP";
|
||||
export const CONNREFUSED: "ECONNREFUSED";
|
||||
export const TIMEOUT: "ETIMEOUT";
|
||||
export const EOF: "EOF";
|
||||
export const FILE: "EFILE";
|
||||
export const NOMEM: "ENOMEM";
|
||||
export const DESTRUCTION: "EDESTRUCTION";
|
||||
export const BADSTR: "EBADSTR";
|
||||
export const BADFLAGS: "EBADFLAGS";
|
||||
export const NONAME: "ENONAME";
|
||||
export const BADHINTS: "EBADHINTS";
|
||||
export const NOTINITIALIZED: "ENOTINITIALIZED";
|
||||
export const LOADIPHLPAPI: "ELOADIPHLPAPI";
|
||||
export const ADDRGETNETWORKPARAMS: "EADDRGETNETWORKPARAMS";
|
||||
export const CANCELLED: "ECANCELLED";
|
||||
export interface ResolverOptions {
|
||||
/**
|
||||
* Query timeout in milliseconds, or `-1` to use the default timeout.
|
||||
*/
|
||||
timeout?: number | undefined;
|
||||
/**
|
||||
* The number of tries the resolver will try contacting each name server before giving up.
|
||||
* @default 4
|
||||
*/
|
||||
tries?: number;
|
||||
/**
|
||||
* 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-v24.x/api/dns.html#dnssetserversservers) does not affect
|
||||
* other resolvers:
|
||||
*
|
||||
* ```js
|
||||
* import { Resolver } from 'node:dns';
|
||||
* const resolver = new Resolver();
|
||||
* resolver.setServers(['4.4.4.4']);
|
||||
*
|
||||
* // This request will use the server at 4.4.4.4, independent of global settings.
|
||||
* resolver.resolve4('example.org', (err, addresses) => {
|
||||
* // ...
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* The following methods from the `node:dns` module are available:
|
||||
*
|
||||
* * `resolver.getServers()`
|
||||
* * `resolver.resolve()`
|
||||
* * `resolver.resolve4()`
|
||||
* * `resolver.resolve6()`
|
||||
* * `resolver.resolveAny()`
|
||||
* * `resolver.resolveCaa()`
|
||||
* * `resolver.resolveCname()`
|
||||
* * `resolver.resolveMx()`
|
||||
* * `resolver.resolveNaptr()`
|
||||
* * `resolver.resolveNs()`
|
||||
* * `resolver.resolvePtr()`
|
||||
* * `resolver.resolveSoa()`
|
||||
* * `resolver.resolveSrv()`
|
||||
* * `resolver.resolveTxt()`
|
||||
* * `resolver.reverse()`
|
||||
* * `resolver.setServers()`
|
||||
* @since v8.3.0
|
||||
*/
|
||||
export class Resolver {
|
||||
constructor(options?: ResolverOptions);
|
||||
/**
|
||||
* Cancel all outstanding DNS queries made by this resolver. The corresponding
|
||||
* callbacks will be called with an error with code `ECANCELLED`.
|
||||
* @since v8.3.0
|
||||
*/
|
||||
cancel(): void;
|
||||
getServers: typeof getServers;
|
||||
resolve: typeof resolve;
|
||||
resolve4: typeof resolve4;
|
||||
resolve6: typeof resolve6;
|
||||
resolveAny: typeof resolveAny;
|
||||
resolveCaa: typeof resolveCaa;
|
||||
resolveCname: typeof resolveCname;
|
||||
resolveMx: typeof resolveMx;
|
||||
resolveNaptr: typeof resolveNaptr;
|
||||
resolveNs: typeof resolveNs;
|
||||
resolvePtr: typeof resolvePtr;
|
||||
resolveSoa: typeof resolveSoa;
|
||||
resolveSrv: typeof resolveSrv;
|
||||
resolveTlsa: typeof resolveTlsa;
|
||||
resolveTxt: typeof resolveTxt;
|
||||
reverse: typeof reverse;
|
||||
/**
|
||||
* The resolver instance will send its requests from the specified IP address.
|
||||
* This allows programs to specify outbound interfaces when used on multi-homed
|
||||
* systems.
|
||||
*
|
||||
* If a v4 or v6 address is not specified, it is set to the default and the
|
||||
* operating system will choose a local address automatically.
|
||||
*
|
||||
* The resolver will use the v4 local address when making requests to IPv4 DNS
|
||||
* servers, and the v6 local address when making requests to IPv6 DNS servers.
|
||||
* The `rrtype` of resolution requests has no impact on the local address used.
|
||||
* @since v15.1.0, v14.17.0
|
||||
* @param [ipv4='0.0.0.0'] A string representation of an IPv4 address.
|
||||
* @param [ipv6='::0'] A string representation of an IPv6 address.
|
||||
*/
|
||||
setLocalAddress(ipv4?: string, ipv6?: string): void;
|
||||
setServers: typeof setServers;
|
||||
}
|
||||
export { dnsPromises as promises };
|
||||
}
|
||||
declare module "node:dns" {
|
||||
export * from "dns";
|
||||
}
|
||||
503
node_modules/@types/node/dns/promises.d.ts
generated
vendored
Normal file
@@ -0,0 +1,503 @@
|
||||
/**
|
||||
* 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 `import { promises as dnsPromises } from 'node:dns'` or `import dnsPromises from 'node:dns/promises'`.
|
||||
* @since v10.6.0
|
||||
*/
|
||||
declare module "dns/promises" {
|
||||
import {
|
||||
AnyRecord,
|
||||
CaaRecord,
|
||||
LookupAddress,
|
||||
LookupAllOptions,
|
||||
LookupOneOptions,
|
||||
LookupOptions,
|
||||
MxRecord,
|
||||
NaptrRecord,
|
||||
RecordWithTtl,
|
||||
ResolveOptions,
|
||||
ResolverOptions,
|
||||
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),
|
||||
* that are currently configured for DNS resolution. A string will include a port
|
||||
* section if a custom port is used.
|
||||
*
|
||||
* ```js
|
||||
* [
|
||||
* '4.4.4.4',
|
||||
* '2001:4860:4860::8888',
|
||||
* '4.4.4.4:1053',
|
||||
* '[2001:4860:4860::8888]:1053',
|
||||
* ]
|
||||
* ```
|
||||
* @since v10.6.0
|
||||
*/
|
||||
function getServers(): string[];
|
||||
/**
|
||||
* Resolves a host name (e.g. `'nodejs.org'`) into the first found A (IPv4) or
|
||||
* AAAA (IPv6) record. All `option` properties are optional. If `options` is an
|
||||
* integer, then it must be `4` or `6` – if `options` is not provided, then IPv4
|
||||
* and IPv6 addresses are both returned if found.
|
||||
*
|
||||
* With the `all` option set to `true`, the `Promise` is resolved with `addresses` being an array of objects with the properties `address` and `family`.
|
||||
*
|
||||
* 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.
|
||||
* Keep in mind that `err.code` will be set to `'ENOTFOUND'` not only when
|
||||
* the host name does not exist but also when the lookup fails in other ways
|
||||
* such as no available file descriptors.
|
||||
*
|
||||
* [`dnsPromises.lookup()`](https://nodejs.org/docs/latest-v20.x/api/dns.html#dnspromiseslookuphostname-options) does not necessarily have anything to do with the DNS
|
||||
* protocol. 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) before
|
||||
* using `dnsPromises.lookup()`.
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* ```js
|
||||
* import dns from 'node:dns';
|
||||
* const dnsPromises = dns.promises;
|
||||
* const options = {
|
||||
* family: 6,
|
||||
* hints: dns.ADDRCONFIG | dns.V4MAPPED,
|
||||
* };
|
||||
*
|
||||
* dnsPromises.lookup('example.com', options).then((result) => {
|
||||
* console.log('address: %j family: IPv%s', result.address, result.family);
|
||||
* // address: "2606:2800:220:1:248:1893:25c8:1946" family: IPv6
|
||||
* });
|
||||
*
|
||||
* // When options.all is true, the result will be an Array.
|
||||
* options.all = true;
|
||||
* dnsPromises.lookup('example.com', options).then((result) => {
|
||||
* console.log('addresses: %j', result);
|
||||
* // addresses: [{"address":"2606:2800:220:1:248:1893:25c8:1946","family":6}]
|
||||
* });
|
||||
* ```
|
||||
* @since v10.6.0
|
||||
*/
|
||||
function lookup(hostname: string, family: number): Promise<LookupAddress>;
|
||||
function lookup(hostname: string, options: LookupOneOptions): Promise<LookupAddress>;
|
||||
function lookup(hostname: string, options: LookupAllOptions): Promise<LookupAddress[]>;
|
||||
function lookup(hostname: string, options: LookupOptions): Promise<LookupAddress | LookupAddress[]>;
|
||||
function lookup(hostname: string): Promise<LookupAddress>;
|
||||
/**
|
||||
* Resolves the given `address` and `port` into a host name and service using
|
||||
* the operating system's underlying `getnameinfo` implementation.
|
||||
*
|
||||
* 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 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
|
||||
* import dnsPromises from 'node:dns';
|
||||
* dnsPromises.lookupService('127.0.0.1', 22).then((result) => {
|
||||
* console.log(result.hostname, result.service);
|
||||
* // Prints: localhost ssh
|
||||
* });
|
||||
* ```
|
||||
* @since v10.6.0
|
||||
*/
|
||||
function lookupService(
|
||||
address: string,
|
||||
port: number,
|
||||
): Promise<{
|
||||
hostname: string;
|
||||
service: string;
|
||||
}>;
|
||||
/**
|
||||
* Uses the DNS protocol to resolve a host name (e.g. `'nodejs.org'`) into an array
|
||||
* of the resource records. When successful, the `Promise` is resolved with an
|
||||
* array of resource records. The type and structure of individual results vary
|
||||
* based on `rrtype`:
|
||||
*
|
||||
* <omitted>
|
||||
*
|
||||
* 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 one of the [DNS error codes](https://nodejs.org/docs/latest-v20.x/api/dns.html#error-codes).
|
||||
* @since v10.6.0
|
||||
* @param hostname Host name to resolve.
|
||||
* @param [rrtype='A'] Resource record type.
|
||||
*/
|
||||
function resolve(hostname: string): 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: "MX"): Promise<MxRecord[]>;
|
||||
function resolve(hostname: string, rrtype: "NAPTR"): Promise<NaptrRecord[]>;
|
||||
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[]
|
||||
| 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']`).
|
||||
* @since v10.6.0
|
||||
* @param hostname Host name to resolve.
|
||||
*/
|
||||
function resolve4(hostname: string): Promise<string[]>;
|
||||
function resolve4(hostname: string, options: ResolveWithTtlOptions): Promise<RecordWithTtl[]>;
|
||||
function resolve4(hostname: string, options: ResolveOptions): Promise<string[] | RecordWithTtl[]>;
|
||||
/**
|
||||
* Uses the DNS protocol to resolve IPv6 addresses (`AAAA` records) for the `hostname`. On success, the `Promise` is resolved with an array of IPv6
|
||||
* addresses.
|
||||
* @since v10.6.0
|
||||
* @param hostname Host name to resolve.
|
||||
*/
|
||||
function resolve6(hostname: string): Promise<string[]>;
|
||||
function resolve6(hostname: string, options: ResolveWithTtlOptions): Promise<RecordWithTtl[]>;
|
||||
function resolve6(hostname: string, options: ResolveOptions): Promise<string[] | RecordWithTtl[]>;
|
||||
/**
|
||||
* Uses the DNS protocol to resolve all records (also known as `ANY` or `*` query).
|
||||
* On success, the `Promise` is resolved with an array containing various types of
|
||||
* records. Each object has a property `type` that indicates the type of the
|
||||
* current record. And depending on the `type`, additional properties will be
|
||||
* present on the object:
|
||||
*
|
||||
* <omitted>
|
||||
*
|
||||
* Here is an example of the result object:
|
||||
*
|
||||
* ```js
|
||||
* [ { type: 'A', address: '127.0.0.1', ttl: 299 },
|
||||
* { type: 'CNAME', value: 'example.com' },
|
||||
* { type: 'MX', exchange: 'alt4.aspmx.l.example.com', priority: 50 },
|
||||
* { type: 'NS', value: 'ns1.example.com' },
|
||||
* { type: 'TXT', entries: [ 'v=spf1 include:_spf.example.com ~all' ] },
|
||||
* { type: 'SOA',
|
||||
* nsname: 'ns1.example.com',
|
||||
* hostmaster: 'admin.example.com',
|
||||
* serial: 156696742,
|
||||
* refresh: 900,
|
||||
* retry: 900,
|
||||
* expire: 1800,
|
||||
* minttl: 60 } ]
|
||||
* ```
|
||||
* @since v10.6.0
|
||||
*/
|
||||
function resolveAny(hostname: string): Promise<AnyRecord[]>;
|
||||
/**
|
||||
* Uses the DNS protocol to resolve `CAA` records for the `hostname`. On success,
|
||||
* the `Promise` is resolved with an array of objects containing available
|
||||
* certification authority authorization records available for the `hostname` (e.g. `[{critical: 0, iodef: 'mailto:pki@example.com'},{critical: 128, issue: 'pki.example.com'}]`).
|
||||
* @since v15.0.0, v14.17.0
|
||||
*/
|
||||
function resolveCaa(hostname: string): Promise<CaaRecord[]>;
|
||||
/**
|
||||
* Uses the DNS protocol to resolve `CNAME` records for the `hostname`. On success,
|
||||
* the `Promise` is resolved with an array of canonical name records available for
|
||||
* the `hostname` (e.g. `['bar.example.com']`).
|
||||
* @since v10.6.0
|
||||
*/
|
||||
function resolveCname(hostname: string): Promise<string[]>;
|
||||
/**
|
||||
* Uses the DNS protocol to resolve mail exchange records (`MX` records) for the `hostname`. On success, the `Promise` is resolved with an array of objects
|
||||
* containing both a `priority` and `exchange` property (e.g.`[{priority: 10, exchange: 'mx.example.com'}, ...]`).
|
||||
* @since v10.6.0
|
||||
*/
|
||||
function resolveMx(hostname: string): Promise<MxRecord[]>;
|
||||
/**
|
||||
* Uses the DNS protocol to resolve regular expression-based records (`NAPTR` records) for the `hostname`. On success, the `Promise` is resolved with an array
|
||||
* of objects with the following properties:
|
||||
*
|
||||
* * `flags`
|
||||
* * `service`
|
||||
* * `regexp`
|
||||
* * `replacement`
|
||||
* * `order`
|
||||
* * `preference`
|
||||
*
|
||||
* ```js
|
||||
* {
|
||||
* flags: 's',
|
||||
* service: 'SIP+D2U',
|
||||
* regexp: '',
|
||||
* replacement: '_sip._udp.example.com',
|
||||
* order: 30,
|
||||
* preference: 100
|
||||
* }
|
||||
* ```
|
||||
* @since v10.6.0
|
||||
*/
|
||||
function resolveNaptr(hostname: string): Promise<NaptrRecord[]>;
|
||||
/**
|
||||
* Uses the DNS protocol to resolve name server records (`NS` records) for the `hostname`. On success, the `Promise` is resolved with an array of name server
|
||||
* records available for `hostname` (e.g.`['ns1.example.com', 'ns2.example.com']`).
|
||||
* @since v10.6.0
|
||||
*/
|
||||
function resolveNs(hostname: string): Promise<string[]>;
|
||||
/**
|
||||
* Uses the DNS protocol to resolve pointer records (`PTR` records) for the `hostname`. On success, the `Promise` is resolved with an array of strings
|
||||
* containing the reply records.
|
||||
* @since v10.6.0
|
||||
*/
|
||||
function resolvePtr(hostname: string): Promise<string[]>;
|
||||
/**
|
||||
* Uses the DNS protocol to resolve a start of authority record (`SOA` record) for
|
||||
* the `hostname`. On success, the `Promise` is resolved with an object with the
|
||||
* following properties:
|
||||
*
|
||||
* * `nsname`
|
||||
* * `hostmaster`
|
||||
* * `serial`
|
||||
* * `refresh`
|
||||
* * `retry`
|
||||
* * `expire`
|
||||
* * `minttl`
|
||||
*
|
||||
* ```js
|
||||
* {
|
||||
* nsname: 'ns.example.com',
|
||||
* hostmaster: 'root.example.com',
|
||||
* serial: 2013101809,
|
||||
* refresh: 10000,
|
||||
* retry: 2400,
|
||||
* expire: 604800,
|
||||
* minttl: 3600
|
||||
* }
|
||||
* ```
|
||||
* @since v10.6.0
|
||||
*/
|
||||
function resolveSoa(hostname: string): Promise<SoaRecord>;
|
||||
/**
|
||||
* Uses the DNS protocol to resolve service records (`SRV` records) for the `hostname`. On success, the `Promise` is resolved with an array of objects with
|
||||
* the following properties:
|
||||
*
|
||||
* * `priority`
|
||||
* * `weight`
|
||||
* * `port`
|
||||
* * `name`
|
||||
*
|
||||
* ```js
|
||||
* {
|
||||
* priority: 10,
|
||||
* weight: 5,
|
||||
* port: 21223,
|
||||
* name: 'service.example.com'
|
||||
* }
|
||||
* ```
|
||||
* @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
|
||||
* one record. Depending on the use case, these could be either joined together or
|
||||
* treated separately.
|
||||
* @since v10.6.0
|
||||
*/
|
||||
function resolveTxt(hostname: string): Promise<string[][]>;
|
||||
/**
|
||||
* Performs a reverse DNS query that resolves an IPv4 or IPv6 address to an
|
||||
* array of host names.
|
||||
*
|
||||
* 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 one of the [DNS error codes](https://nodejs.org/docs/latest-v20.x/api/dns.html#error-codes).
|
||||
* @since v10.6.0
|
||||
*/
|
||||
function reverse(ip: string): Promise<string[]>;
|
||||
/**
|
||||
* Get the default value for `verbatim` in {@link lookup} and [dnsPromises.lookup()](https://nodejs.org/docs/latest-v20.x/api/dns.html#dnspromiseslookuphostname-options).
|
||||
* The value could be:
|
||||
*
|
||||
* * `ipv4first`: for `verbatim` defaulting to `false`.
|
||||
* * `verbatim`: for `verbatim` defaulting to `true`.
|
||||
* @since v20.1.0
|
||||
*/
|
||||
function getDefaultResultOrder(): "ipv4first" | "verbatim";
|
||||
/**
|
||||
* Sets the IP address and port of servers to be used when performing DNS
|
||||
* resolution. The `servers` argument is an array of [RFC 5952](https://tools.ietf.org/html/rfc5952#section-6) formatted
|
||||
* addresses. If the port is the IANA default DNS port (53) it can be omitted.
|
||||
*
|
||||
* ```js
|
||||
* dnsPromises.setServers([
|
||||
* '4.4.4.4',
|
||||
* '[2001:4860:4860::8888]',
|
||||
* '4.4.4.4:1053',
|
||||
* '[2001:4860:4860::8888]:1053',
|
||||
* ]);
|
||||
* ```
|
||||
*
|
||||
* An error will be thrown if an invalid address is provided.
|
||||
*
|
||||
* The `dnsPromises.setServers()` method must not be called while a DNS query is in
|
||||
* progress.
|
||||
*
|
||||
* This method works much like [resolve.conf](https://man7.org/linux/man-pages/man5/resolv.conf.5.html).
|
||||
* That is, if attempting to resolve with the first server provided results in a `NOTFOUND` error, the `resolve()` method will _not_ attempt to resolve with
|
||||
* subsequent servers provided. Fallback DNS servers will only be used if the
|
||||
* earlier ones time out or result in some other error.
|
||||
* @since v10.6.0
|
||||
* @param servers array of `RFC 5952` formatted addresses
|
||||
*/
|
||||
function setServers(servers: readonly string[]): void;
|
||||
/**
|
||||
* Set the default value of `order` in `dns.lookup()` and `{@link lookup}`. The value could be:
|
||||
*
|
||||
* * `ipv4first`: sets default `order` to `ipv4first`.
|
||||
* * `ipv6first`: sets default `order` to `ipv6first`.
|
||||
* * `verbatim`: sets default `order` to `verbatim`.
|
||||
*
|
||||
* The default is `verbatim` and [dnsPromises.setDefaultResultOrder()](https://nodejs.org/docs/latest-v20.x/api/dns.html#dnspromisessetdefaultresultorderorder)
|
||||
* 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), [`dnsPromises.setDefaultResultOrder()`](https://nodejs.org/docs/latest-v20.x/api/dns.html#dnspromisessetdefaultresultorderorder)
|
||||
* 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'`.
|
||||
*/
|
||||
function setDefaultResultOrder(order: "ipv4first" | "ipv6first" | "verbatim"): void;
|
||||
// Error codes
|
||||
const NODATA: "ENODATA";
|
||||
const FORMERR: "EFORMERR";
|
||||
const SERVFAIL: "ESERVFAIL";
|
||||
const NOTFOUND: "ENOTFOUND";
|
||||
const NOTIMP: "ENOTIMP";
|
||||
const REFUSED: "EREFUSED";
|
||||
const BADQUERY: "EBADQUERY";
|
||||
const BADNAME: "EBADNAME";
|
||||
const BADFAMILY: "EBADFAMILY";
|
||||
const BADRESP: "EBADRESP";
|
||||
const CONNREFUSED: "ECONNREFUSED";
|
||||
const TIMEOUT: "ETIMEOUT";
|
||||
const EOF: "EOF";
|
||||
const FILE: "EFILE";
|
||||
const NOMEM: "ENOMEM";
|
||||
const DESTRUCTION: "EDESTRUCTION";
|
||||
const BADSTR: "EBADSTR";
|
||||
const BADFLAGS: "EBADFLAGS";
|
||||
const NONAME: "ENONAME";
|
||||
const BADHINTS: "EBADHINTS";
|
||||
const NOTINITIALIZED: "ENOTINITIALIZED";
|
||||
const LOADIPHLPAPI: "ELOADIPHLPAPI";
|
||||
const ADDRGETNETWORKPARAMS: "EADDRGETNETWORKPARAMS";
|
||||
const CANCELLED: "ECANCELLED";
|
||||
|
||||
/**
|
||||
* 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#dnspromisessetserversservers) does not affect
|
||||
* other resolvers:
|
||||
*
|
||||
* ```js
|
||||
* 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.
|
||||
* resolver.resolve4('example.org').then((addresses) => {
|
||||
* // ...
|
||||
* });
|
||||
*
|
||||
* // Alternatively, the same code can be written using async-await style.
|
||||
* (async function() {
|
||||
* const addresses = await resolver.resolve4('example.org');
|
||||
* })();
|
||||
* ```
|
||||
*
|
||||
* The following methods from the `dnsPromises` API are available:
|
||||
*
|
||||
* * `resolver.getServers()`
|
||||
* * `resolver.resolve()`
|
||||
* * `resolver.resolve4()`
|
||||
* * `resolver.resolve6()`
|
||||
* * `resolver.resolveAny()`
|
||||
* * `resolver.resolveCaa()`
|
||||
* * `resolver.resolveCname()`
|
||||
* * `resolver.resolveMx()`
|
||||
* * `resolver.resolveNaptr()`
|
||||
* * `resolver.resolveNs()`
|
||||
* * `resolver.resolvePtr()`
|
||||
* * `resolver.resolveSoa()`
|
||||
* * `resolver.resolveSrv()`
|
||||
* * `resolver.resolveTxt()`
|
||||
* * `resolver.reverse()`
|
||||
* * `resolver.setServers()`
|
||||
* @since v10.6.0
|
||||
*/
|
||||
class Resolver {
|
||||
constructor(options?: ResolverOptions);
|
||||
/**
|
||||
* Cancel all outstanding DNS queries made by this resolver. The corresponding
|
||||
* callbacks will be called with an error with code `ECANCELLED`.
|
||||
* @since v8.3.0
|
||||
*/
|
||||
cancel(): void;
|
||||
getServers: typeof getServers;
|
||||
resolve: typeof resolve;
|
||||
resolve4: typeof resolve4;
|
||||
resolve6: typeof resolve6;
|
||||
resolveAny: typeof resolveAny;
|
||||
resolveCaa: typeof resolveCaa;
|
||||
resolveCname: typeof resolveCname;
|
||||
resolveMx: typeof resolveMx;
|
||||
resolveNaptr: typeof resolveNaptr;
|
||||
resolveNs: typeof resolveNs;
|
||||
resolvePtr: typeof resolvePtr;
|
||||
resolveSoa: typeof resolveSoa;
|
||||
resolveSrv: typeof resolveSrv;
|
||||
resolveTlsa: typeof resolveTlsa;
|
||||
resolveTxt: typeof resolveTxt;
|
||||
reverse: typeof reverse;
|
||||
/**
|
||||
* The resolver instance will send its requests from the specified IP address.
|
||||
* This allows programs to specify outbound interfaces when used on multi-homed
|
||||
* systems.
|
||||
*
|
||||
* If a v4 or v6 address is not specified, it is set to the default and the
|
||||
* operating system will choose a local address automatically.
|
||||
*
|
||||
* The resolver will use the v4 local address when making requests to IPv4 DNS
|
||||
* servers, and the v6 local address when making requests to IPv6 DNS servers.
|
||||
* The `rrtype` of resolution requests has no impact on the local address used.
|
||||
* @since v15.1.0, v14.17.0
|
||||
* @param [ipv4='0.0.0.0'] A string representation of an IPv4 address.
|
||||
* @param [ipv6='::0'] A string representation of an IPv6 address.
|
||||
*/
|
||||
setLocalAddress(ipv4?: string, ipv6?: string): void;
|
||||
setServers: typeof setServers;
|
||||
}
|
||||
}
|
||||
declare module "node:dns/promises" {
|
||||
export * from "dns/promises";
|
||||
}
|
||||
170
node_modules/@types/node/domain.d.ts
generated
vendored
Normal file
@@ -0,0 +1,170 @@
|
||||
/**
|
||||
* **This module is pending deprecation.** Once a replacement API has been
|
||||
* finalized, this module will be fully deprecated. Most developers should
|
||||
* **not** have cause to use this module. Users who absolutely must have
|
||||
* the functionality that domains provide may rely on it for the time being
|
||||
* but should expect to have to migrate to a different solution
|
||||
* in the future.
|
||||
*
|
||||
* Domains provide a way to handle multiple different IO operations as a
|
||||
* single group. If any of the event emitters or callbacks registered to a
|
||||
* domain emit an `'error'` event, or throw an error, then the domain object
|
||||
* 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/v24.x/lib/domain.js)
|
||||
*/
|
||||
declare module "domain" {
|
||||
import EventEmitter = require("node:events");
|
||||
/**
|
||||
* The `Domain` class encapsulates the functionality of routing errors and
|
||||
* uncaught exceptions to the active `Domain` object.
|
||||
*
|
||||
* To handle the errors that it catches, listen to its `'error'` event.
|
||||
*/
|
||||
class Domain extends EventEmitter {
|
||||
/**
|
||||
* An array of timers and event emitters that have been explicitly added
|
||||
* to the domain.
|
||||
*/
|
||||
members: Array<EventEmitter | NodeJS.Timer>;
|
||||
/**
|
||||
* The `enter()` method is plumbing used by the `run()`, `bind()`, and `intercept()` methods to set the active domain. It sets `domain.active` and `process.domain` to the domain, and implicitly
|
||||
* pushes the domain onto the domain
|
||||
* stack managed by the domain module (see {@link exit} for details on the
|
||||
* domain stack). The call to `enter()` delimits the beginning of a chain of
|
||||
* asynchronous calls and I/O operations bound to a domain.
|
||||
*
|
||||
* Calling `enter()` changes only the active domain, and does not alter the domain
|
||||
* itself. `enter()` and `exit()` can be called an arbitrary number of times on a
|
||||
* single domain.
|
||||
*/
|
||||
enter(): void;
|
||||
/**
|
||||
* The `exit()` method exits the current domain, popping it off the domain stack.
|
||||
* Any time execution is going to switch to the context of a different chain of
|
||||
* asynchronous calls, it's important to ensure that the current domain is exited.
|
||||
* The call to `exit()` delimits either the end of or an interruption to the chain
|
||||
* of asynchronous calls and I/O operations bound to a domain.
|
||||
*
|
||||
* If there are multiple, nested domains bound to the current execution context, `exit()` will exit any domains nested within this domain.
|
||||
*
|
||||
* Calling `exit()` changes only the active domain, and does not alter the domain
|
||||
* itself. `enter()` and `exit()` can be called an arbitrary number of times on a
|
||||
* single domain.
|
||||
*/
|
||||
exit(): void;
|
||||
/**
|
||||
* Run the supplied function in the context of the domain, implicitly
|
||||
* binding all event emitters, timers, and low-level requests that are
|
||||
* created in that context. Optionally, arguments can be passed to
|
||||
* the function.
|
||||
*
|
||||
* This is the most basic way to use a domain.
|
||||
*
|
||||
* ```js
|
||||
* import domain from 'node:domain';
|
||||
* import fs from 'node:fs';
|
||||
* const d = domain.create();
|
||||
* d.on('error', (er) => {
|
||||
* console.error('Caught error!', er);
|
||||
* });
|
||||
* d.run(() => {
|
||||
* process.nextTick(() => {
|
||||
* setTimeout(() => { // Simulating some various async stuff
|
||||
* fs.open('non-existent file', 'r', (er, fd) => {
|
||||
* if (er) throw er;
|
||||
* // proceed...
|
||||
* });
|
||||
* }, 100);
|
||||
* });
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* In this example, the `d.on('error')` handler will be triggered, rather
|
||||
* than crashing the program.
|
||||
*/
|
||||
run<T>(fn: (...args: any[]) => T, ...args: any[]): T;
|
||||
/**
|
||||
* Explicitly adds an emitter to the domain. If any event handlers called by
|
||||
* the emitter throw an error, or if the emitter emits an `'error'` event, it
|
||||
* will be routed to the domain's `'error'` event, just like with implicit
|
||||
* binding.
|
||||
*
|
||||
* This also works with timers that are returned from `setInterval()` and `setTimeout()`. If their callback function throws, it will be caught by
|
||||
* the domain `'error'` handler.
|
||||
*
|
||||
* If the Timer or `EventEmitter` was already bound to a domain, it is removed
|
||||
* from that one, and bound to this one instead.
|
||||
* @param emitter emitter or timer to be added to the domain
|
||||
*/
|
||||
add(emitter: EventEmitter | NodeJS.Timer): void;
|
||||
/**
|
||||
* The opposite of {@link add}. Removes domain handling from the
|
||||
* specified emitter.
|
||||
* @param emitter emitter or timer to be removed from the domain
|
||||
*/
|
||||
remove(emitter: EventEmitter | NodeJS.Timer): void;
|
||||
/**
|
||||
* The returned function will be a wrapper around the supplied callback
|
||||
* function. When the returned function is called, any errors that are
|
||||
* thrown will be routed to the domain's `'error'` event.
|
||||
*
|
||||
* ```js
|
||||
* const d = domain.create();
|
||||
*
|
||||
* function readSomeFile(filename, cb) {
|
||||
* fs.readFile(filename, 'utf8', d.bind((er, data) => {
|
||||
* // If this throws, it will also be passed to the domain.
|
||||
* return cb(er, data ? JSON.parse(data) : null);
|
||||
* }));
|
||||
* }
|
||||
*
|
||||
* d.on('error', (er) => {
|
||||
* // An error occurred somewhere. If we throw it now, it will crash the program
|
||||
* // with the normal line number and stack message.
|
||||
* });
|
||||
* ```
|
||||
* @param callback The callback function
|
||||
* @return The bound function
|
||||
*/
|
||||
bind<T extends Function>(callback: T): T;
|
||||
/**
|
||||
* This method is almost identical to {@link bind}. However, in
|
||||
* addition to catching thrown errors, it will also intercept `Error` objects sent as the first argument to the function.
|
||||
*
|
||||
* In this way, the common `if (err) return callback(err);` pattern can be replaced
|
||||
* with a single error handler in a single place.
|
||||
*
|
||||
* ```js
|
||||
* const d = domain.create();
|
||||
*
|
||||
* function readSomeFile(filename, cb) {
|
||||
* fs.readFile(filename, 'utf8', d.intercept((data) => {
|
||||
* // Note, the first argument is never passed to the
|
||||
* // callback since it is assumed to be the 'Error' argument
|
||||
* // and thus intercepted by the domain.
|
||||
*
|
||||
* // If this throws, it will also be passed to the domain
|
||||
* // so the error-handling logic can be moved to the 'error'
|
||||
* // event on the domain instead of being repeated throughout
|
||||
* // the program.
|
||||
* return cb(null, JSON.parse(data));
|
||||
* }));
|
||||
* }
|
||||
*
|
||||
* d.on('error', (er) => {
|
||||
* // An error occurred somewhere. If we throw it now, it will crash the program
|
||||
* // with the normal line number and stack message.
|
||||
* });
|
||||
* ```
|
||||
* @param callback The callback function
|
||||
* @return The intercepted function
|
||||
*/
|
||||
intercept<T extends Function>(callback: T): T;
|
||||
}
|
||||
function create(): Domain;
|
||||
}
|
||||
declare module "node:domain" {
|
||||
export * from "domain";
|
||||
}
|
||||
930
node_modules/@types/node/events.d.ts
generated
vendored
Normal file
@@ -0,0 +1,930 @@
|
||||
/**
|
||||
* Much of the Node.js core API is built around an idiomatic asynchronous
|
||||
* event-driven architecture in which certain kinds of objects (called "emitters")
|
||||
* emit named events that cause `Function` objects ("listeners") to be called.
|
||||
*
|
||||
* For instance: a `net.Server` object emits an event each time a peer
|
||||
* connects to it; a `fs.ReadStream` emits an event when the file is opened;
|
||||
* a `stream` emits an event whenever data is available to be read.
|
||||
*
|
||||
* All objects that emit events are instances of the `EventEmitter` class. These
|
||||
* objects expose an `eventEmitter.on()` function that allows one or more
|
||||
* functions to be attached to named events emitted by the object. Typically,
|
||||
* event names are camel-cased strings but any valid JavaScript property key
|
||||
* can be used.
|
||||
*
|
||||
* When the `EventEmitter` object emits an event, all of the functions attached
|
||||
* to that specific event are called _synchronously_. Any values returned by the
|
||||
* called listeners are _ignored_ and discarded.
|
||||
*
|
||||
* The following example shows a simple `EventEmitter` instance with a single
|
||||
* listener. The `eventEmitter.on()` method is used to register listeners, while
|
||||
* the `eventEmitter.emit()` method is used to trigger the event.
|
||||
*
|
||||
* ```js
|
||||
* import { EventEmitter } from 'node:events';
|
||||
*
|
||||
* class MyEmitter extends EventEmitter {}
|
||||
*
|
||||
* const myEmitter = new MyEmitter();
|
||||
* myEmitter.on('event', () => {
|
||||
* console.log('an event occurred!');
|
||||
* });
|
||||
* myEmitter.emit('event');
|
||||
* ```
|
||||
* @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.
|
||||
*/
|
||||
captureRejections?: boolean | undefined;
|
||||
}
|
||||
interface StaticEventEmitterOptions {
|
||||
/**
|
||||
* Can be used to cancel awaiting events.
|
||||
*/
|
||||
signal?: AbortSignal | undefined;
|
||||
}
|
||||
interface StaticEventEmitterIteratorOptions extends StaticEventEmitterOptions {
|
||||
/**
|
||||
* Names of events that will end the iteration.
|
||||
*/
|
||||
close?: string[] | undefined;
|
||||
/**
|
||||
* The high watermark. The emitter is paused every time the size of events being buffered is higher than it.
|
||||
* Supported only on emitters implementing `pause()` and `resume()` methods.
|
||||
* @default Number.MAX_SAFE_INTEGER
|
||||
*/
|
||||
highWaterMark?: number | undefined;
|
||||
/**
|
||||
* The low watermark. The emitter is resumed every time the size of events being buffered is lower than it.
|
||||
* Supported only on emitters implementing `pause()` and `resume()` methods.
|
||||
* @default 1
|
||||
*/
|
||||
lowWaterMark?: number | undefined;
|
||||
}
|
||||
interface EventEmitter<T extends EventMap<T> = DefaultEventMap> extends NodeJS.EventEmitter<T> {}
|
||||
type EventMap<T> = Record<keyof T, any[]> | DefaultEventMap;
|
||||
type DefaultEventMap = [never];
|
||||
type AnyRest = [...args: any[]];
|
||||
type Args<K, T> = T extends DefaultEventMap ? AnyRest : (
|
||||
K extends keyof T ? T[K] : never
|
||||
);
|
||||
type Key<K, T> = T extends DefaultEventMap ? string | symbol : K | keyof T;
|
||||
type Key2<K, T> = T extends DefaultEventMap ? string | symbol : K & keyof T;
|
||||
type Listener<K, T, F> = T extends DefaultEventMap ? F : (
|
||||
K extends keyof T ? (
|
||||
T[K] extends unknown[] ? (...args: T[K]) => void : never
|
||||
)
|
||||
: never
|
||||
);
|
||||
type Listener1<K, T> = Listener<K, T, (...args: any[]) => void>;
|
||||
type Listener2<K, T> = Listener<K, T, Function>;
|
||||
|
||||
/**
|
||||
* The `EventEmitter` class is defined and exposed by the `node:events` module:
|
||||
*
|
||||
* ```js
|
||||
* import { EventEmitter } from 'node:events';
|
||||
* ```
|
||||
*
|
||||
* All `EventEmitter`s emit the event `'newListener'` when new listeners are
|
||||
* added and `'removeListener'` when existing listeners are removed.
|
||||
*
|
||||
* It supports the following option:
|
||||
* @since v0.1.26
|
||||
*/
|
||||
class EventEmitter<T extends EventMap<T> = DefaultEventMap> {
|
||||
constructor(options?: EventEmitterOptions);
|
||||
|
||||
[EventEmitter.captureRejectionSymbol]?<K>(error: Error, event: Key<K, T>, ...args: Args<K, T>): void;
|
||||
|
||||
/**
|
||||
* Creates a `Promise` that is fulfilled when the `EventEmitter` emits the given
|
||||
* event or that is rejected if the `EventEmitter` emits `'error'` while waiting.
|
||||
* The `Promise` will resolve with an array of all the arguments emitted to the
|
||||
* given event.
|
||||
*
|
||||
* This method is intentionally generic and works with the web platform [EventTarget](https://dom.spec.whatwg.org/#interface-eventtarget) interface, which has no special`'error'` event
|
||||
* semantics and does not listen to the `'error'` event.
|
||||
*
|
||||
* ```js
|
||||
* import { once, EventEmitter } from 'node:events';
|
||||
* import process from 'node:process';
|
||||
*
|
||||
* const ee = new EventEmitter();
|
||||
*
|
||||
* process.nextTick(() => {
|
||||
* ee.emit('myevent', 42);
|
||||
* });
|
||||
*
|
||||
* const [value] = await once(ee, 'myevent');
|
||||
* console.log(value);
|
||||
*
|
||||
* const err = new Error('kaboom');
|
||||
* process.nextTick(() => {
|
||||
* ee.emit('error', err);
|
||||
* });
|
||||
*
|
||||
* try {
|
||||
* await once(ee, 'myevent');
|
||||
* } catch (err) {
|
||||
* console.error('error happened', err);
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* The special handling of the `'error'` event is only used when `events.once()` is used to wait for another event. If `events.once()` is used to wait for the
|
||||
* '`error'` event itself, then it is treated as any other kind of event without
|
||||
* special handling:
|
||||
*
|
||||
* ```js
|
||||
* import { EventEmitter, once } from 'node:events';
|
||||
*
|
||||
* const ee = new EventEmitter();
|
||||
*
|
||||
* once(ee, 'error')
|
||||
* .then(([err]) => console.log('ok', err.message))
|
||||
* .catch((err) => console.error('error', err.message));
|
||||
*
|
||||
* ee.emit('error', new Error('boom'));
|
||||
*
|
||||
* // Prints: ok boom
|
||||
* ```
|
||||
*
|
||||
* An `AbortSignal` can be used to cancel waiting for the event:
|
||||
*
|
||||
* ```js
|
||||
* import { EventEmitter, once } from 'node:events';
|
||||
*
|
||||
* const ee = new EventEmitter();
|
||||
* const ac = new AbortController();
|
||||
*
|
||||
* async function foo(emitter, event, signal) {
|
||||
* try {
|
||||
* await once(emitter, event, { signal });
|
||||
* console.log('event emitted!');
|
||||
* } catch (error) {
|
||||
* if (error.name === 'AbortError') {
|
||||
* console.error('Waiting for the event was canceled!');
|
||||
* } else {
|
||||
* console.error('There was an error', error.message);
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* foo(ee, 'foo', ac.signal);
|
||||
* ac.abort(); // Abort waiting for the event
|
||||
* ee.emit('foo'); // Prints: Waiting for the event was canceled!
|
||||
* ```
|
||||
* @since v11.13.0, v10.16.0
|
||||
*/
|
||||
static once(
|
||||
emitter: NodeJS.EventEmitter,
|
||||
eventName: string | symbol,
|
||||
options?: StaticEventEmitterOptions,
|
||||
): Promise<any[]>;
|
||||
static once(emitter: EventTarget, eventName: string, options?: StaticEventEmitterOptions): Promise<any[]>;
|
||||
/**
|
||||
* ```js
|
||||
* import { on, EventEmitter } from 'node:events';
|
||||
* import process from 'node:process';
|
||||
*
|
||||
* const ee = new EventEmitter();
|
||||
*
|
||||
* // Emit later on
|
||||
* process.nextTick(() => {
|
||||
* ee.emit('foo', 'bar');
|
||||
* ee.emit('foo', 42);
|
||||
* });
|
||||
*
|
||||
* for await (const event of on(ee, 'foo')) {
|
||||
* // The execution of this inner block is synchronous and it
|
||||
* // processes one event at a time (even with await). Do not use
|
||||
* // if concurrent execution is required.
|
||||
* console.log(event); // prints ['bar'] [42]
|
||||
* }
|
||||
* // Unreachable here
|
||||
* ```
|
||||
*
|
||||
* Returns an `AsyncIterator` that iterates `eventName` events. It will throw
|
||||
* if the `EventEmitter` emits `'error'`. It removes all listeners when
|
||||
* exiting the loop. The `value` returned by each iteration is an array
|
||||
* composed of the emitted event arguments.
|
||||
*
|
||||
* An `AbortSignal` can be used to cancel waiting on events:
|
||||
*
|
||||
* ```js
|
||||
* import { on, EventEmitter } from 'node:events';
|
||||
* import process from 'node:process';
|
||||
*
|
||||
* const ac = new AbortController();
|
||||
*
|
||||
* (async () => {
|
||||
* const ee = new EventEmitter();
|
||||
*
|
||||
* // Emit later on
|
||||
* process.nextTick(() => {
|
||||
* ee.emit('foo', 'bar');
|
||||
* ee.emit('foo', 42);
|
||||
* });
|
||||
*
|
||||
* for await (const event of on(ee, 'foo', { signal: ac.signal })) {
|
||||
* // The execution of this inner block is synchronous and it
|
||||
* // processes one event at a time (even with await). Do not use
|
||||
* // if concurrent execution is required.
|
||||
* console.log(event); // prints ['bar'] [42]
|
||||
* }
|
||||
* // Unreachable here
|
||||
* })();
|
||||
*
|
||||
* process.nextTick(() => ac.abort());
|
||||
* ```
|
||||
*
|
||||
* Use the `close` option to specify an array of event names that will end the iteration:
|
||||
*
|
||||
* ```js
|
||||
* import { on, EventEmitter } from 'node:events';
|
||||
* import process from 'node:process';
|
||||
*
|
||||
* const ee = new EventEmitter();
|
||||
*
|
||||
* // Emit later on
|
||||
* process.nextTick(() => {
|
||||
* ee.emit('foo', 'bar');
|
||||
* ee.emit('foo', 42);
|
||||
* ee.emit('close');
|
||||
* });
|
||||
*
|
||||
* for await (const event of on(ee, 'foo', { close: ['close'] })) {
|
||||
* console.log(event); // prints ['bar'] [42]
|
||||
* }
|
||||
* // the loop will exit after 'close' is emitted
|
||||
* console.log('done'); // prints 'done'
|
||||
* ```
|
||||
* @since v13.6.0, v12.16.0
|
||||
* @return An `AsyncIterator` that iterates `eventName` events emitted by the `emitter`
|
||||
*/
|
||||
static on(
|
||||
emitter: NodeJS.EventEmitter,
|
||||
eventName: string | symbol,
|
||||
options?: StaticEventEmitterIteratorOptions,
|
||||
): NodeJS.AsyncIterator<any[]>;
|
||||
static on(
|
||||
emitter: EventTarget,
|
||||
eventName: string,
|
||||
options?: StaticEventEmitterIteratorOptions,
|
||||
): NodeJS.AsyncIterator<any[]>;
|
||||
/**
|
||||
* A class method that returns the number of listeners for the given `eventName` registered on the given `emitter`.
|
||||
*
|
||||
* ```js
|
||||
* import { EventEmitter, listenerCount } from 'node:events';
|
||||
*
|
||||
* const myEmitter = new EventEmitter();
|
||||
* myEmitter.on('event', () => {});
|
||||
* myEmitter.on('event', () => {});
|
||||
* console.log(listenerCount(myEmitter, 'event'));
|
||||
* // Prints: 2
|
||||
* ```
|
||||
* @since v0.9.12
|
||||
* @deprecated Since v3.2.0 - Use `listenerCount` instead.
|
||||
* @param emitter The emitter to query
|
||||
* @param eventName The event name
|
||||
*/
|
||||
static listenerCount(emitter: NodeJS.EventEmitter, eventName: string | symbol): number;
|
||||
/**
|
||||
* Returns a copy of the array of listeners for the event named `eventName`.
|
||||
*
|
||||
* For `EventEmitter`s this behaves exactly the same as calling `.listeners` on
|
||||
* the emitter.
|
||||
*
|
||||
* For `EventTarget`s this is the only way to get the event listeners for the
|
||||
* event target. This is useful for debugging and diagnostic purposes.
|
||||
*
|
||||
* ```js
|
||||
* import { getEventListeners, EventEmitter } from 'node:events';
|
||||
*
|
||||
* {
|
||||
* const ee = new EventEmitter();
|
||||
* const listener = () => console.log('Events are fun');
|
||||
* ee.on('foo', listener);
|
||||
* console.log(getEventListeners(ee, 'foo')); // [ [Function: listener] ]
|
||||
* }
|
||||
* {
|
||||
* const et = new EventTarget();
|
||||
* const listener = () => console.log('Events are fun');
|
||||
* et.addEventListener('foo', listener);
|
||||
* console.log(getEventListeners(et, 'foo')); // [ [Function: listener] ]
|
||||
* }
|
||||
* ```
|
||||
* @since v15.2.0, v14.17.0
|
||||
*/
|
||||
static getEventListeners(emitter: EventTarget | NodeJS.EventEmitter, name: string | symbol): Function[];
|
||||
/**
|
||||
* Returns the currently set max amount of listeners.
|
||||
*
|
||||
* For `EventEmitter`s this behaves exactly the same as calling `.getMaxListeners` on
|
||||
* the emitter.
|
||||
*
|
||||
* For `EventTarget`s this is the only way to get the max event listeners for the
|
||||
* event target. If the number of event handlers on a single EventTarget exceeds
|
||||
* the max set, the EventTarget will print a warning.
|
||||
*
|
||||
* ```js
|
||||
* import { getMaxListeners, setMaxListeners, EventEmitter } from 'node:events';
|
||||
*
|
||||
* {
|
||||
* const ee = new EventEmitter();
|
||||
* console.log(getMaxListeners(ee)); // 10
|
||||
* setMaxListeners(11, ee);
|
||||
* console.log(getMaxListeners(ee)); // 11
|
||||
* }
|
||||
* {
|
||||
* const et = new EventTarget();
|
||||
* console.log(getMaxListeners(et)); // 10
|
||||
* setMaxListeners(11, et);
|
||||
* console.log(getMaxListeners(et)); // 11
|
||||
* }
|
||||
* ```
|
||||
* @since v19.9.0
|
||||
*/
|
||||
static getMaxListeners(emitter: EventTarget | NodeJS.EventEmitter): number;
|
||||
/**
|
||||
* ```js
|
||||
* import { setMaxListeners, EventEmitter } from 'node:events';
|
||||
*
|
||||
* const target = new EventTarget();
|
||||
* const emitter = new EventEmitter();
|
||||
*
|
||||
* setMaxListeners(5, target, emitter);
|
||||
* ```
|
||||
* @since v15.4.0
|
||||
* @param n A non-negative number. The maximum number of listeners per `EventTarget` event.
|
||||
* @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;
|
||||
/**
|
||||
* Listens once to the `abort` event on the provided `signal`.
|
||||
*
|
||||
* Listening to the `abort` event on abort signals is unsafe and may
|
||||
* lead to resource leaks since another third party with the signal can
|
||||
* call `e.stopImmediatePropagation()`. Unfortunately Node.js cannot change
|
||||
* this since it would violate the web standard. Additionally, the original
|
||||
* API makes it easy to forget to remove listeners.
|
||||
*
|
||||
* This API allows safely using `AbortSignal`s in Node.js APIs by solving these
|
||||
* two issues by listening to the event such that `stopImmediatePropagation` does
|
||||
* not prevent the listener from running.
|
||||
*
|
||||
* Returns a disposable so that it may be unsubscribed from more easily.
|
||||
*
|
||||
* ```js
|
||||
* import { addAbortListener } from 'node:events';
|
||||
*
|
||||
* function example(signal) {
|
||||
* let disposable;
|
||||
* try {
|
||||
* signal.addEventListener('abort', (e) => e.stopImmediatePropagation());
|
||||
* disposable = addAbortListener(signal, (e) => {
|
||||
* // Do something when signal is aborted.
|
||||
* });
|
||||
* } finally {
|
||||
* disposable?.[Symbol.dispose]();
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
* @since v20.5.0
|
||||
* @return Disposable that removes the `abort` listener.
|
||||
*/
|
||||
static addAbortListener(signal: AbortSignal, resource: (event: Event) => void): Disposable;
|
||||
/**
|
||||
* This symbol shall be used to install a listener for only monitoring `'error'` events. Listeners installed using this symbol are called before the regular `'error'` listeners are called.
|
||||
*
|
||||
* Installing a listener using this symbol does not change the behavior once an `'error'` event is emitted. Therefore, the process will still crash if no
|
||||
* regular `'error'` listener is installed.
|
||||
* @since v13.6.0, v12.17.0
|
||||
*/
|
||||
static readonly errorMonitor: unique symbol;
|
||||
/**
|
||||
* Value: `Symbol.for('nodejs.rejection')`
|
||||
*
|
||||
* See how to write a custom `rejection handler`.
|
||||
* @since v13.4.0, v12.16.0
|
||||
*/
|
||||
static readonly captureRejectionSymbol: unique symbol;
|
||||
/**
|
||||
* Value: [boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type)
|
||||
*
|
||||
* Change the default `captureRejections` option on all new `EventEmitter` objects.
|
||||
* @since v13.4.0, v12.16.0
|
||||
*/
|
||||
static captureRejections: boolean;
|
||||
/**
|
||||
* By default, a maximum of `10` listeners can be registered for any single
|
||||
* event. This limit can be changed for individual `EventEmitter` instances
|
||||
* using the `emitter.setMaxListeners(n)` method. To change the default
|
||||
* for _all_`EventEmitter` instances, the `events.defaultMaxListeners` property
|
||||
* can be used. If this value is not a positive number, a `RangeError` is thrown.
|
||||
*
|
||||
* Take caution when setting the `events.defaultMaxListeners` because the
|
||||
* change affects _all_ `EventEmitter` instances, including those created before
|
||||
* the change is made. However, calling `emitter.setMaxListeners(n)` still has
|
||||
* precedence over `events.defaultMaxListeners`.
|
||||
*
|
||||
* This is not a hard limit. The `EventEmitter` instance will allow
|
||||
* more listeners to be added but will output a trace warning to stderr indicating
|
||||
* that a "possible EventEmitter memory leak" has been detected. For any single
|
||||
* `EventEmitter`, the `emitter.getMaxListeners()` and `emitter.setMaxListeners()` methods can be used to
|
||||
* temporarily avoid this warning:
|
||||
*
|
||||
* ```js
|
||||
* import { EventEmitter } from 'node:events';
|
||||
* const emitter = new EventEmitter();
|
||||
* emitter.setMaxListeners(emitter.getMaxListeners() + 1);
|
||||
* emitter.once('event', () => {
|
||||
* // do stuff
|
||||
* emitter.setMaxListeners(Math.max(emitter.getMaxListeners() - 1, 0));
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* The `--trace-warnings` command-line flag can be used to display the
|
||||
* stack trace for such warnings.
|
||||
*
|
||||
* The emitted warning can be inspected with `process.on('warning')` and will
|
||||
* have the additional `emitter`, `type`, and `count` properties, referring to
|
||||
* the event emitter instance, the event's name and the number of attached
|
||||
* listeners, respectively.
|
||||
* Its `name` property is set to `'MaxListenersExceededWarning'`.
|
||||
* @since v0.11.2
|
||||
*/
|
||||
static defaultMaxListeners: number;
|
||||
}
|
||||
import internal = require("node:events");
|
||||
namespace EventEmitter {
|
||||
// Should just be `export { EventEmitter }`, but that doesn't work in TypeScript 3.4
|
||||
export { internal as EventEmitter };
|
||||
export interface Abortable {
|
||||
/**
|
||||
* When provided the corresponding `AbortController` can be used to cancel an asynchronous action.
|
||||
*/
|
||||
signal?: AbortSignal | undefined;
|
||||
}
|
||||
|
||||
export interface EventEmitterReferencingAsyncResource extends AsyncResource {
|
||||
readonly eventEmitter: EventEmitterAsyncResource;
|
||||
}
|
||||
|
||||
export interface EventEmitterAsyncResourceOptions extends AsyncResourceOptions, EventEmitterOptions {
|
||||
/**
|
||||
* The type of async event, this is required when instantiating `EventEmitterAsyncResource`
|
||||
* directly rather than as a child class.
|
||||
* @default new.target.name if instantiated as a child class.
|
||||
*/
|
||||
name?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Integrates `EventEmitter` with `AsyncResource` for `EventEmitter`s that
|
||||
* require manual async tracking. Specifically, all events emitted by instances
|
||||
* of `events.EventEmitterAsyncResource` will run within its `async context`.
|
||||
*
|
||||
* ```js
|
||||
* import { EventEmitterAsyncResource, EventEmitter } from 'node:events';
|
||||
* import { notStrictEqual, strictEqual } from 'node:assert';
|
||||
* import { executionAsyncId, triggerAsyncId } from 'node:async_hooks';
|
||||
*
|
||||
* // Async tracking tooling will identify this as 'Q'.
|
||||
* const ee1 = new EventEmitterAsyncResource({ name: 'Q' });
|
||||
*
|
||||
* // 'foo' listeners will run in the EventEmitters async context.
|
||||
* ee1.on('foo', () => {
|
||||
* strictEqual(executionAsyncId(), ee1.asyncId);
|
||||
* strictEqual(triggerAsyncId(), ee1.triggerAsyncId);
|
||||
* });
|
||||
*
|
||||
* const ee2 = new EventEmitter();
|
||||
*
|
||||
* // 'foo' listeners on ordinary EventEmitters that do not track async
|
||||
* // context, however, run in the same async context as the emit().
|
||||
* ee2.on('foo', () => {
|
||||
* notStrictEqual(executionAsyncId(), ee2.asyncId);
|
||||
* notStrictEqual(triggerAsyncId(), ee2.triggerAsyncId);
|
||||
* });
|
||||
*
|
||||
* Promise.resolve().then(() => {
|
||||
* ee1.emit('foo');
|
||||
* ee2.emit('foo');
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* The `EventEmitterAsyncResource` class has the same methods and takes the
|
||||
* same options as `EventEmitter` and `AsyncResource` themselves.
|
||||
* @since v17.4.0, v16.14.0
|
||||
*/
|
||||
export class EventEmitterAsyncResource extends EventEmitter {
|
||||
/**
|
||||
* @param options Only optional in child class.
|
||||
*/
|
||||
constructor(options?: EventEmitterAsyncResourceOptions);
|
||||
/**
|
||||
* Call all `destroy` hooks. This should only ever be called once. An error will
|
||||
* be thrown if it is called more than once. This **must** be manually called. If
|
||||
* the resource is left to be collected by the GC then the `destroy` hooks will
|
||||
* never be called.
|
||||
*/
|
||||
emitDestroy(): void;
|
||||
/**
|
||||
* The unique `asyncId` assigned to the resource.
|
||||
*/
|
||||
readonly asyncId: number;
|
||||
/**
|
||||
* The same triggerAsyncId that is passed to the AsyncResource constructor.
|
||||
*/
|
||||
readonly triggerAsyncId: number;
|
||||
/**
|
||||
* The returned `AsyncResource` object has an additional `eventEmitter` property
|
||||
* that provides a reference to this `EventEmitterAsyncResource`.
|
||||
*/
|
||||
readonly asyncResource: EventEmitterReferencingAsyncResource;
|
||||
}
|
||||
}
|
||||
global {
|
||||
namespace NodeJS {
|
||||
interface EventEmitter<T extends EventMap<T> = DefaultEventMap> {
|
||||
[EventEmitter.captureRejectionSymbol]?<K>(error: Error, event: Key<K, T>, ...args: Args<K, T>): void;
|
||||
/**
|
||||
* Alias for `emitter.on(eventName, listener)`.
|
||||
* @since v0.1.26
|
||||
*/
|
||||
addListener<K>(eventName: Key<K, T>, listener: Listener1<K, T>): this;
|
||||
/**
|
||||
* Adds the `listener` function to the end of the listeners array for the event
|
||||
* named `eventName`. No checks are made to see if the `listener` has already
|
||||
* been added. Multiple calls passing the same combination of `eventName` and
|
||||
* `listener` will result in the `listener` being added, and called, multiple times.
|
||||
*
|
||||
* ```js
|
||||
* server.on('connection', (stream) => {
|
||||
* console.log('someone connected!');
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* Returns a reference to the `EventEmitter`, so that calls can be chained.
|
||||
*
|
||||
* By default, event listeners are invoked in the order they are added. The `emitter.prependListener()` method can be used as an alternative to add the
|
||||
* event listener to the beginning of the listeners array.
|
||||
*
|
||||
* ```js
|
||||
* import { EventEmitter } from 'node:events';
|
||||
* const myEE = new EventEmitter();
|
||||
* myEE.on('foo', () => console.log('a'));
|
||||
* myEE.prependListener('foo', () => console.log('b'));
|
||||
* myEE.emit('foo');
|
||||
* // Prints:
|
||||
* // b
|
||||
* // a
|
||||
* ```
|
||||
* @since v0.1.101
|
||||
* @param eventName The name of the event.
|
||||
* @param listener The callback function
|
||||
*/
|
||||
on<K>(eventName: Key<K, T>, listener: Listener1<K, T>): this;
|
||||
/**
|
||||
* Adds a **one-time** `listener` function for the event named `eventName`. The
|
||||
* next time `eventName` is triggered, this listener is removed and then invoked.
|
||||
*
|
||||
* ```js
|
||||
* server.once('connection', (stream) => {
|
||||
* console.log('Ah, we have our first user!');
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* Returns a reference to the `EventEmitter`, so that calls can be chained.
|
||||
*
|
||||
* By default, event listeners are invoked in the order they are added. The `emitter.prependOnceListener()` method can be used as an alternative to add the
|
||||
* event listener to the beginning of the listeners array.
|
||||
*
|
||||
* ```js
|
||||
* import { EventEmitter } from 'node:events';
|
||||
* const myEE = new EventEmitter();
|
||||
* myEE.once('foo', () => console.log('a'));
|
||||
* myEE.prependOnceListener('foo', () => console.log('b'));
|
||||
* myEE.emit('foo');
|
||||
* // Prints:
|
||||
* // b
|
||||
* // a
|
||||
* ```
|
||||
* @since v0.3.0
|
||||
* @param eventName The name of the event.
|
||||
* @param listener The callback function
|
||||
*/
|
||||
once<K>(eventName: Key<K, T>, listener: Listener1<K, T>): this;
|
||||
/**
|
||||
* Removes the specified `listener` from the listener array for the event named `eventName`.
|
||||
*
|
||||
* ```js
|
||||
* const callback = (stream) => {
|
||||
* console.log('someone connected!');
|
||||
* };
|
||||
* server.on('connection', callback);
|
||||
* // ...
|
||||
* server.removeListener('connection', callback);
|
||||
* ```
|
||||
*
|
||||
* `removeListener()` will remove, at most, one instance of a listener from the
|
||||
* listener array. If any single listener has been added multiple times to the
|
||||
* listener array for the specified `eventName`, then `removeListener()` must be
|
||||
* called multiple times to remove each instance.
|
||||
*
|
||||
* Once an event is emitted, all listeners attached to it at the
|
||||
* time of emitting are called in order. This implies that any `removeListener()` or `removeAllListeners()` calls _after_ emitting and _before_ the last listener finishes execution
|
||||
* will not remove them from`emit()` in progress. Subsequent events behave as expected.
|
||||
*
|
||||
* ```js
|
||||
* import { EventEmitter } from 'node:events';
|
||||
* class MyEmitter extends EventEmitter {}
|
||||
* const myEmitter = new MyEmitter();
|
||||
*
|
||||
* const callbackA = () => {
|
||||
* console.log('A');
|
||||
* myEmitter.removeListener('event', callbackB);
|
||||
* };
|
||||
*
|
||||
* const callbackB = () => {
|
||||
* console.log('B');
|
||||
* };
|
||||
*
|
||||
* myEmitter.on('event', callbackA);
|
||||
*
|
||||
* myEmitter.on('event', callbackB);
|
||||
*
|
||||
* // callbackA removes listener callbackB but it will still be called.
|
||||
* // Internal listener array at time of emit [callbackA, callbackB]
|
||||
* myEmitter.emit('event');
|
||||
* // Prints:
|
||||
* // A
|
||||
* // B
|
||||
*
|
||||
* // callbackB is now removed.
|
||||
* // Internal listener array [callbackA]
|
||||
* myEmitter.emit('event');
|
||||
* // Prints:
|
||||
* // A
|
||||
* ```
|
||||
*
|
||||
* Because listeners are managed using an internal array, calling this will
|
||||
* change the position indices of any listener registered _after_ the listener
|
||||
* being removed. This will not impact the order in which listeners are called,
|
||||
* but it means that any copies of the listener array as returned by
|
||||
* the `emitter.listeners()` method will need to be recreated.
|
||||
*
|
||||
* When a single function has been added as a handler multiple times for a single
|
||||
* event (as in the example below), `removeListener()` will remove the most
|
||||
* recently added instance. In the example the `once('ping')` listener is removed:
|
||||
*
|
||||
* ```js
|
||||
* import { EventEmitter } from 'node:events';
|
||||
* const ee = new EventEmitter();
|
||||
*
|
||||
* function pong() {
|
||||
* console.log('pong');
|
||||
* }
|
||||
*
|
||||
* ee.on('ping', pong);
|
||||
* ee.once('ping', pong);
|
||||
* ee.removeListener('ping', pong);
|
||||
*
|
||||
* ee.emit('ping');
|
||||
* ee.emit('ping');
|
||||
* ```
|
||||
*
|
||||
* Returns a reference to the `EventEmitter`, so that calls can be chained.
|
||||
* @since v0.1.26
|
||||
*/
|
||||
removeListener<K>(eventName: Key<K, T>, listener: Listener1<K, T>): this;
|
||||
/**
|
||||
* Alias for `emitter.removeListener()`.
|
||||
* @since v10.0.0
|
||||
*/
|
||||
off<K>(eventName: Key<K, T>, listener: Listener1<K, T>): this;
|
||||
/**
|
||||
* Removes all listeners, or those of the specified `eventName`.
|
||||
*
|
||||
* It is bad practice to remove listeners added elsewhere in the code,
|
||||
* particularly when the `EventEmitter` instance was created by some other
|
||||
* component or module (e.g. sockets or file streams).
|
||||
*
|
||||
* Returns a reference to the `EventEmitter`, so that calls can be chained.
|
||||
* @since v0.1.26
|
||||
*/
|
||||
removeAllListeners(eventName?: Key<unknown, T>): this;
|
||||
/**
|
||||
* By default `EventEmitter`s will print a warning if more than `10` listeners are
|
||||
* added for a particular event. This is a useful default that helps finding
|
||||
* memory leaks. The `emitter.setMaxListeners()` method allows the limit to be
|
||||
* modified for this specific `EventEmitter` instance. The value can be set to `Infinity` (or `0`) to indicate an unlimited number of listeners.
|
||||
*
|
||||
* Returns a reference to the `EventEmitter`, so that calls can be chained.
|
||||
* @since v0.3.5
|
||||
*/
|
||||
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 EventEmitter.defaultMaxListeners}.
|
||||
* @since v1.0.0
|
||||
*/
|
||||
getMaxListeners(): number;
|
||||
/**
|
||||
* Returns a copy of the array of listeners for the event named `eventName`.
|
||||
*
|
||||
* ```js
|
||||
* server.on('connection', (stream) => {
|
||||
* console.log('someone connected!');
|
||||
* });
|
||||
* console.log(util.inspect(server.listeners('connection')));
|
||||
* // Prints: [ [Function] ]
|
||||
* ```
|
||||
* @since v0.1.26
|
||||
*/
|
||||
listeners<K>(eventName: Key<K, T>): Array<Listener2<K, T>>;
|
||||
/**
|
||||
* Returns a copy of the array of listeners for the event named `eventName`,
|
||||
* including any wrappers (such as those created by `.once()`).
|
||||
*
|
||||
* ```js
|
||||
* import { EventEmitter } from 'node:events';
|
||||
* const emitter = new EventEmitter();
|
||||
* emitter.once('log', () => console.log('log once'));
|
||||
*
|
||||
* // Returns a new Array with a function `onceWrapper` which has a property
|
||||
* // `listener` which contains the original listener bound above
|
||||
* const listeners = emitter.rawListeners('log');
|
||||
* const logFnWrapper = listeners[0];
|
||||
*
|
||||
* // Logs "log once" to the console and does not unbind the `once` event
|
||||
* logFnWrapper.listener();
|
||||
*
|
||||
* // Logs "log once" to the console and removes the listener
|
||||
* logFnWrapper();
|
||||
*
|
||||
* emitter.on('log', () => console.log('log persistently'));
|
||||
* // Will return a new Array with a single function bound by `.on()` above
|
||||
* const newListeners = emitter.rawListeners('log');
|
||||
*
|
||||
* // Logs "log persistently" twice
|
||||
* newListeners[0]();
|
||||
* emitter.emit('log');
|
||||
* ```
|
||||
* @since v9.4.0
|
||||
*/
|
||||
rawListeners<K>(eventName: Key<K, T>): Array<Listener2<K, T>>;
|
||||
/**
|
||||
* Synchronously calls each of the listeners registered for the event named `eventName`, in the order they were registered, passing the supplied arguments
|
||||
* to each.
|
||||
*
|
||||
* Returns `true` if the event had listeners, `false` otherwise.
|
||||
*
|
||||
* ```js
|
||||
* import { EventEmitter } from 'node:events';
|
||||
* const myEmitter = new EventEmitter();
|
||||
*
|
||||
* // First listener
|
||||
* myEmitter.on('event', function firstListener() {
|
||||
* console.log('Helloooo! first listener');
|
||||
* });
|
||||
* // Second listener
|
||||
* myEmitter.on('event', function secondListener(arg1, arg2) {
|
||||
* console.log(`event with parameters ${arg1}, ${arg2} in second listener`);
|
||||
* });
|
||||
* // Third listener
|
||||
* myEmitter.on('event', function thirdListener(...args) {
|
||||
* const parameters = args.join(', ');
|
||||
* console.log(`event with parameters ${parameters} in third listener`);
|
||||
* });
|
||||
*
|
||||
* console.log(myEmitter.listeners('event'));
|
||||
*
|
||||
* myEmitter.emit('event', 1, 2, 3, 4, 5);
|
||||
*
|
||||
* // Prints:
|
||||
* // [
|
||||
* // [Function: firstListener],
|
||||
* // [Function: secondListener],
|
||||
* // [Function: thirdListener]
|
||||
* // ]
|
||||
* // Helloooo! first listener
|
||||
* // event with parameters 1, 2 in second listener
|
||||
* // event with parameters 1, 2, 3, 4, 5 in third listener
|
||||
* ```
|
||||
* @since v0.1.26
|
||||
*/
|
||||
emit<K>(eventName: Key<K, T>, ...args: Args<K, T>): boolean;
|
||||
/**
|
||||
* Returns the number of listeners listening for the event named `eventName`.
|
||||
* If `listener` is provided, it will return how many times the listener is found
|
||||
* in the list of the listeners of the event.
|
||||
* @since v3.2.0
|
||||
* @param eventName The name of the event being listened for
|
||||
* @param listener The event handler function
|
||||
*/
|
||||
listenerCount<K>(eventName: Key<K, T>, listener?: Listener2<K, T>): number;
|
||||
/**
|
||||
* Adds the `listener` function to the _beginning_ of the listeners array for the
|
||||
* event named `eventName`. No checks are made to see if the `listener` has
|
||||
* already been added. Multiple calls passing the same combination of `eventName`
|
||||
* and `listener` will result in the `listener` being added, and called, multiple times.
|
||||
*
|
||||
* ```js
|
||||
* server.prependListener('connection', (stream) => {
|
||||
* console.log('someone connected!');
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* Returns a reference to the `EventEmitter`, so that calls can be chained.
|
||||
* @since v6.0.0
|
||||
* @param eventName The name of the event.
|
||||
* @param listener The callback function
|
||||
*/
|
||||
prependListener<K>(eventName: Key<K, T>, listener: Listener1<K, T>): this;
|
||||
/**
|
||||
* Adds a **one-time**`listener` function for the event named `eventName` to the _beginning_ of the listeners array. The next time `eventName` is triggered, this
|
||||
* listener is removed, and then invoked.
|
||||
*
|
||||
* ```js
|
||||
* server.prependOnceListener('connection', (stream) => {
|
||||
* console.log('Ah, we have our first user!');
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* Returns a reference to the `EventEmitter`, so that calls can be chained.
|
||||
* @since v6.0.0
|
||||
* @param eventName The name of the event.
|
||||
* @param listener The callback function
|
||||
*/
|
||||
prependOnceListener<K>(eventName: Key<K, T>, listener: Listener1<K, T>): this;
|
||||
/**
|
||||
* Returns an array listing the events for which the emitter has registered
|
||||
* listeners. The values in the array are strings or `Symbol`s.
|
||||
*
|
||||
* ```js
|
||||
* import { EventEmitter } from 'node:events';
|
||||
*
|
||||
* const myEE = new EventEmitter();
|
||||
* myEE.on('foo', () => {});
|
||||
* myEE.on('bar', () => {});
|
||||
*
|
||||
* const sym = Symbol('symbol');
|
||||
* myEE.on(sym, () => {});
|
||||
*
|
||||
* console.log(myEE.eventNames());
|
||||
* // Prints: [ 'foo', 'bar', Symbol(symbol) ]
|
||||
* ```
|
||||
* @since v6.0.0
|
||||
*/
|
||||
eventNames(): Array<(string | symbol) & Key2<unknown, T>>;
|
||||
}
|
||||
}
|
||||
}
|
||||
export = EventEmitter;
|
||||
}
|
||||
declare module "node:events" {
|
||||
import events = require("events");
|
||||
export = events;
|
||||
}
|
||||
4473
node_modules/@types/node/fs.d.ts
generated
vendored
Normal file
1299
node_modules/@types/node/fs/promises.d.ts
generated
vendored
Normal file
168
node_modules/@types/node/globals.d.ts
generated
vendored
Normal file
@@ -0,0 +1,168 @@
|
||||
declare var global: typeof globalThis;
|
||||
|
||||
declare var process: NodeJS.Process;
|
||||
declare var console: Console;
|
||||
|
||||
interface ErrorConstructor {
|
||||
/**
|
||||
* Creates a `.stack` property on `targetObject`, which when accessed returns
|
||||
* a string representing the location in the code at which
|
||||
* `Error.captureStackTrace()` was called.
|
||||
*
|
||||
* ```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();
|
||||
* ```
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable this API with the `--expose-gc` CLI flag.
|
||||
*/
|
||||
declare var gc: NodeJS.GCFunction | 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 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;
|
||||
}
|
||||
|
||||
interface Dict<T> {
|
||||
[key: string]: T | undefined;
|
||||
}
|
||||
|
||||
interface ReadOnlyDict<T> {
|
||||
readonly [key: string]: T | 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>;
|
||||
}
|
||||
}
|
||||
22
node_modules/@types/node/globals.typedarray.d.ts
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
export {}; // Make this a module
|
||||
|
||||
declare global {
|
||||
namespace NodeJS {
|
||||
type TypedArray<TArrayBuffer extends ArrayBufferLike = ArrayBufferLike> =
|
||||
| Uint8Array<TArrayBuffer>
|
||||
| Uint8ClampedArray<TArrayBuffer>
|
||||
| Uint16Array<TArrayBuffer>
|
||||
| Uint32Array<TArrayBuffer>
|
||||
| Int8Array<TArrayBuffer>
|
||||
| Int16Array<TArrayBuffer>
|
||||
| Int32Array<TArrayBuffer>
|
||||
| BigUint64Array<TArrayBuffer>
|
||||
| BigInt64Array<TArrayBuffer>
|
||||
| Float16Array<TArrayBuffer>
|
||||
| Float32Array<TArrayBuffer>
|
||||
| Float64Array<TArrayBuffer>;
|
||||
type ArrayBufferView<TArrayBuffer extends ArrayBufferLike = ArrayBufferLike> =
|
||||
| TypedArray<TArrayBuffer>
|
||||
| DataView<TArrayBuffer>;
|
||||
}
|
||||
}
|
||||
2070
node_modules/@types/node/http.d.ts
generated
vendored
Normal file
2630
node_modules/@types/node/http2.d.ts
generated
vendored
Normal file
550
node_modules/@types/node/https.d.ts
generated
vendored
Normal file
@@ -0,0 +1,550 @@
|
||||
/**
|
||||
* 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/v24.x/lib/https.js)
|
||||
*/
|
||||
declare module "https" {
|
||||
import { Duplex } from "node:stream";
|
||||
import * as tls from "node:tls";
|
||||
import * as http from "node:http";
|
||||
import { URL } from "node:url";
|
||||
type ServerOptions<
|
||||
Request extends typeof http.IncomingMessage = typeof http.IncomingMessage,
|
||||
Response extends typeof http.ServerResponse<InstanceType<Request>> = typeof http.ServerResponse,
|
||||
> = tls.SecureContextOptions & tls.TlsOptions & http.ServerOptions<Request, Response>;
|
||||
type RequestOptions =
|
||||
& 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 {
|
||||
maxCachedSessions?: number | undefined;
|
||||
}
|
||||
/**
|
||||
* An `Agent` object for HTTPS similar to `http.Agent`. See {@link request} for more information.
|
||||
* @since v0.4.5
|
||||
*/
|
||||
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<InstanceType<Request>> = typeof http.ServerResponse,
|
||||
> extends http.Server<Request, Response> {}
|
||||
/**
|
||||
* See `http.Server` for more information.
|
||||
* @since v0.3.4
|
||||
*/
|
||||
class Server<
|
||||
Request extends typeof http.IncomingMessage = typeof http.IncomingMessage,
|
||||
Response extends typeof http.ServerResponse<InstanceType<Request>> = typeof http.ServerResponse,
|
||||
> extends tls.Server {
|
||||
constructor(requestListener?: http.RequestListener<Request, Response>);
|
||||
constructor(
|
||||
options: ServerOptions<Request, Response>,
|
||||
requestListener?: http.RequestListener<Request, Response>,
|
||||
);
|
||||
/**
|
||||
* Closes all connections connected to this server.
|
||||
* @since v18.2.0
|
||||
*/
|
||||
closeAllConnections(): void;
|
||||
/**
|
||||
* Closes all connections connected to this server which are not sending a request or waiting for a response.
|
||||
* @since v18.2.0
|
||||
*/
|
||||
closeIdleConnections(): void;
|
||||
addListener(event: string, listener: (...args: any[]) => void): this;
|
||||
addListener(event: "keylog", listener: (line: Buffer, tlsSocket: tls.TLSSocket) => void): this;
|
||||
addListener(
|
||||
event: "newSession",
|
||||
listener: (sessionId: Buffer, sessionData: Buffer, callback: (err: Error, resp: Buffer) => void) => void,
|
||||
): this;
|
||||
addListener(
|
||||
event: "OCSPRequest",
|
||||
listener: (
|
||||
certificate: Buffer,
|
||||
issuer: Buffer,
|
||||
callback: (err: Error | null, resp: Buffer) => void,
|
||||
) => void,
|
||||
): this;
|
||||
addListener(
|
||||
event: "resumeSession",
|
||||
listener: (sessionId: Buffer, callback: (err: Error, sessionData: Buffer) => void) => void,
|
||||
): this;
|
||||
addListener(event: "secureConnection", listener: (tlsSocket: tls.TLSSocket) => void): this;
|
||||
addListener(event: "tlsClientError", listener: (err: Error, tlsSocket: tls.TLSSocket) => void): this;
|
||||
addListener(event: "close", listener: () => void): this;
|
||||
addListener(event: "connection", listener: (socket: Duplex) => void): this;
|
||||
addListener(event: "error", listener: (err: Error) => void): this;
|
||||
addListener(event: "listening", listener: () => void): this;
|
||||
addListener(event: "checkContinue", listener: http.RequestListener<Request, Response>): this;
|
||||
addListener(event: "checkExpectation", listener: http.RequestListener<Request, Response>): this;
|
||||
addListener(event: "clientError", listener: (err: Error, socket: Duplex) => void): this;
|
||||
addListener(
|
||||
event: "connect",
|
||||
listener: (req: InstanceType<Request>, socket: Duplex, head: Buffer) => void,
|
||||
): this;
|
||||
addListener(event: "request", listener: http.RequestListener<Request, Response>): this;
|
||||
addListener(
|
||||
event: "upgrade",
|
||||
listener: (req: InstanceType<Request>, socket: Duplex, head: Buffer) => void,
|
||||
): this;
|
||||
emit(event: string, ...args: any[]): boolean;
|
||||
emit(event: "keylog", line: Buffer, tlsSocket: tls.TLSSocket): boolean;
|
||||
emit(
|
||||
event: "newSession",
|
||||
sessionId: Buffer,
|
||||
sessionData: Buffer,
|
||||
callback: (err: Error, resp: Buffer) => void,
|
||||
): boolean;
|
||||
emit(
|
||||
event: "OCSPRequest",
|
||||
certificate: Buffer,
|
||||
issuer: Buffer,
|
||||
callback: (err: Error | null, resp: Buffer) => 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;
|
||||
emit(event: "connection", socket: Duplex): boolean;
|
||||
emit(event: "error", err: Error): boolean;
|
||||
emit(event: "listening"): boolean;
|
||||
emit(
|
||||
event: "checkContinue",
|
||||
req: InstanceType<Request>,
|
||||
res: InstanceType<Response>,
|
||||
): boolean;
|
||||
emit(
|
||||
event: "checkExpectation",
|
||||
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: "request",
|
||||
req: InstanceType<Request>,
|
||||
res: InstanceType<Response>,
|
||||
): boolean;
|
||||
emit(event: "upgrade", req: InstanceType<Request>, socket: Duplex, head: Buffer): boolean;
|
||||
on(event: string, listener: (...args: any[]) => void): this;
|
||||
on(event: "keylog", listener: (line: Buffer, tlsSocket: tls.TLSSocket) => void): this;
|
||||
on(
|
||||
event: "newSession",
|
||||
listener: (sessionId: Buffer, sessionData: Buffer, callback: (err: Error, resp: Buffer) => void) => void,
|
||||
): this;
|
||||
on(
|
||||
event: "OCSPRequest",
|
||||
listener: (
|
||||
certificate: Buffer,
|
||||
issuer: Buffer,
|
||||
callback: (err: Error | null, resp: Buffer) => void,
|
||||
) => void,
|
||||
): this;
|
||||
on(
|
||||
event: "resumeSession",
|
||||
listener: (sessionId: Buffer, callback: (err: Error, sessionData: Buffer) => void) => void,
|
||||
): this;
|
||||
on(event: "secureConnection", listener: (tlsSocket: tls.TLSSocket) => void): this;
|
||||
on(event: "tlsClientError", listener: (err: Error, tlsSocket: tls.TLSSocket) => void): this;
|
||||
on(event: "close", listener: () => void): this;
|
||||
on(event: "connection", listener: (socket: Duplex) => void): this;
|
||||
on(event: "error", listener: (err: Error) => void): this;
|
||||
on(event: "listening", listener: () => void): this;
|
||||
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: "request", listener: http.RequestListener<Request, Response>): this;
|
||||
on(event: "upgrade", listener: (req: InstanceType<Request>, socket: Duplex, head: Buffer) => void): this;
|
||||
once(event: string, listener: (...args: any[]) => void): this;
|
||||
once(event: "keylog", listener: (line: Buffer, tlsSocket: tls.TLSSocket) => void): this;
|
||||
once(
|
||||
event: "newSession",
|
||||
listener: (sessionId: Buffer, sessionData: Buffer, callback: (err: Error, resp: Buffer) => void) => void,
|
||||
): this;
|
||||
once(
|
||||
event: "OCSPRequest",
|
||||
listener: (
|
||||
certificate: Buffer,
|
||||
issuer: Buffer,
|
||||
callback: (err: Error | null, resp: Buffer) => void,
|
||||
) => void,
|
||||
): this;
|
||||
once(
|
||||
event: "resumeSession",
|
||||
listener: (sessionId: Buffer, callback: (err: Error, sessionData: Buffer) => void) => void,
|
||||
): this;
|
||||
once(event: "secureConnection", listener: (tlsSocket: tls.TLSSocket) => void): this;
|
||||
once(event: "tlsClientError", listener: (err: Error, tlsSocket: tls.TLSSocket) => void): this;
|
||||
once(event: "close", listener: () => void): this;
|
||||
once(event: "connection", listener: (socket: Duplex) => void): this;
|
||||
once(event: "error", listener: (err: Error) => void): this;
|
||||
once(event: "listening", listener: () => void): this;
|
||||
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: "request", listener: http.RequestListener<Request, Response>): this;
|
||||
once(event: "upgrade", listener: (req: InstanceType<Request>, socket: Duplex, head: Buffer) => void): this;
|
||||
prependListener(event: string, listener: (...args: any[]) => void): this;
|
||||
prependListener(event: "keylog", listener: (line: Buffer, tlsSocket: tls.TLSSocket) => void): this;
|
||||
prependListener(
|
||||
event: "newSession",
|
||||
listener: (sessionId: Buffer, sessionData: Buffer, callback: (err: Error, resp: Buffer) => void) => void,
|
||||
): this;
|
||||
prependListener(
|
||||
event: "OCSPRequest",
|
||||
listener: (
|
||||
certificate: Buffer,
|
||||
issuer: Buffer,
|
||||
callback: (err: Error | null, resp: Buffer) => void,
|
||||
) => void,
|
||||
): this;
|
||||
prependListener(
|
||||
event: "resumeSession",
|
||||
listener: (sessionId: Buffer, callback: (err: Error, sessionData: Buffer) => void) => void,
|
||||
): this;
|
||||
prependListener(event: "secureConnection", listener: (tlsSocket: tls.TLSSocket) => void): this;
|
||||
prependListener(event: "tlsClientError", listener: (err: Error, tlsSocket: tls.TLSSocket) => void): this;
|
||||
prependListener(event: "close", listener: () => void): this;
|
||||
prependListener(event: "connection", listener: (socket: Duplex) => void): this;
|
||||
prependListener(event: "error", listener: (err: Error) => void): this;
|
||||
prependListener(event: "listening", listener: () => void): this;
|
||||
prependListener(event: "checkContinue", listener: http.RequestListener<Request, Response>): this;
|
||||
prependListener(event: "checkExpectation", listener: http.RequestListener<Request, Response>): this;
|
||||
prependListener(event: "clientError", listener: (err: Error, socket: Duplex) => void): this;
|
||||
prependListener(
|
||||
event: "connect",
|
||||
listener: (req: InstanceType<Request>, socket: Duplex, head: Buffer) => void,
|
||||
): this;
|
||||
prependListener(event: "request", listener: http.RequestListener<Request, Response>): this;
|
||||
prependListener(
|
||||
event: "upgrade",
|
||||
listener: (req: InstanceType<Request>, socket: Duplex, head: Buffer) => void,
|
||||
): this;
|
||||
prependOnceListener(event: string, listener: (...args: any[]) => void): this;
|
||||
prependOnceListener(event: "keylog", listener: (line: Buffer, tlsSocket: tls.TLSSocket) => void): this;
|
||||
prependOnceListener(
|
||||
event: "newSession",
|
||||
listener: (sessionId: Buffer, sessionData: Buffer, callback: (err: Error, resp: Buffer) => void) => void,
|
||||
): this;
|
||||
prependOnceListener(
|
||||
event: "OCSPRequest",
|
||||
listener: (
|
||||
certificate: Buffer,
|
||||
issuer: Buffer,
|
||||
callback: (err: Error | null, resp: Buffer) => void,
|
||||
) => void,
|
||||
): this;
|
||||
prependOnceListener(
|
||||
event: "resumeSession",
|
||||
listener: (sessionId: Buffer, callback: (err: Error, sessionData: Buffer) => void) => void,
|
||||
): this;
|
||||
prependOnceListener(event: "secureConnection", listener: (tlsSocket: tls.TLSSocket) => void): this;
|
||||
prependOnceListener(event: "tlsClientError", listener: (err: Error, tlsSocket: tls.TLSSocket) => void): this;
|
||||
prependOnceListener(event: "close", listener: () => void): this;
|
||||
prependOnceListener(event: "connection", listener: (socket: Duplex) => void): this;
|
||||
prependOnceListener(event: "error", listener: (err: Error) => void): this;
|
||||
prependOnceListener(event: "listening", listener: () => void): this;
|
||||
prependOnceListener(event: "checkContinue", listener: http.RequestListener<Request, Response>): this;
|
||||
prependOnceListener(event: "checkExpectation", listener: http.RequestListener<Request, Response>): this;
|
||||
prependOnceListener(event: "clientError", listener: (err: Error, socket: Duplex) => void): this;
|
||||
prependOnceListener(
|
||||
event: "connect",
|
||||
listener: (req: InstanceType<Request>, socket: Duplex, head: Buffer) => void,
|
||||
): this;
|
||||
prependOnceListener(event: "request", listener: http.RequestListener<Request, Response>): this;
|
||||
prependOnceListener(
|
||||
event: "upgrade",
|
||||
listener: (req: InstanceType<Request>, socket: Duplex, head: Buffer) => void,
|
||||
): this;
|
||||
}
|
||||
/**
|
||||
* ```js
|
||||
* // curl -k https://localhost:8000/
|
||||
* import https from 'node:https';
|
||||
* import fs from 'node:fs';
|
||||
*
|
||||
* const options = {
|
||||
* key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
|
||||
* cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem'),
|
||||
* };
|
||||
*
|
||||
* https.createServer(options, (req, res) => {
|
||||
* res.writeHead(200);
|
||||
* res.end('hello world\n');
|
||||
* }).listen(8000);
|
||||
* ```
|
||||
*
|
||||
* Or
|
||||
*
|
||||
* ```js
|
||||
* import https from 'node:https';
|
||||
* import fs from 'node:fs';
|
||||
*
|
||||
* const options = {
|
||||
* pfx: fs.readFileSync('test/fixtures/test_cert.pfx'),
|
||||
* passphrase: 'sample',
|
||||
* };
|
||||
*
|
||||
* https.createServer(options, (req, res) => {
|
||||
* res.writeHead(200);
|
||||
* res.end('hello world\n');
|
||||
* }).listen(8000);
|
||||
* ```
|
||||
* @since v0.3.4
|
||||
* @param options Accepts `options` from `createServer`, `createSecureContext` and `createServer`.
|
||||
* @param requestListener A listener to be added to the `'request'` event.
|
||||
*/
|
||||
function createServer<
|
||||
Request extends typeof http.IncomingMessage = typeof http.IncomingMessage,
|
||||
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<InstanceType<Request>> = typeof http.ServerResponse,
|
||||
>(
|
||||
options: ServerOptions<Request, Response>,
|
||||
requestListener?: http.RequestListener<Request, Response>,
|
||||
): Server<Request, Response>;
|
||||
/**
|
||||
* Makes a request to a secure web server.
|
||||
*
|
||||
* The following additional `options` from `tls.connect()` are also accepted: `ca`, `cert`, `ciphers`, `clientCertEngine`, `crl`, `dhparam`, `ecdhCurve`, `honorCipherOrder`, `key`, `passphrase`,
|
||||
* `pfx`, `rejectUnauthorized`, `secureOptions`, `secureProtocol`, `servername`, `sessionIdContext`, `highWaterMark`.
|
||||
*
|
||||
* `options` can be an object, a string, or a `URL` object. If `options` is a
|
||||
* string, it is automatically parsed with `new URL()`. If it is a `URL` object, it will be automatically converted to an ordinary `options` object.
|
||||
*
|
||||
* `https.request()` returns an instance of the `http.ClientRequest` class. The `ClientRequest` instance is a writable stream. If one needs to
|
||||
* upload a file with a POST request, then write to the `ClientRequest` object.
|
||||
*
|
||||
* ```js
|
||||
* import https from 'node:https';
|
||||
*
|
||||
* const options = {
|
||||
* hostname: 'encrypted.google.com',
|
||||
* port: 443,
|
||||
* path: '/',
|
||||
* method: 'GET',
|
||||
* };
|
||||
*
|
||||
* const req = https.request(options, (res) => {
|
||||
* console.log('statusCode:', res.statusCode);
|
||||
* console.log('headers:', res.headers);
|
||||
*
|
||||
* res.on('data', (d) => {
|
||||
* process.stdout.write(d);
|
||||
* });
|
||||
* });
|
||||
*
|
||||
* req.on('error', (e) => {
|
||||
* console.error(e);
|
||||
* });
|
||||
* req.end();
|
||||
* ```
|
||||
*
|
||||
* Example using options from `tls.connect()`:
|
||||
*
|
||||
* ```js
|
||||
* const options = {
|
||||
* hostname: 'encrypted.google.com',
|
||||
* port: 443,
|
||||
* path: '/',
|
||||
* method: 'GET',
|
||||
* key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
|
||||
* cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem'),
|
||||
* };
|
||||
* options.agent = new https.Agent(options);
|
||||
*
|
||||
* const req = https.request(options, (res) => {
|
||||
* // ...
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* Alternatively, opt out of connection pooling by not using an `Agent`.
|
||||
*
|
||||
* ```js
|
||||
* const options = {
|
||||
* hostname: 'encrypted.google.com',
|
||||
* port: 443,
|
||||
* path: '/',
|
||||
* method: 'GET',
|
||||
* key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
|
||||
* cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem'),
|
||||
* agent: false,
|
||||
* };
|
||||
*
|
||||
* const req = https.request(options, (res) => {
|
||||
* // ...
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* Example using a `URL` as `options`:
|
||||
*
|
||||
* ```js
|
||||
* const options = new URL('https://abc:xyz@example.com');
|
||||
*
|
||||
* const req = https.request(options, (res) => {
|
||||
* // ...
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* Example pinning on certificate fingerprint, or the public key (similar to`pin-sha256`):
|
||||
*
|
||||
* ```js
|
||||
* 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');
|
||||
* }
|
||||
* const options = {
|
||||
* hostname: 'github.com',
|
||||
* port: 443,
|
||||
* path: '/',
|
||||
* method: 'GET',
|
||||
* checkServerIdentity: function(host, cert) {
|
||||
* // Make sure the certificate is issued to the host we are connected to
|
||||
* const err = tls.checkServerIdentity(host, cert);
|
||||
* if (err) {
|
||||
* return err;
|
||||
* }
|
||||
*
|
||||
* // Pin the public key, similar to HPKP pin-sha256 pinning
|
||||
* const pubkey256 = 'pL1+qb9HTMRZJmuC/bB/ZI9d302BYrrqiVuRyW+DGrU=';
|
||||
* if (sha256(cert.pubkey) !== pubkey256) {
|
||||
* const msg = 'Certificate verification error: ' +
|
||||
* `The public key of '${cert.subject.CN}' ` +
|
||||
* 'does not match our pinned fingerprint';
|
||||
* return new Error(msg);
|
||||
* }
|
||||
*
|
||||
* // Pin the exact certificate, rather than the pub key
|
||||
* const cert256 = '25:FE:39:32:D9:63:8C:8A:FC:A1:9A:29:87:' +
|
||||
* 'D8:3E:4C:1D:98:DB:71:E4:1A:48:03:98:EA:22:6A:BD:8B:93:16';
|
||||
* if (cert.fingerprint256 !== cert256) {
|
||||
* const msg = 'Certificate verification error: ' +
|
||||
* `The certificate of '${cert.subject.CN}' ` +
|
||||
* 'does not match our pinned fingerprint';
|
||||
* return new Error(msg);
|
||||
* }
|
||||
*
|
||||
* // This loop is informational only.
|
||||
* // Print the certificate and public key fingerprints of all certs in the
|
||||
* // chain. Its common to pin the public key of the issuer on the public
|
||||
* // internet, while pinning the public key of the service in sensitive
|
||||
* // environments.
|
||||
* do {
|
||||
* console.log('Subject Common Name:', cert.subject.CN);
|
||||
* console.log(' Certificate SHA256 fingerprint:', cert.fingerprint256);
|
||||
*
|
||||
* hash = crypto.createHash('sha256');
|
||||
* console.log(' Public key ping-sha256:', sha256(cert.pubkey));
|
||||
*
|
||||
* lastprint256 = cert.fingerprint256;
|
||||
* cert = cert.issuerCertificate;
|
||||
* } while (cert.fingerprint256 !== lastprint256);
|
||||
*
|
||||
* },
|
||||
* };
|
||||
*
|
||||
* options.agent = new https.Agent(options);
|
||||
* const req = https.request(options, (res) => {
|
||||
* console.log('All OK. Server matched our pinned cert or public key');
|
||||
* console.log('statusCode:', res.statusCode);
|
||||
* // Print the HPKP values
|
||||
* console.log('headers:', res.headers['public-key-pins']);
|
||||
*
|
||||
* res.on('data', (d) => {});
|
||||
* });
|
||||
*
|
||||
* req.on('error', (e) => {
|
||||
* console.error(e.message);
|
||||
* });
|
||||
* req.end();
|
||||
* ```
|
||||
*
|
||||
* Outputs for example:
|
||||
*
|
||||
* ```text
|
||||
* Subject Common Name: github.com
|
||||
* Certificate SHA256 fingerprint: 25:FE:39:32:D9:63:8C:8A:FC:A1:9A:29:87:D8:3E:4C:1D:98:DB:71:E4:1A:48:03:98:EA:22:6A:BD:8B:93:16
|
||||
* Public key ping-sha256: pL1+qb9HTMRZJmuC/bB/ZI9d302BYrrqiVuRyW+DGrU=
|
||||
* Subject Common Name: DigiCert SHA2 Extended Validation Server CA
|
||||
* Certificate SHA256 fingerprint: 40:3E:06:2A:26:53:05:91:13:28:5B:AF:80:A0:D4:AE:42:2C:84:8C:9F:78:FA:D0:1F:C9:4B:C5:B8:7F:EF:1A
|
||||
* Public key ping-sha256: RRM1dGqnDFsCJXBTHky16vi1obOlCgFFn/yOhI/y+ho=
|
||||
* Subject Common Name: DigiCert High Assurance EV Root CA
|
||||
* Certificate SHA256 fingerprint: 74:31:E5:F4:C3:C1:CE:46:90:77:4F:0B:61:E0:54:40:88:3B:A9:A0:1E:D0:0B:A6:AB:D7:80:6E:D3:B1:18:CF
|
||||
* Public key ping-sha256: WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18=
|
||||
* All OK. Server matched our pinned cert or public key
|
||||
* statusCode: 200
|
||||
* headers: max-age=0; pin-sha256="WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18="; pin-sha256="RRM1dGqnDFsCJXBTHky16vi1obOlCgFFn/yOhI/y+ho=";
|
||||
* pin-sha256="k2v657xBsOVe1PQRwOsHsw3bsGT2VzIqz5K+59sNQws="; pin-sha256="K87oWBWM9UZfyddvDfoxL+8lpNyoUB2ptGtn0fv6G2Q="; pin-sha256="IQBnNBEiFuhj+8x6X8XLgh01V9Ic5/V3IRQLNFFc7v4=";
|
||||
* pin-sha256="iie1VXtL7HzAMF+/PVPR9xzT80kQxdZeJ+zduCB3uj0="; pin-sha256="LvRiGEjRqfzurezaWuj8Wie2gyHMrW5Q06LspMnox7A="; includeSubDomains
|
||||
* ```
|
||||
* @since v0.3.6
|
||||
* @param options Accepts all `options` from `request`, with some differences in default values:
|
||||
*/
|
||||
function request(
|
||||
options: RequestOptions | string | URL,
|
||||
callback?: (res: http.IncomingMessage) => void,
|
||||
): http.ClientRequest;
|
||||
function request(
|
||||
url: string | URL,
|
||||
options: RequestOptions,
|
||||
callback?: (res: http.IncomingMessage) => void,
|
||||
): http.ClientRequest;
|
||||
/**
|
||||
* Like `http.get()` but for HTTPS.
|
||||
*
|
||||
* `options` can be an object, a string, or a `URL` object. If `options` is a
|
||||
* 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
|
||||
* import https from 'node:https';
|
||||
*
|
||||
* https.get('https://encrypted.google.com/', (res) => {
|
||||
* console.log('statusCode:', res.statusCode);
|
||||
* console.log('headers:', res.headers);
|
||||
*
|
||||
* res.on('data', (d) => {
|
||||
* process.stdout.write(d);
|
||||
* });
|
||||
*
|
||||
* }).on('error', (e) => {
|
||||
* console.error(e);
|
||||
* });
|
||||
* ```
|
||||
* @since v0.3.6
|
||||
* @param options Accepts the same `options` as {@link request}, with the `method` always set to `GET`.
|
||||
*/
|
||||
function get(
|
||||
options: RequestOptions | string | URL,
|
||||
callback?: (res: http.IncomingMessage) => void,
|
||||
): http.ClientRequest;
|
||||
function get(
|
||||
url: string | URL,
|
||||
options: RequestOptions,
|
||||
callback?: (res: http.IncomingMessage) => void,
|
||||
): http.ClientRequest;
|
||||
let globalAgent: Agent;
|
||||
}
|
||||
declare module "node:https" {
|
||||
export * from "https";
|
||||
}
|
||||
99
node_modules/@types/node/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
/**
|
||||
* License for programmatically and manually incorporated
|
||||
* documentation aka. `JSDoc` from https://github.com/nodejs/node/tree/master/doc
|
||||
*
|
||||
* Copyright Node.js contributors. All rights reserved.
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// NOTE: These definitions support Node.js and TypeScript 5.8+.
|
||||
|
||||
// Reference required TypeScript libraries:
|
||||
/// <reference lib="es2020" />
|
||||
/// <reference lib="esnext.disposable" />
|
||||
/// <reference lib="esnext.float16" />
|
||||
|
||||
// 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/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="assert.d.ts" />
|
||||
/// <reference path="assert/strict.d.ts" />
|
||||
/// <reference path="async_hooks.d.ts" />
|
||||
/// <reference path="buffer.d.ts" />
|
||||
/// <reference path="child_process.d.ts" />
|
||||
/// <reference path="cluster.d.ts" />
|
||||
/// <reference path="console.d.ts" />
|
||||
/// <reference path="constants.d.ts" />
|
||||
/// <reference path="crypto.d.ts" />
|
||||
/// <reference path="dgram.d.ts" />
|
||||
/// <reference path="diagnostics_channel.d.ts" />
|
||||
/// <reference path="dns.d.ts" />
|
||||
/// <reference path="dns/promises.d.ts" />
|
||||
/// <reference path="domain.d.ts" />
|
||||
/// <reference path="events.d.ts" />
|
||||
/// <reference path="fs.d.ts" />
|
||||
/// <reference path="fs/promises.d.ts" />
|
||||
/// <reference path="http.d.ts" />
|
||||
/// <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" />
|
||||
/// <reference path="path.d.ts" />
|
||||
/// <reference path="perf_hooks.d.ts" />
|
||||
/// <reference path="process.d.ts" />
|
||||
/// <reference path="punycode.d.ts" />
|
||||
/// <reference path="querystring.d.ts" />
|
||||
/// <reference path="readline.d.ts" />
|
||||
/// <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" />
|
||||
/// <reference path="stream/web.d.ts" />
|
||||
/// <reference path="string_decoder.d.ts" />
|
||||
/// <reference path="test.d.ts" />
|
||||
/// <reference path="timers.d.ts" />
|
||||
/// <reference path="timers/promises.d.ts" />
|
||||
/// <reference path="tls.d.ts" />
|
||||
/// <reference path="trace_events.d.ts" />
|
||||
/// <reference path="tty.d.ts" />
|
||||
/// <reference path="url.d.ts" />
|
||||
/// <reference path="util.d.ts" />
|
||||
/// <reference path="v8.d.ts" />
|
||||
/// <reference path="vm.d.ts" />
|
||||
/// <reference path="wasi.d.ts" />
|
||||
/// <reference path="worker_threads.d.ts" />
|
||||
/// <reference path="zlib.d.ts" />
|
||||
253
node_modules/@types/node/inspector.d.ts
generated
vendored
Normal file
@@ -0,0 +1,253 @@
|
||||
/**
|
||||
* The `node:inspector` module provides an API for interacting with the V8
|
||||
* inspector.
|
||||
* @see [source](https://github.com/nodejs/node/blob/v24.x/lib/inspector.js)
|
||||
*/
|
||||
declare module "inspector" {
|
||||
import EventEmitter = require("node:events");
|
||||
/**
|
||||
* The `inspector.Session` is used for dispatching messages to the V8 inspector
|
||||
* back-end and receiving message responses and notifications.
|
||||
*/
|
||||
class Session extends EventEmitter {
|
||||
/**
|
||||
* Create a new instance of the inspector.Session class.
|
||||
* The inspector session needs to be connected through `session.connect()` before the messages can be dispatched to the inspector backend.
|
||||
*/
|
||||
constructor();
|
||||
/**
|
||||
* Connects a session to the inspector back-end.
|
||||
*/
|
||||
connect(): void;
|
||||
/**
|
||||
* Connects a session to the inspector back-end.
|
||||
* An exception will be thrown if this API was not called on a Worker thread.
|
||||
* @since v12.11.0
|
||||
*/
|
||||
connectToMainThread(): void;
|
||||
/**
|
||||
* Immediately close the session. All pending message callbacks will be called with an error.
|
||||
* `session.connect()` will need to be called to be able to send messages again.
|
||||
* Reconnected session will lose all inspector state, such as enabled agents or configured breakpoints.
|
||||
*/
|
||||
disconnect(): void;
|
||||
}
|
||||
/**
|
||||
* Activate inspector on host and port. Equivalent to `node --inspect=[[host:]port]`, but can be done programmatically after node has
|
||||
* started.
|
||||
*
|
||||
* If wait is `true`, will block until a client has connected to the inspect port
|
||||
* and flow control has been passed to the debugger client.
|
||||
*
|
||||
* See the [security warning](https://nodejs.org/docs/latest-v24.x/api/cli.html#warning-binding-inspector-to-a-public-ipport-combination-is-insecure)
|
||||
* regarding the `host` parameter usage.
|
||||
* @param port Port to listen on for inspector connections. Defaults to what was specified on the CLI.
|
||||
* @param host Host to listen on for inspector connections. Defaults to what was specified on the CLI.
|
||||
* @param wait Block until a client has connected. Defaults to what was specified on the CLI.
|
||||
* @returns Disposable that calls `inspector.close()`.
|
||||
*/
|
||||
function open(port?: number, host?: string, wait?: boolean): Disposable;
|
||||
/**
|
||||
* Deactivate the inspector. Blocks until there are no active connections.
|
||||
*/
|
||||
function close(): void;
|
||||
/**
|
||||
* Return the URL of the active inspector, or `undefined` if there is none.
|
||||
*
|
||||
* ```console
|
||||
* $ node --inspect -p 'inspector.url()'
|
||||
* Debugger listening on ws://127.0.0.1:9229/166e272e-7a30-4d09-97ce-f1c012b43c34
|
||||
* For help, see: https://nodejs.org/en/docs/inspector
|
||||
* ws://127.0.0.1:9229/166e272e-7a30-4d09-97ce-f1c012b43c34
|
||||
*
|
||||
* $ node --inspect=localhost:3000 -p 'inspector.url()'
|
||||
* Debugger listening on ws://localhost:3000/51cf8d0e-3c36-4c59-8efd-54519839e56a
|
||||
* For help, see: https://nodejs.org/en/docs/inspector
|
||||
* ws://localhost:3000/51cf8d0e-3c36-4c59-8efd-54519839e56a
|
||||
*
|
||||
* $ node -p 'inspector.url()'
|
||||
* undefined
|
||||
* ```
|
||||
*/
|
||||
function url(): string | undefined;
|
||||
/**
|
||||
* Blocks until a client (existing or connected later) has sent `Runtime.runIfWaitingForDebugger` command.
|
||||
*
|
||||
* An exception will be thrown if there is no active inspector.
|
||||
* @since v12.7.0
|
||||
*/
|
||||
function waitForDebugger(): void;
|
||||
// These methods are exposed by the V8 inspector console API (inspector/v8-console.h).
|
||||
// The method signatures differ from those of the Node.js console, and are deliberately
|
||||
// typed permissively.
|
||||
interface InspectorConsole {
|
||||
debug(...data: any[]): void;
|
||||
error(...data: any[]): void;
|
||||
info(...data: any[]): void;
|
||||
log(...data: any[]): void;
|
||||
warn(...data: any[]): void;
|
||||
dir(...data: any[]): void;
|
||||
dirxml(...data: any[]): void;
|
||||
table(...data: any[]): void;
|
||||
trace(...data: any[]): void;
|
||||
group(...data: any[]): void;
|
||||
groupCollapsed(...data: any[]): void;
|
||||
groupEnd(...data: any[]): void;
|
||||
clear(...data: any[]): void;
|
||||
count(label?: any): void;
|
||||
countReset(label?: any): void;
|
||||
assert(value?: any, ...data: any[]): void;
|
||||
profile(label?: any): void;
|
||||
profileEnd(label?: any): void;
|
||||
time(label?: any): void;
|
||||
timeLog(label?: any): void;
|
||||
timeStamp(label?: any): void;
|
||||
}
|
||||
/**
|
||||
* An object to send messages to the remote inspector console.
|
||||
* @since v11.0.0
|
||||
*/
|
||||
const console: InspectorConsole;
|
||||
// DevTools protocol event broadcast methods
|
||||
namespace Network {
|
||||
/**
|
||||
* This feature is only available with the `--experimental-network-inspection` flag enabled.
|
||||
*
|
||||
* Broadcasts the `Network.requestWillBeSent` event to connected frontends. This event indicates that
|
||||
* the application is about to send an HTTP request.
|
||||
* @since v22.6.0
|
||||
*/
|
||||
function requestWillBeSent(params: RequestWillBeSentEventDataType): void;
|
||||
/**
|
||||
* This feature is only available with the `--experimental-network-inspection` flag enabled.
|
||||
*
|
||||
* Broadcasts the `Network.dataReceived` event to connected frontends, or buffers the data if
|
||||
* `Network.streamResourceContent` command was not invoked for the given request yet.
|
||||
*
|
||||
* Also enables `Network.getResponseBody` command to retrieve the response data.
|
||||
* @since v24.2.0
|
||||
*/
|
||||
function dataReceived(params: DataReceivedEventDataType): void;
|
||||
/**
|
||||
* This feature is only available with the `--experimental-network-inspection` flag enabled.
|
||||
*
|
||||
* Enables `Network.getRequestPostData` command to retrieve the request data.
|
||||
* @since v24.3.0
|
||||
*/
|
||||
function dataSent(params: unknown): void;
|
||||
/**
|
||||
* This feature is only available with the `--experimental-network-inspection` flag enabled.
|
||||
*
|
||||
* Broadcasts the `Network.responseReceived` event to connected frontends. This event indicates that
|
||||
* HTTP response is available.
|
||||
* @since v22.6.0
|
||||
*/
|
||||
function responseReceived(params: ResponseReceivedEventDataType): void;
|
||||
/**
|
||||
* This feature is only available with the `--experimental-network-inspection` flag enabled.
|
||||
*
|
||||
* Broadcasts the `Network.loadingFinished` event to connected frontends. This event indicates that
|
||||
* HTTP request has finished loading.
|
||||
* @since v22.6.0
|
||||
*/
|
||||
function loadingFinished(params: LoadingFinishedEventDataType): void;
|
||||
/**
|
||||
* This feature is only available with the `--experimental-network-inspection` flag enabled.
|
||||
*
|
||||
* Broadcasts the `Network.loadingFailed` event to connected frontends. This event indicates that
|
||||
* HTTP request has failed to load.
|
||||
* @since v22.7.0
|
||||
*/
|
||||
function loadingFailed(params: LoadingFailedEventDataType): void;
|
||||
}
|
||||
namespace NetworkResources {
|
||||
/**
|
||||
* This feature is only available with the `--experimental-inspector-network-resource` flag enabled.
|
||||
*
|
||||
* The inspector.NetworkResources.put method is used to provide a response for a loadNetworkResource
|
||||
* request issued via the Chrome DevTools Protocol (CDP).
|
||||
* This is typically triggered when a source map is specified by URL, and a DevTools frontend—such as
|
||||
* Chrome—requests the resource to retrieve the source map.
|
||||
*
|
||||
* This method allows developers to predefine the resource content to be served in response to such CDP requests.
|
||||
*
|
||||
* ```js
|
||||
* const inspector = require('node:inspector');
|
||||
* // By preemptively calling put to register the resource, a source map can be resolved when
|
||||
* // a loadNetworkResource request is made from the frontend.
|
||||
* async function setNetworkResources() {
|
||||
* const mapUrl = 'http://localhost:3000/dist/app.js.map';
|
||||
* const tsUrl = 'http://localhost:3000/src/app.ts';
|
||||
* const distAppJsMap = await fetch(mapUrl).then((res) => res.text());
|
||||
* const srcAppTs = await fetch(tsUrl).then((res) => res.text());
|
||||
* inspector.NetworkResources.put(mapUrl, distAppJsMap);
|
||||
* inspector.NetworkResources.put(tsUrl, srcAppTs);
|
||||
* };
|
||||
* setNetworkResources().then(() => {
|
||||
* require('./dist/app');
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* For more details, see the official CDP documentation: [Network.loadNetworkResource](https://chromedevtools.github.io/devtools-protocol/tot/Network/#method-loadNetworkResource)
|
||||
* @since v24.5.0
|
||||
* @experimental
|
||||
*/
|
||||
function put(url: string, data: string): void;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The `node:inspector` module provides an API for interacting with the V8
|
||||
* inspector.
|
||||
*/
|
||||
declare module "node:inspector" {
|
||||
export * from "inspector";
|
||||
}
|
||||
|
||||
/**
|
||||
* The `node:inspector/promises` module provides an API for interacting with the V8
|
||||
* inspector.
|
||||
* @see [source](https://github.com/nodejs/node/blob/v24.x/lib/inspector/promises.js)
|
||||
* @since v19.0.0
|
||||
*/
|
||||
declare module "inspector/promises" {
|
||||
import EventEmitter = require("node:events");
|
||||
export { close, console, NetworkResources, open, url, waitForDebugger } from "inspector";
|
||||
/**
|
||||
* The `inspector.Session` is used for dispatching messages to the V8 inspector
|
||||
* back-end and receiving message responses and notifications.
|
||||
* @since v19.0.0
|
||||
*/
|
||||
export class Session extends EventEmitter {
|
||||
/**
|
||||
* Create a new instance of the inspector.Session class.
|
||||
* The inspector session needs to be connected through `session.connect()` before the messages can be dispatched to the inspector backend.
|
||||
*/
|
||||
constructor();
|
||||
/**
|
||||
* Connects a session to the inspector back-end.
|
||||
*/
|
||||
connect(): void;
|
||||
/**
|
||||
* Connects a session to the inspector back-end.
|
||||
* An exception will be thrown if this API was not called on a Worker thread.
|
||||
* @since v12.11.0
|
||||
*/
|
||||
connectToMainThread(): void;
|
||||
/**
|
||||
* Immediately close the session. All pending message callbacks will be called with an error.
|
||||
* `session.connect()` will need to be called to be able to send messages again.
|
||||
* Reconnected session will lose all inspector state, such as enabled agents or configured breakpoints.
|
||||
*/
|
||||
disconnect(): void;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The `node:inspector/promises` module provides an API for interacting with the V8
|
||||
* inspector.
|
||||
* @since v19.0.0
|
||||
*/
|
||||
declare module "node:inspector/promises" {
|
||||
export * from "inspector/promises";
|
||||
}
|
||||
4052
node_modules/@types/node/inspector.generated.d.ts
generated
vendored
Normal file
894
node_modules/@types/node/module.d.ts
generated
vendored
Normal file
@@ -0,0 +1,894 @@
|
||||
/**
|
||||
* @since v0.3.7
|
||||
*/
|
||||
declare module "module" {
|
||||
import { URL } from "node:url";
|
||||
class Module {
|
||||
constructor(id: string, parent?: Module);
|
||||
}
|
||||
interface Module extends NodeJS.Module {}
|
||||
namespace Module {
|
||||
export { Module };
|
||||
}
|
||||
namespace Module {
|
||||
/**
|
||||
* A list of the names of all modules provided by Node.js. Can be used to verify
|
||||
* if a module is maintained by a third party or not.
|
||||
*
|
||||
* Note: the list doesn't contain prefix-only modules like `node:test`.
|
||||
* @since v9.3.0, v8.10.0, v6.13.0
|
||||
*/
|
||||
const builtinModules: readonly string[];
|
||||
/**
|
||||
* @since v12.2.0
|
||||
* @param path Filename to be used to construct the require
|
||||
* function. Must be a file URL object, file URL string, or absolute path
|
||||
* string.
|
||||
*/
|
||||
function createRequire(path: string | URL): NodeJS.Require;
|
||||
namespace constants {
|
||||
/**
|
||||
* The following constants are returned as the `status` field in the object returned by
|
||||
* {@link enableCompileCache} to indicate the result of the attempt to enable the
|
||||
* [module compile cache](https://nodejs.org/docs/latest-v24.x/api/module.html#module-compile-cache).
|
||||
* @since v22.8.0
|
||||
*/
|
||||
namespace compileCacheStatus {
|
||||
/**
|
||||
* Node.js has enabled the compile cache successfully. The directory used to store the
|
||||
* compile cache will be returned in the `directory` field in the
|
||||
* returned object.
|
||||
*/
|
||||
const ENABLED: number;
|
||||
/**
|
||||
* The compile cache has already been enabled before, either by a previous call to
|
||||
* {@link enableCompileCache}, or by the `NODE_COMPILE_CACHE=dir`
|
||||
* environment variable. The directory used to store the
|
||||
* compile cache will be returned in the `directory` field in the
|
||||
* returned object.
|
||||
*/
|
||||
const ALREADY_ENABLED: number;
|
||||
/**
|
||||
* Node.js fails to enable the compile cache. This can be caused by the lack of
|
||||
* permission to use the specified directory, or various kinds of file system errors.
|
||||
* The detail of the failure will be returned in the `message` field in the
|
||||
* returned object.
|
||||
*/
|
||||
const FAILED: number;
|
||||
/**
|
||||
* Node.js cannot enable the compile cache because the environment variable
|
||||
* `NODE_DISABLE_COMPILE_CACHE=1` has been set.
|
||||
*/
|
||||
const DISABLED: number;
|
||||
}
|
||||
}
|
||||
interface EnableCompileCacheResult {
|
||||
/**
|
||||
* One of the {@link constants.compileCacheStatus}
|
||||
*/
|
||||
status: number;
|
||||
/**
|
||||
* If Node.js cannot enable the compile cache, this contains
|
||||
* the error message. Only set if `status` is `module.constants.compileCacheStatus.FAILED`.
|
||||
*/
|
||||
message?: string;
|
||||
/**
|
||||
* If the compile cache is enabled, this contains the directory
|
||||
* where the compile cache is stored. Only set if `status` is
|
||||
* `module.constants.compileCacheStatus.ENABLED` or
|
||||
* `module.constants.compileCacheStatus.ALREADY_ENABLED`.
|
||||
*/
|
||||
directory?: string;
|
||||
}
|
||||
/**
|
||||
* Enable [module compile cache](https://nodejs.org/docs/latest-v24.x/api/module.html#module-compile-cache)
|
||||
* in the current Node.js instance.
|
||||
*
|
||||
* If `cacheDir` is not specified, Node.js will either use the directory specified by the
|
||||
* `NODE_COMPILE_CACHE=dir` environment variable if it's set, or use
|
||||
* `path.join(os.tmpdir(), 'node-compile-cache')` otherwise. For general use cases, it's
|
||||
* recommended to call `module.enableCompileCache()` without specifying the `cacheDir`,
|
||||
* so that the directory can be overridden by the `NODE_COMPILE_CACHE` environment
|
||||
* variable when necessary.
|
||||
*
|
||||
* Since compile cache is supposed to be a quiet optimization that is not required for the
|
||||
* application to be functional, this method is designed to not throw any exception when the
|
||||
* compile cache cannot be enabled. Instead, it will return an object containing an error
|
||||
* message in the `message` field to aid debugging.
|
||||
* If compile cache is enabled successfully, the `directory` field in the returned object
|
||||
* contains the path to the directory where the compile cache is stored. The `status`
|
||||
* field in the returned object would be one of the `module.constants.compileCacheStatus`
|
||||
* values to indicate the result of the attempt to enable the
|
||||
* [module compile cache](https://nodejs.org/docs/latest-v24.x/api/module.html#module-compile-cache).
|
||||
*
|
||||
* This method only affects the current Node.js instance. To enable it in child worker threads,
|
||||
* either call this method in child worker threads too, or set the
|
||||
* `process.env.NODE_COMPILE_CACHE` value to compile cache directory so the behavior can
|
||||
* be inherited into the child workers. The directory can be obtained either from the
|
||||
* `directory` field returned by this method, or with {@link getCompileCacheDir}.
|
||||
* @since v22.8.0
|
||||
* @param cacheDir Optional path to specify the directory where the compile cache
|
||||
* will be stored/retrieved.
|
||||
*/
|
||||
function enableCompileCache(cacheDir?: string): EnableCompileCacheResult;
|
||||
/**
|
||||
* Flush the [module compile cache](https://nodejs.org/docs/latest-v24.x/api/module.html#module-compile-cache)
|
||||
* accumulated from modules already loaded
|
||||
* in the current Node.js instance to disk. This returns after all the flushing
|
||||
* file system operations come to an end, no matter they succeed or not. If there
|
||||
* are any errors, this will fail silently, since compile cache misses should not
|
||||
* interfere with the actual operation of the application.
|
||||
* @since v22.10.0
|
||||
*/
|
||||
function flushCompileCache(): void;
|
||||
/**
|
||||
* @since v22.8.0
|
||||
* @return Path to the [module compile cache](https://nodejs.org/docs/latest-v24.x/api/module.html#module-compile-cache)
|
||||
* directory if it is enabled, or `undefined` otherwise.
|
||||
*/
|
||||
function getCompileCacheDir(): string | undefined;
|
||||
/**
|
||||
* ```text
|
||||
* /path/to/project
|
||||
* ├ packages/
|
||||
* ├ bar/
|
||||
* ├ bar.js
|
||||
* └ package.json // name = '@foo/bar'
|
||||
* └ qux/
|
||||
* ├ node_modules/
|
||||
* └ some-package/
|
||||
* └ package.json // name = 'some-package'
|
||||
* ├ qux.js
|
||||
* └ package.json // name = '@foo/qux'
|
||||
* ├ main.js
|
||||
* └ package.json // name = '@foo'
|
||||
* ```
|
||||
* ```js
|
||||
* // /path/to/project/packages/bar/bar.js
|
||||
* import { findPackageJSON } from 'node:module';
|
||||
*
|
||||
* findPackageJSON('..', import.meta.url);
|
||||
* // '/path/to/project/package.json'
|
||||
* // Same result when passing an absolute specifier instead:
|
||||
* findPackageJSON(new URL('../', import.meta.url));
|
||||
* findPackageJSON(import.meta.resolve('../'));
|
||||
*
|
||||
* findPackageJSON('some-package', import.meta.url);
|
||||
* // '/path/to/project/packages/bar/node_modules/some-package/package.json'
|
||||
* // When passing an absolute specifier, you might get a different result if the
|
||||
* // resolved module is inside a subfolder that has nested `package.json`.
|
||||
* findPackageJSON(import.meta.resolve('some-package'));
|
||||
* // '/path/to/project/packages/bar/node_modules/some-package/some-subfolder/package.json'
|
||||
*
|
||||
* findPackageJSON('@foo/qux', import.meta.url);
|
||||
* // '/path/to/project/packages/qux/package.json'
|
||||
* ```
|
||||
* @since v22.14.0
|
||||
* @param specifier The specifier for the module whose `package.json` to
|
||||
* retrieve. When passing a _bare specifier_, the `package.json` at the root of
|
||||
* the package is returned. When passing a _relative specifier_ or an _absolute specifier_,
|
||||
* the closest parent `package.json` is returned.
|
||||
* @param base The absolute location (`file:` URL string or FS path) of the
|
||||
* containing module. For CJS, use `__filename` (not `__dirname`!); for ESM, use
|
||||
* `import.meta.url`. You do not need to pass it if `specifier` is an _absolute specifier_.
|
||||
* @returns A path if the `package.json` is found. When `startLocation`
|
||||
* is a package, the package's root `package.json`; when a relative or unresolved, the closest
|
||||
* `package.json` to the `startLocation`.
|
||||
*/
|
||||
function findPackageJSON(specifier: string | URL, base?: string | URL): string | undefined;
|
||||
/**
|
||||
* @since v18.6.0, v16.17.0
|
||||
*/
|
||||
function isBuiltin(moduleName: string): boolean;
|
||||
interface RegisterOptions<Data> {
|
||||
/**
|
||||
* If you want to resolve `specifier` relative to a
|
||||
* base URL, such as `import.meta.url`, you can pass that URL here. This
|
||||
* property is ignored if the `parentURL` is supplied as the second argument.
|
||||
* @default 'data:'
|
||||
*/
|
||||
parentURL?: string | URL | undefined;
|
||||
/**
|
||||
* Any arbitrary, cloneable JavaScript value to pass into the
|
||||
* {@link initialize} hook.
|
||||
*/
|
||||
data?: Data | undefined;
|
||||
/**
|
||||
* [Transferable objects](https://nodejs.org/docs/latest-v24.x/api/worker_threads.html#portpostmessagevalue-transferlist)
|
||||
* to be passed into the `initialize` hook.
|
||||
*/
|
||||
transferList?: any[] | undefined;
|
||||
}
|
||||
/* eslint-disable @definitelytyped/no-unnecessary-generics */
|
||||
/**
|
||||
* Register a module that exports hooks that customize Node.js module
|
||||
* resolution and loading behavior. See
|
||||
* [Customization hooks](https://nodejs.org/docs/latest-v24.x/api/module.html#customization-hooks).
|
||||
*
|
||||
* This feature requires `--allow-worker` if used with the
|
||||
* [Permission Model](https://nodejs.org/docs/latest-v24.x/api/permissions.html#permission-model).
|
||||
* @since v20.6.0, v18.19.0
|
||||
* @param specifier Customization hooks to be registered; this should be
|
||||
* the same string that would be passed to `import()`, except that if it is
|
||||
* relative, it is resolved relative to `parentURL`.
|
||||
* @param parentURL f you want to resolve `specifier` relative to a base
|
||||
* URL, such as `import.meta.url`, you can pass that URL here.
|
||||
*/
|
||||
function register<Data = any>(
|
||||
specifier: string | URL,
|
||||
parentURL?: string | URL,
|
||||
options?: RegisterOptions<Data>,
|
||||
): void;
|
||||
function register<Data = any>(specifier: string | URL, options?: RegisterOptions<Data>): void;
|
||||
interface RegisterHooksOptions {
|
||||
/**
|
||||
* See [load hook](https://nodejs.org/docs/latest-v24.x/api/module.html#loadurl-context-nextload).
|
||||
* @default undefined
|
||||
*/
|
||||
load?: LoadHookSync | undefined;
|
||||
/**
|
||||
* See [resolve hook](https://nodejs.org/docs/latest-v24.x/api/module.html#resolvespecifier-context-nextresolve).
|
||||
* @default undefined
|
||||
*/
|
||||
resolve?: ResolveHookSync | undefined;
|
||||
}
|
||||
interface ModuleHooks {
|
||||
/**
|
||||
* Deregister the hook instance.
|
||||
*/
|
||||
deregister(): void;
|
||||
}
|
||||
/**
|
||||
* Register [hooks](https://nodejs.org/docs/latest-v24.x/api/module.html#customization-hooks)
|
||||
* that customize Node.js module resolution and loading behavior.
|
||||
* @since v22.15.0
|
||||
* @experimental
|
||||
*/
|
||||
function registerHooks(options: RegisterHooksOptions): ModuleHooks;
|
||||
interface StripTypeScriptTypesOptions {
|
||||
/**
|
||||
* Possible values are:
|
||||
* * `'strip'` Only strip type annotations without performing the transformation of TypeScript features.
|
||||
* * `'transform'` Strip type annotations and transform TypeScript features to JavaScript.
|
||||
* @default 'strip'
|
||||
*/
|
||||
mode?: "strip" | "transform" | undefined;
|
||||
/**
|
||||
* Only when `mode` is `'transform'`, if `true`, a source map
|
||||
* will be generated for the transformed code.
|
||||
* @default false
|
||||
*/
|
||||
sourceMap?: boolean | undefined;
|
||||
/**
|
||||
* Specifies the source url used in the source map.
|
||||
*/
|
||||
sourceUrl?: string | undefined;
|
||||
}
|
||||
/**
|
||||
* `module.stripTypeScriptTypes()` removes type annotations from TypeScript code. It
|
||||
* can be used to strip type annotations from TypeScript code before running it
|
||||
* with `vm.runInContext()` or `vm.compileFunction()`.
|
||||
* By default, it will throw an error if the code contains TypeScript features
|
||||
* that require transformation such as `Enums`,
|
||||
* see [type-stripping](https://nodejs.org/docs/latest-v24.x/api/typescript.md#type-stripping) for more information.
|
||||
* When mode is `'transform'`, it also transforms TypeScript features to JavaScript,
|
||||
* see [transform TypeScript features](https://nodejs.org/docs/latest-v24.x/api/typescript.md#typescript-features) for more information.
|
||||
* When mode is `'strip'`, source maps are not generated, because locations are preserved.
|
||||
* If `sourceMap` is provided, when mode is `'strip'`, an error will be thrown.
|
||||
*
|
||||
* _WARNING_: The output of this function should not be considered stable across Node.js versions,
|
||||
* due to changes in the TypeScript parser.
|
||||
*
|
||||
* ```js
|
||||
* import { stripTypeScriptTypes } from 'node:module';
|
||||
* const code = 'const a: number = 1;';
|
||||
* const strippedCode = stripTypeScriptTypes(code);
|
||||
* console.log(strippedCode);
|
||||
* // Prints: const a = 1;
|
||||
* ```
|
||||
*
|
||||
* If `sourceUrl` is provided, it will be used appended as a comment at the end of the output:
|
||||
*
|
||||
* ```js
|
||||
* import { stripTypeScriptTypes } from 'node:module';
|
||||
* const code = 'const a: number = 1;';
|
||||
* const strippedCode = stripTypeScriptTypes(code, { mode: 'strip', sourceUrl: 'source.ts' });
|
||||
* console.log(strippedCode);
|
||||
* // Prints: const a = 1\n\n//# sourceURL=source.ts;
|
||||
* ```
|
||||
*
|
||||
* When `mode` is `'transform'`, the code is transformed to JavaScript:
|
||||
*
|
||||
* ```js
|
||||
* import { stripTypeScriptTypes } from 'node:module';
|
||||
* const code = `
|
||||
* namespace MathUtil {
|
||||
* export const add = (a: number, b: number) => a + b;
|
||||
* }`;
|
||||
* const strippedCode = stripTypeScriptTypes(code, { mode: 'transform', sourceMap: true });
|
||||
* console.log(strippedCode);
|
||||
* // Prints:
|
||||
* // var MathUtil;
|
||||
* // (function(MathUtil) {
|
||||
* // MathUtil.add = (a, b)=>a + b;
|
||||
* // })(MathUtil || (MathUtil = {}));
|
||||
* // # sourceMappingURL=data:application/json;base64, ...
|
||||
* ```
|
||||
* @since v22.13.0
|
||||
* @param code The code to strip type annotations from.
|
||||
* @returns The code with type annotations stripped.
|
||||
*/
|
||||
function stripTypeScriptTypes(code: string, options?: StripTypeScriptTypesOptions): string;
|
||||
/* eslint-enable @definitelytyped/no-unnecessary-generics */
|
||||
/**
|
||||
* The `module.syncBuiltinESMExports()` method updates all the live bindings for
|
||||
* builtin `ES Modules` to match the properties of the `CommonJS` exports. It
|
||||
* does not add or remove exported names from the `ES Modules`.
|
||||
*
|
||||
* ```js
|
||||
* import fs from 'node:fs';
|
||||
* import assert from 'node:assert';
|
||||
* import { syncBuiltinESMExports } from 'node:module';
|
||||
*
|
||||
* fs.readFile = newAPI;
|
||||
*
|
||||
* delete fs.readFileSync;
|
||||
*
|
||||
* function newAPI() {
|
||||
* // ...
|
||||
* }
|
||||
*
|
||||
* fs.newAPI = newAPI;
|
||||
*
|
||||
* syncBuiltinESMExports();
|
||||
*
|
||||
* import('node:fs').then((esmFS) => {
|
||||
* // It syncs the existing readFile property with the new value
|
||||
* assert.strictEqual(esmFS.readFile, newAPI);
|
||||
* // readFileSync has been deleted from the required fs
|
||||
* assert.strictEqual('readFileSync' in fs, false);
|
||||
* // syncBuiltinESMExports() does not remove readFileSync from esmFS
|
||||
* assert.strictEqual('readFileSync' in esmFS, true);
|
||||
* // syncBuiltinESMExports() does not add names
|
||||
* assert.strictEqual(esmFS.newAPI, undefined);
|
||||
* });
|
||||
* ```
|
||||
* @since v12.12.0
|
||||
*/
|
||||
function syncBuiltinESMExports(): void;
|
||||
interface ImportAttributes extends NodeJS.Dict<string> {
|
||||
type?: string | undefined;
|
||||
}
|
||||
type ImportPhase = "source" | "evaluation";
|
||||
type ModuleFormat =
|
||||
| "addon"
|
||||
| "builtin"
|
||||
| "commonjs"
|
||||
| "commonjs-typescript"
|
||||
| "json"
|
||||
| "module"
|
||||
| "module-typescript"
|
||||
| "wasm";
|
||||
type ModuleSource = string | ArrayBuffer | NodeJS.TypedArray;
|
||||
/**
|
||||
* The `initialize` hook provides a way to define a custom function that runs in
|
||||
* the hooks thread when the hooks module is initialized. Initialization happens
|
||||
* when the hooks module is registered via {@link register}.
|
||||
*
|
||||
* This hook can receive data from a {@link register} invocation, including
|
||||
* ports and other transferable objects. The return value of `initialize` can be a
|
||||
* `Promise`, in which case it will be awaited before the main application thread
|
||||
* execution resumes.
|
||||
*/
|
||||
type InitializeHook<Data = any> = (data: Data) => void | Promise<void>;
|
||||
interface ResolveHookContext {
|
||||
/**
|
||||
* Export conditions of the relevant `package.json`
|
||||
*/
|
||||
conditions: string[];
|
||||
/**
|
||||
* An object whose key-value pairs represent the assertions for the module to import
|
||||
*/
|
||||
importAttributes: ImportAttributes;
|
||||
/**
|
||||
* The module importing this one, or undefined if this is the Node.js entry point
|
||||
*/
|
||||
parentURL: string | undefined;
|
||||
}
|
||||
interface ResolveFnOutput {
|
||||
/**
|
||||
* A hint to the load hook (it might be ignored); can be an intermediary value.
|
||||
*/
|
||||
format?: string | null | undefined;
|
||||
/**
|
||||
* The import attributes to use when caching the module (optional; if excluded the input will be used)
|
||||
*/
|
||||
importAttributes?: ImportAttributes | undefined;
|
||||
/**
|
||||
* A signal that this hook intends to terminate the chain of `resolve` hooks.
|
||||
* @default false
|
||||
*/
|
||||
shortCircuit?: boolean | undefined;
|
||||
/**
|
||||
* The absolute URL to which this input resolves
|
||||
*/
|
||||
url: string;
|
||||
}
|
||||
/**
|
||||
* The `resolve` hook chain is responsible for telling Node.js where to find and
|
||||
* how to cache a given `import` statement or expression, or `require` call. It can
|
||||
* optionally return a format (such as `'module'`) as a hint to the `load` hook. If
|
||||
* a format is specified, the `load` hook is ultimately responsible for providing
|
||||
* the final `format` value (and it is free to ignore the hint provided by
|
||||
* `resolve`); if `resolve` provides a `format`, a custom `load` hook is required
|
||||
* even if only to pass the value to the Node.js default `load` hook.
|
||||
*/
|
||||
type ResolveHook = (
|
||||
specifier: string,
|
||||
context: ResolveHookContext,
|
||||
nextResolve: (
|
||||
specifier: string,
|
||||
context?: Partial<ResolveHookContext>,
|
||||
) => ResolveFnOutput | Promise<ResolveFnOutput>,
|
||||
) => ResolveFnOutput | Promise<ResolveFnOutput>;
|
||||
type ResolveHookSync = (
|
||||
specifier: string,
|
||||
context: ResolveHookContext,
|
||||
nextResolve: (
|
||||
specifier: string,
|
||||
context?: Partial<ResolveHookContext>,
|
||||
) => ResolveFnOutput,
|
||||
) => ResolveFnOutput;
|
||||
interface LoadHookContext {
|
||||
/**
|
||||
* Export conditions of the relevant `package.json`
|
||||
*/
|
||||
conditions: string[];
|
||||
/**
|
||||
* The format optionally supplied by the `resolve` hook chain (can be an intermediary value).
|
||||
*/
|
||||
format: string | null | undefined;
|
||||
/**
|
||||
* An object whose key-value pairs represent the assertions for the module to import
|
||||
*/
|
||||
importAttributes: ImportAttributes;
|
||||
}
|
||||
interface LoadFnOutput {
|
||||
format: string | null | undefined;
|
||||
/**
|
||||
* A signal that this hook intends to terminate the chain of `resolve` hooks.
|
||||
* @default false
|
||||
*/
|
||||
shortCircuit?: boolean | undefined;
|
||||
/**
|
||||
* The source for Node.js to evaluate
|
||||
*/
|
||||
source?: ModuleSource | undefined;
|
||||
}
|
||||
/**
|
||||
* The `load` hook provides a way to define a custom method of determining how a
|
||||
* URL should be interpreted, retrieved, and parsed. It is also in charge of
|
||||
* validating the import attributes.
|
||||
*/
|
||||
type LoadHook = (
|
||||
url: string,
|
||||
context: LoadHookContext,
|
||||
nextLoad: (
|
||||
url: string,
|
||||
context?: Partial<LoadHookContext>,
|
||||
) => LoadFnOutput | Promise<LoadFnOutput>,
|
||||
) => LoadFnOutput | Promise<LoadFnOutput>;
|
||||
type LoadHookSync = (
|
||||
url: string,
|
||||
context: LoadHookContext,
|
||||
nextLoad: (
|
||||
url: string,
|
||||
context?: Partial<LoadHookContext>,
|
||||
) => LoadFnOutput,
|
||||
) => LoadFnOutput;
|
||||
interface SourceMapsSupport {
|
||||
/**
|
||||
* If the source maps support is enabled
|
||||
*/
|
||||
enabled: boolean;
|
||||
/**
|
||||
* If the support is enabled for files in `node_modules`.
|
||||
*/
|
||||
nodeModules: boolean;
|
||||
/**
|
||||
* If the support is enabled for generated code from `eval` or `new Function`.
|
||||
*/
|
||||
generatedCode: boolean;
|
||||
}
|
||||
/**
|
||||
* This method returns whether the [Source Map v3](https://tc39.es/ecma426/) support for stack
|
||||
* traces is enabled.
|
||||
* @since v23.7.0, v22.14.0
|
||||
*/
|
||||
function getSourceMapsSupport(): SourceMapsSupport;
|
||||
/**
|
||||
* `path` is the resolved path for the file for which a corresponding source map
|
||||
* should be fetched.
|
||||
* @since v13.7.0, v12.17.0
|
||||
* @return Returns `module.SourceMap` if a source map is found, `undefined` otherwise.
|
||||
*/
|
||||
function findSourceMap(path: string): SourceMap | undefined;
|
||||
interface SetSourceMapsSupportOptions {
|
||||
/**
|
||||
* If enabling the support for files in `node_modules`.
|
||||
* @default false
|
||||
*/
|
||||
nodeModules?: boolean | undefined;
|
||||
/**
|
||||
* If enabling the support for generated code from `eval` or `new Function`.
|
||||
* @default false
|
||||
*/
|
||||
generatedCode?: boolean | undefined;
|
||||
}
|
||||
/**
|
||||
* This function enables or disables the [Source Map v3](https://tc39.es/ecma426/) support for
|
||||
* stack traces.
|
||||
*
|
||||
* It provides same features as launching Node.js process with commandline options
|
||||
* `--enable-source-maps`, with additional options to alter the support for files
|
||||
* in `node_modules` or generated codes.
|
||||
*
|
||||
* Only source maps in JavaScript files that are loaded after source maps has been
|
||||
* enabled will be parsed and loaded. Preferably, use the commandline options
|
||||
* `--enable-source-maps` to avoid losing track of source maps of modules loaded
|
||||
* before this API call.
|
||||
* @since v23.7.0, v22.14.0
|
||||
*/
|
||||
function setSourceMapsSupport(enabled: boolean, options?: SetSourceMapsSupportOptions): void;
|
||||
interface SourceMapConstructorOptions {
|
||||
/**
|
||||
* @since v21.0.0, v20.5.0
|
||||
*/
|
||||
lineLengths?: readonly number[] | undefined;
|
||||
}
|
||||
interface SourceMapPayload {
|
||||
file: string;
|
||||
version: number;
|
||||
sources: string[];
|
||||
sourcesContent: string[];
|
||||
names: string[];
|
||||
mappings: string;
|
||||
sourceRoot: string;
|
||||
}
|
||||
interface SourceMapping {
|
||||
generatedLine: number;
|
||||
generatedColumn: number;
|
||||
originalSource: string;
|
||||
originalLine: number;
|
||||
originalColumn: number;
|
||||
}
|
||||
interface SourceOrigin {
|
||||
/**
|
||||
* The name of the range in the source map, if one was provided
|
||||
*/
|
||||
name: string | undefined;
|
||||
/**
|
||||
* The file name of the original source, as reported in the SourceMap
|
||||
*/
|
||||
fileName: string;
|
||||
/**
|
||||
* The 1-indexed lineNumber of the corresponding call site in the original source
|
||||
*/
|
||||
lineNumber: number;
|
||||
/**
|
||||
* The 1-indexed columnNumber of the corresponding call site in the original source
|
||||
*/
|
||||
columnNumber: number;
|
||||
}
|
||||
/**
|
||||
* @since v13.7.0, v12.17.0
|
||||
*/
|
||||
class SourceMap {
|
||||
constructor(payload: SourceMapPayload, options?: SourceMapConstructorOptions);
|
||||
/**
|
||||
* Getter for the payload used to construct the `SourceMap` instance.
|
||||
*/
|
||||
readonly payload: SourceMapPayload;
|
||||
/**
|
||||
* Given a line offset and column offset in the generated source
|
||||
* file, returns an object representing the SourceMap range in the
|
||||
* original file if found, or an empty object if not.
|
||||
*
|
||||
* The object returned contains the following keys:
|
||||
*
|
||||
* The returned value represents the raw range as it appears in the
|
||||
* SourceMap, based on zero-indexed offsets, _not_ 1-indexed line and
|
||||
* column numbers as they appear in Error messages and CallSite
|
||||
* objects.
|
||||
*
|
||||
* To get the corresponding 1-indexed line and column numbers from a
|
||||
* lineNumber and columnNumber as they are reported by Error stacks
|
||||
* and CallSite objects, use `sourceMap.findOrigin(lineNumber, columnNumber)`
|
||||
* @param lineOffset The zero-indexed line number offset in the generated source
|
||||
* @param columnOffset The zero-indexed column number offset in the generated source
|
||||
*/
|
||||
findEntry(lineOffset: number, columnOffset: number): SourceMapping | {};
|
||||
/**
|
||||
* Given a 1-indexed `lineNumber` and `columnNumber` from a call site in the generated source,
|
||||
* find the corresponding call site location in the original source.
|
||||
*
|
||||
* If the `lineNumber` and `columnNumber` provided are not found in any source map,
|
||||
* then an empty object is returned.
|
||||
* @param lineNumber The 1-indexed line number of the call site in the generated source
|
||||
* @param columnNumber The 1-indexed column number of the call site in the generated source
|
||||
*/
|
||||
findOrigin(lineNumber: number, columnNumber: number): SourceOrigin | {};
|
||||
}
|
||||
function runMain(main?: string): void;
|
||||
function wrap(script: string): string;
|
||||
}
|
||||
global {
|
||||
interface ImportMeta {
|
||||
/**
|
||||
* The directory name of the current module.
|
||||
*
|
||||
* This is the same as the `path.dirname()` of the `import.meta.filename`.
|
||||
*
|
||||
* > **Caveat**: only present on `file:` modules.
|
||||
* @since v21.2.0, v20.11.0
|
||||
*/
|
||||
dirname: string;
|
||||
/**
|
||||
* The full absolute path and filename of the current module, with
|
||||
* symlinks resolved.
|
||||
*
|
||||
* This is the same as the `url.fileURLToPath()` of the `import.meta.url`.
|
||||
*
|
||||
* > **Caveat** only local modules support this property. Modules not using the
|
||||
* > `file:` protocol will not provide it.
|
||||
* @since v21.2.0, v20.11.0
|
||||
*/
|
||||
filename: string;
|
||||
/**
|
||||
* The absolute `file:` URL of the module.
|
||||
*
|
||||
* This is defined exactly the same as it is in browsers providing the URL of the
|
||||
* current module file.
|
||||
*
|
||||
* This enables useful patterns such as relative file loading:
|
||||
*
|
||||
* ```js
|
||||
* import { readFileSync } from 'node:fs';
|
||||
* const buffer = readFileSync(new URL('./data.proto', import.meta.url));
|
||||
* ```
|
||||
*/
|
||||
url: string;
|
||||
/**
|
||||
* `import.meta.resolve` is a module-relative resolution function scoped to
|
||||
* each module, returning the URL string.
|
||||
*
|
||||
* ```js
|
||||
* const dependencyAsset = import.meta.resolve('component-lib/asset.css');
|
||||
* // file:///app/node_modules/component-lib/asset.css
|
||||
* import.meta.resolve('./dep.js');
|
||||
* // file:///app/dep.js
|
||||
* ```
|
||||
*
|
||||
* All features of the Node.js module resolution are supported. Dependency
|
||||
* resolutions are subject to the permitted exports resolutions within the package.
|
||||
*
|
||||
* **Caveats**:
|
||||
*
|
||||
* * This can result in synchronous file-system operations, which
|
||||
* can impact performance similarly to `require.resolve`.
|
||||
* * This feature is not available within custom loaders (it would
|
||||
* create a deadlock).
|
||||
* @since v13.9.0, v12.16.0
|
||||
* @param specifier The module specifier to resolve relative to the
|
||||
* current module.
|
||||
* @param parent An optional absolute parent module URL to resolve from.
|
||||
* **Default:** `import.meta.url`
|
||||
* @returns The absolute URL string that the specifier would resolve to.
|
||||
*/
|
||||
resolve(specifier: string, parent?: string | URL): string;
|
||||
/**
|
||||
* `true` when the current module is the entry point of the current process; `false` otherwise.
|
||||
*
|
||||
* Equivalent to `require.main === module` in CommonJS.
|
||||
*
|
||||
* Analogous to Python's `__name__ == "__main__"`.
|
||||
*
|
||||
* ```js
|
||||
* export function foo() {
|
||||
* return 'Hello, world';
|
||||
* }
|
||||
*
|
||||
* function main() {
|
||||
* const message = foo();
|
||||
* console.log(message);
|
||||
* }
|
||||
*
|
||||
* if (import.meta.main) main();
|
||||
* // `foo` can be imported from another module without possible side-effects from `main`
|
||||
* ```
|
||||
* @since v24.2.0
|
||||
* @experimental
|
||||
*/
|
||||
main: boolean;
|
||||
}
|
||||
namespace NodeJS {
|
||||
interface Module {
|
||||
/**
|
||||
* The module objects required for the first time by this one.
|
||||
* @since v0.1.16
|
||||
*/
|
||||
children: Module[];
|
||||
/**
|
||||
* The `module.exports` object is created by the `Module` system. Sometimes this is
|
||||
* not acceptable; many want their module to be an instance of some class. To do
|
||||
* this, assign the desired export object to `module.exports`.
|
||||
* @since v0.1.16
|
||||
*/
|
||||
exports: any;
|
||||
/**
|
||||
* The fully resolved filename of the module.
|
||||
* @since v0.1.16
|
||||
*/
|
||||
filename: string;
|
||||
/**
|
||||
* The identifier for the module. Typically this is the fully resolved
|
||||
* filename.
|
||||
* @since v0.1.16
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* `true` if the module is running during the Node.js preload
|
||||
* phase.
|
||||
* @since v15.4.0, v14.17.0
|
||||
*/
|
||||
isPreloading: boolean;
|
||||
/**
|
||||
* Whether or not the module is done loading, or is in the process of
|
||||
* loading.
|
||||
* @since v0.1.16
|
||||
*/
|
||||
loaded: boolean;
|
||||
/**
|
||||
* The module that first required this one, or `null` if the current module is the
|
||||
* entry point of the current process, or `undefined` if the module was loaded by
|
||||
* something that is not a CommonJS module (e.g. REPL or `import`).
|
||||
* @since v0.1.16
|
||||
* @deprecated Please use `require.main` and `module.children` instead.
|
||||
*/
|
||||
parent: Module | null | undefined;
|
||||
/**
|
||||
* The directory name of the module. This is usually the same as the
|
||||
* `path.dirname()` of the `module.id`.
|
||||
* @since v11.14.0
|
||||
*/
|
||||
path: string;
|
||||
/**
|
||||
* The search paths for the module.
|
||||
* @since v0.4.0
|
||||
*/
|
||||
paths: string[];
|
||||
/**
|
||||
* The `module.require()` method provides a way to load a module as if
|
||||
* `require()` was called from the original module.
|
||||
* @since v0.5.1
|
||||
*/
|
||||
require(id: string): any;
|
||||
}
|
||||
interface Require {
|
||||
/**
|
||||
* Used to import modules, `JSON`, and local files.
|
||||
* @since v0.1.13
|
||||
*/
|
||||
(id: string): any;
|
||||
/**
|
||||
* Modules are cached in this object when they are required. By deleting a key
|
||||
* value from this object, the next `require` will reload the module.
|
||||
* This does not apply to
|
||||
* [native addons](https://nodejs.org/docs/latest-v24.x/api/addons.html),
|
||||
* for which reloading will result in an error.
|
||||
* @since v0.3.0
|
||||
*/
|
||||
cache: Dict<Module>;
|
||||
/**
|
||||
* Instruct `require` on how to handle certain file extensions.
|
||||
* @since v0.3.0
|
||||
* @deprecated
|
||||
*/
|
||||
extensions: RequireExtensions;
|
||||
/**
|
||||
* The `Module` object representing the entry script loaded when the Node.js
|
||||
* process launched, or `undefined` if the entry point of the program is not a
|
||||
* CommonJS module.
|
||||
* @since v0.1.17
|
||||
*/
|
||||
main: Module | undefined;
|
||||
/**
|
||||
* @since v0.3.0
|
||||
*/
|
||||
resolve: RequireResolve;
|
||||
}
|
||||
/** @deprecated */
|
||||
interface RequireExtensions extends Dict<(module: Module, filename: string) => any> {
|
||||
".js": (module: Module, filename: string) => any;
|
||||
".json": (module: Module, filename: string) => any;
|
||||
".node": (module: Module, filename: string) => any;
|
||||
}
|
||||
interface RequireResolveOptions {
|
||||
/**
|
||||
* Paths to resolve module location from. If present, these
|
||||
* paths are used instead of the default resolution paths, with the exception
|
||||
* of
|
||||
* [GLOBAL\_FOLDERS](https://nodejs.org/docs/latest-v24.x/api/modules.html#loading-from-the-global-folders)
|
||||
* like `$HOME/.node_modules`, which are
|
||||
* always included. Each of these paths is used as a starting point for
|
||||
* the module resolution algorithm, meaning that the `node_modules` hierarchy
|
||||
* is checked from this location.
|
||||
* @since v8.9.0
|
||||
*/
|
||||
paths?: string[] | undefined;
|
||||
}
|
||||
interface RequireResolve {
|
||||
/**
|
||||
* Use the internal `require()` machinery to look up the location of a module,
|
||||
* but rather than loading the module, just return the resolved filename.
|
||||
*
|
||||
* If the module can not be found, a `MODULE_NOT_FOUND` error is thrown.
|
||||
* @since v0.3.0
|
||||
* @param request The module path to resolve.
|
||||
*/
|
||||
(request: string, options?: RequireResolveOptions): string;
|
||||
/**
|
||||
* Returns an array containing the paths searched during resolution of `request` or
|
||||
* `null` if the `request` string references a core module, for example `http` or
|
||||
* `fs`.
|
||||
* @since v8.9.0
|
||||
* @param request The module path whose lookup paths are being retrieved.
|
||||
*/
|
||||
paths(request: string): string[] | null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* The directory name of the current module. This is the same as the
|
||||
* `path.dirname()` of the `__filename`.
|
||||
* @since v0.1.27
|
||||
*/
|
||||
var __dirname: string;
|
||||
/**
|
||||
* The file name of the current module. This is the current module file's absolute
|
||||
* path with symlinks resolved.
|
||||
*
|
||||
* For a main program this is not necessarily the same as the file name used in the
|
||||
* command line.
|
||||
* @since v0.0.1
|
||||
*/
|
||||
var __filename: string;
|
||||
/**
|
||||
* The `exports` variable is available within a module's file-level scope, and is
|
||||
* assigned the value of `module.exports` before the module is evaluated.
|
||||
* @since v0.1.16
|
||||
*/
|
||||
var exports: NodeJS.Module["exports"];
|
||||
/**
|
||||
* A reference to the current module.
|
||||
* @since v0.1.16
|
||||
*/
|
||||
var module: NodeJS.Module;
|
||||
/**
|
||||
* @since v0.1.13
|
||||
*/
|
||||
var require: NodeJS.Require;
|
||||
// Global-scope aliases for backwards compatibility with @types/node <13.0.x
|
||||
// TODO: consider removing in a future major version update
|
||||
/** @deprecated Use `NodeJS.Module` instead. */
|
||||
interface NodeModule extends NodeJS.Module {}
|
||||
/** @deprecated Use `NodeJS.Require` instead. */
|
||||
interface NodeRequire extends NodeJS.Require {}
|
||||
/** @deprecated Use `NodeJS.RequireResolve` instead. */
|
||||
interface RequireResolve extends NodeJS.RequireResolve {}
|
||||
}
|
||||
export = Module;
|
||||
}
|
||||
declare module "node:module" {
|
||||
import module = require("module");
|
||||
export = module;
|
||||
}
|
||||