feat: implement Zen 4.0 Focus-First layout with SOAP notes and hotkeys
Build Curio HMS / build-and-deploy (push) Successful in 48s
Details
Build Curio HMS / build-and-deploy (push) Successful in 48s
Details
This commit is contained in:
parent
6e2f9b4f94
commit
6058f9a862
144
dashboard.css
144
dashboard.css
|
|
@ -1312,6 +1312,150 @@
|
||||||
min-width: 180px !important;
|
min-width: 180px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* --- WORLD-CLASS ZEN 4.0 ADD-ONS --- */
|
||||||
|
.safety-header {
|
||||||
|
background: white;
|
||||||
|
padding: 1.5rem 2.5rem;
|
||||||
|
border-radius: 20px;
|
||||||
|
box-shadow: 0 4px 20px rgba(0,0,0,0.03);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
position: sticky;
|
||||||
|
top: 1rem;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.patient-identity-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.patient-identity-row h1 {
|
||||||
|
font-size: 2rem;
|
||||||
|
font-family: 'Outfit', sans-serif;
|
||||||
|
color: var(--primary);
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.patient-identity-row .allergy-tag {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zen-layout-3col {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 15% 55% 30%;
|
||||||
|
gap: 2rem;
|
||||||
|
align-items: start;
|
||||||
|
transition: grid-template-columns 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zen-layout-3col.collapsed-queue {
|
||||||
|
grid-template-columns: 5% 65% 30%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zen-pipeline {
|
||||||
|
background: white;
|
||||||
|
border-radius: 20px;
|
||||||
|
padding: 1.5rem;
|
||||||
|
box-shadow: 0 4px 20px rgba(0,0,0,0.03);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zen-pipeline.collapsed {
|
||||||
|
padding: 1.5rem 0.5rem;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zen-pipeline.collapsed .pipeline-header h3,
|
||||||
|
.zen-pipeline.collapsed .pipeline-header .badge,
|
||||||
|
.zen-pipeline.collapsed .p-info {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zen-pipeline.collapsed .p-token {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
padding: 0.25rem;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zen-workspace-soap {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.soap-container {
|
||||||
|
background: white;
|
||||||
|
border-radius: 30px;
|
||||||
|
padding: 2.5rem;
|
||||||
|
box-shadow: 0 10px 40px rgba(0,0,0,0.02);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.soap-field {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.soap-field label {
|
||||||
|
font-family: 'Outfit', sans-serif;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--primary);
|
||||||
|
font-size: 1.1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zen-textarea-small {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 100px;
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 1rem;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
line-height: 1.6;
|
||||||
|
color: var(--text-main);
|
||||||
|
font-family: 'Inter', sans-serif;
|
||||||
|
resize: vertical;
|
||||||
|
background: #F8FAFC;
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zen-textarea-small:focus {
|
||||||
|
outline: none;
|
||||||
|
background: white;
|
||||||
|
border-color: var(--secondary);
|
||||||
|
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-sync {
|
||||||
|
background: #EEF2FF;
|
||||||
|
color: #4F46E5;
|
||||||
|
border: 1px solid #C7D2FE;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-sync:hover {
|
||||||
|
background: #E0E7FF;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.rx-panels {
|
.rx-panels {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
|
|
|
||||||
157
dashboard.html
157
dashboard.html
|
|
@ -113,11 +113,30 @@
|
||||||
|
|
||||||
<!-- DOCTOR ZEN VIEW (Clinical Focus) -->
|
<!-- DOCTOR ZEN VIEW (Clinical Focus) -->
|
||||||
<div id="doctor-zen-section" class="hidden">
|
<div id="doctor-zen-section" class="hidden">
|
||||||
<div class="zen-layout">
|
<!-- Persistent Safety Header -->
|
||||||
<!-- Left: The Pipeline -->
|
<div class="safety-header">
|
||||||
<aside class="zen-pipeline">
|
<div class="patient-identity-row">
|
||||||
|
<span class="pill active">Now Seeing</span>
|
||||||
|
<h1>Rahul Verma <small>(28y, M)</small></h1>
|
||||||
|
<span class="pill triage">#012 • Viral Fever Triage</span>
|
||||||
|
<span class="allergy-tag urgent-alert">‼️ PEANUTS ALLERGY</span>
|
||||||
|
</div>
|
||||||
|
<div class="action-center">
|
||||||
|
<select id="scribeLang" class="lang-select">
|
||||||
|
<option value="en-US">English</option>
|
||||||
|
<option value="te-IN">తెలుగు</option>
|
||||||
|
</select>
|
||||||
|
<button id="zenScribeBtn" class="btn-zen scribe" onclick="toggleZenScribe()">🎙️ Scribe</button>
|
||||||
|
<button class="btn-zen history" onclick="openHistory()">📂 History</button>
|
||||||
|
<button class="btn-zen start" onclick="openConsultation()">✍️ Start</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="zen-layout-3col">
|
||||||
|
<!-- Left: Collapsible Queue (15%) -->
|
||||||
|
<aside class="zen-pipeline" id="zenPipeline">
|
||||||
<div class="pipeline-header">
|
<div class="pipeline-header">
|
||||||
<h3>Up Next</h3>
|
<h3>Queue <small>(Ctrl+Q)</small></h3>
|
||||||
<span class="badge">4 Waiting</span>
|
<span class="badge">4 Waiting</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="pipeline-list">
|
<div class="pipeline-list">
|
||||||
|
|
@ -138,81 +157,73 @@
|
||||||
</div>
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
<!-- Center: The Workspace -->
|
<!-- Center: Structured SOAP Workspace (55%) -->
|
||||||
<main class="zen-workspace">
|
<main class="zen-workspace-soap">
|
||||||
<div class="patient-info-slab">
|
<div id="scribeStatus" class="scribe-status-bar hidden">
|
||||||
<div class="patient-identity">
|
<span class="pulse-dot"></span> <span id="scribeStatusText">AI Scribe Recording... (Ctrl+Shift+S to Pause)</span>
|
||||||
<div class="meta-pills">
|
</div>
|
||||||
<span class="pill active">Now Seeing</span>
|
|
||||||
<span class="pill time">08:45 AM</span>
|
|
||||||
</div>
|
|
||||||
<h1>Rahul Verma <small>(28y, Male)</small></h1>
|
|
||||||
<div class="meta-pills">
|
|
||||||
<span class="pill triage">#012</span>
|
|
||||||
<span class="pill time">Viral Fever Triage</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="action-center">
|
<div class="soap-container">
|
||||||
<select id="scribeLang" class="lang-select">
|
<div class="soap-field">
|
||||||
<option value="en-US">English</option>
|
<label for="soap-s">Subjective</label>
|
||||||
<option value="te-IN">తెలుగు</option>
|
<textarea id="soap-s" class="zen-textarea-small" placeholder="Patient reports..."></textarea>
|
||||||
</select>
|
</div>
|
||||||
<button id="zenScribeBtn" class="btn-zen scribe" onclick="toggleZenScribe()">🎙️ Scribe</button>
|
<div class="soap-field">
|
||||||
<button class="btn-zen history" onclick="openHistory()">📂 History</button>
|
<div class="field-header">
|
||||||
<button class="btn-zen start" onclick="openConsultation()">✍️ Start</button>
|
<label for="soap-o">Objective</label>
|
||||||
|
<button class="btn-small btn-sync" onclick="syncVitals()">⬇️ Sync Vitals</button>
|
||||||
|
</div>
|
||||||
|
<textarea id="soap-o" class="zen-textarea-small" placeholder="Observations, vitals, exam findings..."></textarea>
|
||||||
|
</div>
|
||||||
|
<div class="soap-field">
|
||||||
|
<label for="soap-a">Assessment</label>
|
||||||
|
<textarea id="soap-a" class="zen-textarea-small" placeholder="Diagnosis, reasoning..."></textarea>
|
||||||
|
</div>
|
||||||
|
<div class="soap-field">
|
||||||
|
<label for="soap-p">Plan</label>
|
||||||
|
<textarea id="soap-p" class="zen-textarea-small" placeholder="Treatment, Rx, follow-up..."></textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="scribeStatus" class="scribe-status-bar hidden">
|
<div id="aiSummaryCard" class="summary-card hidden">
|
||||||
<span class="pulse-dot"></span> AI Clinical Intelligence is Active...
|
<div class="card-header">✨ AI Clinical Summary</div>
|
||||||
</div>
|
<div id="summaryText" class="summary-content"></div>
|
||||||
|
<div class="summary-actions">
|
||||||
<div class="zen-grid">
|
<button class="btn-small secondary" onclick="shareSummary()">📤 Send</button>
|
||||||
<div class="note-canvas-container">
|
<button class="btn-small secondary" onclick="printSummary()">🖨️ Print</button>
|
||||||
<textarea id="consultationNotes" placeholder="Begin clinical documentation or use AI Scribe..." class="zen-textarea"></textarea>
|
|
||||||
|
|
||||||
<div id="aiSummaryCard" class="summary-card hidden">
|
|
||||||
<div class="card-header">✨ AI Clinical Summary</div>
|
|
||||||
<div id="summaryText" class="summary-content"></div>
|
|
||||||
<div class="summary-actions">
|
|
||||||
<button class="btn-small secondary" onclick="shareSummary()">📤 Send</button>
|
|
||||||
<button class="btn-small secondary" onclick="printSummary()">🖨️ Print</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="zen-sidebar">
|
|
||||||
<div class="insight-card">
|
|
||||||
<div class="card-header">🩺 Patient Vitals</div>
|
|
||||||
<div class="vitals-grid">
|
|
||||||
<div class="vital-item">
|
|
||||||
<span class="label">Temp</span>
|
|
||||||
<span class="value">98.6°F</span>
|
|
||||||
</div>
|
|
||||||
<div class="vital-item warning">
|
|
||||||
<span class="label">BP</span>
|
|
||||||
<span class="value">140/90</span>
|
|
||||||
</div>
|
|
||||||
<div class="vital-item">
|
|
||||||
<span class="label">SpO2</span>
|
|
||||||
<span class="value">98%</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="allergy-tag">⚠️ Peanuts Allergy</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="ai-nudge-box">
|
|
||||||
<div class="card-header">✨ AI Assistant</div>
|
|
||||||
<p id="aiNudgeText">Listening for diagnosis...</p>
|
|
||||||
<div class="suggested-tags">
|
|
||||||
<span>#ViralFever</span>
|
|
||||||
<span>#FluProtocols</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
<!-- Right: AI Assistant & Vitals (30%) -->
|
||||||
|
<aside class="zen-sidebar-right">
|
||||||
|
<div class="insight-card">
|
||||||
|
<div class="card-header">🩺 Vitals Widget</div>
|
||||||
|
<div class="vitals-grid">
|
||||||
|
<div class="vital-item">
|
||||||
|
<span class="label">Temp</span>
|
||||||
|
<span class="value" id="vital-temp">98.6°F</span>
|
||||||
|
</div>
|
||||||
|
<div class="vital-item warning">
|
||||||
|
<span class="label">BP</span>
|
||||||
|
<span class="value" id="vital-bp">140/90</span>
|
||||||
|
</div>
|
||||||
|
<div class="vital-item">
|
||||||
|
<span class="label">SpO2</span>
|
||||||
|
<span class="value" id="vital-spo2">98%</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ai-nudge-box">
|
||||||
|
<div class="card-header">✨ AI Suggestions</div>
|
||||||
|
<p id="aiNudgeText">Listening for diagnosis...</p>
|
||||||
|
<div class="suggested-tags">
|
||||||
|
<span>#ViralFever</span>
|
||||||
|
<span>#FluProtocols</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -526,6 +537,6 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
<script src="dashboard.js?v=20"></script>
|
<script src="dashboard.js?v=21"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
92
dashboard.js
92
dashboard.js
|
|
@ -164,23 +164,65 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||||
|
|
||||||
showSection(config.defaultSection === 'zen' ? 'zen' : config.defaultSection);
|
showSection(config.defaultSection === 'zen' ? 'zen' : config.defaultSection);
|
||||||
|
|
||||||
// AI Nudge Simulation Logic
|
// Zen 4.0 Macros & Nudge Logic
|
||||||
const notesArea = document.getElementById("consultationNotes");
|
const MACROS = {
|
||||||
|
".fever": "Patient presents with elevated body temperature. Antipyretics advised. Rest and hydration recommended.",
|
||||||
|
".cough": "Patient reports persistent cough. Chest sounds clear bilaterally. Recommended symptomatic relief.",
|
||||||
|
".cold": "Patient reports nasal congestion and rhinorrhea. Viral etiology suspected. Supportive care advised."
|
||||||
|
};
|
||||||
|
|
||||||
const nudgeText = document.getElementById("aiNudgeText");
|
const nudgeText = document.getElementById("aiNudgeText");
|
||||||
const tagsContainer = document.querySelector(".suggested-tags");
|
const tagsContainer = document.querySelector(".suggested-tags");
|
||||||
|
|
||||||
if (notesArea) {
|
document.addEventListener("input", (e) => {
|
||||||
notesArea.addEventListener("input", (e) => {
|
if (e.target && e.target.tagName === 'TEXTAREA' && e.target.id.startsWith('soap-')) {
|
||||||
const val = e.target.value.toLowerCase();
|
let val = e.target.value;
|
||||||
if (val.includes("fever") || val.includes("temperature")) {
|
let modified = false;
|
||||||
nudgeText.innerText = "✨ AI suggests: Patient has elevated temp. Consider prescribing Paracetamol and checking for throat infection.";
|
for (const [macro, text] of Object.entries(MACROS)) {
|
||||||
tagsContainer.innerHTML = '<span>#ViralFever</span><span>#InfectionCheck</span>';
|
if (val.includes(macro)) {
|
||||||
} else if (val.includes("cough") || val.includes("breath")) {
|
val = val.replace(macro, text);
|
||||||
nudgeText.innerText = "✨ AI suggests: Respiratory symptoms detected. Check SpO2 and listen for chest congestion.";
|
modified = true;
|
||||||
tagsContainer.innerHTML = '<span>#AsthmaProtocol</span><span>#Bronchitis</span>';
|
}
|
||||||
}
|
}
|
||||||
});
|
if (modified) {
|
||||||
}
|
e.target.value = val;
|
||||||
|
// Dispatch event so other listeners (if any) know the value changed
|
||||||
|
e.target.dispatchEvent(new Event('input', { bubbles: true }));
|
||||||
|
return; // Prevent recursive trigger on this pass
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nudge Logic update
|
||||||
|
if (nudgeText && tagsContainer) {
|
||||||
|
const lowerVal = val.toLowerCase();
|
||||||
|
if (lowerVal.includes("fever") || lowerVal.includes("temperature")) {
|
||||||
|
nudgeText.innerText = "✨ AI suggests: Patient has elevated temp. Consider prescribing Paracetamol and checking for throat infection.";
|
||||||
|
tagsContainer.innerHTML = '<span>#ViralFever</span><span>#InfectionCheck</span>';
|
||||||
|
} else if (lowerVal.includes("cough") || lowerVal.includes("breath")) {
|
||||||
|
nudgeText.innerText = "✨ AI suggests: Respiratory symptoms detected. Check SpO2 and listen for chest congestion.";
|
||||||
|
tagsContainer.innerHTML = '<span>#AsthmaProtocol</span><span>#Bronchitis</span>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Zen 4.0 Global Hotkeys
|
||||||
|
document.addEventListener("keydown", (e) => {
|
||||||
|
// Ctrl + Q to toggle queue sidebar
|
||||||
|
if (e.ctrlKey && e.key.toLowerCase() === 'q') {
|
||||||
|
e.preventDefault();
|
||||||
|
const layout = document.querySelector('.zen-layout-3col');
|
||||||
|
const pipeline = document.getElementById('zenPipeline');
|
||||||
|
if (layout && pipeline) {
|
||||||
|
layout.classList.toggle('collapsed-queue');
|
||||||
|
pipeline.classList.toggle('collapsed');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Ctrl + Shift + S to toggle Scribe
|
||||||
|
if (e.ctrlKey && e.shiftKey && e.key.toLowerCase() === 's') {
|
||||||
|
e.preventDefault();
|
||||||
|
window.toggleZenScribe();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Initialize Recognition
|
// Initialize Recognition
|
||||||
if ('webkitSpeechRecognition' in window) {
|
if ('webkitSpeechRecognition' in window) {
|
||||||
|
|
@ -193,7 +235,14 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||||
for (let i = event.resultIndex; i < event.results.length; ++i) {
|
for (let i = event.resultIndex; i < event.results.length; ++i) {
|
||||||
if (event.results[i].isFinal) {
|
if (event.results[i].isFinal) {
|
||||||
const transcript = event.results[i][0].transcript;
|
const transcript = event.results[i][0].transcript;
|
||||||
document.getElementById("consultationNotes").value += transcript + '. ';
|
// Default streaming to Subjective section or active field
|
||||||
|
const activeField = document.activeElement;
|
||||||
|
if (activeField && activeField.tagName === 'TEXTAREA' && activeField.id.startsWith('soap-')) {
|
||||||
|
activeField.value += transcript + '. ';
|
||||||
|
} else {
|
||||||
|
const defaultField = document.getElementById("soap-s");
|
||||||
|
if (defaultField) defaultField.value += transcript + '. ';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -623,3 +672,18 @@ function renderAlerts(alerts) {
|
||||||
|
|
||||||
aiAlertsContainer.innerHTML = html;
|
aiAlertsContainer.innerHTML = html;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ==========================================
|
||||||
|
// Zen 4.0 Vitals Sync
|
||||||
|
// ==========================================
|
||||||
|
window.syncVitals = () => {
|
||||||
|
const temp = document.getElementById("vital-temp")?.innerText || "";
|
||||||
|
const bp = document.getElementById("vital-bp")?.innerText || "";
|
||||||
|
const spo2 = document.getElementById("vital-spo2")?.innerText || "";
|
||||||
|
const objectiveField = document.getElementById("soap-o");
|
||||||
|
if (objectiveField) {
|
||||||
|
objectiveField.value += `\n[Vitals Sync] Temp: ${temp}, BP: ${bp}, SpO2: ${spo2}\n`;
|
||||||
|
// Trigger input event to resize textarea or run macros if needed
|
||||||
|
objectiveField.dispatchEvent(new Event('input', { bubbles: true }));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
#!/bin/sh
|
||||||
|
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||||
|
|
||||||
|
case `uname` in
|
||||||
|
*CYGWIN*|*MINGW*|*MSYS*)
|
||||||
|
if command -v cygpath > /dev/null 2>&1; then
|
||||||
|
basedir=`cygpath -w "$basedir"`
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ -x "$basedir/node" ]; then
|
||||||
|
exec "$basedir/node" "$basedir/../mime/cli.js" "$@"
|
||||||
|
else
|
||||||
|
exec node "$basedir/../mime/cli.js" "$@"
|
||||||
|
fi
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
@ECHO off
|
||||||
|
GOTO start
|
||||||
|
:find_dp0
|
||||||
|
SET dp0=%~dp0
|
||||||
|
EXIT /b
|
||||||
|
:start
|
||||||
|
SETLOCAL
|
||||||
|
CALL :find_dp0
|
||||||
|
|
||||||
|
IF EXIST "%dp0%\node.exe" (
|
||||||
|
SET "_prog=%dp0%\node.exe"
|
||||||
|
) ELSE (
|
||||||
|
SET "_prog=node"
|
||||||
|
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||||
|
)
|
||||||
|
|
||||||
|
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\mime\cli.js" %*
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
#!/usr/bin/env pwsh
|
||||||
|
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||||
|
|
||||||
|
$exe=""
|
||||||
|
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||||
|
# Fix case when both the Windows and Linux builds of Node
|
||||||
|
# are installed in the same directory
|
||||||
|
$exe=".exe"
|
||||||
|
}
|
||||||
|
$ret=0
|
||||||
|
if (Test-Path "$basedir/node$exe") {
|
||||||
|
# Support pipeline input
|
||||||
|
if ($MyInvocation.ExpectingInput) {
|
||||||
|
$input | & "$basedir/node$exe" "$basedir/../mime/cli.js" $args
|
||||||
|
} else {
|
||||||
|
& "$basedir/node$exe" "$basedir/../mime/cli.js" $args
|
||||||
|
}
|
||||||
|
$ret=$LASTEXITCODE
|
||||||
|
} else {
|
||||||
|
# Support pipeline input
|
||||||
|
if ($MyInvocation.ExpectingInput) {
|
||||||
|
$input | & "node$exe" "$basedir/../mime/cli.js" $args
|
||||||
|
} else {
|
||||||
|
& "node$exe" "$basedir/../mime/cli.js" $args
|
||||||
|
}
|
||||||
|
$ret=$LASTEXITCODE
|
||||||
|
}
|
||||||
|
exit $ret
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
#!/bin/sh
|
||||||
|
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||||
|
|
||||||
|
case `uname` in
|
||||||
|
*CYGWIN*|*MINGW*|*MSYS*)
|
||||||
|
if command -v cygpath > /dev/null 2>&1; then
|
||||||
|
basedir=`cygpath -w "$basedir"`
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ -x "$basedir/node" ]; then
|
||||||
|
exec "$basedir/node" "$basedir/../@grpc/proto-loader/build/bin/proto-loader-gen-types.js" "$@"
|
||||||
|
else
|
||||||
|
exec node "$basedir/../@grpc/proto-loader/build/bin/proto-loader-gen-types.js" "$@"
|
||||||
|
fi
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
@ECHO off
|
||||||
|
GOTO start
|
||||||
|
:find_dp0
|
||||||
|
SET dp0=%~dp0
|
||||||
|
EXIT /b
|
||||||
|
:start
|
||||||
|
SETLOCAL
|
||||||
|
CALL :find_dp0
|
||||||
|
|
||||||
|
IF EXIST "%dp0%\node.exe" (
|
||||||
|
SET "_prog=%dp0%\node.exe"
|
||||||
|
) ELSE (
|
||||||
|
SET "_prog=node"
|
||||||
|
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||||
|
)
|
||||||
|
|
||||||
|
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\@grpc\proto-loader\build\bin\proto-loader-gen-types.js" %*
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
#!/usr/bin/env pwsh
|
||||||
|
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||||
|
|
||||||
|
$exe=""
|
||||||
|
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||||
|
# Fix case when both the Windows and Linux builds of Node
|
||||||
|
# are installed in the same directory
|
||||||
|
$exe=".exe"
|
||||||
|
}
|
||||||
|
$ret=0
|
||||||
|
if (Test-Path "$basedir/node$exe") {
|
||||||
|
# Support pipeline input
|
||||||
|
if ($MyInvocation.ExpectingInput) {
|
||||||
|
$input | & "$basedir/node$exe" "$basedir/../@grpc/proto-loader/build/bin/proto-loader-gen-types.js" $args
|
||||||
|
} else {
|
||||||
|
& "$basedir/node$exe" "$basedir/../@grpc/proto-loader/build/bin/proto-loader-gen-types.js" $args
|
||||||
|
}
|
||||||
|
$ret=$LASTEXITCODE
|
||||||
|
} else {
|
||||||
|
# Support pipeline input
|
||||||
|
if ($MyInvocation.ExpectingInput) {
|
||||||
|
$input | & "node$exe" "$basedir/../@grpc/proto-loader/build/bin/proto-loader-gen-types.js" $args
|
||||||
|
} else {
|
||||||
|
& "node$exe" "$basedir/../@grpc/proto-loader/build/bin/proto-loader-gen-types.js" $args
|
||||||
|
}
|
||||||
|
$ret=$LASTEXITCODE
|
||||||
|
}
|
||||||
|
exit $ret
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
#!/bin/sh
|
||||||
|
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||||
|
|
||||||
|
case `uname` in
|
||||||
|
*CYGWIN*|*MINGW*|*MSYS*)
|
||||||
|
if command -v cygpath > /dev/null 2>&1; then
|
||||||
|
basedir=`cygpath -w "$basedir"`
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ -x "$basedir/node" ]; then
|
||||||
|
exec "$basedir/node" "$basedir/../uuid/dist-node/bin/uuid" "$@"
|
||||||
|
else
|
||||||
|
exec node "$basedir/../uuid/dist-node/bin/uuid" "$@"
|
||||||
|
fi
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
@ECHO off
|
||||||
|
GOTO start
|
||||||
|
:find_dp0
|
||||||
|
SET dp0=%~dp0
|
||||||
|
EXIT /b
|
||||||
|
:start
|
||||||
|
SETLOCAL
|
||||||
|
CALL :find_dp0
|
||||||
|
|
||||||
|
IF EXIST "%dp0%\node.exe" (
|
||||||
|
SET "_prog=%dp0%\node.exe"
|
||||||
|
) ELSE (
|
||||||
|
SET "_prog=node"
|
||||||
|
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||||
|
)
|
||||||
|
|
||||||
|
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\uuid\dist-node\bin\uuid" %*
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
#!/usr/bin/env pwsh
|
||||||
|
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||||
|
|
||||||
|
$exe=""
|
||||||
|
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||||
|
# Fix case when both the Windows and Linux builds of Node
|
||||||
|
# are installed in the same directory
|
||||||
|
$exe=".exe"
|
||||||
|
}
|
||||||
|
$ret=0
|
||||||
|
if (Test-Path "$basedir/node$exe") {
|
||||||
|
# Support pipeline input
|
||||||
|
if ($MyInvocation.ExpectingInput) {
|
||||||
|
$input | & "$basedir/node$exe" "$basedir/../uuid/dist-node/bin/uuid" $args
|
||||||
|
} else {
|
||||||
|
& "$basedir/node$exe" "$basedir/../uuid/dist-node/bin/uuid" $args
|
||||||
|
}
|
||||||
|
$ret=$LASTEXITCODE
|
||||||
|
} else {
|
||||||
|
# Support pipeline input
|
||||||
|
if ($MyInvocation.ExpectingInput) {
|
||||||
|
$input | & "node$exe" "$basedir/../uuid/dist-node/bin/uuid" $args
|
||||||
|
} else {
|
||||||
|
& "node$exe" "$basedir/../uuid/dist-node/bin/uuid" $args
|
||||||
|
}
|
||||||
|
$ret=$LASTEXITCODE
|
||||||
|
}
|
||||||
|
exit $ret
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,201 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright {yyyy} {name of copyright owner}
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
http://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.
|
||||||
|
|
@ -0,0 +1,84 @@
|
||||||
|
# Pure JavaScript gRPC Client
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Node 12 is recommended. The exact set of compatible Node versions can be found in the `engines` field of the `package.json` file.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm install @grpc/grpc-js
|
||||||
|
```
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
Documentation specifically for the `@grpc/grpc-js` package is currently not available. However, [documentation is available for the `grpc` package](https://grpc.github.io/grpc/node/grpc.html), and the two packages contain mostly the same interface. There are a few notable differences, however, and these differences are noted in the "Migrating from grpc" section below.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- Clients
|
||||||
|
- Automatic reconnection
|
||||||
|
- Servers
|
||||||
|
- Streaming
|
||||||
|
- Metadata
|
||||||
|
- Partial compression support: clients can compress and decompress messages, and servers can decompress request messages
|
||||||
|
- Pick first and round robin load balancing policies
|
||||||
|
- Client Interceptors
|
||||||
|
- Connection Keepalives
|
||||||
|
- HTTP Connect support (proxies)
|
||||||
|
|
||||||
|
If you need a feature from the `grpc` package that is not provided by the `@grpc/grpc-js`, please file a feature request with that information.
|
||||||
|
|
||||||
|
This library does not directly handle `.proto` files. To use `.proto` files with this library we recommend using the `@grpc/proto-loader` package.
|
||||||
|
|
||||||
|
## Migrating from [`grpc`](https://www.npmjs.com/package/grpc)
|
||||||
|
|
||||||
|
`@grpc/grpc-js` is almost a drop-in replacement for `grpc`, but you may need to make a few code changes to use it:
|
||||||
|
|
||||||
|
- If you are currently loading `.proto` files using `grpc.load`, that function is not available in this library. You should instead load your `.proto` files using `@grpc/proto-loader` and load the resulting package definition objects into `@grpc/grpc-js` using `grpc.loadPackageDefinition`.
|
||||||
|
- If you are currently loading packages generated by `grpc-tools`, you should instead generate your files using the `generate_package_definition` option in `grpc-tools`, then load the object exported by the generated file into `@grpc/grpc-js` using `grpc.loadPackageDefinition`.
|
||||||
|
- If you have a server and you are using `Server#bind` to bind ports, you will need to use `Server#bindAsync` instead.
|
||||||
|
- If you are using any channel options supported in `grpc` but not supported in `@grpc/grpc-js`, you may need to adjust your code to handle the different behavior. Refer to [the list of supported options](#supported-channel-options) below.
|
||||||
|
- Refer to the [detailed package comparison](https://github.com/grpc/grpc-node/blob/master/PACKAGE-COMPARISON.md) for more details on the differences between `grpc` and `@grpc/grpc-js`.
|
||||||
|
|
||||||
|
## Supported Channel Options
|
||||||
|
Many channel arguments supported in `grpc` are not supported in `@grpc/grpc-js`. The channel arguments supported by `@grpc/grpc-js` are:
|
||||||
|
- `grpc.ssl_target_name_override`
|
||||||
|
- `grpc.primary_user_agent`
|
||||||
|
- `grpc.secondary_user_agent`
|
||||||
|
- `grpc.default_authority`
|
||||||
|
- `grpc.keepalive_time_ms`
|
||||||
|
- `grpc.keepalive_timeout_ms`
|
||||||
|
- `grpc.keepalive_permit_without_calls`
|
||||||
|
- `grpc.service_config`
|
||||||
|
- `grpc.max_concurrent_streams`
|
||||||
|
- `grpc.initial_reconnect_backoff_ms`
|
||||||
|
- `grpc.max_reconnect_backoff_ms`
|
||||||
|
- `grpc.use_local_subchannel_pool`
|
||||||
|
- `grpc.max_send_message_length`
|
||||||
|
- `grpc.max_receive_message_length`
|
||||||
|
- `grpc.enable_http_proxy`
|
||||||
|
- `grpc.default_compression_algorithm`
|
||||||
|
- `grpc.enable_channelz`
|
||||||
|
- `grpc.dns_min_time_between_resolutions_ms`
|
||||||
|
- `grpc.enable_retries`
|
||||||
|
- `grpc.max_connection_age_ms`
|
||||||
|
- `grpc.max_connection_age_grace_ms`
|
||||||
|
- `grpc.max_connection_idle_ms`
|
||||||
|
- `grpc.per_rpc_retry_buffer_size`
|
||||||
|
- `grpc.retry_buffer_size`
|
||||||
|
- `grpc.service_config_disable_resolution`
|
||||||
|
- `grpc.client_idle_timeout_ms`
|
||||||
|
- `grpc-node.max_session_memory`
|
||||||
|
- `grpc-node.tls_enable_trace`
|
||||||
|
- `grpc-node.retry_max_attempts_limit`
|
||||||
|
- `grpc-node.flow_control_window`
|
||||||
|
- `channelOverride`
|
||||||
|
- `channelFactoryOverride`
|
||||||
|
|
||||||
|
## Some Notes on API Guarantees
|
||||||
|
|
||||||
|
The public API of this library follows semantic versioning, with some caveats:
|
||||||
|
|
||||||
|
- Some methods are prefixed with an underscore. These methods are internal and should not be considered part of the public API.
|
||||||
|
- The class `Call` is only exposed due to limitations of TypeScript. It should not be considered part of the public API.
|
||||||
|
- In general, any API that is exposed by this library but is not exposed by the `grpc` library is likely an error and should not be considered part of the public API.
|
||||||
|
- The `grpc.experimental` namespace contains APIs that have not stabilized. Any API in that namespace may break in any minor version update.
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { ServiceDefinition } from './make-client';
|
||||||
|
import { Server, UntypedServiceImplementation } from './server';
|
||||||
|
interface GetServiceDefinition {
|
||||||
|
(): ServiceDefinition;
|
||||||
|
}
|
||||||
|
interface GetHandlers {
|
||||||
|
(): UntypedServiceImplementation;
|
||||||
|
}
|
||||||
|
export declare function registerAdminService(getServiceDefinition: GetServiceDefinition, getHandlers: GetHandlers): void;
|
||||||
|
export declare function addAdminServicesToServer(server: Server): void;
|
||||||
|
export {};
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
"use strict";
|
||||||
|
/*
|
||||||
|
* Copyright 2021 gRPC 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
|
||||||
|
*
|
||||||
|
* http://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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.registerAdminService = registerAdminService;
|
||||||
|
exports.addAdminServicesToServer = addAdminServicesToServer;
|
||||||
|
const registeredAdminServices = [];
|
||||||
|
function registerAdminService(getServiceDefinition, getHandlers) {
|
||||||
|
registeredAdminServices.push({ getServiceDefinition, getHandlers });
|
||||||
|
}
|
||||||
|
function addAdminServicesToServer(server) {
|
||||||
|
for (const { getServiceDefinition, getHandlers } of registeredAdminServices) {
|
||||||
|
server.addService(getServiceDefinition(), getHandlers());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//# sourceMappingURL=admin.js.map
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"admin.js","sourceRoot":"","sources":["../../src/admin.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;AAkBH,oDAKC;AAED,4DAIC;AAhBD,MAAM,uBAAuB,GAGvB,EAAE,CAAC;AAET,SAAgB,oBAAoB,CAClC,oBAA0C,EAC1C,WAAwB;IAExB,uBAAuB,CAAC,IAAI,CAAC,EAAE,oBAAoB,EAAE,WAAW,EAAE,CAAC,CAAC;AACtE,CAAC;AAED,SAAgB,wBAAwB,CAAC,MAAc;IACrD,KAAK,MAAM,EAAE,oBAAoB,EAAE,WAAW,EAAE,IAAI,uBAAuB,EAAE,CAAC;QAC5E,MAAM,CAAC,UAAU,CAAC,oBAAoB,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC;IAC3D,CAAC;AACH,CAAC"}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { PeerCertificate } from "tls";
|
||||||
|
export interface AuthContext {
|
||||||
|
transportSecurityType?: string;
|
||||||
|
sslPeerCertificate?: PeerCertificate;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
"use strict";
|
||||||
|
/*
|
||||||
|
* Copyright 2025 gRPC 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
|
||||||
|
*
|
||||||
|
* http://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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
//# sourceMappingURL=auth-context.js.map
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"auth-context.js","sourceRoot":"","sources":["../../src/auth-context.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG"}
|
||||||
|
|
@ -0,0 +1,94 @@
|
||||||
|
export interface BackoffOptions {
|
||||||
|
initialDelay?: number;
|
||||||
|
multiplier?: number;
|
||||||
|
jitter?: number;
|
||||||
|
maxDelay?: number;
|
||||||
|
}
|
||||||
|
export declare class BackoffTimeout {
|
||||||
|
private callback;
|
||||||
|
/**
|
||||||
|
* The delay time at the start, and after each reset.
|
||||||
|
*/
|
||||||
|
private readonly initialDelay;
|
||||||
|
/**
|
||||||
|
* The exponential backoff multiplier.
|
||||||
|
*/
|
||||||
|
private readonly multiplier;
|
||||||
|
/**
|
||||||
|
* The maximum delay time
|
||||||
|
*/
|
||||||
|
private readonly maxDelay;
|
||||||
|
/**
|
||||||
|
* The maximum fraction by which the delay time can randomly vary after
|
||||||
|
* applying the multiplier.
|
||||||
|
*/
|
||||||
|
private readonly jitter;
|
||||||
|
/**
|
||||||
|
* The delay time for the next time the timer runs.
|
||||||
|
*/
|
||||||
|
private nextDelay;
|
||||||
|
/**
|
||||||
|
* The handle of the underlying timer. If running is false, this value refers
|
||||||
|
* to an object representing a timer that has ended, but it can still be
|
||||||
|
* interacted with without error.
|
||||||
|
*/
|
||||||
|
private timerId;
|
||||||
|
/**
|
||||||
|
* Indicates whether the timer is currently running.
|
||||||
|
*/
|
||||||
|
private running;
|
||||||
|
/**
|
||||||
|
* Indicates whether the timer should keep the Node process running if no
|
||||||
|
* other async operation is doing so.
|
||||||
|
*/
|
||||||
|
private hasRef;
|
||||||
|
/**
|
||||||
|
* The time that the currently running timer was started. Only valid if
|
||||||
|
* running is true.
|
||||||
|
*/
|
||||||
|
private startTime;
|
||||||
|
/**
|
||||||
|
* The approximate time that the currently running timer will end. Only valid
|
||||||
|
* if running is true.
|
||||||
|
*/
|
||||||
|
private endTime;
|
||||||
|
private id;
|
||||||
|
private static nextId;
|
||||||
|
constructor(callback: () => void, options?: BackoffOptions);
|
||||||
|
private static getNextId;
|
||||||
|
private trace;
|
||||||
|
private runTimer;
|
||||||
|
/**
|
||||||
|
* Call the callback after the current amount of delay time
|
||||||
|
*/
|
||||||
|
runOnce(): void;
|
||||||
|
/**
|
||||||
|
* Stop the timer. The callback will not be called until `runOnce` is called
|
||||||
|
* again.
|
||||||
|
*/
|
||||||
|
stop(): void;
|
||||||
|
/**
|
||||||
|
* Reset the delay time to its initial value. If the timer is still running,
|
||||||
|
* retroactively apply that reset to the current timer.
|
||||||
|
*/
|
||||||
|
reset(): void;
|
||||||
|
/**
|
||||||
|
* Check whether the timer is currently running.
|
||||||
|
*/
|
||||||
|
isRunning(): boolean;
|
||||||
|
/**
|
||||||
|
* Set that while the timer is running, it should keep the Node process
|
||||||
|
* running.
|
||||||
|
*/
|
||||||
|
ref(): void;
|
||||||
|
/**
|
||||||
|
* Set that while the timer is running, it should not keep the Node process
|
||||||
|
* running.
|
||||||
|
*/
|
||||||
|
unref(): void;
|
||||||
|
/**
|
||||||
|
* Get the approximate timestamp of when the timer will fire. Only valid if
|
||||||
|
* this.isRunning() is true.
|
||||||
|
*/
|
||||||
|
getEndTime(): Date;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,191 @@
|
||||||
|
"use strict";
|
||||||
|
/*
|
||||||
|
* Copyright 2019 gRPC 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
|
||||||
|
*
|
||||||
|
* http://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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.BackoffTimeout = void 0;
|
||||||
|
const constants_1 = require("./constants");
|
||||||
|
const logging = require("./logging");
|
||||||
|
const TRACER_NAME = 'backoff';
|
||||||
|
const INITIAL_BACKOFF_MS = 1000;
|
||||||
|
const BACKOFF_MULTIPLIER = 1.6;
|
||||||
|
const MAX_BACKOFF_MS = 120000;
|
||||||
|
const BACKOFF_JITTER = 0.2;
|
||||||
|
/**
|
||||||
|
* Get a number uniformly at random in the range [min, max)
|
||||||
|
* @param min
|
||||||
|
* @param max
|
||||||
|
*/
|
||||||
|
function uniformRandom(min, max) {
|
||||||
|
return Math.random() * (max - min) + min;
|
||||||
|
}
|
||||||
|
class BackoffTimeout {
|
||||||
|
constructor(callback, options) {
|
||||||
|
this.callback = callback;
|
||||||
|
/**
|
||||||
|
* The delay time at the start, and after each reset.
|
||||||
|
*/
|
||||||
|
this.initialDelay = INITIAL_BACKOFF_MS;
|
||||||
|
/**
|
||||||
|
* The exponential backoff multiplier.
|
||||||
|
*/
|
||||||
|
this.multiplier = BACKOFF_MULTIPLIER;
|
||||||
|
/**
|
||||||
|
* The maximum delay time
|
||||||
|
*/
|
||||||
|
this.maxDelay = MAX_BACKOFF_MS;
|
||||||
|
/**
|
||||||
|
* The maximum fraction by which the delay time can randomly vary after
|
||||||
|
* applying the multiplier.
|
||||||
|
*/
|
||||||
|
this.jitter = BACKOFF_JITTER;
|
||||||
|
/**
|
||||||
|
* Indicates whether the timer is currently running.
|
||||||
|
*/
|
||||||
|
this.running = false;
|
||||||
|
/**
|
||||||
|
* Indicates whether the timer should keep the Node process running if no
|
||||||
|
* other async operation is doing so.
|
||||||
|
*/
|
||||||
|
this.hasRef = true;
|
||||||
|
/**
|
||||||
|
* The time that the currently running timer was started. Only valid if
|
||||||
|
* running is true.
|
||||||
|
*/
|
||||||
|
this.startTime = new Date();
|
||||||
|
/**
|
||||||
|
* The approximate time that the currently running timer will end. Only valid
|
||||||
|
* if running is true.
|
||||||
|
*/
|
||||||
|
this.endTime = new Date();
|
||||||
|
this.id = BackoffTimeout.getNextId();
|
||||||
|
if (options) {
|
||||||
|
if (options.initialDelay) {
|
||||||
|
this.initialDelay = options.initialDelay;
|
||||||
|
}
|
||||||
|
if (options.multiplier) {
|
||||||
|
this.multiplier = options.multiplier;
|
||||||
|
}
|
||||||
|
if (options.jitter) {
|
||||||
|
this.jitter = options.jitter;
|
||||||
|
}
|
||||||
|
if (options.maxDelay) {
|
||||||
|
this.maxDelay = options.maxDelay;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.trace('constructed initialDelay=' + this.initialDelay + ' multiplier=' + this.multiplier + ' jitter=' + this.jitter + ' maxDelay=' + this.maxDelay);
|
||||||
|
this.nextDelay = this.initialDelay;
|
||||||
|
this.timerId = setTimeout(() => { }, 0);
|
||||||
|
clearTimeout(this.timerId);
|
||||||
|
}
|
||||||
|
static getNextId() {
|
||||||
|
return this.nextId++;
|
||||||
|
}
|
||||||
|
trace(text) {
|
||||||
|
logging.trace(constants_1.LogVerbosity.DEBUG, TRACER_NAME, '{' + this.id + '} ' + text);
|
||||||
|
}
|
||||||
|
runTimer(delay) {
|
||||||
|
var _a, _b;
|
||||||
|
this.trace('runTimer(delay=' + delay + ')');
|
||||||
|
this.endTime = this.startTime;
|
||||||
|
this.endTime.setMilliseconds(this.endTime.getMilliseconds() + delay);
|
||||||
|
clearTimeout(this.timerId);
|
||||||
|
this.timerId = setTimeout(() => {
|
||||||
|
this.trace('timer fired');
|
||||||
|
this.running = false;
|
||||||
|
this.callback();
|
||||||
|
}, delay);
|
||||||
|
if (!this.hasRef) {
|
||||||
|
(_b = (_a = this.timerId).unref) === null || _b === void 0 ? void 0 : _b.call(_a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Call the callback after the current amount of delay time
|
||||||
|
*/
|
||||||
|
runOnce() {
|
||||||
|
this.trace('runOnce()');
|
||||||
|
this.running = true;
|
||||||
|
this.startTime = new Date();
|
||||||
|
this.runTimer(this.nextDelay);
|
||||||
|
const nextBackoff = Math.min(this.nextDelay * this.multiplier, this.maxDelay);
|
||||||
|
const jitterMagnitude = nextBackoff * this.jitter;
|
||||||
|
this.nextDelay =
|
||||||
|
nextBackoff + uniformRandom(-jitterMagnitude, jitterMagnitude);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Stop the timer. The callback will not be called until `runOnce` is called
|
||||||
|
* again.
|
||||||
|
*/
|
||||||
|
stop() {
|
||||||
|
this.trace('stop()');
|
||||||
|
clearTimeout(this.timerId);
|
||||||
|
this.running = false;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Reset the delay time to its initial value. If the timer is still running,
|
||||||
|
* retroactively apply that reset to the current timer.
|
||||||
|
*/
|
||||||
|
reset() {
|
||||||
|
this.trace('reset() running=' + this.running);
|
||||||
|
this.nextDelay = this.initialDelay;
|
||||||
|
if (this.running) {
|
||||||
|
const now = new Date();
|
||||||
|
const newEndTime = this.startTime;
|
||||||
|
newEndTime.setMilliseconds(newEndTime.getMilliseconds() + this.nextDelay);
|
||||||
|
clearTimeout(this.timerId);
|
||||||
|
if (now < newEndTime) {
|
||||||
|
this.runTimer(newEndTime.getTime() - now.getTime());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.running = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Check whether the timer is currently running.
|
||||||
|
*/
|
||||||
|
isRunning() {
|
||||||
|
return this.running;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Set that while the timer is running, it should keep the Node process
|
||||||
|
* running.
|
||||||
|
*/
|
||||||
|
ref() {
|
||||||
|
var _a, _b;
|
||||||
|
this.hasRef = true;
|
||||||
|
(_b = (_a = this.timerId).ref) === null || _b === void 0 ? void 0 : _b.call(_a);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Set that while the timer is running, it should not keep the Node process
|
||||||
|
* running.
|
||||||
|
*/
|
||||||
|
unref() {
|
||||||
|
var _a, _b;
|
||||||
|
this.hasRef = false;
|
||||||
|
(_b = (_a = this.timerId).unref) === null || _b === void 0 ? void 0 : _b.call(_a);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Get the approximate timestamp of when the timer will fire. Only valid if
|
||||||
|
* this.isRunning() is true.
|
||||||
|
*/
|
||||||
|
getEndTime() {
|
||||||
|
return this.endTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.BackoffTimeout = BackoffTimeout;
|
||||||
|
BackoffTimeout.nextId = 0;
|
||||||
|
//# sourceMappingURL=backoff-timeout.js.map
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"backoff-timeout.js","sourceRoot":"","sources":["../../src/backoff-timeout.ts"],"names":[],"mappings":"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"}
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
import { Metadata } from './metadata';
|
||||||
|
export interface CallMetadataOptions {
|
||||||
|
method_name: string;
|
||||||
|
service_url: string;
|
||||||
|
}
|
||||||
|
export type CallMetadataGenerator = (options: CallMetadataOptions, cb: (err: Error | null, metadata?: Metadata) => void) => void;
|
||||||
|
export interface OldOAuth2Client {
|
||||||
|
getRequestMetadata: (url: string, callback: (err: Error | null, headers?: {
|
||||||
|
[index: string]: string;
|
||||||
|
}) => void) => void;
|
||||||
|
}
|
||||||
|
export interface CurrentOAuth2Client {
|
||||||
|
getRequestHeaders: (url?: string) => Promise<{
|
||||||
|
[index: string]: string;
|
||||||
|
}>;
|
||||||
|
}
|
||||||
|
export type OAuth2Client = OldOAuth2Client | CurrentOAuth2Client;
|
||||||
|
/**
|
||||||
|
* A class that represents a generic method of adding authentication-related
|
||||||
|
* metadata on a per-request basis.
|
||||||
|
*/
|
||||||
|
export declare abstract class CallCredentials {
|
||||||
|
/**
|
||||||
|
* Asynchronously generates a new Metadata object.
|
||||||
|
* @param options Options used in generating the Metadata object.
|
||||||
|
*/
|
||||||
|
abstract generateMetadata(options: CallMetadataOptions): Promise<Metadata>;
|
||||||
|
/**
|
||||||
|
* Creates a new CallCredentials object from properties of both this and
|
||||||
|
* another CallCredentials object. This object's metadata generator will be
|
||||||
|
* called first.
|
||||||
|
* @param callCredentials The other CallCredentials object.
|
||||||
|
*/
|
||||||
|
abstract compose(callCredentials: CallCredentials): CallCredentials;
|
||||||
|
/**
|
||||||
|
* Check whether two call credentials objects are equal. Separate
|
||||||
|
* SingleCallCredentials with identical metadata generator functions are
|
||||||
|
* equal.
|
||||||
|
* @param other The other CallCredentials object to compare with.
|
||||||
|
*/
|
||||||
|
abstract _equals(other: CallCredentials): boolean;
|
||||||
|
/**
|
||||||
|
* Creates a new CallCredentials object from a given function that generates
|
||||||
|
* Metadata objects.
|
||||||
|
* @param metadataGenerator A function that accepts a set of options, and
|
||||||
|
* generates a Metadata object based on these options, which is passed back
|
||||||
|
* to the caller via a supplied (err, metadata) callback.
|
||||||
|
*/
|
||||||
|
static createFromMetadataGenerator(metadataGenerator: CallMetadataGenerator): CallCredentials;
|
||||||
|
/**
|
||||||
|
* Create a gRPC credential from a Google credential object.
|
||||||
|
* @param googleCredentials The authentication client to use.
|
||||||
|
* @return The resulting CallCredentials object.
|
||||||
|
*/
|
||||||
|
static createFromGoogleCredential(googleCredentials: OAuth2Client): CallCredentials;
|
||||||
|
static createEmpty(): CallCredentials;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,153 @@
|
||||||
|
"use strict";
|
||||||
|
/*
|
||||||
|
* Copyright 2019 gRPC 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
|
||||||
|
*
|
||||||
|
* http://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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.CallCredentials = void 0;
|
||||||
|
const metadata_1 = require("./metadata");
|
||||||
|
function isCurrentOauth2Client(client) {
|
||||||
|
return ('getRequestHeaders' in client &&
|
||||||
|
typeof client.getRequestHeaders === 'function');
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* A class that represents a generic method of adding authentication-related
|
||||||
|
* metadata on a per-request basis.
|
||||||
|
*/
|
||||||
|
class CallCredentials {
|
||||||
|
/**
|
||||||
|
* Creates a new CallCredentials object from a given function that generates
|
||||||
|
* Metadata objects.
|
||||||
|
* @param metadataGenerator A function that accepts a set of options, and
|
||||||
|
* generates a Metadata object based on these options, which is passed back
|
||||||
|
* to the caller via a supplied (err, metadata) callback.
|
||||||
|
*/
|
||||||
|
static createFromMetadataGenerator(metadataGenerator) {
|
||||||
|
return new SingleCallCredentials(metadataGenerator);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Create a gRPC credential from a Google credential object.
|
||||||
|
* @param googleCredentials The authentication client to use.
|
||||||
|
* @return The resulting CallCredentials object.
|
||||||
|
*/
|
||||||
|
static createFromGoogleCredential(googleCredentials) {
|
||||||
|
return CallCredentials.createFromMetadataGenerator((options, callback) => {
|
||||||
|
let getHeaders;
|
||||||
|
if (isCurrentOauth2Client(googleCredentials)) {
|
||||||
|
getHeaders = googleCredentials.getRequestHeaders(options.service_url);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
getHeaders = new Promise((resolve, reject) => {
|
||||||
|
googleCredentials.getRequestMetadata(options.service_url, (err, headers) => {
|
||||||
|
if (err) {
|
||||||
|
reject(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!headers) {
|
||||||
|
reject(new Error('Headers not set by metadata plugin'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
resolve(headers);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
getHeaders.then(headers => {
|
||||||
|
const metadata = new metadata_1.Metadata();
|
||||||
|
for (const key of Object.keys(headers)) {
|
||||||
|
metadata.add(key, headers[key]);
|
||||||
|
}
|
||||||
|
callback(null, metadata);
|
||||||
|
}, err => {
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
static createEmpty() {
|
||||||
|
return new EmptyCallCredentials();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.CallCredentials = CallCredentials;
|
||||||
|
class ComposedCallCredentials extends CallCredentials {
|
||||||
|
constructor(creds) {
|
||||||
|
super();
|
||||||
|
this.creds = creds;
|
||||||
|
}
|
||||||
|
async generateMetadata(options) {
|
||||||
|
const base = new metadata_1.Metadata();
|
||||||
|
const generated = await Promise.all(this.creds.map(cred => cred.generateMetadata(options)));
|
||||||
|
for (const gen of generated) {
|
||||||
|
base.merge(gen);
|
||||||
|
}
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
compose(other) {
|
||||||
|
return new ComposedCallCredentials(this.creds.concat([other]));
|
||||||
|
}
|
||||||
|
_equals(other) {
|
||||||
|
if (this === other) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (other instanceof ComposedCallCredentials) {
|
||||||
|
return this.creds.every((value, index) => value._equals(other.creds[index]));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class SingleCallCredentials extends CallCredentials {
|
||||||
|
constructor(metadataGenerator) {
|
||||||
|
super();
|
||||||
|
this.metadataGenerator = metadataGenerator;
|
||||||
|
}
|
||||||
|
generateMetadata(options) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this.metadataGenerator(options, (err, metadata) => {
|
||||||
|
if (metadata !== undefined) {
|
||||||
|
resolve(metadata);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
reject(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
compose(other) {
|
||||||
|
return new ComposedCallCredentials([this, other]);
|
||||||
|
}
|
||||||
|
_equals(other) {
|
||||||
|
if (this === other) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (other instanceof SingleCallCredentials) {
|
||||||
|
return this.metadataGenerator === other.metadataGenerator;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class EmptyCallCredentials extends CallCredentials {
|
||||||
|
generateMetadata(options) {
|
||||||
|
return Promise.resolve(new metadata_1.Metadata());
|
||||||
|
}
|
||||||
|
compose(other) {
|
||||||
|
return other;
|
||||||
|
}
|
||||||
|
_equals(other) {
|
||||||
|
return other instanceof EmptyCallCredentials;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//# sourceMappingURL=call-credentials.js.map
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"call-credentials.js","sourceRoot":"","sources":["../../src/call-credentials.ts"],"names":[],"mappings":"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"}
|
||||||
|
|
@ -0,0 +1,101 @@
|
||||||
|
import { AuthContext } from './auth-context';
|
||||||
|
import { CallCredentials } from './call-credentials';
|
||||||
|
import { Status } from './constants';
|
||||||
|
import { Deadline } from './deadline';
|
||||||
|
import { Metadata } from './metadata';
|
||||||
|
import { ServerSurfaceCall } from './server-call';
|
||||||
|
export interface CallStreamOptions {
|
||||||
|
deadline: Deadline;
|
||||||
|
flags: number;
|
||||||
|
host: string;
|
||||||
|
parentCall: ServerSurfaceCall | null;
|
||||||
|
}
|
||||||
|
export type PartialCallStreamOptions = Partial<CallStreamOptions>;
|
||||||
|
export interface StatusObject {
|
||||||
|
code: Status;
|
||||||
|
details: string;
|
||||||
|
metadata: Metadata;
|
||||||
|
}
|
||||||
|
export type PartialStatusObject = Pick<StatusObject, 'code' | 'details'> & {
|
||||||
|
metadata?: Metadata | null | undefined;
|
||||||
|
};
|
||||||
|
export interface StatusOrOk<T> {
|
||||||
|
ok: true;
|
||||||
|
value: T;
|
||||||
|
}
|
||||||
|
export interface StatusOrError {
|
||||||
|
ok: false;
|
||||||
|
error: StatusObject;
|
||||||
|
}
|
||||||
|
export type StatusOr<T> = StatusOrOk<T> | StatusOrError;
|
||||||
|
export declare function statusOrFromValue<T>(value: T): StatusOr<T>;
|
||||||
|
export declare function statusOrFromError<T>(error: PartialStatusObject): StatusOr<T>;
|
||||||
|
export declare const enum WriteFlags {
|
||||||
|
BufferHint = 1,
|
||||||
|
NoCompress = 2,
|
||||||
|
WriteThrough = 4
|
||||||
|
}
|
||||||
|
export interface WriteObject {
|
||||||
|
message: Buffer;
|
||||||
|
flags?: number;
|
||||||
|
}
|
||||||
|
export interface MetadataListener {
|
||||||
|
(metadata: Metadata, next: (metadata: Metadata) => void): void;
|
||||||
|
}
|
||||||
|
export interface MessageListener {
|
||||||
|
(message: any, next: (message: any) => void): void;
|
||||||
|
}
|
||||||
|
export interface StatusListener {
|
||||||
|
(status: StatusObject, next: (status: StatusObject) => void): void;
|
||||||
|
}
|
||||||
|
export interface FullListener {
|
||||||
|
onReceiveMetadata: MetadataListener;
|
||||||
|
onReceiveMessage: MessageListener;
|
||||||
|
onReceiveStatus: StatusListener;
|
||||||
|
}
|
||||||
|
export type Listener = Partial<FullListener>;
|
||||||
|
/**
|
||||||
|
* An object with methods for handling the responses to a call.
|
||||||
|
*/
|
||||||
|
export interface InterceptingListener {
|
||||||
|
onReceiveMetadata(metadata: Metadata): void;
|
||||||
|
onReceiveMessage(message: any): void;
|
||||||
|
onReceiveStatus(status: StatusObject): void;
|
||||||
|
}
|
||||||
|
export declare function isInterceptingListener(listener: Listener | InterceptingListener): listener is InterceptingListener;
|
||||||
|
export declare class InterceptingListenerImpl implements InterceptingListener {
|
||||||
|
private listener;
|
||||||
|
private nextListener;
|
||||||
|
private processingMetadata;
|
||||||
|
private hasPendingMessage;
|
||||||
|
private pendingMessage;
|
||||||
|
private processingMessage;
|
||||||
|
private pendingStatus;
|
||||||
|
constructor(listener: FullListener, nextListener: InterceptingListener);
|
||||||
|
private processPendingMessage;
|
||||||
|
private processPendingStatus;
|
||||||
|
onReceiveMetadata(metadata: Metadata): void;
|
||||||
|
onReceiveMessage(message: any): void;
|
||||||
|
onReceiveStatus(status: StatusObject): void;
|
||||||
|
}
|
||||||
|
export interface WriteCallback {
|
||||||
|
(error?: Error | null): void;
|
||||||
|
}
|
||||||
|
export interface MessageContext {
|
||||||
|
callback?: WriteCallback;
|
||||||
|
flags?: number;
|
||||||
|
}
|
||||||
|
export interface Call {
|
||||||
|
cancelWithStatus(status: Status, details: string): void;
|
||||||
|
getPeer(): string;
|
||||||
|
start(metadata: Metadata, listener: InterceptingListener): void;
|
||||||
|
sendMessageWithContext(context: MessageContext, message: Buffer): void;
|
||||||
|
startRead(): void;
|
||||||
|
halfClose(): void;
|
||||||
|
getCallNumber(): number;
|
||||||
|
setCredentials(credentials: CallCredentials): void;
|
||||||
|
getAuthContext(): AuthContext | null;
|
||||||
|
}
|
||||||
|
export interface DeadlineInfoProvider {
|
||||||
|
getDeadlineInfo(): string[];
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,100 @@
|
||||||
|
"use strict";
|
||||||
|
/*
|
||||||
|
* Copyright 2022 gRPC 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
|
||||||
|
*
|
||||||
|
* http://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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.InterceptingListenerImpl = void 0;
|
||||||
|
exports.statusOrFromValue = statusOrFromValue;
|
||||||
|
exports.statusOrFromError = statusOrFromError;
|
||||||
|
exports.isInterceptingListener = isInterceptingListener;
|
||||||
|
const metadata_1 = require("./metadata");
|
||||||
|
function statusOrFromValue(value) {
|
||||||
|
return {
|
||||||
|
ok: true,
|
||||||
|
value: value
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function statusOrFromError(error) {
|
||||||
|
var _a;
|
||||||
|
return {
|
||||||
|
ok: false,
|
||||||
|
error: Object.assign(Object.assign({}, error), { metadata: (_a = error.metadata) !== null && _a !== void 0 ? _a : new metadata_1.Metadata() })
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function isInterceptingListener(listener) {
|
||||||
|
return (listener.onReceiveMetadata !== undefined &&
|
||||||
|
listener.onReceiveMetadata.length === 1);
|
||||||
|
}
|
||||||
|
class InterceptingListenerImpl {
|
||||||
|
constructor(listener, nextListener) {
|
||||||
|
this.listener = listener;
|
||||||
|
this.nextListener = nextListener;
|
||||||
|
this.processingMetadata = false;
|
||||||
|
this.hasPendingMessage = false;
|
||||||
|
this.processingMessage = false;
|
||||||
|
this.pendingStatus = null;
|
||||||
|
}
|
||||||
|
processPendingMessage() {
|
||||||
|
if (this.hasPendingMessage) {
|
||||||
|
this.nextListener.onReceiveMessage(this.pendingMessage);
|
||||||
|
this.pendingMessage = null;
|
||||||
|
this.hasPendingMessage = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
processPendingStatus() {
|
||||||
|
if (this.pendingStatus) {
|
||||||
|
this.nextListener.onReceiveStatus(this.pendingStatus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onReceiveMetadata(metadata) {
|
||||||
|
this.processingMetadata = true;
|
||||||
|
this.listener.onReceiveMetadata(metadata, metadata => {
|
||||||
|
this.processingMetadata = false;
|
||||||
|
this.nextListener.onReceiveMetadata(metadata);
|
||||||
|
this.processPendingMessage();
|
||||||
|
this.processPendingStatus();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
onReceiveMessage(message) {
|
||||||
|
/* If this listener processes messages asynchronously, the last message may
|
||||||
|
* be reordered with respect to the status */
|
||||||
|
this.processingMessage = true;
|
||||||
|
this.listener.onReceiveMessage(message, msg => {
|
||||||
|
this.processingMessage = false;
|
||||||
|
if (this.processingMetadata) {
|
||||||
|
this.pendingMessage = msg;
|
||||||
|
this.hasPendingMessage = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.nextListener.onReceiveMessage(msg);
|
||||||
|
this.processPendingStatus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
onReceiveStatus(status) {
|
||||||
|
this.listener.onReceiveStatus(status, processedStatus => {
|
||||||
|
if (this.processingMetadata || this.processingMessage) {
|
||||||
|
this.pendingStatus = processedStatus;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.nextListener.onReceiveStatus(processedStatus);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.InterceptingListenerImpl = InterceptingListenerImpl;
|
||||||
|
//# sourceMappingURL=call-interface.js.map
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"call-interface.js","sourceRoot":"","sources":["../../src/call-interface.ts"],"names":[],"mappings":"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"}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
export declare function getNextCallNumber(): number;
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
"use strict";
|
||||||
|
/*
|
||||||
|
* Copyright 2022 gRPC 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
|
||||||
|
*
|
||||||
|
* http://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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.getNextCallNumber = getNextCallNumber;
|
||||||
|
let nextCallNumber = 0;
|
||||||
|
function getNextCallNumber() {
|
||||||
|
return nextCallNumber++;
|
||||||
|
}
|
||||||
|
//# sourceMappingURL=call-number.js.map
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"call-number.js","sourceRoot":"","sources":["../../src/call-number.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;AAIH,8CAEC;AAJD,IAAI,cAAc,GAAG,CAAC,CAAC;AAEvB,SAAgB,iBAAiB;IAC/B,OAAO,cAAc,EAAE,CAAC;AAC1B,CAAC"}
|
||||||
|
|
@ -0,0 +1,86 @@
|
||||||
|
import { EventEmitter } from 'events';
|
||||||
|
import { Duplex, Readable, Writable } from 'stream';
|
||||||
|
import { StatusObject } from './call-interface';
|
||||||
|
import { EmitterAugmentation1 } from './events';
|
||||||
|
import { Metadata } from './metadata';
|
||||||
|
import { ObjectReadable, ObjectWritable, WriteCallback } from './object-stream';
|
||||||
|
import { InterceptingCallInterface } from './client-interceptors';
|
||||||
|
import { AuthContext } from './auth-context';
|
||||||
|
/**
|
||||||
|
* A type extending the built-in Error object with additional fields.
|
||||||
|
*/
|
||||||
|
export type ServiceError = StatusObject & Error;
|
||||||
|
/**
|
||||||
|
* A base type for all user-facing values returned by client-side method calls.
|
||||||
|
*/
|
||||||
|
export type SurfaceCall = {
|
||||||
|
call?: InterceptingCallInterface;
|
||||||
|
cancel(): void;
|
||||||
|
getPeer(): string;
|
||||||
|
getAuthContext(): AuthContext | null;
|
||||||
|
} & EmitterAugmentation1<'metadata', Metadata> & EmitterAugmentation1<'status', StatusObject> & EventEmitter;
|
||||||
|
/**
|
||||||
|
* A type representing the return value of a unary method call.
|
||||||
|
*/
|
||||||
|
export type ClientUnaryCall = SurfaceCall;
|
||||||
|
/**
|
||||||
|
* A type representing the return value of a server stream method call.
|
||||||
|
*/
|
||||||
|
export type ClientReadableStream<ResponseType> = {
|
||||||
|
deserialize: (chunk: Buffer) => ResponseType;
|
||||||
|
} & SurfaceCall & ObjectReadable<ResponseType>;
|
||||||
|
/**
|
||||||
|
* A type representing the return value of a client stream method call.
|
||||||
|
*/
|
||||||
|
export type ClientWritableStream<RequestType> = {
|
||||||
|
serialize: (value: RequestType) => Buffer;
|
||||||
|
} & SurfaceCall & ObjectWritable<RequestType>;
|
||||||
|
/**
|
||||||
|
* A type representing the return value of a bidirectional stream method call.
|
||||||
|
*/
|
||||||
|
export type ClientDuplexStream<RequestType, ResponseType> = ClientWritableStream<RequestType> & ClientReadableStream<ResponseType>;
|
||||||
|
/**
|
||||||
|
* Construct a ServiceError from a StatusObject. This function exists primarily
|
||||||
|
* as an attempt to make the error stack trace clearly communicate that the
|
||||||
|
* error is not necessarily a problem in gRPC itself.
|
||||||
|
* @param status
|
||||||
|
*/
|
||||||
|
export declare function callErrorFromStatus(status: StatusObject, callerStack: string): ServiceError;
|
||||||
|
export declare class ClientUnaryCallImpl extends EventEmitter implements ClientUnaryCall {
|
||||||
|
call?: InterceptingCallInterface;
|
||||||
|
constructor();
|
||||||
|
cancel(): void;
|
||||||
|
getPeer(): string;
|
||||||
|
getAuthContext(): AuthContext | null;
|
||||||
|
}
|
||||||
|
export declare class ClientReadableStreamImpl<ResponseType> extends Readable implements ClientReadableStream<ResponseType> {
|
||||||
|
readonly deserialize: (chunk: Buffer) => ResponseType;
|
||||||
|
call?: InterceptingCallInterface;
|
||||||
|
constructor(deserialize: (chunk: Buffer) => ResponseType);
|
||||||
|
cancel(): void;
|
||||||
|
getPeer(): string;
|
||||||
|
getAuthContext(): AuthContext | null;
|
||||||
|
_read(_size: number): void;
|
||||||
|
}
|
||||||
|
export declare class ClientWritableStreamImpl<RequestType> extends Writable implements ClientWritableStream<RequestType> {
|
||||||
|
readonly serialize: (value: RequestType) => Buffer;
|
||||||
|
call?: InterceptingCallInterface;
|
||||||
|
constructor(serialize: (value: RequestType) => Buffer);
|
||||||
|
cancel(): void;
|
||||||
|
getPeer(): string;
|
||||||
|
getAuthContext(): AuthContext | null;
|
||||||
|
_write(chunk: RequestType, encoding: string, cb: WriteCallback): void;
|
||||||
|
_final(cb: Function): void;
|
||||||
|
}
|
||||||
|
export declare class ClientDuplexStreamImpl<RequestType, ResponseType> extends Duplex implements ClientDuplexStream<RequestType, ResponseType> {
|
||||||
|
readonly serialize: (value: RequestType) => Buffer;
|
||||||
|
readonly deserialize: (chunk: Buffer) => ResponseType;
|
||||||
|
call?: InterceptingCallInterface;
|
||||||
|
constructor(serialize: (value: RequestType) => Buffer, deserialize: (chunk: Buffer) => ResponseType);
|
||||||
|
cancel(): void;
|
||||||
|
getPeer(): string;
|
||||||
|
getAuthContext(): AuthContext | null;
|
||||||
|
_read(_size: number): void;
|
||||||
|
_write(chunk: RequestType, encoding: string, cb: WriteCallback): void;
|
||||||
|
_final(cb: Function): void;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,152 @@
|
||||||
|
"use strict";
|
||||||
|
/*
|
||||||
|
* Copyright 2019 gRPC 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
|
||||||
|
*
|
||||||
|
* http://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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.ClientDuplexStreamImpl = exports.ClientWritableStreamImpl = exports.ClientReadableStreamImpl = exports.ClientUnaryCallImpl = void 0;
|
||||||
|
exports.callErrorFromStatus = callErrorFromStatus;
|
||||||
|
const events_1 = require("events");
|
||||||
|
const stream_1 = require("stream");
|
||||||
|
const constants_1 = require("./constants");
|
||||||
|
/**
|
||||||
|
* Construct a ServiceError from a StatusObject. This function exists primarily
|
||||||
|
* as an attempt to make the error stack trace clearly communicate that the
|
||||||
|
* error is not necessarily a problem in gRPC itself.
|
||||||
|
* @param status
|
||||||
|
*/
|
||||||
|
function callErrorFromStatus(status, callerStack) {
|
||||||
|
const message = `${status.code} ${constants_1.Status[status.code]}: ${status.details}`;
|
||||||
|
const error = new Error(message);
|
||||||
|
const stack = `${error.stack}\nfor call at\n${callerStack}`;
|
||||||
|
return Object.assign(new Error(message), status, { stack });
|
||||||
|
}
|
||||||
|
class ClientUnaryCallImpl extends events_1.EventEmitter {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
cancel() {
|
||||||
|
var _a;
|
||||||
|
(_a = this.call) === null || _a === void 0 ? void 0 : _a.cancelWithStatus(constants_1.Status.CANCELLED, 'Cancelled on client');
|
||||||
|
}
|
||||||
|
getPeer() {
|
||||||
|
var _a, _b;
|
||||||
|
return (_b = (_a = this.call) === null || _a === void 0 ? void 0 : _a.getPeer()) !== null && _b !== void 0 ? _b : 'unknown';
|
||||||
|
}
|
||||||
|
getAuthContext() {
|
||||||
|
var _a, _b;
|
||||||
|
return (_b = (_a = this.call) === null || _a === void 0 ? void 0 : _a.getAuthContext()) !== null && _b !== void 0 ? _b : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.ClientUnaryCallImpl = ClientUnaryCallImpl;
|
||||||
|
class ClientReadableStreamImpl extends stream_1.Readable {
|
||||||
|
constructor(deserialize) {
|
||||||
|
super({ objectMode: true });
|
||||||
|
this.deserialize = deserialize;
|
||||||
|
}
|
||||||
|
cancel() {
|
||||||
|
var _a;
|
||||||
|
(_a = this.call) === null || _a === void 0 ? void 0 : _a.cancelWithStatus(constants_1.Status.CANCELLED, 'Cancelled on client');
|
||||||
|
}
|
||||||
|
getPeer() {
|
||||||
|
var _a, _b;
|
||||||
|
return (_b = (_a = this.call) === null || _a === void 0 ? void 0 : _a.getPeer()) !== null && _b !== void 0 ? _b : 'unknown';
|
||||||
|
}
|
||||||
|
getAuthContext() {
|
||||||
|
var _a, _b;
|
||||||
|
return (_b = (_a = this.call) === null || _a === void 0 ? void 0 : _a.getAuthContext()) !== null && _b !== void 0 ? _b : null;
|
||||||
|
}
|
||||||
|
_read(_size) {
|
||||||
|
var _a;
|
||||||
|
(_a = this.call) === null || _a === void 0 ? void 0 : _a.startRead();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.ClientReadableStreamImpl = ClientReadableStreamImpl;
|
||||||
|
class ClientWritableStreamImpl extends stream_1.Writable {
|
||||||
|
constructor(serialize) {
|
||||||
|
super({ objectMode: true });
|
||||||
|
this.serialize = serialize;
|
||||||
|
}
|
||||||
|
cancel() {
|
||||||
|
var _a;
|
||||||
|
(_a = this.call) === null || _a === void 0 ? void 0 : _a.cancelWithStatus(constants_1.Status.CANCELLED, 'Cancelled on client');
|
||||||
|
}
|
||||||
|
getPeer() {
|
||||||
|
var _a, _b;
|
||||||
|
return (_b = (_a = this.call) === null || _a === void 0 ? void 0 : _a.getPeer()) !== null && _b !== void 0 ? _b : 'unknown';
|
||||||
|
}
|
||||||
|
getAuthContext() {
|
||||||
|
var _a, _b;
|
||||||
|
return (_b = (_a = this.call) === null || _a === void 0 ? void 0 : _a.getAuthContext()) !== null && _b !== void 0 ? _b : null;
|
||||||
|
}
|
||||||
|
_write(chunk, encoding, cb) {
|
||||||
|
var _a;
|
||||||
|
const context = {
|
||||||
|
callback: cb,
|
||||||
|
};
|
||||||
|
const flags = Number(encoding);
|
||||||
|
if (!Number.isNaN(flags)) {
|
||||||
|
context.flags = flags;
|
||||||
|
}
|
||||||
|
(_a = this.call) === null || _a === void 0 ? void 0 : _a.sendMessageWithContext(context, chunk);
|
||||||
|
}
|
||||||
|
_final(cb) {
|
||||||
|
var _a;
|
||||||
|
(_a = this.call) === null || _a === void 0 ? void 0 : _a.halfClose();
|
||||||
|
cb();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.ClientWritableStreamImpl = ClientWritableStreamImpl;
|
||||||
|
class ClientDuplexStreamImpl extends stream_1.Duplex {
|
||||||
|
constructor(serialize, deserialize) {
|
||||||
|
super({ objectMode: true });
|
||||||
|
this.serialize = serialize;
|
||||||
|
this.deserialize = deserialize;
|
||||||
|
}
|
||||||
|
cancel() {
|
||||||
|
var _a;
|
||||||
|
(_a = this.call) === null || _a === void 0 ? void 0 : _a.cancelWithStatus(constants_1.Status.CANCELLED, 'Cancelled on client');
|
||||||
|
}
|
||||||
|
getPeer() {
|
||||||
|
var _a, _b;
|
||||||
|
return (_b = (_a = this.call) === null || _a === void 0 ? void 0 : _a.getPeer()) !== null && _b !== void 0 ? _b : 'unknown';
|
||||||
|
}
|
||||||
|
getAuthContext() {
|
||||||
|
var _a, _b;
|
||||||
|
return (_b = (_a = this.call) === null || _a === void 0 ? void 0 : _a.getAuthContext()) !== null && _b !== void 0 ? _b : null;
|
||||||
|
}
|
||||||
|
_read(_size) {
|
||||||
|
var _a;
|
||||||
|
(_a = this.call) === null || _a === void 0 ? void 0 : _a.startRead();
|
||||||
|
}
|
||||||
|
_write(chunk, encoding, cb) {
|
||||||
|
var _a;
|
||||||
|
const context = {
|
||||||
|
callback: cb,
|
||||||
|
};
|
||||||
|
const flags = Number(encoding);
|
||||||
|
if (!Number.isNaN(flags)) {
|
||||||
|
context.flags = flags;
|
||||||
|
}
|
||||||
|
(_a = this.call) === null || _a === void 0 ? void 0 : _a.sendMessageWithContext(context, chunk);
|
||||||
|
}
|
||||||
|
_final(cb) {
|
||||||
|
var _a;
|
||||||
|
(_a = this.call) === null || _a === void 0 ? void 0 : _a.halfClose();
|
||||||
|
cb();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.ClientDuplexStreamImpl = ClientDuplexStreamImpl;
|
||||||
|
//# sourceMappingURL=call.js.map
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"call.js","sourceRoot":"","sources":["../../src/call.ts"],"names":[],"mappings":"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"}
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
export interface CaCertificateUpdate {
|
||||||
|
caCertificate: Buffer;
|
||||||
|
}
|
||||||
|
export interface IdentityCertificateUpdate {
|
||||||
|
certificate: Buffer;
|
||||||
|
privateKey: Buffer;
|
||||||
|
}
|
||||||
|
export interface CaCertificateUpdateListener {
|
||||||
|
(update: CaCertificateUpdate | null): void;
|
||||||
|
}
|
||||||
|
export interface IdentityCertificateUpdateListener {
|
||||||
|
(update: IdentityCertificateUpdate | null): void;
|
||||||
|
}
|
||||||
|
export interface CertificateProvider {
|
||||||
|
addCaCertificateListener(listener: CaCertificateUpdateListener): void;
|
||||||
|
removeCaCertificateListener(listener: CaCertificateUpdateListener): void;
|
||||||
|
addIdentityCertificateListener(listener: IdentityCertificateUpdateListener): void;
|
||||||
|
removeIdentityCertificateListener(listener: IdentityCertificateUpdateListener): void;
|
||||||
|
}
|
||||||
|
export interface FileWatcherCertificateProviderConfig {
|
||||||
|
certificateFile?: string | undefined;
|
||||||
|
privateKeyFile?: string | undefined;
|
||||||
|
caCertificateFile?: string | undefined;
|
||||||
|
refreshIntervalMs: number;
|
||||||
|
}
|
||||||
|
export declare class FileWatcherCertificateProvider implements CertificateProvider {
|
||||||
|
private config;
|
||||||
|
private refreshTimer;
|
||||||
|
private fileResultPromise;
|
||||||
|
private latestCaUpdate;
|
||||||
|
private caListeners;
|
||||||
|
private latestIdentityUpdate;
|
||||||
|
private identityListeners;
|
||||||
|
private lastUpdateTime;
|
||||||
|
constructor(config: FileWatcherCertificateProviderConfig);
|
||||||
|
private updateCertificates;
|
||||||
|
private maybeStartWatchingFiles;
|
||||||
|
private maybeStopWatchingFiles;
|
||||||
|
addCaCertificateListener(listener: CaCertificateUpdateListener): void;
|
||||||
|
removeCaCertificateListener(listener: CaCertificateUpdateListener): void;
|
||||||
|
addIdentityCertificateListener(listener: IdentityCertificateUpdateListener): void;
|
||||||
|
removeIdentityCertificateListener(listener: IdentityCertificateUpdateListener): void;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,141 @@
|
||||||
|
"use strict";
|
||||||
|
/*
|
||||||
|
* Copyright 2024 gRPC 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
|
||||||
|
*
|
||||||
|
* http://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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.FileWatcherCertificateProvider = void 0;
|
||||||
|
const fs = require("fs");
|
||||||
|
const logging = require("./logging");
|
||||||
|
const constants_1 = require("./constants");
|
||||||
|
const util_1 = require("util");
|
||||||
|
const TRACER_NAME = 'certificate_provider';
|
||||||
|
function trace(text) {
|
||||||
|
logging.trace(constants_1.LogVerbosity.DEBUG, TRACER_NAME, text);
|
||||||
|
}
|
||||||
|
const readFilePromise = (0, util_1.promisify)(fs.readFile);
|
||||||
|
class FileWatcherCertificateProvider {
|
||||||
|
constructor(config) {
|
||||||
|
this.config = config;
|
||||||
|
this.refreshTimer = null;
|
||||||
|
this.fileResultPromise = null;
|
||||||
|
this.latestCaUpdate = undefined;
|
||||||
|
this.caListeners = new Set();
|
||||||
|
this.latestIdentityUpdate = undefined;
|
||||||
|
this.identityListeners = new Set();
|
||||||
|
this.lastUpdateTime = null;
|
||||||
|
if ((config.certificateFile === undefined) !== (config.privateKeyFile === undefined)) {
|
||||||
|
throw new Error('certificateFile and privateKeyFile must be set or unset together');
|
||||||
|
}
|
||||||
|
if (config.certificateFile === undefined && config.caCertificateFile === undefined) {
|
||||||
|
throw new Error('At least one of certificateFile and caCertificateFile must be set');
|
||||||
|
}
|
||||||
|
trace('File watcher constructed with config ' + JSON.stringify(config));
|
||||||
|
}
|
||||||
|
updateCertificates() {
|
||||||
|
if (this.fileResultPromise) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.fileResultPromise = Promise.allSettled([
|
||||||
|
this.config.certificateFile ? readFilePromise(this.config.certificateFile) : Promise.reject(),
|
||||||
|
this.config.privateKeyFile ? readFilePromise(this.config.privateKeyFile) : Promise.reject(),
|
||||||
|
this.config.caCertificateFile ? readFilePromise(this.config.caCertificateFile) : Promise.reject()
|
||||||
|
]);
|
||||||
|
this.fileResultPromise.then(([certificateResult, privateKeyResult, caCertificateResult]) => {
|
||||||
|
if (!this.refreshTimer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
trace('File watcher read certificates certificate ' + certificateResult.status + ', privateKey ' + privateKeyResult.status + ', CA certificate ' + caCertificateResult.status);
|
||||||
|
this.lastUpdateTime = new Date();
|
||||||
|
this.fileResultPromise = null;
|
||||||
|
if (certificateResult.status === 'fulfilled' && privateKeyResult.status === 'fulfilled') {
|
||||||
|
this.latestIdentityUpdate = {
|
||||||
|
certificate: certificateResult.value,
|
||||||
|
privateKey: privateKeyResult.value
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.latestIdentityUpdate = null;
|
||||||
|
}
|
||||||
|
if (caCertificateResult.status === 'fulfilled') {
|
||||||
|
this.latestCaUpdate = {
|
||||||
|
caCertificate: caCertificateResult.value
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.latestCaUpdate = null;
|
||||||
|
}
|
||||||
|
for (const listener of this.identityListeners) {
|
||||||
|
listener(this.latestIdentityUpdate);
|
||||||
|
}
|
||||||
|
for (const listener of this.caListeners) {
|
||||||
|
listener(this.latestCaUpdate);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
trace('File watcher initiated certificate update');
|
||||||
|
}
|
||||||
|
maybeStartWatchingFiles() {
|
||||||
|
if (!this.refreshTimer) {
|
||||||
|
/* Perform the first read immediately, but only if there was not already
|
||||||
|
* a recent read, to avoid reading from the filesystem significantly more
|
||||||
|
* frequently than configured if the provider quickly switches between
|
||||||
|
* used and unused. */
|
||||||
|
const timeSinceLastUpdate = this.lastUpdateTime ? (new Date()).getTime() - this.lastUpdateTime.getTime() : Infinity;
|
||||||
|
if (timeSinceLastUpdate > this.config.refreshIntervalMs) {
|
||||||
|
this.updateCertificates();
|
||||||
|
}
|
||||||
|
if (timeSinceLastUpdate > this.config.refreshIntervalMs * 2) {
|
||||||
|
// Clear out old updates if they are definitely stale
|
||||||
|
this.latestCaUpdate = undefined;
|
||||||
|
this.latestIdentityUpdate = undefined;
|
||||||
|
}
|
||||||
|
this.refreshTimer = setInterval(() => this.updateCertificates(), this.config.refreshIntervalMs);
|
||||||
|
trace('File watcher started watching');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
maybeStopWatchingFiles() {
|
||||||
|
if (this.caListeners.size === 0 && this.identityListeners.size === 0) {
|
||||||
|
this.fileResultPromise = null;
|
||||||
|
if (this.refreshTimer) {
|
||||||
|
clearInterval(this.refreshTimer);
|
||||||
|
this.refreshTimer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addCaCertificateListener(listener) {
|
||||||
|
this.caListeners.add(listener);
|
||||||
|
this.maybeStartWatchingFiles();
|
||||||
|
if (this.latestCaUpdate !== undefined) {
|
||||||
|
process.nextTick(listener, this.latestCaUpdate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
removeCaCertificateListener(listener) {
|
||||||
|
this.caListeners.delete(listener);
|
||||||
|
this.maybeStopWatchingFiles();
|
||||||
|
}
|
||||||
|
addIdentityCertificateListener(listener) {
|
||||||
|
this.identityListeners.add(listener);
|
||||||
|
this.maybeStartWatchingFiles();
|
||||||
|
if (this.latestIdentityUpdate !== undefined) {
|
||||||
|
process.nextTick(listener, this.latestIdentityUpdate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
removeIdentityCertificateListener(listener) {
|
||||||
|
this.identityListeners.delete(listener);
|
||||||
|
this.maybeStopWatchingFiles();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.FileWatcherCertificateProvider = FileWatcherCertificateProvider;
|
||||||
|
//# sourceMappingURL=certificate-provider.js.map
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"certificate-provider.js","sourceRoot":"","sources":["../../src/certificate-provider.ts"],"names":[],"mappings":"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"}
|
||||||
|
|
@ -0,0 +1,119 @@
|
||||||
|
import { PeerCertificate, SecureContext } from 'tls';
|
||||||
|
import { CallCredentials } from './call-credentials';
|
||||||
|
import { CertificateProvider } from './certificate-provider';
|
||||||
|
import { Socket } from 'net';
|
||||||
|
import { ChannelOptions } from './channel-options';
|
||||||
|
import { GrpcUri } from './uri-parser';
|
||||||
|
/**
|
||||||
|
* A callback that will receive the expected hostname and presented peer
|
||||||
|
* certificate as parameters. The callback should return an error to
|
||||||
|
* indicate that the presented certificate is considered invalid and
|
||||||
|
* otherwise returned undefined.
|
||||||
|
*/
|
||||||
|
export type CheckServerIdentityCallback = (hostname: string, cert: PeerCertificate) => Error | undefined;
|
||||||
|
/**
|
||||||
|
* Additional peer verification options that can be set when creating
|
||||||
|
* SSL credentials.
|
||||||
|
*/
|
||||||
|
export interface VerifyOptions {
|
||||||
|
/**
|
||||||
|
* If set, this callback will be invoked after the usual hostname verification
|
||||||
|
* has been performed on the peer certificate.
|
||||||
|
*/
|
||||||
|
checkServerIdentity?: CheckServerIdentityCallback;
|
||||||
|
rejectUnauthorized?: boolean;
|
||||||
|
}
|
||||||
|
export interface SecureConnectResult {
|
||||||
|
socket: Socket;
|
||||||
|
secure: boolean;
|
||||||
|
}
|
||||||
|
export interface SecureConnector {
|
||||||
|
connect(socket: Socket): Promise<SecureConnectResult>;
|
||||||
|
waitForReady(): Promise<void>;
|
||||||
|
getCallCredentials(): CallCredentials;
|
||||||
|
destroy(): void;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* A class that contains credentials for communicating over a channel, as well
|
||||||
|
* as a set of per-call credentials, which are applied to every method call made
|
||||||
|
* over a channel initialized with an instance of this class.
|
||||||
|
*/
|
||||||
|
export declare abstract class ChannelCredentials {
|
||||||
|
/**
|
||||||
|
* Returns a copy of this object with the included set of per-call credentials
|
||||||
|
* expanded to include callCredentials.
|
||||||
|
* @param callCredentials A CallCredentials object to associate with this
|
||||||
|
* instance.
|
||||||
|
*/
|
||||||
|
compose(callCredentials: CallCredentials): ChannelCredentials;
|
||||||
|
/**
|
||||||
|
* Indicates whether this credentials object creates a secure channel.
|
||||||
|
*/
|
||||||
|
abstract _isSecure(): boolean;
|
||||||
|
/**
|
||||||
|
* Check whether two channel credentials objects are equal. Two secure
|
||||||
|
* credentials are equal if they were constructed with the same parameters.
|
||||||
|
* @param other The other ChannelCredentials Object
|
||||||
|
*/
|
||||||
|
abstract _equals(other: ChannelCredentials): boolean;
|
||||||
|
abstract _createSecureConnector(channelTarget: GrpcUri, options: ChannelOptions, callCredentials?: CallCredentials): SecureConnector;
|
||||||
|
/**
|
||||||
|
* Return a new ChannelCredentials instance with a given set of credentials.
|
||||||
|
* The resulting instance can be used to construct a Channel that communicates
|
||||||
|
* over TLS.
|
||||||
|
* @param rootCerts The root certificate data.
|
||||||
|
* @param privateKey The client certificate private key, if available.
|
||||||
|
* @param certChain The client certificate key chain, if available.
|
||||||
|
* @param verifyOptions Additional options to modify certificate verification
|
||||||
|
*/
|
||||||
|
static createSsl(rootCerts?: Buffer | null, privateKey?: Buffer | null, certChain?: Buffer | null, verifyOptions?: VerifyOptions): ChannelCredentials;
|
||||||
|
/**
|
||||||
|
* Return a new ChannelCredentials instance with credentials created using
|
||||||
|
* the provided secureContext. The resulting instances can be used to
|
||||||
|
* construct a Channel that communicates over TLS. gRPC will not override
|
||||||
|
* anything in the provided secureContext, so the environment variables
|
||||||
|
* GRPC_SSL_CIPHER_SUITES and GRPC_DEFAULT_SSL_ROOTS_FILE_PATH will
|
||||||
|
* not be applied.
|
||||||
|
* @param secureContext The return value of tls.createSecureContext()
|
||||||
|
* @param verifyOptions Additional options to modify certificate verification
|
||||||
|
*/
|
||||||
|
static createFromSecureContext(secureContext: SecureContext, verifyOptions?: VerifyOptions): ChannelCredentials;
|
||||||
|
/**
|
||||||
|
* Return a new ChannelCredentials instance with no credentials.
|
||||||
|
*/
|
||||||
|
static createInsecure(): ChannelCredentials;
|
||||||
|
}
|
||||||
|
declare class CertificateProviderChannelCredentialsImpl extends ChannelCredentials {
|
||||||
|
private caCertificateProvider;
|
||||||
|
private identityCertificateProvider;
|
||||||
|
private verifyOptions;
|
||||||
|
private refcount;
|
||||||
|
/**
|
||||||
|
* `undefined` means that the certificates have not yet been loaded. `null`
|
||||||
|
* means that an attempt to load them has completed, and has failed.
|
||||||
|
*/
|
||||||
|
private latestCaUpdate;
|
||||||
|
/**
|
||||||
|
* `undefined` means that the certificates have not yet been loaded. `null`
|
||||||
|
* means that an attempt to load them has completed, and has failed.
|
||||||
|
*/
|
||||||
|
private latestIdentityUpdate;
|
||||||
|
private caCertificateUpdateListener;
|
||||||
|
private identityCertificateUpdateListener;
|
||||||
|
private secureContextWatchers;
|
||||||
|
private static SecureConnectorImpl;
|
||||||
|
constructor(caCertificateProvider: CertificateProvider, identityCertificateProvider: CertificateProvider | null, verifyOptions: VerifyOptions);
|
||||||
|
_isSecure(): boolean;
|
||||||
|
_equals(other: ChannelCredentials): boolean;
|
||||||
|
private ref;
|
||||||
|
private unref;
|
||||||
|
_createSecureConnector(channelTarget: GrpcUri, options: ChannelOptions, callCredentials?: CallCredentials): SecureConnector;
|
||||||
|
private maybeUpdateWatchers;
|
||||||
|
private handleCaCertificateUpdate;
|
||||||
|
private handleIdentityCertitificateUpdate;
|
||||||
|
private hasReceivedUpdates;
|
||||||
|
private getSecureContext;
|
||||||
|
private getLatestSecureContext;
|
||||||
|
}
|
||||||
|
export declare function createCertificateProviderChannelCredentials(caCertificateProvider: CertificateProvider, identityCertificateProvider: CertificateProvider | null, verifyOptions?: VerifyOptions): CertificateProviderChannelCredentialsImpl;
|
||||||
|
export {};
|
||||||
|
|
@ -0,0 +1,430 @@
|
||||||
|
"use strict";
|
||||||
|
/*
|
||||||
|
* Copyright 2019 gRPC 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
|
||||||
|
*
|
||||||
|
* http://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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.ChannelCredentials = void 0;
|
||||||
|
exports.createCertificateProviderChannelCredentials = createCertificateProviderChannelCredentials;
|
||||||
|
const tls_1 = require("tls");
|
||||||
|
const call_credentials_1 = require("./call-credentials");
|
||||||
|
const tls_helpers_1 = require("./tls-helpers");
|
||||||
|
const uri_parser_1 = require("./uri-parser");
|
||||||
|
const resolver_1 = require("./resolver");
|
||||||
|
const logging_1 = require("./logging");
|
||||||
|
const constants_1 = require("./constants");
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
function verifyIsBufferOrNull(obj, friendlyName) {
|
||||||
|
if (obj && !(obj instanceof Buffer)) {
|
||||||
|
throw new TypeError(`${friendlyName}, if provided, must be a Buffer.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* A class that contains credentials for communicating over a channel, as well
|
||||||
|
* as a set of per-call credentials, which are applied to every method call made
|
||||||
|
* over a channel initialized with an instance of this class.
|
||||||
|
*/
|
||||||
|
class ChannelCredentials {
|
||||||
|
/**
|
||||||
|
* Returns a copy of this object with the included set of per-call credentials
|
||||||
|
* expanded to include callCredentials.
|
||||||
|
* @param callCredentials A CallCredentials object to associate with this
|
||||||
|
* instance.
|
||||||
|
*/
|
||||||
|
compose(callCredentials) {
|
||||||
|
return new ComposedChannelCredentialsImpl(this, callCredentials);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Return a new ChannelCredentials instance with a given set of credentials.
|
||||||
|
* The resulting instance can be used to construct a Channel that communicates
|
||||||
|
* over TLS.
|
||||||
|
* @param rootCerts The root certificate data.
|
||||||
|
* @param privateKey The client certificate private key, if available.
|
||||||
|
* @param certChain The client certificate key chain, if available.
|
||||||
|
* @param verifyOptions Additional options to modify certificate verification
|
||||||
|
*/
|
||||||
|
static createSsl(rootCerts, privateKey, certChain, verifyOptions) {
|
||||||
|
var _a;
|
||||||
|
verifyIsBufferOrNull(rootCerts, 'Root certificate');
|
||||||
|
verifyIsBufferOrNull(privateKey, 'Private key');
|
||||||
|
verifyIsBufferOrNull(certChain, 'Certificate chain');
|
||||||
|
if (privateKey && !certChain) {
|
||||||
|
throw new Error('Private key must be given with accompanying certificate chain');
|
||||||
|
}
|
||||||
|
if (!privateKey && certChain) {
|
||||||
|
throw new Error('Certificate chain must be given with accompanying private key');
|
||||||
|
}
|
||||||
|
const secureContext = (0, tls_1.createSecureContext)({
|
||||||
|
ca: (_a = rootCerts !== null && rootCerts !== void 0 ? rootCerts : (0, tls_helpers_1.getDefaultRootsData)()) !== null && _a !== void 0 ? _a : undefined,
|
||||||
|
key: privateKey !== null && privateKey !== void 0 ? privateKey : undefined,
|
||||||
|
cert: certChain !== null && certChain !== void 0 ? certChain : undefined,
|
||||||
|
ciphers: tls_helpers_1.CIPHER_SUITES,
|
||||||
|
});
|
||||||
|
return new SecureChannelCredentialsImpl(secureContext, verifyOptions !== null && verifyOptions !== void 0 ? verifyOptions : {});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Return a new ChannelCredentials instance with credentials created using
|
||||||
|
* the provided secureContext. The resulting instances can be used to
|
||||||
|
* construct a Channel that communicates over TLS. gRPC will not override
|
||||||
|
* anything in the provided secureContext, so the environment variables
|
||||||
|
* GRPC_SSL_CIPHER_SUITES and GRPC_DEFAULT_SSL_ROOTS_FILE_PATH will
|
||||||
|
* not be applied.
|
||||||
|
* @param secureContext The return value of tls.createSecureContext()
|
||||||
|
* @param verifyOptions Additional options to modify certificate verification
|
||||||
|
*/
|
||||||
|
static createFromSecureContext(secureContext, verifyOptions) {
|
||||||
|
return new SecureChannelCredentialsImpl(secureContext, verifyOptions !== null && verifyOptions !== void 0 ? verifyOptions : {});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Return a new ChannelCredentials instance with no credentials.
|
||||||
|
*/
|
||||||
|
static createInsecure() {
|
||||||
|
return new InsecureChannelCredentialsImpl();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.ChannelCredentials = ChannelCredentials;
|
||||||
|
class InsecureChannelCredentialsImpl extends ChannelCredentials {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
compose(callCredentials) {
|
||||||
|
throw new Error('Cannot compose insecure credentials');
|
||||||
|
}
|
||||||
|
_isSecure() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_equals(other) {
|
||||||
|
return other instanceof InsecureChannelCredentialsImpl;
|
||||||
|
}
|
||||||
|
_createSecureConnector(channelTarget, options, callCredentials) {
|
||||||
|
return {
|
||||||
|
connect(socket) {
|
||||||
|
return Promise.resolve({
|
||||||
|
socket,
|
||||||
|
secure: false
|
||||||
|
});
|
||||||
|
},
|
||||||
|
waitForReady: () => {
|
||||||
|
return Promise.resolve();
|
||||||
|
},
|
||||||
|
getCallCredentials: () => {
|
||||||
|
return callCredentials !== null && callCredentials !== void 0 ? callCredentials : call_credentials_1.CallCredentials.createEmpty();
|
||||||
|
},
|
||||||
|
destroy() { }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function getConnectionOptions(secureContext, verifyOptions, channelTarget, options) {
|
||||||
|
var _a, _b;
|
||||||
|
const connectionOptions = {
|
||||||
|
secureContext: secureContext
|
||||||
|
};
|
||||||
|
let realTarget = channelTarget;
|
||||||
|
if ('grpc.http_connect_target' in options) {
|
||||||
|
const parsedTarget = (0, uri_parser_1.parseUri)(options['grpc.http_connect_target']);
|
||||||
|
if (parsedTarget) {
|
||||||
|
realTarget = parsedTarget;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const targetPath = (0, resolver_1.getDefaultAuthority)(realTarget);
|
||||||
|
const hostPort = (0, uri_parser_1.splitHostPort)(targetPath);
|
||||||
|
const remoteHost = (_a = hostPort === null || hostPort === void 0 ? void 0 : hostPort.host) !== null && _a !== void 0 ? _a : targetPath;
|
||||||
|
connectionOptions.host = remoteHost;
|
||||||
|
if (verifyOptions.checkServerIdentity) {
|
||||||
|
connectionOptions.checkServerIdentity = verifyOptions.checkServerIdentity;
|
||||||
|
}
|
||||||
|
if (verifyOptions.rejectUnauthorized !== undefined) {
|
||||||
|
connectionOptions.rejectUnauthorized = verifyOptions.rejectUnauthorized;
|
||||||
|
}
|
||||||
|
connectionOptions.ALPNProtocols = ['h2'];
|
||||||
|
if (options['grpc.ssl_target_name_override']) {
|
||||||
|
const sslTargetNameOverride = options['grpc.ssl_target_name_override'];
|
||||||
|
const originalCheckServerIdentity = (_b = connectionOptions.checkServerIdentity) !== null && _b !== void 0 ? _b : tls_1.checkServerIdentity;
|
||||||
|
connectionOptions.checkServerIdentity = (host, cert) => {
|
||||||
|
return originalCheckServerIdentity(sslTargetNameOverride, cert);
|
||||||
|
};
|
||||||
|
connectionOptions.servername = sslTargetNameOverride;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
connectionOptions.servername = remoteHost;
|
||||||
|
}
|
||||||
|
if (options['grpc-node.tls_enable_trace']) {
|
||||||
|
connectionOptions.enableTrace = true;
|
||||||
|
}
|
||||||
|
return connectionOptions;
|
||||||
|
}
|
||||||
|
class SecureConnectorImpl {
|
||||||
|
constructor(connectionOptions, callCredentials) {
|
||||||
|
this.connectionOptions = connectionOptions;
|
||||||
|
this.callCredentials = callCredentials;
|
||||||
|
}
|
||||||
|
connect(socket) {
|
||||||
|
const tlsConnectOptions = Object.assign({ socket: socket }, this.connectionOptions);
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const tlsSocket = (0, tls_1.connect)(tlsConnectOptions, () => {
|
||||||
|
var _a;
|
||||||
|
if (((_a = this.connectionOptions.rejectUnauthorized) !== null && _a !== void 0 ? _a : true) && !tlsSocket.authorized) {
|
||||||
|
reject(tlsSocket.authorizationError);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
resolve({
|
||||||
|
socket: tlsSocket,
|
||||||
|
secure: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
tlsSocket.on('error', (error) => {
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
waitForReady() {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
getCallCredentials() {
|
||||||
|
return this.callCredentials;
|
||||||
|
}
|
||||||
|
destroy() { }
|
||||||
|
}
|
||||||
|
class SecureChannelCredentialsImpl extends ChannelCredentials {
|
||||||
|
constructor(secureContext, verifyOptions) {
|
||||||
|
super();
|
||||||
|
this.secureContext = secureContext;
|
||||||
|
this.verifyOptions = verifyOptions;
|
||||||
|
}
|
||||||
|
_isSecure() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
_equals(other) {
|
||||||
|
if (this === other) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (other instanceof SecureChannelCredentialsImpl) {
|
||||||
|
return (this.secureContext === other.secureContext &&
|
||||||
|
this.verifyOptions.checkServerIdentity ===
|
||||||
|
other.verifyOptions.checkServerIdentity);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_createSecureConnector(channelTarget, options, callCredentials) {
|
||||||
|
const connectionOptions = getConnectionOptions(this.secureContext, this.verifyOptions, channelTarget, options);
|
||||||
|
return new SecureConnectorImpl(connectionOptions, callCredentials !== null && callCredentials !== void 0 ? callCredentials : call_credentials_1.CallCredentials.createEmpty());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class CertificateProviderChannelCredentialsImpl extends ChannelCredentials {
|
||||||
|
constructor(caCertificateProvider, identityCertificateProvider, verifyOptions) {
|
||||||
|
super();
|
||||||
|
this.caCertificateProvider = caCertificateProvider;
|
||||||
|
this.identityCertificateProvider = identityCertificateProvider;
|
||||||
|
this.verifyOptions = verifyOptions;
|
||||||
|
this.refcount = 0;
|
||||||
|
/**
|
||||||
|
* `undefined` means that the certificates have not yet been loaded. `null`
|
||||||
|
* means that an attempt to load them has completed, and has failed.
|
||||||
|
*/
|
||||||
|
this.latestCaUpdate = undefined;
|
||||||
|
/**
|
||||||
|
* `undefined` means that the certificates have not yet been loaded. `null`
|
||||||
|
* means that an attempt to load them has completed, and has failed.
|
||||||
|
*/
|
||||||
|
this.latestIdentityUpdate = undefined;
|
||||||
|
this.caCertificateUpdateListener = this.handleCaCertificateUpdate.bind(this);
|
||||||
|
this.identityCertificateUpdateListener = this.handleIdentityCertitificateUpdate.bind(this);
|
||||||
|
this.secureContextWatchers = [];
|
||||||
|
}
|
||||||
|
_isSecure() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
_equals(other) {
|
||||||
|
var _a, _b;
|
||||||
|
if (this === other) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (other instanceof CertificateProviderChannelCredentialsImpl) {
|
||||||
|
return this.caCertificateProvider === other.caCertificateProvider &&
|
||||||
|
this.identityCertificateProvider === other.identityCertificateProvider &&
|
||||||
|
((_a = this.verifyOptions) === null || _a === void 0 ? void 0 : _a.checkServerIdentity) === ((_b = other.verifyOptions) === null || _b === void 0 ? void 0 : _b.checkServerIdentity);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ref() {
|
||||||
|
var _a;
|
||||||
|
if (this.refcount === 0) {
|
||||||
|
this.caCertificateProvider.addCaCertificateListener(this.caCertificateUpdateListener);
|
||||||
|
(_a = this.identityCertificateProvider) === null || _a === void 0 ? void 0 : _a.addIdentityCertificateListener(this.identityCertificateUpdateListener);
|
||||||
|
}
|
||||||
|
this.refcount += 1;
|
||||||
|
}
|
||||||
|
unref() {
|
||||||
|
var _a;
|
||||||
|
this.refcount -= 1;
|
||||||
|
if (this.refcount === 0) {
|
||||||
|
this.caCertificateProvider.removeCaCertificateListener(this.caCertificateUpdateListener);
|
||||||
|
(_a = this.identityCertificateProvider) === null || _a === void 0 ? void 0 : _a.removeIdentityCertificateListener(this.identityCertificateUpdateListener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_createSecureConnector(channelTarget, options, callCredentials) {
|
||||||
|
this.ref();
|
||||||
|
return new CertificateProviderChannelCredentialsImpl.SecureConnectorImpl(this, channelTarget, options, callCredentials !== null && callCredentials !== void 0 ? callCredentials : call_credentials_1.CallCredentials.createEmpty());
|
||||||
|
}
|
||||||
|
maybeUpdateWatchers() {
|
||||||
|
if (this.hasReceivedUpdates()) {
|
||||||
|
for (const watcher of this.secureContextWatchers) {
|
||||||
|
watcher(this.getLatestSecureContext());
|
||||||
|
}
|
||||||
|
this.secureContextWatchers = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
handleCaCertificateUpdate(update) {
|
||||||
|
this.latestCaUpdate = update;
|
||||||
|
this.maybeUpdateWatchers();
|
||||||
|
}
|
||||||
|
handleIdentityCertitificateUpdate(update) {
|
||||||
|
this.latestIdentityUpdate = update;
|
||||||
|
this.maybeUpdateWatchers();
|
||||||
|
}
|
||||||
|
hasReceivedUpdates() {
|
||||||
|
if (this.latestCaUpdate === undefined) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.identityCertificateProvider && this.latestIdentityUpdate === undefined) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
getSecureContext() {
|
||||||
|
if (this.hasReceivedUpdates()) {
|
||||||
|
return Promise.resolve(this.getLatestSecureContext());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
this.secureContextWatchers.push(resolve);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getLatestSecureContext() {
|
||||||
|
var _a, _b;
|
||||||
|
if (!this.latestCaUpdate) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (this.identityCertificateProvider !== null && !this.latestIdentityUpdate) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return (0, tls_1.createSecureContext)({
|
||||||
|
ca: this.latestCaUpdate.caCertificate,
|
||||||
|
key: (_a = this.latestIdentityUpdate) === null || _a === void 0 ? void 0 : _a.privateKey,
|
||||||
|
cert: (_b = this.latestIdentityUpdate) === null || _b === void 0 ? void 0 : _b.certificate,
|
||||||
|
ciphers: tls_helpers_1.CIPHER_SUITES
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
(0, logging_1.log)(constants_1.LogVerbosity.ERROR, 'Failed to createSecureContext with error ' + e.message);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CertificateProviderChannelCredentialsImpl.SecureConnectorImpl = class {
|
||||||
|
constructor(parent, channelTarget, options, callCredentials) {
|
||||||
|
this.parent = parent;
|
||||||
|
this.channelTarget = channelTarget;
|
||||||
|
this.options = options;
|
||||||
|
this.callCredentials = callCredentials;
|
||||||
|
}
|
||||||
|
connect(socket) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const secureContext = this.parent.getLatestSecureContext();
|
||||||
|
if (!secureContext) {
|
||||||
|
reject(new Error('Failed to load credentials'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (socket.closed) {
|
||||||
|
reject(new Error('Socket closed while loading credentials'));
|
||||||
|
}
|
||||||
|
const connnectionOptions = getConnectionOptions(secureContext, this.parent.verifyOptions, this.channelTarget, this.options);
|
||||||
|
const tlsConnectOptions = Object.assign({ socket: socket }, connnectionOptions);
|
||||||
|
const closeCallback = () => {
|
||||||
|
reject(new Error('Socket closed'));
|
||||||
|
};
|
||||||
|
const errorCallback = (error) => {
|
||||||
|
reject(error);
|
||||||
|
};
|
||||||
|
const tlsSocket = (0, tls_1.connect)(tlsConnectOptions, () => {
|
||||||
|
var _a;
|
||||||
|
tlsSocket.removeListener('close', closeCallback);
|
||||||
|
tlsSocket.removeListener('error', errorCallback);
|
||||||
|
if (((_a = this.parent.verifyOptions.rejectUnauthorized) !== null && _a !== void 0 ? _a : true) && !tlsSocket.authorized) {
|
||||||
|
reject(tlsSocket.authorizationError);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
resolve({
|
||||||
|
socket: tlsSocket,
|
||||||
|
secure: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
tlsSocket.once('close', closeCallback);
|
||||||
|
tlsSocket.once('error', errorCallback);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async waitForReady() {
|
||||||
|
await this.parent.getSecureContext();
|
||||||
|
}
|
||||||
|
getCallCredentials() {
|
||||||
|
return this.callCredentials;
|
||||||
|
}
|
||||||
|
destroy() {
|
||||||
|
this.parent.unref();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
function createCertificateProviderChannelCredentials(caCertificateProvider, identityCertificateProvider, verifyOptions) {
|
||||||
|
return new CertificateProviderChannelCredentialsImpl(caCertificateProvider, identityCertificateProvider, verifyOptions !== null && verifyOptions !== void 0 ? verifyOptions : {});
|
||||||
|
}
|
||||||
|
class ComposedChannelCredentialsImpl extends ChannelCredentials {
|
||||||
|
constructor(channelCredentials, callCredentials) {
|
||||||
|
super();
|
||||||
|
this.channelCredentials = channelCredentials;
|
||||||
|
this.callCredentials = callCredentials;
|
||||||
|
if (!channelCredentials._isSecure()) {
|
||||||
|
throw new Error('Cannot compose insecure credentials');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
compose(callCredentials) {
|
||||||
|
const combinedCallCredentials = this.callCredentials.compose(callCredentials);
|
||||||
|
return new ComposedChannelCredentialsImpl(this.channelCredentials, combinedCallCredentials);
|
||||||
|
}
|
||||||
|
_isSecure() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
_equals(other) {
|
||||||
|
if (this === other) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (other instanceof ComposedChannelCredentialsImpl) {
|
||||||
|
return (this.channelCredentials._equals(other.channelCredentials) &&
|
||||||
|
this.callCredentials._equals(other.callCredentials));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_createSecureConnector(channelTarget, options, callCredentials) {
|
||||||
|
const combinedCallCredentials = this.callCredentials.compose(callCredentials !== null && callCredentials !== void 0 ? callCredentials : call_credentials_1.CallCredentials.createEmpty());
|
||||||
|
return this.channelCredentials._createSecureConnector(channelTarget, options, combinedCallCredentials);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//# sourceMappingURL=channel-credentials.js.map
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,81 @@
|
||||||
|
import { CompressionAlgorithms } from './compression-algorithms';
|
||||||
|
/**
|
||||||
|
* An interface that contains options used when initializing a Channel instance.
|
||||||
|
*/
|
||||||
|
export interface ChannelOptions {
|
||||||
|
'grpc.ssl_target_name_override'?: string;
|
||||||
|
'grpc.primary_user_agent'?: string;
|
||||||
|
'grpc.secondary_user_agent'?: string;
|
||||||
|
'grpc.default_authority'?: string;
|
||||||
|
'grpc.keepalive_time_ms'?: number;
|
||||||
|
'grpc.keepalive_timeout_ms'?: number;
|
||||||
|
'grpc.keepalive_permit_without_calls'?: number;
|
||||||
|
'grpc.service_config'?: string;
|
||||||
|
'grpc.max_concurrent_streams'?: number;
|
||||||
|
'grpc.initial_reconnect_backoff_ms'?: number;
|
||||||
|
'grpc.max_reconnect_backoff_ms'?: number;
|
||||||
|
'grpc.use_local_subchannel_pool'?: number;
|
||||||
|
'grpc.max_send_message_length'?: number;
|
||||||
|
'grpc.max_receive_message_length'?: number;
|
||||||
|
'grpc.enable_http_proxy'?: number;
|
||||||
|
'grpc.http_connect_target'?: string;
|
||||||
|
'grpc.http_connect_creds'?: string;
|
||||||
|
'grpc.default_compression_algorithm'?: CompressionAlgorithms;
|
||||||
|
'grpc.enable_channelz'?: number;
|
||||||
|
'grpc.dns_min_time_between_resolutions_ms'?: number;
|
||||||
|
'grpc.enable_retries'?: number;
|
||||||
|
'grpc.per_rpc_retry_buffer_size'?: number;
|
||||||
|
'grpc.retry_buffer_size'?: number;
|
||||||
|
'grpc.max_connection_age_ms'?: number;
|
||||||
|
'grpc.max_connection_age_grace_ms'?: number;
|
||||||
|
'grpc.max_connection_idle_ms'?: number;
|
||||||
|
'grpc-node.max_session_memory'?: number;
|
||||||
|
'grpc.service_config_disable_resolution'?: number;
|
||||||
|
'grpc.client_idle_timeout_ms'?: number;
|
||||||
|
/**
|
||||||
|
* Set the enableTrace option in TLS clients and servers
|
||||||
|
*/
|
||||||
|
'grpc-node.tls_enable_trace'?: number;
|
||||||
|
'grpc.lb.ring_hash.ring_size_cap'?: number;
|
||||||
|
'grpc-node.retry_max_attempts_limit'?: number;
|
||||||
|
'grpc-node.flow_control_window'?: number;
|
||||||
|
'grpc.server_call_metric_recording'?: number;
|
||||||
|
[key: string]: any;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* This is for checking provided options at runtime. This is an object for
|
||||||
|
* easier membership checking.
|
||||||
|
*/
|
||||||
|
export declare const recognizedOptions: {
|
||||||
|
'grpc.ssl_target_name_override': boolean;
|
||||||
|
'grpc.primary_user_agent': boolean;
|
||||||
|
'grpc.secondary_user_agent': boolean;
|
||||||
|
'grpc.default_authority': boolean;
|
||||||
|
'grpc.keepalive_time_ms': boolean;
|
||||||
|
'grpc.keepalive_timeout_ms': boolean;
|
||||||
|
'grpc.keepalive_permit_without_calls': boolean;
|
||||||
|
'grpc.service_config': boolean;
|
||||||
|
'grpc.max_concurrent_streams': boolean;
|
||||||
|
'grpc.initial_reconnect_backoff_ms': boolean;
|
||||||
|
'grpc.max_reconnect_backoff_ms': boolean;
|
||||||
|
'grpc.use_local_subchannel_pool': boolean;
|
||||||
|
'grpc.max_send_message_length': boolean;
|
||||||
|
'grpc.max_receive_message_length': boolean;
|
||||||
|
'grpc.enable_http_proxy': boolean;
|
||||||
|
'grpc.enable_channelz': boolean;
|
||||||
|
'grpc.dns_min_time_between_resolutions_ms': boolean;
|
||||||
|
'grpc.enable_retries': boolean;
|
||||||
|
'grpc.per_rpc_retry_buffer_size': boolean;
|
||||||
|
'grpc.retry_buffer_size': boolean;
|
||||||
|
'grpc.max_connection_age_ms': boolean;
|
||||||
|
'grpc.max_connection_age_grace_ms': boolean;
|
||||||
|
'grpc-node.max_session_memory': boolean;
|
||||||
|
'grpc.service_config_disable_resolution': boolean;
|
||||||
|
'grpc.client_idle_timeout_ms': boolean;
|
||||||
|
'grpc-node.tls_enable_trace': boolean;
|
||||||
|
'grpc.lb.ring_hash.ring_size_cap': boolean;
|
||||||
|
'grpc-node.retry_max_attempts_limit': boolean;
|
||||||
|
'grpc-node.flow_control_window': boolean;
|
||||||
|
'grpc.server_call_metric_recording': boolean;
|
||||||
|
};
|
||||||
|
export declare function channelOptionsEqual(options1: ChannelOptions, options2: ChannelOptions): boolean;
|
||||||
|
|
@ -0,0 +1,73 @@
|
||||||
|
"use strict";
|
||||||
|
/*
|
||||||
|
* Copyright 2019 gRPC 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
|
||||||
|
*
|
||||||
|
* http://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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.recognizedOptions = void 0;
|
||||||
|
exports.channelOptionsEqual = channelOptionsEqual;
|
||||||
|
/**
|
||||||
|
* This is for checking provided options at runtime. This is an object for
|
||||||
|
* easier membership checking.
|
||||||
|
*/
|
||||||
|
exports.recognizedOptions = {
|
||||||
|
'grpc.ssl_target_name_override': true,
|
||||||
|
'grpc.primary_user_agent': true,
|
||||||
|
'grpc.secondary_user_agent': true,
|
||||||
|
'grpc.default_authority': true,
|
||||||
|
'grpc.keepalive_time_ms': true,
|
||||||
|
'grpc.keepalive_timeout_ms': true,
|
||||||
|
'grpc.keepalive_permit_without_calls': true,
|
||||||
|
'grpc.service_config': true,
|
||||||
|
'grpc.max_concurrent_streams': true,
|
||||||
|
'grpc.initial_reconnect_backoff_ms': true,
|
||||||
|
'grpc.max_reconnect_backoff_ms': true,
|
||||||
|
'grpc.use_local_subchannel_pool': true,
|
||||||
|
'grpc.max_send_message_length': true,
|
||||||
|
'grpc.max_receive_message_length': true,
|
||||||
|
'grpc.enable_http_proxy': true,
|
||||||
|
'grpc.enable_channelz': true,
|
||||||
|
'grpc.dns_min_time_between_resolutions_ms': true,
|
||||||
|
'grpc.enable_retries': true,
|
||||||
|
'grpc.per_rpc_retry_buffer_size': true,
|
||||||
|
'grpc.retry_buffer_size': true,
|
||||||
|
'grpc.max_connection_age_ms': true,
|
||||||
|
'grpc.max_connection_age_grace_ms': true,
|
||||||
|
'grpc-node.max_session_memory': true,
|
||||||
|
'grpc.service_config_disable_resolution': true,
|
||||||
|
'grpc.client_idle_timeout_ms': true,
|
||||||
|
'grpc-node.tls_enable_trace': true,
|
||||||
|
'grpc.lb.ring_hash.ring_size_cap': true,
|
||||||
|
'grpc-node.retry_max_attempts_limit': true,
|
||||||
|
'grpc-node.flow_control_window': true,
|
||||||
|
'grpc.server_call_metric_recording': true
|
||||||
|
};
|
||||||
|
function channelOptionsEqual(options1, options2) {
|
||||||
|
const keys1 = Object.keys(options1).sort();
|
||||||
|
const keys2 = Object.keys(options2).sort();
|
||||||
|
if (keys1.length !== keys2.length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (let i = 0; i < keys1.length; i += 1) {
|
||||||
|
if (keys1[i] !== keys2[i]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (options1[keys1[i]] !== options2[keys2[i]]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//# sourceMappingURL=channel-options.js.map
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"channel-options.js","sourceRoot":"","sources":["../../src/channel-options.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;;AA8FH,kDAkBC;AAvDD;;;GAGG;AACU,QAAA,iBAAiB,GAAG;IAC/B,+BAA+B,EAAE,IAAI;IACrC,yBAAyB,EAAE,IAAI;IAC/B,2BAA2B,EAAE,IAAI;IACjC,wBAAwB,EAAE,IAAI;IAC9B,wBAAwB,EAAE,IAAI;IAC9B,2BAA2B,EAAE,IAAI;IACjC,qCAAqC,EAAE,IAAI;IAC3C,qBAAqB,EAAE,IAAI;IAC3B,6BAA6B,EAAE,IAAI;IACnC,mCAAmC,EAAE,IAAI;IACzC,+BAA+B,EAAE,IAAI;IACrC,gCAAgC,EAAE,IAAI;IACtC,8BAA8B,EAAE,IAAI;IACpC,iCAAiC,EAAE,IAAI;IACvC,wBAAwB,EAAE,IAAI;IAC9B,sBAAsB,EAAE,IAAI;IAC5B,0CAA0C,EAAE,IAAI;IAChD,qBAAqB,EAAE,IAAI;IAC3B,gCAAgC,EAAE,IAAI;IACtC,wBAAwB,EAAE,IAAI;IAC9B,4BAA4B,EAAE,IAAI;IAClC,kCAAkC,EAAE,IAAI;IACxC,8BAA8B,EAAE,IAAI;IACpC,wCAAwC,EAAE,IAAI;IAC9C,6BAA6B,EAAE,IAAI;IACnC,4BAA4B,EAAE,IAAI;IAClC,iCAAiC,EAAE,IAAI;IACvC,oCAAoC,EAAE,IAAI;IAC1C,+BAA+B,EAAE,IAAI;IACrC,mCAAmC,EAAE,IAAI;CAC1C,CAAC;AAEF,SAAgB,mBAAmB,CACjC,QAAwB,EACxB,QAAwB;IAExB,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3C,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3C,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC;QAClC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACzC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YAC1B,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9C,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
import { ChannelCredentials } from './channel-credentials';
|
||||||
|
import { ChannelOptions } from './channel-options';
|
||||||
|
import { ServerSurfaceCall } from './server-call';
|
||||||
|
import { ConnectivityState } from './connectivity-state';
|
||||||
|
import type { ChannelRef } from './channelz';
|
||||||
|
import { Call } from './call-interface';
|
||||||
|
import { Deadline } from './deadline';
|
||||||
|
/**
|
||||||
|
* An interface that represents a communication channel to a server specified
|
||||||
|
* by a given address.
|
||||||
|
*/
|
||||||
|
export interface Channel {
|
||||||
|
/**
|
||||||
|
* Close the channel. This has the same functionality as the existing
|
||||||
|
* grpc.Client.prototype.close
|
||||||
|
*/
|
||||||
|
close(): void;
|
||||||
|
/**
|
||||||
|
* Return the target that this channel connects to
|
||||||
|
*/
|
||||||
|
getTarget(): string;
|
||||||
|
/**
|
||||||
|
* Get the channel's current connectivity state. This method is here mainly
|
||||||
|
* because it is in the existing internal Channel class, and there isn't
|
||||||
|
* another good place to put it.
|
||||||
|
* @param tryToConnect If true, the channel will start connecting if it is
|
||||||
|
* idle. Otherwise, idle channels will only start connecting when a
|
||||||
|
* call starts.
|
||||||
|
*/
|
||||||
|
getConnectivityState(tryToConnect: boolean): ConnectivityState;
|
||||||
|
/**
|
||||||
|
* Watch for connectivity state changes. This is also here mainly because
|
||||||
|
* it is in the existing external Channel class.
|
||||||
|
* @param currentState The state to watch for transitions from. This should
|
||||||
|
* always be populated by calling getConnectivityState immediately
|
||||||
|
* before.
|
||||||
|
* @param deadline A deadline for waiting for a state change
|
||||||
|
* @param callback Called with no error when a state change, or with an
|
||||||
|
* error if the deadline passes without a state change.
|
||||||
|
*/
|
||||||
|
watchConnectivityState(currentState: ConnectivityState, deadline: Date | number, callback: (error?: Error) => void): void;
|
||||||
|
/**
|
||||||
|
* Get the channelz reference object for this channel. A request to the
|
||||||
|
* channelz service for the id in this object will provide information
|
||||||
|
* about this channel.
|
||||||
|
*/
|
||||||
|
getChannelzRef(): ChannelRef;
|
||||||
|
/**
|
||||||
|
* Create a call object. Call is an opaque type that is used by the Client
|
||||||
|
* class. This function is called by the gRPC library when starting a
|
||||||
|
* request. Implementers should return an instance of Call that is returned
|
||||||
|
* from calling createCall on an instance of the provided Channel class.
|
||||||
|
* @param method The full method string to request.
|
||||||
|
* @param deadline The call deadline
|
||||||
|
* @param host A host string override for making the request
|
||||||
|
* @param parentCall A server call to propagate some information from
|
||||||
|
* @param propagateFlags A bitwise combination of elements of grpc.propagate
|
||||||
|
* that indicates what information to propagate from parentCall.
|
||||||
|
*/
|
||||||
|
createCall(method: string, deadline: Deadline, host: string | null | undefined, parentCall: ServerSurfaceCall | null, propagateFlags: number | null | undefined): Call;
|
||||||
|
}
|
||||||
|
export declare class ChannelImplementation implements Channel {
|
||||||
|
private internalChannel;
|
||||||
|
constructor(target: string, credentials: ChannelCredentials, options: ChannelOptions);
|
||||||
|
close(): void;
|
||||||
|
getTarget(): string;
|
||||||
|
getConnectivityState(tryToConnect: boolean): ConnectivityState;
|
||||||
|
watchConnectivityState(currentState: ConnectivityState, deadline: Date | number, callback: (error?: Error) => void): void;
|
||||||
|
/**
|
||||||
|
* Get the channelz reference object for this channel. The returned value is
|
||||||
|
* garbage if channelz is disabled for this channel.
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
getChannelzRef(): ChannelRef;
|
||||||
|
createCall(method: string, deadline: Deadline, host: string | null | undefined, parentCall: ServerSurfaceCall | null, propagateFlags: number | null | undefined): Call;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
"use strict";
|
||||||
|
/*
|
||||||
|
* Copyright 2019 gRPC 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
|
||||||
|
*
|
||||||
|
* http://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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.ChannelImplementation = void 0;
|
||||||
|
const channel_credentials_1 = require("./channel-credentials");
|
||||||
|
const internal_channel_1 = require("./internal-channel");
|
||||||
|
class ChannelImplementation {
|
||||||
|
constructor(target, credentials, options) {
|
||||||
|
if (typeof target !== 'string') {
|
||||||
|
throw new TypeError('Channel target must be a string');
|
||||||
|
}
|
||||||
|
if (!(credentials instanceof channel_credentials_1.ChannelCredentials)) {
|
||||||
|
throw new TypeError('Channel credentials must be a ChannelCredentials object');
|
||||||
|
}
|
||||||
|
if (options) {
|
||||||
|
if (typeof options !== 'object') {
|
||||||
|
throw new TypeError('Channel options must be an object');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.internalChannel = new internal_channel_1.InternalChannel(target, credentials, options);
|
||||||
|
}
|
||||||
|
close() {
|
||||||
|
this.internalChannel.close();
|
||||||
|
}
|
||||||
|
getTarget() {
|
||||||
|
return this.internalChannel.getTarget();
|
||||||
|
}
|
||||||
|
getConnectivityState(tryToConnect) {
|
||||||
|
return this.internalChannel.getConnectivityState(tryToConnect);
|
||||||
|
}
|
||||||
|
watchConnectivityState(currentState, deadline, callback) {
|
||||||
|
this.internalChannel.watchConnectivityState(currentState, deadline, callback);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Get the channelz reference object for this channel. The returned value is
|
||||||
|
* garbage if channelz is disabled for this channel.
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
getChannelzRef() {
|
||||||
|
return this.internalChannel.getChannelzRef();
|
||||||
|
}
|
||||||
|
createCall(method, deadline, host, parentCall, propagateFlags) {
|
||||||
|
if (typeof method !== 'string') {
|
||||||
|
throw new TypeError('Channel#createCall: method must be a string');
|
||||||
|
}
|
||||||
|
if (!(typeof deadline === 'number' || deadline instanceof Date)) {
|
||||||
|
throw new TypeError('Channel#createCall: deadline must be a number or Date');
|
||||||
|
}
|
||||||
|
return this.internalChannel.createCall(method, deadline, host, parentCall, propagateFlags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.ChannelImplementation = ChannelImplementation;
|
||||||
|
//# sourceMappingURL=channel.js.map
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"channel.js","sourceRoot":"","sources":["../../src/channel.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;;AAEH,+DAA2D;AAO3D,yDAAqD;AAoErD,MAAa,qBAAqB;IAGhC,YACE,MAAc,EACd,WAA+B,EAC/B,OAAuB;QAEvB,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC/B,MAAM,IAAI,SAAS,CAAC,iCAAiC,CAAC,CAAC;QACzD,CAAC;QACD,IAAI,CAAC,CAAC,WAAW,YAAY,wCAAkB,CAAC,EAAE,CAAC;YACjD,MAAM,IAAI,SAAS,CACjB,yDAAyD,CAC1D,CAAC;QACJ,CAAC;QACD,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;gBAChC,MAAM,IAAI,SAAS,CAAC,mCAAmC,CAAC,CAAC;YAC3D,CAAC;QACH,CAAC;QAED,IAAI,CAAC,eAAe,GAAG,IAAI,kCAAe,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;IAC3E,CAAC;IAED,KAAK;QACH,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;IAC/B,CAAC;IAED,SAAS;QACP,OAAO,IAAI,CAAC,eAAe,CAAC,SAAS,EAAE,CAAC;IAC1C,CAAC;IAED,oBAAoB,CAAC,YAAqB;QACxC,OAAO,IAAI,CAAC,eAAe,CAAC,oBAAoB,CAAC,YAAY,CAAC,CAAC;IACjE,CAAC;IAED,sBAAsB,CACpB,YAA+B,EAC/B,QAAuB,EACvB,QAAiC;QAEjC,IAAI,CAAC,eAAe,CAAC,sBAAsB,CACzC,YAAY,EACZ,QAAQ,EACR,QAAQ,CACT,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,cAAc;QACZ,OAAO,IAAI,CAAC,eAAe,CAAC,cAAc,EAAE,CAAC;IAC/C,CAAC;IAED,UAAU,CACR,MAAc,EACd,QAAkB,EAClB,IAA+B,EAC/B,UAAoC,EACpC,cAAyC;QAEzC,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC/B,MAAM,IAAI,SAAS,CAAC,6CAA6C,CAAC,CAAC;QACrE,CAAC;QACD,IAAI,CAAC,CAAC,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,YAAY,IAAI,CAAC,EAAE,CAAC;YAChE,MAAM,IAAI,SAAS,CACjB,uDAAuD,CACxD,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC,eAAe,CAAC,UAAU,CACpC,MAAM,EACN,QAAQ,EACR,IAAI,EACJ,UAAU,EACV,cAAc,CACf,CAAC;IACJ,CAAC;CACF;AAjFD,sDAiFC"}
|
||||||
|
|
@ -0,0 +1,158 @@
|
||||||
|
import { OrderedMap } from '@js-sdsl/ordered-map';
|
||||||
|
import { ConnectivityState } from './connectivity-state';
|
||||||
|
import { ChannelTrace } from './generated/grpc/channelz/v1/ChannelTrace';
|
||||||
|
import { SubchannelAddress } from './subchannel-address';
|
||||||
|
import { ChannelzDefinition, ChannelzHandlers } from './generated/grpc/channelz/v1/Channelz';
|
||||||
|
export type TraceSeverity = 'CT_UNKNOWN' | 'CT_INFO' | 'CT_WARNING' | 'CT_ERROR';
|
||||||
|
interface Ref {
|
||||||
|
kind: EntityTypes;
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
export interface ChannelRef extends Ref {
|
||||||
|
kind: EntityTypes.channel;
|
||||||
|
}
|
||||||
|
export interface SubchannelRef extends Ref {
|
||||||
|
kind: EntityTypes.subchannel;
|
||||||
|
}
|
||||||
|
export interface ServerRef extends Ref {
|
||||||
|
kind: EntityTypes.server;
|
||||||
|
}
|
||||||
|
export interface SocketRef extends Ref {
|
||||||
|
kind: EntityTypes.socket;
|
||||||
|
}
|
||||||
|
interface TraceEvent {
|
||||||
|
description: string;
|
||||||
|
severity: TraceSeverity;
|
||||||
|
timestamp: Date;
|
||||||
|
childChannel?: ChannelRef;
|
||||||
|
childSubchannel?: SubchannelRef;
|
||||||
|
}
|
||||||
|
export declare class ChannelzTraceStub {
|
||||||
|
readonly events: TraceEvent[];
|
||||||
|
readonly creationTimestamp: Date;
|
||||||
|
readonly eventsLogged = 0;
|
||||||
|
addTrace(): void;
|
||||||
|
getTraceMessage(): ChannelTrace;
|
||||||
|
}
|
||||||
|
export declare class ChannelzTrace {
|
||||||
|
events: TraceEvent[];
|
||||||
|
creationTimestamp: Date;
|
||||||
|
eventsLogged: number;
|
||||||
|
constructor();
|
||||||
|
addTrace(severity: TraceSeverity, description: string, child?: ChannelRef | SubchannelRef): void;
|
||||||
|
getTraceMessage(): ChannelTrace;
|
||||||
|
}
|
||||||
|
export declare class ChannelzChildrenTracker {
|
||||||
|
private channelChildren;
|
||||||
|
private subchannelChildren;
|
||||||
|
private socketChildren;
|
||||||
|
private trackerMap;
|
||||||
|
refChild(child: ChannelRef | SubchannelRef | SocketRef): void;
|
||||||
|
unrefChild(child: ChannelRef | SubchannelRef | SocketRef): void;
|
||||||
|
getChildLists(): ChannelzChildren;
|
||||||
|
}
|
||||||
|
export declare class ChannelzChildrenTrackerStub extends ChannelzChildrenTracker {
|
||||||
|
refChild(): void;
|
||||||
|
unrefChild(): void;
|
||||||
|
}
|
||||||
|
export declare class ChannelzCallTracker {
|
||||||
|
callsStarted: number;
|
||||||
|
callsSucceeded: number;
|
||||||
|
callsFailed: number;
|
||||||
|
lastCallStartedTimestamp: Date | null;
|
||||||
|
addCallStarted(): void;
|
||||||
|
addCallSucceeded(): void;
|
||||||
|
addCallFailed(): void;
|
||||||
|
}
|
||||||
|
export declare class ChannelzCallTrackerStub extends ChannelzCallTracker {
|
||||||
|
addCallStarted(): void;
|
||||||
|
addCallSucceeded(): void;
|
||||||
|
addCallFailed(): void;
|
||||||
|
}
|
||||||
|
export interface ChannelzChildren {
|
||||||
|
channels: OrderedMap<number, {
|
||||||
|
ref: ChannelRef;
|
||||||
|
count: number;
|
||||||
|
}>;
|
||||||
|
subchannels: OrderedMap<number, {
|
||||||
|
ref: SubchannelRef;
|
||||||
|
count: number;
|
||||||
|
}>;
|
||||||
|
sockets: OrderedMap<number, {
|
||||||
|
ref: SocketRef;
|
||||||
|
count: number;
|
||||||
|
}>;
|
||||||
|
}
|
||||||
|
export interface ChannelInfo {
|
||||||
|
target: string;
|
||||||
|
state: ConnectivityState;
|
||||||
|
trace: ChannelzTrace | ChannelzTraceStub;
|
||||||
|
callTracker: ChannelzCallTracker | ChannelzCallTrackerStub;
|
||||||
|
children: ChannelzChildren;
|
||||||
|
}
|
||||||
|
export type SubchannelInfo = ChannelInfo;
|
||||||
|
export interface ServerInfo {
|
||||||
|
trace: ChannelzTrace;
|
||||||
|
callTracker: ChannelzCallTracker;
|
||||||
|
listenerChildren: ChannelzChildren;
|
||||||
|
sessionChildren: ChannelzChildren;
|
||||||
|
}
|
||||||
|
export interface TlsInfo {
|
||||||
|
cipherSuiteStandardName: string | null;
|
||||||
|
cipherSuiteOtherName: string | null;
|
||||||
|
localCertificate: Buffer | null;
|
||||||
|
remoteCertificate: Buffer | null;
|
||||||
|
}
|
||||||
|
export interface SocketInfo {
|
||||||
|
localAddress: SubchannelAddress | null;
|
||||||
|
remoteAddress: SubchannelAddress | null;
|
||||||
|
security: TlsInfo | null;
|
||||||
|
remoteName: string | null;
|
||||||
|
streamsStarted: number;
|
||||||
|
streamsSucceeded: number;
|
||||||
|
streamsFailed: number;
|
||||||
|
messagesSent: number;
|
||||||
|
messagesReceived: number;
|
||||||
|
keepAlivesSent: number;
|
||||||
|
lastLocalStreamCreatedTimestamp: Date | null;
|
||||||
|
lastRemoteStreamCreatedTimestamp: Date | null;
|
||||||
|
lastMessageSentTimestamp: Date | null;
|
||||||
|
lastMessageReceivedTimestamp: Date | null;
|
||||||
|
localFlowControlWindow: number | null;
|
||||||
|
remoteFlowControlWindow: number | null;
|
||||||
|
}
|
||||||
|
interface ChannelEntry {
|
||||||
|
ref: ChannelRef;
|
||||||
|
getInfo(): ChannelInfo;
|
||||||
|
}
|
||||||
|
interface SubchannelEntry {
|
||||||
|
ref: SubchannelRef;
|
||||||
|
getInfo(): SubchannelInfo;
|
||||||
|
}
|
||||||
|
interface ServerEntry {
|
||||||
|
ref: ServerRef;
|
||||||
|
getInfo(): ServerInfo;
|
||||||
|
}
|
||||||
|
interface SocketEntry {
|
||||||
|
ref: SocketRef;
|
||||||
|
getInfo(): SocketInfo;
|
||||||
|
}
|
||||||
|
export declare const enum EntityTypes {
|
||||||
|
channel = "channel",
|
||||||
|
subchannel = "subchannel",
|
||||||
|
server = "server",
|
||||||
|
socket = "socket"
|
||||||
|
}
|
||||||
|
export type RefByType<T extends EntityTypes> = T extends EntityTypes.channel ? ChannelRef : T extends EntityTypes.server ? ServerRef : T extends EntityTypes.socket ? SocketRef : T extends EntityTypes.subchannel ? SubchannelRef : never;
|
||||||
|
export type EntryByType<T extends EntityTypes> = T extends EntityTypes.channel ? ChannelEntry : T extends EntityTypes.server ? ServerEntry : T extends EntityTypes.socket ? SocketEntry : T extends EntityTypes.subchannel ? SubchannelEntry : never;
|
||||||
|
export type InfoByType<T extends EntityTypes> = T extends EntityTypes.channel ? ChannelInfo : T extends EntityTypes.subchannel ? SubchannelInfo : T extends EntityTypes.server ? ServerInfo : T extends EntityTypes.socket ? SocketInfo : never;
|
||||||
|
export declare const registerChannelzChannel: (name: string, getInfo: () => ChannelInfo, channelzEnabled: boolean) => ChannelRef;
|
||||||
|
export declare const registerChannelzSubchannel: (name: string, getInfo: () => ChannelInfo, channelzEnabled: boolean) => SubchannelRef;
|
||||||
|
export declare const registerChannelzServer: (name: string, getInfo: () => ServerInfo, channelzEnabled: boolean) => ServerRef;
|
||||||
|
export declare const registerChannelzSocket: (name: string, getInfo: () => SocketInfo, channelzEnabled: boolean) => SocketRef;
|
||||||
|
export declare function unregisterChannelzRef(ref: ChannelRef | SubchannelRef | ServerRef | SocketRef): void;
|
||||||
|
export declare function getChannelzHandlers(): ChannelzHandlers;
|
||||||
|
export declare function getChannelzServiceDefinition(): ChannelzDefinition;
|
||||||
|
export declare function setup(): void;
|
||||||
|
export {};
|
||||||
|
|
@ -0,0 +1,598 @@
|
||||||
|
"use strict";
|
||||||
|
/*
|
||||||
|
* Copyright 2021 gRPC 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
|
||||||
|
*
|
||||||
|
* http://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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.registerChannelzSocket = exports.registerChannelzServer = exports.registerChannelzSubchannel = exports.registerChannelzChannel = exports.ChannelzCallTrackerStub = exports.ChannelzCallTracker = exports.ChannelzChildrenTrackerStub = exports.ChannelzChildrenTracker = exports.ChannelzTrace = exports.ChannelzTraceStub = void 0;
|
||||||
|
exports.unregisterChannelzRef = unregisterChannelzRef;
|
||||||
|
exports.getChannelzHandlers = getChannelzHandlers;
|
||||||
|
exports.getChannelzServiceDefinition = getChannelzServiceDefinition;
|
||||||
|
exports.setup = setup;
|
||||||
|
const net_1 = require("net");
|
||||||
|
const ordered_map_1 = require("@js-sdsl/ordered-map");
|
||||||
|
const connectivity_state_1 = require("./connectivity-state");
|
||||||
|
const constants_1 = require("./constants");
|
||||||
|
const subchannel_address_1 = require("./subchannel-address");
|
||||||
|
const admin_1 = require("./admin");
|
||||||
|
const make_client_1 = require("./make-client");
|
||||||
|
function channelRefToMessage(ref) {
|
||||||
|
return {
|
||||||
|
channel_id: ref.id,
|
||||||
|
name: ref.name,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function subchannelRefToMessage(ref) {
|
||||||
|
return {
|
||||||
|
subchannel_id: ref.id,
|
||||||
|
name: ref.name,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function serverRefToMessage(ref) {
|
||||||
|
return {
|
||||||
|
server_id: ref.id,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function socketRefToMessage(ref) {
|
||||||
|
return {
|
||||||
|
socket_id: ref.id,
|
||||||
|
name: ref.name,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* The loose upper bound on the number of events that should be retained in a
|
||||||
|
* trace. This may be exceeded by up to a factor of 2. Arbitrarily chosen as a
|
||||||
|
* number that should be large enough to contain the recent relevant
|
||||||
|
* information, but small enough to not use excessive memory.
|
||||||
|
*/
|
||||||
|
const TARGET_RETAINED_TRACES = 32;
|
||||||
|
/**
|
||||||
|
* Default number of sockets/servers/channels/subchannels to return
|
||||||
|
*/
|
||||||
|
const DEFAULT_MAX_RESULTS = 100;
|
||||||
|
class ChannelzTraceStub {
|
||||||
|
constructor() {
|
||||||
|
this.events = [];
|
||||||
|
this.creationTimestamp = new Date();
|
||||||
|
this.eventsLogged = 0;
|
||||||
|
}
|
||||||
|
addTrace() { }
|
||||||
|
getTraceMessage() {
|
||||||
|
return {
|
||||||
|
creation_timestamp: dateToProtoTimestamp(this.creationTimestamp),
|
||||||
|
num_events_logged: this.eventsLogged,
|
||||||
|
events: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.ChannelzTraceStub = ChannelzTraceStub;
|
||||||
|
class ChannelzTrace {
|
||||||
|
constructor() {
|
||||||
|
this.events = [];
|
||||||
|
this.eventsLogged = 0;
|
||||||
|
this.creationTimestamp = new Date();
|
||||||
|
}
|
||||||
|
addTrace(severity, description, child) {
|
||||||
|
const timestamp = new Date();
|
||||||
|
this.events.push({
|
||||||
|
description: description,
|
||||||
|
severity: severity,
|
||||||
|
timestamp: timestamp,
|
||||||
|
childChannel: (child === null || child === void 0 ? void 0 : child.kind) === 'channel' ? child : undefined,
|
||||||
|
childSubchannel: (child === null || child === void 0 ? void 0 : child.kind) === 'subchannel' ? child : undefined,
|
||||||
|
});
|
||||||
|
// Whenever the trace array gets too large, discard the first half
|
||||||
|
if (this.events.length >= TARGET_RETAINED_TRACES * 2) {
|
||||||
|
this.events = this.events.slice(TARGET_RETAINED_TRACES);
|
||||||
|
}
|
||||||
|
this.eventsLogged += 1;
|
||||||
|
}
|
||||||
|
getTraceMessage() {
|
||||||
|
return {
|
||||||
|
creation_timestamp: dateToProtoTimestamp(this.creationTimestamp),
|
||||||
|
num_events_logged: this.eventsLogged,
|
||||||
|
events: this.events.map(event => {
|
||||||
|
return {
|
||||||
|
description: event.description,
|
||||||
|
severity: event.severity,
|
||||||
|
timestamp: dateToProtoTimestamp(event.timestamp),
|
||||||
|
channel_ref: event.childChannel
|
||||||
|
? channelRefToMessage(event.childChannel)
|
||||||
|
: null,
|
||||||
|
subchannel_ref: event.childSubchannel
|
||||||
|
? subchannelRefToMessage(event.childSubchannel)
|
||||||
|
: null,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.ChannelzTrace = ChannelzTrace;
|
||||||
|
class ChannelzChildrenTracker {
|
||||||
|
constructor() {
|
||||||
|
this.channelChildren = new ordered_map_1.OrderedMap();
|
||||||
|
this.subchannelChildren = new ordered_map_1.OrderedMap();
|
||||||
|
this.socketChildren = new ordered_map_1.OrderedMap();
|
||||||
|
this.trackerMap = {
|
||||||
|
["channel" /* EntityTypes.channel */]: this.channelChildren,
|
||||||
|
["subchannel" /* EntityTypes.subchannel */]: this.subchannelChildren,
|
||||||
|
["socket" /* EntityTypes.socket */]: this.socketChildren,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
refChild(child) {
|
||||||
|
const tracker = this.trackerMap[child.kind];
|
||||||
|
const trackedChild = tracker.find(child.id);
|
||||||
|
if (trackedChild.equals(tracker.end())) {
|
||||||
|
tracker.setElement(child.id, {
|
||||||
|
ref: child,
|
||||||
|
count: 1,
|
||||||
|
}, trackedChild);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
trackedChild.pointer[1].count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unrefChild(child) {
|
||||||
|
const tracker = this.trackerMap[child.kind];
|
||||||
|
const trackedChild = tracker.getElementByKey(child.id);
|
||||||
|
if (trackedChild !== undefined) {
|
||||||
|
trackedChild.count -= 1;
|
||||||
|
if (trackedChild.count === 0) {
|
||||||
|
tracker.eraseElementByKey(child.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getChildLists() {
|
||||||
|
return {
|
||||||
|
channels: this.channelChildren,
|
||||||
|
subchannels: this.subchannelChildren,
|
||||||
|
sockets: this.socketChildren,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.ChannelzChildrenTracker = ChannelzChildrenTracker;
|
||||||
|
class ChannelzChildrenTrackerStub extends ChannelzChildrenTracker {
|
||||||
|
refChild() { }
|
||||||
|
unrefChild() { }
|
||||||
|
}
|
||||||
|
exports.ChannelzChildrenTrackerStub = ChannelzChildrenTrackerStub;
|
||||||
|
class ChannelzCallTracker {
|
||||||
|
constructor() {
|
||||||
|
this.callsStarted = 0;
|
||||||
|
this.callsSucceeded = 0;
|
||||||
|
this.callsFailed = 0;
|
||||||
|
this.lastCallStartedTimestamp = null;
|
||||||
|
}
|
||||||
|
addCallStarted() {
|
||||||
|
this.callsStarted += 1;
|
||||||
|
this.lastCallStartedTimestamp = new Date();
|
||||||
|
}
|
||||||
|
addCallSucceeded() {
|
||||||
|
this.callsSucceeded += 1;
|
||||||
|
}
|
||||||
|
addCallFailed() {
|
||||||
|
this.callsFailed += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.ChannelzCallTracker = ChannelzCallTracker;
|
||||||
|
class ChannelzCallTrackerStub extends ChannelzCallTracker {
|
||||||
|
addCallStarted() { }
|
||||||
|
addCallSucceeded() { }
|
||||||
|
addCallFailed() { }
|
||||||
|
}
|
||||||
|
exports.ChannelzCallTrackerStub = ChannelzCallTrackerStub;
|
||||||
|
const entityMaps = {
|
||||||
|
["channel" /* EntityTypes.channel */]: new ordered_map_1.OrderedMap(),
|
||||||
|
["subchannel" /* EntityTypes.subchannel */]: new ordered_map_1.OrderedMap(),
|
||||||
|
["server" /* EntityTypes.server */]: new ordered_map_1.OrderedMap(),
|
||||||
|
["socket" /* EntityTypes.socket */]: new ordered_map_1.OrderedMap(),
|
||||||
|
};
|
||||||
|
const generateRegisterFn = (kind) => {
|
||||||
|
let nextId = 1;
|
||||||
|
function getNextId() {
|
||||||
|
return nextId++;
|
||||||
|
}
|
||||||
|
const entityMap = entityMaps[kind];
|
||||||
|
return (name, getInfo, channelzEnabled) => {
|
||||||
|
const id = getNextId();
|
||||||
|
const ref = { id, name, kind };
|
||||||
|
if (channelzEnabled) {
|
||||||
|
entityMap.setElement(id, { ref, getInfo });
|
||||||
|
}
|
||||||
|
return ref;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
exports.registerChannelzChannel = generateRegisterFn("channel" /* EntityTypes.channel */);
|
||||||
|
exports.registerChannelzSubchannel = generateRegisterFn("subchannel" /* EntityTypes.subchannel */);
|
||||||
|
exports.registerChannelzServer = generateRegisterFn("server" /* EntityTypes.server */);
|
||||||
|
exports.registerChannelzSocket = generateRegisterFn("socket" /* EntityTypes.socket */);
|
||||||
|
function unregisterChannelzRef(ref) {
|
||||||
|
entityMaps[ref.kind].eraseElementByKey(ref.id);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Parse a single section of an IPv6 address as two bytes
|
||||||
|
* @param addressSection A hexadecimal string of length up to 4
|
||||||
|
* @returns The pair of bytes representing this address section
|
||||||
|
*/
|
||||||
|
function parseIPv6Section(addressSection) {
|
||||||
|
const numberValue = Number.parseInt(addressSection, 16);
|
||||||
|
return [(numberValue / 256) | 0, numberValue % 256];
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Parse a chunk of an IPv6 address string to some number of bytes
|
||||||
|
* @param addressChunk Some number of segments of up to 4 hexadecimal
|
||||||
|
* characters each, joined by colons.
|
||||||
|
* @returns The list of bytes representing this address chunk
|
||||||
|
*/
|
||||||
|
function parseIPv6Chunk(addressChunk) {
|
||||||
|
if (addressChunk === '') {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
const bytePairs = addressChunk
|
||||||
|
.split(':')
|
||||||
|
.map(section => parseIPv6Section(section));
|
||||||
|
const result = [];
|
||||||
|
return result.concat(...bytePairs);
|
||||||
|
}
|
||||||
|
function isIPv6MappedIPv4(ipAddress) {
|
||||||
|
return (0, net_1.isIPv6)(ipAddress) && ipAddress.toLowerCase().startsWith('::ffff:') && (0, net_1.isIPv4)(ipAddress.substring(7));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Prerequisite: isIPv4(ipAddress)
|
||||||
|
* @param ipAddress
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function ipv4AddressStringToBuffer(ipAddress) {
|
||||||
|
return Buffer.from(Uint8Array.from(ipAddress.split('.').map(segment => Number.parseInt(segment))));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Converts an IPv4 or IPv6 address from string representation to binary
|
||||||
|
* representation
|
||||||
|
* @param ipAddress an IP address in standard IPv4 or IPv6 text format
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function ipAddressStringToBuffer(ipAddress) {
|
||||||
|
if ((0, net_1.isIPv4)(ipAddress)) {
|
||||||
|
return ipv4AddressStringToBuffer(ipAddress);
|
||||||
|
}
|
||||||
|
else if (isIPv6MappedIPv4(ipAddress)) {
|
||||||
|
return ipv4AddressStringToBuffer(ipAddress.substring(7));
|
||||||
|
}
|
||||||
|
else if ((0, net_1.isIPv6)(ipAddress)) {
|
||||||
|
let leftSection;
|
||||||
|
let rightSection;
|
||||||
|
const doubleColonIndex = ipAddress.indexOf('::');
|
||||||
|
if (doubleColonIndex === -1) {
|
||||||
|
leftSection = ipAddress;
|
||||||
|
rightSection = '';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
leftSection = ipAddress.substring(0, doubleColonIndex);
|
||||||
|
rightSection = ipAddress.substring(doubleColonIndex + 2);
|
||||||
|
}
|
||||||
|
const leftBuffer = Buffer.from(parseIPv6Chunk(leftSection));
|
||||||
|
const rightBuffer = Buffer.from(parseIPv6Chunk(rightSection));
|
||||||
|
const middleBuffer = Buffer.alloc(16 - leftBuffer.length - rightBuffer.length, 0);
|
||||||
|
return Buffer.concat([leftBuffer, middleBuffer, rightBuffer]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function connectivityStateToMessage(state) {
|
||||||
|
switch (state) {
|
||||||
|
case connectivity_state_1.ConnectivityState.CONNECTING:
|
||||||
|
return {
|
||||||
|
state: 'CONNECTING',
|
||||||
|
};
|
||||||
|
case connectivity_state_1.ConnectivityState.IDLE:
|
||||||
|
return {
|
||||||
|
state: 'IDLE',
|
||||||
|
};
|
||||||
|
case connectivity_state_1.ConnectivityState.READY:
|
||||||
|
return {
|
||||||
|
state: 'READY',
|
||||||
|
};
|
||||||
|
case connectivity_state_1.ConnectivityState.SHUTDOWN:
|
||||||
|
return {
|
||||||
|
state: 'SHUTDOWN',
|
||||||
|
};
|
||||||
|
case connectivity_state_1.ConnectivityState.TRANSIENT_FAILURE:
|
||||||
|
return {
|
||||||
|
state: 'TRANSIENT_FAILURE',
|
||||||
|
};
|
||||||
|
default:
|
||||||
|
return {
|
||||||
|
state: 'UNKNOWN',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function dateToProtoTimestamp(date) {
|
||||||
|
if (!date) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const millisSinceEpoch = date.getTime();
|
||||||
|
return {
|
||||||
|
seconds: (millisSinceEpoch / 1000) | 0,
|
||||||
|
nanos: (millisSinceEpoch % 1000) * 1000000,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function getChannelMessage(channelEntry) {
|
||||||
|
const resolvedInfo = channelEntry.getInfo();
|
||||||
|
const channelRef = [];
|
||||||
|
const subchannelRef = [];
|
||||||
|
resolvedInfo.children.channels.forEach(el => {
|
||||||
|
channelRef.push(channelRefToMessage(el[1].ref));
|
||||||
|
});
|
||||||
|
resolvedInfo.children.subchannels.forEach(el => {
|
||||||
|
subchannelRef.push(subchannelRefToMessage(el[1].ref));
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
ref: channelRefToMessage(channelEntry.ref),
|
||||||
|
data: {
|
||||||
|
target: resolvedInfo.target,
|
||||||
|
state: connectivityStateToMessage(resolvedInfo.state),
|
||||||
|
calls_started: resolvedInfo.callTracker.callsStarted,
|
||||||
|
calls_succeeded: resolvedInfo.callTracker.callsSucceeded,
|
||||||
|
calls_failed: resolvedInfo.callTracker.callsFailed,
|
||||||
|
last_call_started_timestamp: dateToProtoTimestamp(resolvedInfo.callTracker.lastCallStartedTimestamp),
|
||||||
|
trace: resolvedInfo.trace.getTraceMessage(),
|
||||||
|
},
|
||||||
|
channel_ref: channelRef,
|
||||||
|
subchannel_ref: subchannelRef,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function GetChannel(call, callback) {
|
||||||
|
const channelId = parseInt(call.request.channel_id, 10);
|
||||||
|
const channelEntry = entityMaps["channel" /* EntityTypes.channel */].getElementByKey(channelId);
|
||||||
|
if (channelEntry === undefined) {
|
||||||
|
callback({
|
||||||
|
code: constants_1.Status.NOT_FOUND,
|
||||||
|
details: 'No channel data found for id ' + channelId,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
callback(null, { channel: getChannelMessage(channelEntry) });
|
||||||
|
}
|
||||||
|
function GetTopChannels(call, callback) {
|
||||||
|
const maxResults = parseInt(call.request.max_results, 10) || DEFAULT_MAX_RESULTS;
|
||||||
|
const resultList = [];
|
||||||
|
const startId = parseInt(call.request.start_channel_id, 10);
|
||||||
|
const channelEntries = entityMaps["channel" /* EntityTypes.channel */];
|
||||||
|
let i;
|
||||||
|
for (i = channelEntries.lowerBound(startId); !i.equals(channelEntries.end()) && resultList.length < maxResults; i = i.next()) {
|
||||||
|
resultList.push(getChannelMessage(i.pointer[1]));
|
||||||
|
}
|
||||||
|
callback(null, {
|
||||||
|
channel: resultList,
|
||||||
|
end: i.equals(channelEntries.end()),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function getServerMessage(serverEntry) {
|
||||||
|
const resolvedInfo = serverEntry.getInfo();
|
||||||
|
const listenSocket = [];
|
||||||
|
resolvedInfo.listenerChildren.sockets.forEach(el => {
|
||||||
|
listenSocket.push(socketRefToMessage(el[1].ref));
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
ref: serverRefToMessage(serverEntry.ref),
|
||||||
|
data: {
|
||||||
|
calls_started: resolvedInfo.callTracker.callsStarted,
|
||||||
|
calls_succeeded: resolvedInfo.callTracker.callsSucceeded,
|
||||||
|
calls_failed: resolvedInfo.callTracker.callsFailed,
|
||||||
|
last_call_started_timestamp: dateToProtoTimestamp(resolvedInfo.callTracker.lastCallStartedTimestamp),
|
||||||
|
trace: resolvedInfo.trace.getTraceMessage(),
|
||||||
|
},
|
||||||
|
listen_socket: listenSocket,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function GetServer(call, callback) {
|
||||||
|
const serverId = parseInt(call.request.server_id, 10);
|
||||||
|
const serverEntries = entityMaps["server" /* EntityTypes.server */];
|
||||||
|
const serverEntry = serverEntries.getElementByKey(serverId);
|
||||||
|
if (serverEntry === undefined) {
|
||||||
|
callback({
|
||||||
|
code: constants_1.Status.NOT_FOUND,
|
||||||
|
details: 'No server data found for id ' + serverId,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
callback(null, { server: getServerMessage(serverEntry) });
|
||||||
|
}
|
||||||
|
function GetServers(call, callback) {
|
||||||
|
const maxResults = parseInt(call.request.max_results, 10) || DEFAULT_MAX_RESULTS;
|
||||||
|
const startId = parseInt(call.request.start_server_id, 10);
|
||||||
|
const serverEntries = entityMaps["server" /* EntityTypes.server */];
|
||||||
|
const resultList = [];
|
||||||
|
let i;
|
||||||
|
for (i = serverEntries.lowerBound(startId); !i.equals(serverEntries.end()) && resultList.length < maxResults; i = i.next()) {
|
||||||
|
resultList.push(getServerMessage(i.pointer[1]));
|
||||||
|
}
|
||||||
|
callback(null, {
|
||||||
|
server: resultList,
|
||||||
|
end: i.equals(serverEntries.end()),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function GetSubchannel(call, callback) {
|
||||||
|
const subchannelId = parseInt(call.request.subchannel_id, 10);
|
||||||
|
const subchannelEntry = entityMaps["subchannel" /* EntityTypes.subchannel */].getElementByKey(subchannelId);
|
||||||
|
if (subchannelEntry === undefined) {
|
||||||
|
callback({
|
||||||
|
code: constants_1.Status.NOT_FOUND,
|
||||||
|
details: 'No subchannel data found for id ' + subchannelId,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const resolvedInfo = subchannelEntry.getInfo();
|
||||||
|
const listenSocket = [];
|
||||||
|
resolvedInfo.children.sockets.forEach(el => {
|
||||||
|
listenSocket.push(socketRefToMessage(el[1].ref));
|
||||||
|
});
|
||||||
|
const subchannelMessage = {
|
||||||
|
ref: subchannelRefToMessage(subchannelEntry.ref),
|
||||||
|
data: {
|
||||||
|
target: resolvedInfo.target,
|
||||||
|
state: connectivityStateToMessage(resolvedInfo.state),
|
||||||
|
calls_started: resolvedInfo.callTracker.callsStarted,
|
||||||
|
calls_succeeded: resolvedInfo.callTracker.callsSucceeded,
|
||||||
|
calls_failed: resolvedInfo.callTracker.callsFailed,
|
||||||
|
last_call_started_timestamp: dateToProtoTimestamp(resolvedInfo.callTracker.lastCallStartedTimestamp),
|
||||||
|
trace: resolvedInfo.trace.getTraceMessage(),
|
||||||
|
},
|
||||||
|
socket_ref: listenSocket,
|
||||||
|
};
|
||||||
|
callback(null, { subchannel: subchannelMessage });
|
||||||
|
}
|
||||||
|
function subchannelAddressToAddressMessage(subchannelAddress) {
|
||||||
|
var _a;
|
||||||
|
if ((0, subchannel_address_1.isTcpSubchannelAddress)(subchannelAddress)) {
|
||||||
|
return {
|
||||||
|
address: 'tcpip_address',
|
||||||
|
tcpip_address: {
|
||||||
|
ip_address: (_a = ipAddressStringToBuffer(subchannelAddress.host)) !== null && _a !== void 0 ? _a : undefined,
|
||||||
|
port: subchannelAddress.port,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return {
|
||||||
|
address: 'uds_address',
|
||||||
|
uds_address: {
|
||||||
|
filename: subchannelAddress.path,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function GetSocket(call, callback) {
|
||||||
|
var _a, _b, _c, _d, _e;
|
||||||
|
const socketId = parseInt(call.request.socket_id, 10);
|
||||||
|
const socketEntry = entityMaps["socket" /* EntityTypes.socket */].getElementByKey(socketId);
|
||||||
|
if (socketEntry === undefined) {
|
||||||
|
callback({
|
||||||
|
code: constants_1.Status.NOT_FOUND,
|
||||||
|
details: 'No socket data found for id ' + socketId,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const resolvedInfo = socketEntry.getInfo();
|
||||||
|
const securityMessage = resolvedInfo.security
|
||||||
|
? {
|
||||||
|
model: 'tls',
|
||||||
|
tls: {
|
||||||
|
cipher_suite: resolvedInfo.security.cipherSuiteStandardName
|
||||||
|
? 'standard_name'
|
||||||
|
: 'other_name',
|
||||||
|
standard_name: (_a = resolvedInfo.security.cipherSuiteStandardName) !== null && _a !== void 0 ? _a : undefined,
|
||||||
|
other_name: (_b = resolvedInfo.security.cipherSuiteOtherName) !== null && _b !== void 0 ? _b : undefined,
|
||||||
|
local_certificate: (_c = resolvedInfo.security.localCertificate) !== null && _c !== void 0 ? _c : undefined,
|
||||||
|
remote_certificate: (_d = resolvedInfo.security.remoteCertificate) !== null && _d !== void 0 ? _d : undefined,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
: null;
|
||||||
|
const socketMessage = {
|
||||||
|
ref: socketRefToMessage(socketEntry.ref),
|
||||||
|
local: resolvedInfo.localAddress
|
||||||
|
? subchannelAddressToAddressMessage(resolvedInfo.localAddress)
|
||||||
|
: null,
|
||||||
|
remote: resolvedInfo.remoteAddress
|
||||||
|
? subchannelAddressToAddressMessage(resolvedInfo.remoteAddress)
|
||||||
|
: null,
|
||||||
|
remote_name: (_e = resolvedInfo.remoteName) !== null && _e !== void 0 ? _e : undefined,
|
||||||
|
security: securityMessage,
|
||||||
|
data: {
|
||||||
|
keep_alives_sent: resolvedInfo.keepAlivesSent,
|
||||||
|
streams_started: resolvedInfo.streamsStarted,
|
||||||
|
streams_succeeded: resolvedInfo.streamsSucceeded,
|
||||||
|
streams_failed: resolvedInfo.streamsFailed,
|
||||||
|
last_local_stream_created_timestamp: dateToProtoTimestamp(resolvedInfo.lastLocalStreamCreatedTimestamp),
|
||||||
|
last_remote_stream_created_timestamp: dateToProtoTimestamp(resolvedInfo.lastRemoteStreamCreatedTimestamp),
|
||||||
|
messages_received: resolvedInfo.messagesReceived,
|
||||||
|
messages_sent: resolvedInfo.messagesSent,
|
||||||
|
last_message_received_timestamp: dateToProtoTimestamp(resolvedInfo.lastMessageReceivedTimestamp),
|
||||||
|
last_message_sent_timestamp: dateToProtoTimestamp(resolvedInfo.lastMessageSentTimestamp),
|
||||||
|
local_flow_control_window: resolvedInfo.localFlowControlWindow
|
||||||
|
? { value: resolvedInfo.localFlowControlWindow }
|
||||||
|
: null,
|
||||||
|
remote_flow_control_window: resolvedInfo.remoteFlowControlWindow
|
||||||
|
? { value: resolvedInfo.remoteFlowControlWindow }
|
||||||
|
: null,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
callback(null, { socket: socketMessage });
|
||||||
|
}
|
||||||
|
function GetServerSockets(call, callback) {
|
||||||
|
const serverId = parseInt(call.request.server_id, 10);
|
||||||
|
const serverEntry = entityMaps["server" /* EntityTypes.server */].getElementByKey(serverId);
|
||||||
|
if (serverEntry === undefined) {
|
||||||
|
callback({
|
||||||
|
code: constants_1.Status.NOT_FOUND,
|
||||||
|
details: 'No server data found for id ' + serverId,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const startId = parseInt(call.request.start_socket_id, 10);
|
||||||
|
const maxResults = parseInt(call.request.max_results, 10) || DEFAULT_MAX_RESULTS;
|
||||||
|
const resolvedInfo = serverEntry.getInfo();
|
||||||
|
// If we wanted to include listener sockets in the result, this line would
|
||||||
|
// instead say
|
||||||
|
// const allSockets = resolvedInfo.listenerChildren.sockets.concat(resolvedInfo.sessionChildren.sockets).sort((ref1, ref2) => ref1.id - ref2.id);
|
||||||
|
const allSockets = resolvedInfo.sessionChildren.sockets;
|
||||||
|
const resultList = [];
|
||||||
|
let i;
|
||||||
|
for (i = allSockets.lowerBound(startId); !i.equals(allSockets.end()) && resultList.length < maxResults; i = i.next()) {
|
||||||
|
resultList.push(socketRefToMessage(i.pointer[1].ref));
|
||||||
|
}
|
||||||
|
callback(null, {
|
||||||
|
socket_ref: resultList,
|
||||||
|
end: i.equals(allSockets.end()),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function getChannelzHandlers() {
|
||||||
|
return {
|
||||||
|
GetChannel,
|
||||||
|
GetTopChannels,
|
||||||
|
GetServer,
|
||||||
|
GetServers,
|
||||||
|
GetSubchannel,
|
||||||
|
GetSocket,
|
||||||
|
GetServerSockets,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
let loadedChannelzDefinition = null;
|
||||||
|
function getChannelzServiceDefinition() {
|
||||||
|
if (loadedChannelzDefinition) {
|
||||||
|
return loadedChannelzDefinition;
|
||||||
|
}
|
||||||
|
/* The purpose of this complexity is to avoid loading @grpc/proto-loader at
|
||||||
|
* runtime for users who will not use/enable channelz. */
|
||||||
|
const loaderLoadSync = require('@grpc/proto-loader')
|
||||||
|
.loadSync;
|
||||||
|
const loadedProto = loaderLoadSync('channelz.proto', {
|
||||||
|
keepCase: true,
|
||||||
|
longs: String,
|
||||||
|
enums: String,
|
||||||
|
defaults: true,
|
||||||
|
oneofs: true,
|
||||||
|
includeDirs: [`${__dirname}/../../proto`],
|
||||||
|
});
|
||||||
|
const channelzGrpcObject = (0, make_client_1.loadPackageDefinition)(loadedProto);
|
||||||
|
loadedChannelzDefinition =
|
||||||
|
channelzGrpcObject.grpc.channelz.v1.Channelz.service;
|
||||||
|
return loadedChannelzDefinition;
|
||||||
|
}
|
||||||
|
function setup() {
|
||||||
|
(0, admin_1.registerAdminService)(getChannelzServiceDefinition, getChannelzHandlers);
|
||||||
|
}
|
||||||
|
//# sourceMappingURL=channelz.js.map
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,123 @@
|
||||||
|
import { Metadata } from './metadata';
|
||||||
|
import { Listener, MetadataListener, MessageListener, StatusListener, InterceptingListener, MessageContext } from './call-interface';
|
||||||
|
import { Status } from './constants';
|
||||||
|
import { Channel } from './channel';
|
||||||
|
import { CallOptions } from './client';
|
||||||
|
import { ClientMethodDefinition } from './make-client';
|
||||||
|
import { AuthContext } from './auth-context';
|
||||||
|
/**
|
||||||
|
* Error class associated with passing both interceptors and interceptor
|
||||||
|
* providers to a client constructor or as call options.
|
||||||
|
*/
|
||||||
|
export declare class InterceptorConfigurationError extends Error {
|
||||||
|
constructor(message: string);
|
||||||
|
}
|
||||||
|
export interface MetadataRequester {
|
||||||
|
(metadata: Metadata, listener: InterceptingListener, next: (metadata: Metadata, listener: InterceptingListener | Listener) => void): void;
|
||||||
|
}
|
||||||
|
export interface MessageRequester {
|
||||||
|
(message: any, next: (message: any) => void): void;
|
||||||
|
}
|
||||||
|
export interface CloseRequester {
|
||||||
|
(next: () => void): void;
|
||||||
|
}
|
||||||
|
export interface CancelRequester {
|
||||||
|
(next: () => void): void;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* An object with methods for intercepting and modifying outgoing call operations.
|
||||||
|
*/
|
||||||
|
export interface FullRequester {
|
||||||
|
start: MetadataRequester;
|
||||||
|
sendMessage: MessageRequester;
|
||||||
|
halfClose: CloseRequester;
|
||||||
|
cancel: CancelRequester;
|
||||||
|
}
|
||||||
|
export type Requester = Partial<FullRequester>;
|
||||||
|
export declare class ListenerBuilder {
|
||||||
|
private metadata;
|
||||||
|
private message;
|
||||||
|
private status;
|
||||||
|
withOnReceiveMetadata(onReceiveMetadata: MetadataListener): this;
|
||||||
|
withOnReceiveMessage(onReceiveMessage: MessageListener): this;
|
||||||
|
withOnReceiveStatus(onReceiveStatus: StatusListener): this;
|
||||||
|
build(): Listener;
|
||||||
|
}
|
||||||
|
export declare class RequesterBuilder {
|
||||||
|
private start;
|
||||||
|
private message;
|
||||||
|
private halfClose;
|
||||||
|
private cancel;
|
||||||
|
withStart(start: MetadataRequester): this;
|
||||||
|
withSendMessage(sendMessage: MessageRequester): this;
|
||||||
|
withHalfClose(halfClose: CloseRequester): this;
|
||||||
|
withCancel(cancel: CancelRequester): this;
|
||||||
|
build(): Requester;
|
||||||
|
}
|
||||||
|
export interface InterceptorOptions extends CallOptions {
|
||||||
|
method_definition: ClientMethodDefinition<any, any>;
|
||||||
|
}
|
||||||
|
export interface InterceptingCallInterface {
|
||||||
|
cancelWithStatus(status: Status, details: string): void;
|
||||||
|
getPeer(): string;
|
||||||
|
start(metadata: Metadata, listener?: Partial<InterceptingListener>): void;
|
||||||
|
sendMessageWithContext(context: MessageContext, message: any): void;
|
||||||
|
sendMessage(message: any): void;
|
||||||
|
startRead(): void;
|
||||||
|
halfClose(): void;
|
||||||
|
getAuthContext(): AuthContext | null;
|
||||||
|
}
|
||||||
|
export declare class InterceptingCall implements InterceptingCallInterface {
|
||||||
|
private nextCall;
|
||||||
|
/**
|
||||||
|
* The requester that this InterceptingCall uses to modify outgoing operations
|
||||||
|
*/
|
||||||
|
private requester;
|
||||||
|
/**
|
||||||
|
* Indicates that metadata has been passed to the requester's start
|
||||||
|
* method but it has not been passed to the corresponding next callback
|
||||||
|
*/
|
||||||
|
private processingMetadata;
|
||||||
|
/**
|
||||||
|
* Message context for a pending message that is waiting for
|
||||||
|
*/
|
||||||
|
private pendingMessageContext;
|
||||||
|
private pendingMessage;
|
||||||
|
/**
|
||||||
|
* Indicates that a message has been passed to the requester's sendMessage
|
||||||
|
* method but it has not been passed to the corresponding next callback
|
||||||
|
*/
|
||||||
|
private processingMessage;
|
||||||
|
/**
|
||||||
|
* Indicates that a status was received but could not be propagated because
|
||||||
|
* a message was still being processed.
|
||||||
|
*/
|
||||||
|
private pendingHalfClose;
|
||||||
|
constructor(nextCall: InterceptingCallInterface, requester?: Requester);
|
||||||
|
cancelWithStatus(status: Status, details: string): void;
|
||||||
|
getPeer(): string;
|
||||||
|
private processPendingMessage;
|
||||||
|
private processPendingHalfClose;
|
||||||
|
start(metadata: Metadata, interceptingListener?: Partial<InterceptingListener>): void;
|
||||||
|
sendMessageWithContext(context: MessageContext, message: any): void;
|
||||||
|
sendMessage(message: any): void;
|
||||||
|
startRead(): void;
|
||||||
|
halfClose(): void;
|
||||||
|
getAuthContext(): AuthContext | null;
|
||||||
|
}
|
||||||
|
export interface NextCall {
|
||||||
|
(options: InterceptorOptions): InterceptingCallInterface;
|
||||||
|
}
|
||||||
|
export interface Interceptor {
|
||||||
|
(options: InterceptorOptions, nextCall: NextCall): InterceptingCall;
|
||||||
|
}
|
||||||
|
export interface InterceptorProvider {
|
||||||
|
(methodDefinition: ClientMethodDefinition<any, any>): Interceptor;
|
||||||
|
}
|
||||||
|
export interface InterceptorArguments {
|
||||||
|
clientInterceptors: Interceptor[];
|
||||||
|
clientInterceptorProviders: InterceptorProvider[];
|
||||||
|
callInterceptors: Interceptor[];
|
||||||
|
callInterceptorProviders: InterceptorProvider[];
|
||||||
|
}
|
||||||
|
export declare function getInterceptingCall(interceptorArgs: InterceptorArguments, methodDefinition: ClientMethodDefinition<any, any>, options: CallOptions, channel: Channel): InterceptingCallInterface;
|
||||||
|
|
@ -0,0 +1,434 @@
|
||||||
|
"use strict";
|
||||||
|
/*
|
||||||
|
* Copyright 2019 gRPC 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
|
||||||
|
*
|
||||||
|
* http://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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.InterceptingCall = exports.RequesterBuilder = exports.ListenerBuilder = exports.InterceptorConfigurationError = void 0;
|
||||||
|
exports.getInterceptingCall = getInterceptingCall;
|
||||||
|
const metadata_1 = require("./metadata");
|
||||||
|
const call_interface_1 = require("./call-interface");
|
||||||
|
const constants_1 = require("./constants");
|
||||||
|
const error_1 = require("./error");
|
||||||
|
/**
|
||||||
|
* Error class associated with passing both interceptors and interceptor
|
||||||
|
* providers to a client constructor or as call options.
|
||||||
|
*/
|
||||||
|
class InterceptorConfigurationError extends Error {
|
||||||
|
constructor(message) {
|
||||||
|
super(message);
|
||||||
|
this.name = 'InterceptorConfigurationError';
|
||||||
|
Error.captureStackTrace(this, InterceptorConfigurationError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.InterceptorConfigurationError = InterceptorConfigurationError;
|
||||||
|
class ListenerBuilder {
|
||||||
|
constructor() {
|
||||||
|
this.metadata = undefined;
|
||||||
|
this.message = undefined;
|
||||||
|
this.status = undefined;
|
||||||
|
}
|
||||||
|
withOnReceiveMetadata(onReceiveMetadata) {
|
||||||
|
this.metadata = onReceiveMetadata;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
withOnReceiveMessage(onReceiveMessage) {
|
||||||
|
this.message = onReceiveMessage;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
withOnReceiveStatus(onReceiveStatus) {
|
||||||
|
this.status = onReceiveStatus;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
build() {
|
||||||
|
return {
|
||||||
|
onReceiveMetadata: this.metadata,
|
||||||
|
onReceiveMessage: this.message,
|
||||||
|
onReceiveStatus: this.status,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.ListenerBuilder = ListenerBuilder;
|
||||||
|
class RequesterBuilder {
|
||||||
|
constructor() {
|
||||||
|
this.start = undefined;
|
||||||
|
this.message = undefined;
|
||||||
|
this.halfClose = undefined;
|
||||||
|
this.cancel = undefined;
|
||||||
|
}
|
||||||
|
withStart(start) {
|
||||||
|
this.start = start;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
withSendMessage(sendMessage) {
|
||||||
|
this.message = sendMessage;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
withHalfClose(halfClose) {
|
||||||
|
this.halfClose = halfClose;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
withCancel(cancel) {
|
||||||
|
this.cancel = cancel;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
build() {
|
||||||
|
return {
|
||||||
|
start: this.start,
|
||||||
|
sendMessage: this.message,
|
||||||
|
halfClose: this.halfClose,
|
||||||
|
cancel: this.cancel,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.RequesterBuilder = RequesterBuilder;
|
||||||
|
/**
|
||||||
|
* A Listener with a default pass-through implementation of each method. Used
|
||||||
|
* for filling out Listeners with some methods omitted.
|
||||||
|
*/
|
||||||
|
const defaultListener = {
|
||||||
|
onReceiveMetadata: (metadata, next) => {
|
||||||
|
next(metadata);
|
||||||
|
},
|
||||||
|
onReceiveMessage: (message, next) => {
|
||||||
|
next(message);
|
||||||
|
},
|
||||||
|
onReceiveStatus: (status, next) => {
|
||||||
|
next(status);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* A Requester with a default pass-through implementation of each method. Used
|
||||||
|
* for filling out Requesters with some methods omitted.
|
||||||
|
*/
|
||||||
|
const defaultRequester = {
|
||||||
|
start: (metadata, listener, next) => {
|
||||||
|
next(metadata, listener);
|
||||||
|
},
|
||||||
|
sendMessage: (message, next) => {
|
||||||
|
next(message);
|
||||||
|
},
|
||||||
|
halfClose: next => {
|
||||||
|
next();
|
||||||
|
},
|
||||||
|
cancel: next => {
|
||||||
|
next();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
class InterceptingCall {
|
||||||
|
constructor(nextCall, requester) {
|
||||||
|
var _a, _b, _c, _d;
|
||||||
|
this.nextCall = nextCall;
|
||||||
|
/**
|
||||||
|
* Indicates that metadata has been passed to the requester's start
|
||||||
|
* method but it has not been passed to the corresponding next callback
|
||||||
|
*/
|
||||||
|
this.processingMetadata = false;
|
||||||
|
/**
|
||||||
|
* Message context for a pending message that is waiting for
|
||||||
|
*/
|
||||||
|
this.pendingMessageContext = null;
|
||||||
|
/**
|
||||||
|
* Indicates that a message has been passed to the requester's sendMessage
|
||||||
|
* method but it has not been passed to the corresponding next callback
|
||||||
|
*/
|
||||||
|
this.processingMessage = false;
|
||||||
|
/**
|
||||||
|
* Indicates that a status was received but could not be propagated because
|
||||||
|
* a message was still being processed.
|
||||||
|
*/
|
||||||
|
this.pendingHalfClose = false;
|
||||||
|
if (requester) {
|
||||||
|
this.requester = {
|
||||||
|
start: (_a = requester.start) !== null && _a !== void 0 ? _a : defaultRequester.start,
|
||||||
|
sendMessage: (_b = requester.sendMessage) !== null && _b !== void 0 ? _b : defaultRequester.sendMessage,
|
||||||
|
halfClose: (_c = requester.halfClose) !== null && _c !== void 0 ? _c : defaultRequester.halfClose,
|
||||||
|
cancel: (_d = requester.cancel) !== null && _d !== void 0 ? _d : defaultRequester.cancel,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.requester = defaultRequester;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cancelWithStatus(status, details) {
|
||||||
|
this.requester.cancel(() => {
|
||||||
|
this.nextCall.cancelWithStatus(status, details);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
getPeer() {
|
||||||
|
return this.nextCall.getPeer();
|
||||||
|
}
|
||||||
|
processPendingMessage() {
|
||||||
|
if (this.pendingMessageContext) {
|
||||||
|
this.nextCall.sendMessageWithContext(this.pendingMessageContext, this.pendingMessage);
|
||||||
|
this.pendingMessageContext = null;
|
||||||
|
this.pendingMessage = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
processPendingHalfClose() {
|
||||||
|
if (this.pendingHalfClose) {
|
||||||
|
this.nextCall.halfClose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
start(metadata, interceptingListener) {
|
||||||
|
var _a, _b, _c, _d, _e, _f;
|
||||||
|
const fullInterceptingListener = {
|
||||||
|
onReceiveMetadata: (_b = (_a = interceptingListener === null || interceptingListener === void 0 ? void 0 : interceptingListener.onReceiveMetadata) === null || _a === void 0 ? void 0 : _a.bind(interceptingListener)) !== null && _b !== void 0 ? _b : (metadata => { }),
|
||||||
|
onReceiveMessage: (_d = (_c = interceptingListener === null || interceptingListener === void 0 ? void 0 : interceptingListener.onReceiveMessage) === null || _c === void 0 ? void 0 : _c.bind(interceptingListener)) !== null && _d !== void 0 ? _d : (message => { }),
|
||||||
|
onReceiveStatus: (_f = (_e = interceptingListener === null || interceptingListener === void 0 ? void 0 : interceptingListener.onReceiveStatus) === null || _e === void 0 ? void 0 : _e.bind(interceptingListener)) !== null && _f !== void 0 ? _f : (status => { }),
|
||||||
|
};
|
||||||
|
this.processingMetadata = true;
|
||||||
|
this.requester.start(metadata, fullInterceptingListener, (md, listener) => {
|
||||||
|
var _a, _b, _c;
|
||||||
|
this.processingMetadata = false;
|
||||||
|
let finalInterceptingListener;
|
||||||
|
if ((0, call_interface_1.isInterceptingListener)(listener)) {
|
||||||
|
finalInterceptingListener = listener;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const fullListener = {
|
||||||
|
onReceiveMetadata: (_a = listener.onReceiveMetadata) !== null && _a !== void 0 ? _a : defaultListener.onReceiveMetadata,
|
||||||
|
onReceiveMessage: (_b = listener.onReceiveMessage) !== null && _b !== void 0 ? _b : defaultListener.onReceiveMessage,
|
||||||
|
onReceiveStatus: (_c = listener.onReceiveStatus) !== null && _c !== void 0 ? _c : defaultListener.onReceiveStatus,
|
||||||
|
};
|
||||||
|
finalInterceptingListener = new call_interface_1.InterceptingListenerImpl(fullListener, fullInterceptingListener);
|
||||||
|
}
|
||||||
|
this.nextCall.start(md, finalInterceptingListener);
|
||||||
|
this.processPendingMessage();
|
||||||
|
this.processPendingHalfClose();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
sendMessageWithContext(context, message) {
|
||||||
|
this.processingMessage = true;
|
||||||
|
this.requester.sendMessage(message, finalMessage => {
|
||||||
|
this.processingMessage = false;
|
||||||
|
if (this.processingMetadata) {
|
||||||
|
this.pendingMessageContext = context;
|
||||||
|
this.pendingMessage = message;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.nextCall.sendMessageWithContext(context, finalMessage);
|
||||||
|
this.processPendingHalfClose();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
sendMessage(message) {
|
||||||
|
this.sendMessageWithContext({}, message);
|
||||||
|
}
|
||||||
|
startRead() {
|
||||||
|
this.nextCall.startRead();
|
||||||
|
}
|
||||||
|
halfClose() {
|
||||||
|
this.requester.halfClose(() => {
|
||||||
|
if (this.processingMetadata || this.processingMessage) {
|
||||||
|
this.pendingHalfClose = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.nextCall.halfClose();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
getAuthContext() {
|
||||||
|
return this.nextCall.getAuthContext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.InterceptingCall = InterceptingCall;
|
||||||
|
function getCall(channel, path, options) {
|
||||||
|
var _a, _b;
|
||||||
|
const deadline = (_a = options.deadline) !== null && _a !== void 0 ? _a : Infinity;
|
||||||
|
const host = options.host;
|
||||||
|
const parent = (_b = options.parent) !== null && _b !== void 0 ? _b : null;
|
||||||
|
const propagateFlags = options.propagate_flags;
|
||||||
|
const credentials = options.credentials;
|
||||||
|
const call = channel.createCall(path, deadline, host, parent, propagateFlags);
|
||||||
|
if (credentials) {
|
||||||
|
call.setCredentials(credentials);
|
||||||
|
}
|
||||||
|
return call;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* InterceptingCall implementation that directly owns the underlying Call
|
||||||
|
* object and handles serialization and deseraizliation.
|
||||||
|
*/
|
||||||
|
class BaseInterceptingCall {
|
||||||
|
constructor(call,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
methodDefinition) {
|
||||||
|
this.call = call;
|
||||||
|
this.methodDefinition = methodDefinition;
|
||||||
|
}
|
||||||
|
cancelWithStatus(status, details) {
|
||||||
|
this.call.cancelWithStatus(status, details);
|
||||||
|
}
|
||||||
|
getPeer() {
|
||||||
|
return this.call.getPeer();
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
sendMessageWithContext(context, message) {
|
||||||
|
let serialized;
|
||||||
|
try {
|
||||||
|
serialized = this.methodDefinition.requestSerialize(message);
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
this.call.cancelWithStatus(constants_1.Status.INTERNAL, `Request message serialization failure: ${(0, error_1.getErrorMessage)(e)}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.call.sendMessageWithContext(context, serialized);
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
sendMessage(message) {
|
||||||
|
this.sendMessageWithContext({}, message);
|
||||||
|
}
|
||||||
|
start(metadata, interceptingListener) {
|
||||||
|
let readError = null;
|
||||||
|
this.call.start(metadata, {
|
||||||
|
onReceiveMetadata: metadata => {
|
||||||
|
var _a;
|
||||||
|
(_a = interceptingListener === null || interceptingListener === void 0 ? void 0 : interceptingListener.onReceiveMetadata) === null || _a === void 0 ? void 0 : _a.call(interceptingListener, metadata);
|
||||||
|
},
|
||||||
|
onReceiveMessage: message => {
|
||||||
|
var _a;
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
let deserialized;
|
||||||
|
try {
|
||||||
|
deserialized = this.methodDefinition.responseDeserialize(message);
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
readError = {
|
||||||
|
code: constants_1.Status.INTERNAL,
|
||||||
|
details: `Response message parsing error: ${(0, error_1.getErrorMessage)(e)}`,
|
||||||
|
metadata: new metadata_1.Metadata(),
|
||||||
|
};
|
||||||
|
this.call.cancelWithStatus(readError.code, readError.details);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
(_a = interceptingListener === null || interceptingListener === void 0 ? void 0 : interceptingListener.onReceiveMessage) === null || _a === void 0 ? void 0 : _a.call(interceptingListener, deserialized);
|
||||||
|
},
|
||||||
|
onReceiveStatus: status => {
|
||||||
|
var _a, _b;
|
||||||
|
if (readError) {
|
||||||
|
(_a = interceptingListener === null || interceptingListener === void 0 ? void 0 : interceptingListener.onReceiveStatus) === null || _a === void 0 ? void 0 : _a.call(interceptingListener, readError);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
(_b = interceptingListener === null || interceptingListener === void 0 ? void 0 : interceptingListener.onReceiveStatus) === null || _b === void 0 ? void 0 : _b.call(interceptingListener, status);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
startRead() {
|
||||||
|
this.call.startRead();
|
||||||
|
}
|
||||||
|
halfClose() {
|
||||||
|
this.call.halfClose();
|
||||||
|
}
|
||||||
|
getAuthContext() {
|
||||||
|
return this.call.getAuthContext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* BaseInterceptingCall with special-cased behavior for methods with unary
|
||||||
|
* responses.
|
||||||
|
*/
|
||||||
|
class BaseUnaryInterceptingCall extends BaseInterceptingCall {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
constructor(call, methodDefinition) {
|
||||||
|
super(call, methodDefinition);
|
||||||
|
}
|
||||||
|
start(metadata, listener) {
|
||||||
|
var _a, _b;
|
||||||
|
let receivedMessage = false;
|
||||||
|
const wrapperListener = {
|
||||||
|
onReceiveMetadata: (_b = (_a = listener === null || listener === void 0 ? void 0 : listener.onReceiveMetadata) === null || _a === void 0 ? void 0 : _a.bind(listener)) !== null && _b !== void 0 ? _b : (metadata => { }),
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
onReceiveMessage: (message) => {
|
||||||
|
var _a;
|
||||||
|
receivedMessage = true;
|
||||||
|
(_a = listener === null || listener === void 0 ? void 0 : listener.onReceiveMessage) === null || _a === void 0 ? void 0 : _a.call(listener, message);
|
||||||
|
},
|
||||||
|
onReceiveStatus: (status) => {
|
||||||
|
var _a, _b;
|
||||||
|
if (!receivedMessage) {
|
||||||
|
(_a = listener === null || listener === void 0 ? void 0 : listener.onReceiveMessage) === null || _a === void 0 ? void 0 : _a.call(listener, null);
|
||||||
|
}
|
||||||
|
(_b = listener === null || listener === void 0 ? void 0 : listener.onReceiveStatus) === null || _b === void 0 ? void 0 : _b.call(listener, status);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
super.start(metadata, wrapperListener);
|
||||||
|
this.call.startRead();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* BaseInterceptingCall with special-cased behavior for methods with streaming
|
||||||
|
* responses.
|
||||||
|
*/
|
||||||
|
class BaseStreamingInterceptingCall extends BaseInterceptingCall {
|
||||||
|
}
|
||||||
|
function getBottomInterceptingCall(channel, options,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
methodDefinition) {
|
||||||
|
const call = getCall(channel, methodDefinition.path, options);
|
||||||
|
if (methodDefinition.responseStream) {
|
||||||
|
return new BaseStreamingInterceptingCall(call, methodDefinition);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return new BaseUnaryInterceptingCall(call, methodDefinition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function getInterceptingCall(interceptorArgs,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
methodDefinition, options, channel) {
|
||||||
|
if (interceptorArgs.clientInterceptors.length > 0 &&
|
||||||
|
interceptorArgs.clientInterceptorProviders.length > 0) {
|
||||||
|
throw new InterceptorConfigurationError('Both interceptors and interceptor_providers were passed as options ' +
|
||||||
|
'to the client constructor. Only one of these is allowed.');
|
||||||
|
}
|
||||||
|
if (interceptorArgs.callInterceptors.length > 0 &&
|
||||||
|
interceptorArgs.callInterceptorProviders.length > 0) {
|
||||||
|
throw new InterceptorConfigurationError('Both interceptors and interceptor_providers were passed as call ' +
|
||||||
|
'options. Only one of these is allowed.');
|
||||||
|
}
|
||||||
|
let interceptors = [];
|
||||||
|
// Interceptors passed to the call override interceptors passed to the client constructor
|
||||||
|
if (interceptorArgs.callInterceptors.length > 0 ||
|
||||||
|
interceptorArgs.callInterceptorProviders.length > 0) {
|
||||||
|
interceptors = []
|
||||||
|
.concat(interceptorArgs.callInterceptors, interceptorArgs.callInterceptorProviders.map(provider => provider(methodDefinition)))
|
||||||
|
.filter(interceptor => interceptor);
|
||||||
|
// Filter out falsy values when providers return nothing
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
interceptors = []
|
||||||
|
.concat(interceptorArgs.clientInterceptors, interceptorArgs.clientInterceptorProviders.map(provider => provider(methodDefinition)))
|
||||||
|
.filter(interceptor => interceptor);
|
||||||
|
// Filter out falsy values when providers return nothing
|
||||||
|
}
|
||||||
|
const interceptorOptions = Object.assign({}, options, {
|
||||||
|
method_definition: methodDefinition,
|
||||||
|
});
|
||||||
|
/* For each interceptor in the list, the nextCall function passed to it is
|
||||||
|
* based on the next interceptor in the list, using a nextCall function
|
||||||
|
* constructed with the following interceptor in the list, and so on. The
|
||||||
|
* initialValue, which is effectively at the end of the list, is a nextCall
|
||||||
|
* function that invokes getBottomInterceptingCall, the result of which
|
||||||
|
* handles (de)serialization and also gets the underlying call from the
|
||||||
|
* channel. */
|
||||||
|
const getCall = interceptors.reduceRight((nextCall, nextInterceptor) => {
|
||||||
|
return currentOptions => nextInterceptor(currentOptions, nextCall);
|
||||||
|
}, (finalOptions) => getBottomInterceptingCall(channel, finalOptions, methodDefinition));
|
||||||
|
return getCall(interceptorOptions);
|
||||||
|
}
|
||||||
|
//# sourceMappingURL=client-interceptors.js.map
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,74 @@
|
||||||
|
import { ClientDuplexStream, ClientReadableStream, ClientUnaryCall, ClientWritableStream, ServiceError, SurfaceCall } from './call';
|
||||||
|
import { CallCredentials } from './call-credentials';
|
||||||
|
import { Channel } from './channel';
|
||||||
|
import { ChannelCredentials } from './channel-credentials';
|
||||||
|
import { ChannelOptions } from './channel-options';
|
||||||
|
import { Metadata } from './metadata';
|
||||||
|
import { ClientMethodDefinition } from './make-client';
|
||||||
|
import { Interceptor, InterceptorProvider } from './client-interceptors';
|
||||||
|
import { ServerUnaryCall, ServerReadableStream, ServerWritableStream, ServerDuplexStream } from './server-call';
|
||||||
|
import { Deadline } from './deadline';
|
||||||
|
declare const CHANNEL_SYMBOL: unique symbol;
|
||||||
|
declare const INTERCEPTOR_SYMBOL: unique symbol;
|
||||||
|
declare const INTERCEPTOR_PROVIDER_SYMBOL: unique symbol;
|
||||||
|
declare const CALL_INVOCATION_TRANSFORMER_SYMBOL: unique symbol;
|
||||||
|
export interface UnaryCallback<ResponseType> {
|
||||||
|
(err: ServiceError | null, value?: ResponseType): void;
|
||||||
|
}
|
||||||
|
export interface CallOptions {
|
||||||
|
deadline?: Deadline;
|
||||||
|
host?: string;
|
||||||
|
parent?: ServerUnaryCall<any, any> | ServerReadableStream<any, any> | ServerWritableStream<any, any> | ServerDuplexStream<any, any>;
|
||||||
|
propagate_flags?: number;
|
||||||
|
credentials?: CallCredentials;
|
||||||
|
interceptors?: Interceptor[];
|
||||||
|
interceptor_providers?: InterceptorProvider[];
|
||||||
|
}
|
||||||
|
export interface CallProperties<RequestType, ResponseType> {
|
||||||
|
argument?: RequestType;
|
||||||
|
metadata: Metadata;
|
||||||
|
call: SurfaceCall;
|
||||||
|
channel: Channel;
|
||||||
|
methodDefinition: ClientMethodDefinition<RequestType, ResponseType>;
|
||||||
|
callOptions: CallOptions;
|
||||||
|
callback?: UnaryCallback<ResponseType>;
|
||||||
|
}
|
||||||
|
export interface CallInvocationTransformer {
|
||||||
|
(callProperties: CallProperties<any, any>): CallProperties<any, any>;
|
||||||
|
}
|
||||||
|
export type ClientOptions = Partial<ChannelOptions> & {
|
||||||
|
channelOverride?: Channel;
|
||||||
|
channelFactoryOverride?: (address: string, credentials: ChannelCredentials, options: ClientOptions) => Channel;
|
||||||
|
interceptors?: Interceptor[];
|
||||||
|
interceptor_providers?: InterceptorProvider[];
|
||||||
|
callInvocationTransformer?: CallInvocationTransformer;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* A generic gRPC client. Primarily useful as a base class for all generated
|
||||||
|
* clients.
|
||||||
|
*/
|
||||||
|
export declare class Client {
|
||||||
|
private readonly [CHANNEL_SYMBOL];
|
||||||
|
private readonly [INTERCEPTOR_SYMBOL];
|
||||||
|
private readonly [INTERCEPTOR_PROVIDER_SYMBOL];
|
||||||
|
private readonly [CALL_INVOCATION_TRANSFORMER_SYMBOL]?;
|
||||||
|
constructor(address: string, credentials: ChannelCredentials, options?: ClientOptions);
|
||||||
|
close(): void;
|
||||||
|
getChannel(): Channel;
|
||||||
|
waitForReady(deadline: Deadline, callback: (error?: Error) => void): void;
|
||||||
|
private checkOptionalUnaryResponseArguments;
|
||||||
|
makeUnaryRequest<RequestType, ResponseType>(method: string, serialize: (value: RequestType) => Buffer, deserialize: (value: Buffer) => ResponseType, argument: RequestType, metadata: Metadata, options: CallOptions, callback: UnaryCallback<ResponseType>): ClientUnaryCall;
|
||||||
|
makeUnaryRequest<RequestType, ResponseType>(method: string, serialize: (value: RequestType) => Buffer, deserialize: (value: Buffer) => ResponseType, argument: RequestType, metadata: Metadata, callback: UnaryCallback<ResponseType>): ClientUnaryCall;
|
||||||
|
makeUnaryRequest<RequestType, ResponseType>(method: string, serialize: (value: RequestType) => Buffer, deserialize: (value: Buffer) => ResponseType, argument: RequestType, options: CallOptions, callback: UnaryCallback<ResponseType>): ClientUnaryCall;
|
||||||
|
makeUnaryRequest<RequestType, ResponseType>(method: string, serialize: (value: RequestType) => Buffer, deserialize: (value: Buffer) => ResponseType, argument: RequestType, callback: UnaryCallback<ResponseType>): ClientUnaryCall;
|
||||||
|
makeClientStreamRequest<RequestType, ResponseType>(method: string, serialize: (value: RequestType) => Buffer, deserialize: (value: Buffer) => ResponseType, metadata: Metadata, options: CallOptions, callback: UnaryCallback<ResponseType>): ClientWritableStream<RequestType>;
|
||||||
|
makeClientStreamRequest<RequestType, ResponseType>(method: string, serialize: (value: RequestType) => Buffer, deserialize: (value: Buffer) => ResponseType, metadata: Metadata, callback: UnaryCallback<ResponseType>): ClientWritableStream<RequestType>;
|
||||||
|
makeClientStreamRequest<RequestType, ResponseType>(method: string, serialize: (value: RequestType) => Buffer, deserialize: (value: Buffer) => ResponseType, options: CallOptions, callback: UnaryCallback<ResponseType>): ClientWritableStream<RequestType>;
|
||||||
|
makeClientStreamRequest<RequestType, ResponseType>(method: string, serialize: (value: RequestType) => Buffer, deserialize: (value: Buffer) => ResponseType, callback: UnaryCallback<ResponseType>): ClientWritableStream<RequestType>;
|
||||||
|
private checkMetadataAndOptions;
|
||||||
|
makeServerStreamRequest<RequestType, ResponseType>(method: string, serialize: (value: RequestType) => Buffer, deserialize: (value: Buffer) => ResponseType, argument: RequestType, metadata: Metadata, options?: CallOptions): ClientReadableStream<ResponseType>;
|
||||||
|
makeServerStreamRequest<RequestType, ResponseType>(method: string, serialize: (value: RequestType) => Buffer, deserialize: (value: Buffer) => ResponseType, argument: RequestType, options?: CallOptions): ClientReadableStream<ResponseType>;
|
||||||
|
makeBidiStreamRequest<RequestType, ResponseType>(method: string, serialize: (value: RequestType) => Buffer, deserialize: (value: Buffer) => ResponseType, metadata: Metadata, options?: CallOptions): ClientDuplexStream<RequestType, ResponseType>;
|
||||||
|
makeBidiStreamRequest<RequestType, ResponseType>(method: string, serialize: (value: RequestType) => Buffer, deserialize: (value: Buffer) => ResponseType, options?: CallOptions): ClientDuplexStream<RequestType, ResponseType>;
|
||||||
|
}
|
||||||
|
export {};
|
||||||
|
|
@ -0,0 +1,433 @@
|
||||||
|
"use strict";
|
||||||
|
/*
|
||||||
|
* Copyright 2019 gRPC 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
|
||||||
|
*
|
||||||
|
* http://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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.Client = void 0;
|
||||||
|
const call_1 = require("./call");
|
||||||
|
const channel_1 = require("./channel");
|
||||||
|
const connectivity_state_1 = require("./connectivity-state");
|
||||||
|
const constants_1 = require("./constants");
|
||||||
|
const metadata_1 = require("./metadata");
|
||||||
|
const client_interceptors_1 = require("./client-interceptors");
|
||||||
|
const CHANNEL_SYMBOL = Symbol();
|
||||||
|
const INTERCEPTOR_SYMBOL = Symbol();
|
||||||
|
const INTERCEPTOR_PROVIDER_SYMBOL = Symbol();
|
||||||
|
const CALL_INVOCATION_TRANSFORMER_SYMBOL = Symbol();
|
||||||
|
function isFunction(arg) {
|
||||||
|
return typeof arg === 'function';
|
||||||
|
}
|
||||||
|
function getErrorStackString(error) {
|
||||||
|
var _a;
|
||||||
|
return ((_a = error.stack) === null || _a === void 0 ? void 0 : _a.split('\n').slice(1).join('\n')) || 'no stack trace available';
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* A generic gRPC client. Primarily useful as a base class for all generated
|
||||||
|
* clients.
|
||||||
|
*/
|
||||||
|
class Client {
|
||||||
|
constructor(address, credentials, options = {}) {
|
||||||
|
var _a, _b;
|
||||||
|
options = Object.assign({}, options);
|
||||||
|
this[INTERCEPTOR_SYMBOL] = (_a = options.interceptors) !== null && _a !== void 0 ? _a : [];
|
||||||
|
delete options.interceptors;
|
||||||
|
this[INTERCEPTOR_PROVIDER_SYMBOL] = (_b = options.interceptor_providers) !== null && _b !== void 0 ? _b : [];
|
||||||
|
delete options.interceptor_providers;
|
||||||
|
if (this[INTERCEPTOR_SYMBOL].length > 0 &&
|
||||||
|
this[INTERCEPTOR_PROVIDER_SYMBOL].length > 0) {
|
||||||
|
throw new Error('Both interceptors and interceptor_providers were passed as options ' +
|
||||||
|
'to the client constructor. Only one of these is allowed.');
|
||||||
|
}
|
||||||
|
this[CALL_INVOCATION_TRANSFORMER_SYMBOL] =
|
||||||
|
options.callInvocationTransformer;
|
||||||
|
delete options.callInvocationTransformer;
|
||||||
|
if (options.channelOverride) {
|
||||||
|
this[CHANNEL_SYMBOL] = options.channelOverride;
|
||||||
|
}
|
||||||
|
else if (options.channelFactoryOverride) {
|
||||||
|
const channelFactoryOverride = options.channelFactoryOverride;
|
||||||
|
delete options.channelFactoryOverride;
|
||||||
|
this[CHANNEL_SYMBOL] = channelFactoryOverride(address, credentials, options);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this[CHANNEL_SYMBOL] = new channel_1.ChannelImplementation(address, credentials, options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close() {
|
||||||
|
this[CHANNEL_SYMBOL].close();
|
||||||
|
}
|
||||||
|
getChannel() {
|
||||||
|
return this[CHANNEL_SYMBOL];
|
||||||
|
}
|
||||||
|
waitForReady(deadline, callback) {
|
||||||
|
const checkState = (err) => {
|
||||||
|
if (err) {
|
||||||
|
callback(new Error('Failed to connect before the deadline'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let newState;
|
||||||
|
try {
|
||||||
|
newState = this[CHANNEL_SYMBOL].getConnectivityState(true);
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
callback(new Error('The channel has been closed'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (newState === connectivity_state_1.ConnectivityState.READY) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
try {
|
||||||
|
this[CHANNEL_SYMBOL].watchConnectivityState(newState, deadline, checkState);
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
callback(new Error('The channel has been closed'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
setImmediate(checkState);
|
||||||
|
}
|
||||||
|
checkOptionalUnaryResponseArguments(arg1, arg2, arg3) {
|
||||||
|
if (isFunction(arg1)) {
|
||||||
|
return { metadata: new metadata_1.Metadata(), options: {}, callback: arg1 };
|
||||||
|
}
|
||||||
|
else if (isFunction(arg2)) {
|
||||||
|
if (arg1 instanceof metadata_1.Metadata) {
|
||||||
|
return { metadata: arg1, options: {}, callback: arg2 };
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return { metadata: new metadata_1.Metadata(), options: arg1, callback: arg2 };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!(arg1 instanceof metadata_1.Metadata &&
|
||||||
|
arg2 instanceof Object &&
|
||||||
|
isFunction(arg3))) {
|
||||||
|
throw new Error('Incorrect arguments passed');
|
||||||
|
}
|
||||||
|
return { metadata: arg1, options: arg2, callback: arg3 };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
makeUnaryRequest(method, serialize, deserialize, argument, metadata, options, callback) {
|
||||||
|
var _a, _b;
|
||||||
|
const checkedArguments = this.checkOptionalUnaryResponseArguments(metadata, options, callback);
|
||||||
|
const methodDefinition = {
|
||||||
|
path: method,
|
||||||
|
requestStream: false,
|
||||||
|
responseStream: false,
|
||||||
|
requestSerialize: serialize,
|
||||||
|
responseDeserialize: deserialize,
|
||||||
|
};
|
||||||
|
let callProperties = {
|
||||||
|
argument: argument,
|
||||||
|
metadata: checkedArguments.metadata,
|
||||||
|
call: new call_1.ClientUnaryCallImpl(),
|
||||||
|
channel: this[CHANNEL_SYMBOL],
|
||||||
|
methodDefinition: methodDefinition,
|
||||||
|
callOptions: checkedArguments.options,
|
||||||
|
callback: checkedArguments.callback,
|
||||||
|
};
|
||||||
|
if (this[CALL_INVOCATION_TRANSFORMER_SYMBOL]) {
|
||||||
|
callProperties = this[CALL_INVOCATION_TRANSFORMER_SYMBOL](callProperties);
|
||||||
|
}
|
||||||
|
const emitter = callProperties.call;
|
||||||
|
const interceptorArgs = {
|
||||||
|
clientInterceptors: this[INTERCEPTOR_SYMBOL],
|
||||||
|
clientInterceptorProviders: this[INTERCEPTOR_PROVIDER_SYMBOL],
|
||||||
|
callInterceptors: (_a = callProperties.callOptions.interceptors) !== null && _a !== void 0 ? _a : [],
|
||||||
|
callInterceptorProviders: (_b = callProperties.callOptions.interceptor_providers) !== null && _b !== void 0 ? _b : [],
|
||||||
|
};
|
||||||
|
const call = (0, client_interceptors_1.getInterceptingCall)(interceptorArgs, callProperties.methodDefinition, callProperties.callOptions, callProperties.channel);
|
||||||
|
/* This needs to happen before the emitter is used. Unfortunately we can't
|
||||||
|
* enforce this with the type system. We need to construct this emitter
|
||||||
|
* before calling the CallInvocationTransformer, and we need to create the
|
||||||
|
* call after that. */
|
||||||
|
emitter.call = call;
|
||||||
|
let responseMessage = null;
|
||||||
|
let receivedStatus = false;
|
||||||
|
let callerStackError = new Error();
|
||||||
|
call.start(callProperties.metadata, {
|
||||||
|
onReceiveMetadata: metadata => {
|
||||||
|
emitter.emit('metadata', metadata);
|
||||||
|
},
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
onReceiveMessage(message) {
|
||||||
|
if (responseMessage !== null) {
|
||||||
|
call.cancelWithStatus(constants_1.Status.UNIMPLEMENTED, 'Too many responses received');
|
||||||
|
}
|
||||||
|
responseMessage = message;
|
||||||
|
},
|
||||||
|
onReceiveStatus(status) {
|
||||||
|
if (receivedStatus) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
receivedStatus = true;
|
||||||
|
if (status.code === constants_1.Status.OK) {
|
||||||
|
if (responseMessage === null) {
|
||||||
|
const callerStack = getErrorStackString(callerStackError);
|
||||||
|
callProperties.callback((0, call_1.callErrorFromStatus)({
|
||||||
|
code: constants_1.Status.UNIMPLEMENTED,
|
||||||
|
details: 'No message received',
|
||||||
|
metadata: status.metadata,
|
||||||
|
}, callerStack));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
callProperties.callback(null, responseMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const callerStack = getErrorStackString(callerStackError);
|
||||||
|
callProperties.callback((0, call_1.callErrorFromStatus)(status, callerStack));
|
||||||
|
}
|
||||||
|
/* Avoid retaining the callerStackError object in the call context of
|
||||||
|
* the status event handler. */
|
||||||
|
callerStackError = null;
|
||||||
|
emitter.emit('status', status);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
call.sendMessage(argument);
|
||||||
|
call.halfClose();
|
||||||
|
return emitter;
|
||||||
|
}
|
||||||
|
makeClientStreamRequest(method, serialize, deserialize, metadata, options, callback) {
|
||||||
|
var _a, _b;
|
||||||
|
const checkedArguments = this.checkOptionalUnaryResponseArguments(metadata, options, callback);
|
||||||
|
const methodDefinition = {
|
||||||
|
path: method,
|
||||||
|
requestStream: true,
|
||||||
|
responseStream: false,
|
||||||
|
requestSerialize: serialize,
|
||||||
|
responseDeserialize: deserialize,
|
||||||
|
};
|
||||||
|
let callProperties = {
|
||||||
|
metadata: checkedArguments.metadata,
|
||||||
|
call: new call_1.ClientWritableStreamImpl(serialize),
|
||||||
|
channel: this[CHANNEL_SYMBOL],
|
||||||
|
methodDefinition: methodDefinition,
|
||||||
|
callOptions: checkedArguments.options,
|
||||||
|
callback: checkedArguments.callback,
|
||||||
|
};
|
||||||
|
if (this[CALL_INVOCATION_TRANSFORMER_SYMBOL]) {
|
||||||
|
callProperties = this[CALL_INVOCATION_TRANSFORMER_SYMBOL](callProperties);
|
||||||
|
}
|
||||||
|
const emitter = callProperties.call;
|
||||||
|
const interceptorArgs = {
|
||||||
|
clientInterceptors: this[INTERCEPTOR_SYMBOL],
|
||||||
|
clientInterceptorProviders: this[INTERCEPTOR_PROVIDER_SYMBOL],
|
||||||
|
callInterceptors: (_a = callProperties.callOptions.interceptors) !== null && _a !== void 0 ? _a : [],
|
||||||
|
callInterceptorProviders: (_b = callProperties.callOptions.interceptor_providers) !== null && _b !== void 0 ? _b : [],
|
||||||
|
};
|
||||||
|
const call = (0, client_interceptors_1.getInterceptingCall)(interceptorArgs, callProperties.methodDefinition, callProperties.callOptions, callProperties.channel);
|
||||||
|
/* This needs to happen before the emitter is used. Unfortunately we can't
|
||||||
|
* enforce this with the type system. We need to construct this emitter
|
||||||
|
* before calling the CallInvocationTransformer, and we need to create the
|
||||||
|
* call after that. */
|
||||||
|
emitter.call = call;
|
||||||
|
let responseMessage = null;
|
||||||
|
let receivedStatus = false;
|
||||||
|
let callerStackError = new Error();
|
||||||
|
call.start(callProperties.metadata, {
|
||||||
|
onReceiveMetadata: metadata => {
|
||||||
|
emitter.emit('metadata', metadata);
|
||||||
|
},
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
onReceiveMessage(message) {
|
||||||
|
if (responseMessage !== null) {
|
||||||
|
call.cancelWithStatus(constants_1.Status.UNIMPLEMENTED, 'Too many responses received');
|
||||||
|
}
|
||||||
|
responseMessage = message;
|
||||||
|
call.startRead();
|
||||||
|
},
|
||||||
|
onReceiveStatus(status) {
|
||||||
|
if (receivedStatus) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
receivedStatus = true;
|
||||||
|
if (status.code === constants_1.Status.OK) {
|
||||||
|
if (responseMessage === null) {
|
||||||
|
const callerStack = getErrorStackString(callerStackError);
|
||||||
|
callProperties.callback((0, call_1.callErrorFromStatus)({
|
||||||
|
code: constants_1.Status.UNIMPLEMENTED,
|
||||||
|
details: 'No message received',
|
||||||
|
metadata: status.metadata,
|
||||||
|
}, callerStack));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
callProperties.callback(null, responseMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const callerStack = getErrorStackString(callerStackError);
|
||||||
|
callProperties.callback((0, call_1.callErrorFromStatus)(status, callerStack));
|
||||||
|
}
|
||||||
|
/* Avoid retaining the callerStackError object in the call context of
|
||||||
|
* the status event handler. */
|
||||||
|
callerStackError = null;
|
||||||
|
emitter.emit('status', status);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return emitter;
|
||||||
|
}
|
||||||
|
checkMetadataAndOptions(arg1, arg2) {
|
||||||
|
let metadata;
|
||||||
|
let options;
|
||||||
|
if (arg1 instanceof metadata_1.Metadata) {
|
||||||
|
metadata = arg1;
|
||||||
|
if (arg2) {
|
||||||
|
options = arg2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
options = {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (arg1) {
|
||||||
|
options = arg1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
options = {};
|
||||||
|
}
|
||||||
|
metadata = new metadata_1.Metadata();
|
||||||
|
}
|
||||||
|
return { metadata, options };
|
||||||
|
}
|
||||||
|
makeServerStreamRequest(method, serialize, deserialize, argument, metadata, options) {
|
||||||
|
var _a, _b;
|
||||||
|
const checkedArguments = this.checkMetadataAndOptions(metadata, options);
|
||||||
|
const methodDefinition = {
|
||||||
|
path: method,
|
||||||
|
requestStream: false,
|
||||||
|
responseStream: true,
|
||||||
|
requestSerialize: serialize,
|
||||||
|
responseDeserialize: deserialize,
|
||||||
|
};
|
||||||
|
let callProperties = {
|
||||||
|
argument: argument,
|
||||||
|
metadata: checkedArguments.metadata,
|
||||||
|
call: new call_1.ClientReadableStreamImpl(deserialize),
|
||||||
|
channel: this[CHANNEL_SYMBOL],
|
||||||
|
methodDefinition: methodDefinition,
|
||||||
|
callOptions: checkedArguments.options,
|
||||||
|
};
|
||||||
|
if (this[CALL_INVOCATION_TRANSFORMER_SYMBOL]) {
|
||||||
|
callProperties = this[CALL_INVOCATION_TRANSFORMER_SYMBOL](callProperties);
|
||||||
|
}
|
||||||
|
const stream = callProperties.call;
|
||||||
|
const interceptorArgs = {
|
||||||
|
clientInterceptors: this[INTERCEPTOR_SYMBOL],
|
||||||
|
clientInterceptorProviders: this[INTERCEPTOR_PROVIDER_SYMBOL],
|
||||||
|
callInterceptors: (_a = callProperties.callOptions.interceptors) !== null && _a !== void 0 ? _a : [],
|
||||||
|
callInterceptorProviders: (_b = callProperties.callOptions.interceptor_providers) !== null && _b !== void 0 ? _b : [],
|
||||||
|
};
|
||||||
|
const call = (0, client_interceptors_1.getInterceptingCall)(interceptorArgs, callProperties.methodDefinition, callProperties.callOptions, callProperties.channel);
|
||||||
|
/* This needs to happen before the emitter is used. Unfortunately we can't
|
||||||
|
* enforce this with the type system. We need to construct this emitter
|
||||||
|
* before calling the CallInvocationTransformer, and we need to create the
|
||||||
|
* call after that. */
|
||||||
|
stream.call = call;
|
||||||
|
let receivedStatus = false;
|
||||||
|
let callerStackError = new Error();
|
||||||
|
call.start(callProperties.metadata, {
|
||||||
|
onReceiveMetadata(metadata) {
|
||||||
|
stream.emit('metadata', metadata);
|
||||||
|
},
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
onReceiveMessage(message) {
|
||||||
|
stream.push(message);
|
||||||
|
},
|
||||||
|
onReceiveStatus(status) {
|
||||||
|
if (receivedStatus) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
receivedStatus = true;
|
||||||
|
stream.push(null);
|
||||||
|
if (status.code !== constants_1.Status.OK) {
|
||||||
|
const callerStack = getErrorStackString(callerStackError);
|
||||||
|
stream.emit('error', (0, call_1.callErrorFromStatus)(status, callerStack));
|
||||||
|
}
|
||||||
|
/* Avoid retaining the callerStackError object in the call context of
|
||||||
|
* the status event handler. */
|
||||||
|
callerStackError = null;
|
||||||
|
stream.emit('status', status);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
call.sendMessage(argument);
|
||||||
|
call.halfClose();
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
makeBidiStreamRequest(method, serialize, deserialize, metadata, options) {
|
||||||
|
var _a, _b;
|
||||||
|
const checkedArguments = this.checkMetadataAndOptions(metadata, options);
|
||||||
|
const methodDefinition = {
|
||||||
|
path: method,
|
||||||
|
requestStream: true,
|
||||||
|
responseStream: true,
|
||||||
|
requestSerialize: serialize,
|
||||||
|
responseDeserialize: deserialize,
|
||||||
|
};
|
||||||
|
let callProperties = {
|
||||||
|
metadata: checkedArguments.metadata,
|
||||||
|
call: new call_1.ClientDuplexStreamImpl(serialize, deserialize),
|
||||||
|
channel: this[CHANNEL_SYMBOL],
|
||||||
|
methodDefinition: methodDefinition,
|
||||||
|
callOptions: checkedArguments.options,
|
||||||
|
};
|
||||||
|
if (this[CALL_INVOCATION_TRANSFORMER_SYMBOL]) {
|
||||||
|
callProperties = this[CALL_INVOCATION_TRANSFORMER_SYMBOL](callProperties);
|
||||||
|
}
|
||||||
|
const stream = callProperties.call;
|
||||||
|
const interceptorArgs = {
|
||||||
|
clientInterceptors: this[INTERCEPTOR_SYMBOL],
|
||||||
|
clientInterceptorProviders: this[INTERCEPTOR_PROVIDER_SYMBOL],
|
||||||
|
callInterceptors: (_a = callProperties.callOptions.interceptors) !== null && _a !== void 0 ? _a : [],
|
||||||
|
callInterceptorProviders: (_b = callProperties.callOptions.interceptor_providers) !== null && _b !== void 0 ? _b : [],
|
||||||
|
};
|
||||||
|
const call = (0, client_interceptors_1.getInterceptingCall)(interceptorArgs, callProperties.methodDefinition, callProperties.callOptions, callProperties.channel);
|
||||||
|
/* This needs to happen before the emitter is used. Unfortunately we can't
|
||||||
|
* enforce this with the type system. We need to construct this emitter
|
||||||
|
* before calling the CallInvocationTransformer, and we need to create the
|
||||||
|
* call after that. */
|
||||||
|
stream.call = call;
|
||||||
|
let receivedStatus = false;
|
||||||
|
let callerStackError = new Error();
|
||||||
|
call.start(callProperties.metadata, {
|
||||||
|
onReceiveMetadata(metadata) {
|
||||||
|
stream.emit('metadata', metadata);
|
||||||
|
},
|
||||||
|
onReceiveMessage(message) {
|
||||||
|
stream.push(message);
|
||||||
|
},
|
||||||
|
onReceiveStatus(status) {
|
||||||
|
if (receivedStatus) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
receivedStatus = true;
|
||||||
|
stream.push(null);
|
||||||
|
if (status.code !== constants_1.Status.OK) {
|
||||||
|
const callerStack = getErrorStackString(callerStackError);
|
||||||
|
stream.emit('error', (0, call_1.callErrorFromStatus)(status, callerStack));
|
||||||
|
}
|
||||||
|
/* Avoid retaining the callerStackError object in the call context of
|
||||||
|
* the status event handler. */
|
||||||
|
callerStackError = null;
|
||||||
|
stream.emit('status', status);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return stream;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.Client = Client;
|
||||||
|
//# sourceMappingURL=client.js.map
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,5 @@
|
||||||
|
export declare enum CompressionAlgorithms {
|
||||||
|
identity = 0,
|
||||||
|
deflate = 1,
|
||||||
|
gzip = 2
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
"use strict";
|
||||||
|
/*
|
||||||
|
* Copyright 2021 gRPC 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
|
||||||
|
*
|
||||||
|
* http://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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.CompressionAlgorithms = void 0;
|
||||||
|
var CompressionAlgorithms;
|
||||||
|
(function (CompressionAlgorithms) {
|
||||||
|
CompressionAlgorithms[CompressionAlgorithms["identity"] = 0] = "identity";
|
||||||
|
CompressionAlgorithms[CompressionAlgorithms["deflate"] = 1] = "deflate";
|
||||||
|
CompressionAlgorithms[CompressionAlgorithms["gzip"] = 2] = "gzip";
|
||||||
|
})(CompressionAlgorithms || (exports.CompressionAlgorithms = CompressionAlgorithms = {}));
|
||||||
|
//# sourceMappingURL=compression-algorithms.js.map
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"compression-algorithms.js","sourceRoot":"","sources":["../../src/compression-algorithms.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;;AAEH,IAAY,qBAIX;AAJD,WAAY,qBAAqB;IAC/B,yEAAY,CAAA;IACZ,uEAAW,CAAA;IACX,iEAAQ,CAAA;AACV,CAAC,EAJW,qBAAqB,qCAArB,qBAAqB,QAIhC"}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
import { WriteObject } from './call-interface';
|
||||||
|
import { Channel } from './channel';
|
||||||
|
import { ChannelOptions } from './channel-options';
|
||||||
|
import { BaseFilter, Filter, FilterFactory } from './filter';
|
||||||
|
import { Metadata } from './metadata';
|
||||||
|
type SharedCompressionFilterConfig = {
|
||||||
|
serverSupportedEncodingHeader?: string;
|
||||||
|
};
|
||||||
|
export declare class CompressionFilter extends BaseFilter implements Filter {
|
||||||
|
private sharedFilterConfig;
|
||||||
|
private sendCompression;
|
||||||
|
private receiveCompression;
|
||||||
|
private currentCompressionAlgorithm;
|
||||||
|
private maxReceiveMessageLength;
|
||||||
|
private maxSendMessageLength;
|
||||||
|
constructor(channelOptions: ChannelOptions, sharedFilterConfig: SharedCompressionFilterConfig);
|
||||||
|
sendMetadata(metadata: Promise<Metadata>): Promise<Metadata>;
|
||||||
|
receiveMetadata(metadata: Metadata): Metadata;
|
||||||
|
sendMessage(message: Promise<WriteObject>): Promise<WriteObject>;
|
||||||
|
receiveMessage(message: Promise<Buffer>): Promise<Buffer<ArrayBufferLike>>;
|
||||||
|
}
|
||||||
|
export declare class CompressionFilterFactory implements FilterFactory<CompressionFilter> {
|
||||||
|
private readonly options;
|
||||||
|
private sharedFilterConfig;
|
||||||
|
constructor(channel: Channel, options: ChannelOptions);
|
||||||
|
createFilter(): CompressionFilter;
|
||||||
|
}
|
||||||
|
export {};
|
||||||
|
|
@ -0,0 +1,307 @@
|
||||||
|
"use strict";
|
||||||
|
/*
|
||||||
|
* Copyright 2019 gRPC 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
|
||||||
|
*
|
||||||
|
* http://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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.CompressionFilterFactory = exports.CompressionFilter = void 0;
|
||||||
|
const zlib = require("zlib");
|
||||||
|
const compression_algorithms_1 = require("./compression-algorithms");
|
||||||
|
const constants_1 = require("./constants");
|
||||||
|
const filter_1 = require("./filter");
|
||||||
|
const logging = require("./logging");
|
||||||
|
const isCompressionAlgorithmKey = (key) => {
|
||||||
|
return (typeof key === 'number' && typeof compression_algorithms_1.CompressionAlgorithms[key] === 'string');
|
||||||
|
};
|
||||||
|
class CompressionHandler {
|
||||||
|
/**
|
||||||
|
* @param message Raw uncompressed message bytes
|
||||||
|
* @param compress Indicates whether the message should be compressed
|
||||||
|
* @return Framed message, compressed if applicable
|
||||||
|
*/
|
||||||
|
async writeMessage(message, compress) {
|
||||||
|
let messageBuffer = message;
|
||||||
|
if (compress) {
|
||||||
|
messageBuffer = await this.compressMessage(messageBuffer);
|
||||||
|
}
|
||||||
|
const output = Buffer.allocUnsafe(messageBuffer.length + 5);
|
||||||
|
output.writeUInt8(compress ? 1 : 0, 0);
|
||||||
|
output.writeUInt32BE(messageBuffer.length, 1);
|
||||||
|
messageBuffer.copy(output, 5);
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param data Framed message, possibly compressed
|
||||||
|
* @return Uncompressed message
|
||||||
|
*/
|
||||||
|
async readMessage(data) {
|
||||||
|
const compressed = data.readUInt8(0) === 1;
|
||||||
|
let messageBuffer = data.slice(5);
|
||||||
|
if (compressed) {
|
||||||
|
messageBuffer = await this.decompressMessage(messageBuffer);
|
||||||
|
}
|
||||||
|
return messageBuffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class IdentityHandler extends CompressionHandler {
|
||||||
|
async compressMessage(message) {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
async writeMessage(message, compress) {
|
||||||
|
const output = Buffer.allocUnsafe(message.length + 5);
|
||||||
|
/* With "identity" compression, messages should always be marked as
|
||||||
|
* uncompressed */
|
||||||
|
output.writeUInt8(0, 0);
|
||||||
|
output.writeUInt32BE(message.length, 1);
|
||||||
|
message.copy(output, 5);
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
decompressMessage(message) {
|
||||||
|
return Promise.reject(new Error('Received compressed message but "grpc-encoding" header was identity'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class DeflateHandler extends CompressionHandler {
|
||||||
|
constructor(maxRecvMessageLength) {
|
||||||
|
super();
|
||||||
|
this.maxRecvMessageLength = maxRecvMessageLength;
|
||||||
|
}
|
||||||
|
compressMessage(message) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
zlib.deflate(message, (err, output) => {
|
||||||
|
if (err) {
|
||||||
|
reject(err);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
resolve(output);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
decompressMessage(message) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
let totalLength = 0;
|
||||||
|
const messageParts = [];
|
||||||
|
const decompresser = zlib.createInflate();
|
||||||
|
decompresser.on('error', (error) => {
|
||||||
|
reject({
|
||||||
|
code: constants_1.Status.INTERNAL,
|
||||||
|
details: 'Failed to decompress deflate-encoded message'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
decompresser.on('data', (chunk) => {
|
||||||
|
messageParts.push(chunk);
|
||||||
|
totalLength += chunk.byteLength;
|
||||||
|
if (this.maxRecvMessageLength !== -1 && totalLength > this.maxRecvMessageLength) {
|
||||||
|
decompresser.destroy();
|
||||||
|
reject({
|
||||||
|
code: constants_1.Status.RESOURCE_EXHAUSTED,
|
||||||
|
details: `Received message that decompresses to a size larger than ${this.maxRecvMessageLength}`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
decompresser.on('end', () => {
|
||||||
|
resolve(Buffer.concat(messageParts));
|
||||||
|
});
|
||||||
|
decompresser.write(message);
|
||||||
|
decompresser.end();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class GzipHandler extends CompressionHandler {
|
||||||
|
constructor(maxRecvMessageLength) {
|
||||||
|
super();
|
||||||
|
this.maxRecvMessageLength = maxRecvMessageLength;
|
||||||
|
}
|
||||||
|
compressMessage(message) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
zlib.gzip(message, (err, output) => {
|
||||||
|
if (err) {
|
||||||
|
reject(err);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
resolve(output);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
decompressMessage(message) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
let totalLength = 0;
|
||||||
|
const messageParts = [];
|
||||||
|
const decompresser = zlib.createGunzip();
|
||||||
|
decompresser.on('error', (error) => {
|
||||||
|
reject({
|
||||||
|
code: constants_1.Status.INTERNAL,
|
||||||
|
details: 'Failed to decompress gzip-encoded message'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
decompresser.on('data', (chunk) => {
|
||||||
|
messageParts.push(chunk);
|
||||||
|
totalLength += chunk.byteLength;
|
||||||
|
if (this.maxRecvMessageLength !== -1 && totalLength > this.maxRecvMessageLength) {
|
||||||
|
decompresser.destroy();
|
||||||
|
reject({
|
||||||
|
code: constants_1.Status.RESOURCE_EXHAUSTED,
|
||||||
|
details: `Received message that decompresses to a size larger than ${this.maxRecvMessageLength}`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
decompresser.on('end', () => {
|
||||||
|
resolve(Buffer.concat(messageParts));
|
||||||
|
});
|
||||||
|
decompresser.write(message);
|
||||||
|
decompresser.end();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class UnknownHandler extends CompressionHandler {
|
||||||
|
constructor(compressionName) {
|
||||||
|
super();
|
||||||
|
this.compressionName = compressionName;
|
||||||
|
}
|
||||||
|
compressMessage(message) {
|
||||||
|
return Promise.reject(new Error(`Received message compressed with unsupported compression method ${this.compressionName}`));
|
||||||
|
}
|
||||||
|
decompressMessage(message) {
|
||||||
|
// This should be unreachable
|
||||||
|
return Promise.reject(new Error(`Compression method not supported: ${this.compressionName}`));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function getCompressionHandler(compressionName, maxReceiveMessageSize) {
|
||||||
|
switch (compressionName) {
|
||||||
|
case 'identity':
|
||||||
|
return new IdentityHandler();
|
||||||
|
case 'deflate':
|
||||||
|
return new DeflateHandler(maxReceiveMessageSize);
|
||||||
|
case 'gzip':
|
||||||
|
return new GzipHandler(maxReceiveMessageSize);
|
||||||
|
default:
|
||||||
|
return new UnknownHandler(compressionName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class CompressionFilter extends filter_1.BaseFilter {
|
||||||
|
constructor(channelOptions, sharedFilterConfig) {
|
||||||
|
var _a, _b, _c;
|
||||||
|
super();
|
||||||
|
this.sharedFilterConfig = sharedFilterConfig;
|
||||||
|
this.sendCompression = new IdentityHandler();
|
||||||
|
this.receiveCompression = new IdentityHandler();
|
||||||
|
this.currentCompressionAlgorithm = 'identity';
|
||||||
|
const compressionAlgorithmKey = channelOptions['grpc.default_compression_algorithm'];
|
||||||
|
this.maxReceiveMessageLength = (_a = channelOptions['grpc.max_receive_message_length']) !== null && _a !== void 0 ? _a : constants_1.DEFAULT_MAX_RECEIVE_MESSAGE_LENGTH;
|
||||||
|
this.maxSendMessageLength = (_b = channelOptions['grpc.max_send_message_length']) !== null && _b !== void 0 ? _b : constants_1.DEFAULT_MAX_SEND_MESSAGE_LENGTH;
|
||||||
|
if (compressionAlgorithmKey !== undefined) {
|
||||||
|
if (isCompressionAlgorithmKey(compressionAlgorithmKey)) {
|
||||||
|
const clientSelectedEncoding = compression_algorithms_1.CompressionAlgorithms[compressionAlgorithmKey];
|
||||||
|
const serverSupportedEncodings = (_c = sharedFilterConfig.serverSupportedEncodingHeader) === null || _c === void 0 ? void 0 : _c.split(',');
|
||||||
|
/**
|
||||||
|
* There are two possible situations here:
|
||||||
|
* 1) We don't have any info yet from the server about what compression it supports
|
||||||
|
* In that case we should just use what the client tells us to use
|
||||||
|
* 2) We've previously received a response from the server including a grpc-accept-encoding header
|
||||||
|
* In that case we only want to use the encoding chosen by the client if the server supports it
|
||||||
|
*/
|
||||||
|
if (!serverSupportedEncodings ||
|
||||||
|
serverSupportedEncodings.includes(clientSelectedEncoding)) {
|
||||||
|
this.currentCompressionAlgorithm = clientSelectedEncoding;
|
||||||
|
this.sendCompression = getCompressionHandler(this.currentCompressionAlgorithm, -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
logging.log(constants_1.LogVerbosity.ERROR, `Invalid value provided for grpc.default_compression_algorithm option: ${compressionAlgorithmKey}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async sendMetadata(metadata) {
|
||||||
|
const headers = await metadata;
|
||||||
|
headers.set('grpc-accept-encoding', 'identity,deflate,gzip');
|
||||||
|
headers.set('accept-encoding', 'identity');
|
||||||
|
// No need to send the header if it's "identity" - behavior is identical; save the bandwidth
|
||||||
|
if (this.currentCompressionAlgorithm === 'identity') {
|
||||||
|
headers.remove('grpc-encoding');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
headers.set('grpc-encoding', this.currentCompressionAlgorithm);
|
||||||
|
}
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
receiveMetadata(metadata) {
|
||||||
|
const receiveEncoding = metadata.get('grpc-encoding');
|
||||||
|
if (receiveEncoding.length > 0) {
|
||||||
|
const encoding = receiveEncoding[0];
|
||||||
|
if (typeof encoding === 'string') {
|
||||||
|
this.receiveCompression = getCompressionHandler(encoding, this.maxReceiveMessageLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
metadata.remove('grpc-encoding');
|
||||||
|
/* Check to see if the compression we're using to send messages is supported by the server
|
||||||
|
* If not, reset the sendCompression filter and have it use the default IdentityHandler */
|
||||||
|
const serverSupportedEncodingsHeader = metadata.get('grpc-accept-encoding')[0];
|
||||||
|
if (serverSupportedEncodingsHeader) {
|
||||||
|
this.sharedFilterConfig.serverSupportedEncodingHeader =
|
||||||
|
serverSupportedEncodingsHeader;
|
||||||
|
const serverSupportedEncodings = serverSupportedEncodingsHeader.split(',');
|
||||||
|
if (!serverSupportedEncodings.includes(this.currentCompressionAlgorithm)) {
|
||||||
|
this.sendCompression = new IdentityHandler();
|
||||||
|
this.currentCompressionAlgorithm = 'identity';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
metadata.remove('grpc-accept-encoding');
|
||||||
|
return metadata;
|
||||||
|
}
|
||||||
|
async sendMessage(message) {
|
||||||
|
var _a;
|
||||||
|
/* This filter is special. The input message is the bare message bytes,
|
||||||
|
* and the output is a framed and possibly compressed message. For this
|
||||||
|
* reason, this filter should be at the bottom of the filter stack */
|
||||||
|
const resolvedMessage = await message;
|
||||||
|
if (this.maxSendMessageLength !== -1 && resolvedMessage.message.length > this.maxSendMessageLength) {
|
||||||
|
throw {
|
||||||
|
code: constants_1.Status.RESOURCE_EXHAUSTED,
|
||||||
|
details: `Attempted to send message with a size larger than ${this.maxSendMessageLength}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
let compress;
|
||||||
|
if (this.sendCompression instanceof IdentityHandler) {
|
||||||
|
compress = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
compress = (((_a = resolvedMessage.flags) !== null && _a !== void 0 ? _a : 0) & 2 /* WriteFlags.NoCompress */) === 0;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
message: await this.sendCompression.writeMessage(resolvedMessage.message, compress),
|
||||||
|
flags: resolvedMessage.flags,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
async receiveMessage(message) {
|
||||||
|
/* This filter is also special. The input message is framed and possibly
|
||||||
|
* compressed, and the output message is deframed and uncompressed. So
|
||||||
|
* this is another reason that this filter should be at the bottom of the
|
||||||
|
* filter stack. */
|
||||||
|
return this.receiveCompression.readMessage(await message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.CompressionFilter = CompressionFilter;
|
||||||
|
class CompressionFilterFactory {
|
||||||
|
constructor(channel, options) {
|
||||||
|
this.options = options;
|
||||||
|
this.sharedFilterConfig = {};
|
||||||
|
}
|
||||||
|
createFilter() {
|
||||||
|
return new CompressionFilter(this.options, this.sharedFilterConfig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.CompressionFilterFactory = CompressionFilterFactory;
|
||||||
|
//# sourceMappingURL=compression-filter.js.map
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,7 @@
|
||||||
|
export declare enum ConnectivityState {
|
||||||
|
IDLE = 0,
|
||||||
|
CONNECTING = 1,
|
||||||
|
READY = 2,
|
||||||
|
TRANSIENT_FAILURE = 3,
|
||||||
|
SHUTDOWN = 4
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
"use strict";
|
||||||
|
/*
|
||||||
|
* Copyright 2021 gRPC 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
|
||||||
|
*
|
||||||
|
* http://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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.ConnectivityState = void 0;
|
||||||
|
var ConnectivityState;
|
||||||
|
(function (ConnectivityState) {
|
||||||
|
ConnectivityState[ConnectivityState["IDLE"] = 0] = "IDLE";
|
||||||
|
ConnectivityState[ConnectivityState["CONNECTING"] = 1] = "CONNECTING";
|
||||||
|
ConnectivityState[ConnectivityState["READY"] = 2] = "READY";
|
||||||
|
ConnectivityState[ConnectivityState["TRANSIENT_FAILURE"] = 3] = "TRANSIENT_FAILURE";
|
||||||
|
ConnectivityState[ConnectivityState["SHUTDOWN"] = 4] = "SHUTDOWN";
|
||||||
|
})(ConnectivityState || (exports.ConnectivityState = ConnectivityState = {}));
|
||||||
|
//# sourceMappingURL=connectivity-state.js.map
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"connectivity-state.js","sourceRoot":"","sources":["../../src/connectivity-state.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;;AAEH,IAAY,iBAMX;AAND,WAAY,iBAAiB;IAC3B,yDAAI,CAAA;IACJ,qEAAU,CAAA;IACV,2DAAK,CAAA;IACL,mFAAiB,CAAA;IACjB,iEAAQ,CAAA;AACV,CAAC,EANW,iBAAiB,iCAAjB,iBAAiB,QAM5B"}
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
export declare enum Status {
|
||||||
|
OK = 0,
|
||||||
|
CANCELLED = 1,
|
||||||
|
UNKNOWN = 2,
|
||||||
|
INVALID_ARGUMENT = 3,
|
||||||
|
DEADLINE_EXCEEDED = 4,
|
||||||
|
NOT_FOUND = 5,
|
||||||
|
ALREADY_EXISTS = 6,
|
||||||
|
PERMISSION_DENIED = 7,
|
||||||
|
RESOURCE_EXHAUSTED = 8,
|
||||||
|
FAILED_PRECONDITION = 9,
|
||||||
|
ABORTED = 10,
|
||||||
|
OUT_OF_RANGE = 11,
|
||||||
|
UNIMPLEMENTED = 12,
|
||||||
|
INTERNAL = 13,
|
||||||
|
UNAVAILABLE = 14,
|
||||||
|
DATA_LOSS = 15,
|
||||||
|
UNAUTHENTICATED = 16
|
||||||
|
}
|
||||||
|
export declare enum LogVerbosity {
|
||||||
|
DEBUG = 0,
|
||||||
|
INFO = 1,
|
||||||
|
ERROR = 2,
|
||||||
|
NONE = 3
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* NOTE: This enum is not currently used in any implemented API in this
|
||||||
|
* library. It is included only for type parity with the other implementation.
|
||||||
|
*/
|
||||||
|
export declare enum Propagate {
|
||||||
|
DEADLINE = 1,
|
||||||
|
CENSUS_STATS_CONTEXT = 2,
|
||||||
|
CENSUS_TRACING_CONTEXT = 4,
|
||||||
|
CANCELLATION = 8,
|
||||||
|
DEFAULTS = 65535
|
||||||
|
}
|
||||||
|
export declare const DEFAULT_MAX_SEND_MESSAGE_LENGTH = -1;
|
||||||
|
export declare const DEFAULT_MAX_RECEIVE_MESSAGE_LENGTH: number;
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
"use strict";
|
||||||
|
/*
|
||||||
|
* Copyright 2019 gRPC 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
|
||||||
|
*
|
||||||
|
* http://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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.DEFAULT_MAX_RECEIVE_MESSAGE_LENGTH = exports.DEFAULT_MAX_SEND_MESSAGE_LENGTH = exports.Propagate = exports.LogVerbosity = exports.Status = void 0;
|
||||||
|
var Status;
|
||||||
|
(function (Status) {
|
||||||
|
Status[Status["OK"] = 0] = "OK";
|
||||||
|
Status[Status["CANCELLED"] = 1] = "CANCELLED";
|
||||||
|
Status[Status["UNKNOWN"] = 2] = "UNKNOWN";
|
||||||
|
Status[Status["INVALID_ARGUMENT"] = 3] = "INVALID_ARGUMENT";
|
||||||
|
Status[Status["DEADLINE_EXCEEDED"] = 4] = "DEADLINE_EXCEEDED";
|
||||||
|
Status[Status["NOT_FOUND"] = 5] = "NOT_FOUND";
|
||||||
|
Status[Status["ALREADY_EXISTS"] = 6] = "ALREADY_EXISTS";
|
||||||
|
Status[Status["PERMISSION_DENIED"] = 7] = "PERMISSION_DENIED";
|
||||||
|
Status[Status["RESOURCE_EXHAUSTED"] = 8] = "RESOURCE_EXHAUSTED";
|
||||||
|
Status[Status["FAILED_PRECONDITION"] = 9] = "FAILED_PRECONDITION";
|
||||||
|
Status[Status["ABORTED"] = 10] = "ABORTED";
|
||||||
|
Status[Status["OUT_OF_RANGE"] = 11] = "OUT_OF_RANGE";
|
||||||
|
Status[Status["UNIMPLEMENTED"] = 12] = "UNIMPLEMENTED";
|
||||||
|
Status[Status["INTERNAL"] = 13] = "INTERNAL";
|
||||||
|
Status[Status["UNAVAILABLE"] = 14] = "UNAVAILABLE";
|
||||||
|
Status[Status["DATA_LOSS"] = 15] = "DATA_LOSS";
|
||||||
|
Status[Status["UNAUTHENTICATED"] = 16] = "UNAUTHENTICATED";
|
||||||
|
})(Status || (exports.Status = Status = {}));
|
||||||
|
var LogVerbosity;
|
||||||
|
(function (LogVerbosity) {
|
||||||
|
LogVerbosity[LogVerbosity["DEBUG"] = 0] = "DEBUG";
|
||||||
|
LogVerbosity[LogVerbosity["INFO"] = 1] = "INFO";
|
||||||
|
LogVerbosity[LogVerbosity["ERROR"] = 2] = "ERROR";
|
||||||
|
LogVerbosity[LogVerbosity["NONE"] = 3] = "NONE";
|
||||||
|
})(LogVerbosity || (exports.LogVerbosity = LogVerbosity = {}));
|
||||||
|
/**
|
||||||
|
* NOTE: This enum is not currently used in any implemented API in this
|
||||||
|
* library. It is included only for type parity with the other implementation.
|
||||||
|
*/
|
||||||
|
var Propagate;
|
||||||
|
(function (Propagate) {
|
||||||
|
Propagate[Propagate["DEADLINE"] = 1] = "DEADLINE";
|
||||||
|
Propagate[Propagate["CENSUS_STATS_CONTEXT"] = 2] = "CENSUS_STATS_CONTEXT";
|
||||||
|
Propagate[Propagate["CENSUS_TRACING_CONTEXT"] = 4] = "CENSUS_TRACING_CONTEXT";
|
||||||
|
Propagate[Propagate["CANCELLATION"] = 8] = "CANCELLATION";
|
||||||
|
// https://github.com/grpc/grpc/blob/master/include/grpc/impl/codegen/propagation_bits.h#L43
|
||||||
|
Propagate[Propagate["DEFAULTS"] = 65535] = "DEFAULTS";
|
||||||
|
})(Propagate || (exports.Propagate = Propagate = {}));
|
||||||
|
// -1 means unlimited
|
||||||
|
exports.DEFAULT_MAX_SEND_MESSAGE_LENGTH = -1;
|
||||||
|
// 4 MB default
|
||||||
|
exports.DEFAULT_MAX_RECEIVE_MESSAGE_LENGTH = 4 * 1024 * 1024;
|
||||||
|
//# sourceMappingURL=constants.js.map
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;;AAEH,IAAY,MAkBX;AAlBD,WAAY,MAAM;IAChB,+BAAM,CAAA;IACN,6CAAS,CAAA;IACT,yCAAO,CAAA;IACP,2DAAgB,CAAA;IAChB,6DAAiB,CAAA;IACjB,6CAAS,CAAA;IACT,uDAAc,CAAA;IACd,6DAAiB,CAAA;IACjB,+DAAkB,CAAA;IAClB,iEAAmB,CAAA;IACnB,0CAAO,CAAA;IACP,oDAAY,CAAA;IACZ,sDAAa,CAAA;IACb,4CAAQ,CAAA;IACR,kDAAW,CAAA;IACX,8CAAS,CAAA;IACT,0DAAe,CAAA;AACjB,CAAC,EAlBW,MAAM,sBAAN,MAAM,QAkBjB;AAED,IAAY,YAKX;AALD,WAAY,YAAY;IACtB,iDAAS,CAAA;IACT,+CAAI,CAAA;IACJ,iDAAK,CAAA;IACL,+CAAI,CAAA;AACN,CAAC,EALW,YAAY,4BAAZ,YAAY,QAKvB;AAED;;;GAGG;AACH,IAAY,SAWX;AAXD,WAAY,SAAS;IACnB,iDAAY,CAAA;IACZ,yEAAwB,CAAA;IACxB,6EAA0B,CAAA;IAC1B,yDAAgB,CAAA;IAChB,4FAA4F;IAC5F,qDAIwB,CAAA;AAC1B,CAAC,EAXW,SAAS,yBAAT,SAAS,QAWpB;AAED,qBAAqB;AACR,QAAA,+BAA+B,GAAG,CAAC,CAAC,CAAC;AAElD,eAAe;AACF,QAAA,kCAAkC,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC"}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { Status } from './constants';
|
||||||
|
export declare function restrictControlPlaneStatusCode(code: Status, details: string): {
|
||||||
|
code: Status;
|
||||||
|
details: string;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
"use strict";
|
||||||
|
/*
|
||||||
|
* Copyright 2022 gRPC 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
|
||||||
|
*
|
||||||
|
* http://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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.restrictControlPlaneStatusCode = restrictControlPlaneStatusCode;
|
||||||
|
const constants_1 = require("./constants");
|
||||||
|
const INAPPROPRIATE_CONTROL_PLANE_CODES = [
|
||||||
|
constants_1.Status.OK,
|
||||||
|
constants_1.Status.INVALID_ARGUMENT,
|
||||||
|
constants_1.Status.NOT_FOUND,
|
||||||
|
constants_1.Status.ALREADY_EXISTS,
|
||||||
|
constants_1.Status.FAILED_PRECONDITION,
|
||||||
|
constants_1.Status.ABORTED,
|
||||||
|
constants_1.Status.OUT_OF_RANGE,
|
||||||
|
constants_1.Status.DATA_LOSS,
|
||||||
|
];
|
||||||
|
function restrictControlPlaneStatusCode(code, details) {
|
||||||
|
if (INAPPROPRIATE_CONTROL_PLANE_CODES.includes(code)) {
|
||||||
|
return {
|
||||||
|
code: constants_1.Status.INTERNAL,
|
||||||
|
details: `Invalid status from control plane: ${code} ${constants_1.Status[code]} ${details}`,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return { code, details };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//# sourceMappingURL=control-plane-status.js.map
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"control-plane-status.js","sourceRoot":"","sources":["../../src/control-plane-status.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;AAeH,wEAYC;AAzBD,2CAAqC;AAErC,MAAM,iCAAiC,GAAa;IAClD,kBAAM,CAAC,EAAE;IACT,kBAAM,CAAC,gBAAgB;IACvB,kBAAM,CAAC,SAAS;IAChB,kBAAM,CAAC,cAAc;IACrB,kBAAM,CAAC,mBAAmB;IAC1B,kBAAM,CAAC,OAAO;IACd,kBAAM,CAAC,YAAY;IACnB,kBAAM,CAAC,SAAS;CACjB,CAAC;AAEF,SAAgB,8BAA8B,CAC5C,IAAY,EACZ,OAAe;IAEf,IAAI,iCAAiC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACrD,OAAO;YACL,IAAI,EAAE,kBAAM,CAAC,QAAQ;YACrB,OAAO,EAAE,sCAAsC,IAAI,IAAI,kBAAM,CAAC,IAAI,CAAC,IAAI,OAAO,EAAE;SACjF,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAC3B,CAAC;AACH,CAAC"}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
export type Deadline = Date | number;
|
||||||
|
export declare function minDeadline(...deadlineList: Deadline[]): Deadline;
|
||||||
|
export declare function getDeadlineTimeoutString(deadline: Deadline): string;
|
||||||
|
/**
|
||||||
|
* Get the timeout value that should be passed to setTimeout now for the timer
|
||||||
|
* to end at the deadline. For any deadline before now, the timer should end
|
||||||
|
* immediately, represented by a value of 0. For any deadline more than
|
||||||
|
* MAX_TIMEOUT_TIME milliseconds in the future, a timer cannot be set that will
|
||||||
|
* end at that time, so it is treated as infinitely far in the future.
|
||||||
|
* @param deadline
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export declare function getRelativeTimeout(deadline: Deadline): number;
|
||||||
|
export declare function deadlineToString(deadline: Deadline): string;
|
||||||
|
/**
|
||||||
|
* Calculate the difference between two dates as a number of seconds and format
|
||||||
|
* it as a string.
|
||||||
|
* @param startDate
|
||||||
|
* @param endDate
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export declare function formatDateDifference(startDate: Date, endDate: Date): string;
|
||||||
|
|
@ -0,0 +1,108 @@
|
||||||
|
"use strict";
|
||||||
|
/*
|
||||||
|
* Copyright 2019 gRPC 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
|
||||||
|
*
|
||||||
|
* http://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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.minDeadline = minDeadline;
|
||||||
|
exports.getDeadlineTimeoutString = getDeadlineTimeoutString;
|
||||||
|
exports.getRelativeTimeout = getRelativeTimeout;
|
||||||
|
exports.deadlineToString = deadlineToString;
|
||||||
|
exports.formatDateDifference = formatDateDifference;
|
||||||
|
function minDeadline(...deadlineList) {
|
||||||
|
let minValue = Infinity;
|
||||||
|
for (const deadline of deadlineList) {
|
||||||
|
const deadlineMsecs = deadline instanceof Date ? deadline.getTime() : deadline;
|
||||||
|
if (deadlineMsecs < minValue) {
|
||||||
|
minValue = deadlineMsecs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return minValue;
|
||||||
|
}
|
||||||
|
const units = [
|
||||||
|
['m', 1],
|
||||||
|
['S', 1000],
|
||||||
|
['M', 60 * 1000],
|
||||||
|
['H', 60 * 60 * 1000],
|
||||||
|
];
|
||||||
|
function getDeadlineTimeoutString(deadline) {
|
||||||
|
const now = new Date().getTime();
|
||||||
|
if (deadline instanceof Date) {
|
||||||
|
deadline = deadline.getTime();
|
||||||
|
}
|
||||||
|
const timeoutMs = Math.max(deadline - now, 0);
|
||||||
|
for (const [unit, factor] of units) {
|
||||||
|
const amount = timeoutMs / factor;
|
||||||
|
if (amount < 1e8) {
|
||||||
|
return String(Math.ceil(amount)) + unit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new Error('Deadline is too far in the future');
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* See https://nodejs.org/api/timers.html#settimeoutcallback-delay-args
|
||||||
|
* In particular, "When delay is larger than 2147483647 or less than 1, the
|
||||||
|
* delay will be set to 1. Non-integer delays are truncated to an integer."
|
||||||
|
* This number of milliseconds is almost 25 days.
|
||||||
|
*/
|
||||||
|
const MAX_TIMEOUT_TIME = 2147483647;
|
||||||
|
/**
|
||||||
|
* Get the timeout value that should be passed to setTimeout now for the timer
|
||||||
|
* to end at the deadline. For any deadline before now, the timer should end
|
||||||
|
* immediately, represented by a value of 0. For any deadline more than
|
||||||
|
* MAX_TIMEOUT_TIME milliseconds in the future, a timer cannot be set that will
|
||||||
|
* end at that time, so it is treated as infinitely far in the future.
|
||||||
|
* @param deadline
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function getRelativeTimeout(deadline) {
|
||||||
|
const deadlineMs = deadline instanceof Date ? deadline.getTime() : deadline;
|
||||||
|
const now = new Date().getTime();
|
||||||
|
const timeout = deadlineMs - now;
|
||||||
|
if (timeout < 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (timeout > MAX_TIMEOUT_TIME) {
|
||||||
|
return Infinity;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return timeout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function deadlineToString(deadline) {
|
||||||
|
if (deadline instanceof Date) {
|
||||||
|
return deadline.toISOString();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const dateDeadline = new Date(deadline);
|
||||||
|
if (Number.isNaN(dateDeadline.getTime())) {
|
||||||
|
return '' + deadline;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return dateDeadline.toISOString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Calculate the difference between two dates as a number of seconds and format
|
||||||
|
* it as a string.
|
||||||
|
* @param startDate
|
||||||
|
* @param endDate
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function formatDateDifference(startDate, endDate) {
|
||||||
|
return ((endDate.getTime() - startDate.getTime()) / 1000).toFixed(3) + 's';
|
||||||
|
}
|
||||||
|
//# sourceMappingURL=deadline.js.map
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"deadline.js","sourceRoot":"","sources":["../../src/deadline.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;AAIH,kCAUC;AASD,4DAaC;AAmBD,gDAWC;AAED,4CAWC;AASD,oDAEC;AAtFD,SAAgB,WAAW,CAAC,GAAG,YAAwB;IACrD,IAAI,QAAQ,GAAG,QAAQ,CAAC;IACxB,KAAK,MAAM,QAAQ,IAAI,YAAY,EAAE,CAAC;QACpC,MAAM,aAAa,GACjB,QAAQ,YAAY,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;QAC3D,IAAI,aAAa,GAAG,QAAQ,EAAE,CAAC;YAC7B,QAAQ,GAAG,aAAa,CAAC;QAC3B,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,KAAK,GAA4B;IACrC,CAAC,GAAG,EAAE,CAAC,CAAC;IACR,CAAC,GAAG,EAAE,IAAI,CAAC;IACX,CAAC,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC;IAChB,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;CACtB,CAAC;AAEF,SAAgB,wBAAwB,CAAC,QAAkB;IACzD,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;IACjC,IAAI,QAAQ,YAAY,IAAI,EAAE,CAAC;QAC7B,QAAQ,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC;IAChC,CAAC;IACD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;IAC9C,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC;QAClC,IAAI,MAAM,GAAG,GAAG,EAAE,CAAC;YACjB,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC;QAC1C,CAAC;IACH,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;AACvD,CAAC;AAED;;;;;GAKG;AACH,MAAM,gBAAgB,GAAG,UAAU,CAAC;AAEpC;;;;;;;;GAQG;AACH,SAAgB,kBAAkB,CAAC,QAAkB;IACnD,MAAM,UAAU,GAAG,QAAQ,YAAY,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC5E,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;IACjC,MAAM,OAAO,GAAG,UAAU,GAAG,GAAG,CAAC;IACjC,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;QAChB,OAAO,CAAC,CAAC;IACX,CAAC;SAAM,IAAI,OAAO,GAAG,gBAAgB,EAAE,CAAC;QACtC,OAAO,QAAQ,CAAC;IAClB,CAAC;SAAM,CAAC;QACN,OAAO,OAAO,CAAC;IACjB,CAAC;AACH,CAAC;AAED,SAAgB,gBAAgB,CAAC,QAAkB;IACjD,IAAI,QAAQ,YAAY,IAAI,EAAE,CAAC;QAC7B,OAAO,QAAQ,CAAC,WAAW,EAAE,CAAC;IAChC,CAAC;SAAM,CAAC;QACN,MAAM,YAAY,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxC,IAAI,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;YACzC,OAAO,EAAE,GAAG,QAAQ,CAAC;QACvB,CAAC;aAAM,CAAC;YACN,OAAO,YAAY,CAAC,WAAW,EAAE,CAAC;QACpC,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,oBAAoB,CAAC,SAAe,EAAE,OAAa;IACjE,OAAO,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;AAC7E,CAAC"}
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
export interface Duration {
|
||||||
|
seconds: number;
|
||||||
|
nanos: number;
|
||||||
|
}
|
||||||
|
export interface DurationMessage {
|
||||||
|
seconds: string;
|
||||||
|
nanos: number;
|
||||||
|
}
|
||||||
|
export declare function durationMessageToDuration(message: DurationMessage): Duration;
|
||||||
|
export declare function msToDuration(millis: number): Duration;
|
||||||
|
export declare function durationToMs(duration: Duration): number;
|
||||||
|
export declare function isDuration(value: any): value is Duration;
|
||||||
|
export declare function isDurationMessage(value: any): value is DurationMessage;
|
||||||
|
export declare function parseDuration(value: string): Duration | null;
|
||||||
|
export declare function durationToString(duration: Duration): string;
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
"use strict";
|
||||||
|
/*
|
||||||
|
* Copyright 2022 gRPC 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
|
||||||
|
*
|
||||||
|
* http://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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.durationMessageToDuration = durationMessageToDuration;
|
||||||
|
exports.msToDuration = msToDuration;
|
||||||
|
exports.durationToMs = durationToMs;
|
||||||
|
exports.isDuration = isDuration;
|
||||||
|
exports.isDurationMessage = isDurationMessage;
|
||||||
|
exports.parseDuration = parseDuration;
|
||||||
|
exports.durationToString = durationToString;
|
||||||
|
function durationMessageToDuration(message) {
|
||||||
|
return {
|
||||||
|
seconds: Number.parseInt(message.seconds),
|
||||||
|
nanos: message.nanos
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function msToDuration(millis) {
|
||||||
|
return {
|
||||||
|
seconds: (millis / 1000) | 0,
|
||||||
|
nanos: ((millis % 1000) * 1000000) | 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function durationToMs(duration) {
|
||||||
|
return (duration.seconds * 1000 + duration.nanos / 1000000) | 0;
|
||||||
|
}
|
||||||
|
function isDuration(value) {
|
||||||
|
return typeof value.seconds === 'number' && typeof value.nanos === 'number';
|
||||||
|
}
|
||||||
|
function isDurationMessage(value) {
|
||||||
|
return typeof value.seconds === 'string' && typeof value.nanos === 'number';
|
||||||
|
}
|
||||||
|
const durationRegex = /^(\d+)(?:\.(\d+))?s$/;
|
||||||
|
function parseDuration(value) {
|
||||||
|
const match = value.match(durationRegex);
|
||||||
|
if (!match) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
seconds: Number.parseInt(match[1], 10),
|
||||||
|
nanos: match[2] ? Number.parseInt(match[2].padEnd(9, '0'), 10) : 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function durationToString(duration) {
|
||||||
|
if (duration.nanos === 0) {
|
||||||
|
return `${duration.seconds}s`;
|
||||||
|
}
|
||||||
|
let scaleFactor;
|
||||||
|
if (duration.nanos % 1000000 === 0) {
|
||||||
|
scaleFactor = 1000000;
|
||||||
|
}
|
||||||
|
else if (duration.nanos % 1000 === 0) {
|
||||||
|
scaleFactor = 1000;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
scaleFactor = 1;
|
||||||
|
}
|
||||||
|
return `${duration.seconds}.${duration.nanos / scaleFactor}s`;
|
||||||
|
}
|
||||||
|
//# sourceMappingURL=duration.js.map
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"duration.js","sourceRoot":"","sources":["../../src/duration.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;AAYH,8DAKC;AAED,oCAKC;AAED,oCAEC;AAED,gCAEC;AAED,8CAEC;AAGD,sCASC;AAED,4CAaC;AAnDD,SAAgB,yBAAyB,CAAC,OAAwB;IAChE,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC;QACzC,KAAK,EAAE,OAAO,CAAC,KAAK;KACrB,CAAC;AACJ,CAAC;AAED,SAAgB,YAAY,CAAC,MAAc;IACzC,OAAO;QACL,OAAO,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC;QAC5B,KAAK,EAAE,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,OAAS,CAAC,GAAG,CAAC;KACzC,CAAC;AACJ,CAAC;AAED,SAAgB,YAAY,CAAC,QAAkB;IAC7C,OAAO,CAAC,QAAQ,CAAC,OAAO,GAAG,IAAI,GAAG,QAAQ,CAAC,KAAK,GAAG,OAAS,CAAC,GAAG,CAAC,CAAC;AACpE,CAAC;AAED,SAAgB,UAAU,CAAC,KAAU;IACnC,OAAO,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC;AAC9E,CAAC;AAED,SAAgB,iBAAiB,CAAC,KAAU;IAC1C,OAAO,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC;AAC9E,CAAC;AAED,MAAM,aAAa,GAAG,sBAAsB,CAAC;AAC7C,SAAgB,aAAa,CAAC,KAAa;IACzC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IACzC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QACtC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;KACnE,CAAC;AACJ,CAAC;AAED,SAAgB,gBAAgB,CAAC,QAAkB;IACjD,IAAI,QAAQ,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,GAAG,QAAQ,CAAC,OAAO,GAAG,CAAC;IAChC,CAAC;IACD,IAAI,WAAmB,CAAC;IACxB,IAAI,QAAQ,CAAC,KAAK,GAAG,OAAS,KAAK,CAAC,EAAE,CAAC;QACrC,WAAW,GAAG,OAAS,CAAC;IAC1B,CAAC;SAAM,IAAI,QAAQ,CAAC,KAAK,GAAG,IAAK,KAAK,CAAC,EAAE,CAAC;QACxC,WAAW,GAAG,IAAK,CAAC;IACtB,CAAC;SAAM,CAAC;QACN,WAAW,GAAG,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,GAAG,QAAQ,CAAC,OAAO,IAAI,QAAQ,CAAC,KAAK,GAAC,WAAW,GAAG,CAAC;AAC9D,CAAC"}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
export declare const GRPC_NODE_USE_ALTERNATIVE_RESOLVER: boolean;
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
"use strict";
|
||||||
|
/*
|
||||||
|
* Copyright 2024 gRPC 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
|
||||||
|
*
|
||||||
|
* http://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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
var _a;
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.GRPC_NODE_USE_ALTERNATIVE_RESOLVER = void 0;
|
||||||
|
exports.GRPC_NODE_USE_ALTERNATIVE_RESOLVER = ((_a = process.env.GRPC_NODE_USE_ALTERNATIVE_RESOLVER) !== null && _a !== void 0 ? _a : 'false') === 'true';
|
||||||
|
//# sourceMappingURL=environment.js.map
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"environment.js","sourceRoot":"","sources":["../../src/environment.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;;;AAEU,QAAA,kCAAkC,GAC7C,CAAC,MAAA,OAAO,CAAC,GAAG,CAAC,kCAAkC,mCAAI,OAAO,CAAC,KAAK,MAAM,CAAC"}
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
export declare function getErrorMessage(error: unknown): string;
|
||||||
|
export declare function getErrorCode(error: unknown): number | null;
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
"use strict";
|
||||||
|
/*
|
||||||
|
* Copyright 2022 gRPC 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
|
||||||
|
*
|
||||||
|
* http://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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.getErrorMessage = getErrorMessage;
|
||||||
|
exports.getErrorCode = getErrorCode;
|
||||||
|
function getErrorMessage(error) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
return error.message;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return String(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function getErrorCode(error) {
|
||||||
|
if (typeof error === 'object' &&
|
||||||
|
error !== null &&
|
||||||
|
'code' in error &&
|
||||||
|
typeof error.code === 'number') {
|
||||||
|
return error.code;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//# sourceMappingURL=error.js.map
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"error.js","sourceRoot":"","sources":["../../src/error.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;AAEH,0CAMC;AAED,oCAWC;AAnBD,SAAgB,eAAe,CAAC,KAAc;IAC5C,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC,OAAO,CAAC;IACvB,CAAC;SAAM,CAAC;QACN,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;AACH,CAAC;AAED,SAAgB,YAAY,CAAC,KAAc;IACzC,IACE,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,MAAM,IAAI,KAAK;QACf,OAAQ,KAAiC,CAAC,IAAI,KAAK,QAAQ,EAC3D,CAAC;QACD,OAAQ,KAAgC,CAAC,IAAI,CAAC;IAChD,CAAC;SAAM,CAAC;QACN,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
export interface EmitterAugmentation1<Name extends string | symbol, Arg> {
|
||||||
|
addListener(event: Name, listener: (arg1: Arg) => void): this;
|
||||||
|
emit(event: Name, arg1: Arg): boolean;
|
||||||
|
on(event: Name, listener: (arg1: Arg) => void): this;
|
||||||
|
once(event: Name, listener: (arg1: Arg) => void): this;
|
||||||
|
prependListener(event: Name, listener: (arg1: Arg) => void): this;
|
||||||
|
prependOnceListener(event: Name, listener: (arg1: Arg) => void): this;
|
||||||
|
removeListener(event: Name, listener: (arg1: Arg) => void): this;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
"use strict";
|
||||||
|
/*
|
||||||
|
* Copyright 2019 gRPC 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
|
||||||
|
*
|
||||||
|
* http://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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
//# sourceMappingURL=events.js.map
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/events.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG"}
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
export { trace, log } from './logging';
|
||||||
|
export { Resolver, ResolverListener, registerResolver, ConfigSelector, createResolver, CHANNEL_ARGS_CONFIG_SELECTOR_KEY, } from './resolver';
|
||||||
|
export { GrpcUri, uriToString, splitHostPort, HostPort } from './uri-parser';
|
||||||
|
export { Duration, durationToMs, parseDuration } from './duration';
|
||||||
|
export { BackoffTimeout } from './backoff-timeout';
|
||||||
|
export { LoadBalancer, TypedLoadBalancingConfig, ChannelControlHelper, createChildChannelControlHelper, registerLoadBalancerType, selectLbConfigFromList, parseLoadBalancingConfig, isLoadBalancerNameRegistered, } from './load-balancer';
|
||||||
|
export { LeafLoadBalancer } from './load-balancer-pick-first';
|
||||||
|
export { SubchannelAddress, subchannelAddressToString, Endpoint, endpointToString, endpointHasAddress, EndpointMap, } from './subchannel-address';
|
||||||
|
export { ChildLoadBalancerHandler } from './load-balancer-child-handler';
|
||||||
|
export { Picker, UnavailablePicker, QueuePicker, PickResult, PickArgs, PickResultType, } from './picker';
|
||||||
|
export { Call as CallStream, StatusOr, statusOrFromValue, statusOrFromError } from './call-interface';
|
||||||
|
export { Filter, BaseFilter, FilterFactory } from './filter';
|
||||||
|
export { FilterStackFactory } from './filter-stack';
|
||||||
|
export { registerAdminService } from './admin';
|
||||||
|
export { SubchannelInterface, BaseSubchannelWrapper, ConnectivityStateListener, HealthListener, } from './subchannel-interface';
|
||||||
|
export { OutlierDetectionRawConfig, SuccessRateEjectionConfig, FailurePercentageEjectionConfig, } from './load-balancer-outlier-detection';
|
||||||
|
export { createServerCredentialsWithInterceptors, createCertificateProviderServerCredentials } from './server-credentials';
|
||||||
|
export { CaCertificateUpdate, CaCertificateUpdateListener, IdentityCertificateUpdate, IdentityCertificateUpdateListener, CertificateProvider, FileWatcherCertificateProvider, FileWatcherCertificateProviderConfig } from './certificate-provider';
|
||||||
|
export { createCertificateProviderChannelCredentials, SecureConnector, SecureConnectResult } from './channel-credentials';
|
||||||
|
export { SUBCHANNEL_ARGS_EXCLUDE_KEY_PREFIX } from './internal-channel';
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.SUBCHANNEL_ARGS_EXCLUDE_KEY_PREFIX = exports.createCertificateProviderChannelCredentials = exports.FileWatcherCertificateProvider = exports.createCertificateProviderServerCredentials = exports.createServerCredentialsWithInterceptors = exports.BaseSubchannelWrapper = exports.registerAdminService = exports.FilterStackFactory = exports.BaseFilter = exports.statusOrFromError = exports.statusOrFromValue = exports.PickResultType = exports.QueuePicker = exports.UnavailablePicker = exports.ChildLoadBalancerHandler = exports.EndpointMap = exports.endpointHasAddress = exports.endpointToString = exports.subchannelAddressToString = exports.LeafLoadBalancer = exports.isLoadBalancerNameRegistered = exports.parseLoadBalancingConfig = exports.selectLbConfigFromList = exports.registerLoadBalancerType = exports.createChildChannelControlHelper = exports.BackoffTimeout = exports.parseDuration = exports.durationToMs = exports.splitHostPort = exports.uriToString = exports.CHANNEL_ARGS_CONFIG_SELECTOR_KEY = exports.createResolver = exports.registerResolver = exports.log = exports.trace = void 0;
|
||||||
|
var logging_1 = require("./logging");
|
||||||
|
Object.defineProperty(exports, "trace", { enumerable: true, get: function () { return logging_1.trace; } });
|
||||||
|
Object.defineProperty(exports, "log", { enumerable: true, get: function () { return logging_1.log; } });
|
||||||
|
var resolver_1 = require("./resolver");
|
||||||
|
Object.defineProperty(exports, "registerResolver", { enumerable: true, get: function () { return resolver_1.registerResolver; } });
|
||||||
|
Object.defineProperty(exports, "createResolver", { enumerable: true, get: function () { return resolver_1.createResolver; } });
|
||||||
|
Object.defineProperty(exports, "CHANNEL_ARGS_CONFIG_SELECTOR_KEY", { enumerable: true, get: function () { return resolver_1.CHANNEL_ARGS_CONFIG_SELECTOR_KEY; } });
|
||||||
|
var uri_parser_1 = require("./uri-parser");
|
||||||
|
Object.defineProperty(exports, "uriToString", { enumerable: true, get: function () { return uri_parser_1.uriToString; } });
|
||||||
|
Object.defineProperty(exports, "splitHostPort", { enumerable: true, get: function () { return uri_parser_1.splitHostPort; } });
|
||||||
|
var duration_1 = require("./duration");
|
||||||
|
Object.defineProperty(exports, "durationToMs", { enumerable: true, get: function () { return duration_1.durationToMs; } });
|
||||||
|
Object.defineProperty(exports, "parseDuration", { enumerable: true, get: function () { return duration_1.parseDuration; } });
|
||||||
|
var backoff_timeout_1 = require("./backoff-timeout");
|
||||||
|
Object.defineProperty(exports, "BackoffTimeout", { enumerable: true, get: function () { return backoff_timeout_1.BackoffTimeout; } });
|
||||||
|
var load_balancer_1 = require("./load-balancer");
|
||||||
|
Object.defineProperty(exports, "createChildChannelControlHelper", { enumerable: true, get: function () { return load_balancer_1.createChildChannelControlHelper; } });
|
||||||
|
Object.defineProperty(exports, "registerLoadBalancerType", { enumerable: true, get: function () { return load_balancer_1.registerLoadBalancerType; } });
|
||||||
|
Object.defineProperty(exports, "selectLbConfigFromList", { enumerable: true, get: function () { return load_balancer_1.selectLbConfigFromList; } });
|
||||||
|
Object.defineProperty(exports, "parseLoadBalancingConfig", { enumerable: true, get: function () { return load_balancer_1.parseLoadBalancingConfig; } });
|
||||||
|
Object.defineProperty(exports, "isLoadBalancerNameRegistered", { enumerable: true, get: function () { return load_balancer_1.isLoadBalancerNameRegistered; } });
|
||||||
|
var load_balancer_pick_first_1 = require("./load-balancer-pick-first");
|
||||||
|
Object.defineProperty(exports, "LeafLoadBalancer", { enumerable: true, get: function () { return load_balancer_pick_first_1.LeafLoadBalancer; } });
|
||||||
|
var subchannel_address_1 = require("./subchannel-address");
|
||||||
|
Object.defineProperty(exports, "subchannelAddressToString", { enumerable: true, get: function () { return subchannel_address_1.subchannelAddressToString; } });
|
||||||
|
Object.defineProperty(exports, "endpointToString", { enumerable: true, get: function () { return subchannel_address_1.endpointToString; } });
|
||||||
|
Object.defineProperty(exports, "endpointHasAddress", { enumerable: true, get: function () { return subchannel_address_1.endpointHasAddress; } });
|
||||||
|
Object.defineProperty(exports, "EndpointMap", { enumerable: true, get: function () { return subchannel_address_1.EndpointMap; } });
|
||||||
|
var load_balancer_child_handler_1 = require("./load-balancer-child-handler");
|
||||||
|
Object.defineProperty(exports, "ChildLoadBalancerHandler", { enumerable: true, get: function () { return load_balancer_child_handler_1.ChildLoadBalancerHandler; } });
|
||||||
|
var picker_1 = require("./picker");
|
||||||
|
Object.defineProperty(exports, "UnavailablePicker", { enumerable: true, get: function () { return picker_1.UnavailablePicker; } });
|
||||||
|
Object.defineProperty(exports, "QueuePicker", { enumerable: true, get: function () { return picker_1.QueuePicker; } });
|
||||||
|
Object.defineProperty(exports, "PickResultType", { enumerable: true, get: function () { return picker_1.PickResultType; } });
|
||||||
|
var call_interface_1 = require("./call-interface");
|
||||||
|
Object.defineProperty(exports, "statusOrFromValue", { enumerable: true, get: function () { return call_interface_1.statusOrFromValue; } });
|
||||||
|
Object.defineProperty(exports, "statusOrFromError", { enumerable: true, get: function () { return call_interface_1.statusOrFromError; } });
|
||||||
|
var filter_1 = require("./filter");
|
||||||
|
Object.defineProperty(exports, "BaseFilter", { enumerable: true, get: function () { return filter_1.BaseFilter; } });
|
||||||
|
var filter_stack_1 = require("./filter-stack");
|
||||||
|
Object.defineProperty(exports, "FilterStackFactory", { enumerable: true, get: function () { return filter_stack_1.FilterStackFactory; } });
|
||||||
|
var admin_1 = require("./admin");
|
||||||
|
Object.defineProperty(exports, "registerAdminService", { enumerable: true, get: function () { return admin_1.registerAdminService; } });
|
||||||
|
var subchannel_interface_1 = require("./subchannel-interface");
|
||||||
|
Object.defineProperty(exports, "BaseSubchannelWrapper", { enumerable: true, get: function () { return subchannel_interface_1.BaseSubchannelWrapper; } });
|
||||||
|
var server_credentials_1 = require("./server-credentials");
|
||||||
|
Object.defineProperty(exports, "createServerCredentialsWithInterceptors", { enumerable: true, get: function () { return server_credentials_1.createServerCredentialsWithInterceptors; } });
|
||||||
|
Object.defineProperty(exports, "createCertificateProviderServerCredentials", { enumerable: true, get: function () { return server_credentials_1.createCertificateProviderServerCredentials; } });
|
||||||
|
var certificate_provider_1 = require("./certificate-provider");
|
||||||
|
Object.defineProperty(exports, "FileWatcherCertificateProvider", { enumerable: true, get: function () { return certificate_provider_1.FileWatcherCertificateProvider; } });
|
||||||
|
var channel_credentials_1 = require("./channel-credentials");
|
||||||
|
Object.defineProperty(exports, "createCertificateProviderChannelCredentials", { enumerable: true, get: function () { return channel_credentials_1.createCertificateProviderChannelCredentials; } });
|
||||||
|
var internal_channel_1 = require("./internal-channel");
|
||||||
|
Object.defineProperty(exports, "SUBCHANNEL_ARGS_EXCLUDE_KEY_PREFIX", { enumerable: true, get: function () { return internal_channel_1.SUBCHANNEL_ARGS_EXCLUDE_KEY_PREFIX; } });
|
||||||
|
//# sourceMappingURL=experimental.js.map
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"experimental.js","sourceRoot":"","sources":["../../src/experimental.ts"],"names":[],"mappings":";;;AAAA,qCAAuC;AAA9B,gGAAA,KAAK,OAAA;AAAE,8FAAA,GAAG,OAAA;AACnB,uCAOoB;AAJlB,4GAAA,gBAAgB,OAAA;AAEhB,0GAAA,cAAc,OAAA;AACd,4HAAA,gCAAgC,OAAA;AAElC,2CAA6E;AAA3D,yGAAA,WAAW,OAAA;AAAE,2GAAA,aAAa,OAAA;AAC5C,uCAAmE;AAAhD,wGAAA,YAAY,OAAA;AAAE,yGAAA,aAAa,OAAA;AAC9C,qDAAmD;AAA1C,iHAAA,cAAc,OAAA;AACvB,iDASyB;AALvB,gIAAA,+BAA+B,OAAA;AAC/B,yHAAA,wBAAwB,OAAA;AACxB,uHAAA,sBAAsB,OAAA;AACtB,yHAAA,wBAAwB,OAAA;AACxB,6HAAA,4BAA4B,OAAA;AAE9B,uEAA8D;AAArD,4HAAA,gBAAgB,OAAA;AACzB,2DAO8B;AAL5B,+HAAA,yBAAyB,OAAA;AAEzB,sHAAA,gBAAgB,OAAA;AAChB,wHAAA,kBAAkB,OAAA;AAClB,iHAAA,WAAW,OAAA;AAEb,6EAAyE;AAAhE,uIAAA,wBAAwB,OAAA;AACjC,mCAOkB;AALhB,2GAAA,iBAAiB,OAAA;AACjB,qGAAA,WAAW,OAAA;AAGX,wGAAA,cAAc,OAAA;AAEhB,mDAK0B;AAFxB,mHAAA,iBAAiB,OAAA;AACjB,mHAAA,iBAAiB,OAAA;AAEnB,mCAA6D;AAA5C,oGAAA,UAAU,OAAA;AAC3B,+CAAoD;AAA3C,kHAAA,kBAAkB,OAAA;AAC3B,iCAA+C;AAAtC,6GAAA,oBAAoB,OAAA;AAC7B,+DAKgC;AAH9B,6HAAA,qBAAqB,OAAA;AAUvB,2DAA2H;AAAlH,6IAAA,uCAAuC,OAAA;AAAE,gJAAA,0CAA0C,OAAA;AAC5F,+DAQgC;AAF9B,sIAAA,8BAA8B,OAAA;AAGhC,6DAA0H;AAAjH,kJAAA,2CAA2C,OAAA;AACpD,uDAAwE;AAA/D,sIAAA,kCAAkC,OAAA"}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
import { StatusObject, WriteObject } from './call-interface';
|
||||||
|
import { Filter, FilterFactory } from './filter';
|
||||||
|
import { Metadata } from './metadata';
|
||||||
|
export declare class FilterStack implements Filter {
|
||||||
|
private readonly filters;
|
||||||
|
constructor(filters: Filter[]);
|
||||||
|
sendMetadata(metadata: Promise<Metadata>): Promise<Metadata>;
|
||||||
|
receiveMetadata(metadata: Metadata): Metadata;
|
||||||
|
sendMessage(message: Promise<WriteObject>): Promise<WriteObject>;
|
||||||
|
receiveMessage(message: Promise<Buffer>): Promise<Buffer>;
|
||||||
|
receiveTrailers(status: StatusObject): StatusObject;
|
||||||
|
push(filters: Filter[]): void;
|
||||||
|
getFilters(): Filter[];
|
||||||
|
}
|
||||||
|
export declare class FilterStackFactory implements FilterFactory<FilterStack> {
|
||||||
|
private readonly factories;
|
||||||
|
constructor(factories: Array<FilterFactory<Filter>>);
|
||||||
|
push(filterFactories: FilterFactory<Filter>[]): void;
|
||||||
|
clone(): FilterStackFactory;
|
||||||
|
createFilter(): FilterStack;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,82 @@
|
||||||
|
"use strict";
|
||||||
|
/*
|
||||||
|
* Copyright 2019 gRPC 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
|
||||||
|
*
|
||||||
|
* http://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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.FilterStackFactory = exports.FilterStack = void 0;
|
||||||
|
class FilterStack {
|
||||||
|
constructor(filters) {
|
||||||
|
this.filters = filters;
|
||||||
|
}
|
||||||
|
sendMetadata(metadata) {
|
||||||
|
let result = metadata;
|
||||||
|
for (let i = 0; i < this.filters.length; i++) {
|
||||||
|
result = this.filters[i].sendMetadata(result);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
receiveMetadata(metadata) {
|
||||||
|
let result = metadata;
|
||||||
|
for (let i = this.filters.length - 1; i >= 0; i--) {
|
||||||
|
result = this.filters[i].receiveMetadata(result);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
sendMessage(message) {
|
||||||
|
let result = message;
|
||||||
|
for (let i = 0; i < this.filters.length; i++) {
|
||||||
|
result = this.filters[i].sendMessage(result);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
receiveMessage(message) {
|
||||||
|
let result = message;
|
||||||
|
for (let i = this.filters.length - 1; i >= 0; i--) {
|
||||||
|
result = this.filters[i].receiveMessage(result);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
receiveTrailers(status) {
|
||||||
|
let result = status;
|
||||||
|
for (let i = this.filters.length - 1; i >= 0; i--) {
|
||||||
|
result = this.filters[i].receiveTrailers(result);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
push(filters) {
|
||||||
|
this.filters.unshift(...filters);
|
||||||
|
}
|
||||||
|
getFilters() {
|
||||||
|
return this.filters;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.FilterStack = FilterStack;
|
||||||
|
class FilterStackFactory {
|
||||||
|
constructor(factories) {
|
||||||
|
this.factories = factories;
|
||||||
|
}
|
||||||
|
push(filterFactories) {
|
||||||
|
this.factories.unshift(...filterFactories);
|
||||||
|
}
|
||||||
|
clone() {
|
||||||
|
return new FilterStackFactory([...this.factories]);
|
||||||
|
}
|
||||||
|
createFilter() {
|
||||||
|
return new FilterStack(this.factories.map(factory => factory.createFilter()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.FilterStackFactory = FilterStackFactory;
|
||||||
|
//# sourceMappingURL=filter-stack.js.map
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"filter-stack.js","sourceRoot":"","sources":["../../src/filter-stack.ts"],"names":[],"mappings":"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"}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
import { StatusObject, WriteObject } from './call-interface';
|
||||||
|
import { Metadata } from './metadata';
|
||||||
|
/**
|
||||||
|
* Filter classes represent related per-call logic and state that is primarily
|
||||||
|
* used to modify incoming and outgoing data. All async filters can be
|
||||||
|
* rejected. The rejection error must be a StatusObject, and a rejection will
|
||||||
|
* cause the call to end with that status.
|
||||||
|
*/
|
||||||
|
export interface Filter {
|
||||||
|
sendMetadata(metadata: Promise<Metadata>): Promise<Metadata>;
|
||||||
|
receiveMetadata(metadata: Metadata): Metadata;
|
||||||
|
sendMessage(message: Promise<WriteObject>): Promise<WriteObject>;
|
||||||
|
receiveMessage(message: Promise<Buffer>): Promise<Buffer>;
|
||||||
|
receiveTrailers(status: StatusObject): StatusObject;
|
||||||
|
}
|
||||||
|
export declare abstract class BaseFilter implements Filter {
|
||||||
|
sendMetadata(metadata: Promise<Metadata>): Promise<Metadata>;
|
||||||
|
receiveMetadata(metadata: Metadata): Metadata;
|
||||||
|
sendMessage(message: Promise<WriteObject>): Promise<WriteObject>;
|
||||||
|
receiveMessage(message: Promise<Buffer>): Promise<Buffer>;
|
||||||
|
receiveTrailers(status: StatusObject): StatusObject;
|
||||||
|
}
|
||||||
|
export interface FilterFactory<T extends Filter> {
|
||||||
|
createFilter(): T;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
"use strict";
|
||||||
|
/*
|
||||||
|
* Copyright 2019 gRPC 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
|
||||||
|
*
|
||||||
|
* http://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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.BaseFilter = void 0;
|
||||||
|
class BaseFilter {
|
||||||
|
async sendMetadata(metadata) {
|
||||||
|
return metadata;
|
||||||
|
}
|
||||||
|
receiveMetadata(metadata) {
|
||||||
|
return metadata;
|
||||||
|
}
|
||||||
|
async sendMessage(message) {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
async receiveMessage(message) {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
receiveTrailers(status) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.BaseFilter = BaseFilter;
|
||||||
|
//# sourceMappingURL=filter.js.map
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"filter.js","sourceRoot":"","sources":["../../src/filter.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;;AAuBH,MAAsB,UAAU;IAC9B,KAAK,CAAC,YAAY,CAAC,QAA2B;QAC5C,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,eAAe,CAAC,QAAkB;QAChC,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,OAA6B;QAC7C,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,OAAwB;QAC3C,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,eAAe,CAAC,MAAoB;QAClC,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AApBD,gCAoBC"}
|
||||||
|
|
@ -0,0 +1,118 @@
|
||||||
|
import type * as grpc from '../index';
|
||||||
|
import type { MessageTypeDefinition } from '@grpc/proto-loader';
|
||||||
|
import type { Any as _google_protobuf_Any, Any__Output as _google_protobuf_Any__Output } from './google/protobuf/Any';
|
||||||
|
import type { BoolValue as _google_protobuf_BoolValue, BoolValue__Output as _google_protobuf_BoolValue__Output } from './google/protobuf/BoolValue';
|
||||||
|
import type { BytesValue as _google_protobuf_BytesValue, BytesValue__Output as _google_protobuf_BytesValue__Output } from './google/protobuf/BytesValue';
|
||||||
|
import type { DoubleValue as _google_protobuf_DoubleValue, DoubleValue__Output as _google_protobuf_DoubleValue__Output } from './google/protobuf/DoubleValue';
|
||||||
|
import type { Duration as _google_protobuf_Duration, Duration__Output as _google_protobuf_Duration__Output } from './google/protobuf/Duration';
|
||||||
|
import type { FloatValue as _google_protobuf_FloatValue, FloatValue__Output as _google_protobuf_FloatValue__Output } from './google/protobuf/FloatValue';
|
||||||
|
import type { Int32Value as _google_protobuf_Int32Value, Int32Value__Output as _google_protobuf_Int32Value__Output } from './google/protobuf/Int32Value';
|
||||||
|
import type { Int64Value as _google_protobuf_Int64Value, Int64Value__Output as _google_protobuf_Int64Value__Output } from './google/protobuf/Int64Value';
|
||||||
|
import type { StringValue as _google_protobuf_StringValue, StringValue__Output as _google_protobuf_StringValue__Output } from './google/protobuf/StringValue';
|
||||||
|
import type { Timestamp as _google_protobuf_Timestamp, Timestamp__Output as _google_protobuf_Timestamp__Output } from './google/protobuf/Timestamp';
|
||||||
|
import type { UInt32Value as _google_protobuf_UInt32Value, UInt32Value__Output as _google_protobuf_UInt32Value__Output } from './google/protobuf/UInt32Value';
|
||||||
|
import type { UInt64Value as _google_protobuf_UInt64Value, UInt64Value__Output as _google_protobuf_UInt64Value__Output } from './google/protobuf/UInt64Value';
|
||||||
|
import type { Address as _grpc_channelz_v1_Address, Address__Output as _grpc_channelz_v1_Address__Output } from './grpc/channelz/v1/Address';
|
||||||
|
import type { Channel as _grpc_channelz_v1_Channel, Channel__Output as _grpc_channelz_v1_Channel__Output } from './grpc/channelz/v1/Channel';
|
||||||
|
import type { ChannelConnectivityState as _grpc_channelz_v1_ChannelConnectivityState, ChannelConnectivityState__Output as _grpc_channelz_v1_ChannelConnectivityState__Output } from './grpc/channelz/v1/ChannelConnectivityState';
|
||||||
|
import type { ChannelData as _grpc_channelz_v1_ChannelData, ChannelData__Output as _grpc_channelz_v1_ChannelData__Output } from './grpc/channelz/v1/ChannelData';
|
||||||
|
import type { ChannelRef as _grpc_channelz_v1_ChannelRef, ChannelRef__Output as _grpc_channelz_v1_ChannelRef__Output } from './grpc/channelz/v1/ChannelRef';
|
||||||
|
import type { ChannelTrace as _grpc_channelz_v1_ChannelTrace, ChannelTrace__Output as _grpc_channelz_v1_ChannelTrace__Output } from './grpc/channelz/v1/ChannelTrace';
|
||||||
|
import type { ChannelTraceEvent as _grpc_channelz_v1_ChannelTraceEvent, ChannelTraceEvent__Output as _grpc_channelz_v1_ChannelTraceEvent__Output } from './grpc/channelz/v1/ChannelTraceEvent';
|
||||||
|
import type { ChannelzClient as _grpc_channelz_v1_ChannelzClient, ChannelzDefinition as _grpc_channelz_v1_ChannelzDefinition } from './grpc/channelz/v1/Channelz';
|
||||||
|
import type { GetChannelRequest as _grpc_channelz_v1_GetChannelRequest, GetChannelRequest__Output as _grpc_channelz_v1_GetChannelRequest__Output } from './grpc/channelz/v1/GetChannelRequest';
|
||||||
|
import type { GetChannelResponse as _grpc_channelz_v1_GetChannelResponse, GetChannelResponse__Output as _grpc_channelz_v1_GetChannelResponse__Output } from './grpc/channelz/v1/GetChannelResponse';
|
||||||
|
import type { GetServerRequest as _grpc_channelz_v1_GetServerRequest, GetServerRequest__Output as _grpc_channelz_v1_GetServerRequest__Output } from './grpc/channelz/v1/GetServerRequest';
|
||||||
|
import type { GetServerResponse as _grpc_channelz_v1_GetServerResponse, GetServerResponse__Output as _grpc_channelz_v1_GetServerResponse__Output } from './grpc/channelz/v1/GetServerResponse';
|
||||||
|
import type { GetServerSocketsRequest as _grpc_channelz_v1_GetServerSocketsRequest, GetServerSocketsRequest__Output as _grpc_channelz_v1_GetServerSocketsRequest__Output } from './grpc/channelz/v1/GetServerSocketsRequest';
|
||||||
|
import type { GetServerSocketsResponse as _grpc_channelz_v1_GetServerSocketsResponse, GetServerSocketsResponse__Output as _grpc_channelz_v1_GetServerSocketsResponse__Output } from './grpc/channelz/v1/GetServerSocketsResponse';
|
||||||
|
import type { GetServersRequest as _grpc_channelz_v1_GetServersRequest, GetServersRequest__Output as _grpc_channelz_v1_GetServersRequest__Output } from './grpc/channelz/v1/GetServersRequest';
|
||||||
|
import type { GetServersResponse as _grpc_channelz_v1_GetServersResponse, GetServersResponse__Output as _grpc_channelz_v1_GetServersResponse__Output } from './grpc/channelz/v1/GetServersResponse';
|
||||||
|
import type { GetSocketRequest as _grpc_channelz_v1_GetSocketRequest, GetSocketRequest__Output as _grpc_channelz_v1_GetSocketRequest__Output } from './grpc/channelz/v1/GetSocketRequest';
|
||||||
|
import type { GetSocketResponse as _grpc_channelz_v1_GetSocketResponse, GetSocketResponse__Output as _grpc_channelz_v1_GetSocketResponse__Output } from './grpc/channelz/v1/GetSocketResponse';
|
||||||
|
import type { GetSubchannelRequest as _grpc_channelz_v1_GetSubchannelRequest, GetSubchannelRequest__Output as _grpc_channelz_v1_GetSubchannelRequest__Output } from './grpc/channelz/v1/GetSubchannelRequest';
|
||||||
|
import type { GetSubchannelResponse as _grpc_channelz_v1_GetSubchannelResponse, GetSubchannelResponse__Output as _grpc_channelz_v1_GetSubchannelResponse__Output } from './grpc/channelz/v1/GetSubchannelResponse';
|
||||||
|
import type { GetTopChannelsRequest as _grpc_channelz_v1_GetTopChannelsRequest, GetTopChannelsRequest__Output as _grpc_channelz_v1_GetTopChannelsRequest__Output } from './grpc/channelz/v1/GetTopChannelsRequest';
|
||||||
|
import type { GetTopChannelsResponse as _grpc_channelz_v1_GetTopChannelsResponse, GetTopChannelsResponse__Output as _grpc_channelz_v1_GetTopChannelsResponse__Output } from './grpc/channelz/v1/GetTopChannelsResponse';
|
||||||
|
import type { Security as _grpc_channelz_v1_Security, Security__Output as _grpc_channelz_v1_Security__Output } from './grpc/channelz/v1/Security';
|
||||||
|
import type { Server as _grpc_channelz_v1_Server, Server__Output as _grpc_channelz_v1_Server__Output } from './grpc/channelz/v1/Server';
|
||||||
|
import type { ServerData as _grpc_channelz_v1_ServerData, ServerData__Output as _grpc_channelz_v1_ServerData__Output } from './grpc/channelz/v1/ServerData';
|
||||||
|
import type { ServerRef as _grpc_channelz_v1_ServerRef, ServerRef__Output as _grpc_channelz_v1_ServerRef__Output } from './grpc/channelz/v1/ServerRef';
|
||||||
|
import type { Socket as _grpc_channelz_v1_Socket, Socket__Output as _grpc_channelz_v1_Socket__Output } from './grpc/channelz/v1/Socket';
|
||||||
|
import type { SocketData as _grpc_channelz_v1_SocketData, SocketData__Output as _grpc_channelz_v1_SocketData__Output } from './grpc/channelz/v1/SocketData';
|
||||||
|
import type { SocketOption as _grpc_channelz_v1_SocketOption, SocketOption__Output as _grpc_channelz_v1_SocketOption__Output } from './grpc/channelz/v1/SocketOption';
|
||||||
|
import type { SocketOptionLinger as _grpc_channelz_v1_SocketOptionLinger, SocketOptionLinger__Output as _grpc_channelz_v1_SocketOptionLinger__Output } from './grpc/channelz/v1/SocketOptionLinger';
|
||||||
|
import type { SocketOptionTcpInfo as _grpc_channelz_v1_SocketOptionTcpInfo, SocketOptionTcpInfo__Output as _grpc_channelz_v1_SocketOptionTcpInfo__Output } from './grpc/channelz/v1/SocketOptionTcpInfo';
|
||||||
|
import type { SocketOptionTimeout as _grpc_channelz_v1_SocketOptionTimeout, SocketOptionTimeout__Output as _grpc_channelz_v1_SocketOptionTimeout__Output } from './grpc/channelz/v1/SocketOptionTimeout';
|
||||||
|
import type { SocketRef as _grpc_channelz_v1_SocketRef, SocketRef__Output as _grpc_channelz_v1_SocketRef__Output } from './grpc/channelz/v1/SocketRef';
|
||||||
|
import type { Subchannel as _grpc_channelz_v1_Subchannel, Subchannel__Output as _grpc_channelz_v1_Subchannel__Output } from './grpc/channelz/v1/Subchannel';
|
||||||
|
import type { SubchannelRef as _grpc_channelz_v1_SubchannelRef, SubchannelRef__Output as _grpc_channelz_v1_SubchannelRef__Output } from './grpc/channelz/v1/SubchannelRef';
|
||||||
|
type SubtypeConstructor<Constructor extends new (...args: any) => any, Subtype> = {
|
||||||
|
new (...args: ConstructorParameters<Constructor>): Subtype;
|
||||||
|
};
|
||||||
|
export interface ProtoGrpcType {
|
||||||
|
google: {
|
||||||
|
protobuf: {
|
||||||
|
Any: MessageTypeDefinition<_google_protobuf_Any, _google_protobuf_Any__Output>;
|
||||||
|
BoolValue: MessageTypeDefinition<_google_protobuf_BoolValue, _google_protobuf_BoolValue__Output>;
|
||||||
|
BytesValue: MessageTypeDefinition<_google_protobuf_BytesValue, _google_protobuf_BytesValue__Output>;
|
||||||
|
DoubleValue: MessageTypeDefinition<_google_protobuf_DoubleValue, _google_protobuf_DoubleValue__Output>;
|
||||||
|
Duration: MessageTypeDefinition<_google_protobuf_Duration, _google_protobuf_Duration__Output>;
|
||||||
|
FloatValue: MessageTypeDefinition<_google_protobuf_FloatValue, _google_protobuf_FloatValue__Output>;
|
||||||
|
Int32Value: MessageTypeDefinition<_google_protobuf_Int32Value, _google_protobuf_Int32Value__Output>;
|
||||||
|
Int64Value: MessageTypeDefinition<_google_protobuf_Int64Value, _google_protobuf_Int64Value__Output>;
|
||||||
|
StringValue: MessageTypeDefinition<_google_protobuf_StringValue, _google_protobuf_StringValue__Output>;
|
||||||
|
Timestamp: MessageTypeDefinition<_google_protobuf_Timestamp, _google_protobuf_Timestamp__Output>;
|
||||||
|
UInt32Value: MessageTypeDefinition<_google_protobuf_UInt32Value, _google_protobuf_UInt32Value__Output>;
|
||||||
|
UInt64Value: MessageTypeDefinition<_google_protobuf_UInt64Value, _google_protobuf_UInt64Value__Output>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
grpc: {
|
||||||
|
channelz: {
|
||||||
|
v1: {
|
||||||
|
Address: MessageTypeDefinition<_grpc_channelz_v1_Address, _grpc_channelz_v1_Address__Output>;
|
||||||
|
Channel: MessageTypeDefinition<_grpc_channelz_v1_Channel, _grpc_channelz_v1_Channel__Output>;
|
||||||
|
ChannelConnectivityState: MessageTypeDefinition<_grpc_channelz_v1_ChannelConnectivityState, _grpc_channelz_v1_ChannelConnectivityState__Output>;
|
||||||
|
ChannelData: MessageTypeDefinition<_grpc_channelz_v1_ChannelData, _grpc_channelz_v1_ChannelData__Output>;
|
||||||
|
ChannelRef: MessageTypeDefinition<_grpc_channelz_v1_ChannelRef, _grpc_channelz_v1_ChannelRef__Output>;
|
||||||
|
ChannelTrace: MessageTypeDefinition<_grpc_channelz_v1_ChannelTrace, _grpc_channelz_v1_ChannelTrace__Output>;
|
||||||
|
ChannelTraceEvent: MessageTypeDefinition<_grpc_channelz_v1_ChannelTraceEvent, _grpc_channelz_v1_ChannelTraceEvent__Output>;
|
||||||
|
/**
|
||||||
|
* Channelz is a service exposed by gRPC servers that provides detailed debug
|
||||||
|
* information.
|
||||||
|
*/
|
||||||
|
Channelz: SubtypeConstructor<typeof grpc.Client, _grpc_channelz_v1_ChannelzClient> & {
|
||||||
|
service: _grpc_channelz_v1_ChannelzDefinition;
|
||||||
|
};
|
||||||
|
GetChannelRequest: MessageTypeDefinition<_grpc_channelz_v1_GetChannelRequest, _grpc_channelz_v1_GetChannelRequest__Output>;
|
||||||
|
GetChannelResponse: MessageTypeDefinition<_grpc_channelz_v1_GetChannelResponse, _grpc_channelz_v1_GetChannelResponse__Output>;
|
||||||
|
GetServerRequest: MessageTypeDefinition<_grpc_channelz_v1_GetServerRequest, _grpc_channelz_v1_GetServerRequest__Output>;
|
||||||
|
GetServerResponse: MessageTypeDefinition<_grpc_channelz_v1_GetServerResponse, _grpc_channelz_v1_GetServerResponse__Output>;
|
||||||
|
GetServerSocketsRequest: MessageTypeDefinition<_grpc_channelz_v1_GetServerSocketsRequest, _grpc_channelz_v1_GetServerSocketsRequest__Output>;
|
||||||
|
GetServerSocketsResponse: MessageTypeDefinition<_grpc_channelz_v1_GetServerSocketsResponse, _grpc_channelz_v1_GetServerSocketsResponse__Output>;
|
||||||
|
GetServersRequest: MessageTypeDefinition<_grpc_channelz_v1_GetServersRequest, _grpc_channelz_v1_GetServersRequest__Output>;
|
||||||
|
GetServersResponse: MessageTypeDefinition<_grpc_channelz_v1_GetServersResponse, _grpc_channelz_v1_GetServersResponse__Output>;
|
||||||
|
GetSocketRequest: MessageTypeDefinition<_grpc_channelz_v1_GetSocketRequest, _grpc_channelz_v1_GetSocketRequest__Output>;
|
||||||
|
GetSocketResponse: MessageTypeDefinition<_grpc_channelz_v1_GetSocketResponse, _grpc_channelz_v1_GetSocketResponse__Output>;
|
||||||
|
GetSubchannelRequest: MessageTypeDefinition<_grpc_channelz_v1_GetSubchannelRequest, _grpc_channelz_v1_GetSubchannelRequest__Output>;
|
||||||
|
GetSubchannelResponse: MessageTypeDefinition<_grpc_channelz_v1_GetSubchannelResponse, _grpc_channelz_v1_GetSubchannelResponse__Output>;
|
||||||
|
GetTopChannelsRequest: MessageTypeDefinition<_grpc_channelz_v1_GetTopChannelsRequest, _grpc_channelz_v1_GetTopChannelsRequest__Output>;
|
||||||
|
GetTopChannelsResponse: MessageTypeDefinition<_grpc_channelz_v1_GetTopChannelsResponse, _grpc_channelz_v1_GetTopChannelsResponse__Output>;
|
||||||
|
Security: MessageTypeDefinition<_grpc_channelz_v1_Security, _grpc_channelz_v1_Security__Output>;
|
||||||
|
Server: MessageTypeDefinition<_grpc_channelz_v1_Server, _grpc_channelz_v1_Server__Output>;
|
||||||
|
ServerData: MessageTypeDefinition<_grpc_channelz_v1_ServerData, _grpc_channelz_v1_ServerData__Output>;
|
||||||
|
ServerRef: MessageTypeDefinition<_grpc_channelz_v1_ServerRef, _grpc_channelz_v1_ServerRef__Output>;
|
||||||
|
Socket: MessageTypeDefinition<_grpc_channelz_v1_Socket, _grpc_channelz_v1_Socket__Output>;
|
||||||
|
SocketData: MessageTypeDefinition<_grpc_channelz_v1_SocketData, _grpc_channelz_v1_SocketData__Output>;
|
||||||
|
SocketOption: MessageTypeDefinition<_grpc_channelz_v1_SocketOption, _grpc_channelz_v1_SocketOption__Output>;
|
||||||
|
SocketOptionLinger: MessageTypeDefinition<_grpc_channelz_v1_SocketOptionLinger, _grpc_channelz_v1_SocketOptionLinger__Output>;
|
||||||
|
SocketOptionTcpInfo: MessageTypeDefinition<_grpc_channelz_v1_SocketOptionTcpInfo, _grpc_channelz_v1_SocketOptionTcpInfo__Output>;
|
||||||
|
SocketOptionTimeout: MessageTypeDefinition<_grpc_channelz_v1_SocketOptionTimeout, _grpc_channelz_v1_SocketOptionTimeout__Output>;
|
||||||
|
SocketRef: MessageTypeDefinition<_grpc_channelz_v1_SocketRef, _grpc_channelz_v1_SocketRef__Output>;
|
||||||
|
Subchannel: MessageTypeDefinition<_grpc_channelz_v1_Subchannel, _grpc_channelz_v1_Subchannel__Output>;
|
||||||
|
SubchannelRef: MessageTypeDefinition<_grpc_channelz_v1_SubchannelRef, _grpc_channelz_v1_SubchannelRef__Output>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
export {};
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
//# sourceMappingURL=channelz.js.map
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"channelz.js","sourceRoot":"","sources":["../../../src/generated/channelz.ts"],"names":[],"mappings":""}
|
||||||
9
node_modules/@grpc/grpc-js/build/src/generated/google/protobuf/Any.d.ts
generated
vendored
Normal file
9
node_modules/@grpc/grpc-js/build/src/generated/google/protobuf/Any.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
import type { AnyExtension } from '@grpc/proto-loader';
|
||||||
|
export type Any = AnyExtension | {
|
||||||
|
type_url: string;
|
||||||
|
value: Buffer | Uint8Array | string;
|
||||||
|
};
|
||||||
|
export interface Any__Output {
|
||||||
|
'type_url': (string);
|
||||||
|
'value': (Buffer);
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue