( strings: string | string[], ...values: string[] )
| 116 | const errorLog = createLogger('error'); |
| 117 | |
| 118 | export const dedent = ( |
| 119 | strings: string | string[], |
| 120 | ...values: string[] |
| 121 | ): string => { |
| 122 | const raw = Array.isArray(strings) ? strings : [strings]; |
| 123 | |
| 124 | let result = ''; |
| 125 | |
| 126 | for (let i = 0; i < raw.length; i++) { |
| 127 | result += raw[i] |
| 128 | // join lines when there is a suppressed newline |
| 129 | .replace(/\\\n[ \t]*/g, '') |
| 130 | // handle escaped back-ticks |
| 131 | .replace(/\\`/g, '`'); |
| 132 | |
| 133 | if (i < values.length) { |
| 134 | result += values[i]; |
| 135 | } |
| 136 | } |
| 137 | |
| 138 | // now strip indentation |
| 139 | const lines = result.split('\n'); |
| 140 | let mIndent: number | null = null; |
| 141 | lines.forEach((l) => { |
| 142 | const m = l.match(/^(\s+)\S+/); |
| 143 | if (m) { |
| 144 | const indent = m[1].length; |
| 145 | if (!mIndent) { |
| 146 | // this is the first indented line |
| 147 | mIndent = indent; |
| 148 | } else { |
| 149 | mIndent = Math.min(mIndent, indent); |
| 150 | } |
| 151 | } |
| 152 | }); |
| 153 | |
| 154 | if (mIndent !== null) { |
| 155 | const m = mIndent; |
| 156 | result = lines.map((l) => (l[0] === ' ' ? l.slice(m) : l)).join('\n'); |
| 157 | } |
| 158 | |
| 159 | return ( |
| 160 | result |
| 161 | // dedent eats leading and trailing whitespace too |
| 162 | .trim() |
| 163 | // handle escaped newlines at the end to ensure they don't get stripped too |
| 164 | .replace(/\\n/g, '\n') |
| 165 | ); |
| 166 | }; |
| 167 | |
| 168 | export const isConnected = (connection: Duplex | ServerResponse): boolean => |
| 169 | isHTTP(connection) ? !!connection.socket?.writable : !!connection.writable; |
no outgoing calls
no test coverage detected